summaryrefslogtreecommitdiff
path: root/chromium/content
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-28 15:28:34 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-08-28 13:54:51 +0000
commit2a19c63448c84c1805fb1a585c3651318bb86ca7 (patch)
treeeb17888e8531aa6ee5e85721bd553b832a7e5156 /chromium/content
parentb014812705fc80bff0a5c120dfcef88f349816dc (diff)
downloadqtwebengine-chromium-2a19c63448c84c1805fb1a585c3651318bb86ca7.tar.gz
BASELINE: Update Chromium to 69.0.3497.70
Change-Id: I2b7b56e4e7a8b26656930def0d4575dc32b900a0 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/content')
-rw-r--r--chromium/content/BUILD.gn3
-rw-r--r--chromium/content/DEPS5
-rw-r--r--chromium/content/app/BUILD.gn5
-rw-r--r--chromium/content/app/DEPS2
-rw-r--r--chromium/content/app/android/content_main.cc22
-rw-r--r--chromium/content/app/content_main.cc2
-rw-r--r--chromium/content/app/content_main_runner_impl.cc147
-rw-r--r--chromium/content/app/content_main_runner_impl.h19
-rw-r--r--chromium/content/app/content_service_manager_main_delegate.cc12
-rw-r--r--chromium/content/app/content_service_manager_main_delegate.h14
-rw-r--r--chromium/content/app/mojo/mojo_init.cc8
-rw-r--r--chromium/content/app/strings/content_strings.grd44
-rw-r--r--chromium/content/app/strings/translations/content_strings_am.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_ar.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_bg.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_bn.xtb19
-rw-r--r--chromium/content/app/strings/translations/content_strings_ca.xtb19
-rw-r--r--chromium/content/app/strings/translations/content_strings_cs.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_da.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_de.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_el.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_en-GB.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_es-419.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_es.xtb15
-rw-r--r--chromium/content/app/strings/translations/content_strings_et.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_fa.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_fi.xtb15
-rw-r--r--chromium/content/app/strings/translations/content_strings_fil.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_fr.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_gu.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_hi.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_hr.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_hu.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_id.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_it.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_iw.xtb15
-rw-r--r--chromium/content/app/strings/translations/content_strings_ja.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_kn.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_ko.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_lt.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_lv.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_ml.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_mr.xtb17
-rw-r--r--chromium/content/app/strings/translations/content_strings_ms.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_nl.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_no.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_pl.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_pt-BR.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_pt-PT.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_ro.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_ru.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_sk.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_sl.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_sr.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_sv.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_sw.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_ta.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_te.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_th.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_tr.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_uk.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_vi.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_zh-CN.xtb13
-rw-r--r--chromium/content/app/strings/translations/content_strings_zh-TW.xtb13
-rw-r--r--chromium/content/browser/BUILD.gn165
-rw-r--r--chromium/content/browser/DEPS14
-rw-r--r--chromium/content/browser/OWNERS5
-rw-r--r--chromium/content/browser/accessibility/accessibility_event_recorder_win.cc16
-rw-r--r--chromium/content/browser/accessibility/accessibility_ipc_error_browsertest.cc8
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter.cc22
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm6
-rw-r--r--chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc5
-rw-r--r--chromium/content/browser/accessibility/accessibility_ui.cc12
-rw-r--r--chromium/content/browser/accessibility/accessibility_win_browsertest.cc23
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility.cc85
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility.h8
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_android.cc20
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_cocoa.h4
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_cocoa.mm795
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_com_win.cc133
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_com_win.h39
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_mac.h2
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_mac.mm34
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_mac_unittest.mm121
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager.cc24
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager.h7
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_mac.h2
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm17
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc63
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_manager_win.cc5
-rw-r--r--chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc56
-rw-r--r--chromium/content/browser/accessibility/captioning_controller.cc2
-rw-r--r--chromium/content/browser/accessibility/cross_platform_accessibility_browsertest.cc53
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc10
-rw-r--r--chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc48
-rw-r--r--chromium/content/browser/accessibility/hit_testing_browsertest.cc224
-rw-r--r--chromium/content/browser/accessibility/line_layout_browsertest.cc97
-rw-r--r--chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc2
-rw-r--r--chromium/content/browser/accessibility/touch_accessibility_aura_browsertest.cc10
-rw-r--r--chromium/content/browser/accessibility/web_contents_accessibility_android.cc4
-rw-r--r--chromium/content/browser/android/browser_startup_controller.cc36
-rw-r--r--chromium/content/browser/android/browser_startup_controller.h1
-rw-r--r--chromium/content/browser/android/content_feature_list.cc1
-rw-r--r--chromium/content/browser/android/content_startup_flags.cc8
-rw-r--r--chromium/content/browser/android/content_startup_flags.h3
-rw-r--r--chromium/content/browser/android/content_video_view.cc172
-rw-r--r--chromium/content/browser/android/content_video_view.h115
-rw-r--r--chromium/content/browser/android/content_view_core.cc153
-rw-r--r--chromium/content/browser/android/content_view_core.h74
-rw-r--r--chromium/content/browser/android/content_view_render_view.cc138
-rw-r--r--chromium/content/browser/android/content_view_render_view.h77
-rw-r--r--chromium/content/browser/android/dialog_overlay_impl.cc4
-rw-r--r--chromium/content/browser/android/gesture_listener_manager.cc54
-rw-r--r--chromium/content/browser/android/gesture_listener_manager.h1
-rw-r--r--chromium/content/browser/android/overscroll_controller_android.cc20
-rw-r--r--chromium/content/browser/android/overscroll_controller_android.h11
-rw-r--r--chromium/content/browser/android/selection/composited_touch_handle_drawable.cc95
-rw-r--r--chromium/content/browser/android/selection/composited_touch_handle_drawable.h16
-rw-r--r--chromium/content/browser/android/selection/selection_popup_controller.cc3
-rw-r--r--chromium/content/browser/android/synchronous_compositor_host.cc10
-rw-r--r--chromium/content/browser/android/synchronous_compositor_host.h1
-rw-r--r--chromium/content/browser/android/url_request_content_job.cc6
-rw-r--r--chromium/content/browser/android/url_request_content_job.h4
-rw-r--r--chromium/content/browser/android/web_contents_observer_proxy.cc7
-rw-r--r--chromium/content/browser/android/web_contents_observer_proxy.h1
-rw-r--r--chromium/content/browser/appcache/appcache_backend_impl.cc31
-rw-r--r--chromium/content/browser/appcache/appcache_backend_impl.h7
-rw-r--r--chromium/content/browser/appcache/appcache_database.cc78
-rw-r--r--chromium/content/browser/appcache/appcache_database.h4
-rw-r--r--chromium/content/browser/appcache/appcache_disk_cache.cc6
-rw-r--r--chromium/content/browser/appcache/appcache_dispatcher_host.cc24
-rw-r--r--chromium/content/browser/appcache/appcache_host.cc17
-rw-r--r--chromium/content/browser/appcache/appcache_host.h4
-rw-r--r--chromium/content/browser/appcache/appcache_internals_ui.cc2
-rw-r--r--chromium/content/browser/appcache/appcache_navigation_handle.cc14
-rw-r--r--chromium/content/browser/appcache/appcache_navigation_handle.h15
-rw-r--r--chromium/content/browser/appcache/appcache_navigation_handle_core.cc6
-rw-r--r--chromium/content/browser/appcache/appcache_navigation_handle_core.h2
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler.cc6
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler.h8
-rw-r--r--chromium/content/browser/appcache/appcache_request_handler_unittest.cc35
-rw-r--r--chromium/content/browser/appcache/appcache_service_impl.h2
-rw-r--r--chromium/content/browser/appcache/appcache_storage_impl_unittest.cc4
-rw-r--r--chromium/content/browser/appcache/appcache_subresource_url_factory.cc61
-rw-r--r--chromium/content/browser/appcache/appcache_subresource_url_factory.h23
-rw-r--r--chromium/content/browser/appcache/appcache_update_job_unittest.cc11
-rw-r--r--chromium/content/browser/appcache/appcache_update_url_loader_request.cc9
-rw-r--r--chromium/content/browser/appcache/appcache_update_url_loader_request.h4
-rw-r--r--chromium/content/browser/appcache/appcache_url_loader_job.cc5
-rw-r--r--chromium/content/browser/appcache/appcache_url_loader_job.h4
-rw-r--r--chromium/content/browser/appcache/appcache_url_loader_request.cc7
-rw-r--r--chromium/content/browser/appcache/chrome_appcache_service.cc22
-rw-r--r--chromium/content/browser/appcache/chrome_appcache_service.h16
-rw-r--r--chromium/content/browser/background_fetch/background_fetch.proto47
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_context.cc288
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_context.h122
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_data_manager.cc538
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_data_manager.h85
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_data_manager_observer.h31
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_data_manager_unittest.cc732
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_delegate_proxy.cc33
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_delegate_proxy.h11
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_delegate_proxy_unittest.cc35
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc14
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h16
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_event_dispatcher.cc25
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_event_dispatcher.h15
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc12
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_job_controller.cc9
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_job_controller.h8
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_job_controller_unittest.cc92
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_request_info.cc13
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_request_info.h12
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_scheduler.cc31
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_scheduler.h8
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_service_impl.h1
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_service_unittest.cc187
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_test_base.cc31
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_test_base.h10
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_test_data_manager.cc76
-rw-r--r--chromium/content/browser/background_fetch/background_fetch_test_data_manager.h51
-rw-r--r--chromium/content/browser/background_fetch/mock_background_fetch_delegate.cc6
-rw-r--r--chromium/content/browser/background_fetch/mock_background_fetch_delegate.h2
-rw-r--r--chromium/content/browser/background_fetch/storage/README.md13
-rw-r--r--chromium/content/browser/background_fetch/storage/cleanup_task.cc23
-rw-r--r--chromium/content/browser/background_fetch/storage/cleanup_task.h11
-rw-r--r--chromium/content/browser/background_fetch/storage/create_metadata_task.cc131
-rw-r--r--chromium/content/browser/background_fetch/storage/create_metadata_task.h16
-rw-r--r--chromium/content/browser/background_fetch/storage/database_helpers.cc41
-rw-r--r--chromium/content/browser/background_fetch/storage/database_helpers.h4
-rw-r--r--chromium/content/browser/background_fetch/storage/database_task.cc60
-rw-r--r--chromium/content/browser/background_fetch/storage/database_task.h65
-rw-r--r--chromium/content/browser/background_fetch/storage/delete_registration_task.cc77
-rw-r--r--chromium/content/browser/background_fetch/storage/delete_registration_task.h25
-rw-r--r--chromium/content/browser/background_fetch/storage/get_developer_ids_task.cc25
-rw-r--r--chromium/content/browser/background_fetch/storage/get_developer_ids_task.h10
-rw-r--r--chromium/content/browser/background_fetch/storage/get_initialization_data_task.cc536
-rw-r--r--chromium/content/browser/background_fetch/storage/get_initialization_data_task.h100
-rw-r--r--chromium/content/browser/background_fetch/storage/get_metadata_task.cc47
-rw-r--r--chromium/content/browser/background_fetch/storage/get_metadata_task.h10
-rw-r--r--chromium/content/browser/background_fetch/storage/get_num_requests_task.cc88
-rw-r--r--chromium/content/browser/background_fetch/storage/get_num_requests_task.h53
-rw-r--r--chromium/content/browser/background_fetch/storage/get_settled_fetches_task.cc143
-rw-r--r--chromium/content/browser/background_fetch/storage/get_settled_fetches_task.h40
-rw-r--r--chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc34
-rw-r--r--chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.h10
-rw-r--r--chromium/content/browser/background_fetch/storage/mark_request_complete_task.cc228
-rw-r--r--chromium/content/browser/background_fetch/storage/mark_request_complete_task.h38
-rw-r--r--chromium/content/browser/background_fetch/storage/start_next_pending_request_task.cc45
-rw-r--r--chromium/content/browser/background_fetch/storage/start_next_pending_request_task.h14
-rw-r--r--chromium/content/browser/background_fetch/storage/update_registration_ui_task.cc24
-rw-r--r--chromium/content/browser/background_fetch/storage/update_registration_ui_task.h8
-rw-r--r--chromium/content/browser/background_sync/background_sync_browsertest.cc9
-rw-r--r--chromium/content/browser/background_sync/background_sync_manager.cc106
-rw-r--r--chromium/content/browser/background_sync/background_sync_manager.h20
-rw-r--r--chromium/content/browser/background_sync/background_sync_manager_unittest.cc112
-rw-r--r--chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc20
-rw-r--r--chromium/content/browser/bad_message.h6
-rw-r--r--chromium/content/browser/battery_monitor_browsertest.cc9
-rw-r--r--chromium/content/browser/blob_storage/OWNERS2
-rw-r--r--chromium/content/browser/blob_storage/blob_internals_url_loader.cc2
-rw-r--r--chromium/content/browser/blob_storage/blob_url_browsertest.cc23
-rw-r--r--chromium/content/browser/blob_storage/blob_url_loader_factory.cc88
-rw-r--r--chromium/content/browser/blob_storage/blob_url_loader_factory.h88
-rw-r--r--chromium/content/browser/blob_storage/blob_url_unittest.cc36
-rw-r--r--chromium/content/browser/blob_storage/chrome_blob_storage_context.cc43
-rw-r--r--chromium/content/browser/blob_storage/chrome_blob_storage_context.h21
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc3
-rw-r--r--chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.h2
-rw-r--r--chromium/content/browser/bluetooth/tools/BUILD.gn1
-rw-r--r--chromium/content/browser/bluetooth/web_bluetooth_service_impl.cc4
-rw-r--r--chromium/content/browser/browser_child_process_host_impl.cc23
-rw-r--r--chromium/content/browser/browser_child_process_host_impl.h12
-rw-r--r--chromium/content/browser/browser_context.cc89
-rw-r--r--chromium/content/browser/browser_main.cc8
-rw-r--r--chromium/content/browser/browser_main.h5
-rw-r--r--chromium/content/browser/browser_main_loop.cc249
-rw-r--r--chromium/content/browser/browser_main_loop.h42
-rw-r--r--chromium/content/browser/browser_main_loop_unittest.cc4
-rw-r--r--chromium/content/browser/browser_main_runner_impl.cc9
-rw-r--r--chromium/content/browser/browser_main_runner_impl.h7
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_embedder.cc8
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_embedder.h6
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest.cc17
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest.h18
-rw-r--r--chromium/content/browser/browser_process_sub_thread.cc9
-rw-r--r--chromium/content/browser/browser_side_navigation_browsertest.cc404
-rw-r--r--chromium/content/browser/browsing_data/browsing_data_remover_impl.cc4
-rw-r--r--chromium/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc17
-rw-r--r--chromium/content/browser/cache_storage/README.md13
-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.cc85
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache.h7
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc79
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_context_impl.cc7
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_context_impl.h3
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_manager.cc9
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_manager.h19
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc2
-rw-r--r--chromium/content/browser/cache_storage/cache_storage_operation_unittest.cc2
-rw-r--r--chromium/content/browser/child_process_launcher.cc15
-rw-r--r--chromium/content/browser/child_process_launcher.h74
-rw-r--r--chromium/content/browser/child_process_launcher_helper.cc47
-rw-r--r--chromium/content/browser/child_process_launcher_helper.h51
-rw-r--r--chromium/content/browser/child_process_launcher_helper_android.cc79
-rw-r--r--chromium/content/browser/child_process_launcher_helper_fuchsia.cc30
-rw-r--r--chromium/content/browser/child_process_launcher_helper_linux.cc17
-rw-r--r--chromium/content/browser/child_process_launcher_helper_mac.cc16
-rw-r--r--chromium/content/browser/child_process_launcher_helper_posix.cc11
-rw-r--r--chromium/content/browser/child_process_launcher_helper_posix.h6
-rw-r--r--chromium/content/browser/child_process_launcher_helper_win.cc25
-rw-r--r--chromium/content/browser/child_process_security_policy_impl.cc259
-rw-r--r--chromium/content/browser/child_process_security_policy_impl.h25
-rw-r--r--chromium/content/browser/child_process_security_policy_unittest.cc210
-rw-r--r--chromium/content/browser/code_cache/generated_code_cache.cc383
-rw-r--r--chromium/content/browser/code_cache/generated_code_cache.h125
-rw-r--r--chromium/content/browser/code_cache/generated_code_cache_unittest.cc293
-rw-r--r--chromium/content/browser/compositor/external_begin_frame_controller_client_impl.cc45
-rw-r--r--chromium/content/browser/compositor/external_begin_frame_controller_client_impl.h45
-rw-r--r--chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc17
-rw-r--r--chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h7
-rw-r--r--chromium/content/browser/compositor/gpu_process_transport_factory.cc134
-rw-r--r--chromium/content/browser/compositor/gpu_process_transport_factory.h7
-rw-r--r--chromium/content/browser/compositor/gpu_vsync_begin_frame_source.cc87
-rw-r--r--chromium/content/browser/compositor/gpu_vsync_begin_frame_source.h52
-rw-r--r--chromium/content/browser/compositor/gpu_vsync_begin_frame_source_unittest.cc190
-rw-r--r--chromium/content/browser/compositor/image_transport_factory.h4
-rw-r--r--chromium/content/browser/compositor/image_transport_factory_browsertest.cc63
-rw-r--r--chromium/content/browser/compositor/in_process_display_client.cc73
-rw-r--r--chromium/content/browser/compositor/in_process_display_client.h54
-rw-r--r--chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc1
-rw-r--r--chromium/content/browser/compositor/owned_mailbox.cc4
-rw-r--r--chromium/content/browser/compositor/owned_mailbox.h3
-rw-r--r--chromium/content/browser/compositor/reflector_impl_unittest.cc1
-rw-r--r--chromium/content/browser/compositor/software_browser_compositor_output_surface.cc6
-rw-r--r--chromium/content/browser/compositor/viz_process_transport_factory.cc325
-rw-r--r--chromium/content/browser/compositor/viz_process_transport_factory.h66
-rw-r--r--chromium/content/browser/compositor/vulkan_browser_compositor_output_surface.cc4
-rw-r--r--chromium/content/browser/compositor/vulkan_browser_compositor_output_surface.h1
-rw-r--r--chromium/content/browser/content_service_browsertest.cc59
-rw-r--r--chromium/content/browser/content_service_delegate_impl.cc90
-rw-r--r--chromium/content/browser/content_service_delegate_impl.h56
-rw-r--r--chromium/content/browser/cookie_store/cookie_store_manager.cc21
-rw-r--r--chromium/content/browser/cookie_store/cookie_store_manager.h4
-rw-r--r--chromium/content/browser/cookie_store/cookie_store_manager_unittest.cc106
-rw-r--r--chromium/content/browser/dedicated_worker/dedicated_worker_host.cc57
-rw-r--r--chromium/content/browser/device_sensors/device_sensor_browsertest.cc39
-rw-r--r--chromium/content/browser/devtools/README.md3
-rw-r--r--chromium/content/browser/devtools/browser_devtools_agent_host.cc53
-rw-r--r--chromium/content/browser/devtools/browser_devtools_agent_host.h15
-rw-r--r--chromium/content/browser/devtools/devtools_agent_host_impl.cc69
-rw-r--r--chromium/content/browser/devtools/devtools_agent_host_impl.h27
-rw-r--r--chromium/content/browser/devtools/devtools_http_handler.cc5
-rw-r--r--chromium/content/browser/devtools/devtools_manager_unittest.cc43
-rw-r--r--chromium/content/browser/devtools/devtools_pipe_handler.cc11
-rw-r--r--chromium/content/browser/devtools/devtools_session.cc24
-rw-r--r--chromium/content/browser/devtools/devtools_session.h5
-rw-r--r--chromium/content/browser/devtools/devtools_url_interceptor_request_job.cc69
-rw-r--r--chromium/content/browser/devtools/devtools_url_interceptor_request_job.h4
-rw-r--r--chromium/content/browser/devtools/devtools_url_loader_interceptor.cc42
-rw-r--r--chromium/content/browser/devtools/devtools_url_request_interceptor.cc4
-rw-r--r--chromium/content/browser/devtools/devtools_video_consumer.cc42
-rw-r--r--chromium/content/browser/devtools/devtools_video_consumer.h28
-rw-r--r--chromium/content/browser/devtools/devtools_video_consumer_unittest.cc32
-rw-r--r--chromium/content/browser/devtools/protocol/browser_handler.cc22
-rw-r--r--chromium/content/browser/devtools/protocol/browser_handler.h2
-rw-r--r--chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc18
-rw-r--r--chromium/content/browser/devtools/protocol/emulation_handler.cc39
-rw-r--r--chromium/content/browser/devtools/protocol/emulation_handler.h16
-rw-r--r--chromium/content/browser/devtools/protocol/input_handler.cc43
-rw-r--r--chromium/content/browser/devtools/protocol/network_handler.cc231
-rw-r--r--chromium/content/browser/devtools/protocol/network_handler.h28
-rw-r--r--chromium/content/browser/devtools/protocol/page_handler.cc51
-rw-r--r--chromium/content/browser/devtools/protocol/page_handler.h9
-rw-r--r--chromium/content/browser/devtools/protocol/service_worker_handler.cc7
-rw-r--r--chromium/content/browser/devtools/protocol/system_info_handler.cc4
-rw-r--r--chromium/content/browser/devtools/protocol/target_handler.cc293
-rw-r--r--chromium/content/browser/devtools/protocol/target_handler.h16
-rw-r--r--chromium/content/browser/devtools/protocol/tracing_handler.cc99
-rw-r--r--chromium/content/browser/devtools/protocol/tracing_handler.h12
-rw-r--r--chromium/content/browser/devtools/protocol_config.json4
-rw-r--r--chromium/content/browser/devtools/render_frame_devtools_agent_host.cc80
-rw-r--r--chromium/content/browser/devtools/render_frame_devtools_agent_host.h15
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_agent_host.cc13
-rw-r--r--chromium/content/browser/devtools/service_worker_devtools_agent_host.h5
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_agent_host.cc13
-rw-r--r--chromium/content/browser/devtools/shared_worker_devtools_agent_host.h5
-rw-r--r--chromium/content/browser/devtools/target_registry.cc56
-rw-r--r--chromium/content/browser/devtools/target_registry.h44
-rw-r--r--chromium/content/browser/display_cutout/OWNERS3
-rw-r--r--chromium/content/browser/display_cutout/display_cutout_browsertest.cc468
-rw-r--r--chromium/content/browser/display_cutout/display_cutout_constants.h37
-rw-r--r--chromium/content/browser/display_cutout/display_cutout_host_impl.cc230
-rw-r--r--chromium/content/browser/display_cutout/display_cutout_host_impl.h100
-rw-r--r--chromium/content/browser/do_not_track_browsertest.cc193
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_area.cc2
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_browsertest.cc126
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_wrapper.cc20
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_context_wrapper.h8
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_database_unittest.cc5
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_namespace.cc4
-rw-r--r--chromium/content/browser/dom_storage/dom_storage_namespace.h3
-rw-r--r--chromium/content/browser/dom_storage/local_storage_context_mojo.cc195
-rw-r--r--chromium/content/browser/dom_storage/local_storage_context_mojo.h20
-rw-r--r--chromium/content/browser/dom_storage/local_storage_context_mojo_unittest.cc389
-rw-r--r--chromium/content/browser/dom_storage/session_storage_area_impl.cc (renamed from chromium/content/browser/dom_storage/session_storage_leveldb_wrapper.cc)109
-rw-r--r--chromium/content/browser/dom_storage/session_storage_area_impl.h (renamed from chromium/content/browser/dom_storage/session_storage_leveldb_wrapper.h)61
-rw-r--r--chromium/content/browser/dom_storage/session_storage_area_impl_unittest.cc (renamed from chromium/content/browser/dom_storage/session_storage_leveldb_wrapper_unittest.cc)206
-rw-r--r--chromium/content/browser/dom_storage/session_storage_context_mojo.cc217
-rw-r--r--chromium/content/browser/dom_storage/session_storage_context_mojo.h51
-rw-r--r--chromium/content/browser/dom_storage/session_storage_context_mojo_unittest.cc568
-rw-r--r--chromium/content/browser/dom_storage/session_storage_data_map.cc31
-rw-r--r--chromium/content/browser/dom_storage/session_storage_data_map.h31
-rw-r--r--chromium/content/browser/dom_storage/session_storage_data_map_unittest.cc44
-rw-r--r--chromium/content/browser/dom_storage/session_storage_database.cc20
-rw-r--r--chromium/content/browser/dom_storage/session_storage_database_unittest.cc20
-rw-r--r--chromium/content/browser/dom_storage/session_storage_metadata.cc3
-rw-r--r--chromium/content/browser/dom_storage/session_storage_namespace_impl.cc11
-rw-r--r--chromium/content/browser/dom_storage/session_storage_namespace_impl.h8
-rw-r--r--chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo.cc48
-rw-r--r--chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo.h39
-rw-r--r--chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo_unittest.cc191
-rw-r--r--chromium/content/browser/dom_storage/storage_area_impl.cc (renamed from chromium/content/browser/leveldb_wrapper_impl.cc)251
-rw-r--r--chromium/content/browser/dom_storage/storage_area_impl.h (renamed from chromium/content/browser/leveldb_wrapper_impl.h)89
-rw-r--r--chromium/content/browser/dom_storage/storage_area_impl_unittest.cc (renamed from chromium/content/browser/leveldb_wrapper_impl_unittest.cc)587
-rw-r--r--chromium/content/browser/download/blob_download_url_loader_factory_getter.cc38
-rw-r--r--chromium/content/browser/download/blob_download_url_loader_factory_getter.h40
-rw-r--r--chromium/content/browser/download/download_browsertest.cc303
-rw-r--r--chromium/content/browser/download/download_manager_impl.cc201
-rw-r--r--chromium/content/browser/download/download_manager_impl.h37
-rw-r--r--chromium/content/browser/download/download_manager_impl_unittest.cc69
-rw-r--r--chromium/content/browser/download/download_request_core.cc26
-rw-r--r--chromium/content/browser/download/download_request_core.h4
-rw-r--r--chromium/content/browser/download/download_request_core_unittest.cc3
-rw-r--r--chromium/content/browser/download/download_resource_handler.cc60
-rw-r--r--chromium/content/browser/download/download_resource_handler.h12
-rw-r--r--chromium/content/browser/download/download_utils.cc4
-rw-r--r--chromium/content/browser/download/file_download_url_loader_factory_getter.cc44
-rw-r--r--chromium/content/browser/download/file_download_url_loader_factory_getter.h36
-rw-r--r--chromium/content/browser/download/mhtml_generation_browsertest.cc2
-rw-r--r--chromium/content/browser/download/save_package.cc7
-rw-r--r--chromium/content/browser/download/url_downloader.cc40
-rw-r--r--chromium/content/browser/download/url_downloader.h9
-rw-r--r--chromium/content/browser/download/url_downloader_factory.cc3
-rw-r--r--chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc33
-rw-r--r--chromium/content/browser/download/web_ui_download_url_loader_factory_getter.h40
-rw-r--r--chromium/content/browser/file_url_loader_factory.cc13
-rw-r--r--chromium/content/browser/fileapi/browser_file_system_helper.cc6
-rw-r--r--chromium/content/browser/fileapi/file_system_url_loader_factory.cc13
-rw-r--r--chromium/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc32
-rw-r--r--chromium/content/browser/find_request_manager_browsertest.cc9
-rw-r--r--chromium/content/browser/frame_host/blocked_scheme_navigation_browsertest.cc6
-rw-r--r--chromium/content/browser/frame_host/cross_process_frame_connector.cc76
-rw-r--r--chromium/content/browser/frame_host/cross_process_frame_connector.h9
-rw-r--r--chromium/content/browser/frame_host/frame_navigation_entry.h12
-rw-r--r--chromium/content/browser/frame_host/frame_tree.cc4
-rw-r--r--chromium/content/browser/frame_host/frame_tree.h1
-rw-r--r--chromium/content/browser/frame_host/frame_tree_node.cc32
-rw-r--r--chromium/content/browser/frame_host/frame_tree_node.h54
-rw-r--r--chromium/content/browser/frame_host/frame_tree_unittest.cc68
-rw-r--r--chromium/content/browser/frame_host/interstitial_page_impl.cc7
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_delegate.h9
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl.cc799
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl.h61
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc187
-rw-r--r--chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc69
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_impl.cc49
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_impl.h36
-rw-r--r--chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc23
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl.cc14
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl.h12
-rw-r--r--chromium/content/browser/frame_host/navigation_handle_impl_browsertest.cc2
-rw-r--r--chromium/content/browser/frame_host/navigation_request.cc298
-rw-r--r--chromium/content/browser/frame_host/navigation_request.h63
-rw-r--r--chromium/content/browser/frame_host/navigation_request_info.cc11
-rw-r--r--chromium/content/browser/frame_host/navigation_request_info.h35
-rw-r--r--chromium/content/browser/frame_host/navigator.cc25
-rw-r--r--chromium/content/browser/frame_host/navigator.h43
-rw-r--r--chromium/content/browser/frame_host/navigator_delegate.cc3
-rw-r--r--chromium/content/browser/frame_host/navigator_delegate.h8
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.cc375
-rw-r--r--chromium/content/browser/frame_host/navigator_impl.h46
-rw-r--r--chromium/content/browser/frame_host/navigator_impl_unittest.cc92
-rw-r--r--chromium/content/browser/frame_host/origin_policy_throttle.cc249
-rw-r--r--chromium/content/browser/frame_host/origin_policy_throttle.h86
-rw-r--r--chromium/content/browser/frame_host/origin_policy_throttle_unittest.cc155
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_android.cc8
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_delegate.cc6
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_delegate.h11
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc4
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl.cc752
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl.h121
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_impl_browsertest.cc7
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager.cc168
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager.h16
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager_browsertest.cc555
-rw-r--r--chromium/content/browser/frame_host/render_frame_host_manager_unittest.cc26
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter.cc108
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter.h7
-rw-r--r--chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc30
-rw-r--r--chromium/content/browser/frame_host/render_frame_proxy_host.cc35
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest.cc64
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest.h10
-rw-r--r--chromium/content/browser/frame_host/render_widget_host_view_guest_unittest.cc89
-rw-r--r--chromium/content/browser/frame_host/webui_navigation_browsertest.cc220
-rw-r--r--chromium/content/browser/generic_sensor/generic_sensor_browsertest.cc50
-rw-r--r--chromium/content/browser/generic_sensor/sensor_provider_proxy_impl.cc57
-rw-r--r--chromium/content/browser/generic_sensor/sensor_provider_proxy_impl.h17
-rw-r--r--chromium/content/browser/geolocation/geolocation_service_impl.cc22
-rw-r--r--chromium/content/browser/geolocation/geolocation_service_impl.h11
-rw-r--r--chromium/content/browser/geolocation/geolocation_service_impl_unittest.cc23
-rw-r--r--chromium/content/browser/gpu/OWNERS1
-rw-r--r--chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc23
-rw-r--r--chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc13
-rw-r--r--chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h9
-rw-r--r--chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc115
-rw-r--r--chromium/content/browser/gpu/ca_transaction_gpu_coordinator.h60
-rw-r--r--chromium/content/browser/gpu/compositor_util.cc23
-rw-r--r--chromium/content/browser/gpu/gpu_client_impl.cc97
-rw-r--r--chromium/content/browser/gpu/gpu_client_impl.h62
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl.cc33
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl.h44
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private.cc179
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private.h33
-rw-r--r--chromium/content/browser/gpu/gpu_data_manager_impl_private_unittest.cc42
-rw-r--r--chromium/content/browser/gpu/gpu_internals_ui.cc74
-rw-r--r--chromium/content/browser/gpu/gpu_process_host.cc345
-rw-r--r--chromium/content/browser/gpu/gpu_process_host.h42
-rw-r--r--chromium/content/browser/host_zoom_map_impl.cc19
-rw-r--r--chromium/content/browser/host_zoom_map_impl.h6
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_backing_store.cc4
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_backing_store_unittest.cc10
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_impl.cc9
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_impl.h4
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc50
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_internals_ui.cc2
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue.cc2
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue.h4
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue_unittest.cc18
-rw-r--r--chromium/content/browser/indexed_db/indexed_db_tombstone_sweeper_unittest.cc2
-rw-r--r--chromium/content/browser/isolated_origin_browsertest.cc31
-rw-r--r--chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.cc11
-rw-r--r--chromium/content/browser/keyboard_lock_browsertest.cc45
-rw-r--r--chromium/content/browser/linux_ipc_browsertest.cc91
-rw-r--r--chromium/content/browser/loader/cors_file_origin_browsertest.cc86
-rw-r--r--chromium/content/browser/loader/cross_site_document_blocking_browsertest.cc235
-rw-r--r--chromium/content/browser/loader/cross_site_document_resource_handler.cc60
-rw-r--r--chromium/content/browser/loader/cross_site_document_resource_handler.h4
-rw-r--r--chromium/content/browser/loader/cross_site_document_resource_handler_unittest.cc2
-rw-r--r--chromium/content/browser/loader/data_pipe_to_source_stream.cc6
-rw-r--r--chromium/content/browser/loader/data_pipe_to_source_stream.h5
-rw-r--r--chromium/content/browser/loader/detachable_resource_handler.cc15
-rw-r--r--chromium/content/browser/loader/detachable_resource_handler.h1
-rw-r--r--chromium/content/browser/loader/download_utils_impl.cc (renamed from chromium/content/browser/loader/navigation_loader_util.cc)11
-rw-r--r--chromium/content/browser/loader/download_utils_impl.h22
-rw-r--r--chromium/content/browser/loader/downloaded_temp_file_impl.cc30
-rw-r--r--chromium/content/browser/loader/downloaded_temp_file_impl.h40
-rw-r--r--chromium/content/browser/loader/intercepting_resource_handler.cc8
-rw-r--r--chromium/content/browser/loader/layered_resource_handler.cc5
-rw-r--r--chromium/content/browser/loader/layered_resource_handler.h1
-rw-r--r--chromium/content/browser/loader/loader_browsertest.cc50
-rw-r--r--chromium/content/browser/loader/merkle_integrity_source_stream.cc2
-rw-r--r--chromium/content/browser/loader/merkle_integrity_source_stream_unittest.cc16
-rw-r--r--chromium/content/browser/loader/mime_sniffing_resource_handler.cc9
-rw-r--r--chromium/content/browser/loader/mock_resource_loader.cc9
-rw-r--r--chromium/content/browser/loader/mojo_async_resource_handler.cc90
-rw-r--r--chromium/content/browser/loader/mojo_async_resource_handler.h13
-rw-r--r--chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc74
-rw-r--r--chromium/content/browser/loader/navigation_loader_util.h34
-rw-r--r--chromium/content/browser/loader/navigation_url_loader.h10
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl.cc272
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl.h8
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_impl_unittest.cc97
-rw-r--r--chromium/content/browser/loader/navigation_url_loader_unittest.cc6
-rw-r--r--chromium/content/browser/loader/null_resource_controller.cc9
-rw-r--r--chromium/content/browser/loader/null_resource_controller.h2
-rw-r--r--chromium/content/browser/loader/prefetch_browsertest.cc34
-rw-r--r--chromium/content/browser/loader/prefetch_url_loader.cc36
-rw-r--r--chromium/content/browser/loader/prefetch_url_loader.h18
-rw-r--r--chromium/content/browser/loader/prefetch_url_loader_service.cc55
-rw-r--r--chromium/content/browser/loader/prefetch_url_loader_service.h27
-rw-r--r--chromium/content/browser/loader/redirect_to_file_resource_handler.cc376
-rw-r--r--chromium/content/browser/loader/redirect_to_file_resource_handler.h138
-rw-r--r--chromium/content/browser/loader/redirect_to_file_resource_handler_unittest.cc925
-rw-r--r--chromium/content/browser/loader/resource_buffer.cc173
-rw-r--r--chromium/content/browser/loader/resource_buffer.h122
-rw-r--r--chromium/content/browser/loader/resource_buffer_unittest.cc137
-rw-r--r--chromium/content/browser/loader/resource_controller.h11
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_impl.cc195
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_impl.h52
-rw-r--r--chromium/content/browser/loader/resource_dispatcher_host_unittest.cc153
-rw-r--r--chromium/content/browser/loader/resource_handler.cc5
-rw-r--r--chromium/content/browser/loader/resource_handler.h8
-rw-r--r--chromium/content/browser/loader/resource_hints_impl.cc38
-rw-r--r--chromium/content/browser/loader/resource_loader.cc111
-rw-r--r--chromium/content/browser/loader/resource_loader.h26
-rw-r--r--chromium/content/browser/loader/resource_loader_unittest.cc3
-rw-r--r--chromium/content/browser/loader/resource_message_filter.cc31
-rw-r--r--chromium/content/browser/loader/resource_message_filter.h2
-rw-r--r--chromium/content/browser/loader/resource_request_info_impl.cc29
-rw-r--r--chromium/content/browser/loader/resource_request_info_impl.h41
-rw-r--r--chromium/content/browser/loader/resource_scheduler_filter.cc20
-rw-r--r--chromium/content/browser/loader/resource_scheduler_filter.h23
-rw-r--r--chromium/content/browser/loader/stream_resource_handler.cc4
-rw-r--r--chromium/content/browser/loader/stream_resource_handler.h2
-rw-r--r--chromium/content/browser/loader/temporary_file_stream.cc71
-rw-r--r--chromium/content/browser/loader/temporary_file_stream.h46
-rw-r--r--chromium/content/browser/loader/temporary_file_stream_unittest.cc121
-rw-r--r--chromium/content/browser/loader/test_resource_handler.cc13
-rw-r--r--chromium/content/browser/loader/test_resource_handler.h12
-rw-r--r--chromium/content/browser/loader/url_loader_factory_impl_unittest.cc131
-rw-r--r--chromium/content/browser/loader/wake_lock_resource_throttle.cc70
-rw-r--r--chromium/content/browser/loader/wake_lock_resource_throttle.h46
-rw-r--r--chromium/content/browser/manifest/manifest_icon_downloader.cc1
-rw-r--r--chromium/content/browser/manifest/manifest_icon_selector.cc86
-rw-r--r--chromium/content/browser/manifest/manifest_icon_selector_unittest.cc499
-rw-r--r--chromium/content/browser/media/android/browser_media_player_manager.cc115
-rw-r--r--chromium/content/browser/media/android/browser_media_player_manager.h14
-rw-r--r--chromium/content/browser/media/android/browser_surface_view_manager.cc130
-rw-r--r--chromium/content/browser/media/android/browser_surface_view_manager.h60
-rw-r--r--chromium/content/browser/media/android/media_player_renderer.cc5
-rw-r--r--chromium/content/browser/media/android/media_player_renderer.h1
-rw-r--r--chromium/content/browser/media/android/media_web_contents_observer_android.cc38
-rw-r--r--chromium/content/browser/media/android/media_web_contents_observer_android.h11
-rw-r--r--chromium/content/browser/media/audible_metrics_unittest.cc4
-rw-r--r--chromium/content/browser/media/audio_input_stream_broker.cc12
-rw-r--r--chromium/content/browser/media/audio_input_stream_broker.h4
-rw-r--r--chromium/content/browser/media/audio_input_stream_broker_unittest.cc5
-rw-r--r--chromium/content/browser/media/audio_log_factory.cc25
-rw-r--r--chromium/content/browser/media/audio_log_factory.h28
-rw-r--r--chromium/content/browser/media/audio_loopback_stream_broker.cc2
-rw-r--r--chromium/content/browser/media/audio_loopback_stream_broker.h2
-rw-r--r--chromium/content/browser/media/audio_loopback_stream_broker_unittest.cc11
-rw-r--r--chromium/content/browser/media/audio_output_stream_broker.cc10
-rw-r--r--chromium/content/browser/media/audio_output_stream_broker.h3
-rw-r--r--chromium/content/browser/media/audio_output_stream_broker_unittest.cc4
-rw-r--r--chromium/content/browser/media/audio_stream_monitor.cc2
-rw-r--r--chromium/content/browser/media/capture/aura_window_capture_machine.cc485
-rw-r--r--chromium/content/browser/media/capture/aura_window_capture_machine.h150
-rw-r--r--chromium/content/browser/media/capture/content_capture_device_browsertest_base.cc2
-rw-r--r--chromium/content/browser/media/capture/cursor_renderer.cc6
-rw-r--r--chromium/content/browser/media/capture/cursor_renderer.h4
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device_aura.cc82
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device_aura.h48
-rw-r--r--chromium/content/browser/media/capture/desktop_capture_device_aura_unittest.cc175
-rw-r--r--chromium/content/browser/media/capture/fake_webcontent_capture_machine.cc35
-rw-r--r--chromium/content/browser/media/capture/fake_webcontent_capture_machine.h41
-rw-r--r--chromium/content/browser/media/capture/frame_sink_video_capture_device.cc26
-rw-r--r--chromium/content/browser/media/capture/frame_sink_video_capture_device.h7
-rw-r--r--chromium/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc10
-rw-r--r--chromium/content/browser/media/capture/lame_window_capturer_chromeos.cc4
-rw-r--r--chromium/content/browser/media/capture/lame_window_capturer_chromeos.h4
-rw-r--r--chromium/content/browser/media/capture/screen_capture_device_android.cc52
-rw-r--r--chromium/content/browser/media/capture/screen_capture_device_android.h15
-rw-r--r--chromium/content/browser/media/capture/web_contents_audio_input_stream.cc23
-rw-r--r--chromium/content/browser/media/capture/web_contents_video_capture_device.cc15
-rw-r--r--chromium/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc8
-rw-r--r--chromium/content/browser/media/cdm_registry_impl_unittest.cc125
-rw-r--r--chromium/content/browser/media/encrypted_media_browsertest.cc111
-rw-r--r--chromium/content/browser/media/flinging_renderer.cc3
-rw-r--r--chromium/content/browser/media/flinging_renderer.h6
-rw-r--r--chromium/content/browser/media/flinging_renderer_unittest.cc6
-rw-r--r--chromium/content/browser/media/key_system_support_impl.cc134
-rw-r--r--chromium/content/browser/media/key_system_support_impl_unittest.cc92
-rw-r--r--chromium/content/browser/media/media_autoplay_browsertest.cc66
-rw-r--r--chromium/content/browser/media/media_canplaytype_browsertest.cc24
-rw-r--r--chromium/content/browser/media/media_internals.cc100
-rw-r--r--chromium/content/browser/media/media_internals.h16
-rw-r--r--chromium/content/browser/media/media_source_browsertest.cc29
-rw-r--r--chromium/content/browser/media/media_web_contents_observer.cc92
-rw-r--r--chromium/content/browser/media/media_web_contents_observer.h4
-rw-r--r--chromium/content/browser/media/midi_host.cc4
-rw-r--r--chromium/content/browser/media/mojo_audio_logging_adapter.cc49
-rw-r--r--chromium/content/browser/media/mojo_audio_logging_adapter.h45
-rw-r--r--chromium/content/browser/media/session/media_session_controller.cc23
-rw-r--r--chromium/content/browser/media/session/media_session_controller_unittest.cc15
-rw-r--r--chromium/content/browser/media/session/media_session_controllers_manager.cc2
-rw-r--r--chromium/content/browser/media/session/media_session_controllers_manager_unittest.cc4
-rw-r--r--chromium/content/browser/media/session/media_session_impl_browsertest.cc2
-rw-r--r--chromium/content/browser/media/session/media_session_impl_uma_unittest.cc2
-rw-r--r--chromium/content/browser/media/session/media_session_service_impl_browsertest.cc27
-rw-r--r--chromium/content/browser/media/session/media_session_uma_helper_unittest.cc2
-rw-r--r--chromium/content/browser/memory/memory_coordinator_impl_browsertest.cc19
-rw-r--r--chromium/content/browser/mojo_sandbox_browsertest.cc1
-rw-r--r--chromium/content/browser/net/network_quality_observer_impl.cc20
-rw-r--r--chromium/content/browser/net/network_quality_observer_impl_unittest.cc2
-rw-r--r--chromium/content/browser/net/quota_policy_cookie_store.cc87
-rw-r--r--chromium/content/browser/net/quota_policy_cookie_store.h33
-rw-r--r--chromium/content/browser/net/reporting_service_proxy.cc40
-rw-r--r--chromium/content/browser/net_info_browsertest.cc2
-rw-r--r--chromium/content/browser/network_service_browsertest.cc8
-rw-r--r--chromium/content/browser/network_service_client.cc82
-rw-r--r--chromium/content/browser/network_service_client.h21
-rw-r--r--chromium/content/browser/network_service_client_unittest.cc192
-rw-r--r--chromium/content/browser/network_service_instance.cc3
-rw-r--r--chromium/content/browser/notifications/blink_notification_service_impl.cc258
-rw-r--r--chromium/content/browser/notifications/blink_notification_service_impl.h44
-rw-r--r--chromium/content/browser/notifications/blink_notification_service_impl_unittest.cc113
-rw-r--r--chromium/content/browser/notifications/notification_database.cc110
-rw-r--r--chromium/content/browser/notifications/notification_database.h25
-rw-r--r--chromium/content/browser/notifications/notification_database_data_conversions.cc24
-rw-r--r--chromium/content/browser/notifications/notification_database_data_unittest.cc30
-rw-r--r--chromium/content/browser/notifications/notification_database_unittest.cc94
-rw-r--r--chromium/content/browser/notifications/notification_event_dispatcher_impl.cc151
-rw-r--r--chromium/content/browser/notifications/notification_event_dispatcher_impl.h5
-rw-r--r--chromium/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc43
-rw-r--r--chromium/content/browser/notifications/platform_notification_context_impl.cc42
-rw-r--r--chromium/content/browser/notifications/platform_notification_context_impl.h29
-rw-r--r--chromium/content/browser/notifications/platform_notification_context_unittest.cc62
-rw-r--r--chromium/content/browser/oop_browsertest.cc22
-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_browsertest.cc22
-rw-r--r--chromium/content/browser/payments/payment_app_content_unittest_base.cc30
-rw-r--r--chromium/content/browser/payments/payment_app_database.cc100
-rw-r--r--chromium/content/browser/payments/payment_app_database.h50
-rw-r--r--chromium/content/browser/payments/payment_app_info_fetcher.cc8
-rw-r--r--chromium/content/browser/payments/payment_app_provider_impl.cc64
-rw-r--r--chromium/content/browser/payments/payment_app_provider_impl_unittest.cc4
-rw-r--r--chromium/content/browser/payments/payment_instrument_icon_fetcher.cc18
-rw-r--r--chromium/content/browser/payments/payment_instrument_icon_fetcher.h2
-rw-r--r--chromium/content/browser/performance_memory_browsertest.cc56
-rw-r--r--chromium/content/browser/permissions/permission_controller_impl.cc126
-rw-r--r--chromium/content/browser/permissions/permission_controller_impl.h72
-rw-r--r--chromium/content/browser/permissions/permission_service_context.cc24
-rw-r--r--chromium/content/browser/permissions/permission_service_impl.cc40
-rw-r--r--chromium/content/browser/picture_in_picture/overlay_surface_embedder.cc57
-rw-r--r--chromium/content/browser/picture_in_picture/overlay_surface_embedder.h9
-rw-r--r--chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc105
-rw-r--r--chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h17
-rw-r--r--chromium/content/browser/plugin_service_impl.cc8
-rw-r--r--chromium/content/browser/plugin_service_impl_unittest.cc25
-rw-r--r--chromium/content/browser/pointer_lock_browsertest.cc82
-rw-r--r--chromium/content/browser/pointer_lock_browsertest_mac.mm14
-rw-r--r--chromium/content/browser/power_monitor_browsertest.cc10
-rw-r--r--chromium/content/browser/ppapi_plugin_process_host.cc1
-rw-r--r--chromium/content/browser/presentation/presentation_service_impl_unittest.cc2
-rw-r--r--chromium/content/browser/process_internals/process_internals.mojom5
-rw-r--r--chromium/content/browser/process_internals/process_internals_handler_impl.cc13
-rw-r--r--chromium/content/browser/process_internals/process_internals_handler_impl.h2
-rw-r--r--chromium/content/browser/process_internals/process_internals_ui.cc2
-rw-r--r--chromium/content/browser/push_messaging/push_messaging_manager.cc97
-rw-r--r--chromium/content/browser/push_messaging/push_messaging_manager.h17
-rw-r--r--chromium/content/browser/push_messaging/push_messaging_router.cc66
-rw-r--r--chromium/content/browser/push_messaging/push_messaging_router.h8
-rw-r--r--chromium/content/browser/renderer_host/OWNERS4
-rw-r--r--chromium/content/browser/renderer_host/browser_compositor_view_mac.h36
-rw-r--r--chromium/content/browser/renderer_host/browser_compositor_view_mac.mm305
-rw-r--r--chromium/content/browser/renderer_host/clipboard_host_impl.cc138
-rw-r--r--chromium/content/browser/renderer_host/clipboard_host_impl.h23
-rw-r--r--chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc62
-rw-r--r--chromium/content/browser/renderer_host/compositor_impl_android.cc245
-rw-r--r--chromium/content/browser/renderer_host/compositor_impl_android.h31
-rw-r--r--chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc101
-rw-r--r--chromium/content/browser/renderer_host/delegated_frame_host.cc86
-rw-r--r--chromium/content/browser/renderer_host/delegated_frame_host.h26
-rw-r--r--chromium/content/browser/renderer_host/display_util.cc4
-rw-r--r--chromium/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc5
-rw-r--r--chromium/content/browser/renderer_host/font_utils_linux.cc265
-rw-r--r--chromium/content/browser/renderer_host/font_utils_linux.h22
-rw-r--r--chromium/content/browser/renderer_host/frame_connector_delegate.h7
-rw-r--r--chromium/content/browser/renderer_host/frame_metadata_util.cc29
-rw-r--r--chromium/content/browser/renderer_host/frame_metadata_util.h10
-rw-r--r--chromium/content/browser/renderer_host/input/README.md23
-rw-r--r--chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc14
-rw-r--r--chromium/content/browser/renderer_host/input/fling_browsertest.cc90
-rw-r--r--chromium/content/browser/renderer_host/input/fling_controller.cc47
-rw-r--r--chromium/content/browser/renderer_host/input/fling_controller.h2
-rw-r--r--chromium/content/browser/renderer_host/input/fling_controller_unittest.cc18
-rw-r--r--chromium/content/browser/renderer_host/input/fling_scheduler.cc1
-rw-r--r--chromium/content/browser/renderer_host/input/fling_scheduler.h6
-rw-r--r--chromium/content/browser/renderer_host/input/fling_scheduler_android.cc83
-rw-r--r--chromium/content/browser/renderer_host/input/fling_scheduler_android.h55
-rw-r--r--chromium/content/browser/renderer_host/input/fling_scheduler_base.h20
-rw-r--r--chromium/content/browser/renderer_host/input/gesture_event_queue.cc26
-rw-r--r--chromium/content/browser/renderer_host/input/gesture_event_queue.h11
-rw-r--r--chromium/content/browser/renderer_host/input/gesture_event_queue_unittest.cc69
-rw-r--r--chromium/content/browser/renderer_host/input/input_router.h11
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl.cc69
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl.h17
-rw-r--r--chromium/content/browser/renderer_host/input/input_router_impl_unittest.cc398
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc120
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.cc145
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_wheel_event_queue.h26
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_wheel_event_queue_unittest.cc520
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.cc5
-rw-r--r--chromium/content/browser/renderer_host/input/mouse_wheel_phase_handler.h6
-rw-r--r--chromium/content/browser/renderer_host/input/passthrough_touch_event_queue_unittest.cc6
-rw-r--r--chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.cc98
-rw-r--r--chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker.h9
-rw-r--r--chromium/content/browser/renderer_host/input/render_widget_host_latency_tracker_unittest.cc269
-rw-r--r--chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc100
-rw-r--r--chromium/content/browser/renderer_host/input/stylus_text_selector.cc2
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_controller_unittest.cc39
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_gesture_target_base.cc2
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc3
-rw-r--r--chromium/content/browser/renderer_host/input/synthetic_pointer_action_unittest.cc33
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_browsertest.cc71
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_filter.cc137
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_filter.h26
-rw-r--r--chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc951
-rw-r--r--chromium/content/browser/renderer_host/input/touch_emulator.cc4
-rw-r--r--chromium/content/browser/renderer_host/input/touch_emulator.h1
-rw-r--r--chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc3
-rw-r--r--chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.h2
-rw-r--r--chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc12
-rw-r--r--chromium/content/browser/renderer_host/input/touchpad_pinch_browsertest.cc187
-rw-r--r--chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue.cc161
-rw-r--r--chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue.h76
-rw-r--r--chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue_unittest.cc350
-rw-r--r--chromium/content/browser/renderer_host/input/web_input_event_builders_mac.mm4
-rw-r--r--chromium/content/browser/renderer_host/input/wheel_scroll_latching_browsertest.cc306
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_stream_handle.cc5
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_stream_handle.h2
-rw-r--r--chromium/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/media/audio_output_authorization_handler.cc8
-rw-r--r--chromium/content/browser/renderer_host/media/audio_service_listener.cc30
-rw-r--r--chromium/content/browser/renderer_host/media/audio_service_listener.h4
-rw-r--r--chromium/content/browser/renderer_host/media/audio_service_listener_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/media/fake_video_capture_device_launcher.cc1
-rw-r--r--chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc18
-rw-r--r--chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.h1
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_dispatcher_host.cc31
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_manager.cc108
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_manager.h32
-rw-r--r--chromium/content/browser/renderer_host/media/media_devices_manager_unittest.cc260
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_manager.cc100
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_manager.h15
-rw-r--r--chromium/content/browser/renderer_host/media/media_stream_ui_proxy_unittest.cc64
-rw-r--r--chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.cc4
-rw-r--r--chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc15
-rw-r--r--chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc5
-rw-r--r--chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc2
-rw-r--r--chromium/content/browser/renderer_host/media/service_video_capture_device_launcher_unittest.cc1
-rw-r--r--chromium/content/browser/renderer_host/media/service_video_capture_provider.cc57
-rw-r--r--chromium/content/browser/renderer_host/media/service_video_capture_provider.h14
-rw-r--r--chromium/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc18
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_browsertest.cc21
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_controller.cc3
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_controller_unittest.cc14
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_dependencies.cc53
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_dependencies.h25
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc336
-rw-r--r--chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h123
-rw-r--r--chromium/content/browser/renderer_host/overscroll_controller.cc12
-rw-r--r--chromium/content/browser/renderer_host/overscroll_controller.h2
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc10
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h5
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc4
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc6
-rw-r--r--chromium/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc13
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc2
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_gamepad_host.cc7
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc15
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.cc26
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h11
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc34
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h11
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_android.cc16
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc14
-rw-r--r--chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_android.cc20
-rw-r--r--chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc17
-rw-r--r--chromium/content/browser/renderer_host/plugin_registry_impl.cc87
-rw-r--r--chromium/content/browser/renderer_host/plugin_registry_impl.h43
-rw-r--r--chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc15
-rw-r--r--chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h3
-rw-r--r--chromium/content/browser/renderer_host/render_message_filter.cc4
-rw-r--r--chromium/content/browser/renderer_host/render_message_filter.h5
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_browsertest.cc2
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_impl.cc582
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_impl.h27
-rw-r--r--chromium/content/browser/renderer_host/render_process_host_unittest.cc49
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate.cc4
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_delegate.h7
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_factory.cc9
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_factory.h2
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_impl.cc72
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_impl.h17
-rw-r--r--chromium/content/browser/renderer_host/render_view_host_unittest.cc1
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_browsertest.cc82
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_delegate.cc11
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_delegate.h29
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.cc346
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_impl.h71
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_input_event_router.cc285
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_input_event_router.h8
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge.h126
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h99
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.mm (renamed from chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge.mm)158
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_ns_view_client.h163
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h3
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_unittest.cc348
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_android.cc569
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_android.h54
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura.cc110
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura.h18
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc1239
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_base.cc92
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_base.h35
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_browsertest.cc3
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_child_frame.cc244
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_child_frame.h45
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc41
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc89
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_cocoa.h30
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_cocoa.mm353
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_event_handler.cc160
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_event_handler.h2
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac.h212
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac.mm498
-rw-r--r--chromium/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.mm4
-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.mm293
-rw-r--r--chromium/content/browser/renderer_host/render_widget_targeter.cc18
-rw-r--r--chromium/content/browser/renderer_host/ui_events_helper.cc5
-rw-r--r--chromium/content/browser/renderer_host/web_database_host_impl.cc4
-rw-r--r--chromium/content/browser/renderer_interface_binders.cc22
-rw-r--r--chromium/content/browser/resources/gpu/OWNERS3
-rw-r--r--chromium/content/browser/resources/gpu/info_view.js1
-rw-r--r--chromium/content/browser/resources/histograms/histograms_internals.html2
-rw-r--r--chromium/content/browser/resources/media/peer_connection_update_table.js8
-rw-r--r--chromium/content/browser/resources/process/process_internals.html2
-rw-r--r--chromium/content/browser/resources/process/process_internals.js5
-rw-r--r--chromium/content/browser/resources/service_worker/serviceworker_internals.js4
-rw-r--r--chromium/content/browser/sandbox_ipc_linux.cc253
-rw-r--r--chromium/content/browser/sandbox_ipc_linux.h38
-rw-r--r--chromium/content/browser/sandbox_parameters_mac.mm5
-rw-r--r--chromium/content/browser/screen_orientation/screen_orientation_delegate_android.cc9
-rw-r--r--chromium/content/browser/security_exploit_browsertest.cc95
-rw-r--r--chromium/content/browser/service_manager/common_browser_interfaces.cc51
-rw-r--r--chromium/content/browser/service_manager/service_manager_context.cc288
-rw-r--r--chromium/content/browser/service_manager/service_manager_context.h17
-rw-r--r--chromium/content/browser/service_worker/OWNERS8
-rw-r--r--chromium/content/browser/service_worker/README.md44
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance.cc327
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance.h93
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc535
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_registry.h2
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_test_helper.cc293
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_test_helper.h155
-rw-r--r--chromium/content/browser/service_worker/service_worker_browsertest.cc512
-rw-r--r--chromium/content/browser/service_worker/service_worker_client_utils.cc10
-rw-r--r--chromium/content/browser/service_worker/service_worker_client_utils.h4
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core.cc110
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core.h58
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core_observer.h8
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core_unittest.cc19
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_request_handler.cc3
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_request_handler_unittest.cc12
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_unittest.cc65
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_watcher.cc6
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_watcher.h8
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_watcher_unittest.cc19
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_wrapper.cc242
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_wrapper.h38
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc132
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler.h15
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.cc17
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_dispatcher_host.cc173
-rw-r--r--chromium/content/browser/service_worker/service_worker_dispatcher_host.h87
-rw-r--r--chromium/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc292
-rw-r--r--chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc79
-rw-r--r--chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h26
-rw-r--r--chromium/content/browser/service_worker/service_worker_installed_script_loader.cc12
-rw-r--r--chromium/content/browser/service_worker/service_worker_installed_script_loader.h4
-rw-r--r--chromium/content/browser/service_worker/service_worker_installed_scripts_sender.cc3
-rw-r--r--chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc2
-rw-r--r--chromium/content/browser/service_worker/service_worker_internals_ui.cc41
-rw-r--r--chromium/content/browser/service_worker/service_worker_internals_ui.h7
-rw-r--r--chromium/content/browser/service_worker/service_worker_job_unittest.cc229
-rw-r--r--chromium/content/browser/service_worker/service_worker_lifetime_tracker_unittest.cc2
-rw-r--r--chromium/content/browser/service_worker/service_worker_metrics.cc337
-rw-r--r--chromium/content/browser/service_worker/service_worker_metrics.h176
-rw-r--r--chromium/content/browser/service_worker/service_worker_metrics_unittest.cc251
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc18
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_loader.cc181
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_loader.h19
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc186
-rw-r--r--chromium/content/browser/service_worker/service_worker_new_script_loader.cc195
-rw-r--r--chromium/content/browser/service_worker/service_worker_new_script_loader.h69
-rw-r--r--chromium/content/browser/service_worker/service_worker_new_script_loader_unittest.cc598
-rw-r--r--chromium/content/browser/service_worker/service_worker_object_host.cc (renamed from chromium/content/browser/service_worker/service_worker_handle.cc)70
-rw-r--r--chromium/content/browser/service_worker/service_worker_object_host.h (renamed from chromium/content/browser/service_worker/service_worker_handle.h)71
-rw-r--r--chromium/content/browser/service_worker/service_worker_object_host_unittest.cc (renamed from chromium/content/browser/service_worker/service_worker_handle_unittest.cc)166
-rw-r--r--chromium/content/browser/service_worker/service_worker_ping_controller.cc68
-rw-r--r--chromium/content/browser/service_worker/service_worker_ping_controller.h54
-rw-r--r--chromium/content/browser/service_worker/service_worker_process_manager.cc17
-rw-r--r--chromium/content/browser/service_worker/service_worker_process_manager.h17
-rw-r--r--chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc45
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host.cc366
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host.h141
-rw-r--r--chromium/content/browser/service_worker/service_worker_provider_host_unittest.cc414
-rw-r--r--chromium/content/browser/service_worker/service_worker_read_from_cache_job.cc3
-rw-r--r--chromium/content/browser/service_worker/service_worker_read_from_cache_job_unittest.cc43
-rw-r--r--chromium/content/browser/service_worker/service_worker_register_job.cc145
-rw-r--r--chromium/content/browser/service_worker/service_worker_register_job.h42
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration.cc41
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration.h16
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_object_host.cc28
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_object_host.h8
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_status.cc47
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_status.h6
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_unittest.cc64
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler.cc31
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_request_handler_unittest.cc6
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_loader_factory.cc102
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_loader_factory.h5
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage.cc183
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage.h32
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage_unittest.cc493
-rw-r--r--chromium/content/browser/service_worker/service_worker_test_utils.cc125
-rw-r--r--chromium/content/browser/service_worker/service_worker_test_utils.h36
-rw-r--r--chromium/content/browser/service_worker/service_worker_type_converters.cc16
-rw-r--r--chromium/content/browser/service_worker/service_worker_type_converters.h15
-rw-r--r--chromium/content/browser/service_worker/service_worker_unregister_job.cc24
-rw-r--r--chromium/content/browser/service_worker/service_worker_unregister_job.h13
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_job_wrapper.cc14
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job.cc10
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job.h6
-rw-r--r--chromium/content/browser/service_worker/service_worker_url_request_job_unittest.cc67
-rw-r--r--chromium/content/browser/service_worker/service_worker_version.cc430
-rw-r--r--chromium/content/browser/service_worker/service_worker_version.h148
-rw-r--r--chromium/content/browser/service_worker/service_worker_version_unittest.cc247
-rw-r--r--chromium/content/browser/service_worker/service_worker_write_to_cache_job.cc3
-rw-r--r--chromium/content/browser/service_worker/service_worker_write_to_cache_job.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_write_to_cache_job_unittest.cc34
-rw-r--r--chromium/content/browser/shared_worker/OWNERS1
-rw-r--r--chromium/content/browser/shared_worker/mock_shared_worker.cc3
-rw-r--r--chromium/content/browser/shared_worker/mock_shared_worker.h3
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_connector_impl.cc16
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_connector_impl.h3
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_host.cc59
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_host.h6
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_host_unittest.cc23
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_script_loader.cc21
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_script_loader.h8
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_script_loader_factory.cc4
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl.cc171
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl.h27
-rw-r--r--chromium/content/browser/shared_worker/shared_worker_service_impl_unittest.cc2
-rw-r--r--chromium/content/browser/shared_worker/worker_browsertest.cc37
-rw-r--r--chromium/content/browser/site_instance_impl.cc47
-rw-r--r--chromium/content/browser/site_instance_impl.h7
-rw-r--r--chromium/content/browser/site_instance_impl_unittest.cc107
-rw-r--r--chromium/content/browser/site_per_process_browsertest.cc945
-rw-r--r--chromium/content/browser/site_per_process_hit_test_browsertest.cc546
-rw-r--r--chromium/content/browser/site_per_process_mac_browsertest.mm22
-rw-r--r--chromium/content/browser/snapshot_browsertest.cc25
-rw-r--r--chromium/content/browser/speech/chunked_byte_buffer.cc2
-rw-r--r--chromium/content/browser/speech/chunked_byte_buffer.h3
-rw-r--r--chromium/content/browser/speech/speech_recognition_browsertest.cc16
-rw-r--r--chromium/content/browser/speech/speech_recognition_dispatcher_host.cc73
-rw-r--r--chromium/content/browser/speech/speech_recognition_dispatcher_host.h65
-rw-r--r--chromium/content/browser/speech/speech_recognition_engine.cc429
-rw-r--r--chromium/content/browser/speech/speech_recognition_engine.h67
-rw-r--r--chromium/content/browser/speech/speech_recognition_engine_unittest.cc533
-rw-r--r--chromium/content/browser/speech/speech_recognition_manager_impl.cc21
-rw-r--r--chromium/content/browser/speech/speech_recognition_manager_impl.h13
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl.cc58
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl.h15
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl_android.cc24
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl_android.h7
-rw-r--r--chromium/content/browser/speech/speech_recognizer_impl_unittest.cc197
-rw-r--r--chromium/content/browser/startup_data_impl.cc13
-rw-r--r--chromium/content/browser/startup_data_impl.h26
-rw-r--r--chromium/content/browser/startup_task_runner.cc17
-rw-r--r--chromium/content/browser/startup_task_runner.h4
-rw-r--r--chromium/content/browser/startup_task_runner_unittest.cc10
-rw-r--r--chromium/content/browser/storage_partition_impl.cc67
-rw-r--r--chromium/content/browser/storage_partition_impl.h22
-rw-r--r--chromium/content/browser/storage_partition_impl_browsertest.cc88
-rw-r--r--chromium/content/browser/storage_partition_impl_map.cc5
-rw-r--r--chromium/content/browser/tracing/background_memory_tracing_observer.cc73
-rw-r--r--chromium/content/browser/tracing/background_memory_tracing_observer.h6
-rw-r--r--chromium/content/browser/tracing/background_memory_tracing_observer_unittest.cc176
-rw-r--r--chromium/content/browser/tracing/background_tracing_manager_browsertest.cc60
-rw-r--r--chromium/content/browser/tracing/background_tracing_manager_impl.cc9
-rw-r--r--chromium/content/browser/tracing/cast_tracing_agent.cc3
-rw-r--r--chromium/content/browser/tracing/cros_tracing_agent.cc3
-rw-r--r--chromium/content/browser/tracing/etw_tracing_agent_win.cc3
-rw-r--r--chromium/content/browser/tracing/memory_instrumentation_browsertest.cc19
-rw-r--r--chromium/content/browser/tracing/power_tracing_agent.cc6
-rw-r--r--chromium/content/browser/tracing/tracing_controller_impl.cc31
-rw-r--r--chromium/content/browser/url_loader_factory_getter.cc31
-rw-r--r--chromium/content/browser/url_loader_factory_getter.h10
-rw-r--r--chromium/content/browser/utility_process_host.cc37
-rw-r--r--chromium/content/browser/utility_process_host.h16
-rw-r--r--chromium/content/browser/utility_process_host_browsertest.cc134
-rw-r--r--chromium/content/browser/vibration_browsertest.cc9
-rw-r--r--chromium/content/browser/web_contents/aura/overscroll_navigation_overlay_unittest.cc4
-rw-r--r--chromium/content/browser/web_contents/web_contents_android.cc32
-rw-r--r--chromium/content/browser/web_contents/web_contents_android.h25
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl.cc407
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl.h100
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl_browsertest.cc271
-rw-r--r--chromium/content/browser/web_contents/web_contents_impl_unittest.cc406
-rw-r--r--chromium/content/browser/web_contents/web_contents_view.h10
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_android.cc107
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_android.h6
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_aura.cc12
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_aura.h4
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_aura_browsertest.cc3
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_child_frame.cc6
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_child_frame.h4
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_guest.cc13
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_guest.h4
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_mac.h19
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_mac.mm40
-rw-r--r--chromium/content/browser/web_contents/web_contents_view_mac_unittest.mm24
-rw-r--r--chromium/content/browser/web_package/signed_exchange_cert_fetcher.cc75
-rw-r--r--chromium/content/browser/web_package/signed_exchange_cert_fetcher.h11
-rw-r--r--chromium/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc15
-rw-r--r--chromium/content/browser/web_package/signed_exchange_cert_fetcher_factory.h5
-rw-r--r--chromium/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc177
-rw-r--r--chromium/content/browser/web_package/signed_exchange_certificate_chain.cc181
-rw-r--r--chromium/content/browser/web_package/signed_exchange_certificate_chain.h6
-rw-r--r--chromium/content/browser/web_package/signed_exchange_certificate_chain_fuzzer.cc2
-rw-r--r--chromium/content/browser/web_package/signed_exchange_certificate_chain_unittest.cc255
-rw-r--r--chromium/content/browser/web_package/signed_exchange_consts.h11
-rw-r--r--chromium/content/browser/web_package/signed_exchange_devtools_proxy.cc24
-rw-r--r--chromium/content/browser/web_package/signed_exchange_devtools_proxy.h14
-rw-r--r--chromium/content/browser/web_package/signed_exchange_envelope.cc (renamed from chromium/content/browser/web_package/signed_exchange_header.cc)195
-rw-r--r--chromium/content/browser/web_package/signed_exchange_envelope.h (renamed from chromium/content/browser/web_package/signed_exchange_header.h)43
-rw-r--r--chromium/content/browser/web_package/signed_exchange_envelope_unittest.cc230
-rw-r--r--chromium/content/browser/web_package/signed_exchange_error.cc48
-rw-r--r--chromium/content/browser/web_package/signed_exchange_error.h50
-rw-r--r--chromium/content/browser/web_package/signed_exchange_handler.cc365
-rw-r--r--chromium/content/browser/web_package/signed_exchange_handler.h20
-rw-r--r--chromium/content/browser/web_package/signed_exchange_handler_unittest.cc590
-rw-r--r--chromium/content/browser/web_package/signed_exchange_header_parser_unittest.cc281
-rw-r--r--chromium/content/browser/web_package/signed_exchange_header_unittest.cc210
-rw-r--r--chromium/content/browser/web_package/signed_exchange_loader.cc (renamed from chromium/content/browser/web_package/web_package_loader.cc)137
-rw-r--r--chromium/content/browser/web_package/signed_exchange_loader.h (renamed from chromium/content/browser/web_package/web_package_loader.h)37
-rw-r--r--chromium/content/browser/web_package/signed_exchange_prefetch_handler.cc (renamed from chromium/content/browser/web_package/web_package_prefetch_handler.cc)45
-rw-r--r--chromium/content/browser/web_package/signed_exchange_prefetch_handler.h (renamed from chromium/content/browser/web_package/web_package_prefetch_handler.h)34
-rw-r--r--chromium/content/browser/web_package/signed_exchange_prologue.cc83
-rw-r--r--chromium/content/browser/web_package/signed_exchange_prologue.h74
-rw-r--r--chromium/content/browser/web_package/signed_exchange_prologue_unittest.cc63
-rw-r--r--chromium/content/browser/web_package/signed_exchange_request_handler.cc (renamed from chromium/content/browser/web_package/web_package_request_handler.cc)41
-rw-r--r--chromium/content/browser/web_package/signed_exchange_request_handler.h (renamed from chromium/content/browser/web_package/web_package_request_handler.h)25
-rw-r--r--chromium/content/browser/web_package/signed_exchange_request_handler_browsertest.cc (renamed from chromium/content/browser/web_package/web_package_request_handler_browsertest.cc)224
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_header_field.cc (renamed from chromium/content/browser/web_package/signed_exchange_header_parser.cc)175
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_header_field.h (renamed from chromium/content/browser/web_package/signed_exchange_header_parser.h)12
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc333
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_verifier.cc229
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_verifier.h9
-rw-r--r--chromium/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc276
-rw-r--r--chromium/content/browser/web_package/signed_exchange_utils.cc19
-rw-r--r--chromium/content/browser/web_package/signed_exchange_utils.h17
-rw-r--r--chromium/content/browser/webauth/OWNERS3
-rw-r--r--chromium/content/browser/webauth/authenticator_impl.cc489
-rw-r--r--chromium/content/browser/webauth/authenticator_impl.h39
-rw-r--r--chromium/content/browser/webauth/authenticator_impl_unittest.cc627
-rw-r--r--chromium/content/browser/webauth/authenticator_type_converters.cc30
-rw-r--r--chromium/content/browser/webauth/authenticator_type_converters.h40
-rw-r--r--chromium/content/browser/webauth/scoped_virtual_authenticator_environment.cc10
-rw-r--r--chromium/content/browser/webauth/scoped_virtual_authenticator_environment.h10
-rw-r--r--chromium/content/browser/webauth/virtual_authenticator.cc21
-rw-r--r--chromium/content/browser/webauth/virtual_authenticator.h10
-rw-r--r--chromium/content/browser/webauth/webauth_browsertest.cc731
-rw-r--r--chromium/content/browser/webrtc/webrtc_audio_browsertest.cc79
-rw-r--r--chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc138
-rw-r--r--chromium/content/browser/webrtc/webrtc_internals.cc10
-rw-r--r--chromium/content/browser/webrtc/webrtc_stress_image_capture_browsertest.cc126
-rw-r--r--chromium/content/browser/webrtc/webrtc_video_capture_service_browsertest.cc473
-rw-r--r--chromium/content/browser/websockets/websocket_manager.cc7
-rw-r--r--chromium/content/browser/websockets/websocket_manager.h10
-rw-r--r--chromium/content/browser/websockets/websocket_manager_unittest.cc1
-rw-r--r--chromium/content/browser/webui/content_web_ui_controller_factory.cc28
-rw-r--r--chromium/content/browser/webui/content_web_ui_controller_factory.h10
-rw-r--r--chromium/content/browser/webui/shared_resources_data_source.cc72
-rw-r--r--chromium/content/browser/webui/url_data_manager_backend.cc49
-rw-r--r--chromium/content/browser/webui/url_data_manager_backend.h7
-rw-r--r--chromium/content/browser/webui/url_data_source_impl.h20
-rw-r--r--chromium/content/browser/webui/web_ui_controller_factory_registry.cc16
-rw-r--r--chromium/content/browser/webui/web_ui_controller_factory_registry.h5
-rw-r--r--chromium/content/browser/webui/web_ui_impl.cc7
-rw-r--r--chromium/content/browser/webui/web_ui_impl.h2
-rw-r--r--chromium/content/browser/webui/web_ui_mojo_browsertest.cc155
-rw-r--r--chromium/content/browser/webui/web_ui_url_loader_factory.cc4
-rw-r--r--chromium/content/child/BUILD.gn9
-rw-r--r--chromium/content/child/DEPS1
-rw-r--r--chromium/content/child/blink_platform_impl.cc41
-rw-r--r--chromium/content/child/blink_platform_impl.h5
-rw-r--r--chromium/content/child/browser_font_resource_trusted.cc3
-rw-r--r--chromium/content/child/child_process_sandbox_support_impl_linux.cc147
-rw-r--r--chromium/content/child/child_process_sandbox_support_impl_linux.h17
-rw-r--r--chromium/content/child/child_thread_impl.cc96
-rw-r--r--chromium/content/child/child_thread_impl.h20
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc2
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.cc18
-rw-r--r--chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_win.h35
-rw-r--r--chromium/content/child/dwrite_font_proxy/font_fallback_win.cc6
-rw-r--r--chromium/content/child/dwrite_font_proxy/font_fallback_win.h2
-rw-r--r--chromium/content/child/font_warmup_win.cc2
-rw-r--r--chromium/content/child/font_warmup_win_unittest.cc2
-rw-r--r--chromium/content/child/image_decoder.cc14
-rw-r--r--chromium/content/child/runtime_features.cc87
-rw-r--r--chromium/content/child/scoped_web_callbacks.h112
-rw-r--r--chromium/content/child/webthemeengine_impl_android.cc7
-rw-r--r--chromium/content/child/webthemeengine_impl_android.h2
-rw-r--r--chromium/content/child/webthemeengine_impl_default.cc8
-rw-r--r--chromium/content/child/webthemeengine_impl_default.h2
-rw-r--r--chromium/content/common/BUILD.gn39
-rw-r--r--chromium/content/common/DEPS4
-rw-r--r--chromium/content/common/accessibility_messages.h44
-rw-r--r--chromium/content/common/background_fetch/background_fetch_struct_traits.cc13
-rw-r--r--chromium/content/common/background_fetch/background_fetch_struct_traits.h20
-rw-r--r--chromium/content/common/background_fetch/background_fetch_struct_traits_unittest.cc56
-rw-r--r--chromium/content/common/background_fetch/background_fetch_types.cc6
-rw-r--r--chromium/content/common/background_fetch/background_fetch_types.h20
-rw-r--r--chromium/content/common/browser_plugin/browser_plugin_messages.h2
-rw-r--r--chromium/content/common/cache_storage/OWNERS15
-rw-r--r--chromium/content/common/cache_storage/cache_storage_mojom_traits.h80
-rw-r--r--chromium/content/common/common_sandbox_support_linux.cc5
-rw-r--r--chromium/content/common/content_message_generator.h14
-rw-r--r--chromium/content/common/content_param_traits.cc4
-rw-r--r--chromium/content/common/content_security_policy/csp_context.cc8
-rw-r--r--chromium/content/common/dom_storage/dom_storage_map.cc5
-rw-r--r--chromium/content/common/dom_storage/dom_storage_map.h7
-rw-r--r--chromium/content/common/fileapi/file_system_messages.h4
-rw-r--r--chromium/content/common/font_config_ipc_linux.cc179
-rw-r--r--chromium/content/common/font_config_ipc_linux.h81
-rw-r--r--chromium/content/common/frame.mojom34
-rw-r--r--chromium/content/common/frame_message_enums.h16
-rw-r--r--chromium/content/common/frame_messages.h74
-rw-r--r--chromium/content/common/frame_visual_properties.h4
-rw-r--r--chromium/content/common/in_process_child_thread_params.cc4
-rw-r--r--chromium/content/common/in_process_child_thread_params.h10
-rw-r--r--chromium/content/common/indexed_db/OWNERS3
-rw-r--r--chromium/content/common/input/event_with_latency_info_unittest.cc7
-rw-r--r--chromium/content/common/input/input_event_struct_traits.cc14
-rw-r--r--chromium/content/common/input/input_handler.mojom1
-rw-r--r--chromium/content/common/input/sync_compositor_messages.h2
-rw-r--r--chromium/content/common/input/synchronous_compositor.mojom4
-rw-r--r--chromium/content/common/input/synthetic_web_input_event_builders.cc10
-rw-r--r--chromium/content/common/layer_tree_settings_factory.cc35
-rw-r--r--chromium/content/common/layer_tree_settings_factory.h27
-rw-r--r--chromium/content/common/leveldb_wrapper.mojom88
-rw-r--r--chromium/content/common/media/cdm_info.cc41
-rw-r--r--chromium/content/common/media/media_player_delegate_messages.h4
-rw-r--r--chromium/content/common/media/media_player_messages_android.h3
-rw-r--r--chromium/content/common/media/renderer_audio_input_stream_factory.mojom2
-rw-r--r--chromium/content/common/media/surface_view_manager_messages_android.h30
-rw-r--r--chromium/content/common/native_types.mojom7
-rw-r--r--chromium/content/common/native_types.typemap2
-rw-r--r--chromium/content/common/native_types_mac.typemap2
-rw-r--r--chromium/content/common/navigation_client.mojom83
-rw-r--r--chromium/content/common/navigation_params.cc4
-rw-r--r--chromium/content/common/navigation_params.h15
-rw-r--r--chromium/content/common/navigation_subresource_loader_params.cc3
-rw-r--r--chromium/content/common/navigation_subresource_loader_params.h8
-rw-r--r--chromium/content/common/net/record_load_histograms.cc42
-rw-r--r--chromium/content/common/net/record_load_histograms.h19
-rw-r--r--chromium/content/common/net/url_fetcher.cc36
-rw-r--r--chromium/content/common/net/url_request_user_data.h3
-rw-r--r--chromium/content/common/page_message_enums.h15
-rw-r--r--chromium/content/common/page_messages.h15
-rw-r--r--chromium/content/common/platform_notification_param_traits.h (renamed from chromium/content/common/platform_notification_messages.h)15
-rw-r--r--chromium/content/common/render_frame_metadata.mojom27
-rw-r--r--chromium/content/common/render_frame_metadata_struct_traits.cc12
-rw-r--r--chromium/content/common/render_frame_metadata_struct_traits.h34
-rw-r--r--chromium/content/common/render_widget_host_ns_view.mojom230
-rw-r--r--chromium/content/common/renderer.mojom16
-rw-r--r--chromium/content/common/renderer_host.mojom5
-rw-r--r--chromium/content/common/sandbox_init_mac.cc18
-rw-r--r--chromium/content/common/sandbox_policy_fuchsia.cc74
-rw-r--r--chromium/content/common/sandbox_policy_fuchsia.h32
-rw-r--r--chromium/content/common/service_manager/DEPS2
-rw-r--r--chromium/content/common/service_manager/child_connection.cc9
-rw-r--r--chromium/content/common/service_manager/child_connection.h4
-rw-r--r--chromium/content/common/service_worker/README.md5
-rw-r--r--chromium/content/common/service_worker/controller_service_worker.mojom32
-rw-r--r--chromium/content/common/service_worker/dispatch_fetch_event_params.mojom47
-rw-r--r--chromium/content/common/service_worker/embedded_worker.mojom56
-rw-r--r--chromium/content/common/service_worker/service_worker.mojom203
-rw-r--r--chromium/content/common/service_worker/service_worker.typemap (renamed from chromium/content/common/service_worker/service_worker_event_dispatcher.typemap)6
-rw-r--r--chromium/content/common/service_worker/service_worker_container.mojom8
-rw-r--r--chromium/content/common/service_worker/service_worker_event_dispatcher.mojom187
-rw-r--r--chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.cc1
-rw-r--r--chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.h5
-rw-r--r--chromium/content/common/service_worker/service_worker_fetch_response_callback.mojom10
-rw-r--r--chromium/content/common/service_worker/service_worker_loader_helpers.cc4
-rw-r--r--chromium/content/common/service_worker/service_worker_messages.h4
-rw-r--r--chromium/content/common/service_worker/service_worker_provider.mojom83
-rw-r--r--chromium/content/common/service_worker/service_worker_provider.typemap12
-rw-r--r--chromium/content/common/service_worker/service_worker_provider_host_info.cc77
-rw-r--r--chromium/content/common/service_worker/service_worker_provider_host_info.h76
-rw-r--r--chromium/content/common/service_worker/service_worker_provider_struct_traits.cc25
-rw-r--r--chromium/content/common/service_worker/service_worker_provider_struct_traits.h51
-rw-r--r--chromium/content/common/service_worker/service_worker_status_code.cc59
-rw-r--r--chromium/content/common/service_worker/service_worker_status_code.h88
-rw-r--r--chromium/content/common/service_worker/service_worker_types.cc2
-rw-r--r--chromium/content/common/service_worker/service_worker_types.h1
-rw-r--r--chromium/content/common/service_worker/service_worker_types.proto2
-rw-r--r--chromium/content/common/service_worker/service_worker_utils.cc63
-rw-r--r--chromium/content/common/service_worker/service_worker_utils.h35
-rw-r--r--chromium/content/common/shared_worker/shared_worker_connector.mojom8
-rw-r--r--chromium/content/common/shared_worker/shared_worker_factory.mojom11
-rw-r--r--chromium/content/common/skia_utils.cc68
-rw-r--r--chromium/content/common/skia_utils.h16
-rw-r--r--chromium/content/common/speech_recognizer.mojom95
-rw-r--r--chromium/content/common/storage_partition_service.mojom27
-rw-r--r--chromium/content/common/swapped_out_messages.cc4
-rw-r--r--chromium/content/common/tab_switching_time_callback.cc32
-rw-r--r--chromium/content/common/tab_switching_time_callback.h22
-rw-r--r--chromium/content/common/throttling_url_loader.cc47
-rw-r--r--chromium/content/common/throttling_url_loader.h14
-rw-r--r--chromium/content/common/throttling_url_loader_unittest.cc18
-rw-r--r--chromium/content/common/typemaps.gni3
-rw-r--r--chromium/content/common/url_schemes.cc2
-rw-r--r--chromium/content/common/view_messages.h48
-rw-r--r--chromium/content/common/visual_properties.h4
-rw-r--r--chromium/content/gpu/BUILD.gn1
-rw-r--r--chromium/content/gpu/gpu_child_thread.cc40
-rw-r--r--chromium/content/gpu/gpu_child_thread.h15
-rw-r--r--chromium/content/gpu/gpu_main.cc21
-rw-r--r--chromium/content/gpu/gpu_service_factory.cc6
-rw-r--r--chromium/content/gpu/gpu_service_factory.h2
-rw-r--r--chromium/content/gpu/in_process_gpu_thread.cc2
-rw-r--r--chromium/content/gpu/in_process_gpu_thread.h2
-rw-r--r--chromium/content/ppapi_plugin/BUILD.gn1
-rw-r--r--chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc51
-rw-r--r--chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h12
-rw-r--r--chromium/content/ppapi_plugin/ppapi_plugin_main.cc6
-rw-r--r--chromium/content/ppapi_plugin/ppapi_thread.cc24
-rw-r--r--chromium/content/ppapi_plugin/ppapi_thread.h6
-rw-r--r--chromium/content/public/android/BUILD.gn95
-rw-r--r--chromium/content/public/android/DEPS2
-rwxr-xr-xchromium/content/public/android/generate_child_service.py56
-rw-r--r--chromium/content/public/app/BUILD.gn9
-rw-r--r--chromium/content/public/app/content_main_delegate.h5
-rw-r--r--chromium/content/public/app/content_main_runner.h2
-rw-r--r--chromium/content/public/app/mojo/content_browser_manifest.json38
-rw-r--r--chromium/content/public/app/mojo/content_plugin_manifest.json1
-rw-r--r--chromium/content/public/app/mojo/content_renderer_manifest.json1
-rw-r--r--chromium/content/public/app/mojo/content_utility_manifest.json3
-rw-r--r--chromium/content/public/browser/BUILD.gn16
-rw-r--r--chromium/content/public/browser/DEPS7
-rw-r--r--chromium/content/public/browser/android/content_view_layer_renderer.h27
-rw-r--r--chromium/content/public/browser/authenticator_request_client_delegate.cc41
-rw-r--r--chromium/content/public/browser/authenticator_request_client_delegate.h85
-rw-r--r--chromium/content/public/browser/ax_event_notification_details.cc9
-rw-r--r--chromium/content/public/browser/ax_event_notification_details.h13
-rw-r--r--chromium/content/public/browser/background_fetch_delegate.h9
-rw-r--r--chromium/content/public/browser/background_fetch_response.cc13
-rw-r--r--chromium/content/public/browser/background_fetch_response.h4
-rw-r--r--chromium/content/public/browser/background_tracing_manager.h6
-rw-r--r--chromium/content/public/browser/browser_child_process_host.h3
-rw-r--r--chromium/content/public/browser/browser_context.h25
-rw-r--r--chromium/content/public/browser/browser_main_parts.h5
-rw-r--r--chromium/content/public/browser/browsing_data_remover.h2
-rw-r--r--chromium/content/public/browser/child_process_data.h3
-rw-r--r--chromium/content/public/browser/child_process_security_policy.h24
-rw-r--r--chromium/content/public/browser/child_process_termination_info.h12
-rw-r--r--chromium/content/public/browser/content_browser_client.cc119
-rw-r--r--chromium/content/public/browser/content_browser_client.h189
-rw-r--r--chromium/content/public/browser/devtools_agent_host_client.cc15
-rw-r--r--chromium/content/public/browser/devtools_agent_host_client.h6
-rw-r--r--chromium/content/public/browser/devtools_agent_host_observer.cc4
-rw-r--r--chromium/content/public/browser/devtools_agent_host_observer.h5
-rw-r--r--chromium/content/public/browser/devtools_manager_delegate.cc4
-rw-r--r--chromium/content/public/browser/devtools_manager_delegate.h3
-rw-r--r--chromium/content/public/browser/download_manager.h5
-rw-r--r--chromium/content/public/browser/download_utils.h28
-rw-r--r--chromium/content/public/browser/gpu_client.h6
-rw-r--r--chromium/content/public/browser/gpu_utils.cc14
-rw-r--r--chromium/content/public/browser/gpu_utils.h2
-rw-r--r--chromium/content/public/browser/keyboard_event_processing_result.h3
-rw-r--r--chromium/content/public/browser/manifest_icon_selector.h41
-rw-r--r--chromium/content/public/browser/media_controller.h44
-rw-r--r--chromium/content/public/browser/navigation_controller.cc3
-rw-r--r--chromium/content/public/browser/navigation_controller.h14
-rw-r--r--chromium/content/public/browser/navigation_handle.h9
-rw-r--r--chromium/content/public/browser/network_connection_tracker.cc (renamed from chromium/content/public/common/network_connection_tracker.cc)74
-rw-r--r--chromium/content/public/browser/network_connection_tracker.h (renamed from chromium/content/public/common/network_connection_tracker.h)69
-rw-r--r--chromium/content/public/browser/network_connection_tracker_unittest.cc (renamed from chromium/content/public/common/network_connection_tracker_unittest.cc)63
-rw-r--r--chromium/content/public/browser/notification_database_data.cc4
-rw-r--r--chromium/content/public/browser/notification_database_data.h7
-rw-r--r--chromium/content/public/browser/notification_event_dispatcher.h4
-rw-r--r--chromium/content/public/browser/notification_registrar.cc8
-rw-r--r--chromium/content/public/browser/overlay_window.h18
-rw-r--r--chromium/content/public/browser/permission_controller.h51
-rw-r--r--chromium/content/public/browser/permission_controller_delegate.h (renamed from chromium/content/public/browser/permission_manager.h)17
-rw-r--r--chromium/content/public/browser/picture_in_picture_window_controller.h13
-rw-r--r--chromium/content/public/browser/platform_notification_context.h26
-rw-r--r--chromium/content/public/browser/platform_notification_service.h23
-rw-r--r--chromium/content/public/browser/presentation_service_delegate.h4
-rw-r--r--chromium/content/public/browser/push_messaging_service.cc9
-rw-r--r--chromium/content/public/browser/reload_type.h8
-rw-r--r--chromium/content/public/browser/render_frame_host.h24
-rw-r--r--chromium/content/public/browser/render_frame_metadata_provider.h4
-rw-r--r--chromium/content/public/browser/render_process_host.h30
-rw-r--r--chromium/content/public/browser/render_process_host_observer.h7
-rw-r--r--chromium/content/public/browser/render_view_host.h7
-rw-r--r--chromium/content/public/browser/render_widget_host.h17
-rw-r--r--chromium/content/public/browser/render_widget_host_view.h7
-rw-r--r--chromium/content/public/browser/resource_context.h2
-rw-r--r--chromium/content/public/browser/resource_hints.h12
-rw-r--r--chromium/content/public/browser/resource_request_info.h11
-rw-r--r--chromium/content/public/browser/service_worker_context.h12
-rw-r--r--chromium/content/public/browser/site_isolation_policy.cc33
-rw-r--r--chromium/content/public/browser/site_isolation_policy.h11
-rw-r--r--chromium/content/public/browser/speech_recognition_event_listener.h20
-rw-r--r--chromium/content/public/browser/speech_recognition_manager.h2
-rw-r--r--chromium/content/public/browser/speech_recognition_manager_delegate.h1
-rw-r--r--chromium/content/public/browser/speech_recognition_session_config.h11
-rw-r--r--chromium/content/public/browser/ssl_host_state_delegate.h4
-rw-r--r--chromium/content/public/browser/startup_data.h18
-rw-r--r--chromium/content/public/browser/storage_partition.h4
-rw-r--r--chromium/content/public/browser/url_data_source.cc7
-rw-r--r--chromium/content/public/browser/url_data_source.h4
-rw-r--r--chromium/content/public/browser/video_capture_device_launcher.cc19
-rw-r--r--chromium/content/public/browser/video_capture_device_launcher.h5
-rw-r--r--chromium/content/public/browser/web_contents.h44
-rw-r--r--chromium/content/public/browser/web_contents_delegate.cc15
-rw-r--r--chromium/content/public/browser/web_contents_delegate.h35
-rw-r--r--chromium/content/public/browser/web_contents_observer.cc29
-rw-r--r--chromium/content/public/browser/web_contents_observer.h50
-rw-r--r--chromium/content/public/browser/web_contents_user_data.h23
-rw-r--r--chromium/content/public/browser/web_ui.h4
-rw-r--r--chromium/content/public/browser/web_ui_controller_factory.h7
-rw-r--r--chromium/content/public/browser/webrtc_event_logger.h28
-rw-r--r--chromium/content/public/child/BUILD.gn1
-rw-r--r--chromium/content/public/child/child_process_sandbox_support_linux.h33
-rw-r--r--chromium/content/public/common/BUILD.gn18
-rw-r--r--chromium/content/public/common/bindings_policy.h17
-rw-r--r--chromium/content/public/common/cdm_info.h64
-rw-r--r--chromium/content/public/common/common_param_traits_macros.h13
-rw-r--r--chromium/content/public/common/content_features.cc182
-rw-r--r--chromium/content/public/common/content_features.h34
-rw-r--r--chromium/content/public/common/content_switches.cc57
-rw-r--r--chromium/content/public/common/content_switches.h15
-rw-r--r--chromium/content/public/common/main_function_params.h5
-rw-r--r--chromium/content/public/common/manifest_struct_traits.h191
-rw-r--r--chromium/content/public/common/media_stream_request.h6
-rw-r--r--chromium/content/public/common/previews_state.h10
-rw-r--r--chromium/content/public/common/renderer_preferences.h5
-rw-r--r--chromium/content/public/common/screen_info.h9
-rw-r--r--chromium/content/public/common/speech_recognition_error.h77
-rw-r--r--chromium/content/public/common/speech_recognition_error.mojom34
-rw-r--r--chromium/content/public/common/speech_recognition_error.typemap14
-rw-r--r--chromium/content/public/common/speech_recognition_error_struct_traits.cc22
-rw-r--r--chromium/content/public/common/speech_recognition_error_struct_traits.h152
-rw-r--r--chromium/content/public/common/speech_recognition_grammar.mojom12
-rw-r--r--chromium/content/public/common/speech_recognition_result.cc20
-rw-r--r--chromium/content/public/common/speech_recognition_result.h44
-rw-r--r--chromium/content/public/common/speech_recognition_result.mojom29
-rw-r--r--chromium/content/public/common/speech_recognition_result.typemap16
-rw-r--r--chromium/content/public/common/speech_recognition_result_struct_traits.cc29
-rw-r--r--chromium/content/public/common/speech_recognition_result_struct_traits.h47
-rw-r--r--chromium/content/public/common/typemaps.gni2
-rw-r--r--chromium/content/public/common/url_fetcher.h31
-rw-r--r--chromium/content/public/common/url_loader_throttle.cc3
-rw-r--r--chromium/content/public/common/url_loader_throttle.h6
-rw-r--r--chromium/content/public/common/use_zoom_for_dsf_policy.h4
-rw-r--r--chromium/content/public/common/web_preferences.cc9
-rw-r--r--chromium/content/public/common/web_preferences.h19
-rw-r--r--chromium/content/public/renderer/content_renderer_client.cc14
-rw-r--r--chromium/content/public/renderer/content_renderer_client.h9
-rw-r--r--chromium/content/public/renderer/key_system_support.cc9
-rw-r--r--chromium/content/public/renderer/key_system_support.h10
-rw-r--r--chromium/content/public/renderer/platform_event_observer.h4
-rw-r--r--chromium/content/public/renderer/render_frame.h6
-rw-r--r--chromium/content/public/renderer/render_frame_observer.h25
-rw-r--r--chromium/content/public/renderer/render_view.h2
-rw-r--r--chromium/content/public/renderer/renderer_gamepad_provider.h4
-rw-r--r--chromium/content/public/renderer/renderer_ppapi_host.h8
-rw-r--r--chromium/content/public/renderer/request_peer.h9
-rw-r--r--chromium/content/public/test/android/BUILD.gn2
-rw-r--r--chromium/content/public/test/test_service.mojom4
-rw-r--r--chromium/content/public/utility/content_utility_client.h3
-rw-r--r--chromium/content/public/utility/utility_thread.h2
-rw-r--r--chromium/content/renderer/BUILD.gn102
-rw-r--r--chromium/content/renderer/OWNERS1
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc6
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_tree_source.cc154
-rw-r--r--chromium/content/renderer/accessibility/blink_ax_tree_source.h5
-rw-r--r--chromium/content/renderer/accessibility/render_accessibility_impl.cc99
-rw-r--r--chromium/content/renderer/accessibility/render_accessibility_impl.h10
-rw-r--r--chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc59
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_proxy.cc65
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_proxy.h26
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_proxy_mojo.cc66
-rw-r--r--chromium/content/renderer/android/synchronous_compositor_proxy_mojo.h48
-rw-r--r--chromium/content/renderer/android/synchronous_layer_tree_frame_sink.cc31
-rw-r--r--chromium/content/renderer/android/synchronous_layer_tree_frame_sink.h14
-rw-r--r--chromium/content/renderer/appcache/web_application_cache_host_impl.cc5
-rw-r--r--chromium/content/renderer/blob_storage/OWNERS3
-rw-r--r--chromium/content/renderer/browser_plugin/browser_plugin.cc70
-rw-r--r--chromium/content/renderer/browser_plugin/browser_plugin.h9
-rw-r--r--chromium/content/renderer/child_frame_compositing_helper.cc3
-rw-r--r--chromium/content/renderer/child_message_filter.cc66
-rw-r--r--chromium/content/renderer/child_message_filter.h74
-rw-r--r--chromium/content/renderer/clipboard_utils.cc28
-rw-r--r--chromium/content/renderer/clipboard_utils.h24
-rw-r--r--chromium/content/renderer/cursor_utils.cc2
-rw-r--r--chromium/content/renderer/device_sensors/OWNERS4
-rw-r--r--chromium/content/renderer/device_sensors/device_motion_event_pump.cc162
-rw-r--r--chromium/content/renderer/device_sensors/device_motion_event_pump.h56
-rw-r--r--chromium/content/renderer/device_sensors/device_motion_event_pump_unittest.cc433
-rw-r--r--chromium/content/renderer/device_sensors/device_orientation_event_pump.cc235
-rw-r--r--chromium/content/renderer/device_sensors/device_orientation_event_pump.h63
-rw-r--r--chromium/content/renderer/device_sensors/device_orientation_event_pump_unittest.cc1018
-rw-r--r--chromium/content/renderer/device_sensors/device_sensor_event_pump.h329
-rw-r--r--chromium/content/renderer/dom_serializer_browsertest.cc6
-rw-r--r--chromium/content/renderer/dom_storage/dom_storage_cached_area.cc12
-rw-r--r--chromium/content/renderer/dom_storage/dom_storage_cached_area.h11
-rw-r--r--chromium/content/renderer/dom_storage/dom_storage_cached_area_unittest.cc3
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_area.cc5
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_area.h2
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_area.cc55
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_area.h34
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_area_unittest.cc7
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_areas.cc36
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_areas.h41
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_cached_areas_unittest.cc20
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_namespace.cc4
-rw-r--r--chromium/content/renderer/dom_storage/local_storage_namespace.h3
-rw-r--r--chromium/content/renderer/dom_storage/mock_leveldb_wrapper.cc27
-rw-r--r--chromium/content/renderer/dom_storage/mock_leveldb_wrapper.h28
-rw-r--r--chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.cc8
-rw-r--r--chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.h1
-rw-r--r--chromium/content/renderer/dom_storage/webstoragearea_impl.cc5
-rw-r--r--chromium/content/renderer/dom_storage/webstoragearea_impl.h2
-rw-r--r--chromium/content/renderer/dom_storage/webstoragenamespace_impl.cc8
-rw-r--r--chromium/content/renderer/dom_storage/webstoragenamespace_impl.h1
-rw-r--r--chromium/content/renderer/fetchers/resource_fetcher_impl.cc6
-rw-r--r--chromium/content/renderer/gamepad_shared_memory_reader.cc138
-rw-r--r--chromium/content/renderer/gamepad_shared_memory_reader.h57
-rw-r--r--chromium/content/renderer/gpu/compositor_dependencies.h11
-rw-r--r--chromium/content/renderer/gpu/gpu_benchmarking_extension.cc75
-rw-r--r--chromium/content/renderer/gpu/gpu_benchmarking_extension.h3
-rw-r--r--chromium/content/renderer/gpu/layer_tree_view.cc742
-rw-r--r--chromium/content/renderer/gpu/layer_tree_view.h (renamed from chromium/content/renderer/gpu/render_widget_compositor.h)156
-rw-r--r--chromium/content/renderer/gpu/layer_tree_view_delegate.h (renamed from chromium/content/renderer/gpu/render_widget_compositor_delegate.h)25
-rw-r--r--chromium/content/renderer/gpu/layer_tree_view_unittest.cc376
-rw-r--r--chromium/content/renderer/gpu/queue_message_swap_promise.cc11
-rw-r--r--chromium/content/renderer/gpu/queue_message_swap_promise.h5
-rw-r--r--chromium/content/renderer/gpu/queue_message_swap_promise_unittest.cc11
-rw-r--r--chromium/content/renderer/gpu/render_widget_compositor.cc1304
-rw-r--r--chromium/content/renderer/gpu/render_widget_compositor_unittest.cc425
-rw-r--r--chromium/content/renderer/image_capture/image_capture_frame_grabber.cc15
-rw-r--r--chromium/content/renderer/image_capture/image_capture_frame_grabber.h13
-rw-r--r--chromium/content/renderer/indexed_db/OWNERS3
-rw-r--r--chromium/content/renderer/input/frame_input_handler_impl.cc15
-rw-r--r--chromium/content/renderer/input/input_event_prediction.cc45
-rw-r--r--chromium/content/renderer/input/input_event_prediction.h13
-rw-r--r--chromium/content/renderer/input/input_event_prediction_unittest.cc22
-rw-r--r--chromium/content/renderer/input/main_thread_event_queue.cc4
-rw-r--r--chromium/content/renderer/input/main_thread_event_queue.h6
-rw-r--r--chromium/content/renderer/input/main_thread_event_queue_task.h2
-rw-r--r--chromium/content/renderer/input/render_widget_input_handler.cc13
-rw-r--r--chromium/content/renderer/input/widget_input_handler_impl.cc4
-rw-r--r--chromium/content/renderer/input/widget_input_handler_manager.cc48
-rw-r--r--chromium/content/renderer/input/widget_input_handler_manager.h13
-rw-r--r--chromium/content/renderer/loader/child_url_loader_factory_bundle.cc44
-rw-r--r--chromium/content/renderer/loader/child_url_loader_factory_bundle.h10
-rw-r--r--chromium/content/renderer/loader/resource_dispatcher.cc138
-rw-r--r--chromium/content/renderer/loader/resource_dispatcher.h15
-rw-r--r--chromium/content/renderer/loader/resource_dispatcher_unittest.cc8
-rw-r--r--chromium/content/renderer/loader/sync_load_context.cc76
-rw-r--r--chromium/content/renderer/loader/sync_load_context.h9
-rw-r--r--chromium/content/renderer/loader/sync_load_response.h12
-rw-r--r--chromium/content/renderer/loader/test_request_peer.cc8
-rw-r--r--chromium/content/renderer/loader/test_request_peer.h4
-rw-r--r--chromium/content/renderer/loader/url_loader_client_impl.cc37
-rw-r--r--chromium/content/renderer/loader/url_loader_client_impl.h9
-rw-r--r--chromium/content/renderer/loader/url_loader_client_impl_unittest.cc46
-rw-r--r--chromium/content/renderer/loader/url_response_body_consumer_unittest.cc4
-rw-r--r--chromium/content/renderer/loader/web_url_loader_impl.cc91
-rw-r--r--chromium/content/renderer/loader/web_url_loader_impl.h17
-rw-r--r--chromium/content/renderer/loader/web_url_loader_impl_unittest.cc21
-rw-r--r--chromium/content/renderer/loader/web_url_request_util.cc10
-rw-r--r--chromium/content/renderer/loader/web_worker_fetch_context_impl.cc (renamed from chromium/content/renderer/service_worker/worker_fetch_context_impl.cc)259
-rw-r--r--chromium/content/renderer/loader/web_worker_fetch_context_impl.h (renamed from chromium/content/renderer/service_worker/worker_fetch_context_impl.h)73
-rw-r--r--chromium/content/renderer/low_memory_mode_controller.cc61
-rw-r--r--chromium/content/renderer/low_memory_mode_controller.h58
-rw-r--r--chromium/content/renderer/low_memory_mode_controller_unittest.cc86
-rw-r--r--chromium/content/renderer/manifest/manifest_parser.cc18
-rw-r--r--chromium/content/renderer/manifest/manifest_parser.h4
-rw-r--r--chromium/content/renderer/manifest/manifest_parser_unittest.cc22
-rw-r--r--chromium/content/renderer/media/android/renderer_media_player_manager.cc4
-rw-r--r--chromium/content/renderer/media/android/renderer_media_player_manager.h3
-rw-r--r--chromium/content/renderer/media/android/renderer_surface_view_manager.cc55
-rw-r--r--chromium/content/renderer/media/android/renderer_surface_view_manager.h49
-rw-r--r--chromium/content/renderer/media/android/stream_texture_factory.cc1
-rw-r--r--chromium/content/renderer/media/audio/audio_device_factory.cc (renamed from chromium/content/renderer/media/audio_device_factory.cc)14
-rw-r--r--chromium/content/renderer/media/audio/audio_device_factory.h (renamed from chromium/content/renderer/media/audio_device_factory.h)6
-rw-r--r--chromium/content/renderer/media/audio/audio_input_ipc_factory.cc (renamed from chromium/content/renderer/media/audio_input_ipc_factory.cc)4
-rw-r--r--chromium/content/renderer/media/audio/audio_input_ipc_factory.h (renamed from chromium/content/renderer/media/audio_input_ipc_factory.h)6
-rw-r--r--chromium/content/renderer/media/audio/audio_output_ipc_factory.cc (renamed from chromium/content/renderer/media/audio_output_ipc_factory.cc)4
-rw-r--r--chromium/content/renderer/media/audio/audio_output_ipc_factory.h (renamed from chromium/content/renderer/media/audio_output_ipc_factory.h)6
-rw-r--r--chromium/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc (renamed from chromium/content/renderer/media/audio_output_ipc_factory_unittest.cc)4
-rw-r--r--chromium/content/renderer/media/audio/audio_renderer_mixer_manager.cc (renamed from chromium/content/renderer/media/audio_renderer_mixer_manager.cc)10
-rw-r--r--chromium/content/renderer/media/audio/audio_renderer_mixer_manager.h (renamed from chromium/content/renderer/media/audio_renderer_mixer_manager.h)14
-rw-r--r--chromium/content/renderer/media/audio/audio_renderer_mixer_manager_unittest.cc (renamed from chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc)72
-rw-r--r--chromium/content/renderer/media/audio/audio_renderer_sink_cache.h (renamed from chromium/content/renderer/media/audio_renderer_sink_cache.h)6
-rw-r--r--chromium/content/renderer/media/audio/audio_renderer_sink_cache_impl.cc (renamed from chromium/content/renderer/media/audio_renderer_sink_cache_impl.cc)4
-rw-r--r--chromium/content/renderer/media/audio/audio_renderer_sink_cache_impl.h (renamed from chromium/content/renderer/media/audio_renderer_sink_cache_impl.h)8
-rw-r--r--chromium/content/renderer/media/audio/audio_renderer_sink_cache_unittest.cc (renamed from chromium/content/renderer/media/audio_renderer_sink_cache_unittest.cc)2
-rw-r--r--chromium/content/renderer/media/audio/mock_audio_device_factory.cc (renamed from chromium/content/renderer/media/mock_audio_device_factory.cc)2
-rw-r--r--chromium/content/renderer/media/audio/mock_audio_device_factory.h (renamed from chromium/content/renderer/media/mock_audio_device_factory.h)8
-rw-r--r--chromium/content/renderer/media/audio/mojo_audio_input_ipc.cc (renamed from chromium/content/renderer/media/mojo_audio_input_ipc.cc)16
-rw-r--r--chromium/content/renderer/media/audio/mojo_audio_input_ipc.h (renamed from chromium/content/renderer/media/mojo_audio_input_ipc.h)8
-rw-r--r--chromium/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc (renamed from chromium/content/renderer/media/mojo_audio_input_ipc_unittest.cc)9
-rw-r--r--chromium/content/renderer/media/audio/mojo_audio_output_ipc.cc (renamed from chromium/content/renderer/media/mojo_audio_output_ipc.cc)21
-rw-r--r--chromium/content/renderer/media/audio/mojo_audio_output_ipc.h (renamed from chromium/content/renderer/media/mojo_audio_output_ipc.h)8
-rw-r--r--chromium/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc (renamed from chromium/content/renderer/media/mojo_audio_output_ipc_unittest.cc)8
-rw-r--r--chromium/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc6
-rw-r--r--chromium/content/renderer/media/media_factory.cc52
-rw-r--r--chromium/content/renderer/media/media_factory.h8
-rw-r--r--chromium/content/renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc4
-rw-r--r--chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.cc4
-rw-r--r--chromium/content/renderer/media/renderer_webaudiodevice_impl.cc2
-rw-r--r--chromium/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc2
-rw-r--r--chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc10
-rw-r--r--chromium/content/renderer/media/renderer_webmediaplayer_delegate.h2
-rw-r--r--chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc3
-rw-r--r--chromium/content/renderer/media/stream/local_media_stream_audio_source.cc2
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_processor.cc70
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_processor.h4
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_processor_options.cc23
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_processor_options.h28
-rw-r--r--chromium/content/renderer/media/stream/media_stream_audio_processor_unittest.cc108
-rw-r--r--chromium/content/renderer/media/stream/media_stream_center.cc34
-rw-r--r--chromium/content/renderer/media/stream/media_stream_center.h14
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util.cc21
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util.h11
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_audio.cc269
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_audio.h52
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc794
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_sets.cc2
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_sets.h2
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_sets_unittest.cc2
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_unittest.cc3
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_video_content.cc14
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_video_content.h1
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.cc38
-rw-r--r--chromium/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc12
-rw-r--r--chromium/content/renderer/media/stream/media_stream_renderer_factory_impl.cc8
-rw-r--r--chromium/content/renderer/media/stream/mock_constraint_factory.cc1
-rw-r--r--chromium/content/renderer/media/stream/processed_local_audio_source.cc19
-rw-r--r--chromium/content/renderer/media/stream/processed_local_audio_source_unittest.cc2
-rw-r--r--chromium/content/renderer/media/stream/track_audio_renderer.cc2
-rw-r--r--chromium/content/renderer/media/stream/user_media_client_impl_unittest.cc117
-rw-r--r--chromium/content/renderer/media/stream/user_media_processor.cc85
-rw-r--r--chromium/content/renderer/media/stream/webmediaplayer_ms.cc36
-rw-r--r--chromium/content/renderer/media/stream/webmediaplayer_ms.h10
-rw-r--r--chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.cc27
-rw-r--r--chromium/content/renderer/media/stream/webmediaplayer_ms_unittest.cc8
-rw-r--r--chromium/content/renderer/media/video_capture_impl.cc6
-rw-r--r--chromium/content/renderer/media/webrtc/audio_codec_factory.cc8
-rw-r--r--chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc193
-rw-r--r--chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h111
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_remote_video_source.cc87
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_remote_video_source.h4
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc4
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc310
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_track_metrics.h31
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_track_metrics_unittest.cc560
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc27
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h2
-rw-r--r--chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc8
-rw-r--r--chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc183
-rw-r--r--chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h71
-rw-r--r--chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc23
-rw-r--r--chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h34
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc26
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h7
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_tracker.cc251
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_tracker.h51
-rw-r--r--chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc364
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_certificate_generator.cc47
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_certificate_generator.h7
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.cc1307
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.h107
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc446
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc292
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h120
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc50
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc377
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_sender.h135
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc26
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.cc357
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.h160
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc363
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_stats.cc19
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_stats.h3
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_stats_unittest.cc45
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_decoder_unittest.cc20
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_encoder.cc69
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_encoder_factory.cc2
-rw-r--r--chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc4
-rw-r--r--chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc225
-rw-r--r--chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h112
-rw-r--r--chromium/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc294
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc15
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc2
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc16
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_audio_sink.h8
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc292
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h182
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc227
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h168
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc206
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc400
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc28
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h2
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc29
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h3
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc40
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc41
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_description_observer.cc166
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_description_observer.h186
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_description_observer_unittest.cc (renamed from chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc)121
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc120
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h140
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_util.h35
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc4
-rw-r--r--chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc40
-rw-r--r--chromium/content/renderer/media/webrtc_local_audio_source_provider.cc2
-rw-r--r--chromium/content/renderer/media_capture_from_element/canvas_capture_handler.cc10
-rw-r--r--chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source.cc4
-rw-r--r--chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc8
-rw-r--r--chromium/content/renderer/media_recorder/media_recorder_handler.cc85
-rw-r--r--chromium/content/renderer/media_recorder/media_recorder_handler.h1
-rw-r--r--chromium/content/renderer/media_recorder/media_recorder_handler_unittest.cc26
-rw-r--r--chromium/content/renderer/media_recorder/vea_encoder.cc15
-rw-r--r--chromium/content/renderer/media_recorder/vea_encoder.h7
-rw-r--r--chromium/content/renderer/media_recorder/video_track_recorder.cc4
-rw-r--r--chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc4
-rw-r--r--chromium/content/renderer/mus/BUILD.gn6
-rw-r--r--chromium/content/renderer/mus/mus_embedded_frame.cc2
-rw-r--r--chromium/content/renderer/mus/renderer_window_tree_client.cc39
-rw-r--r--chromium/content/renderer/mus/renderer_window_tree_client.h8
-rw-r--r--chromium/content/renderer/navigation_client.cc75
-rw-r--r--chromium/content/renderer/navigation_client.h56
-rw-r--r--chromium/content/renderer/navigation_state_impl.cc26
-rw-r--r--chromium/content/renderer/navigation_state_impl.h38
-rw-r--r--chromium/content/renderer/p2p/OWNERS1
-rw-r--r--chromium/content/renderer/pepper/audio_helper.cc22
-rw-r--r--chromium/content/renderer/pepper/audio_helper.h16
-rw-r--r--chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc14
-rw-r--r--chromium/content/renderer/pepper/mock_renderer_ppapi_host.h4
-rw-r--r--chromium/content/renderer/pepper/pepper_audio_input_host.cc39
-rw-r--r--chromium/content/renderer/pepper/pepper_audio_input_host.h12
-rw-r--r--chromium/content/renderer/pepper/pepper_audio_output_host.cc37
-rw-r--r--chromium/content/renderer/pepper/pepper_audio_output_host.h12
-rw-r--r--chromium/content/renderer/pepper/pepper_graphics_2d_host.cc11
-rw-r--r--chromium/content/renderer/pepper/pepper_graphics_2d_host.h4
-rw-r--r--chromium/content/renderer/pepper/pepper_media_stream_track_host_base.cc8
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_audio_input.cc20
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_audio_input.h2
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_audio_output.cc16
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_audio_output.h2
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_audio_output_dev.cc13
-rw-r--r--chromium/content/renderer/pepper/pepper_platform_audio_output_dev.h2
-rw-r--r--chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc44
-rw-r--r--chromium/content/renderer/pepper/pepper_plugin_instance_impl.h12
-rw-r--r--chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc14
-rw-r--r--chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h6
-rw-r--r--chromium/content/renderer/pepper/pepper_url_loader_host.cc18
-rw-r--r--chromium/content/renderer/pepper/pepper_url_loader_host.h4
-rw-r--r--chromium/content/renderer/pepper/pepper_url_request_unittest.cc19
-rw-r--r--chromium/content/renderer/pepper/pepper_video_decoder_host.cc33
-rw-r--r--chromium/content/renderer/pepper/pepper_video_decoder_host.h15
-rw-r--r--chromium/content/renderer/pepper/pepper_video_encoder_host.cc17
-rw-r--r--chromium/content/renderer/pepper/pepper_video_encoder_host.h11
-rw-r--r--chromium/content/renderer/pepper/pepper_video_source_host.cc2
-rw-r--r--chromium/content/renderer/pepper/pepper_webplugin_impl.cc5
-rw-r--r--chromium/content/renderer/pepper/pepper_webplugin_impl.h4
-rw-r--r--chromium/content/renderer/pepper/ppb_audio_impl.cc13
-rw-r--r--chromium/content/renderer/pepper/ppb_audio_impl.h8
-rw-r--r--chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc16
-rw-r--r--chromium/content/renderer/pepper/ppb_graphics_3d_impl.h17
-rw-r--r--chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc20
-rw-r--r--chromium/content/renderer/pepper/renderer_ppapi_host_impl.h4
-rw-r--r--chromium/content/renderer/pepper/resource_creation_impl.cc2
-rw-r--r--chromium/content/renderer/pepper/resource_creation_impl.h2
-rw-r--r--chromium/content/renderer/pepper/url_request_info_util.cc6
-rw-r--r--chromium/content/renderer/pepper/url_response_info_util.cc64
-rw-r--r--chromium/content/renderer/pepper/url_response_info_util.h15
-rw-r--r--chromium/content/renderer/pepper/video_decoder_shim.cc18
-rw-r--r--chromium/content/renderer/pepper/video_decoder_shim.h3
-rw-r--r--chromium/content/renderer/pepper/video_encoder_shim.cc5
-rw-r--r--chromium/content/renderer/push_messaging/push_messaging_client.cc2
-rw-r--r--chromium/content/renderer/render_frame_impl.cc900
-rw-r--r--chromium/content/renderer/render_frame_impl.h107
-rw-r--r--chromium/content/renderer/render_frame_impl_browsertest.cc38
-rw-r--r--chromium/content/renderer/render_frame_metadata_observer_impl.cc117
-rw-r--r--chromium/content/renderer/render_frame_metadata_observer_impl.h30
-rw-r--r--chromium/content/renderer/render_frame_metadata_observer_impl_unittest.cc158
-rw-r--r--chromium/content/renderer/render_frame_proxy.cc80
-rw-r--r--chromium/content/renderer/render_frame_proxy.h20
-rw-r--r--chromium/content/renderer/render_process_impl.cc35
-rw-r--r--chromium/content/renderer/render_thread_impl.cc199
-rw-r--r--chromium/content/renderer/render_thread_impl.h69
-rw-r--r--chromium/content/renderer/render_thread_impl_browsertest.cc22
-rw-r--r--chromium/content/renderer/render_view_browsertest.cc252
-rw-r--r--chromium/content/renderer/render_view_impl.cc365
-rw-r--r--chromium/content/renderer/render_view_impl.h96
-rw-r--r--chromium/content/renderer/render_view_impl_android.cc22
-rw-r--r--chromium/content/renderer/render_widget.cc746
-rw-r--r--chromium/content/renderer/render_widget.h70
-rw-r--r--chromium/content/renderer/render_widget_fullscreen_pepper.cc21
-rw-r--r--chromium/content/renderer/render_widget_fullscreen_pepper.h2
-rw-r--r--chromium/content/renderer/render_widget_owner_delegate.h6
-rw-r--r--chromium/content/renderer/render_widget_unittest.cc60
-rw-r--r--chromium/content/renderer/renderer_blink_platform_impl.cc327
-rw-r--r--chromium/content/renderer/renderer_blink_platform_impl.h84
-rw-r--r--chromium/content/renderer/renderer_main.cc85
-rw-r--r--chromium/content/renderer/renderer_main_platform_delegate_win.cc3
-rw-r--r--chromium/content/renderer/sad_plugin.cc12
-rw-r--r--chromium/content/renderer/sad_plugin.h10
-rw-r--r--chromium/content/renderer/service_worker/controller_service_worker_connector.cc26
-rw-r--r--chromium/content/renderer/service_worker/controller_service_worker_connector.h34
-rw-r--r--chromium/content/renderer/service_worker/controller_service_worker_impl.cc6
-rw-r--r--chromium/content/renderer/service_worker/controller_service_worker_impl.h2
-rw-r--r--chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.cc27
-rw-r--r--chromium/content/renderer/service_worker/embedded_worker_instance_client_impl.h8
-rw-r--r--chromium/content/renderer/service_worker/service_worker_context_client.cc361
-rw-r--r--chromium/content/renderer/service_worker/service_worker_context_client.h70
-rw-r--r--chromium/content/renderer/service_worker/service_worker_context_client_unittest.cc50
-rw-r--r--chromium/content/renderer/service_worker/service_worker_fetch_context_impl.cc34
-rw-r--r--chromium/content/renderer/service_worker/service_worker_fetch_context_impl.h23
-rw-r--r--chromium/content/renderer/service_worker/service_worker_message_filter.cc36
-rw-r--r--chromium/content/renderer/service_worker/service_worker_message_filter.h39
-rw-r--r--chromium/content/renderer/service_worker/service_worker_network_provider.cc64
-rw-r--r--chromium/content/renderer/service_worker/service_worker_network_provider.h19
-rw-r--r--chromium/content/renderer/service_worker/service_worker_provider_context.cc181
-rw-r--r--chromium/content/renderer/service_worker/service_worker_provider_context.h41
-rw-r--r--chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc131
-rw-r--r--chromium/content/renderer/service_worker/service_worker_subresource_loader.cc220
-rw-r--r--chromium/content/renderer/service_worker/service_worker_subresource_loader.h51
-rw-r--r--chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc303
-rw-r--r--chromium/content/renderer/service_worker/service_worker_timeout_timer.cc8
-rw-r--r--chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc7
-rw-r--r--chromium/content/renderer/service_worker/service_worker_type_converters.cc19
-rw-r--r--chromium/content/renderer/service_worker/service_worker_type_converters.h6
-rw-r--r--chromium/content/renderer/service_worker/service_worker_type_util.cc4
-rw-r--r--chromium/content/renderer/service_worker/thread_safe_script_container.h2
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_impl.cc2
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_impl.h10
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h2
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc8
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_provider_impl.h2
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc36
-rw-r--r--chromium/content/renderer/service_worker/web_service_worker_registration_impl.h6
-rw-r--r--chromium/content/renderer/shared_worker/OWNERS1
-rw-r--r--chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc148
-rw-r--r--chromium/content/renderer/shared_worker/embedded_shared_worker_stub.h11
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc10
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_factory_impl.h3
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_repository.cc8
-rw-r--r--chromium/content/renderer/shared_worker/shared_worker_repository.h1
-rw-r--r--chromium/content/renderer/speech_recognition_dispatcher.cc248
-rw-r--r--chromium/content/renderer/speech_recognition_dispatcher.h120
-rw-r--r--chromium/content/renderer/web_database_observer_impl.cc21
-rw-r--r--chromium/content/renderer/web_database_observer_impl.h6
-rw-r--r--chromium/content/renderer/web_frame_utils.cc28
-rw-r--r--chromium/content/renderer/web_frame_utils.h20
-rw-r--r--chromium/content/renderer/webclipboard_impl_browsertest.cc9
-rw-r--r--chromium/content/renderer/webgraphicscontext3d_provider_impl.cc10
-rw-r--r--chromium/content/renderer/webgraphicscontext3d_provider_impl.h5
-rw-r--r--chromium/content/renderer/webpublicsuffixlist_impl.cc26
-rw-r--r--chromium/content/renderer/webpublicsuffixlist_impl.h24
-rw-r--r--chromium/content/renderer/webscrollbarbehavior_impl_aura.cc60
-rw-r--r--chromium/content/renderer/webscrollbarbehavior_impl_aura.h24
-rw-r--r--chromium/content/renderer/webscrollbarbehavior_impl_mac.h31
-rw-r--r--chromium/content/renderer/webscrollbarbehavior_impl_mac.mm21
-rw-r--r--chromium/content/renderer/worker_thread_message_filter.cc49
-rw-r--r--chromium/content/renderer/worker_thread_message_filter.h61
-rw-r--r--chromium/content/shell/BUILD.gn67
-rw-r--r--chromium/content/shell/android/BUILD.gn7
-rw-r--r--chromium/content/shell/test_runner/BUILD.gn5
-rw-r--r--chromium/content/test/BUILD.gn137
-rw-r--r--chromium/content/test/fuzzer/BUILD.gn22
-rw-r--r--chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.cc44
-rw-r--r--chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.h18
-rw-r--r--chromium/content/utility/utility_main.cc18
-rw-r--r--chromium/content/utility/utility_service_factory.cc15
-rw-r--r--chromium/content/utility/utility_service_factory.h4
-rw-r--r--chromium/content/utility/utility_thread_impl.cc5
-rw-r--r--chromium/content/utility/utility_thread_impl.h2
1850 files changed, 60435 insertions, 52895 deletions
diff --git a/chromium/content/BUILD.gn b/chromium/content/BUILD.gn
index 09962146a24..835bd6d5808 100644
--- a/chromium/content/BUILD.gn
+++ b/chromium/content/BUILD.gn
@@ -81,9 +81,6 @@ if (is_component_build) {
component("content") {
public_deps =
content_shared_components + [ "//content/public/app:both_sources" ]
- deps = [
- "//build/config:exe_and_shlib_deps",
- ]
}
} else if (is_nacl_nonsfi) {
source_set("content") {
diff --git a/chromium/content/DEPS b/chromium/content/DEPS
index 1ec0d628f39..bd076e31344 100644
--- a/chromium/content/DEPS
+++ b/chromium/content/DEPS
@@ -24,6 +24,7 @@ include_rules = [
# settings, packaging details, installation or crash reporting.
"+components/services/filesystem",
+ "+components/services/font/public",
"+crypto",
"+grit/blink_resources.h",
@@ -32,9 +33,7 @@ include_rules = [
"+dbus",
"+gpu",
"+media",
- "+mojo/edk/embedder",
- "+mojo/edk/js",
- "+mojo/message_pump",
+ "+mojo/core/embedder",
"+mojo/public",
"+net",
"+ppapi",
diff --git a/chromium/content/app/BUILD.gn b/chromium/content/app/BUILD.gn
index 518bcc9435d..a603f4ff5eb 100644
--- a/chromium/content/app/BUILD.gn
+++ b/chromium/content/app/BUILD.gn
@@ -32,7 +32,7 @@ template("implement_content_app") {
"//services/service_manager/embedder",
"//services/service_manager/public/mojom",
"//services/service_manager/runner/common",
- "//mojo/edk",
+ "//mojo/core/embedder",
"//ppapi/buildflags",
"//ui/base",
"//ui/gfx",
@@ -52,7 +52,6 @@ template("implement_content_app") {
"//content/public/android:jni",
"//device/bluetooth",
"//device/gamepad",
- "//device/geolocation",
"//device/usb",
"//gpu",
"//media",
@@ -126,7 +125,7 @@ template("implement_content_app") {
"android/library_loader_hooks.h",
]
deps += [
- "//mojo/android:libsystem_java",
+ "//mojo/public/java/system:native_support",
"//ui/gl",
]
} else {
diff --git a/chromium/content/app/DEPS b/chromium/content/app/DEPS
index 1020b8e9075..4a94233d26f 100644
--- a/chromium/content/app/DEPS
+++ b/chromium/content/app/DEPS
@@ -3,13 +3,11 @@ include_rules = [
"+content",
"+device/bluetooth",
"+device/gamepad",
- "+device/geolocation",
"+device/usb",
# For loading V8's initial snapshot from external files.
"+gin/public/isolate_holder.h",
"+gin/public/snapshot_fd_data.h",
"+gin/v8_initializer.h",
- "+mojo/android/system/mojo_jni_registrar.h",
"+services/service_manager/embedder",
"+services/service_manager/runner/common",
"+services/service_manager/sandbox/sandbox_type.h",
diff --git a/chromium/content/app/android/content_main.cc b/chromium/content/app/android/content_main.cc
index fbd2b1b1677..f24042458a8 100644
--- a/chromium/content/app/android/content_main.cc
+++ b/chromium/content/app/android/content_main.cc
@@ -27,14 +27,26 @@ LazyInstance<std::unique_ptr<ContentMainDelegate>>::DestructorAtExit
} // namespace
+// TODO(qinmin/hanxi): split this function into 2 separate methods: One to
+// start the ServiceManager and one to start the remainder of the browser
+// process. The first method should always be called upon browser start, and
+// the second method can be deferred. See http://crbug.com/854209.
static jint JNI_ContentMain_Start(JNIEnv* env,
- const JavaParamRef<jclass>& clazz) {
+ const JavaParamRef<jclass>& clazz,
+ jboolean start_service_manager_only) {
TRACE_EVENT0("startup", "content::Start");
- DCHECK(!g_service_manager_main_delegate.Get());
- g_service_manager_main_delegate.Get() =
- std::make_unique<ContentServiceManagerMainDelegate>(
- ContentMainParams(g_content_main_delegate.Get().get()));
+ DCHECK(!g_service_manager_main_delegate.Get() || !start_service_manager_only);
+
+ if (!g_service_manager_main_delegate.Get()) {
+ g_service_manager_main_delegate.Get() =
+ std::make_unique<ContentServiceManagerMainDelegate>(
+ ContentMainParams(g_content_main_delegate.Get().get()));
+ }
+
+ static_cast<ContentServiceManagerMainDelegate*>(
+ g_service_manager_main_delegate.Get().get())
+ ->SetStartServiceManagerOnly(start_service_manager_only);
service_manager::MainParams main_params(
g_service_manager_main_delegate.Get().get());
diff --git a/chromium/content/app/content_main.cc b/chromium/content/app/content_main.cc
index 657761cb5dc..72c771d537e 100644
--- a/chromium/content/app/content_main.cc
+++ b/chromium/content/app/content_main.cc
@@ -12,7 +12,7 @@ namespace content {
int ContentMain(const ContentMainParams& params) {
ContentServiceManagerMainDelegate delegate(params);
service_manager::MainParams main_params(&delegate);
-#if defined(OS_POSIX) && !defined(OS_ANDROID)
+#if !defined(OS_WIN) && !defined(OS_ANDROID)
main_params.argc = params.argc;
main_params.argv = params.argv;
#endif
diff --git a/chromium/content/app/content_main_runner_impl.cc b/chromium/content/app/content_main_runner_impl.cc
index 83e8990edf1..8d789ef1b9f 100644
--- a/chromium/content/app/content_main_runner_impl.cc
+++ b/chromium/content/app/content_main_runner_impl.cc
@@ -42,6 +42,7 @@
#include "components/tracing/common/trace_startup.h"
#include "content/app/mojo/mojo_init.h"
#include "content/browser/browser_process_sub_thread.h"
+#include "content/browser/startup_data_impl.h"
#include "content/common/url_schemes.h"
#include "content/public/app/content_main_delegate.h"
#include "content/public/common/content_constants.h"
@@ -74,6 +75,7 @@
#elif defined(OS_MACOSX)
#include "base/power_monitor/power_monitor_device_source.h"
#include "content/browser/mach_broker_mac.h"
+#include "sandbox/mac/seatbelt_exec.h"
#endif // OS_WIN
#if defined(OS_POSIX) || defined(OS_FUCHSIA)
@@ -96,13 +98,11 @@
#if defined(OS_LINUX)
#include "base/native_library.h"
#include "base/rand_util.h"
-#include "content/common/font_config_ipc_linux.h"
#include "services/service_manager/zygote/common/common_sandbox_support_linux.h"
#include "third_party/blink/public/platform/web_font_render_style.h"
#include "third_party/boringssl/src/include/openssl/crypto.h"
#include "third_party/boringssl/src/include/openssl/rand.h"
-#include "third_party/skia/include/ports/SkFontConfigInterface.h"
-#include "third_party/skia/include/ports/SkFontMgr.h"
+#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/ports/SkFontMgr_android.h"
#include "third_party/webrtc_overrides/init_webrtc.h" // nogncheck
@@ -150,9 +150,6 @@
namespace content {
extern int GpuMain(const content::MainFunctionParams&);
#if BUILDFLAG(ENABLE_PLUGINS)
-#if !defined(OS_LINUX)
-extern int PluginMain(const content::MainFunctionParams&);
-#endif
extern int PpapiPluginMain(const MainFunctionParams&);
extern int PpapiBrokerMain(const MainFunctionParams&);
#endif
@@ -391,9 +388,6 @@ void PreSandboxInit() {
#endif
InitializeWebRtcModule();
- SkFontConfigInterface::SetGlobal(
- sk_make_sp<FontConfigIPC>(service_manager::GetSandboxFD()));
-
// Set the android SkFontMgr for blink. We need to ensure this is done
// before the sandbox is initialized to allow the font manager to access
// font configuration files on disk.
@@ -461,8 +455,7 @@ class ContentClientInitializer {
ContentClient* content_client = GetContentClient();
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
if (process_type.empty()) {
- if (delegate)
- content_client->browser_ = delegate->CreateContentBrowserClient();
+ content_client->browser_ = delegate->CreateContentBrowserClient();
if (!content_client->browser_)
content_client->browser_ = &g_empty_content_browser_client.Get();
}
@@ -473,24 +466,21 @@ class ContentClientInitializer {
if (process_type == switches::kGpuProcess ||
cmd->HasSwitch(switches::kSingleProcess) ||
(process_type.empty() && cmd->HasSwitch(switches::kInProcessGPU))) {
- if (delegate)
- content_client->gpu_ = delegate->CreateContentGpuClient();
+ content_client->gpu_ = delegate->CreateContentGpuClient();
if (!content_client->gpu_)
content_client->gpu_ = &g_empty_content_gpu_client.Get();
}
if (process_type == switches::kRendererProcess ||
cmd->HasSwitch(switches::kSingleProcess)) {
- if (delegate)
- content_client->renderer_ = delegate->CreateContentRendererClient();
+ content_client->renderer_ = delegate->CreateContentRendererClient();
if (!content_client->renderer_)
content_client->renderer_ = &g_empty_content_renderer_client.Get();
}
if (process_type == switches::kUtilityProcess ||
cmd->HasSwitch(switches::kSingleProcess)) {
- if (delegate)
- content_client->utility_ = delegate->CreateContentUtilityClient();
+ content_client->utility_ = delegate->CreateContentUtilityClient();
// TODO(scottmg): http://crbug.com/237249 Should be in _child.
if (!content_client->utility_)
content_client->utility_ = &g_empty_content_utility_client.Get();
@@ -522,10 +512,8 @@ int RunZygote(ContentMainDelegate* delegate) {
std::vector<std::unique_ptr<service_manager::ZygoteForkDelegate>>
zygote_fork_delegates;
- if (delegate) {
- delegate->ZygoteStarting(&zygote_fork_delegates);
- media::InitializeMediaLibrary();
- }
+ delegate->ZygoteStarting(&zygote_fork_delegates);
+ media::InitializeMediaLibrary();
#if defined(OS_LINUX)
PreSandboxInit();
@@ -536,8 +524,7 @@ int RunZygote(ContentMainDelegate* delegate) {
return 1;
}
- if (delegate)
- delegate->ZygoteForked();
+ delegate->ZygoteForked();
// Zygote::HandleForkRequest may have reallocated the command
// line so update it here with the new version.
@@ -567,11 +554,7 @@ int RunZygote(ContentMainDelegate* delegate) {
return kMainFunctions[i].function(main_params);
}
- if (delegate)
- return delegate->RunProcess(process_type, main_params);
-
- NOTREACHED() << "Unknown zygote process type: " << process_type;
- return 1;
+ return delegate->RunProcess(process_type, main_params);
}
#endif // BUILDFLAG(USE_ZYGOTE_HANDLE)
@@ -598,26 +581,20 @@ static void RegisterMainThreadFactories() {
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
// Run the main function for browser process.
// Returns the exit code for this process.
-int RunBrowserProcessMain(
- const MainFunctionParams& main_function_params,
- ContentMainDelegate* delegate,
- std::unique_ptr<BrowserProcessSubThread> service_manager_thread) {
- if (delegate) {
- int exit_code = delegate->RunProcess("", main_function_params);
+int RunBrowserProcessMain(const MainFunctionParams& main_function_params,
+ ContentMainDelegate* delegate) {
+ int exit_code = delegate->RunProcess("", main_function_params);
#if defined(OS_ANDROID)
- // In Android's browser process, the negative exit code doesn't mean the
- // default behavior should be used as the UI message loop is managed by
- // the Java and the browser process's default behavior is always
- // overridden.
+ // In Android's browser process, the negative exit code doesn't mean the
+ // default behavior should be used as the UI message loop is managed by
+ // the Java and the browser process's default behavior is always
+ // overridden.
+ return exit_code;
+#else
+ if (exit_code >= 0)
return exit_code;
+ return BrowserMain(main_function_params);
#endif
- if (exit_code >= 0)
- return exit_code;
- }
- // GetServiceManagerTaskRunnerForEmbedderProcess() needs to be invoked before
- // Run() for the browser process.
- DCHECK(service_manager_thread);
- return BrowserMain(main_function_params, std::move(service_manager_thread));
}
#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
@@ -639,12 +616,9 @@ int RunOtherNamedProcessTypeMain(const std::string& process_type,
for (size_t i = 0; i < base::size(kMainFunctions); ++i) {
if (process_type == kMainFunctions[i].name) {
- if (delegate) {
- int exit_code =
- delegate->RunProcess(process_type, main_function_params);
- if (exit_code >= 0)
- return exit_code;
- }
+ int exit_code = delegate->RunProcess(process_type, main_function_params);
+ if (exit_code >= 0)
+ return exit_code;
return kMainFunctions[i].function(main_function_params);
}
}
@@ -658,11 +632,7 @@ int RunOtherNamedProcessTypeMain(const std::string& process_type,
#endif // BUILDFLAG(USE_ZYGOTE_HANDLE)
// If it's a process we don't know about, the embedder should know.
- if (delegate)
- return delegate->RunProcess(process_type, main_function_params);
-
- NOTREACHED() << "Unknown process type: " << process_type;
- return 1;
+ return delegate->RunProcess(process_type, main_function_params);
}
// static
@@ -682,11 +652,7 @@ ContentMainRunnerImpl::~ContentMainRunnerImpl() {
}
int ContentMainRunnerImpl::TerminateForFatalInitializationError() {
- if (delegate_)
- return delegate_->TerminateForFatalInitializationError();
-
- CHECK(false);
- return 0;
+ return delegate_->TerminateForFatalInitializationError();
}
int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
@@ -747,7 +713,7 @@ int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
#endif // !OS_ANDROID
int exit_code = 0;
- if (delegate_ && delegate_->BasicStartupComplete(&exit_code))
+ if (delegate_->BasicStartupComplete(&exit_code))
return exit_code;
completed_basic_startup_ = true;
@@ -808,13 +774,11 @@ int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
// It's important not to allocate the ports for processes which don't
// register with the power monitor - see https://crbug.com/88867.
if (process_type.empty() ||
- (delegate_ &&
- delegate_->ProcessRegistersWithSystemProcess(process_type))) {
+ delegate_->ProcessRegistersWithSystemProcess(process_type)) {
base::PowerMonitorDeviceSource::AllocateSystemIOPorts();
}
- if (!process_type.empty() &&
- (!delegate_ || delegate_->ShouldSendMachPort(process_type))) {
+ if (!process_type.empty() && delegate_->ShouldSendMachPort(process_type)) {
MachBroker::ChildSendTaskPortToParent();
}
#endif
@@ -889,8 +853,7 @@ int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
}
#endif // !defined(OFFICIAL_BUILD)
- if (delegate_)
- delegate_->PreSandboxStartup();
+ delegate_->PreSandboxStartup();
#if defined(OS_WIN)
if (!InitializeSandbox(
@@ -901,11 +864,11 @@ int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
// Do not initialize the sandbox at this point if the V2
// sandbox is enabled for the process type.
bool v2_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableV2Sandbox);
+ sandbox::switches::kSeatbeltClientName);
if (process_type == switches::kRendererProcess ||
process_type == switches::kPpapiPluginProcess || v2_enabled ||
- (delegate_ && delegate_->DelaySandboxInitialization(process_type))) {
+ delegate_->DelaySandboxInitialization(process_type)) {
// On OS X the renderer sandbox needs to be initialized later in the
// startup sequence in RendererMainPlatformDelegate::EnableSandbox().
} else {
@@ -914,8 +877,7 @@ int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
}
#endif
- if (delegate_)
- delegate_->SandboxInitialized(process_type);
+ delegate_->SandboxInitialized(process_type);
#if BUILDFLAG(USE_ZYGOTE_HANDLE)
if (process_type.empty()) {
@@ -931,7 +893,7 @@ int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
return -1;
}
-int ContentMainRunnerImpl::Run() {
+int ContentMainRunnerImpl::Run(bool start_service_manager_only) {
DCHECK(is_initialized_);
DCHECK(!is_shutdown_);
const base::CommandLine& command_line =
@@ -961,10 +923,30 @@ int ContentMainRunnerImpl::Run() {
// The thread used to start the ServiceManager is handed-off to
// BrowserMain() which may elect to promote it (e.g. to BrowserThread::IO).
if (process_type.empty()) {
- return RunBrowserProcessMain(main_params, delegate_,
- std::move(service_manager_thread_));
+ startup_data_ = std::make_unique<StartupDataImpl>();
+ startup_data_->thread = BrowserProcessSubThread::CreateIOThread();
+ main_params.startup_data = startup_data_.get();
+
+ if (GetContentClient()->browser()->ShouldCreateTaskScheduler()) {
+ // Create the TaskScheduler early to allow upcoming code to use
+ // the post_task.h API. Note: This is okay because RunBrowserProcessMain()
+ // will soon result in invoking TaskScheduler::GetInstance()->Start().
+ // The TaskScheduler being started soon is a strict requirement (delaying
+ // this start would result in posted tasks not running).
+ base::TaskScheduler::Create("Browser");
+ }
+
+ delegate_->PreContentInitialization();
+
+ // Create a MessageLoop if one does not already exist for the current
+ // thread. This thread won't be promoted as BrowserThread::UI until
+ // BrowserMainLoop::MainMessageLoopStart().
+ if (!base::MessageLoopCurrentForUI::IsSet())
+ main_message_loop_ = std::make_unique<base::MessageLoopForUI>();
+
+ return RunBrowserProcessMain(main_params, delegate_);
}
-#endif
+#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
return RunOtherNamedProcessTypeMain(process_type, main_params, delegate_);
}
@@ -973,7 +955,7 @@ void ContentMainRunnerImpl::Shutdown() {
DCHECK(is_initialized_);
DCHECK(!is_shutdown_);
- if (completed_basic_startup_ && delegate_) {
+ if (completed_basic_startup_) {
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
std::string process_type =
@@ -982,6 +964,9 @@ void ContentMainRunnerImpl::Shutdown() {
delegate_->ProcessExiting(process_type);
}
+ // The message loop needs to be destroyed before |exit_manager_|.
+ main_message_loop_.reset();
+
#if defined(OS_WIN)
#ifdef _CRTDBG_MAP_ALLOC
_CrtDumpMemoryLeaks();
@@ -994,14 +979,6 @@ void ContentMainRunnerImpl::Shutdown() {
is_shutdown_ = true;
}
-#if !defined(CHROME_MULTIPLE_DLL_CHILD)
-scoped_refptr<base::SingleThreadTaskRunner>
-ContentMainRunnerImpl::GetServiceManagerTaskRunnerForEmbedderProcess() {
- service_manager_thread_ = BrowserProcessSubThread::CreateIOThread();
- return service_manager_thread_->task_runner();
-}
-#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
-
// static
ContentMainRunner* ContentMainRunner::Create() {
return ContentMainRunnerImpl::Create();
diff --git a/chromium/content/app/content_main_runner_impl.h b/chromium/content/app/content_main_runner_impl.h
index 7fab6f739f7..aff316c59df 100644
--- a/chromium/content/app/content_main_runner_impl.h
+++ b/chromium/content/app/content_main_runner_impl.h
@@ -9,7 +9,9 @@
#include "base/callback_forward.h"
#include "base/memory/scoped_refptr.h"
+#include "base/message_loop/message_loop.h"
#include "build/build_config.h"
+#include "content/browser/startup_data_impl.h"
#include "content/public/app/content_main.h"
#include "content/public/app/content_main_runner.h"
#include "content/public/common/content_client.h"
@@ -22,11 +24,9 @@
namespace base {
class AtExitManager;
-class SingleThreadTaskRunner;
} // namespace base
namespace content {
-class BrowserProcessSubThread;
class ContentMainDelegate;
struct ContentMainParams;
@@ -41,16 +41,9 @@ class ContentMainRunnerImpl : public ContentMainRunner {
// ContentMainRunner:
int Initialize(const ContentMainParams& params) override;
- int Run() override;
+ int Run(bool start_service_manager_only) override;
void Shutdown() override;
-#if !defined(CHROME_MULTIPLE_DLL_CHILD)
- // Creates a thread and returns the SingleThreadTaskRunner on which
- // ServiceManager should run.
- scoped_refptr<base::SingleThreadTaskRunner>
- GetServiceManagerTaskRunnerForEmbedderProcess();
-#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
-
private:
// True if the runner has been initialized.
bool is_initialized_ = false;
@@ -75,12 +68,14 @@ class ContentMainRunnerImpl : public ContentMainRunner {
base::mac::ScopedNSAutoreleasePool* autorelease_pool_ = nullptr;
#endif
- std::unique_ptr<BrowserProcessSubThread> service_manager_thread_;
-
base::Closure* ui_task_ = nullptr;
CreatedMainPartsClosure* created_main_parts_closure_ = nullptr;
+ std::unique_ptr<base::MessageLoop> main_message_loop_;
+
+ std::unique_ptr<StartupDataImpl> startup_data_;
+
DISALLOW_COPY_AND_ASSIGN(ContentMainRunnerImpl);
};
diff --git a/chromium/content/app/content_service_manager_main_delegate.cc b/chromium/content/app/content_service_manager_main_delegate.cc
index f3132ac7103..fc86a7426c5 100644
--- a/chromium/content/app/content_service_manager_main_delegate.cc
+++ b/chromium/content/app/content_service_manager_main_delegate.cc
@@ -50,7 +50,7 @@ bool ContentServiceManagerMainDelegate::IsEmbedderSubprocess() {
}
int ContentServiceManagerMainDelegate::RunEmbedderProcess() {
- return content_main_runner_->Run();
+ return content_main_runner_->Run(start_service_manager_only_);
}
void ContentServiceManagerMainDelegate::ShutDownEmbedderProcess() {
@@ -65,7 +65,7 @@ ContentServiceManagerMainDelegate::OverrideProcessType() {
}
void ContentServiceManagerMainDelegate::OverrideMojoConfiguration(
- mojo::edk::Configuration* config) {
+ mojo::core::Configuration* config) {
// If this is the browser process and there's no remote service manager, we
// will serve as the global Mojo broker.
if (!service_manager::ServiceManagerIsRemote() &&
@@ -126,11 +126,9 @@ ContentServiceManagerMainDelegate::CreateEmbeddedService(
return nullptr;
}
-#if !defined(CHROME_MULTIPLE_DLL_CHILD)
-scoped_refptr<base::SingleThreadTaskRunner> ContentServiceManagerMainDelegate::
- GetServiceManagerTaskRunnerForEmbedderProcess() {
- return content_main_runner_->GetServiceManagerTaskRunnerForEmbedderProcess();
+void ContentServiceManagerMainDelegate::SetStartServiceManagerOnly(
+ bool start_service_manager_only) {
+ start_service_manager_only_ = start_service_manager_only;
}
-#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
} // namespace content
diff --git a/chromium/content/app/content_service_manager_main_delegate.h b/chromium/content/app/content_service_manager_main_delegate.h
index a6ab54a14bc..6f32f97e3f9 100644
--- a/chromium/content/app/content_service_manager_main_delegate.h
+++ b/chromium/content/app/content_service_manager_main_delegate.h
@@ -25,15 +25,11 @@ class ContentServiceManagerMainDelegate : public service_manager::MainDelegate {
// service_manager::MainDelegate:
int Initialize(const InitializeParams& params) override;
-#if !defined(CHROME_MULTIPLE_DLL_CHILD)
- scoped_refptr<base::SingleThreadTaskRunner>
- GetServiceManagerTaskRunnerForEmbedderProcess() override;
-#endif // !defined(CHROME_MULTIPLE_DLL_CHILD)
bool IsEmbedderSubprocess() override;
int RunEmbedderProcess() override;
void ShutDownEmbedderProcess() override;
service_manager::ProcessType OverrideProcessType() override;
- void OverrideMojoConfiguration(mojo::edk::Configuration* config) override;
+ void OverrideMojoConfiguration(mojo::core::Configuration* config) override;
std::unique_ptr<base::Value> CreateServiceCatalog() override;
bool ShouldLaunchAsServiceProcess(
const service_manager::Identity& identity) override;
@@ -46,6 +42,10 @@ class ContentServiceManagerMainDelegate : public service_manager::MainDelegate {
std::unique_ptr<service_manager::Service> CreateEmbeddedService(
const std::string& service_name) override;
+ // Sets the flag whether to start the Service Manager without starting the
+ // full browser.
+ void SetStartServiceManagerOnly(bool start_service_manager_only);
+
private:
ContentMainParams content_main_params_;
std::unique_ptr<ContentMainRunnerImpl> content_main_runner_;
@@ -54,6 +54,10 @@ class ContentServiceManagerMainDelegate : public service_manager::MainDelegate {
bool initialized_ = false;
#endif
+ // Indicates whether to start the Service Manager without starting the full
+ // browser.
+ bool start_service_manager_only_ = false;
+
DISALLOW_COPY_AND_ASSIGN(ContentServiceManagerMainDelegate);
};
diff --git a/chromium/content/app/mojo/mojo_init.cc b/chromium/content/app/mojo/mojo_init.cc
index c32f688aa99..6b9b3773ab1 100644
--- a/chromium/content/app/mojo/mojo_init.cc
+++ b/chromium/content/app/mojo/mojo_init.cc
@@ -10,8 +10,8 @@
#include "base/lazy_instance.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_channel.h"
-#include "mojo/edk/embedder/configuration.h"
-#include "mojo/edk/embedder/embedder.h"
+#include "mojo/core/embedder/configuration.h"
+#include "mojo/core/embedder/embedder.h"
namespace content {
@@ -20,9 +20,9 @@ namespace {
class MojoInitializer {
public:
MojoInitializer() {
- mojo::edk::Configuration config;
+ mojo::core::Configuration config;
config.max_message_num_bytes = IPC::Channel::kMaximumMessageSize;
- mojo::edk::Init(config);
+ mojo::core::Init(config);
}
};
diff --git a/chromium/content/app/strings/content_strings.grd b/chromium/content/app/strings/content_strings.grd
index e2ea8177ef6..e08494f1c85 100644
--- a/chromium/content/app/strings/content_strings.grd
+++ b/chromium/content/app/strings/content_strings.grd
@@ -229,6 +229,9 @@ below:
Week
</message>
+ <message name="IDS_AX_CALENDAR_SHOW_DATE_PICKER" desc="Accessible description of a button to show a calendar from a date input field.">
+ Show date picker
+ </message>
<message name="IDS_AX_CALENDAR_SHOW_MONTH_SELECTOR" desc="Accessible description of a button to show month selection panel in a calendar picker.">
Show month selection panel
</message>
@@ -251,6 +254,12 @@ below:
<message name="IDS_AX_ROLE_COMPLEMENTARY" desc="Accessibility role description for complementary">
complementary
</message>
+ <message name="IDS_AX_ROLE_CONTENT_DELETION" desc="Accessibility role description for content deletion, meaning content that is has been or is suggested to be removed from a document, such as in a revision review">
+ deletion
+ </message>
+ <message name="IDS_AX_ROLE_CONTENT_INSERTION" desc="Accessibility role description for content insertion, meaning content that has been marked or is suggested to be inserte nto a document, such as in a revision review">
+ insertion
+ </message>
<message name="IDS_AX_ROLE_CHECK_BOX" desc="Accessibility role description for a check box">
checkbox
</message>
@@ -467,9 +476,6 @@ below:
<message name="IDS_AX_ROLE_BUTTON" desc="Accessibility role description for a button">
button
</message>
- <message name="IDS_AX_ROLE_CELL" desc="Accessibility role description for a cell, like in a table or grid">
- cell
- </message>
<message name="IDS_AX_ROLE_COLOR_WELL" desc="Accessibility role description for a color picker">
color picker
</message>
@@ -654,6 +660,14 @@ below:
exit full screen
</message>
+ <message name="IDS_AX_MEDIA_ENTER_PICTURE_IN_PICTURE_BUTTON" desc="Accessibility role description for enter Picture-in-Picture button">
+ enter picture-in-picture
+ </message>
+
+ <message name="IDS_AX_MEDIA_EXIT_PICTURE_IN_PICTURE_BUTTON" desc="Accessibility role description for exit Picture-in-Picture button">
+ exit picture-in-picture
+ </message>
+
<message name="IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON" desc="Accessibility role description for show closed captions button">
show closed captions
</message>
@@ -726,6 +740,14 @@ below:
exit full screen
</message>
+ <message name="IDS_AX_MEDIA_ENTER_PICTURE_IN_PICTURE_BUTTON_HELP" desc="Accessibility help description for enter Picture-in-Picture button">
+ play video in picture-in-picture mode
+ </message>
+
+ <message name="IDS_AX_MEDIA_EXIT_PICTURE_IN_PICTURE_BUTTON_HELP" desc="Accessibility help description for exit Picture-in-Picture button">
+ exit picture-in-picture
+ </message>
+
<message name="IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP" desc="Accessibility help description for show closed captions button">
start displaying closed captions
</message>
@@ -932,11 +954,21 @@ 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_OVERFLOW_MENU_PICTURE_IN_PICTURE" desc="Media controls overflow menu item label for a picture-in-picture button.">
- Picture-in-Picture
+ <if expr="is_macosx">
+ <message name="IDS_MEDIA_OVERFLOW_MENU_ENTER_PICTURE_IN_PICTURE" desc="Media contr ls overflow menu item label for a button to enter Picture-in-Picture.">
+ Picture in Picture
+ </message>
+ </if>
+ <if expr="not is_macosx">
+ <message name="IDS_MEDIA_OVERFLOW_MENU_ENTER_PICTURE_IN_PICTURE" desc="Media controls overflow menu item label for a button to enter Picture-in-Picture.">
+ Picture in picture
+ </message>
+ </if>
+ <message name="IDS_MEDIA_OVERFLOW_MENU_EXIT_PICTURE_IN_PICTURE" desc="Media controls overflow menu item label for a button to exit Picture-in-Picture.">
+ Exit picture-in-picture mode
</message>
<message name="IDS_MEDIA_PICTURE_IN_PICTURE_INTERSTITIAL_TEXT" desc="Text message shown to user when in picture in picture mode. When a video is in picture in picture mode, an interstitial with this text appears where the video player is positioned. The video continues to play back in another window that gives the experience that the video is 'popped out'.">
- This video is playing in Picture-in-Picture
+ This video is playing in picture-in-picture mode
</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>
diff --git a/chromium/content/app/strings/translations/content_strings_am.xtb b/chromium/content/app/strings/translations/content_strings_am.xtb
index 6e66f3b1caa..e68c2ac0791 100644
--- a/chromium/content/app/strings/translations/content_strings_am.xtb
+++ b/chromium/content/app/strings/translations/content_strings_am.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">ተንሸራታች</translation>
<translation id="1211441953136645838">የግርጌ ማስታወሻ</translation>
<translation id="1281252709823657822">መገናኛ</translation>
+<translation id="1289247557029249093">ከሥዕል-ውስጥ-ሥዕል ሁነታ ውጣ</translation>
<translation id="1335095011850992622">ክሬዲቶች</translation>
<translation id="1342835525016946179">ጽሑፍ</translation>
<translation id="1359897965706325498">ሰንደቅ</translation>
+<translation id="1548116112524424341">ቪዲዮን በስዕል-ውስጥ-ስዕል ሁነታ አጫውት</translation>
<translation id="1589122976691792535">ክልል</translation>
<translation id="1591562245178063882">በዚህ ወር</translation>
<translation id="1637811476055996098">ፋይሎችን ይምረጡ</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">የዛፍ ፍርግርግ</translation>
<translation id="1822429046913737220">ጥዋት/ከሰዓት</translation>
<translation id="1832974991323546415">በርቀት መሳሪያ ላይ አጫውት</translation>
+<translation id="190587075670221089">ስረዛ</translation>
<translation id="1907737156431278478">ምሳሌ</translation>
<translation id="1921819250265091946">ቀቀ</translation>
<translation id="1930711995431081526">ሁኔታ</translation>
<translation id="1938124657309484470">ዋጋ <ph name="MAXIMUM_DATE_OR_TIME" /> ወይም ከዚያ በፊት መሆን አለበት።</translation>
+<translation id="1946271899482435442">የቀን መልቀሚያ አሳይ</translation>
<translation id="1993104285338243655">ወደ ማንጸባረቅ ተቀይሯል</translation>
<translation id="2060505056492490888">«<ph name="DOT" />» በ«<ph name="INVALIDDOMAIN" />» ውስጥ በተሳሳተ ቦታ ላይ ነው የገባው።</translation>
<translation id="2148716181193084225">ዛሬ</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">አስገባ</translation>
<translation id="2657045182931379222">ግራፊካዊ ነገር</translation>
<translation id="2674318244760992338">ግርጌ</translation>
+<translation id="2706474812903655270">ይህ ቪዲዮ ስዕል-በስዕል ላይ እያጫወተ ነው</translation>
<translation id="2709516037105925701">ራስ-ሙላ</translation>
<translation id="2723001399770238859">ድምጽ</translation>
<translation id="2746543609216772311">ዋጋ <ph name="MINIMUM_DATE_OR_TIME" /> ወይም ከዚያ በኋላ መሆን አለበት።</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">ቀጣዩን ወር አሳይ</translation>
<translation id="512758898067543763">የረድፍ ራስጌ</translation>
<translation id="5143125788380636750">ድሕረ ታሪክ</translation>
-<translation id="5153163864850940242">ይህ ቪዲዮ ስዕል-በስዕል ውስጥ እያጫወተ ነው</translation>
<translation id="5164977714490026579">ዋጋ ከ<ph name="MINIMUM" /> የሚበልጥ ወይም ከእሱ እኩል መሆን አለበት።</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> ፔታ</translation>
<translation id="5307600278924710095">እባክዎ አንድ ክፍል ያስገቡና «<ph name="ATSIGN" />»ን ያስከትሉ። «<ph name="INVALIDADDRESS" />» ያልተሟላ ነው።</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">ኮሎፎን</translation>
<translation id="6934078000481955284">የጽሑፍ ጥቅስ</translation>
<translation id="6941933287844615239">ማህደረ መረጃን አውርድ</translation>
+<translation id="6981594929165378967">ማስገባት</translation>
<translation id="6989848892321993519">እባክዎ ይህን ጽሑፍ ወደ <ph name="MIN_CHARACTERS" /> ወይም ከዚያ በላይ ቁምፊዎች ያራዝሙት (አሁን እየተጠቀሙ ያሉት 1 ቁምፊ ነው)።</translation>
<translation id="709897737746224366">እባክዎ የተጠየቀውን ቅርጸት ያዛምዱ።</translation>
<translation id="7139483182332611405">መቅድም</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">ቀሪ ጊዜ</translation>
<translation id="7740016676195725605">የተዘጉ የስዕል መግለጫዎችን ማሳየት አቁም</translation>
<translation id="7740050170769002709">የኤች ቲ ኤም ኤል ይዘት</translation>
+<translation id="7750228210027921155">በሥዕል ውስጥ ሥዕል</translation>
<translation id="7789962463072032349">ላፍታ አቁም</translation>
<translation id="7802800022689234070">ይፋ ማሳወቂያ ሶስት ማዕዘን</translation>
<translation id="7888071071722539607">እባክዎ በኢሜይል አድራሻው ውስጥ «<ph name="ATSIGN" />» ያካትቱ። «<ph name="INVALIDADDRESS" />» ውስጥ «<ph name="ATSIGN" />» ይጎድላል።</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">ማውጫ</translation>
<translation id="8613126697340063924">በርቀት መልሶ ማጫወትን ተቆጣጠር</translation>
<translation id="862370744433916922">የግርጌ ጽሑፍ</translation>
-<translation id="8741316211671074806">በስዕል-ውስጥ-ስዕል</translation>
<translation id="8750798805984357768">እባክዎ ከእነዚህ አማራጮች ውስጥ አንዱን ይምረጡ።</translation>
<translation id="8785498733064193001">መልሶ ማጫወት ይጀምሩ</translation>
<translation id="8808573423886751634">ምዕራፍ</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">አሰሳ</translation>
<translation id="9050748414552849310">የተዘጉ የስዕል መግለጫዎችን አሳይ</translation>
<translation id="9062295712474918030">ሰነድ</translation>
+<translation id="9093215626363556771">ከስዕል-ውስጥ-ስዕል ውጣ</translation>
<translation id="9108370397979208512">ሒሳብ</translation>
<translation id="9132465097189459683">ሌላ...</translation>
<translation id="9138385573473225930">ማንቂያ</translation>
<translation id="9155987714137265666"><ph name="WEEK" />፣ የሚጀምረው በ<ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">በሥዕል ላይ ሥዕል</translation>
<translation id="9168329111483466115">የግርጌ ማስታወሻ</translation>
-<translation id="947831847158436616">ሕዋስ</translation>
+<translation id="954003015749068518">ወደ ስዕል-ውስጥ-ስዕል ይግቡ</translation>
<translation id="966787709310836684">ምናሌ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_ar.xtb b/chromium/content/app/strings/translations/content_strings_ar.xtb
index 1b74c3db7b1..380b81cc11d 100644
--- a/chromium/content/app/strings/translations/content_strings_ar.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ar.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">شريط تمرير</translation>
<translation id="1211441953136645838">تعليق ختامي</translation>
<translation id="1281252709823657822">مربع حوار</translation>
+<translation id="1289247557029249093">الخروج من وضع "نافذة ضمن النافذة"</translation>
<translation id="1335095011850992622">إسهامات</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">إعلان بانر</translation>
+<translation id="1548116112524424341">تشغيل الفيديو في وضع "نافذة ضمن نافذة"</translation>
<translation id="1589122976691792535">منطقة</translation>
<translation id="1591562245178063882">هذا الشهر</translation>
<translation id="1637811476055996098">اختيار الملفات</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">شبكة متفرعة</translation>
<translation id="1822429046913737220">صباحًا/مساءً</translation>
<translation id="1832974991323546415">تشغيل على جهاز بعيد</translation>
+<translation id="190587075670221089">حذف</translation>
<translation id="1907737156431278478">مثال</translation>
<translation id="1921819250265091946">يوم</translation>
<translation id="1930711995431081526">الحالة</translation>
<translation id="1938124657309484470">يجب أن تكون القيمة <ph name="MAXIMUM_DATE_OR_TIME" /> أو قبل ذلك.</translation>
+<translation id="1946271899482435442">عرض منتقي التاريخ</translation>
<translation id="1993104285338243655">تم التبديل إلى النسخ المطابق.</translation>
<translation id="2060505056492490888">تم استخدام "<ph name="DOT" />" في موضع خاطئ في "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">اليوم</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">إرسال</translation>
<translation id="2657045182931379222">كائن رسومي</translation>
<translation id="2674318244760992338">تذييل</translation>
+<translation id="2706474812903655270">يتم تشغيل هذا الفيديو في الوضع "نافذة ضمن النافذة".</translation>
<translation id="2709516037105925701">الملء التلقائي</translation>
<translation id="2723001399770238859">الصوت</translation>
<translation id="2746543609216772311">يجب أن تكون القيمة <ph name="MINIMUM_DATE_OR_TIME" /> أو بعد ذلك.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">عرض الشهر التالي</translation>
<translation id="512758898067543763">عنوان الصف</translation>
<translation id="5143125788380636750">تتِّمة</translation>
-<translation id="5153163864850940242">يتم تشغيل هذا الفيديو في الوضع "نافذة ضمن النافذة".</translation>
<translation id="5164977714490026579">يجب أن تكون القيمة أكبر من أو تساوي <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> بيتابايت</translation>
<translation id="5307600278924710095">يُرجى إدخال جزء متبوع بعلامة "<ph name="ATSIGN" />"، حيث إن "<ph name="INVALIDADDRESS" />" غير مكتمل.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">إشارة ناشر</translation>
<translation id="6934078000481955284">علامة اقتباس فقرة</translation>
<translation id="6941933287844615239">تنزيل وسائط</translation>
+<translation id="6981594929165378967">إدراج</translation>
<translation id="6989848892321993519">يُرجى إطالة هذا النص إلى <ph name="MIN_CHARACTERS" /> من الحروف أو أكثر (أنت الآن تستخدم حرفًا واحدًا).</translation>
<translation id="709897737746224366">يُرجى مطابقة التنسيق المطلوب.</translation>
<translation id="7139483182332611405">تمهيد</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">المدة المتبقية</translation>
<translation id="7740016676195725605">إيقاف عرض الترجمة والشرح</translation>
<translation id="7740050170769002709">‏محتوى HTML</translation>
+<translation id="7750228210027921155">نافذة ضمن النافذة</translation>
<translation id="7789962463072032349">إيقاف مؤقت</translation>
<translation id="7802800022689234070">مثلث الإفصاح</translation>
<translation id="7888071071722539607">يُرجى تضمين العلامة "<ph name="ATSIGN" />" في عنوان البريد الإلكتروني، حيث يفتقر "<ph name="INVALIDADDRESS" />" إلى العلامة "<ph name="ATSIGN" />".</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">جدول المحتويات</translation>
<translation id="8613126697340063924">التحكم في التشغيل عن بعد</translation>
<translation id="862370744433916922">ترجمة مصاحِبة</translation>
-<translation id="8741316211671074806">نافذة ضمن النافذة</translation>
<translation id="8750798805984357768">يُرجى اختيار أحد هذه الخيارات.</translation>
<translation id="8785498733064193001">بدء التشغيل</translation>
<translation id="8808573423886751634">فصل</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">تنقل</translation>
<translation id="9050748414552849310">عرض الترجمة والشرح</translation>
<translation id="9062295712474918030">المستند</translation>
+<translation id="9093215626363556771">الخروج من وضع "نافذة ضمن نافذة"</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">آخر...</translation>
<translation id="9138385573473225930">تنبيه</translation>
<translation id="9155987714137265666"><ph name="WEEK" />، ابتداء من <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">نافذة ضمن النافذة</translation>
<translation id="9168329111483466115">حاشية سُفلية</translation>
-<translation id="947831847158436616">خلية</translation>
+<translation id="954003015749068518">الدخول في وضع "نافذة ضمن نافذة"</translation>
<translation id="966787709310836684">القائمة</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_bg.xtb b/chromium/content/app/strings/translations/content_strings_bg.xtb
index 14dc2f943d5..a9d48c867bb 100644
--- a/chromium/content/app/strings/translations/content_strings_bg.xtb
+++ b/chromium/content/app/strings/translations/content_strings_bg.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">плъзгач</translation>
<translation id="1211441953136645838">бележка в края</translation>
<translation id="1281252709823657822">диалогов прозорец</translation>
+<translation id="1289247557029249093">Изход от режима „Картина в картината“</translation>
<translation id="1335095011850992622">признания за източника</translation>
<translation id="1342835525016946179">статия</translation>
<translation id="1359897965706325498">банер</translation>
+<translation id="1548116112524424341">възпроизвеждане на видеоклипа в режим „картина в картината“</translation>
<translation id="1589122976691792535">регион</translation>
<translation id="1591562245178063882">Този месец</translation>
<translation id="1637811476055996098">Избор на файлове</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">дървовидна таблица</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">възпроизвеждане на отдалечено устройство</translation>
+<translation id="190587075670221089">изтриване</translation>
<translation id="1907737156431278478">пример</translation>
<translation id="1921819250265091946">дд</translation>
<translation id="1930711995431081526">състояние</translation>
<translation id="1938124657309484470">Стойността трябва да е <ph name="MAXIMUM_DATE_OR_TIME" /> или по-рано.</translation>
+<translation id="1946271899482435442">Показване на инструмента за избор на дата</translation>
<translation id="1993104285338243655">Превключихте към дублиране</translation>
<translation id="2060505056492490888">„<ph name="DOT" />“ се използва на неправилна позиция в/ъв „<ph name="INVALIDDOMAIN" />“.</translation>
<translation id="2148716181193084225">Днес</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Изпращане</translation>
<translation id="2657045182931379222">графичен обект</translation>
<translation id="2674318244760992338">долен колонтитул</translation>
+<translation id="2706474812903655270">Този видеоклип се възпроизвежда в режим „Картина в картината“</translation>
<translation id="2709516037105925701">Автоматично попълване</translation>
<translation id="2723001399770238859">звук</translation>
<translation id="2746543609216772311">Стойността трябва да е <ph name="MINIMUM_DATE_OR_TIME" /> или по-късно.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Показване на следващия месец</translation>
<translation id="512758898067543763">заглавка на ред</translation>
<translation id="5143125788380636750">епилог</translation>
-<translation id="5153163864850940242">Този видеоклип се възпроизвежда в режим „Картина в картината“</translation>
<translation id="5164977714490026579">Стойността трябва да е по-голяма или равна на <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> ПБ</translation>
<translation id="5307600278924710095">Моля, въведете текст преди „<ph name="ATSIGN" />“. „<ph name="INVALIDADDRESS" />“ е непълно.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">колофон</translation>
<translation id="6934078000481955284">блоков цитат</translation>
<translation id="6941933287844615239">изтегляне на мултимедията</translation>
+<translation id="6981594929165378967">вмъкване</translation>
<translation id="6989848892321993519">Моля, удължете този текст до поне <ph name="MIN_CHARACTERS" /> знака (понастоящем използвате 1 знак).</translation>
<translation id="709897737746224366">Моля, спазвайте изисквания формат.</translation>
<translation id="7139483182332611405">предисловие</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">оставащо време</translation>
<translation id="7740016676195725605">спиране на показването на надписите</translation>
<translation id="7740050170769002709">HTML съдържание</translation>
+<translation id="7750228210027921155">Картина в картината</translation>
<translation id="7789962463072032349">поставяне на пауза</translation>
<translation id="7802800022689234070">триъгълник за разкриване на съдържание</translation>
<translation id="7888071071722539607">Моля, включете „<ph name="ATSIGN" />“ в имейл адреса. В/ъв „<ph name="INVALIDADDRESS" />“ липсва „<ph name="ATSIGN" />“.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">съдържание</translation>
<translation id="8613126697340063924">управление на отдалеченото възпроизвеждане</translation>
<translation id="862370744433916922">подзаглавие</translation>
-<translation id="8741316211671074806">Картина в картината</translation>
<translation id="8750798805984357768">Моля, изберете една от тези опции.</translation>
<translation id="8785498733064193001">начало на възпроизвеждането</translation>
<translation id="8808573423886751634">глава</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">навигация</translation>
<translation id="9050748414552849310">показване на надписите</translation>
<translation id="9062295712474918030">документ</translation>
+<translation id="9093215626363556771">изход от режима „Картина в картината“</translation>
<translation id="9108370397979208512">математически израз</translation>
<translation id="9132465097189459683">Други...</translation>
<translation id="9138385573473225930">сигнал</translation>
<translation id="9155987714137265666"><ph name="WEEK" /> – започва от <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Картина в картината</translation>
<translation id="9168329111483466115">бележка под линия</translation>
-<translation id="947831847158436616">клетка</translation>
+<translation id="954003015749068518">вход в режима „Картина в картината“</translation>
<translation id="966787709310836684">меню</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_bn.xtb b/chromium/content/app/strings/translations/content_strings_bn.xtb
index e0bf864e511..43402dab92d 100644
--- a/chromium/content/app/strings/translations/content_strings_bn.xtb
+++ b/chromium/content/app/strings/translations/content_strings_bn.xtb
@@ -2,7 +2,7 @@
<!DOCTYPE translationbundle>
<translationbundle lang="bn">
<translation id="1018939186200882850">মেনু আইটেম</translation>
-<translation id="1020833440720551630">অডিও ট্র্যাক নিঃশব্দ করুন</translation>
+<translation id="1020833440720551630">অডিও ট্র্যাক মিউট করুন</translation>
<translation id="10623998915015855">টগল বোতাম</translation>
<translation id="1088086359088493902">সেকেন্ড</translation>
<translation id="1171774979989969504">দয়া করে কোন ইমেল ঠিকানা প্রবেশ করান:</translation>
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">স্লাইডার</translation>
<translation id="1211441953136645838">এন্ডনোট</translation>
<translation id="1281252709823657822">ডায়ালগ</translation>
+<translation id="1289247557029249093">ছবির-মধ্যে-ছবি মোড থেকে বেরিয়ে আসুন</translation>
<translation id="1335095011850992622">ক্রেডিট</translation>
<translation id="1342835525016946179">নিবন্ধ</translation>
<translation id="1359897965706325498">ব্যানার</translation>
+<translation id="1548116112524424341">ছবির-মধ্যে-ছবি মোডে ভিডিও চালান</translation>
<translation id="1589122976691792535">অঞ্চল</translation>
<translation id="1591562245178063882">এই মাস</translation>
<translation id="1637811476055996098">ফাইল বেছে নিন</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">ট্রি গ্রিড</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">রিমোট ডিভাইসে প্লে করুন</translation>
+<translation id="190587075670221089">মোছা হচ্ছে</translation>
<translation id="1907737156431278478">উদাহরণ</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">স্থিতি</translation>
<translation id="1938124657309484470">মানকে অবশ্যই <ph name="MAXIMUM_DATE_OR_TIME" /> বা আগের হতে হবে৷</translation>
+<translation id="1946271899482435442">তারিখ বেছে নেওয়ার বিকল্পটি দেখান</translation>
<translation id="1993104285338243655">মিররিং এ পরিবর্তন করা হয়েছে</translation>
<translation id="2060505056492490888">'<ph name="INVALIDDOMAIN" />' এ একটি ভুল অবস্থানে '<ph name="DOT" />' ব্যবহৃত হয়েছে৷</translation>
<translation id="2148716181193084225">আজ</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">জমা দিন</translation>
<translation id="2657045182931379222">গ্রাফিক্স অবজেক্ট</translation>
<translation id="2674318244760992338">পাদলেখ</translation>
+<translation id="2706474812903655270">এই ভিডিওটি ছবির-মধ্যে-ছবি মোডে চালানো হচ্ছে</translation>
<translation id="2709516037105925701">স্বয়ংপূরণ</translation>
<translation id="2723001399770238859">অডিও</translation>
<translation id="2746543609216772311">মানকে অবশ্যই <ph name="MINIMUM_DATE_OR_TIME" /> বা পরবর্তী হতে হবে৷</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">পরবর্তী মাস দেখান</translation>
<translation id="512758898067543763">সারি শিরোলেখ</translation>
<translation id="5143125788380636750">উপসংহার</translation>
-<translation id="5153163864850940242">এই ভিডিওটি ছবির-মধ্যে-ছবিতে চালানো হচ্ছে</translation>
<translation id="5164977714490026579">মানটি অবশ্যই <ph name="MINIMUM" />এর চেয়ে বেশি বা সমান হবে৷</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">'<ph name="ATSIGN" />' অনুসরণ করে একটি অংশ লিখুন৷ '<ph name="INVALIDADDRESS" />' অসম্পূর্ণ৷</translation>
@@ -129,7 +133,7 @@
<translation id="5643186887447432888">বোতাম</translation>
<translation id="5677946354068040947">আরও বিকল্প</translation>
<translation id="576709008726043716">পরিচয়</translation>
-<translation id="57838592816432529">নিঃশব্দ করুন</translation>
+<translation id="57838592816432529">মিউট করুন</translation>
<translation id="5860033963881614850">বন্ধ করুন</translation>
<translation id="588258955323874662">সম্পূর্নস্ক্রীণ</translation>
<translation id="5888666972993069672"><ph name="DEVICE_FRIENDLY_NAME" /> এ কাস্ট করা হচ্ছে</translation>
@@ -159,12 +163,13 @@
<translation id="6790428901817661496">চালু করুন</translation>
<translation id="6820355525329141109">প্লাগ ইন লোড করা যায়নি।</translation>
<translation id="6820615603175220800">বিবলিওগ্রাফি রেফারেন্স</translation>
-<translation id="6843725295806269523">নিঃশব্দ</translation>
+<translation id="6843725295806269523">মিউট</translation>
<translation id="6853785296079745596">বন্ধ করা পরিচয়লিপিগুলি লুকান</translation>
<translation id="6885760532393684712">ডিরেক্টরি</translation>
<translation id="689129560213475294">বইটির সম্পর্কে</translation>
<translation id="6934078000481955284">ব্লক উদ্ধৃতি</translation>
<translation id="6941933287844615239">মিডিয়া ডাউনলোড করুন</translation>
+<translation id="6981594929165378967">যোগ করা হচ্ছে</translation>
<translation id="6989848892321993519">দয়া করে এই পাঠ্যকে ন্যূনতম <ph name="MIN_CHARACTERS" /> অক্ষরের বা তার বেশি দৈর্ঘ্যের করুন (আপনি বর্তমানে ১টি অক্ষর ব্যবহার করেছেন)।</translation>
<translation id="709897737746224366">দয়া করে অনুরোধ হওয়া বিন্যাসটি মেলান৷</translation>
<translation id="7139483182332611405">মুখবন্ধ</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">অবশিষ্ট সময়</translation>
<translation id="7740016676195725605">বদ্ধ পরিচয়লিপিগুলির প্রদর্শন থামান</translation>
<translation id="7740050170769002709">HTML সামগ্রী</translation>
+<translation id="7750228210027921155">ছবির-মধ্যে-ছবি</translation>
<translation id="7789962463072032349">বিরাম</translation>
<translation id="7802800022689234070">উম্মোচন ত্রিভুজ</translation>
<translation id="7888071071722539607">ইমেল ঠিনাকাটিতে দয়া করে একটি '<ph name="ATSIGN" />' অন্তর্ভুক্ত করুন৷ '<ph name="INVALIDADDRESS" />' এ একটি '<ph name="ATSIGN" />' অনুপস্থিত৷</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">সূচিপত্র</translation>
<translation id="8613126697340063924">রিমোট প্লেব্যাক নিয়ন্ত্রণ করুন</translation>
<translation id="862370744433916922">সাবটাইটেল</translation>
-<translation id="8741316211671074806">ছবির-মধ্যে-ছবি</translation>
<translation id="8750798805984357768">দয়া করে বিকল্পগুলির একটি নির্বাচন করুন৷</translation>
<translation id="8785498733064193001">প্লেব্যাক শুরু করুন</translation>
<translation id="8808573423886751634">অধ্যায়</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">নেভিগেশন</translation>
<translation id="9050748414552849310">বন্ধ করা পরিচয়লিপিগুলি দেখান</translation>
<translation id="9062295712474918030">দস্তাবেজ</translation>
+<translation id="9093215626363556771">ছবির-মধ্যে-ছবি মোড থেকে বেরিয়ে আসুন</translation>
<translation id="9108370397979208512">গণিত</translation>
<translation id="9132465097189459683">অন্যান্য...</translation>
<translation id="9138385573473225930">সতর্কতা</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, <ph name="WEEK_START_DATE" /> এ শুরু</translation>
+<translation id="916607977885256133">ছবির-মধ্যে-ছবি</translation>
<translation id="9168329111483466115">ফুটনোট</translation>
-<translation id="947831847158436616">কক্ষ</translation>
+<translation id="954003015749068518">ছবির-মধ্যে-ছবি মোডে যান</translation>
<translation id="966787709310836684">মেনু</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_ca.xtb b/chromium/content/app/strings/translations/content_strings_ca.xtb
index fd56238d889..391d68d1d31 100644
--- a/chromium/content/app/strings/translations/content_strings_ca.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ca.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">control lliscant</translation>
<translation id="1211441953136645838">nota final</translation>
<translation id="1281252709823657822">quadre de diàleg</translation>
+<translation id="1289247557029249093">Surt del mode de pantalla en pantalla</translation>
<translation id="1335095011850992622">crèdits</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">bàner</translation>
+<translation id="1548116112524424341">reprodueix el vídeo en mode de pantalla en pantalla</translation>
<translation id="1589122976691792535">regió</translation>
<translation id="1591562245178063882">Aquest mes</translation>
<translation id="1637811476055996098">Trieu els fitxers</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">quadrícula d'arbre</translation>
<translation id="1822429046913737220">a. m./p. m.</translation>
<translation id="1832974991323546415">reprodueix al dispositiu remot</translation>
+<translation id="190587075670221089">supressió</translation>
<translation id="1907737156431278478">exemple</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">estat</translation>
<translation id="1938124657309484470">El valor ha de ser <ph name="MAXIMUM_DATE_OR_TIME" /> o anterior.</translation>
+<translation id="1946271899482435442">Mostra el selector de dates</translation>
<translation id="1993104285338243655">S'ha canviat a projecció</translation>
<translation id="2060505056492490888">"<ph name="DOT" />" s'ha utilitzat en una posició incorrecta a "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">Avui</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Envia</translation>
<translation id="2657045182931379222">objecte gràfic</translation>
<translation id="2674318244760992338">peu</translation>
+<translation id="2706474812903655270">Aquest vídeo s'està reproduint en mode de pantalla en pantalla</translation>
<translation id="2709516037105925701">Emplenament autom.</translation>
<translation id="2723001399770238859">àudio</translation>
<translation id="2746543609216772311">El valor ha de ser <ph name="MINIMUM_DATE_OR_TIME" /> o posterior.</translation>
@@ -104,14 +109,13 @@
<translation id="4812940957355064477">Introduïu un número.</translation>
<translation id="4912536737030637138">entrada bibliogràfica</translation>
<translation id="4975562563186953947">Elements seleccionats: <ph name="SELECTED_COUNT" /></translation>
-<translation id="4992066212339426712">Activa el so</translation>
+<translation id="4992066212339426712">Deixa de silenciar</translation>
<translation id="49969490063480558">Introduïu un domini precedit per "<ph name="ATSIGN" />". "<ph name="INVALIDADDRESS" />" no és una adreça electrònica completa.</translation>
<translation id="5034860022980953847">indicador de progrés</translation>
<translation id="5093189678851173835">epígraf</translation>
<translation id="5117590920725113268">Mostra el mes següent</translation>
<translation id="512758898067543763">capçalera de la fila</translation>
<translation id="5143125788380636750">epíleg</translation>
-<translation id="5153163864850940242">Aquest vídeo s'està reproduint en mode de pantalla en pantalla</translation>
<translation id="5164977714490026579">El valor ha de ser més gran o igual que <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Introduïu un nom d'usuari seguit de "<ph name="ATSIGN" />". "<ph name="INVALIDADDRESS" />" no és una adreça completa.</translation>
@@ -121,7 +125,7 @@
<translation id="5468998798572797635">surt de la pantalla completa</translation>
<translation id="5516424706154626233">selector de data</translation>
<translation id="5537725057119320332">Emet</translation>
-<translation id="5546461542133609677">activa el so</translation>
+<translation id="5546461542133609677">deixa de silenciar</translation>
<translation id="561939826962581046">time</translation>
<translation id="5630795885300617244">Fes doble toc a l'esquerra o a la dreta per saltar 10 s</translation>
<translation id="5631759159893697722">resum</translation>
@@ -138,7 +142,7 @@
<translation id="5987525920412732405">botó de selecció de valors</translation>
<translation id="6015796118275082299">Any</translation>
<translation id="6023896073578205740">quadre de llista</translation>
-<translation id="6101327004457443354">activa el so de la pista d'àudio</translation>
+<translation id="6101327004457443354">deixa de silenciar la pista d'àudio</translation>
<translation id="6150588977291308318">bibliografia</translation>
<translation id="6164829606128959761">comptador</translation>
<translation id="6166809985690652833">cloenda</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">colofó</translation>
<translation id="6934078000481955284">cita en bloc</translation>
<translation id="6941933287844615239">baixa els fitxers multimèdia</translation>
+<translation id="6981594929165378967">inserció</translation>
<translation id="6989848892321993519">Allarga aquest text fins a <ph name="MIN_CHARACTERS" /> caràcters o més (ara n'utilitzes 1).</translation>
<translation id="709897737746224366">Feu servir el format sol·licitat.</translation>
<translation id="7139483182332611405">prefaci</translation>
@@ -186,6 +191,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="7750228210027921155">Pantalla en pantalla</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>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">taula de continguts</translation>
<translation id="8613126697340063924">reproducció amb comandament</translation>
<translation id="862370744433916922">subtítol</translation>
-<translation id="8741316211671074806">Pantalla en pantalla</translation>
<translation id="8750798805984357768">Seleccioneu una d'aquestes opcions.</translation>
<translation id="8785498733064193001">inicia la reproducció</translation>
<translation id="8808573423886751634">capítol</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navegació</translation>
<translation id="9050748414552849310">mostra els subtítols ocults</translation>
<translation id="9062295712474918030">document</translation>
+<translation id="9093215626363556771">surt del mode de pantalla en pantalla</translation>
<translation id="9108370397979208512">matemàtiques</translation>
<translation id="9132465097189459683">Altres...</translation>
<translation id="9138385573473225930">alerta</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, a partir del dia <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Pantalla en pantalla</translation>
<translation id="9168329111483466115">nota al peu</translation>
-<translation id="947831847158436616">cel·la</translation>
+<translation id="954003015749068518">ves al mode de pantalla en pantalla</translation>
<translation id="966787709310836684">menú</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_cs.xtb b/chromium/content/app/strings/translations/content_strings_cs.xtb
index f037cfd0ffe..f6e35d6f41a 100644
--- a/chromium/content/app/strings/translations/content_strings_cs.xtb
+++ b/chromium/content/app/strings/translations/content_strings_cs.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">posuvník</translation>
<translation id="1211441953136645838">koncová poznámka</translation>
<translation id="1281252709823657822">dialogové okno</translation>
+<translation id="1289247557029249093">Ukončit režim obrazu v obraze</translation>
<translation id="1335095011850992622">poděkování</translation>
<translation id="1342835525016946179">čl</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">přehrát video v režimu obrazu v obraze</translation>
<translation id="1589122976691792535">oblast</translation>
<translation id="1591562245178063882">Tento měsíc</translation>
<translation id="1637811476055996098">Zvolit soubory</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">stromová mřížka</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">přehrát ve vzdáleném zařízení</translation>
+<translation id="190587075670221089">smazání</translation>
<translation id="1907737156431278478">příklad</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">stav</translation>
<translation id="1938124657309484470">Datum musí být <ph name="MAXIMUM_DATE_OR_TIME" /> nebo dříve.</translation>
+<translation id="1946271899482435442">Zobrazit výběr data</translation>
<translation id="1993104285338243655">Přepnuto na zrcadlení</translation>
<translation id="2060505056492490888">Znak <ph name="DOT" /> v doméně <ph name="INVALIDDOMAIN" /> není použitý správně.</translation>
<translation id="2148716181193084225">Dnes</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Odeslat</translation>
<translation id="2657045182931379222">grafický objekt</translation>
<translation id="2674318244760992338">zápatí</translation>
+<translation id="2706474812903655270">Toto video se přehrává v režimu obrazu v obraze</translation>
<translation id="2709516037105925701">Automatické vyplňování</translation>
<translation id="2723001399770238859">zvuk</translation>
<translation id="2746543609216772311">Datum musí být <ph name="MINIMUM_DATE_OR_TIME" /> nebo později.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Zobrazit další měsíc</translation>
<translation id="512758898067543763">záhlaví řádku</translation>
<translation id="5143125788380636750">epilog</translation>
-<translation id="5153163864850940242">Toto video se přehrává v režimu obrazu v obraze</translation>
<translation id="5164977714490026579">Hodnota musí být větší nebo rovna <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Zadejte část před znakem <ph name="ATSIGN" />. Adresa <ph name="INVALIDADDRESS" /> není úplná.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofon</translation>
<translation id="6934078000481955284">bloková citace</translation>
<translation id="6941933287844615239">stáhnout média</translation>
+<translation id="6981594929165378967">vložení</translation>
<translation id="6989848892321993519">Prodlužte prosím tento text na <ph name="MIN_CHARACTERS" /> či více znaků. (Aktuálně má 1 znak.)</translation>
<translation id="709897737746224366">Zadejte hodnotu, která odpovídá požadovanému formátu.</translation>
<translation id="7139483182332611405">předmluva</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">zbývající čas</translation>
<translation id="7740016676195725605">ukončit zobrazování titulků</translation>
<translation id="7740050170769002709">Obsah ve formátu HTML</translation>
+<translation id="7750228210027921155">Obraz v obraze</translation>
<translation id="7789962463072032349">pozastavit</translation>
<translation id="7802800022689234070">tlačítko k zobrazení skrytého obsahu</translation>
<translation id="7888071071722539607">Do e-mailové adresy zahrňte znak <ph name="ATSIGN" />. V adrese <ph name="INVALIDADDRESS" /> chybí znak <ph name="ATSIGN" />.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">obsah</translation>
<translation id="8613126697340063924">ovládání vzdáleného přehrávání</translation>
<translation id="862370744433916922">titulek</translation>
-<translation id="8741316211671074806">Obraz v obraze</translation>
<translation id="8750798805984357768">Vyberte jednu z těchto možností.</translation>
<translation id="8785498733064193001">zahájit přehrávání</translation>
<translation id="8808573423886751634">kapitola</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigace</translation>
<translation id="9050748414552849310">zobrazit titulky</translation>
<translation id="9062295712474918030">dokument</translation>
+<translation id="9093215626363556771">ukončit režim obrazu v obraze</translation>
<translation id="9108370397979208512">matematika</translation>
<translation id="9132465097189459683">Jiné…</translation>
<translation id="9138385573473225930">upozornění</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, začíná <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Obraz v obraze</translation>
<translation id="9168329111483466115">poznámka pod čarou</translation>
-<translation id="947831847158436616">buňka</translation>
+<translation id="954003015749068518">spustit režim obrazu v obraze</translation>
<translation id="966787709310836684">nabídka</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_da.xtb b/chromium/content/app/strings/translations/content_strings_da.xtb
index b2b772fcf80..836c37f9680 100644
--- a/chromium/content/app/strings/translations/content_strings_da.xtb
+++ b/chromium/content/app/strings/translations/content_strings_da.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">skyder</translation>
<translation id="1211441953136645838">slutnote</translation>
<translation id="1281252709823657822">dialogboks</translation>
+<translation id="1289247557029249093">Afslut tilstanden med integreret billede</translation>
<translation id="1335095011850992622">anerkendelser</translation>
<translation id="1342835525016946179">artikel</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">afspil video i tilstanden integreret billede</translation>
<translation id="1589122976691792535">område</translation>
<translation id="1591562245178063882">Denne måned</translation>
<translation id="1637811476055996098">Vælg filer</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">trægitter</translation>
<translation id="1822429046913737220">f.m./e.m.</translation>
<translation id="1832974991323546415">afspil på en enhed via fjernadgang</translation>
+<translation id="190587075670221089">sletning</translation>
<translation id="1907737156431278478">eksempel</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">status</translation>
<translation id="1938124657309484470">Værdien må ikke være senere end <ph name="MAXIMUM_DATE_OR_TIME" />.</translation>
+<translation id="1946271899482435442">Vis datovælger</translation>
<translation id="1993104285338243655">Ændret til spejling</translation>
<translation id="2060505056492490888">"<ph name="DOT" />" er placeret forkert i "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">I dag</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Indsend</translation>
<translation id="2657045182931379222">grafikobjekt</translation>
<translation id="2674318244760992338">sidefod</translation>
+<translation id="2706474812903655270">Denne video afspilles i tilstanden med integreret billede</translation>
<translation id="2709516037105925701">AutoFyld</translation>
<translation id="2723001399770238859">lyd</translation>
<translation id="2746543609216772311">Værdien må ikke være tidligere end <ph name="MINIMUM_DATE_OR_TIME" />.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Vis næste måned</translation>
<translation id="512758898067543763">rækkeoverskrift</translation>
<translation id="5143125788380636750">epilog</translation>
-<translation id="5153163864850940242">Denne video afspilles som integreret billede</translation>
<translation id="5164977714490026579">Værdien skal være større end eller lig med <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Angiv den del, der kommer før "<ph name="ATSIGN" />". "<ph name="INVALIDADDRESS" />" er ufuldstændig.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">slutskrift</translation>
<translation id="6934078000481955284">blockquote</translation>
<translation id="6941933287844615239">download medier</translation>
+<translation id="6981594929165378967">indsættelse</translation>
<translation id="6989848892321993519">Forlæng denne tekst til <ph name="MIN_CHARACTERS" /> eller flere tegn (du bruger i øjeblikket ét tegn).</translation>
<translation id="709897737746224366">Find et match til det anmodede format.</translation>
<translation id="7139483182332611405">forord</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">resterende tid</translation>
<translation id="7740016676195725605">stop visning af undertekster</translation>
<translation id="7740050170769002709">HTML-indhold</translation>
+<translation id="7750228210027921155">Integreret billede</translation>
<translation id="7789962463072032349">pause</translation>
<translation id="7802800022689234070">Trekant til at vise eller skjule indhold</translation>
<translation id="7888071071722539607">Mailadressen skal indeholde et "<ph name="ATSIGN" />". "<ph name="INVALIDADDRESS" />" mangler et "<ph name="ATSIGN" />".</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">indholdsfortegnelse</translation>
<translation id="8613126697340063924">kontrollér afspilning via fjernadgang</translation>
<translation id="862370744433916922">undertitel</translation>
-<translation id="8741316211671074806">Integreret billede</translation>
<translation id="8750798805984357768">Vælg en af disse muligheder.</translation>
<translation id="8785498733064193001">start afspilning</translation>
<translation id="8808573423886751634">kapitel</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigation</translation>
<translation id="9050748414552849310">vis undertekster</translation>
<translation id="9062295712474918030">dokument</translation>
+<translation id="9093215626363556771">afslut integreret billede</translation>
<translation id="9108370397979208512">matematik</translation>
<translation id="9132465097189459683">Andet...</translation>
<translation id="9138385573473225930">underretning</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, med start <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Integreret billede</translation>
<translation id="9168329111483466115">fodnote</translation>
-<translation id="947831847158436616">celle</translation>
+<translation id="954003015749068518">start integreret billede</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_de.xtb b/chromium/content/app/strings/translations/content_strings_de.xtb
index 72ba8f81710..f2f2ca89074 100644
--- a/chromium/content/app/strings/translations/content_strings_de.xtb
+++ b/chromium/content/app/strings/translations/content_strings_de.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">Schieberegler</translation>
<translation id="1211441953136645838">Endnote</translation>
<translation id="1281252709823657822">Kleines Fenster</translation>
+<translation id="1289247557029249093">Bild-im-Bild-Modus beenden</translation>
<translation id="1335095011850992622">Mitwirkende</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">Banner</translation>
+<translation id="1548116112524424341">Video im Bild-im-Bild-Modus abspielen</translation>
<translation id="1589122976691792535">Region</translation>
<translation id="1591562245178063882">Aktueller Monat</translation>
<translation id="1637811476055996098">Dateien auswählen</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">Baumraster</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">auf Remote-Gerät wiedergeben</translation>
+<translation id="190587075670221089">Löschen</translation>
<translation id="1907737156431278478">Beispiel</translation>
<translation id="1921819250265091946">tt</translation>
<translation id="1930711995431081526">Status</translation>
<translation id="1938124657309484470">Verwenden Sie <ph name="MAXIMUM_DATE_OR_TIME" /> oder einen früheren Wert.</translation>
+<translation id="1946271899482435442">Datumsauswahl anzeigen</translation>
<translation id="1993104285338243655">Zu 1:1-Wiedergabe gewechselt</translation>
<translation id="2060505056492490888">Das Punktzeichen "<ph name="DOT" />" steht in "<ph name="INVALIDDOMAIN" />" an einer falschen Stelle.</translation>
<translation id="2148716181193084225">Heute</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Senden</translation>
<translation id="2657045182931379222">Grafikobjekt</translation>
<translation id="2674318244760992338">Fußzeile</translation>
+<translation id="2706474812903655270">Dieses Video wird im Bild-in-Bild-Modus wiedergegeben</translation>
<translation id="2709516037105925701">AutoFill</translation>
<translation id="2723001399770238859">Audio</translation>
<translation id="2746543609216772311">Verwenden Sie <ph name="MINIMUM_DATE_OR_TIME" /> oder einen späteren Wert.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Nächsten Monat anzeigen</translation>
<translation id="512758898067543763">Zeilenüberschrift</translation>
<translation id="5143125788380636750">Epilog</translation>
-<translation id="5153163864850940242">Dieses Video wird im Bild-in-Bild-Modus wiedergegeben</translation>
<translation id="5164977714490026579">Wert muss größer als oder gleich <ph name="MINIMUM" /> sein.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Geben Sie etwas vor dem <ph name="ATSIGN" />-Zeichen ein. Die Angabe "<ph name="INVALIDADDRESS" />" ist unvollständig.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">Kolophon</translation>
<translation id="6934078000481955284">blockquote</translation>
<translation id="6941933287844615239">Medien herunterladen</translation>
+<translation id="6981594929165378967">Einfügen</translation>
<translation id="6989848892321993519">Verlängern Sie diesen Text auf mindestens <ph name="MIN_CHARACTERS" /> Zeichen. Derzeit verwenden Sie 1 Zeichen.</translation>
<translation id="709897737746224366">Ihre Eingabe muss mit dem geforderten Format übereinstimmen.</translation>
<translation id="7139483182332611405">Vorbemerkung</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">Verbleibende Zeit</translation>
<translation id="7740016676195725605">Keine Untertitel mehr anzeigen</translation>
<translation id="7740050170769002709">HTML-Inhalte</translation>
+<translation id="7750228210027921155">Bild-in-Bild</translation>
<translation id="7789962463072032349">Pausieren</translation>
<translation id="7802800022689234070">Aufklappdreieck</translation>
<translation id="7888071071722539607">Die E-Mail-Adresse muss ein <ph name="ATSIGN" />-Zeichen enthalten. In der Angabe "<ph name="INVALIDADDRESS" />" fehlt ein <ph name="ATSIGN" />-Zeichen.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">Inhaltsverzeichnis</translation>
<translation id="8613126697340063924">Remote-Wiedergabe steuern</translation>
<translation id="862370744433916922">Untertitel</translation>
-<translation id="8741316211671074806">Bild im Bild</translation>
<translation id="8750798805984357768">Wählen Sie eine dieser Optionen aus.</translation>
<translation id="8785498733064193001">Wiedergabe starten</translation>
<translation id="8808573423886751634">Kapitel</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">Navigation</translation>
<translation id="9050748414552849310">Untertitel anzeigen</translation>
<translation id="9062295712474918030">Dokument</translation>
+<translation id="9093215626363556771">Bild-im-Bild-Modus beenden</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">Andere...</translation>
<translation id="9138385573473225930">Benachrichtigung</translation>
<translation id="9155987714137265666"><ph name="WEEK" /> ab dem <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Bild-in-Bild</translation>
<translation id="9168329111483466115">Fußnote</translation>
-<translation id="947831847158436616">Zelle</translation>
+<translation id="954003015749068518">Bild-im-Bild-Modus aktivieren</translation>
<translation id="966787709310836684">Menü</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_el.xtb b/chromium/content/app/strings/translations/content_strings_el.xtb
index e80b9556f8b..5d16e526ad0 100644
--- a/chromium/content/app/strings/translations/content_strings_el.xtb
+++ b/chromium/content/app/strings/translations/content_strings_el.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">ρυθμιστικό</translation>
<translation id="1211441953136645838">σημείωση τέλους</translation>
<translation id="1281252709823657822">παράθυρο διαλόγου</translation>
+<translation id="1289247557029249093">Έξοδος από τη λειτουργία picture-in-picture</translation>
<translation id="1335095011850992622">συντελεστές</translation>
<translation id="1342835525016946179">άρθρο</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">αναπαραγωγή βίντεο σε λειτουργία picture-in-picture</translation>
<translation id="1589122976691792535">περιοχή</translation>
<translation id="1591562245178063882">Αυτόν το μήνα</translation>
<translation id="1637811476055996098">Επιλογή αρχείων</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">πλέγμα δέντρου</translation>
<translation id="1822429046913737220">Π.Μ./Μ.Μ.</translation>
<translation id="1832974991323546415">αναπαραγωγή σε απομακρυσμένη συσκευή</translation>
+<translation id="190587075670221089">διαγραφή</translation>
<translation id="1907737156431278478">παράδειγμα</translation>
<translation id="1921819250265091946">ηη</translation>
<translation id="1930711995431081526">κατάσταση</translation>
<translation id="1938124657309484470">Η τιμή πρέπει να είναι <ph name="MAXIMUM_DATE_OR_TIME" /> ή προγενέστερη.</translation>
+<translation id="1946271899482435442">Εμφάνιση εργαλείου επιλογής ημερομηνίας</translation>
<translation id="1993104285338243655">Εναλλαγή σε κατοπτρισμό</translation>
<translation id="2060505056492490888">Το σύμβολο "<ph name="DOT" />" χρησιμοποιείται σε λάθος θέση στη διεύθυνση "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">Σήμερα</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Υποβολή</translation>
<translation id="2657045182931379222">αντικείμενο γραφικών</translation>
<translation id="2674318244760992338">υποσέλιδο</translation>
+<translation id="2706474812903655270">Η αναπαραγωγή αυτού του βίντεο γίνεται στη λειτουργία picture-in-picture</translation>
<translation id="2709516037105925701">Αυτόματη συμπλήρωση</translation>
<translation id="2723001399770238859">ήχος</translation>
<translation id="2746543609216772311">Η τιμή πρέπει να είναι <ph name="MINIMUM_DATE_OR_TIME" /> ή μεταγενέστερη.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Εμφάνιση επόμενου μήνα</translation>
<translation id="512758898067543763">κεφαλίδα σειράς</translation>
<translation id="5143125788380636750">επίλογος</translation>
-<translation id="5153163864850940242">Η αναπαραγωγή αυτού του βίντεο γίνεται σε λειτουργία Picture-in-Picture</translation>
<translation id="5164977714490026579">Η τιμή πρέπει να είναι μεγαλύτερη ή ίση του <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Καταχωρίστε το τμήμα της διεύθυνσης πριν το σύμβολο "<ph name="ATSIGN" />". Η διεύθυνση "<ph name="INVALIDADDRESS" />" δεν είναι πλήρης.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">εκδοτικό σήμα</translation>
<translation id="6934078000481955284">blockquote</translation>
<translation id="6941933287844615239">λήψη μέσων</translation>
+<translation id="6981594929165378967">εισαγωγή</translation>
<translation id="6989848892321993519">Αυξήστε την έκταση αυτού του κειμένου στους <ph name="MIN_CHARACTERS" /> χαρακτήρες ή περισσότερο (αυτήν τη στιγμή χρησιμοποιείτε 1 χαρακτήρα).</translation>
<translation id="709897737746224366">Αντιστοιχίστε τη ζητούμενη μορφή.</translation>
<translation id="7139483182332611405">πρόλογος</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">χρόνος που απομένει</translation>
<translation id="7740016676195725605">διακοπή προβολής υπότιτλων</translation>
<translation id="7740050170769002709">Περιεχόμενο HTML</translation>
+<translation id="7750228210027921155">Picture in picture</translation>
<translation id="7789962463072032349">παύση</translation>
<translation id="7802800022689234070">τρίγωνο εμφάνισης/απόκρυψης</translation>
<translation id="7888071071722539607">Συμπεριλάβετε το σύμβολο "<ph name="ATSIGN" />" στη διεύθυνση ηλεκτρονικού ταχυδρομείου. Από τη διεύθυνση "<ph name="INVALIDADDRESS" />" λείπει το σύμβολο "<ph name="ATSIGN" />".</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">πίνακας περιεχομένων</translation>
<translation id="8613126697340063924">έλεγχος απομακρυσμένης αναπαραγωγής</translation>
<translation id="862370744433916922">υπότιτλος</translation>
-<translation id="8741316211671074806">Picture-in-picture</translation>
<translation id="8750798805984357768">Ορίστε μία από αυτές τις επιλογές.</translation>
<translation id="8785498733064193001">έναρξη αναπαραγωγής</translation>
<translation id="8808573423886751634">κεφάλαιο</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">πλοήγηση</translation>
<translation id="9050748414552849310">εμφάνιση υπότιτλων</translation>
<translation id="9062295712474918030">έγγραφο</translation>
+<translation id="9093215626363556771">έξοδος από τη λειτουργία picture-in-picture</translation>
<translation id="9108370397979208512">μαθηματικά</translation>
<translation id="9132465097189459683">Άλλες…</translation>
<translation id="9138385573473225930">ειδοποίηση</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, από τις <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Παράθεση εικόνων</translation>
<translation id="9168329111483466115">υποσημείωση</translation>
-<translation id="947831847158436616">κελί</translation>
+<translation id="954003015749068518">είσοδος στη λειτουργία picture-in-picture</translation>
<translation id="966787709310836684">μενού</translation>
</translationbundle> \ No newline at end of file
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 30e75ecd7ae..c63e0611cc2 100644
--- a/chromium/content/app/strings/translations/content_strings_en-GB.xtb
+++ b/chromium/content/app/strings/translations/content_strings_en-GB.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">slider</translation>
<translation id="1211441953136645838">endnote</translation>
<translation id="1281252709823657822">dialogue</translation>
+<translation id="1289247557029249093">Exit picture-in-picture mode</translation>
<translation id="1335095011850992622">credits</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">play video in picture-in-picture mode</translation>
<translation id="1589122976691792535">region</translation>
<translation id="1591562245178063882">This month</translation>
<translation id="1637811476055996098">Choose Files</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">tree grid</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">play on remote device</translation>
+<translation id="190587075670221089">deletion</translation>
<translation id="1907737156431278478">example</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">status</translation>
<translation id="1938124657309484470">Value must be <ph name="MAXIMUM_DATE_OR_TIME" /> or earlier.</translation>
+<translation id="1946271899482435442">Show date picker</translation>
<translation id="1993104285338243655">Switched to mirroring</translation>
<translation id="2060505056492490888">'<ph name="DOT" />' is used at a wrong position in '<ph name="INVALIDDOMAIN" />'.</translation>
<translation id="2148716181193084225">Today</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Submit</translation>
<translation id="2657045182931379222">graphics object</translation>
<translation id="2674318244760992338">footer</translation>
+<translation id="2706474812903655270">This video is playing in picture-in-picture mode</translation>
<translation id="2709516037105925701">Auto-fill</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">Value must be <ph name="MINIMUM_DATE_OR_TIME" /> or later.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Show next month</translation>
<translation id="512758898067543763">row header</translation>
<translation id="5143125788380636750">epilogue</translation>
-<translation id="5153163864850940242">This video is playing in Picture-in-Picture</translation>
<translation id="5164977714490026579">Value must be greater than or equal to <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Please enter a part followed by '<ph name="ATSIGN" />'. '<ph name="INVALIDADDRESS" />' is incomplete.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">colophon</translation>
<translation id="6934078000481955284">blockquote</translation>
<translation id="6941933287844615239">download media</translation>
+<translation id="6981594929165378967">insertion</translation>
<translation id="6989848892321993519">Please lengthen this text to <ph name="MIN_CHARACTERS" /> characters or more (you are currently using 1 character).</translation>
<translation id="709897737746224366">Please match the format requested.</translation>
<translation id="7139483182332611405">preface</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">remaining time</translation>
<translation id="7740016676195725605">stop displaying closed captions</translation>
<translation id="7740050170769002709">HTML content</translation>
+<translation id="7750228210027921155">Picture-in-picture</translation>
<translation id="7789962463072032349">pause</translation>
<translation id="7802800022689234070">disclosure triangle</translation>
<translation id="7888071071722539607">Please include an '<ph name="ATSIGN" />' in the email address. '<ph name="INVALIDADDRESS" />' is missing an '<ph name="ATSIGN" />'.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">table of contents</translation>
<translation id="8613126697340063924">control remote playback</translation>
<translation id="862370744433916922">subtitle</translation>
-<translation id="8741316211671074806">Picture-in-picture</translation>
<translation id="8750798805984357768">Please select one of these options.</translation>
<translation id="8785498733064193001">begin playback</translation>
<translation id="8808573423886751634">chapter</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigation</translation>
<translation id="9050748414552849310">show closed captions</translation>
<translation id="9062295712474918030">document</translation>
+<translation id="9093215626363556771">exit picture-in-picture</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">Other...</translation>
<translation id="9138385573473225930">alert</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, starting on <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Picture in Picture</translation>
<translation id="9168329111483466115">footnote</translation>
-<translation id="947831847158436616">cell</translation>
+<translation id="954003015749068518">enter picture-in-picture</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
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 b65c8e31e1c..6c990c4fa8b 100644
--- a/chromium/content/app/strings/translations/content_strings_es-419.xtb
+++ b/chromium/content/app/strings/translations/content_strings_es-419.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">control deslizante</translation>
<translation id="1211441953136645838">nota final</translation>
<translation id="1281252709823657822">diálogo</translation>
+<translation id="1289247557029249093">Salir del modo de pantalla en pantalla</translation>
<translation id="1335095011850992622">créditos</translation>
<translation id="1342835525016946179">artículo</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">reproducir video en modo de pantalla en pantalla</translation>
<translation id="1589122976691792535">región</translation>
<translation id="1591562245178063882">Este mes</translation>
<translation id="1637811476055996098">Elegir archivos</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">cuadrícula de árbol</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">jugar en el dispositivo remoto</translation>
+<translation id="190587075670221089">contenido borrado</translation>
<translation id="1907737156431278478">ejemplo</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">estado</translation>
<translation id="1938124657309484470">El valor debe ser igual o anterior a <ph name="MAXIMUM_DATE_OR_TIME" />.</translation>
+<translation id="1946271899482435442">Mostrar el selector de fechas</translation>
<translation id="1993104285338243655">Se cambió a duplicación</translation>
<translation id="2060505056492490888">El signo "<ph name="DOT" />" está colocado en una posición incorrecta en "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">Hoy</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Enviar</translation>
<translation id="2657045182931379222">objeto gráfico</translation>
<translation id="2674318244760992338">pie de página</translation>
+<translation id="2706474812903655270">Este video se reproduce en el modo de pantalla en pantalla</translation>
<translation id="2709516037105925701">Autocompletar</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">El valor debe ser igual o posterior a <ph name="MINIMUM_DATE_OR_TIME" />.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Mostrar el mes siguiente</translation>
<translation id="512758898067543763">encabezado de fila</translation>
<translation id="5143125788380636750">epílogo</translation>
-<translation id="5153163864850940242">Este video se reproduce en el modo de pantalla en pantalla</translation>
<translation id="5164977714490026579">El valor debe ser mayor de o igual a <ph name="MINIMUM" /></translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Ingresa texto antes del signo "<ph name="ATSIGN" />". La dirección "<ph name="INVALIDADDRESS" />" está incompleta.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">colofón</translation>
<translation id="6934078000481955284">bloque entrecomillado</translation>
<translation id="6941933287844615239">descargar medios</translation>
+<translation id="6981594929165378967">contenido agregado</translation>
<translation id="6989848892321993519">Extiende este texto para que tenga <ph name="MIN_CHARACTERS" /> caracteres o más (actualmente usas 1 carácter).</translation>
<translation id="709897737746224366">Haz coincidir el formato solicitado.</translation>
<translation id="7139483182332611405">prefacio</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">tiempo restante</translation>
<translation id="7740016676195725605">dejar de mostrar subtítulos</translation>
<translation id="7740050170769002709">Contenido HTML</translation>
+<translation id="7750228210027921155">Pantalla en pantalla</translation>
<translation id="7789962463072032349">pausa</translation>
<translation id="7802800022689234070">triángulo desplegable</translation>
<translation id="7888071071722539607">Incluye un signo "<ph name="ATSIGN" />" en la dirección de correo electrónico. La dirección "<ph name="INVALIDADDRESS" />" no incluye el signo "<ph name="ATSIGN" />".</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">índice</translation>
<translation id="8613126697340063924">controlar la reproducción remota</translation>
<translation id="862370744433916922">subtítulo</translation>
-<translation id="8741316211671074806">Pantalla en pantalla</translation>
<translation id="8750798805984357768">Selecciona una de estas opciones.</translation>
<translation id="8785498733064193001">comenzar la reproducción</translation>
<translation id="8808573423886751634">capítulo</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navegación</translation>
<translation id="9050748414552849310">mostrar subtítulos</translation>
<translation id="9062295712474918030">documento</translation>
+<translation id="9093215626363556771">salir del modo de pantalla en pantalla</translation>
<translation id="9108370397979208512">expr mtmtc</translation>
<translation id="9132465097189459683">Otra...</translation>
<translation id="9138385573473225930">alerta</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, a partir del <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Pantalla en pantalla</translation>
<translation id="9168329111483466115">nota a pie de página</translation>
-<translation id="947831847158436616">celda</translation>
+<translation id="954003015749068518">ingresar al modo de pantalla en pantalla</translation>
<translation id="966787709310836684">menú</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_es.xtb b/chromium/content/app/strings/translations/content_strings_es.xtb
index 01abb818539..370c170033c 100644
--- a/chromium/content/app/strings/translations/content_strings_es.xtb
+++ b/chromium/content/app/strings/translations/content_strings_es.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">control deslizante</translation>
<translation id="1211441953136645838">nota final</translation>
<translation id="1281252709823657822">cuadro de diálogo</translation>
+<translation id="1289247557029249093">Salir del modo imagen en imagen</translation>
<translation id="1335095011850992622">créditos</translation>
<translation id="1342835525016946179">artículo</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">reproducir vídeo en modo imagen en imagen</translation>
<translation id="1589122976691792535">región</translation>
<translation id="1591562245178063882">Este mes</translation>
<translation id="1637811476055996098">Elegir archivos</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">cuadrícula de árbol</translation>
<translation id="1822429046913737220">A.M./P.M.</translation>
<translation id="1832974991323546415">reproducir en dispositivo remoto</translation>
+<translation id="190587075670221089">eliminación</translation>
<translation id="1907737156431278478">ejemplo</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">estado</translation>
<translation id="1938124657309484470">El valor debe ser igual o anterior a <ph name="MAXIMUM_DATE_OR_TIME" />.</translation>
+<translation id="1946271899482435442">Mostrar selector de fecha</translation>
<translation id="1993104285338243655">Se ha cambiado a proyección</translation>
<translation id="2060505056492490888">El signo "<ph name="DOT" />" está colocado en una posición incorrecta en la dirección "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">Hoy</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Enviar</translation>
<translation id="2657045182931379222">objeto gráfico</translation>
<translation id="2674318244760992338">pie de página</translation>
+<translation id="2706474812903655270">Este vídeo se está reproduciendo en modo imagen en imagen</translation>
<translation id="2709516037105925701">Autocompletar</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">El valor debe ser igual o posterior a <ph name="MINIMUM_DATE_OR_TIME" />.</translation>
@@ -101,7 +106,7 @@
<translation id="4757246831282535685">panel de pestaña</translation>
<translation id="4763480195061959176">vídeo</translation>
<translation id="479989351350248267">buscar</translation>
-<translation id="4812940957355064477">Debes introducir un número.</translation>
+<translation id="4812940957355064477">Debes introducir un número</translation>
<translation id="4912536737030637138">entrada bibliográfica</translation>
<translation id="4975562563186953947"><ph name="SELECTED_COUNT" /> seleccionados</translation>
<translation id="4992066212339426712">Activar sonido</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Mostrar mes siguiente</translation>
<translation id="512758898067543763">encabezado de fila</translation>
<translation id="5143125788380636750">epílogo</translation>
-<translation id="5153163864850940242">Este vídeo se está reproduciendo en modo imagen en imagen</translation>
<translation id="5164977714490026579">El valor debe ser superior o igual a <ph name="MINIMUM" /></translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Introduce texto seguido del signo "<ph name="ATSIGN" />". La dirección "<ph name="INVALIDADDRESS" />" está incompleta.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">colofón</translation>
<translation id="6934078000481955284">blockquote</translation>
<translation id="6941933287844615239">descargar archivos multimedia</translation>
+<translation id="6981594929165378967">inserción</translation>
<translation id="6989848892321993519">Aumenta la longitud de este texto a <ph name="MIN_CHARACTERS" /> caracteres o más (actualmente, el texto tiene 1 carácter).</translation>
<translation id="709897737746224366">Utiliza un formato que coincida con el solicitado</translation>
<translation id="7139483182332611405">prefacio</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">tiempo restante</translation>
<translation id="7740016676195725605">dejar de mostrar subtítulos</translation>
<translation id="7740050170769002709">Contenido HTML</translation>
+<translation id="7750228210027921155">Imagen en imagen</translation>
<translation id="7789962463072032349">pausar</translation>
<translation id="7802800022689234070">triángulo de revelación</translation>
<translation id="7888071071722539607">Incluye un signo "<ph name="ATSIGN" />" en la dirección de correo electrónico. La dirección "<ph name="INVALIDADDRESS" />" no incluye el signo "<ph name="ATSIGN" />".</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">índice</translation>
<translation id="8613126697340063924">reproducción de control remoto</translation>
<translation id="862370744433916922">subtítulo</translation>
-<translation id="8741316211671074806">Imagen en imagen</translation>
<translation id="8750798805984357768">Selecciona una de estas opciones</translation>
<translation id="8785498733064193001">iniciar reproducción</translation>
<translation id="8808573423886751634">capítulo</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navegación</translation>
<translation id="9050748414552849310">mostrar subtítulos</translation>
<translation id="9062295712474918030">documento</translation>
+<translation id="9093215626363556771">salir del modo imagen en imagen</translation>
<translation id="9108370397979208512">expresión matemática</translation>
<translation id="9132465097189459683">Otra...</translation>
<translation id="9138385573473225930">alerta</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, a partir del <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Imagen en imagen</translation>
<translation id="9168329111483466115">nota al pie</translation>
-<translation id="947831847158436616">celda</translation>
+<translation id="954003015749068518">abrir el modo imagen en imagen</translation>
<translation id="966787709310836684">menú</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_et.xtb b/chromium/content/app/strings/translations/content_strings_et.xtb
index c5ea1a2fef5..0490fd119df 100644
--- a/chromium/content/app/strings/translations/content_strings_et.xtb
+++ b/chromium/content/app/strings/translations/content_strings_et.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">liugur</translation>
<translation id="1211441953136645838">järelmärkus</translation>
<translation id="1281252709823657822">dialoog</translation>
+<translation id="1289247557029249093">Välju režiimist Pilt pildis</translation>
<translation id="1335095011850992622">tiitrid</translation>
<translation id="1342835525016946179">artikkel</translation>
<translation id="1359897965706325498">bänner</translation>
+<translation id="1548116112524424341">esita videot režiimis Pilt pildis</translation>
<translation id="1589122976691792535">piirkond</translation>
<translation id="1591562245178063882">See kuu</translation>
<translation id="1637811476055996098">Vali failid</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">puuruudustik</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">kaugseadmes esitamine</translation>
+<translation id="190587075670221089">kustutamine</translation>
<translation id="1907737156431278478">näide</translation>
<translation id="1921819250265091946">pp</translation>
<translation id="1930711995431081526">olek</translation>
<translation id="1938124657309484470">Väärtus peab olema <ph name="MAXIMUM_DATE_OR_TIME" /> või varasem.</translation>
+<translation id="1946271899482435442">Kuupäevavalija kuvamine</translation>
<translation id="1993104285338243655">Lülitatud peegeldamisele</translation>
<translation id="2060505056492490888">Tähist „<ph name="DOT" />” on aadressis „<ph name="INVALIDDOMAIN" />” valesti kasutatud.</translation>
<translation id="2148716181193084225">Täna</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Esita</translation>
<translation id="2657045182931379222">graafika objekt</translation>
<translation id="2674318244760992338">jalus</translation>
+<translation id="2706474812903655270">Videot esitatakse režiimis Pilt pildis</translation>
<translation id="2709516037105925701">Automaatne täitmine</translation>
<translation id="2723001399770238859">heli</translation>
<translation id="2746543609216772311">Väärtus peab olema <ph name="MINIMUM_DATE_OR_TIME" /> või hilisem.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Järgmise kuu kuvamine</translation>
<translation id="512758898067543763">rea päis</translation>
<translation id="5143125788380636750">epiloog</translation>
-<translation id="5153163864850940242">Videot esitatakse pilt-pildis-režiimis</translation>
<translation id="5164977714490026579">Väärtus peab olema suurem või võrdne <ph name="MINIMUM" />-ga.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Sisestage märgile „<ph name="ATSIGN" />” eelnev osa. Aadress „<ph name="INVALIDADDRESS" />” pole täielik.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofoon</translation>
<translation id="6934078000481955284">plokktsitaat</translation>
<translation id="6941933287844615239">laadi meedia alla</translation>
+<translation id="6981594929165378967">lisamine</translation>
<translation id="6989848892321993519">Pikendage teksti vähemalt <ph name="MIN_CHARACTERS" /> tähemärgini (kasutate praegu ühte tähemärki).</translation>
<translation id="709897737746224366">Vastendage nõutav vorming.</translation>
<translation id="7139483182332611405">eessõna</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">järelejäänud aeg</translation>
<translation id="7740016676195725605">subtiitrite kuvamise peatamine</translation>
<translation id="7740050170769002709">HTML-sisu</translation>
+<translation id="7750228210027921155">Pilt pildis</translation>
<translation id="7789962463072032349">peata</translation>
<translation id="7802800022689234070">avalikustamise kolmnurk</translation>
<translation id="7888071071722539607">Lisage e-posti aadressile märk „<ph name="ATSIGN" />”. Aadressist „<ph name="INVALIDADDRESS" />” puudub märk „<ph name="ATSIGN" />”.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">sisukord</translation>
<translation id="8613126697340063924">kaugesituse juhtimine</translation>
<translation id="862370744433916922">alapealkiri</translation>
-<translation id="8741316211671074806">Pilt pildis</translation>
<translation id="8750798805984357768">Tehke üks nendest valikutest.</translation>
<translation id="8785498733064193001">taasesituse alustamine</translation>
<translation id="8808573423886751634">peatükk</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigeerimine</translation>
<translation id="9050748414552849310">subtiitrite kuvamine</translation>
<translation id="9062295712474918030">dokument</translation>
+<translation id="9093215626363556771">välju režiimist Pilt pildis</translation>
<translation id="9108370397979208512">matemaatika</translation>
<translation id="9132465097189459683">Muu ...</translation>
<translation id="9138385573473225930">hoiatus</translation>
<translation id="9155987714137265666"><ph name="WEEK" /> alates kuupäevast <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Pilt pildis</translation>
<translation id="9168329111483466115">allmärkus</translation>
-<translation id="947831847158436616">lahter</translation>
+<translation id="954003015749068518">aktiveeri režiim Pilt pildis</translation>
<translation id="966787709310836684">menüü</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_fa.xtb b/chromium/content/app/strings/translations/content_strings_fa.xtb
index 5f84dfcb4fd..6a0cbe17b8f 100644
--- a/chromium/content/app/strings/translations/content_strings_fa.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fa.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">لغزنده</translation>
<translation id="1211441953136645838">ته‌نویس</translation>
<translation id="1281252709823657822">کادر گفتگو</translation>
+<translation id="1289247557029249093">خروج از حالت تصویردرتصویر</translation>
<translation id="1335095011850992622">دست‌اندرکاران</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">برنما</translation>
+<translation id="1548116112524424341">پخش ویدیو در حالت تصویر در تصویر</translation>
<translation id="1589122976691792535">منطقه</translation>
<translation id="1591562245178063882">این ماه</translation>
<translation id="1637811476055996098">انتخاب فایل‌ها</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">شبکه درختی</translation>
<translation id="1822429046913737220">ق.ظ/ب.ظ</translation>
<translation id="1832974991323546415">پخش در دستگاه راه دور</translation>
+<translation id="190587075670221089">حذف</translation>
<translation id="1907737156431278478">مثال</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">وضعیت</translation>
<translation id="1938124657309484470">مقدار باید <ph name="MAXIMUM_DATE_OR_TIME" /> یا قبل از آن باشد.</translation>
+<translation id="1946271899482435442">نمایش انتخابگر تاریخ</translation>
<translation id="1993104285338243655">به نمایش صفحه‌نمایش روی دستگاه دیگر تغییر یافت</translation>
<translation id="2060505056492490888">«<ph name="DOT" />» در «<ph name="INVALIDDOMAIN" />» در محل اشتباهی قرار دارد.</translation>
<translation id="2148716181193084225">امروز</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">ارائه</translation>
<translation id="2657045182931379222">شیء گرافیکی</translation>
<translation id="2674318244760992338">پانویس</translation>
+<translation id="2706474812903655270">این ویدیو درحال پخش درحالت تصویردرتصویر است</translation>
<translation id="2709516037105925701">تکمیل خودکار</translation>
<translation id="2723001399770238859">صدا</translation>
<translation id="2746543609216772311">مقدار باید <ph name="MINIMUM_DATE_OR_TIME" /> یا بعد از آن باشد.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">نمایش ماه بعدی</translation>
<translation id="512758898067543763">عنوان ردیف</translation>
<translation id="5143125788380636750">گفتار پایانی</translation>
-<translation id="5153163864850940242">این ویدیو درحال پخش شدن در حالت «تصویر در تصویر» است</translation>
<translation id="5164977714490026579">مقدار باید بیشتر یا مساوی با <ph name="MINIMUM" /> باشد.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> پتابایت</translation>
<translation id="5307600278924710095">لطفاً قسمت قبل از «<ph name="ATSIGN" />» را وارد کنید. «<ph name="INVALIDADDRESS" />» ناقص است.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">انجامه</translation>
<translation id="6934078000481955284">نقل‌قول</translation>
<translation id="6941933287844615239">بارگیری رسانه</translation>
+<translation id="6981594929165378967">درج</translation>
<translation id="6989848892321993519">لطفاً این نوشتار را به <ph name="MIN_CHARACTERS" /> نویسه یا بیشتر افزایش دهید (درحال‌حاضر از ۱ نویسه استفاده می‌کنید).</translation>
<translation id="709897737746224366">لطفاً با قالب درخواستی مطابقت دهید.</translation>
<translation id="7139483182332611405">پیش‌گفتار</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">زمان باقی‌مانده</translation>
<translation id="7740016676195725605">توقف نمایش زیرنویس ناشنوایان</translation>
<translation id="7740050170769002709">‏محتوای HTML</translation>
+<translation id="7750228210027921155">تصویردرتصویر</translation>
<translation id="7789962463072032349">مکث</translation>
<translation id="7802800022689234070">مثلث افشا</translation>
<translation id="7888071071722539607">لطفاً نماد «<ph name="ATSIGN" />» را به نشانی ایمیل اضافه کنید. «<ph name="INVALIDADDRESS" />» در «<ph name="ATSIGN" />» موجود نیست.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">فهرست مطالب</translation>
<translation id="8613126697340063924">کنترل بازپخش راه دور</translation>
<translation id="862370744433916922">زیرنویس</translation>
-<translation id="8741316211671074806">تصویردرتصویر</translation>
<translation id="8750798805984357768">لطفاً یکی از این گزینه‌ها را انتخاب کنید.</translation>
<translation id="8785498733064193001">شروع بازپخش</translation>
<translation id="8808573423886751634">فصل</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">پیمایش</translation>
<translation id="9050748414552849310">نمایش زیرنویس ناشنوایان</translation>
<translation id="9062295712474918030">سند</translation>
+<translation id="9093215626363556771">خروج از تصویر در تصویر</translation>
<translation id="9108370397979208512">حساب</translation>
<translation id="9132465097189459683">موارد دیگر...</translation>
<translation id="9138385573473225930">هشدار</translation>
<translation id="9155987714137265666"><ph name="WEEK" />، شروع از <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">تصویر در تصویر</translation>
<translation id="9168329111483466115">پانویس</translation>
-<translation id="947831847158436616">سلول</translation>
+<translation id="954003015749068518">ورود به تصویر در تصویر</translation>
<translation id="966787709310836684">منو</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_fi.xtb b/chromium/content/app/strings/translations/content_strings_fi.xtb
index ffe7d7fb4e5..7d8bdda97b3 100644
--- a/chromium/content/app/strings/translations/content_strings_fi.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fi.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">liukusäädin</translation>
<translation id="1211441953136645838">loppuhuomautus</translation>
<translation id="1281252709823657822">valintaikkuna</translation>
+<translation id="1289247557029249093">Sulje kuva kuvassa ‑tila</translation>
<translation id="1335095011850992622">tunnustukset</translation>
<translation id="1342835525016946179">artikkeli</translation>
<translation id="1359897965706325498">banneri</translation>
+<translation id="1548116112524424341">toista video kuva kuvassa ‑tilassa</translation>
<translation id="1589122976691792535">alue</translation>
<translation id="1591562245178063882">Tässä kuussa</translation>
<translation id="1637811476055996098">Valitse tiedostot</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">puuruudukko</translation>
<translation id="1822429046913737220">AP/IP</translation>
<translation id="1832974991323546415">toista etälaitteella</translation>
+<translation id="190587075670221089">poisto</translation>
<translation id="1907737156431278478">esimerkki</translation>
<translation id="1921819250265091946">pp</translation>
<translation id="1930711995431081526">tila</translation>
<translation id="1938124657309484470">Arvon on oltava <ph name="MAXIMUM_DATE_OR_TIME" /> tai aiempi.</translation>
+<translation id="1946271899482435442">Näytä päivämäärävalitsin</translation>
<translation id="1993104285338243655">Peilaus käynnissä</translation>
<translation id="2060505056492490888"><ph name="DOT" />-merkkiä on käytetty väärässä kohdassa osoitteessa <ph name="INVALIDDOMAIN" />.</translation>
<translation id="2148716181193084225">Tänään</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Lähetä</translation>
<translation id="2657045182931379222">grafiikkaobjekti</translation>
<translation id="2674318244760992338">alaviite</translation>
+<translation id="2706474812903655270">Video toistetaan Kuva kuvassa ‑tilassa</translation>
<translation id="2709516037105925701">Automaattinen täyttö</translation>
<translation id="2723001399770238859">ääni</translation>
<translation id="2746543609216772311">Arvon on oltava <ph name="MINIMUM_DATE_OR_TIME" /> tai myöhempi.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Näytä seuraava kuukausi</translation>
<translation id="512758898067543763">rivin otsikko</translation>
<translation id="5143125788380636750">epilogi</translation>
-<translation id="5153163864850940242">Video toistetaan Kuva kuvassa ‑tilassa</translation>
<translation id="5164977714490026579">Arvon tulee olla suurempi tai yhtä suuri kuin <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> Pt</translation>
<translation id="5307600278924710095">Lisää <ph name="ATSIGN" />-osaa ennen tuleva osa. <ph name="INVALIDADDRESS" /> on puutteellinen.</translation>
@@ -132,7 +136,7 @@
<translation id="57838592816432529">Mykistä</translation>
<translation id="5860033963881614850">Pois käytöstä</translation>
<translation id="588258955323874662">Koko ruutu</translation>
-<translation id="5888666972993069672"><ph name="DEVICE_FRIENDLY_NAME" /> on suoratoiston kohde</translation>
+<translation id="5888666972993069672">Katsotaan TV:stä <ph name="DEVICE_FRIENDLY_NAME" /></translation>
<translation id="5939518447894949180">Tyhjennä</translation>
<translation id="5966707198760109579">Viikko</translation>
<translation id="5987525920412732405">pyöräytyspainike</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofoni</translation>
<translation id="6934078000481955284">muotoiltu lainaus</translation>
<translation id="6941933287844615239">lataa media</translation>
+<translation id="6981594929165378967">lisäys</translation>
<translation id="6989848892321993519">Pidennä tämä teksti vähintään <ph name="MIN_CHARACTERS" /> merkkiin (tällä hetkellä käytössä 1 merkki).</translation>
<translation id="709897737746224366">Käytä pyydettyä muotoilua.</translation>
<translation id="7139483182332611405">johdanto</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">jäljellä oleva aika</translation>
<translation id="7740016676195725605">älä näytä tekstityksiä</translation>
<translation id="7740050170769002709">HTML-sisältö</translation>
+<translation id="7750228210027921155">Kuva kuvassa</translation>
<translation id="7789962463072032349">tauko</translation>
<translation id="7802800022689234070">näyttämiskolmio</translation>
<translation id="7888071071722539607">Sähköpostiosoitteeseen kuuluu <ph name="ATSIGN" />-osa. Osoitteesta <ph name="INVALIDADDRESS" /> puuttuu <ph name="ATSIGN" />.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">sisällysluettelo</translation>
<translation id="8613126697340063924">hallinnoi etätoistoa</translation>
<translation id="862370744433916922">alaotsikko</translation>
-<translation id="8741316211671074806">Kuva kuvassa</translation>
<translation id="8750798805984357768">Valitse yksi vaihtoehdoista.</translation>
<translation id="8785498733064193001">aloita toisto</translation>
<translation id="8808573423886751634">luku</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigointi</translation>
<translation id="9050748414552849310">näytä tekstitykset</translation>
<translation id="9062295712474918030">dokumentti</translation>
+<translation id="9093215626363556771">sulje kuva kuvassa ‑tila</translation>
<translation id="9108370397979208512">matematiikka</translation>
<translation id="9132465097189459683">Muu...</translation>
<translation id="9138385573473225930">ilmoitus</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, alkupäivä: <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Kuva kuvassa</translation>
<translation id="9168329111483466115">alaviite</translation>
-<translation id="947831847158436616">solu</translation>
+<translation id="954003015749068518">avaa kuva kuvassa ‑tila</translation>
<translation id="966787709310836684">valikko</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_fil.xtb b/chromium/content/app/strings/translations/content_strings_fil.xtb
index 7687fc29e30..16304048147 100644
--- a/chromium/content/app/strings/translations/content_strings_fil.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fil.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">slider</translation>
<translation id="1211441953136645838">endnote</translation>
<translation id="1281252709823657822">dialog</translation>
+<translation id="1289247557029249093">Lumabas sa picture-in-picture mode</translation>
<translation id="1335095011850992622">mga credit</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">i-play ang video sa picture-in-picture mode</translation>
<translation id="1589122976691792535">rehiyon</translation>
<translation id="1591562245178063882">Buwang ito</translation>
<translation id="1637811476055996098">Pumili ng Mga File</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">tree grid</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">i-play sa malayuang device</translation>
+<translation id="190587075670221089">pag-delete</translation>
<translation id="1907737156431278478">halimbawa</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">katayuan</translation>
<translation id="1938124657309484470">Dapat <ph name="MAXIMUM_DATE_OR_TIME" /> o mas nauna ang value.</translation>
+<translation id="1946271899482435442">Ipakita ang picker ng petsa</translation>
<translation id="1993104285338243655">Lumipat sa pag-mirror</translation>
<translation id="2060505056492490888">Ginamit ang '<ph name="DOT" />' sa maling posisyon sa '<ph name="INVALIDDOMAIN" />.'</translation>
<translation id="2148716181193084225">Ngayon</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Isumite</translation>
<translation id="2657045182931379222">object ng graphics</translation>
<translation id="2674318244760992338">footer</translation>
+<translation id="2706474812903655270">Nagpe-play ang video na ito sa picture-in-picture mode</translation>
<translation id="2709516037105925701">AutoFill</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">Dapat <ph name="MINIMUM_DATE_OR_TIME" /> o mas bago ang value.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Ipakita ang susunod na buwan</translation>
<translation id="512758898067543763">header ng row</translation>
<translation id="5143125788380636750">epilogue</translation>
-<translation id="5153163864850940242">Nagpe-play ang video na ito sa Picture-in-Picture</translation>
<translation id="5164977714490026579">Dapat mas mataas kaysa sa o katumbas ng <ph name="MINIMUM" /> ang halaga.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> (na) PB</translation>
<translation id="5307600278924710095">Mangyaring maglagay ng isang bahagi na sinusundan ng '<ph name="ATSIGN" />.' Hindi kumpleto ang '<ph name="INVALIDADDRESS" />.'</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">colophon</translation>
<translation id="6934078000481955284">blockquote</translation>
<translation id="6941933287844615239">i-download ang media</translation>
+<translation id="6981594929165378967">paglagay</translation>
<translation id="6989848892321993519">Pakidagdagan ang text na ito nang hanggang <ph name="MIN_CHARACTERS" /> (na) character o higit pa (kasalukuyan kang gumagamit ng 1 character).</translation>
<translation id="709897737746224366">Pakitugma ang hiniling na format.</translation>
<translation id="7139483182332611405">preface</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">natitirang oras</translation>
<translation id="7740016676195725605">ihinto ang pagpapakita ng mga nakasarang caption</translation>
<translation id="7740050170769002709">HTML na nilalaman</translation>
+<translation id="7750228210027921155">Picture in picture</translation>
<translation id="7789962463072032349">i-pause</translation>
<translation id="7802800022689234070">disclosure triangle</translation>
<translation id="7888071071722539607">Mangyaring magsama ng '<ph name="ATSIGN" />' sa email address. Kulang ng '<ph name="ATSIGN" />' ang '<ph name="INVALIDADDRESS" />.'</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">talaan ng nilalaman</translation>
<translation id="8613126697340063924">kontrolin ang malayuang pag-playback</translation>
<translation id="862370744433916922">subtitle</translation>
-<translation id="8741316211671074806">Picture-in-Picture</translation>
<translation id="8750798805984357768">Mangyaring pumili ng isa sa mga opsyong ito.</translation>
<translation id="8785498733064193001">simulan ang pag-playback</translation>
<translation id="8808573423886751634">kabanata</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigation</translation>
<translation id="9050748414552849310">ipakita ang mga nakasarang caption</translation>
<translation id="9062295712474918030">dokumento</translation>
+<translation id="9093215626363556771">lumabas sa picture-in-picture</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">Iba pa...</translation>
<translation id="9138385573473225930">alerto</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, na magsisimula sa <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Picture in Picture</translation>
<translation id="9168329111483466115">footnote</translation>
-<translation id="947831847158436616">cell</translation>
+<translation id="954003015749068518">pumasok sa picture-in-picture</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_fr.xtb b/chromium/content/app/strings/translations/content_strings_fr.xtb
index 8e4af484697..f7877500711 100644
--- a/chromium/content/app/strings/translations/content_strings_fr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_fr.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">curseur</translation>
<translation id="1211441953136645838">note de fin</translation>
<translation id="1281252709823657822">boîte de dialogue</translation>
+<translation id="1289247557029249093">Quitter le mode PIP</translation>
<translation id="1335095011850992622">crédits</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">bannière</translation>
+<translation id="1548116112524424341">diffuser la vidéo en mode PIP</translation>
<translation id="1589122976691792535">région</translation>
<translation id="1591562245178063882">Ce mois</translation>
<translation id="1637811476055996098">Sélect. fichiers</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">arborescence</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">lire sur un appareil à distance</translation>
+<translation id="190587075670221089">suppression</translation>
<translation id="1907737156431278478">exemple</translation>
<translation id="1921819250265091946">jj</translation>
<translation id="1930711995431081526">état</translation>
<translation id="1938124657309484470">La date ou l'heure doit être égale ou antérieure à "<ph name="MAXIMUM_DATE_OR_TIME" />".</translation>
+<translation id="1946271899482435442">Afficher le sélecteur de date</translation>
<translation id="1993104285338243655">Passage à la duplication d'écran</translation>
<translation id="2060505056492490888">L'emplacement du caractère "<ph name="DOT" />" est incorrect dans "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">Aujourd'hui</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Valider</translation>
<translation id="2657045182931379222">objet graphique</translation>
<translation id="2674318244760992338">pied de page</translation>
+<translation id="2706474812903655270">Cette vidéo est diffusée en mode PIP</translation>
<translation id="2709516037105925701">Saisie automatique</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">La date ou l'heure doit être égale ou postérieure à "<ph name="MINIMUM_DATE_OR_TIME" />".</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Afficher le mois suivant</translation>
<translation id="512758898067543763">en-tête de ligne</translation>
<translation id="5143125788380636750">épilogue</translation>
-<translation id="5153163864850940242">Cette vidéo est diffusée en mode PIP (Picture-in-Picture)</translation>
<translation id="5164977714490026579">Cette valeur doit être supérieure ou égale à <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> Po</translation>
<translation id="5307600278924710095">Veuillez saisir la partie manquante avant le caractère "<ph name="ATSIGN" />". L'adresse "<ph name="INVALIDADDRESS" />" est incomplète.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">achevé d'imprimer</translation>
<translation id="6934078000481955284">bloc de citation</translation>
<translation id="6941933287844615239">télécharger des contenus multimédias</translation>
+<translation id="6981594929165378967">insertion</translation>
<translation id="6989848892321993519">Veuillez allonger ce texte pour qu'il comporte au moins <ph name="MIN_CHARACTERS" /> caractères. Il en compte actuellement un seul.</translation>
<translation id="709897737746224366">Veuillez respecter le format requis.</translation>
<translation id="7139483182332611405">préface</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">temps restant</translation>
<translation id="7740016676195725605">ne plus afficher les sous-titres</translation>
<translation id="7740050170769002709">Contenu HTML</translation>
+<translation id="7750228210027921155">Mode PIP (Picture-in-Picture)</translation>
<translation id="7789962463072032349">pause</translation>
<translation id="7802800022689234070">triangle d'expansion</translation>
<translation id="7888071071722539607">Veuillez inclure "<ph name="ATSIGN" />" dans l'adresse e-mail. Il manque un symbole "<ph name="ATSIGN" />" dans "<ph name="INVALIDADDRESS" />".</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">sommaire</translation>
<translation id="8613126697340063924">contrôler la lecture à distance</translation>
<translation id="862370744433916922">sous-titre</translation>
-<translation id="8741316211671074806">Picture-in-Picture</translation>
<translation id="8750798805984357768">Veuillez sélectionner l'une de ces options.</translation>
<translation id="8785498733064193001">commencer la lecture</translation>
<translation id="8808573423886751634">chapitre</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigation</translation>
<translation id="9050748414552849310">afficher les sous-titres</translation>
<translation id="9062295712474918030">document</translation>
+<translation id="9093215626363556771">quitter le mode PIP</translation>
<translation id="9108370397979208512">math.</translation>
<translation id="9132465097189459683">Autre…</translation>
<translation id="9138385573473225930">alerte</translation>
<translation id="9155987714137265666"><ph name="WEEK" /> (premier jour de la semaine : <ph name="WEEK_START_DATE" />)</translation>
+<translation id="916607977885256133">Picture-in-picture</translation>
<translation id="9168329111483466115">note de bas de page</translation>
-<translation id="947831847158436616">cellule</translation>
+<translation id="954003015749068518">utiliser le mode PIP</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_gu.xtb b/chromium/content/app/strings/translations/content_strings_gu.xtb
index 52c5bc2b23d..b5465b62ad4 100644
--- a/chromium/content/app/strings/translations/content_strings_gu.xtb
+++ b/chromium/content/app/strings/translations/content_strings_gu.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">સ્લાઇડર</translation>
<translation id="1211441953136645838">અંતિમ નોંધ</translation>
<translation id="1281252709823657822">સંવાદ</translation>
+<translation id="1289247557029249093">ચિત્રમાં ચિત્ર મોડમાંથી બહાર નીકળો</translation>
<translation id="1335095011850992622">ક્રેડિટ</translation>
<translation id="1342835525016946179">લેખ</translation>
<translation id="1359897965706325498">બેનર</translation>
+<translation id="1548116112524424341">ચિત્ર-માં-ચિત્ર મોડમાં વીડિઓ ચલાવો</translation>
<translation id="1589122976691792535">પ્રદેશ</translation>
<translation id="1591562245178063882">આ મહિને</translation>
<translation id="1637811476055996098">ફાઇલો પસંદ કરો</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">ટ્રી ગ્રિડ</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">રિમોટ ઉપકરણ પર ચલાવો</translation>
+<translation id="190587075670221089">ડિલીટ કરો</translation>
<translation id="1907737156431278478">ઉદાહરણ</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">સ્થિતિ</translation>
<translation id="1938124657309484470">મૂલ્ય <ph name="MAXIMUM_DATE_OR_TIME" /> અથવા પહેલાંનું હોવું આવશ્યક છે.</translation>
+<translation id="1946271899482435442">તારીખ પીકર બતાવો</translation>
<translation id="1993104285338243655">મીરરીંગ પર સ્વિચ કર્યુંં</translation>
<translation id="2060505056492490888">'<ph name="DOT" />' નો ઉપયોગ '<ph name="INVALIDDOMAIN" />' માં ખોટી જગ્યાએ થયો છે.</translation>
<translation id="2148716181193084225">આજે</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">સબમિટ કરો</translation>
<translation id="2657045182931379222">ગ્રાફિક્સ ઑબ્જેક્ટ</translation>
<translation id="2674318244760992338">ફૂટર</translation>
+<translation id="2706474812903655270">આ વીડિઓ ચિત્રમાં ચિત્ર મોડમાં ચાલી રહ્યો છે</translation>
<translation id="2709516037105925701">સ્વતઃભરો</translation>
<translation id="2723001399770238859">ઑડિઓ</translation>
<translation id="2746543609216772311">મૂલ્ય <ph name="MINIMUM_DATE_OR_TIME" /> અથવા પછીનું હોવું આવશ્યક છે.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">આગલો મહિનો દર્શાવો</translation>
<translation id="512758898067543763">પંક્તિ હેડર</translation>
<translation id="5143125788380636750">ઉપસંહાર</translation>
-<translation id="5153163864850940242">આ વીડિઓ ચિત્ર-માં-ચિત્ર મોડમાં ચાલી રહ્યો છે</translation>
<translation id="5164977714490026579">મૂલ્ય <ph name="MINIMUM" /> જેટલું અથવા આનાથી વધુ હોવું આવશ્યક છે.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">કૃપા કરીને '<ph name="ATSIGN" />' ની આગળનો ભાગ દાખલ કરો. '<ph name="INVALIDADDRESS" />' અપૂર્ણ છે.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">પ્રકાશકની માહિતી</translation>
<translation id="6934078000481955284">બ્લૉકક્વોટ</translation>
<translation id="6941933287844615239">મીડિયા ડાઉનલોડ કરો</translation>
+<translation id="6981594929165378967">ઉમેરો</translation>
<translation id="6989848892321993519">કૃપા કરીને આ ટેક્સ્ટને <ph name="MIN_CHARACTERS" /> અથવા તેથી વધુ અક્ષર સુધી લંબાવો (તમે હાલમાં 1 અક્ષરનો ઉપયોગ કરી રહ્યાં છો).</translation>
<translation id="709897737746224366">કૃપા કરીને વિનંતી કરેલા ફોર્મેટ સાથે મેળ કરો.</translation>
<translation id="7139483182332611405">પ્રસ્તાવના</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">બાકીનો સમય</translation>
<translation id="7740016676195725605">વિગતવાર ઉપશીર્ષકનું પ્રદર્શન અટકાવો</translation>
<translation id="7740050170769002709">HTML સામગ્રી</translation>
+<translation id="7750228210027921155">ચિત્રમાં ચિત્ર</translation>
<translation id="7789962463072032349">થોભો</translation>
<translation id="7802800022689234070">પ્રકટીકરણ ત્રિકોણ</translation>
<translation id="7888071071722539607">કૃપા કરીને ઇમેઇલ સરનામાંમાં '<ph name="ATSIGN" />' શામેલ કરો. '<ph name="INVALIDADDRESS" />' માં '<ph name="ATSIGN" />' ખૂટી રહ્યું છે.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">અનુક્રમણિકા</translation>
<translation id="8613126697340063924">રિમોટ પ્લેબેકનું નિયંત્રણ કરો</translation>
<translation id="862370744433916922">(સબટાઇટલ)</translation>
-<translation id="8741316211671074806">ચિત્ર-માં-ચિત્ર</translation>
<translation id="8750798805984357768">કૃપા કરીને આ વિકલ્પોમાંથી કોઈ એક પસંદ કરો.</translation>
<translation id="8785498733064193001">પ્લેબૅક શરૂ કરો</translation>
<translation id="8808573423886751634">પ્રકરણ</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">નેવિગેશન</translation>
<translation id="9050748414552849310">ઉપશીર્ષક બતાવો</translation>
<translation id="9062295712474918030">દસ્તાવેજ</translation>
+<translation id="9093215626363556771">ચિત્ર-માં-ચિત્રમાંથી બહાર નીકળો</translation>
<translation id="9108370397979208512">ગણિત</translation>
<translation id="9132465097189459683">અન્ય...</translation>
<translation id="9138385573473225930">ચેતવણી</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, <ph name="WEEK_START_DATE" /> થી શરૂ કરીને</translation>
+<translation id="916607977885256133">ચિત્ર-માં-ચિત્ર</translation>
<translation id="9168329111483466115">ફૂટનોટ</translation>
-<translation id="947831847158436616">કોષ</translation>
+<translation id="954003015749068518">ચિત્ર-માં-ચિત્રમાં પ્રવેશ કરો</translation>
<translation id="966787709310836684">મેનૂ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_hi.xtb b/chromium/content/app/strings/translations/content_strings_hi.xtb
index 422a5cf250b..6a1fc5cb0ca 100644
--- a/chromium/content/app/strings/translations/content_strings_hi.xtb
+++ b/chromium/content/app/strings/translations/content_strings_hi.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">स्लाइडर</translation>
<translation id="1211441953136645838">एंड नोट</translation>
<translation id="1281252709823657822">संवाद</translation>
+<translation id="1289247557029249093">'पिक्चर में पिक्चर' मोड से बाहर निकलें</translation>
<translation id="1335095011850992622">क्रेडिट</translation>
<translation id="1342835525016946179">लेख</translation>
<translation id="1359897965706325498">बैनर</translation>
+<translation id="1548116112524424341">वीडियो को पिक्चर में पिक्चर मोड में चलाएं</translation>
<translation id="1589122976691792535">क्षेत्र</translation>
<translation id="1591562245178063882">इस माह</translation>
<translation id="1637811476055996098">फ़ाइलें चुनें</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">ट्री ग्रिड</translation>
<translation id="1822429046913737220">पूर्वाह्न/अपराह्न</translation>
<translation id="1832974991323546415">दूरस्थ डिवाइस पर चलाएं</translation>
+<translation id="190587075670221089">मिटाना</translation>
<translation id="1907737156431278478">उदाहरण</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">स्थिति</translation>
<translation id="1938124657309484470">मान <ph name="MAXIMUM_DATE_OR_TIME" /> या पहले का होना चाहिए.</translation>
+<translation id="1946271899482435442">तारीख पिकर दिखाएं</translation>
<translation id="1993104285338243655">स्क्रीन शेयर करने पर स्विच किया गया</translation>
<translation id="2060505056492490888">'<ph name="DOT" />' का '<ph name="INVALIDDOMAIN" />' में गलत स्थान पर उपयोग किया गया है.</translation>
<translation id="2148716181193084225">आज</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">सबमिट करें</translation>
<translation id="2657045182931379222">ग्राफ़िक्स ऑब्जेक्ट</translation>
<translation id="2674318244760992338">पाद लेख</translation>
+<translation id="2706474812903655270">यह वीडियो 'पिक्चर में पिक्चर' मोड में चल रहा है</translation>
<translation id="2709516037105925701">ऑटोमैटिक भरना</translation>
<translation id="2723001399770238859">ऑडियो</translation>
<translation id="2746543609216772311">मान <ph name="MINIMUM_DATE_OR_TIME" /> या बाद का होना चाहिए.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">अगला माह दिखाएं</translation>
<translation id="512758898067543763">पंक्ति शीर्षलेख</translation>
<translation id="5143125788380636750">उपसंहार</translation>
-<translation id="5153163864850940242">यह वीडियो पिक्चर में पिक्चर मोड में चल रहा है</translation>
<translation id="5164977714490026579">मान <ph name="MINIMUM" /> से कम या इसके बराबर होना चाहिए.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">कृपया '<ph name="ATSIGN" />' के पहले वाला भाग डालें. '<ph name="INVALIDADDRESS" />' अधूरा है.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">कॉलफ़न</translation>
<translation id="6934078000481955284">ब्लॉककोट</translation>
<translation id="6941933287844615239">मीडिया डाउनलोड करें</translation>
+<translation id="6981594929165378967">डालना</translation>
<translation id="6989848892321993519">कृपया इस लेख को <ph name="MIN_CHARACTERS" /> या उससे ज़्यादा वर्णों तक बढ़ाएं (आप इस समय 1 वर्ण का उपयोग कर रहे हैं).</translation>
<translation id="709897737746224366">कृपया अनुरोधित प्रारूप का मिलान करें.</translation>
<translation id="7139483182332611405">आमुख</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">शेष समय</translation>
<translation id="7740016676195725605">बंद कैप्शन दिखाना रोकें</translation>
<translation id="7740050170769002709">HTML सामग्री</translation>
+<translation id="7750228210027921155">पिक्चर में पिक्चर</translation>
<translation id="7789962463072032349">पॉज़ करें</translation>
<translation id="7802800022689234070">प्रकटीकरण त्रिकोण</translation>
<translation id="7888071071722539607">कृपया ईमेल पते में '<ph name="ATSIGN" />' शामिल करें. '<ph name="INVALIDADDRESS" />' में '<ph name="ATSIGN" />' नहीं है.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">विषय सूची</translation>
<translation id="8613126697340063924">दूरस्थ प्लेबैक नियंत्रित करें</translation>
<translation id="862370744433916922">सबटाइटल</translation>
-<translation id="8741316211671074806">पिक्चर में पिक्चर</translation>
<translation id="8750798805984357768">कृपया इनमें से कोई विकल्प चुनें.</translation>
<translation id="8785498733064193001">प्लेबैक शुरू करें</translation>
<translation id="8808573423886751634">पाठ</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">मार्गदर्शक</translation>
<translation id="9050748414552849310">बंद कैप्शन दिखाएं</translation>
<translation id="9062295712474918030">दस्तावेज़</translation>
+<translation id="9093215626363556771">पिक्चर में पिक्चर से बाहर निकलें</translation>
<translation id="9108370397979208512">गणित</translation>
<translation id="9132465097189459683">अन्य...</translation>
<translation id="9138385573473225930">सूचना</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, <ph name="WEEK_START_DATE" /> से प्रारंभ हो रहा है</translation>
+<translation id="916607977885256133">पिक्चर में पिक्चर</translation>
<translation id="9168329111483466115">फ़ुटनोट</translation>
-<translation id="947831847158436616">सेल</translation>
+<translation id="954003015749068518">पिक्चर में पिक्चर चालू करें</translation>
<translation id="966787709310836684">मेनू</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_hr.xtb b/chromium/content/app/strings/translations/content_strings_hr.xtb
index 1f23cd9eec2..bbf447885d3 100644
--- a/chromium/content/app/strings/translations/content_strings_hr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_hr.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">klizač</translation>
<translation id="1211441953136645838">završna napomena</translation>
<translation id="1281252709823657822">dijalog</translation>
+<translation id="1289247557029249093">Izlaz iz načina slike u slici</translation>
<translation id="1335095011850992622">zasluge</translation>
<translation id="1342835525016946179">članak</translation>
<translation id="1359897965706325498">natpis</translation>
+<translation id="1548116112524424341">reprodukcija videozapisa u načnu slike u slici</translation>
<translation id="1589122976691792535">regija</translation>
<translation id="1591562245178063882">Ovaj mjesec</translation>
<translation id="1637811476055996098">Odabir datoteka</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">rešetka u obliku stabla</translation>
<translation id="1822429046913737220">prijepodne/poslijepodne</translation>
<translation id="1832974991323546415">reproduciraj na udaljenom uređaju</translation>
+<translation id="190587075670221089">brisanje</translation>
<translation id="1907737156431278478">primjer</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">status</translation>
<translation id="1938124657309484470">Vrijednost mora biti <ph name="MAXIMUM_DATE_OR_TIME" /> ili prije toga.</translation>
+<translation id="1946271899482435442">Prikaz alata za odabir datuma</translation>
<translation id="1993104285338243655">Prebačeno na zrcaljenje</translation>
<translation id="2060505056492490888">Znak "<ph name="DOT" />" upotrebljava se na pogrešnom položaju u domeni "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">Danas</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Pošalji</translation>
<translation id="2657045182931379222">grafički objekt</translation>
<translation id="2674318244760992338">podnožje</translation>
+<translation id="2706474812903655270">Ovaj se videozapis prikazuje u načinu slike u slici</translation>
<translation id="2709516037105925701">Automatsko popunjavanje</translation>
<translation id="2723001399770238859">zvuk</translation>
<translation id="2746543609216772311">Vrijednost mora biti <ph name="MINIMUM_DATE_OR_TIME" /> ili nakon toga.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Prikaži sljedeći mjesec</translation>
<translation id="512758898067543763">zaglavlje retka</translation>
<translation id="5143125788380636750">epilog</translation>
-<translation id="5153163864850940242">Ovaj se videozapis prikazuje u značajci slike u slici</translation>
<translation id="5164977714490026579">Vrijednost mora biti <ph name="MINIMUM" /> ili veća.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Unesite dio adrese ispred znaka "<ph name="ATSIGN" />". "<ph name="INVALIDADDRESS" />" nije potpuna e-adresa.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofon</translation>
<translation id="6934078000481955284">uvučeni citat</translation>
<translation id="6941933287844615239">preuzmi medij</translation>
+<translation id="6981594929165378967">umetanje</translation>
<translation id="6989848892321993519">Produljite broj znakova u tekstu na minimalno <ph name="MIN_CHARACTERS" /> (trenutačno imate 1 znak).</translation>
<translation id="709897737746224366">Udovoljite zadanom formatu.</translation>
<translation id="7139483182332611405">predgovor</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">preostalo vrijeme</translation>
<translation id="7740016676195725605">zaustavljanje prikazivanja titlova</translation>
<translation id="7740050170769002709">HTML sadržaj</translation>
+<translation id="7750228210027921155">Slika u slici</translation>
<translation id="7789962463072032349">pauziraj</translation>
<translation id="7802800022689234070">trokut za otkrivanje</translation>
<translation id="7888071071722539607">Uključite znak "<ph name="ATSIGN" />" u e-adresu. U adresi "<ph name="INVALIDADDRESS" />" nedostaje znak "<ph name="ATSIGN" />".</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">sadržaj</translation>
<translation id="8613126697340063924">upravljaj daljinskom reprodukcijom</translation>
<translation id="862370744433916922">titl</translation>
-<translation id="8741316211671074806">Slika u slici</translation>
<translation id="8750798805984357768">Izaberite jednu od tih opcija.</translation>
<translation id="8785498733064193001">početak reprodukcije</translation>
<translation id="8808573423886751634">poglavlje</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigacija</translation>
<translation id="9050748414552849310">prikazivanje titlova</translation>
<translation id="9062295712474918030">dokument</translation>
+<translation id="9093215626363556771">izlaz iz načina slika u slici</translation>
<translation id="9108370397979208512">mat</translation>
<translation id="9132465097189459683">Drugo...</translation>
<translation id="9138385573473225930">upozorenje</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, počevši od <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Slika u slici</translation>
<translation id="9168329111483466115">fusnota</translation>
-<translation id="947831847158436616">ćelija</translation>
+<translation id="954003015749068518">pokretanje načina slika u slici</translation>
<translation id="966787709310836684">izbornik</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_hu.xtb b/chromium/content/app/strings/translations/content_strings_hu.xtb
index 00378120757..a5ba319109d 100644
--- a/chromium/content/app/strings/translations/content_strings_hu.xtb
+++ b/chromium/content/app/strings/translations/content_strings_hu.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">csúszka</translation>
<translation id="1211441953136645838">záró jegyzet</translation>
<translation id="1281252709823657822">párbeszédpanel</translation>
+<translation id="1289247557029249093">Kilépés a kép a képben módból</translation>
<translation id="1335095011850992622">készítők</translation>
<translation id="1342835525016946179">cikk</translation>
<translation id="1359897965706325498">szalaghirdetés</translation>
+<translation id="1548116112524424341">videó lejátszása kép a képben módban</translation>
<translation id="1589122976691792535">régió</translation>
<translation id="1591562245178063882">Ebben a hónapban</translation>
<translation id="1637811476055996098">Fájlok kiválasztása</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">farács</translation>
<translation id="1822429046913737220">de./du.</translation>
<translation id="1832974991323546415">lejátszás távoli eszközön</translation>
+<translation id="190587075670221089">törlés</translation>
<translation id="1907737156431278478">példa</translation>
<translation id="1921819250265091946">nn</translation>
<translation id="1930711995431081526">állapot</translation>
<translation id="1938124657309484470">Az érték <ph name="MAXIMUM_DATE_OR_TIME" /> vagy azt megelőző kell, hogy legyen.</translation>
+<translation id="1946271899482435442">Dátumválasztó megjelenítése</translation>
<translation id="1993104285338243655">Átváltott tükrözésre</translation>
<translation id="2060505056492490888">A „<ph name="DOT" />” rossz helyen van a(z) „<ph name="INVALIDDOMAIN" />” címben.</translation>
<translation id="2148716181193084225">Ma</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Elküldés</translation>
<translation id="2657045182931379222">grafikus objektum</translation>
<translation id="2674318244760992338">lábléc</translation>
+<translation id="2706474812903655270">A videó lejátszása kép a képben módban történik</translation>
<translation id="2709516037105925701">Automatikus kitöltés</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">Az érték <ph name="MINIMUM_DATE_OR_TIME" /> vagy azt követő kell, hogy legyen.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">A következő hónap megjelenítése</translation>
<translation id="512758898067543763">sorfejléc</translation>
<translation id="5143125788380636750">végszó</translation>
-<translation id="5153163864850940242">A videó lejátszása kép a képben módban történik</translation>
<translation id="5164977714490026579">Az érték legyen nagyobb vagy egyenlő, mint <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Kérjük, adja meg a „<ph name="ATSIGN" />” előtti részt is. A „<ph name="INVALIDADDRESS" />” cím nem teljes.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofon</translation>
<translation id="6934078000481955284">bekezdésszintű idézet</translation>
<translation id="6941933287844615239">médiafájlok letöltése</translation>
+<translation id="6981594929165378967">beszúrás</translation>
<translation id="6989848892321993519">Legalább <ph name="MIN_CHARACTERS" /> karakter hosszú szöveget adjon meg (jelenleg 1 karaktert használ).</translation>
<translation id="709897737746224366">Kérjük, tartsa magát a kívánt formátumhoz.</translation>
<translation id="7139483182332611405">bevezető</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">hátralévő idő</translation>
<translation id="7740016676195725605">feliratok elrejtése</translation>
<translation id="7740050170769002709">HTML-tartalom</translation>
+<translation id="7750228210027921155">Kép a képben</translation>
<translation id="7789962463072032349">szüneteltetés</translation>
<translation id="7802800022689234070">plusz tartalom kibontására szolgáló háromszög</translation>
<translation id="7888071071722539607">Kérjük, írjon egy „<ph name="ATSIGN" />” karaktert az e-mail címbe. A(z) „<ph name="INVALIDADDRESS" />” címből hiányzik a „<ph name="ATSIGN" />” jel.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">tartalomjegyzék</translation>
<translation id="8613126697340063924">távoli lejátszás kezelése</translation>
<translation id="862370744433916922">felirat</translation>
-<translation id="8741316211671074806">Kép a képben</translation>
<translation id="8750798805984357768">Kérjük, válassza ki az egyik opciót.</translation>
<translation id="8785498733064193001">lejátszás indítása</translation>
<translation id="8808573423886751634">fejezet</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigáció</translation>
<translation id="9050748414552849310">feliratok megjelenítése</translation>
<translation id="9062295712474918030">dokumentum</translation>
+<translation id="9093215626363556771">kilépés a kép a képben funkcióból</translation>
<translation id="9108370397979208512">matematika</translation>
<translation id="9132465097189459683">Más...</translation>
<translation id="9138385573473225930">értesítés</translation>
<translation id="9155987714137265666"><ph name="WEEK" />. hét (<ph name="WEEK_START_DATE" />-i dátummal kezdődik)</translation>
+<translation id="916607977885256133">Kép a képben</translation>
<translation id="9168329111483466115">lábjegyzet</translation>
-<translation id="947831847158436616">cella</translation>
+<translation id="954003015749068518">belépés a kép a képben funkcióba</translation>
<translation id="966787709310836684">menü</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_id.xtb b/chromium/content/app/strings/translations/content_strings_id.xtb
index e0da8db2aec..e1c21fd0162 100644
--- a/chromium/content/app/strings/translations/content_strings_id.xtb
+++ b/chromium/content/app/strings/translations/content_strings_id.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">penggeser</translation>
<translation id="1211441953136645838">catatan akhir</translation>
<translation id="1281252709823657822">dialog</translation>
+<translation id="1289247557029249093">Keluar dari mode picture-in-picture</translation>
<translation id="1335095011850992622">daftar penghargaan</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">spanduk</translation>
+<translation id="1548116112524424341">memutar video dalam mode picture-in-picture</translation>
<translation id="1589122976691792535">wilayah</translation>
<translation id="1591562245178063882">Bulan ini</translation>
<translation id="1637811476055996098">Pilih File</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">kisi pohon</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">putar di perangkat jarak jauh</translation>
+<translation id="190587075670221089">penghapusan</translation>
<translation id="1907737156431278478">contoh</translation>
<translation id="1921819250265091946">hh</translation>
<translation id="1930711995431081526">status</translation>
<translation id="1938124657309484470">Tanggal harus <ph name="MAXIMUM_DATE_OR_TIME" /> atau lebih awal.</translation>
+<translation id="1946271899482435442">Tampilkan alat pilih tanggal</translation>
<translation id="1993104285338243655">Dialihkan ke pencerminan</translation>
<translation id="2060505056492490888">'<ph name="DOT" />' digunakan pada posisi yang salah di '<ph name="INVALIDDOMAIN" />'.</translation>
<translation id="2148716181193084225">Hari ini</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Kirim</translation>
<translation id="2657045182931379222">objek grafis</translation>
<translation id="2674318244760992338">footer</translation>
+<translation id="2706474812903655270">Video ini diputar dalam mode picture-in-picture</translation>
<translation id="2709516037105925701">Isi-Otomatis</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">Tanggal harus <ph name="MINIMUM_DATE_OR_TIME" /> atau setelahnya.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Tampilkan bulan berikutnya</translation>
<translation id="512758898067543763">judul baris</translation>
<translation id="5143125788380636750">epilog</translation>
-<translation id="5153163864850940242">Video ini diputar dalam Picture-in-Picture</translation>
<translation id="5164977714490026579">Nilai harus lebih besar daripada atau sama dengan <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Masukkan bagian yang diikuti dengan '<ph name="ATSIGN" />'. '<ph name="INVALIDADDRESS" />' tidak lengkap.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofon</translation>
<translation id="6934078000481955284">blockquote</translation>
<translation id="6941933287844615239">download media</translation>
+<translation id="6981594929165378967">penyisipan</translation>
<translation id="6989848892321993519">Perpanjang teks ini menjadi <ph name="MIN_CHARACTERS" /> karakter atau lebih (saat ini Anda menggunakan 1 karakter).</translation>
<translation id="709897737746224366">Sesuaikan dengan format yang diminta.</translation>
<translation id="7139483182332611405">kata pengantar</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">sisa waktu</translation>
<translation id="7740016676195725605">berhenti menampilkan teks</translation>
<translation id="7740050170769002709">Konten HTML</translation>
+<translation id="7750228210027921155">Picture-in-picture</translation>
<translation id="7789962463072032349">jeda</translation>
<translation id="7802800022689234070">segitiga pengungkapan</translation>
<translation id="7888071071722539607">Sertakan '<ph name="ATSIGN" />' pada alamat email. '<ph name="INVALIDADDRESS" />' tidak memiliki '<ph name="ATSIGN" />'.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">daftar isi</translation>
<translation id="8613126697340063924">kontrol pemutaran jarak jauh</translation>
<translation id="862370744433916922">subjudul</translation>
-<translation id="8741316211671074806">Picture-in-Picture</translation>
<translation id="8750798805984357768">Pilih salah satu opsi berikut.</translation>
<translation id="8785498733064193001">mulai pemutaran</translation>
<translation id="8808573423886751634">bab</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigasi</translation>
<translation id="9050748414552849310">tampilkan teks</translation>
<translation id="9062295712474918030">dokumen</translation>
+<translation id="9093215626363556771">keluar dari mode picture-in-picture</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">Lainnya...</translation>
<translation id="9138385573473225930">notifikasi</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, dimulai pada <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Picture-in-Picture</translation>
<translation id="9168329111483466115">catatan kaki</translation>
-<translation id="947831847158436616">sel</translation>
+<translation id="954003015749068518">masuk mode picture-in-picture</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_it.xtb b/chromium/content/app/strings/translations/content_strings_it.xtb
index 72572258b83..283ac3b20d4 100644
--- a/chromium/content/app/strings/translations/content_strings_it.xtb
+++ b/chromium/content/app/strings/translations/content_strings_it.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">dispositivo di scorrimento</translation>
<translation id="1211441953136645838">nota finale</translation>
<translation id="1281252709823657822">finestra di dialogo</translation>
+<translation id="1289247557029249093">Esci dalla modalità Picture-in-picture</translation>
<translation id="1335095011850992622">ringraziamenti</translation>
<translation id="1342835525016946179">articolo</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">riproduci video in modalità picture in picture</translation>
<translation id="1589122976691792535">regione</translation>
<translation id="1591562245178063882">Questo mese</translation>
<translation id="1637811476055996098">Scegli file</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">griglia ad albero</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">riproduci su dispositivo remoto</translation>
+<translation id="190587075670221089">eliminazione</translation>
<translation id="1907737156431278478">esempio</translation>
<translation id="1921819250265091946">gg</translation>
<translation id="1930711995431081526">stato</translation>
<translation id="1938124657309484470">Il valore deve essere <ph name="MAXIMUM_DATE_OR_TIME" /> o precedente.</translation>
+<translation id="1946271899482435442">Mostra selettore date</translation>
<translation id="1993104285338243655">Sei passato a mirroring</translation>
<translation id="2060505056492490888">Il segno "<ph name="DOT" />" è utilizzato in una posizione errata in "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">Oggi</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Invia</translation>
<translation id="2657045182931379222">oggetto grafico</translation>
<translation id="2674318244760992338">piè di pagina</translation>
+<translation id="2706474812903655270">Questo video è riprodotto in modalità Picture in picture</translation>
<translation id="2709516037105925701">Compilazione automatica</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">Il valore deve essere <ph name="MINIMUM_DATE_OR_TIME" /> o successivo.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Mostra mese successivo</translation>
<translation id="512758898067543763">intestazione di riga</translation>
<translation id="5143125788380636750">epilogo</translation>
-<translation id="5153163864850940242">Questo video è riprodotto in modalità picture in picture</translation>
<translation id="5164977714490026579">Il valore deve essere superiore o uguale a <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Inserisci una parte seguita da "<ph name="ATSIGN" />". Il valore "<ph name="INVALIDADDRESS" />" è incompleto.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">colophon</translation>
<translation id="6934078000481955284">citazione lunga</translation>
<translation id="6941933287844615239">scarica contenuti multimediali</translation>
+<translation id="6981594929165378967">inserimento</translation>
<translation id="6989848892321993519">Prolunga questo testo a <ph name="MIN_CHARACTERS" /> o più caratteri (al momento stai utilizzando 1 carattere).</translation>
<translation id="709897737746224366">Rispetta il formato richiesto.</translation>
<translation id="7139483182332611405">prefazione</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">tempo rimanente</translation>
<translation id="7740016676195725605">interrompi la visualizzazione dei sottotitoli</translation>
<translation id="7740050170769002709">Contenuti HTML</translation>
+<translation id="7750228210027921155">Picture in picture</translation>
<translation id="7789962463072032349">pausa</translation>
<translation id="7802800022689234070">triangolo descrittivo</translation>
<translation id="7888071071722539607">Aggiungi un simbolo "<ph name="ATSIGN" />" nell'indirizzo email. In "<ph name="INVALIDADDRESS" />" manca un simbolo "<ph name="ATSIGN" />".</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">sommario</translation>
<translation id="8613126697340063924">gestisci riproduzione remota</translation>
<translation id="862370744433916922">sottotitolo</translation>
-<translation id="8741316211671074806">Picture in picture</translation>
<translation id="8750798805984357768">Seleziona una di queste opzioni.</translation>
<translation id="8785498733064193001">inizia riproduzione</translation>
<translation id="8808573423886751634">capitolo</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigazione</translation>
<translation id="9050748414552849310">mostra sottotitoli</translation>
<translation id="9062295712474918030">documento</translation>
+<translation id="9093215626363556771">esci da picture in picture</translation>
<translation id="9108370397979208512">elemento matematico</translation>
<translation id="9132465097189459683">Altro...</translation>
<translation id="9138385573473225930">avviso</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, a partire dal giorno <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Picture in picture</translation>
<translation id="9168329111483466115">piè di pagina</translation>
-<translation id="947831847158436616">cella</translation>
+<translation id="954003015749068518">attiva picture in picture</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_iw.xtb b/chromium/content/app/strings/translations/content_strings_iw.xtb
index 3a5a640f164..e0a2ae56a94 100644
--- a/chromium/content/app/strings/translations/content_strings_iw.xtb
+++ b/chromium/content/app/strings/translations/content_strings_iw.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">מחוון</translation>
<translation id="1211441953136645838">הערת סיום</translation>
<translation id="1281252709823657822">דו-שיח</translation>
+<translation id="1289247557029249093">יציאה ממצב 'תמונה בתוך תמונה'</translation>
<translation id="1335095011850992622">קרדיטים</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">מודעת באנר</translation>
+<translation id="1548116112524424341">הפעלת הסרטון במצב 'תמונה בתוך תמונה'</translation>
<translation id="1589122976691792535">אזור</translation>
<translation id="1591562245178063882">החודש</translation>
<translation id="1637811476055996098">בחר קבצים</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">רשת של עץ</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">הפעלה במכשיר מרוחק</translation>
+<translation id="190587075670221089">מחיקה</translation>
<translation id="1907737156431278478">דוגמה</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">מצב</translation>
<translation id="1938124657309484470">על הערך להיות <ph name="MAXIMUM_DATE_OR_TIME" /> או מוקדם יותר.</translation>
+<translation id="1946271899482435442">הצגת בוחר התאריכים</translation>
<translation id="1993104285338243655">הועבר לשיקוף מסך</translation>
<translation id="2060505056492490888">נעשה שימוש ב-'<ph name="DOT" />' במיקום שגוי ב-'<ph name="INVALIDDOMAIN" />'.</translation>
<translation id="2148716181193084225">היום</translation>
@@ -40,7 +44,7 @@
<translation id="2311842470354187719">מעבר דף</translation>
<translation id="2335594187091864976">בוחר תאריך ושעה</translation>
<translation id="248395913932153421">יום</translation>
-<translation id="2507943997699731163">מלא שדה זה.</translation>
+<translation id="2507943997699731163">זהו שדה חובה.</translation>
<translation id="2508569020611168319">רשימת כרטיסיות</translation>
<translation id="2561842179657104141">הצג עוד פקדי מדיה</translation>
<translation id="2572483411312390101">הפעל</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">שלח</translation>
<translation id="2657045182931379222">אובייקט גרפי</translation>
<translation id="2674318244760992338">כותרת תחתונה</translation>
+<translation id="2706474812903655270">הסרטון הזה פועל במצב 'תמונה בתוך תמונה'</translation>
<translation id="2709516037105925701">מילוי אוטומטי</translation>
<translation id="2723001399770238859">אודיו</translation>
<translation id="2746543609216772311">על הערך להיות <ph name="MINIMUM_DATE_OR_TIME" /> ומעלה.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">הצג את החודש הבא</translation>
<translation id="512758898067543763">כותרת שורה</translation>
<translation id="5143125788380636750">אפילוג</translation>
-<translation id="5153163864850940242">הסרטון הזה פועל במצב תמונה בתוך תמונה</translation>
<translation id="5164977714490026579">הערך חייב להיות גדול מ-<ph name="MINIMUM" /> או שווה לו.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">הזן חלק ולאחריו '<ph name="ATSIGN" />'‏. השדה '<ph name="INVALIDADDRESS" />' אינו מלא.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">קולופון</translation>
<translation id="6934078000481955284">‏רכיב blockquote</translation>
<translation id="6941933287844615239">הורד מדיה</translation>
+<translation id="6981594929165378967">הוספה</translation>
<translation id="6989848892321993519">עליך להאריך את הטקסט ל-<ph name="MIN_CHARACTERS" /> תווים או יותר (אתה משתמש כרגע בתו אחד).</translation>
<translation id="709897737746224366">התאם את הפורמט המבוקש.</translation>
<translation id="7139483182332611405">הקדמה</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">זמן שנותר</translation>
<translation id="7740016676195725605">הפסק להציג כתוביות סגורות</translation>
<translation id="7740050170769002709">‏תוכן HTML</translation>
+<translation id="7750228210027921155">תמונה בתוך תמונה</translation>
<translation id="7789962463072032349">השהה</translation>
<translation id="7802800022689234070">משולש הצגה/הסתרה</translation>
<translation id="7888071071722539607">כלול '<ph name="ATSIGN" />' בכתובת האימייל. ב-'<ph name="INVALIDADDRESS" />' חסר '<ph name="ATSIGN" />'.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">תוכן העניינים</translation>
<translation id="8613126697340063924">שליטה בהפעלה מרחוק</translation>
<translation id="862370744433916922">כותרת משנה</translation>
-<translation id="8741316211671074806">תמונה בתוך תמונה</translation>
<translation id="8750798805984357768">בחר אחת מהאפשרויות הבאות.</translation>
<translation id="8785498733064193001">התחל בהפעלה</translation>
<translation id="8808573423886751634">פרק</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">ניווט</translation>
<translation id="9050748414552849310">הצג כתוביות סגורות</translation>
<translation id="9062295712474918030">מסמך</translation>
+<translation id="9093215626363556771">יציאה ממצב 'תמונה בתוך תמונה'</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">אחר...</translation>
<translation id="9138385573473225930">התראה</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, שמתחיל בתאריך <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">תמונה בתוך תמונה</translation>
<translation id="9168329111483466115">הערת שוליים</translation>
-<translation id="947831847158436616">תא</translation>
+<translation id="954003015749068518">מעבר אל מצב 'תמונה בתוך תמונה'</translation>
<translation id="966787709310836684">תפריט</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_ja.xtb b/chromium/content/app/strings/translations/content_strings_ja.xtb
index 314178fe319..c8de1475332 100644
--- a/chromium/content/app/strings/translations/content_strings_ja.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ja.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">スライダ</translation>
<translation id="1211441953136645838">巻末注</translation>
<translation id="1281252709823657822">ダイアログ</translation>
+<translation id="1289247557029249093">ピクチャー イン ピクチャー モードを終了する</translation>
<translation id="1335095011850992622">クレジット</translation>
<translation id="1342835525016946179">記事</translation>
<translation id="1359897965706325498">バナー</translation>
+<translation id="1548116112524424341">ピクチャー イン ピクチャー モードで動画を再生します</translation>
<translation id="1589122976691792535">地域</translation>
<translation id="1591562245178063882">今月</translation>
<translation id="1637811476055996098">ファイル選択</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">ツリーグリッド</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">リモート デバイスで再生</translation>
+<translation id="190587075670221089">削除</translation>
<translation id="1907737156431278478">例</translation>
<translation id="1921819250265091946">日</translation>
<translation id="1930711995431081526">ステータス</translation>
<translation id="1938124657309484470"><ph name="MAXIMUM_DATE_OR_TIME" /> 以前の値を指定する必要があります。</translation>
+<translation id="1946271899482435442">日付選択ツールを表示</translation>
<translation id="1993104285338243655">ミラーリングに切り替わりました</translation>
<translation id="2060505056492490888">「<ph name="INVALIDDOMAIN" />」内の「<ph name="DOT" />」の位置が間違っています。</translation>
<translation id="2148716181193084225">今日</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">送信</translation>
<translation id="2657045182931379222">図形オブジェクト</translation>
<translation id="2674318244760992338">フッター</translation>
+<translation id="2706474812903655270">この動画はピクチャー イン ピクチャー モードで再生されています</translation>
<translation id="2709516037105925701">自動入力</translation>
<translation id="2723001399770238859">音声</translation>
<translation id="2746543609216772311"><ph name="MINIMUM_DATE_OR_TIME" /> 以降の値を指定する必要があります。</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">次の月を表示</translation>
<translation id="512758898067543763">行見出し</translation>
<translation id="5143125788380636750">エピローグ</translation>
-<translation id="5153163864850940242">この動画はピクチャー イン ピクチャーで再生されています</translation>
<translation id="5164977714490026579">値は <ph name="MINIMUM" /> 以上にする必要があります。</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">「<ph name="ATSIGN" />」の前の文字列を入力してください。「<ph name="INVALIDADDRESS" />」は完全なメール アドレスではありません。</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">奥付</translation>
<translation id="6934078000481955284">引用</translation>
<translation id="6941933287844615239">メディアをダウンロード</translation>
+<translation id="6981594929165378967">挿入</translation>
<translation id="6989848892321993519">このテキストは <ph name="MIN_CHARACTERS" /> 文字以上で指定してください(現在 1 文字で指定されています)。</translation>
<translation id="709897737746224366">指定されている形式で入力してください。</translation>
<translation id="7139483182332611405">序文</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">残り時間</translation>
<translation id="7740016676195725605">クローズド キャプションの表示を終了</translation>
<translation id="7740050170769002709">HTML コンテンツ</translation>
+<translation id="7750228210027921155">ピクチャー イン ピクチャー</translation>
<translation id="7789962463072032349">一時停止</translation>
<translation id="7802800022689234070">三角形の展開ボタン</translation>
<translation id="7888071071722539607">メール アドレスに「<ph name="ATSIGN" />」を挿入してください。「<ph name="INVALIDADDRESS" />」内に「<ph name="ATSIGN" />」がありません。</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">目次</translation>
<translation id="8613126697340063924">リモート再生をコントロール</translation>
<translation id="862370744433916922">副題</translation>
-<translation id="8741316211671074806">ピクチャー イン ピクチャー</translation>
<translation id="8750798805984357768">これらのオプションから 1 つ選択してください。</translation>
<translation id="8785498733064193001">再生を開始</translation>
<translation id="8808573423886751634">章</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">ナビゲーション</translation>
<translation id="9050748414552849310">クローズド キャプションを表示</translation>
<translation id="9062295712474918030">ドキュメント</translation>
+<translation id="9093215626363556771">ピクチャー イン ピクチャーを終了します</translation>
<translation id="9108370397979208512">数式</translation>
<translation id="9132465097189459683">その他...</translation>
<translation id="9138385573473225930">アラート</translation>
<translation id="9155987714137265666"><ph name="WEEK_START_DATE" /> から始まる <ph name="WEEK" /></translation>
+<translation id="916607977885256133">ピクチャー イン ピクチャー</translation>
<translation id="9168329111483466115">脚注</translation>
-<translation id="947831847158436616">セル</translation>
+<translation id="954003015749068518">ピクチャー イン ピクチャーを開始します</translation>
<translation id="966787709310836684">メニュー</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_kn.xtb b/chromium/content/app/strings/translations/content_strings_kn.xtb
index 02c6cdc5517..0783881a705 100644
--- a/chromium/content/app/strings/translations/content_strings_kn.xtb
+++ b/chromium/content/app/strings/translations/content_strings_kn.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">ಸ್ಲೈಡರ್</translation>
<translation id="1211441953136645838">ಮುಕ್ತಾಯ ಟಿಪ್ಪಣಿ</translation>
<translation id="1281252709823657822">ಸಂವಾದ</translation>
+<translation id="1289247557029249093">ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ ಮೋಡ್ ಅನ್ನು ನಿರ್ಗಮಿಸಿ</translation>
<translation id="1335095011850992622">ಕ್ರೆಡಿಟ್‌ಗಳು</translation>
<translation id="1342835525016946179">ಲೇಖನ</translation>
<translation id="1359897965706325498">ಬ್ಯಾನರ್</translation>
+<translation id="1548116112524424341">ಚಿತ್ರದಲ್ಲಿನ ಚಿತ್ರದ ಮೋಡ್‌ನಲ್ಲಿ ವೀಡಿಯೊ ಪ್ಲೇ ಮಾಡಿ</translation>
<translation id="1589122976691792535">ಪ್ರದೇಶ</translation>
<translation id="1591562245178063882">ಈ ತಿಂಗಳು</translation>
<translation id="1637811476055996098">ಫೈಲ್‌ಗಳನ್ನು ಆರಿಸಿ</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">ಟ್ರೀ ಗ್ರಿಡ್</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">ರಿಮೋಟ್ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಮಾಡಿ</translation>
+<translation id="190587075670221089">ಅಳಿಸುವಿಕೆ</translation>
<translation id="1907737156431278478">ಉದಾಹರಣೆ</translation>
<translation id="1921819250265091946">ದಿದಿ</translation>
<translation id="1930711995431081526">ಸ್ಥಿತಿ</translation>
<translation id="1938124657309484470">ಮೌಲ್ಯವು <ph name="MAXIMUM_DATE_OR_TIME" /> ಅಥವಾ ಹಿಂದಿನದ್ದಾಗಿರಬೇಕು.</translation>
+<translation id="1946271899482435442">ದಿನಾಂಕದ ಆಯ್ಕೆಯನ್ನು ತೋರಿಸಿ</translation>
<translation id="1993104285338243655">ಪ್ರತಿಬಿಂಬಿಸುವಿಕೆಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ</translation>
<translation id="2060505056492490888">'<ph name="DOT" />' ಅನ್ನು '<ph name="INVALIDDOMAIN" />' ನಲ್ಲಿ ತಪ್ಪಾದ ಸ್ಥಾನದಲ್ಲಿ ಬಳಸಲಾಗಿದೆ.</translation>
<translation id="2148716181193084225">ಇಂದು</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">ಸಲ್ಲಿಸು</translation>
<translation id="2657045182931379222">ಗ್ರಾಫಿಕ್ಸ್ ವಸ್ತು</translation>
<translation id="2674318244760992338">ಅಡಿಟಿಪ್ಪಣಿ</translation>
+<translation id="2706474812903655270">ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ ಮೋಡ್‌ನಲ್ಲಿ ಈ ವೀಡಿಯೊ ಪ್ಲೇ ಆಗುತ್ತಿದೆ</translation>
<translation id="2709516037105925701">ಸ್ವಯಂತುಂಬುವಿಕೆ</translation>
<translation id="2723001399770238859">ಆಡಿಯೋ</translation>
<translation id="2746543609216772311">ಮೌಲ್ಯವು <ph name="MINIMUM_DATE_OR_TIME" /> ಅಥವಾ ನಂತರದ್ದಾಗಿರಬೇಕು.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">ಮುಂದಿನ ತಿಂಗಳು ತೋರಿಸಿ</translation>
<translation id="512758898067543763">ಸಾಲಿನ ಶಿರೋನಾಮೆ</translation>
<translation id="5143125788380636750">ಹಿನ್ನುಡಿ</translation>
-<translation id="5153163864850940242">ಚಿತ್ರದಲ್ಲಿನ ಚಿತ್ರದಲ್ಲಿ ಈ ವೀಡಿಯೊ ಪ್ಲೇ ಆಗುತ್ತಿದೆ</translation>
<translation id="5164977714490026579">ಮೌಲ್ಯವು <ph name="MINIMUM" /> ಕ್ಕಿಂತಲೂ ಹೆಚ್ಚಾಗಿರಬೇಕು ಅಥವಾ ಸಮನಾಗಿರಬೇಕು.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">'<ph name="ATSIGN" />' ನಂತರದ ಭಾಗವನ್ನು ನಮೂದಿಸಿ. '<ph name="INVALIDADDRESS" />' ಅಪೂರ್ಣವಾಗಿದೆ.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">ಕೊಲೊಫೋನ್</translation>
<translation id="6934078000481955284">ಬ್ಲಾಕ್‌ಕೋಟ್</translation>
<translation id="6941933287844615239">ಮಾಧ್ಯಮ ಡೌನ್‌ಲೋಡ್</translation>
+<translation id="6981594929165378967">ಅಳವಡಿಕೆ</translation>
<translation id="6989848892321993519">ಈ ಪಠ್ಯವನ್ನು <ph name="MIN_CHARACTERS" /> ಅಥವಾ ಇದಕ್ಕಿಂತಲೂ ಹೆಚ್ಚಿನ ಅಕ್ಷರಗಳಿಗೆ ಉದ್ದಗೊಳಿಸಿ (ನೀವು ಪ್ರಸ್ತುತ 1 ಅಕ್ಷರಗಳನ್ನು ಬಳಸುತ್ತಿರುವಿರಿ).</translation>
<translation id="709897737746224366">ದಯವಿಟ್ಟು ವಿನಂತಿಸಿದ ಸ್ವರೂಪವನ್ನು ಹೊಂದಿಸಿ.</translation>
<translation id="7139483182332611405">ಮುನ್ನುಡಿ</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">ಉಳಿದಿರುವ ಸಮಯ</translation>
<translation id="7740016676195725605">ಮುಚ್ಚಲಾಗಿರುವ ಶೀರ್ಷಿಕೆಗಳ ಪ್ರದರ್ಶಿಸುವಿಕೆಯನ್ನು ನಿಲ್ಲಿಸಿ</translation>
<translation id="7740050170769002709">HTML ವಿಷಯ</translation>
+<translation id="7750228210027921155">ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ</translation>
<translation id="7789962463072032349">ವಿರಾಮ</translation>
<translation id="7802800022689234070">ತ್ರಿಕೋನ ಪ್ರಕಟಣೆ</translation>
<translation id="7888071071722539607">ಇಮೇಲ್ ವಿಳಾಸದಲ್ಲಿ ಒಂದು '<ph name="ATSIGN" />' ಅನ್ನು ಸೇರಿಸಿ. '<ph name="ATSIGN" />' ನಲ್ಲಿ '<ph name="INVALIDADDRESS" />' ಕಾಣೆಯಾಗಿದೆ.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">ಪರಿವಿಡಿ</translation>
<translation id="8613126697340063924">ರಿಮೋಟ್ ಪ್ಲೇಬ್ಯಾಕ್ ನಿಯಂತ್ರಿಸಿ</translation>
<translation id="862370744433916922">ಉಪಶೀರ್ಷಿಕೆ</translation>
-<translation id="8741316211671074806">ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ</translation>
<translation id="8750798805984357768">ದಯವಿಟ್ಟು ಈ ಕೆಳಗಿನ ಆಯ್ಕೆಗಳಲ್ಲಿ ಒಂದನ್ನು ಆರಿಸಿ.</translation>
<translation id="8785498733064193001">ಪ್ಲೇಬ್ಯಾಕ್ ಪ್ರಾರಂಭಿಸಿ</translation>
<translation id="8808573423886751634">ಅಧ್ಯಾಯ</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">ನ್ಯಾವಿಗೇಷನ್</translation>
<translation id="9050748414552849310">ಮುಚ್ಚಿರುವ ಶೀರ್ಷಿಕೆಗಳನ್ನು ತೋರಿಸಿ</translation>
<translation id="9062295712474918030">ಡಾಕ್ಯುಮೆಂಟ್</translation>
+<translation id="9093215626363556771">ಚಿತ್ರದಲ್ಲಿನ ಚಿತ್ರದಿಂದ ನಿರ್ಗಮಿಸಿ</translation>
<translation id="9108370397979208512">ಮ್ಯಾಥ್</translation>
<translation id="9132465097189459683">ಇತರೆ...</translation>
<translation id="9138385573473225930">ಎಚ್ಚರಿಕೆ</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, <ph name="WEEK_START_DATE" /> ರಂದು ಪ್ರಾರಂಭವಾಗುತ್ತದೆ</translation>
+<translation id="916607977885256133">ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರ</translation>
<translation id="9168329111483466115">ಅಡಿಟಿಪ್ಪಣಿ</translation>
-<translation id="947831847158436616">ಸೆಲ್</translation>
+<translation id="954003015749068518">ಚಿತ್ರದಲ್ಲಿನ ಚಿತ್ರವನ್ನು ಪ್ರವೇಶಿಸಿ</translation>
<translation id="966787709310836684">ಮೆನು</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_ko.xtb b/chromium/content/app/strings/translations/content_strings_ko.xtb
index 0a7e051195e..b9f4f9eac1e 100644
--- a/chromium/content/app/strings/translations/content_strings_ko.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ko.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">슬라이더</translation>
<translation id="1211441953136645838">미주</translation>
<translation id="1281252709823657822">대화상자</translation>
+<translation id="1289247557029249093">PIP 모드 종료</translation>
<translation id="1335095011850992622">저작권 표시</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">배너</translation>
+<translation id="1548116112524424341">PIP 모드로 동영상 재생</translation>
<translation id="1589122976691792535">지역</translation>
<translation id="1591562245178063882">이번 달</translation>
<translation id="1637811476055996098">파일 선택</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">트리 격자</translation>
<translation id="1822429046913737220">오전/오후</translation>
<translation id="1832974991323546415">원격 기기에서 재생</translation>
+<translation id="190587075670221089">삭제</translation>
<translation id="1907737156431278478">예시</translation>
<translation id="1921819250265091946">일</translation>
<translation id="1930711995431081526">상태</translation>
<translation id="1938124657309484470">값은 <ph name="MAXIMUM_DATE_OR_TIME" /> 이전이어야 합니다.</translation>
+<translation id="1946271899482435442">날짜 선택도구 표시</translation>
<translation id="1993104285338243655">미러링으로 전환됨</translation>
<translation id="2060505056492490888">'<ph name="INVALIDDOMAIN" />'에서 '<ph name="DOT" />'의 위치가 잘못되었습니다.</translation>
<translation id="2148716181193084225">오늘</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">제출</translation>
<translation id="2657045182931379222">그래픽 객체</translation>
<translation id="2674318244760992338">바닥글</translation>
+<translation id="2706474812903655270">이 동영상은 PIP 모드에서 재생 중입니다.</translation>
<translation id="2709516037105925701">자동 완성</translation>
<translation id="2723001399770238859">오디오</translation>
<translation id="2746543609216772311">값은 <ph name="MINIMUM_DATE_OR_TIME" /> 이후여야 합니다.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">다음 달 표시</translation>
<translation id="512758898067543763">행 헤더</translation>
<translation id="5143125788380636750">에필로그</translation>
-<translation id="5153163864850940242">이 동영상은 PIP 모드에서 재생 중입니다.</translation>
<translation id="5164977714490026579">값은 <ph name="MINIMUM" /> 이상이어야 합니다.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" />PB</translation>
<translation id="5307600278924710095">'<ph name="ATSIGN" />' 앞 부분을 입력해 주세요. '<ph name="INVALIDADDRESS" />'(이)가 완전하지 않습니다.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">출판사 이름</translation>
<translation id="6934078000481955284">인용구</translation>
<translation id="6941933287844615239">미디어 다운로드</translation>
+<translation id="6981594929165378967">삽입</translation>
<translation id="6989848892321993519">이 텍스트를 <ph name="MIN_CHARACTERS" />자 이상으로 늘리세요(현재 1자 사용 중).</translation>
<translation id="709897737746224366">요청한 형식과 일치시키세요.</translation>
<translation id="7139483182332611405">머리말</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">남은 시간</translation>
<translation id="7740016676195725605">캡션 표시 중지</translation>
<translation id="7740050170769002709">HTML 콘텐츠</translation>
+<translation id="7750228210027921155">PIP 모드</translation>
<translation id="7789962463072032349">일시중지</translation>
<translation id="7802800022689234070">펼치기/접기 삼각형</translation>
<translation id="7888071071722539607">이메일 주소에 '<ph name="ATSIGN" />'를 포함해 주세요. '<ph name="INVALIDADDRESS" />'에 '<ph name="ATSIGN" />'가 없습니다.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">목차</translation>
<translation id="8613126697340063924">원격 재생 제어</translation>
<translation id="862370744433916922">부제</translation>
-<translation id="8741316211671074806">PIP 모드</translation>
<translation id="8750798805984357768">다음 옵션 중 하나를 선택하세요.</translation>
<translation id="8785498733064193001">재생 시작</translation>
<translation id="8808573423886751634">장</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">탐색</translation>
<translation id="9050748414552849310">캡션 표시</translation>
<translation id="9062295712474918030">문서</translation>
+<translation id="9093215626363556771">PIP 모드 종료</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">다른 달...</translation>
<translation id="9138385573473225930">알림</translation>
<translation id="9155987714137265666"><ph name="WEEK" />(<ph name="WEEK_START_DATE" />에 시작)</translation>
+<translation id="916607977885256133">PIP 모드</translation>
<translation id="9168329111483466115">각주</translation>
-<translation id="947831847158436616">셀</translation>
+<translation id="954003015749068518">PIP 모드 시작</translation>
<translation id="966787709310836684">메뉴</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_lt.xtb b/chromium/content/app/strings/translations/content_strings_lt.xtb
index 7ce8525f36b..d3c644686ea 100644
--- a/chromium/content/app/strings/translations/content_strings_lt.xtb
+++ b/chromium/content/app/strings/translations/content_strings_lt.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">šliaužiklis</translation>
<translation id="1211441953136645838">išnaša</translation>
<translation id="1281252709823657822">dialogo langas</translation>
+<translation id="1289247557029249093">Išeiti iš vaizdo vaizde režimo</translation>
<translation id="1335095011850992622">titrai</translation>
<translation id="1342835525016946179">artikelis</translation>
<translation id="1359897965706325498">reklamjuostė</translation>
+<translation id="1548116112524424341">leisti vaizdo įrašą vaizdo vaizde režimu</translation>
<translation id="1589122976691792535">regionas</translation>
<translation id="1591562245178063882">Šis mėnuo</translation>
<translation id="1637811476055996098">Pasirinkti failus</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">medžio tinklelis</translation>
<translation id="1822429046913737220">iki pietų / po pietų</translation>
<translation id="1832974991323546415">leisti naudojant nuotolinį įrenginį</translation>
+<translation id="190587075670221089">trynimas</translation>
<translation id="1907737156431278478">pavyzdys</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">būsena</translation>
<translation id="1938124657309484470">Vertė turi būti <ph name="MAXIMUM_DATE_OR_TIME" /> ar ankstesnė data.</translation>
+<translation id="1946271899482435442">Rodyti datos rinkiklį</translation>
<translation id="1993104285338243655">Perjungta į ekrano vaizdo bendrinimą</translation>
<translation id="2060505056492490888">„<ph name="DOT" />“ naudojamas netinkamoje „<ph name="INVALIDDOMAIN" />“ vietoje.</translation>
<translation id="2148716181193084225">Šiandien</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Pateikti</translation>
<translation id="2657045182931379222">grafikos objektas</translation>
<translation id="2674318244760992338">poraštė</translation>
+<translation id="2706474812903655270">Šis vaizdo įrašas leidžiamas vaizdo vaizde režimu</translation>
<translation id="2709516037105925701">Automatinis pildymas</translation>
<translation id="2723001399770238859">garso įrašas</translation>
<translation id="2746543609216772311">Vertė turi būti <ph name="MINIMUM_DATE_OR_TIME" /> ar vėlesnė data.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Rodyti kitą mėnesį</translation>
<translation id="512758898067543763">eilutės antraštė</translation>
<translation id="5143125788380636750">epilogas</translation>
-<translation id="5153163864850940242">Šis vaizdo įrašas leidžiamas kaip vaizdas vaizde</translation>
<translation id="5164977714490026579">Vertė turi būti <ph name="MINIMUM" /> arba didesnė.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Įveskite el. pašto adreso dalį iki „<ph name="ATSIGN" />“. „<ph name="INVALIDADDRESS" />“ nėra visas el. pašto adresas.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">informacija apie leidimą</translation>
<translation id="6934078000481955284">citata</translation>
<translation id="6941933287844615239">atsisiųsti mediją</translation>
+<translation id="6981594929165378967">įterpimas</translation>
<translation id="6989848892321993519">Pailginkite šį tekstą iki <ph name="MIN_CHARACTERS" /> simb. ar daugiau (šiuo metu naudojate 1 simbolį).</translation>
<translation id="709897737746224366">Priderinkite reikalaujamą formatą.</translation>
<translation id="7139483182332611405">įvadas</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">likęs laikas</translation>
<translation id="7740016676195725605">nebepateikti subtitrų</translation>
<translation id="7740050170769002709">HTML turinys</translation>
+<translation id="7750228210027921155">Vaizdas vaizde</translation>
<translation id="7789962463072032349">pristabdyti</translation>
<translation id="7802800022689234070">paskelbimo trikampis</translation>
<translation id="7888071071722539607">Į el. pašto adresą įtraukite „<ph name="ATSIGN" />“. „<ph name="INVALIDADDRESS" />“ trūksta „<ph name="ATSIGN" />“.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">turinys</translation>
<translation id="8613126697340063924">valdyti nuotolinį atkūrimą</translation>
<translation id="862370744433916922">paantraštė</translation>
-<translation id="8741316211671074806">Vaizdas vaizde</translation>
<translation id="8750798805984357768">Pasirinkite vieną iš šių parinkčių.</translation>
<translation id="8785498733064193001">pradėti atkūrimą</translation>
<translation id="8808573423886751634">skyrius</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">naršymas</translation>
<translation id="9050748414552849310">rodyti subtitrus</translation>
<translation id="9062295712474918030">dokumentas</translation>
+<translation id="9093215626363556771">išeiti iš vaizdo vaizde</translation>
<translation id="9108370397979208512">matematika</translation>
<translation id="9132465097189459683">Kita...</translation>
<translation id="9138385573473225930">įspėjimas</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, nuo <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Vaizdas vaizde</translation>
<translation id="9168329111483466115">išnaša</translation>
-<translation id="947831847158436616">langelis</translation>
+<translation id="954003015749068518">įeiti į vaizdą vaizde</translation>
<translation id="966787709310836684">meniu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_lv.xtb b/chromium/content/app/strings/translations/content_strings_lv.xtb
index 2b2273786b5..cadacb3f77e 100644
--- a/chromium/content/app/strings/translations/content_strings_lv.xtb
+++ b/chromium/content/app/strings/translations/content_strings_lv.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">slīdnis</translation>
<translation id="1211441953136645838">beigu vēre</translation>
<translation id="1281252709823657822">dialoglodziņš</translation>
+<translation id="1289247557029249093">Iziet no režīma “Attēls attēlā”</translation>
<translation id="1335095011850992622">pateicības</translation>
<translation id="1342835525016946179">raksts</translation>
<translation id="1359897965706325498">reklāmkarogs</translation>
+<translation id="1548116112524424341">atskaņot videoklipu režīmā “attēls attēlā”</translation>
<translation id="1589122976691792535">reģions</translation>
<translation id="1591562245178063882">Šis mēnesis</translation>
<translation id="1637811476055996098">Izvēlēties failus</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">koka režģis</translation>
<translation id="1822429046913737220">priekšpusdienā/pēcpusdienā</translation>
<translation id="1832974991323546415">atskaņot attālinātā ierīcē</translation>
+<translation id="190587075670221089">dzēšana</translation>
<translation id="1907737156431278478">piemērs</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">statuss</translation>
<translation id="1938124657309484470">Vērtībai ir jābūt “<ph name="MAXIMUM_DATE_OR_TIME" />” vai agrākam datumam vai laikam.</translation>
+<translation id="1946271899482435442">Rādīt datumu atlasītāju</translation>
<translation id="1993104285338243655">Mainīts uz spoguļošanu</translation>
<translation id="2060505056492490888">Punkts (<ph name="DOT" />) atrodas nepareizā vietā (<ph name="INVALIDDOMAIN" />).</translation>
<translation id="2148716181193084225">Šodien</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Iesniegt</translation>
<translation id="2657045182931379222">grafiskais objekts</translation>
<translation id="2674318244760992338">kājene</translation>
+<translation id="2706474812903655270">Videoklips tiek atskaņots režīmā “Attēls attēlā”</translation>
<translation id="2709516037105925701">Automātiskā aizpilde</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">Vērtībai ir jābūt “<ph name="MINIMUM_DATE_OR_TIME" />” vai vēlākam datumam vai laikam.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Rādīt nākamo mēnesi</translation>
<translation id="512758898067543763">rindas virsraksts</translation>
<translation id="5143125788380636750">epilogs</translation>
-<translation id="5153163864850940242">Videoklips tiek atskaņots režīmā Attēls attēlā</translation>
<translation id="5164977714490026579">Vērtībai ir jābūt lielākai vai vienādai ar <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Lūdzu, ievadiet daļu, kas atrodas pirms zīmes <ph name="ATSIGN" />. “<ph name="INVALIDADDRESS" />” ir nepilna adrese.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">izdošanas ziņas</translation>
<translation id="6934078000481955284">citāta bloks</translation>
<translation id="6941933287844615239">lejupielādēt multivides failus</translation>
+<translation id="6981594929165378967">ievietošana</translation>
<translation id="6989848892321993519">Lūdzu, papildiniet šo tekstu līdz vismaz <ph name="MIN_CHARACTERS" /> rakstzīmēm (pašlaik tas ietver 1 rakstzīmi).</translation>
<translation id="709897737746224366">Pieskaņojiet vērtību prasītajam formātam.</translation>
<translation id="7139483182332611405">ievadraksts</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">atlikušais laiks</translation>
<translation id="7740016676195725605">apturēt slēgto parakstu rādīšanu</translation>
<translation id="7740050170769002709">HTML saturs</translation>
+<translation id="7750228210027921155">Attēls attēlā</translation>
<translation id="7789962463072032349">pauzēt</translation>
<translation id="7802800022689234070">satura atklāšanas trijstūris</translation>
<translation id="7888071071722539607">E-pasta adresē ietveriet zīmi <ph name="ATSIGN" />. Adresē “<ph name="INVALIDADDRESS" />” trūkst zīmes <ph name="ATSIGN" />.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">satura rādītājs</translation>
<translation id="8613126697340063924">kontrolēt attālināto atskaņošanu</translation>
<translation id="862370744433916922">apakšvirsraksts</translation>
-<translation id="8741316211671074806">Attēls attēlā</translation>
<translation id="8750798805984357768">Lūdzu, atlasiet vienu no šīm opcijām.</translation>
<translation id="8785498733064193001">sākt atskaņošanu</translation>
<translation id="8808573423886751634">nodaļa</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigācija</translation>
<translation id="9050748414552849310">rādīt slēgtos parakstus</translation>
<translation id="9062295712474918030">dokuments</translation>
+<translation id="9093215626363556771">aizvērt režīmu “attēls attēlā”</translation>
<translation id="9108370397979208512">matemātiska izteiksme</translation>
<translation id="9132465097189459683">Cits...</translation>
<translation id="9138385573473225930">brīdinājums</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, sākot no: <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Attēls attēlā</translation>
<translation id="9168329111483466115">vēre</translation>
-<translation id="947831847158436616">šūna</translation>
+<translation id="954003015749068518">atvērt režīmu “attēls attēlā”</translation>
<translation id="966787709310836684">izvēlne</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_ml.xtb b/chromium/content/app/strings/translations/content_strings_ml.xtb
index 5b07795a2db..dc74067e2bf 100644
--- a/chromium/content/app/strings/translations/content_strings_ml.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ml.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">സ്ലൈഡർ</translation>
<translation id="1211441953136645838">അന്തിമ കുറിപ്പ്</translation>
<translation id="1281252709823657822">ഡയലോഗ്</translation>
+<translation id="1289247557029249093">ചിത്രത്തിനുള്ളിലെ ചിത്രം മോഡിന് പുറത്ത് കടക്കുക</translation>
<translation id="1335095011850992622">ക്രെഡിറ്റുകൾ</translation>
<translation id="1342835525016946179">ലേഖനം</translation>
<translation id="1359897965706325498">ബാനർ</translation>
+<translation id="1548116112524424341">ചിത്രത്തിനുള്ളിലെ ചിത്രം മോഡിൽ വീഡിയോ പ്ലേ ചെയ്യുക</translation>
<translation id="1589122976691792535">പ്രദേശം</translation>
<translation id="1591562245178063882">ഈ മാസം</translation>
<translation id="1637811476055996098">ഫയലുകൾ തിരഞ്ഞെടുക്കുക</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">ട്രീ ഗ്രിഡ്</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">വിദൂര ഉപകരണത്തിൽ പ്ലേ ചെയ്യുക</translation>
+<translation id="190587075670221089">ഇല്ലാതാക്കൽ</translation>
<translation id="1907737156431278478">ഉദാഹരണം</translation>
<translation id="1921819250265091946">തീയതി</translation>
<translation id="1930711995431081526">നില</translation>
<translation id="1938124657309484470">മൂല്യം <ph name="MAXIMUM_DATE_OR_TIME" /> എന്നതോ അതിനുമുമ്പുള്ള തീയതിയോ ആയിരിക്കണം.</translation>
+<translation id="1946271899482435442">തീയതി തിരഞ്ഞെടുക്കൽ കാണിക്കുക</translation>
<translation id="1993104285338243655">മിററിംഗിലേക്ക് മാറി</translation>
<translation id="2060505056492490888">'<ph name="DOT" />', '<ph name="INVALIDDOMAIN" />' എന്നതിൽ തെറ്റായ സ്ഥാനത്താണ് ഉപയോഗിച്ചിരിക്കുന്നത്.</translation>
<translation id="2148716181193084225">ഇന്ന്</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">സമര്‍പ്പിക്കൂ</translation>
<translation id="2657045182931379222">ഗ്രാഫിക്‌സ് ഒബ്‌ജക്‌റ്റ്</translation>
<translation id="2674318244760992338">അടിക്കുറിപ്പ്</translation>
+<translation id="2706474812903655270">ചിത്രത്തിനുള്ളിലെ ചിത്രം മോഡിലാണ് ഈ വീഡിയോ പ്ലേ ചെയ്യുന്നത്</translation>
<translation id="2709516037105925701">ഓട്ടോഫില്‍</translation>
<translation id="2723001399770238859">ഓഡിയോ</translation>
<translation id="2746543609216772311">മൂല്യം <ph name="MINIMUM_DATE_OR_TIME" /> എന്നതോ അതിനുശേഷമുള്ള തീയതിയോ ആയിരിക്കണം.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">അടുത്ത മാസം കാണിക്കുക</translation>
<translation id="512758898067543763">വരി ശീർഷകം</translation>
<translation id="5143125788380636750">ഉപസംഹാരം</translation>
-<translation id="5153163864850940242">'ചിത്രത്തിനുള്ളിലെ ചിത്രം' മോഡിലാണ് ഈ വീഡിയോ പ്ലേ ചേയ്യുന്നത്</translation>
<translation id="5164977714490026579">മൂല്യം <ph name="MINIMUM" /> എന്നതില്‍ കൂടുതലോ സമമോ ആയിരിക്കണം.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">'<ph name="ATSIGN" />' എന്നതിനുശേഷം ഒരു ഭാഗം നൽകുക.'<ph name="INVALIDADDRESS" />' അപൂർണ്ണമാണ്.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">അച്ചടിമുദ്ര</translation>
<translation id="6934078000481955284">ബ്ലോക്ക്‌കോട്ട്</translation>
<translation id="6941933287844615239">മീഡിയ ഡൗൺലോഡുചെയ്യുക</translation>
+<translation id="6981594929165378967">ചേർക്കൽ</translation>
<translation id="6989848892321993519">ഈ ടെക്‌സ്റ്റിന്റെ ദൈർഘ്യം <ph name="MIN_CHARACTERS" /> പ്രതീകങ്ങളോ അതിൽ കൂടുതലോ ആയി വർദ്ധിപ്പിക്കുക (നിങ്ങൾ നിലവിൽ ഒരു പ്രതീകം മാത്രമേ ഉപയോഗിക്കുന്നുള്ളൂ).</translation>
<translation id="709897737746224366">അഭ്യര്‍ത്ഥി ച്ചഫോര്‍മാറ്റ് ദയവായി പൊരുത്തപ്പെടുത്തുക.</translation>
<translation id="7139483182332611405">പീഠിക</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">അവശേഷിക്കുന്ന സമയം</translation>
<translation id="7740016676195725605">അടച്ച അടിക്കുറിപ്പുകൾ പ്രദർശിപ്പിക്കുന്നത് നിർത്തുക</translation>
<translation id="7740050170769002709">HTML ഉള്ളടക്കം</translation>
+<translation id="7750228210027921155">ചിത്രത്തിനുള്ളിലെ ചിത്രം</translation>
<translation id="7789962463072032349">താല്‍‌ക്കാലികമായി നിര്‍‌ത്തുക</translation>
<translation id="7802800022689234070">ഡിസ്‌ക്ലോഷർ ത്രികോണം</translation>
<translation id="7888071071722539607">ഇമെയിൽ വിലാസത്തിൽ '<ph name="ATSIGN" />' ഉൾപ്പെടുത്തുക. '<ph name="INVALIDADDRESS" />' എന്നതിൽ ഒരു '<ph name="ATSIGN" />' കാണുന്നില്ല.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">ഉള്ളടക്ക പട്ടിക</translation>
<translation id="8613126697340063924">വിദൂര പ്ലേബാക്ക് നിയന്ത്രിക്കുക</translation>
<translation id="862370744433916922">ഉപശീർഷകം</translation>
-<translation id="8741316211671074806">ചിത്രത്തിനുള്ളിലെ ചിത്രം</translation>
<translation id="8750798805984357768">ഈ ഓപ്ഷനുകളിലൊന്ന് ദയവായി തിരഞ്ഞെടുക്കുക.</translation>
<translation id="8785498733064193001">പ്ലേബാക്ക് ആരംഭിക്കുക</translation>
<translation id="8808573423886751634">അധ്യായം</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">നാവിഗേഷൻ</translation>
<translation id="9050748414552849310">അടച്ച അടിക്കുറിപ്പുകൾ കാണിക്കുക</translation>
<translation id="9062295712474918030">പ്രമാണം</translation>
+<translation id="9093215626363556771">ചിത്രത്തിനുള്ളിലെ ചിത്രത്തിന് പുറത്ത് കടക്കുക</translation>
<translation id="9108370397979208512">മാത്ത്</translation>
<translation id="9132465097189459683">മറ്റുള്ളവ...</translation>
<translation id="9138385573473225930">അലേർട്ട്</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, <ph name="WEEK_START_DATE" />-ന് ആരംഭിക്കുന്നു</translation>
+<translation id="916607977885256133">ചിത്രത്തിനുള്ളിൽ ചിത്രം</translation>
<translation id="9168329111483466115">അടിക്കുറിപ്പ്</translation>
-<translation id="947831847158436616">സെൽ</translation>
+<translation id="954003015749068518">ചിത്രത്തിനുള്ളിലെ ചിത്രത്തിലേക്ക് പ്രവേശിക്കുക</translation>
<translation id="966787709310836684">മെനു</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_mr.xtb b/chromium/content/app/strings/translations/content_strings_mr.xtb
index 1f29d299817..9ad80557a3a 100644
--- a/chromium/content/app/strings/translations/content_strings_mr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_mr.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">स्लायडर</translation>
<translation id="1211441953136645838">तळटीप</translation>
<translation id="1281252709823657822">संवाद</translation>
+<translation id="1289247557029249093">चित्रात-चित्र मोडमधून बाहेर पडा</translation>
<translation id="1335095011850992622">श्रेय</translation>
<translation id="1342835525016946179">लेख</translation>
<translation id="1359897965706325498">बॅनर</translation>
+<translation id="1548116112524424341">व्हिडिओ चित्रात-चित्र मोडमध्ये प्ले करा</translation>
<translation id="1589122976691792535">प्रदेश</translation>
<translation id="1591562245178063882">या महिन्यात</translation>
<translation id="1637811476055996098">फायली निवडा</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">ट्री ग्रीड</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">दूरस्थ डिव्हाइसवर प्ले करा</translation>
+<translation id="190587075670221089">हटवणे</translation>
<translation id="1907737156431278478">उदाहरण</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">स्थिती</translation>
<translation id="1938124657309484470">मूल्य <ph name="MAXIMUM_DATE_OR_TIME" /> किंवा आधीचे असणे आवश्यक आहे.</translation>
+<translation id="1946271899482435442">तारीख निवडक दाखवा</translation>
<translation id="1993104285338243655">मिररिंगवर स्विच केले</translation>
<translation id="2060505056492490888">'<ph name="DOT" />' '<ph name="INVALIDDOMAIN" />' मध्ये चुकीच्या स्थितीवर वापरले आहे.</translation>
<translation id="2148716181193084225">आज</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">सबमिट करा</translation>
<translation id="2657045182931379222">ग्राफिक्स ऑब्जेक्ट</translation>
<translation id="2674318244760992338">अधोलेख</translation>
+<translation id="2706474812903655270">हा व्हिडिओ चित्रात-चित्र मोडमध्ये प्ले होत आहे</translation>
<translation id="2709516037105925701">ऑटोफिल</translation>
<translation id="2723001399770238859">ऑडिओ</translation>
<translation id="2746543609216772311">मूल्य <ph name="MINIMUM_DATE_OR_TIME" /> किंवा नंतरचे असणे आवश्यक आहे.</translation>
@@ -76,7 +81,7 @@
<translation id="3808586225841795776">संज्ञा</translation>
<translation id="3822383571486410024">कृपया हा मजकूर <ph name="MIN_CHARACTERS" /> वर्ण किंवा त्यापेक्षा अधिक मोठा करा (आपण सध्‍या <ph name="CURRENT_LENGTH" /> वर्ण वापरत आहात).</translation>
<translation id="383465348367842624">'<ph name="ATSIGN" />' मागुन येणार्‍या भागामध्ये '<ph name="INVALIDCHARACTER" />' चिन्ह नसावे.</translation>
-<translation id="3846214748874656680">पूर्णस्क्रीनमधून बाहेर पडा</translation>
+<translation id="3846214748874656680">क्षेत्रेमधून बाहेर पडा</translation>
<translation id="3920932319529768807">निष्कर्ष</translation>
<translation id="3924558731517983934">अॅप्लिकेशन</translation>
<translation id="3944740393230681990">उपोद्घात</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">पुढील महिना दर्शवा</translation>
<translation id="512758898067543763">पंक्ती शीर्षलेख</translation>
<translation id="5143125788380636750">उपसंहार</translation>
-<translation id="5153163864850940242">हा व्हिडिओ पिक्चर-इन-पिक्चर मध्ये सुरू आहे</translation>
<translation id="5164977714490026579">मूल्य <ph name="MINIMUM" /> पेक्षा मोठे किंवा समान असावे.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">कृपया '<ph name="ATSIGN" />' मागुन येणारा भाग एंटर करा. '<ph name="INVALIDADDRESS" />' अपूर्ण आहे.</translation>
@@ -131,7 +135,7 @@
<translation id="576709008726043716">परिचय</translation>
<translation id="57838592816432529">निःशब्द करा</translation>
<translation id="5860033963881614850">बंद</translation>
-<translation id="588258955323874662">पूर्णस्क्रीन</translation>
+<translation id="588258955323874662">क्षेत्रे</translation>
<translation id="5888666972993069672">आता <ph name="DEVICE_FRIENDLY_NAME" /> वर कास्ट करत आहे</translation>
<translation id="5939518447894949180">रीसेट करा</translation>
<translation id="5966707198760109579">आठवडा</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">बोधचिन्ह</translation>
<translation id="6934078000481955284">ब्लॉककोट</translation>
<translation id="6941933287844615239">मीडिया डाउनलोड करा</translation>
+<translation id="6981594929165378967">घालणे</translation>
<translation id="6989848892321993519">कृपया हा मजकूर <ph name="MIN_CHARACTERS" /> वर्ण किंवा त्यापेक्षा अधिक मोठा करा (आपण सध्‍या 1 वर्ण वापरत आहात).</translation>
<translation id="709897737746224366">कृपया विनंती केलेले स्वरूपन जुळवा.</translation>
<translation id="7139483182332611405">प्रस्तावना</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">शिल्लक वेळ</translation>
<translation id="7740016676195725605">बंद मथळा प्रदर्शित करणे थांबवा</translation>
<translation id="7740050170769002709">HTML सामुग्री</translation>
+<translation id="7750228210027921155">चित्रात-चित्र</translation>
<translation id="7789962463072032349">विराम द्या</translation>
<translation id="7802800022689234070">त्रिकोण प्रकटन</translation>
<translation id="7888071071722539607">कृपया ईमेल पत्त्यामध्ये '<ph name="ATSIGN" />' समाविष्ट करा. '<ph name="INVALIDADDRESS" />' '<ph name="ATSIGN" />' गमावत आहे.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">अनुक्रमणिका</translation>
<translation id="8613126697340063924">दूरस्थ प्लेबॅक नियंत्रित करा</translation>
<translation id="862370744433916922">उपशीर्षक</translation>
-<translation id="8741316211671074806">चित्रात-चित्र</translation>
<translation id="8750798805984357768">कृपया या पर्यायांपैकी एक निवडा.</translation>
<translation id="8785498733064193001">प्लेबॅक आरंभ करा</translation>
<translation id="8808573423886751634">प्रकरण</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">नेव्हिगेशन</translation>
<translation id="9050748414552849310">बंद मथळा दर्शवा</translation>
<translation id="9062295712474918030">दस्तऐवज</translation>
+<translation id="9093215626363556771">चित्रात-चित्र मधून बाहेर पडा</translation>
<translation id="9108370397979208512">गणित</translation>
<translation id="9132465097189459683">अन्य...</translation>
<translation id="9138385573473225930">सूचना</translation>
<translation id="9155987714137265666"><ph name="WEEK_START_DATE" /> रोजी प्रारंभ होणारा, <ph name="WEEK" /></translation>
+<translation id="916607977885256133">चित्रात-चित्र</translation>
<translation id="9168329111483466115">तळटीप</translation>
-<translation id="947831847158436616">सेल</translation>
+<translation id="954003015749068518">चित्रात-चित्र एंटर करा</translation>
<translation id="966787709310836684">मेनू</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_ms.xtb b/chromium/content/app/strings/translations/content_strings_ms.xtb
index 2cad6383b2e..4a46a11a1fc 100644
--- a/chromium/content/app/strings/translations/content_strings_ms.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ms.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">peluncur</translation>
<translation id="1211441953136645838">nota hujung</translation>
<translation id="1281252709823657822">dialog</translation>
+<translation id="1289247557029249093">Keluar daripada mod gambar dalam gambar</translation>
<translation id="1335095011850992622">kredit</translation>
<translation id="1342835525016946179">artikel</translation>
<translation id="1359897965706325498">sepanduk</translation>
+<translation id="1548116112524424341">mainkan video dalam mod gambar dalam gambar</translation>
<translation id="1589122976691792535">wilayah</translation>
<translation id="1591562245178063882">Bulan ini</translation>
<translation id="1637811476055996098">Pilih Fail</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">grid pohon</translation>
<translation id="1822429046913737220">PG / P/M</translation>
<translation id="1832974991323546415">main pada peranti jauh</translation>
+<translation id="190587075670221089">pemadaman</translation>
<translation id="1907737156431278478">contoh</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">status</translation>
<translation id="1938124657309484470">Nilai mestilah <ph name="MAXIMUM_DATE_OR_TIME" /> atau lebih awal.</translation>
+<translation id="1946271899482435442">Tunjukkan pemilih tarikh</translation>
<translation id="1993104285338243655">Beralih kepada pencerminan</translation>
<translation id="2060505056492490888">'<ph name="DOT" />' digunakan pada kedudukan yang salah dalam '<ph name="INVALIDDOMAIN" />'.</translation>
<translation id="2148716181193084225">Hari ini</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Serah</translation>
<translation id="2657045182931379222">objek grafik</translation>
<translation id="2674318244760992338">pembawah</translation>
+<translation id="2706474812903655270">Video ini dimainkan dalam mod gambar dalam gambar</translation>
<translation id="2709516037105925701">Autoisi</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">Nilai mestilah <ph name="MINIMUM_DATE_OR_TIME" /> atau kemudian.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Tunjukkan bulan seterusnya</translation>
<translation id="512758898067543763">pengepala baris</translation>
<translation id="5143125788380636750">epilog</translation>
-<translation id="5153163864850940242">Video ini dimainkan dalam Gambar dalam Gambar</translation>
<translation id="5164977714490026579">Nilai mesti lebih besar daripada atau sama dengan <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Sila masukkan bahagian diikuti oleh '<ph name="ATSIGN" />'. '<ph name="INVALIDADDRESS" />' tidak lengkap.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofon</translation>
<translation id="6934078000481955284">petikan blok</translation>
<translation id="6941933287844615239">muat turun media</translation>
+<translation id="6981594929165378967">penyisipan</translation>
<translation id="6989848892321993519">Sila panjangkan teks ini kepada <ph name="MIN_CHARACTERS" /> aksara atau lebih (anda sedang menggunakan 1 aksara).</translation>
<translation id="709897737746224366">Sila padankan dengan format yang diminta.</translation>
<translation id="7139483182332611405">kata penghantar</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">masa yang tinggal</translation>
<translation id="7740016676195725605">berhenti memaparkan kapsyen tertutup</translation>
<translation id="7740050170769002709">Kandungan HTML</translation>
+<translation id="7750228210027921155">Gambar dalam gambar</translation>
<translation id="7789962463072032349">jeda</translation>
<translation id="7802800022689234070">segi tiga pendedahan</translation>
<translation id="7888071071722539607">Sila masukkan '<ph name="ATSIGN" />' dalam alamat e-mel. '<ph name="INVALIDADDRESS" />' tiada '<ph name="ATSIGN" />'.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">isi kandungan</translation>
<translation id="8613126697340063924">kawal main balik jauh</translation>
<translation id="862370744433916922">sari kata</translation>
-<translation id="8741316211671074806">Gambar dalam Gambar</translation>
<translation id="8750798805984357768">Sila pilih salah satu pilihan ini.</translation>
<translation id="8785498733064193001">mulakan main balik</translation>
<translation id="8808573423886751634">bab</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigasi</translation>
<translation id="9050748414552849310">paparkan kapsyen tertutup</translation>
<translation id="9062295712474918030">dokumen</translation>
+<translation id="9093215626363556771">keluar daripada gambar dalam gambar</translation>
<translation id="9108370397979208512">matematik</translation>
<translation id="9132465097189459683">Lain-lain...</translation>
<translation id="9138385573473225930">makluman</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, bermula pada <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Gambar dalam Gambar</translation>
<translation id="9168329111483466115">nota kaki</translation>
-<translation id="947831847158436616">sel</translation>
+<translation id="954003015749068518">masuk ke gambar dalam gambar</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_nl.xtb b/chromium/content/app/strings/translations/content_strings_nl.xtb
index 96d17a835dc..8d1cea60130 100644
--- a/chromium/content/app/strings/translations/content_strings_nl.xtb
+++ b/chromium/content/app/strings/translations/content_strings_nl.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">schuifregelaar</translation>
<translation id="1211441953136645838">eindnoot</translation>
<translation id="1281252709823657822">dialoogvenster</translation>
+<translation id="1289247557029249093">Scherm-in-scherm-modus afsluiten</translation>
<translation id="1335095011850992622">bronvermelding</translation>
<translation id="1342835525016946179">artikel</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">Video in de scherm-in-scherm-modus afspelen</translation>
<translation id="1589122976691792535">regio</translation>
<translation id="1591562245178063882">Deze maand</translation>
<translation id="1637811476055996098">Bestanden kiezen</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">boomstructuur</translation>
<translation id="1822429046913737220">a.m./p.m.</translation>
<translation id="1832974991323546415">afspelen op extern apparaat</translation>
+<translation id="190587075670221089">verwijdering</translation>
<translation id="1907737156431278478">voorbeeld</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">status</translation>
<translation id="1938124657309484470">Waarde moet <ph name="MAXIMUM_DATE_OR_TIME" /> of eerder zijn.</translation>
+<translation id="1946271899482435442">Datumkiezer weergeven</translation>
<translation id="1993104285338243655">Overgeschakeld naar mirroring</translation>
<translation id="2060505056492490888">'<ph name="DOT" />' wordt op een verkeerde positie gebruikt in '<ph name="INVALIDDOMAIN" />'.</translation>
<translation id="2148716181193084225">Vandaag</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Verzenden</translation>
<translation id="2657045182931379222">grafisch object</translation>
<translation id="2674318244760992338">voettekst</translation>
+<translation id="2706474812903655270">Deze video wordt in de scherm-in-scherm-modus afgespeeld</translation>
<translation id="2709516037105925701">Automatisch aanvullen</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">Waarde moet <ph name="MINIMUM_DATE_OR_TIME" /> of later zijn.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Volgende maand weergeven</translation>
<translation id="512758898067543763">rijkop</translation>
<translation id="5143125788380636750">epiloog</translation>
-<translation id="5153163864850940242">Deze video wordt in de scherm-in-scherm-modus afgespeeld</translation>
<translation id="5164977714490026579">Waarde moet groter dan of gelijk zijn aan <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Geef een naamgedeelte op, gevolgd door '<ph name="ATSIGN" />'. '<ph name="INVALIDADDRESS" />' is onvolledig.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">colofon</translation>
<translation id="6934078000481955284">blok met geciteerde tekst</translation>
<translation id="6941933287844615239">media downloaden</translation>
+<translation id="6981594929165378967">invoeging</translation>
<translation id="6989848892321993519">Breid deze tekst uit tot <ph name="MIN_CHARACTERS" /> tekens of meer (je gebruikt momenteel één teken).</translation>
<translation id="709897737746224366">Zorg dat de indeling voldoet aan de gevraagde indeling.</translation>
<translation id="7139483182332611405">voorwoord</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">resterende tijd</translation>
<translation id="7740016676195725605">het weergeven van ondertiteling stoppen</translation>
<translation id="7740050170769002709">HTML-content</translation>
+<translation id="7750228210027921155">Scherm-in-scherm</translation>
<translation id="7789962463072032349">onderbreken</translation>
<translation id="7802800022689234070">driehoek voor samen-/uitvouwen</translation>
<translation id="7888071071722539607">Gebruik een '<ph name="ATSIGN" />' in thet e-mailadres. In '<ph name="INVALIDADDRESS" />' ontbreekt een '<ph name="ATSIGN" />'.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">inhoudsopgave</translation>
<translation id="8613126697340063924">afspelen bedienen op afstand</translation>
<translation id="862370744433916922">ondertitel</translation>
-<translation id="8741316211671074806">Scherm-in-scherm</translation>
<translation id="8750798805984357768">Selecteer een van deze opties.</translation>
<translation id="8785498733064193001">afspelen starten</translation>
<translation id="8808573423886751634">hoofdstuk</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigatie</translation>
<translation id="9050748414552849310">ondertiteling weergeven</translation>
<translation id="9062295712474918030">document</translation>
+<translation id="9093215626363556771">scherm-in-scherm afsluiten</translation>
<translation id="9108370397979208512">wiskunde</translation>
<translation id="9132465097189459683">Anders...</translation>
<translation id="9138385573473225930">melding</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, die begint op <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Scherm-in-scherm</translation>
<translation id="9168329111483466115">voetnoot</translation>
-<translation id="947831847158436616">cel</translation>
+<translation id="954003015749068518">scherm-in-scherm openen</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_no.xtb b/chromium/content/app/strings/translations/content_strings_no.xtb
index b845d307239..2b165a6bb31 100644
--- a/chromium/content/app/strings/translations/content_strings_no.xtb
+++ b/chromium/content/app/strings/translations/content_strings_no.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">glidebryter</translation>
<translation id="1211441953136645838">sluttnote</translation>
<translation id="1281252709823657822">dialog</translation>
+<translation id="1289247557029249093">Avslutt bilde-i-bilde-modus</translation>
<translation id="1335095011850992622">anerkjennelser</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">spill av videoen i bilde-i-bilde-modus</translation>
<translation id="1589122976691792535">område</translation>
<translation id="1591562245178063882">Denne måneden</translation>
<translation id="1637811476055996098">Velg filer</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">trerutenett</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">spill på ekstern enhet</translation>
+<translation id="190587075670221089">sletting</translation>
<translation id="1907737156431278478">eksempel</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">status</translation>
<translation id="1938124657309484470">Verdien må være <ph name="MAXIMUM_DATE_OR_TIME" /> eller før.</translation>
+<translation id="1946271899482435442">Vis datovelgeren</translation>
<translation id="1993104285338243655">Byttet til speiling</translation>
<translation id="2060505056492490888">«<ph name="DOT" />» er brukt på feil sted i «<ph name="INVALIDDOMAIN" />».</translation>
<translation id="2148716181193084225">I dag</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Send</translation>
<translation id="2657045182931379222">grafikkobjekt</translation>
<translation id="2674318244760992338">fotnote</translation>
+<translation id="2706474812903655270">Denne videoen spilles av i bilde-i-bilde-modus</translation>
<translation id="2709516037105925701">Autofyll</translation>
<translation id="2723001399770238859">lyd</translation>
<translation id="2746543609216772311">Verdien må være <ph name="MINIMUM_DATE_OR_TIME" /> eller senere.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Se neste måned</translation>
<translation id="512758898067543763">radoverskrift</translation>
<translation id="5143125788380636750">epilog</translation>
-<translation id="5153163864850940242">Denne videoen spilles av i bilde-i-bilde</translation>
<translation id="5164977714490026579">Verdien må være større enn eller lik <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Skriv inn en del etterfulgt av «<ph name="ATSIGN" />». «<ph name="INVALIDADDRESS" />» er ufullstendig.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofon</translation>
<translation id="6934078000481955284">blokksitat</translation>
<translation id="6941933287844615239">last ned medier</translation>
+<translation id="6981594929165378967">innsetting</translation>
<translation id="6989848892321993519">Øk lengden på denne teksten med minst <ph name="MIN_CHARACTERS" /> tegn (du bruker for øyeblikket 1 tegn).</translation>
<translation id="709897737746224366">Sørg for samsvar med det forespurte formatet.</translation>
<translation id="7139483182332611405">forord</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">tid som gjenstår</translation>
<translation id="7740016676195725605">slå av tekstingen</translation>
<translation id="7740050170769002709">HTML-innhold</translation>
+<translation id="7750228210027921155">Bilde i bilde</translation>
<translation id="7789962463072032349">stans midlertidig</translation>
<translation id="7802800022689234070">trekant for ekstra innhold</translation>
<translation id="7888071071722539607">Inkluder en «<ph name="ATSIGN" />» i e-postadressen. «<ph name="INVALIDADDRESS" />» mangler en «<ph name="ATSIGN" />».</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">innholdsfortegnelse</translation>
<translation id="8613126697340063924">kontrollér ekstern avspilling</translation>
<translation id="862370744433916922">undertittel</translation>
-<translation id="8741316211671074806">Bilde-i-bilde</translation>
<translation id="8750798805984357768">Velg ett av følgende alternativer.</translation>
<translation id="8785498733064193001">start avspillingen</translation>
<translation id="8808573423886751634">kapittel</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigasjon</translation>
<translation id="9050748414552849310">vis teksting</translation>
<translation id="9062295712474918030">dokument</translation>
+<translation id="9093215626363556771">avslutt bilde-i-bilde</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">Andre</translation>
<translation id="9138385573473225930">varsel</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, med start <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Bilde i bilde</translation>
<translation id="9168329111483466115">fotnote</translation>
-<translation id="947831847158436616">celle</translation>
+<translation id="954003015749068518">start bilde-i-bilde</translation>
<translation id="966787709310836684">meny</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_pl.xtb b/chromium/content/app/strings/translations/content_strings_pl.xtb
index acac3373159..95213b71476 100644
--- a/chromium/content/app/strings/translations/content_strings_pl.xtb
+++ b/chromium/content/app/strings/translations/content_strings_pl.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">suwak</translation>
<translation id="1211441953136645838">przypis końcowy</translation>
<translation id="1281252709823657822">okno dialogowe</translation>
+<translation id="1289247557029249093">Wyłącz tryb obrazu w obrazie</translation>
<translation id="1335095011850992622">autorzy</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">baner</translation>
+<translation id="1548116112524424341">wyświetl film w trybie obrazu w obrazie</translation>
<translation id="1589122976691792535">region</translation>
<translation id="1591562245178063882">W tym miesiącu</translation>
<translation id="1637811476055996098">Wybierz pliki</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">siatka drzewa</translation>
<translation id="1822429046913737220">rano/po południu</translation>
<translation id="1832974991323546415">odtwarzanie na urządzeniu zdalnym</translation>
+<translation id="190587075670221089">usunięcie</translation>
<translation id="1907737156431278478">przykład</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">stan</translation>
<translation id="1938124657309484470">Musisz podać wartość <ph name="MAXIMUM_DATE_OR_TIME" /> lub wcześniejszą.</translation>
+<translation id="1946271899482435442">Pokaż selektor dat</translation>
<translation id="1993104285338243655">Przełączono na odbicie lustrzane</translation>
<translation id="2060505056492490888">„<ph name="DOT" />” występuje w niewłaściwym miejscu w „<ph name="INVALIDDOMAIN" />”.</translation>
<translation id="2148716181193084225">Dzisiaj</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Prześlij</translation>
<translation id="2657045182931379222">obiekt graficzny</translation>
<translation id="2674318244760992338">stopka</translation>
+<translation id="2706474812903655270">Ten film jest odtwarzany w trybie obrazu w obrazie</translation>
<translation id="2709516037105925701">Autouzupełnianie</translation>
<translation id="2723001399770238859">dźwięk</translation>
<translation id="2746543609216772311">Musisz podać wartość <ph name="MINIMUM_DATE_OR_TIME" /> lub późniejszą.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Pokaż przyszły miesiąc</translation>
<translation id="512758898067543763">nagłówek wiersza</translation>
<translation id="5143125788380636750">epilog</translation>
-<translation id="5153163864850940242">Ten film jest odtwarzany w trybie obrazu w obrazie</translation>
<translation id="5164977714490026579">Wartość nie może być mniejsza niż <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Podaj część przed znakiem „<ph name="ATSIGN" />”. Adres „<ph name="INVALIDADDRESS" />” jest niepełny.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofon</translation>
<translation id="6934078000481955284">cytat blokowy</translation>
<translation id="6941933287844615239">pobierz multimedia</translation>
+<translation id="6981594929165378967">wstawienie</translation>
<translation id="6989848892321993519">Wydłuż ten tekst co najmniej do <ph name="MIN_CHARACTERS" /> znaków (teraz używasz jednego znaku).</translation>
<translation id="709897737746224366">Podaj wartość w wymaganym formacie.</translation>
<translation id="7139483182332611405">wstęp</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">pozostały czas</translation>
<translation id="7740016676195725605">przestań pokazywać napisy</translation>
<translation id="7740050170769002709">Treść HTML</translation>
+<translation id="7750228210027921155">Obraz w obrazie</translation>
<translation id="7789962463072032349">wstrzymaj</translation>
<translation id="7802800022689234070">trójkąt rozwinięcia</translation>
<translation id="7888071071722539607">Uwzględnij znak „<ph name="ATSIGN" />” w adresie e-mail. W adresie „<ph name="INVALIDADDRESS" />” brakuje znaku „<ph name="ATSIGN" />”.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">spis treści</translation>
<translation id="8613126697340063924">sterowanie zdalnym odtwarzaniem</translation>
<translation id="862370744433916922">podtytuł</translation>
-<translation id="8741316211671074806">Obraz w obrazie</translation>
<translation id="8750798805984357768">Wybierz jedną z opcji.</translation>
<translation id="8785498733064193001">rozpocznij odtwarzanie</translation>
<translation id="8808573423886751634">rozdział</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">nawigacja</translation>
<translation id="9050748414552849310">pokaż napisy</translation>
<translation id="9062295712474918030">dokument</translation>
+<translation id="9093215626363556771">wyłącz tryb obrazu w obrazie</translation>
<translation id="9108370397979208512">matematyczny</translation>
<translation id="9132465097189459683">Inny...</translation>
<translation id="9138385573473225930">alert</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, początek <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Obraz w obrazie</translation>
<translation id="9168329111483466115">przypis</translation>
-<translation id="947831847158436616">komórka</translation>
+<translation id="954003015749068518">włącz tryb obrazu w obrazie</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
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 12943615149..1f50ea13a7d 100644
--- a/chromium/content/app/strings/translations/content_strings_pt-BR.xtb
+++ b/chromium/content/app/strings/translations/content_strings_pt-BR.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">controle deslizante</translation>
<translation id="1211441953136645838">nota final</translation>
<translation id="1281252709823657822">caixa de diálogo</translation>
+<translation id="1289247557029249093">Sair do modo picture-in-picture</translation>
<translation id="1335095011850992622">créditos</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">assistir vídeo no modo picture-in-picture</translation>
<translation id="1589122976691792535">região</translation>
<translation id="1591562245178063882">Este mês</translation>
<translation id="1637811476055996098">Escolher arquivos</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">grade de árvore</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">reproduzir em dispositivo remoto</translation>
+<translation id="190587075670221089">exclusão</translation>
<translation id="1907737156431278478">exemplo</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">status</translation>
<translation id="1938124657309484470">O valor deve ser <ph name="MAXIMUM_DATE_OR_TIME" /> ou anterior.</translation>
+<translation id="1946271899482435442">Mostrar seletor de datas</translation>
<translation id="1993104285338243655">Alterado para espelhamento</translation>
<translation id="2060505056492490888">"<ph name="DOT" />" está sendo usado em uma posição incorreta em "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">Hoje</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Enviar</translation>
<translation id="2657045182931379222">objeto gráfico</translation>
<translation id="2674318244760992338">rodapé</translation>
+<translation id="2706474812903655270">Este vídeo está sendo reproduzido em picture-in-picture</translation>
<translation id="2709516037105925701">Preenchimento automático</translation>
<translation id="2723001399770238859">áudio</translation>
<translation id="2746543609216772311">O valor deve ser <ph name="MINIMUM_DATE_OR_TIME" /> ou posterior.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Mostrar próximo mês</translation>
<translation id="512758898067543763">cabeçalho de linha</translation>
<translation id="5143125788380636750">epílogo</translation>
-<translation id="5153163864850940242">Este vídeo está sendo reproduzido em picture-in-picture</translation>
<translation id="5164977714490026579">O valor deve ser maior ou igual a <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Insira uma parte seguida por "<ph name="ATSIGN" />". "<ph name="INVALIDADDRESS" />" está incompleto.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">colofão</translation>
<translation id="6934078000481955284">bloco de texto</translation>
<translation id="6941933287844615239">fazer o download da mídia</translation>
+<translation id="6981594929165378967">inserção</translation>
<translation id="6989848892321993519">Aumente esse texto para <ph name="MIN_CHARACTERS" /> caracteres ou mais. No momento, você está usando 1 caractere.</translation>
<translation id="709897737746224366">É preciso que o formato corresponda ao exigido.</translation>
<translation id="7139483182332611405">prefácio</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">tempo restante</translation>
<translation id="7740016676195725605">parar de exibir legendas ocultas</translation>
<translation id="7740050170769002709">Conteúdo HTML</translation>
+<translation id="7750228210027921155">Picture-in-picture</translation>
<translation id="7789962463072032349">pausar</translation>
<translation id="7802800022689234070">triângulo de divulgação</translation>
<translation id="7888071071722539607">Inclua um "<ph name="ATSIGN" />" no endereço de e-mail. "<ph name="INVALIDADDRESS" />" está com um "<ph name="ATSIGN" />" faltando.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">sumário</translation>
<translation id="8613126697340063924">controlar reprodução remota</translation>
<translation id="862370744433916922">subtítulo</translation>
-<translation id="8741316211671074806">Picture-in-picture</translation>
<translation id="8750798805984357768">Selecione uma das opções.</translation>
<translation id="8785498733064193001">iniciar reprodução</translation>
<translation id="8808573423886751634">capítulo</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navegação</translation>
<translation id="9050748414552849310">mostrar legendas ocultas</translation>
<translation id="9062295712474918030">documento</translation>
+<translation id="9093215626363556771">sair de picture-in-picture</translation>
<translation id="9108370397979208512">matemática</translation>
<translation id="9132465097189459683">Outras...</translation>
<translation id="9138385573473225930">alerta</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, que começa em <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Picture-in-picture</translation>
<translation id="9168329111483466115">nota de rodapé</translation>
-<translation id="947831847158436616">célula</translation>
+<translation id="954003015749068518">entrar no modo picture-in-picture</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
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 2c22789449d..54070127810 100644
--- a/chromium/content/app/strings/translations/content_strings_pt-PT.xtb
+++ b/chromium/content/app/strings/translations/content_strings_pt-PT.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">controlo de deslize</translation>
<translation id="1211441953136645838">nota final</translation>
<translation id="1281252709823657822">caixa de diálogo</translation>
+<translation id="1289247557029249093">Sair do modo ecrã no ecrã</translation>
<translation id="1335095011850992622">créditos</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">reproduzir vídeo no modo ecrã no ecrã</translation>
<translation id="1589122976691792535">região</translation>
<translation id="1591562245178063882">Este mês</translation>
<translation id="1637811476055996098">Escolher Ficheiros</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">grelha de árvore</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">reproduzir no dispositivo remoto</translation>
+<translation id="190587075670221089">eliminação</translation>
<translation id="1907737156431278478">exemplo</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">estado</translation>
<translation id="1938124657309484470">O valor tem de ser <ph name="MAXIMUM_DATE_OR_TIME" /> ou anterior.</translation>
+<translation id="1946271899482435442">Mostrar selecionador de data</translation>
<translation id="1993104285338243655">Alterado para espelhamento.</translation>
<translation id="2060505056492490888">"<ph name="DOT" />" está a ser utilizado numa posição errada em "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">Hoje</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Submeter</translation>
<translation id="2657045182931379222">objeto de gráficos</translation>
<translation id="2674318244760992338">rodapé</translation>
+<translation id="2706474812903655270">Este vídeo está a ser reproduzido no modo ecrã no ecrã.</translation>
<translation id="2709516037105925701">Preenchimento automático</translation>
<translation id="2723001399770238859">áudio</translation>
<translation id="2746543609216772311">O valor tem de ser <ph name="MINIMUM_DATE_OR_TIME" /> ou posterior.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Mostrar mês seguinte</translation>
<translation id="512758898067543763">cabeçalho da linha</translation>
<translation id="5143125788380636750">epílogo</translation>
-<translation id="5153163864850940242">Este vídeo está a ser reproduzido no modo ecrã no ecrã</translation>
<translation id="5164977714490026579">O valor tem de ser superior ou igual a <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Introduza uma parte seguida de "<ph name="ATSIGN" />". "<ph name="INVALIDADDRESS" />" está incompleto.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">colofão</translation>
<translation id="6934078000481955284">blockquote</translation>
<translation id="6941933287844615239">transferir multimédia</translation>
+<translation id="6981594929165378967">inserção</translation>
<translation id="6989848892321993519">Aumente este texto para <ph name="MIN_CHARACTERS" /> ou mais carateres (atualmente, está a utilizar 1 caráter).</translation>
<translation id="709897737746224366">Faça corresponder o formato pedido.</translation>
<translation id="7139483182332611405">prefácio</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">tempo restante</translation>
<translation id="7740016676195725605">parar de apresentar legendas ocultas</translation>
<translation id="7740050170769002709">Conteúdo HTML</translation>
+<translation id="7750228210027921155">Ecrã no ecrã</translation>
<translation id="7789962463072032349">pausa</translation>
<translation id="7802800022689234070">triângulo de divulgação</translation>
<translation id="7888071071722539607">Inclua um "<ph name="ATSIGN" />" no endereço de email. Falta um "<ph name="ATSIGN" />" em "<ph name="INVALIDADDRESS" />".</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">índice</translation>
<translation id="8613126697340063924">controlar a reprodução remota</translation>
<translation id="862370744433916922">legenda</translation>
-<translation id="8741316211671074806">Ecrã no ecrã</translation>
<translation id="8750798805984357768">Seleccione uma destas opções.</translation>
<translation id="8785498733064193001">iniciar reprodução</translation>
<translation id="8808573423886751634">capítulo</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navegação</translation>
<translation id="9050748414552849310">apresentar legendas ocultas</translation>
<translation id="9062295712474918030">documento</translation>
+<translation id="9093215626363556771">sair do modo ecrã no ecrã</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">Outra...</translation>
<translation id="9138385573473225930">alerta</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, a partir de <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Ecrã no ecrã</translation>
<translation id="9168329111483466115">nota de rodapé</translation>
-<translation id="947831847158436616">célula</translation>
+<translation id="954003015749068518">entrar no modo ecrã no ecrã</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_ro.xtb b/chromium/content/app/strings/translations/content_strings_ro.xtb
index 4a14856b246..50d67946821 100644
--- a/chromium/content/app/strings/translations/content_strings_ro.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ro.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">glisor</translation>
<translation id="1211441953136645838">notă de final</translation>
<translation id="1281252709823657822">dialog</translation>
+<translation id="1289247557029249093">Ieși din modul picture-in-picture</translation>
<translation id="1335095011850992622">mulțumiri</translation>
<translation id="1342835525016946179">articol</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">redă videoclipul în modul picture-in-picture</translation>
<translation id="1589122976691792535">regiune</translation>
<translation id="1591562245178063882">Luna aceasta</translation>
<translation id="1637811476055996098">Alege fișierele</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">grilă arbore</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">redă pe dispozitiv la distanță</translation>
+<translation id="190587075670221089">ștergere</translation>
<translation id="1907737156431278478">exemplu</translation>
<translation id="1921819250265091946">zz</translation>
<translation id="1930711995431081526">stare</translation>
<translation id="1938124657309484470">Valoarea pentru dată/oră trebuie să fie <ph name="MAXIMUM_DATE_OR_TIME" /> sau una anterioară.</translation>
+<translation id="1946271899482435442">Afișează selectorul de date</translation>
<translation id="1993104285338243655">S-a comutat la oglindire</translation>
<translation id="2060505056492490888">Semnul „<ph name="DOT" />” apare poziționat greșit în „<ph name="INVALIDDOMAIN" />”.</translation>
<translation id="2148716181193084225">Astăzi</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Trimite</translation>
<translation id="2657045182931379222">obiect grafic</translation>
<translation id="2674318244760992338">notă de subsol</translation>
+<translation id="2706474812903655270">Videoclipul se redă în modul picture-in-picture</translation>
<translation id="2709516037105925701">Completare automată</translation>
<translation id="2723001399770238859">audio</translation>
<translation id="2746543609216772311">Valoarea pentru dată/oră trebuie să fie <ph name="MINIMUM_DATE_OR_TIME" /> sau una ulterioară.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Afișează luna următoare</translation>
<translation id="512758898067543763">antet rând</translation>
<translation id="5143125788380636750">epilog</translation>
-<translation id="5153163864850940242">Videoclipul se redă în modul imagine în imagine</translation>
<translation id="5164977714490026579">Valoarea trebuie să fie mai mare sau egală cu <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Introduceți o valoare urmată de semnul „<ph name="ATSIGN" />”. Adresa „<ph name="INVALIDADDRESS" />” nu este completă.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">colofon</translation>
<translation id="6934078000481955284">blockquote</translation>
<translation id="6941933287844615239">descarcă conținut media</translation>
+<translation id="6981594929165378967">inserare</translation>
<translation id="6989848892321993519">Mărește acest text la cel puțin <ph name="MIN_CHARACTERS" /> caractere (în prezent folosești 1 caracter).</translation>
<translation id="709897737746224366">Respectă formatul solicitat.</translation>
<translation id="7139483182332611405">prefață</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">timp rămas</translation>
<translation id="7740016676195725605">nu mai afișați subtitrările</translation>
<translation id="7740050170769002709">Conținut HTML</translation>
+<translation id="7750228210027921155">Picture-in-picture</translation>
<translation id="7789962463072032349">întrerupe</translation>
<translation id="7802800022689234070">triunghi pentru afișare</translation>
<translation id="7888071071722539607">Includeți semnul „<ph name="ATSIGN" />” în adresa de e-mail. Din adresa „<ph name="INVALIDADDRESS" />” lipsește semnul „<ph name="ATSIGN" />”.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">cuprins</translation>
<translation id="8613126697340063924">controlează redarea la distanță</translation>
<translation id="862370744433916922">subtitlu</translation>
-<translation id="8741316211671074806">Picture-in-Picture</translation>
<translation id="8750798805984357768">Selectează una dintre aceste opțiuni.</translation>
<translation id="8785498733064193001">începeți redarea</translation>
<translation id="8808573423886751634">capitol</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigare</translation>
<translation id="9050748414552849310">afișați subtitrările</translation>
<translation id="9062295712474918030">document</translation>
+<translation id="9093215626363556771">ieși din modul picture-in-picture</translation>
<translation id="9108370397979208512">matematică</translation>
<translation id="9132465097189459683">Altele...</translation>
<translation id="9138385573473225930">alertă</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, începând de pe <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Picture-in-Picture</translation>
<translation id="9168329111483466115">notă de subsol</translation>
-<translation id="947831847158436616">celulă</translation>
+<translation id="954003015749068518">intră în modul picture-in-picture</translation>
<translation id="966787709310836684">meniu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_ru.xtb b/chromium/content/app/strings/translations/content_strings_ru.xtb
index c1ba6cbaaf8..4ebbc1c31a9 100644
--- a/chromium/content/app/strings/translations/content_strings_ru.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ru.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">ползунок</translation>
<translation id="1211441953136645838">концевая сноска</translation>
<translation id="1281252709823657822">диалоговое окно</translation>
+<translation id="1289247557029249093">Выйти из режима "Картинка в картинке"</translation>
<translation id="1335095011850992622">выходные сведения</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">баннер</translation>
+<translation id="1548116112524424341">воспроизвести видео в режиме "Картинка в картинке"</translation>
<translation id="1589122976691792535">регион</translation>
<translation id="1591562245178063882">В этом месяце</translation>
<translation id="1637811476055996098">Выбрать файлы</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">сетка в виде дерева</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">воспроизвести на удаленном устройстве</translation>
+<translation id="190587075670221089">удаление</translation>
<translation id="1907737156431278478">пример</translation>
<translation id="1921819250265091946">дд</translation>
<translation id="1930711995431081526">статус</translation>
<translation id="1938124657309484470">Максимальное значение должно быть <ph name="MAXIMUM_DATE_OR_TIME" />.</translation>
+<translation id="1946271899482435442">Показать окно выбора даты</translation>
<translation id="1993104285338243655">Включено дублирование экрана</translation>
<translation id="2060505056492490888">Недопустимое положение символа "<ph name="DOT" />" в адресе "<ph name="INVALIDDOMAIN" />".</translation>
<translation id="2148716181193084225">Сегодня</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Отправить</translation>
<translation id="2657045182931379222">графический объект</translation>
<translation id="2674318244760992338">нижний колонтитул</translation>
+<translation id="2706474812903655270">Видео воспроизводится в режиме "Картинка в картинке".</translation>
<translation id="2709516037105925701">Автозаполнение</translation>
<translation id="2723001399770238859">аудио</translation>
<translation id="2746543609216772311">Минимальное значение должно быть <ph name="MINIMUM_DATE_OR_TIME" />.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Показать следующий месяц</translation>
<translation id="512758898067543763">заголовок строки</translation>
<translation id="5143125788380636750">эпилог</translation>
-<translation id="5153163864850940242">Видео воспроизводится в режиме "Картинка в картинке"</translation>
<translation id="5164977714490026579">Значение должно быть больше или равно <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> ПБ</translation>
<translation id="5307600278924710095">Введите часть адреса до символа "<ph name="ATSIGN" />". Адрес "<ph name="INVALIDADDRESS" />" неполный.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">выпускные данные</translation>
<translation id="6934078000481955284">цитата</translation>
<translation id="6941933287844615239">скачать файл</translation>
+<translation id="6981594929165378967">вставка</translation>
<translation id="6989848892321993519">Текст должен быть не короче <ph name="MIN_CHARACTERS" /> симв. Длина текста сейчас: 1 символ.</translation>
<translation id="709897737746224366">Введите данные в указанном формате.</translation>
<translation id="7139483182332611405">вступление</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">оставшееся время</translation>
<translation id="7740016676195725605">скрыть субтитры</translation>
<translation id="7740050170769002709">HTML-содержание</translation>
+<translation id="7750228210027921155">Картинка в картинке</translation>
<translation id="7789962463072032349">Пауза</translation>
<translation id="7802800022689234070">треугольник развертывания</translation>
<translation id="7888071071722539607">Адрес электронной почты должен содержать символ "<ph name="ATSIGN" />". В адресе "<ph name="INVALIDADDRESS" />" отсутствует символ "<ph name="ATSIGN" />".</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">оглавление</translation>
<translation id="8613126697340063924">управлять воспроизведением на удаленных устройствах</translation>
<translation id="862370744433916922">подзаголовок</translation>
-<translation id="8741316211671074806">Картинка в картинке</translation>
<translation id="8750798805984357768">Выберите один из вариантов.</translation>
<translation id="8785498733064193001">начать воспроизведение</translation>
<translation id="8808573423886751634">глава</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">навигация</translation>
<translation id="9050748414552849310">показать субтитры</translation>
<translation id="9062295712474918030">документ</translation>
+<translation id="9093215626363556771">выйти из режима "Картинка в картинке"</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">Другое…</translation>
<translation id="9138385573473225930">оповещение</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, начинается <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Картинка в картинке</translation>
<translation id="9168329111483466115">сноска</translation>
-<translation id="947831847158436616">ячейка</translation>
+<translation id="954003015749068518">включить режим "Картинка в картинке"</translation>
<translation id="966787709310836684">меню</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_sk.xtb b/chromium/content/app/strings/translations/content_strings_sk.xtb
index ce521185669..799bcaff015 100644
--- a/chromium/content/app/strings/translations/content_strings_sk.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sk.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">posúvač</translation>
<translation id="1211441953136645838">vysvetlivka</translation>
<translation id="1281252709823657822">dialóg</translation>
+<translation id="1289247557029249093">Ukončiť režim obraz v obraze</translation>
<translation id="1335095011850992622">titulky</translation>
<translation id="1342835525016946179">článok</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">prehrať video v režime obrazu v obraze</translation>
<translation id="1589122976691792535">oblasť</translation>
<translation id="1591562245178063882">Tento mesiac</translation>
<translation id="1637811476055996098">Vybrať súbory</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">stromová mriežka</translation>
<translation id="1822429046913737220">AM / PM</translation>
<translation id="1832974991323546415">prehrať na vzdialenom zariadení</translation>
+<translation id="190587075670221089">odstránenie</translation>
<translation id="1907737156431278478">príklad</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">stav</translation>
<translation id="1938124657309484470">Hodnota musí byť <ph name="MAXIMUM_DATE_OR_TIME" /> alebo skôr.</translation>
+<translation id="1946271899482435442">Zobraziť výber dátumu</translation>
<translation id="1993104285338243655">Prepnuté na zrkadlenie</translation>
<translation id="2060505056492490888">Znak <ph name="DOT" /> je v doméne <ph name="INVALIDDOMAIN" /> použitý na nesprávnej pozícii.</translation>
<translation id="2148716181193084225">Dnes</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Odoslať</translation>
<translation id="2657045182931379222">grafický objekt</translation>
<translation id="2674318244760992338">päta</translation>
+<translation id="2706474812903655270">Toto video sa prehráva v režime obraz v obraze</translation>
<translation id="2709516037105925701">Automatické dopĺňanie</translation>
<translation id="2723001399770238859">zvuk</translation>
<translation id="2746543609216772311">Hodnota musí byť <ph name="MINIMUM_DATE_OR_TIME" /> alebo neskôr.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Zobraziť ďalší mesiac</translation>
<translation id="512758898067543763">hlavička riadka</translation>
<translation id="5143125788380636750">epilóg</translation>
-<translation id="5153163864850940242">Toto video sa prehráva v režime Obraz v obraze</translation>
<translation id="5164977714490026579">Hodnota musí byť väčšia alebo rovná hodnote <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Zadajte časť pred znakom <ph name="ATSIGN" />. Adresa <ph name="INVALIDADDRESS" /> je neúplná.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofón</translation>
<translation id="6934078000481955284">značka blockquote</translation>
<translation id="6941933287844615239">stiahnuť médiá</translation>
+<translation id="6981594929165378967">vloženie</translation>
<translation id="6989848892321993519">Predĺžte tento text aspoň na <ph name="MIN_CHARACTERS" /> alebo viac znakov (momentálne používate jeden znak).</translation>
<translation id="709897737746224366">Zadajte hodnotu zodpovedajúcu požadovanému formátu.</translation>
<translation id="7139483182332611405">predslov</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">zostávajúci čas</translation>
<translation id="7740016676195725605">ukončiť zobrazovanie skrytých titulkov</translation>
<translation id="7740050170769002709">Obsah HTML</translation>
+<translation id="7750228210027921155">Obraz v obraze</translation>
<translation id="7789962463072032349">pozastaviť</translation>
<translation id="7802800022689234070">trojuholníkové tlačidlo na zobrazenie skrytého obsahu</translation>
<translation id="7888071071722539607">Uveďte v e-mailovej adrese znak <ph name="ATSIGN" />. V adrese <ph name="INVALIDADDRESS" /> znak <ph name="ATSIGN" /> chýba.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">obsah</translation>
<translation id="8613126697340063924">ovládať vzdialené prehrávanie</translation>
<translation id="862370744433916922">podnadpis</translation>
-<translation id="8741316211671074806">Obraz v obraze</translation>
<translation id="8750798805984357768">Vyberte jednu z týchto možností.</translation>
<translation id="8785498733064193001">začať prehrávanie</translation>
<translation id="8808573423886751634">kapitola</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigácia</translation>
<translation id="9050748414552849310">zobraziť skryté titulky</translation>
<translation id="9062295712474918030">dokument</translation>
+<translation id="9093215626363556771">ukončiť obraz v obraze</translation>
<translation id="9108370397979208512">matematika</translation>
<translation id="9132465097189459683">Iné...</translation>
<translation id="9138385573473225930">upozornenie</translation>
<translation id="9155987714137265666"><ph name="WEEK" /> začínajúci <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Obraz v obraze</translation>
<translation id="9168329111483466115">poznámka pod čiarou</translation>
-<translation id="947831847158436616">bunka</translation>
+<translation id="954003015749068518">zapnúť obraz v obraze</translation>
<translation id="966787709310836684">ponuka</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_sl.xtb b/chromium/content/app/strings/translations/content_strings_sl.xtb
index e21b1f5e558..56db58d546b 100644
--- a/chromium/content/app/strings/translations/content_strings_sl.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sl.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">drsnik</translation>
<translation id="1211441953136645838">končna opomba</translation>
<translation id="1281252709823657822">pogovorno okno</translation>
+<translation id="1289247557029249093">Zapri način slike v sliki</translation>
<translation id="1335095011850992622">seznam sodelujočih</translation>
<translation id="1342835525016946179">člnk</translation>
<translation id="1359897965706325498">pasica</translation>
+<translation id="1548116112524424341">predvajanje videoposnetkov v načinu slike v sliki</translation>
<translation id="1589122976691792535">območje</translation>
<translation id="1591562245178063882">Ta mesec</translation>
<translation id="1637811476055996098">Izberi datoteke</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">drevesna mreža</translation>
<translation id="1822429046913737220">Dopoldne/popoldne</translation>
<translation id="1832974991323546415">predvajanje v oddaljeni napravi</translation>
+<translation id="190587075670221089">brisanje</translation>
<translation id="1907737156431278478">primer</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">stanje</translation>
<translation id="1938124657309484470">Vrednost mora biti <ph name="MAXIMUM_DATE_OR_TIME" /> ali prej.</translation>
+<translation id="1946271899482435442">Pokaži izbirnik datuma</translation>
<translation id="1993104285338243655">Preklopljeno na zrcaljenje</translation>
<translation id="2060505056492490888">»<ph name="DOT" />« je na napačnem mestu v »<ph name="INVALIDDOMAIN" />«.</translation>
<translation id="2148716181193084225">Danes</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Pošlji</translation>
<translation id="2657045182931379222">grafični predmet</translation>
<translation id="2674318244760992338">noga</translation>
+<translation id="2706474812903655270">Ta videoposnetek se predvaja v načinu slike v sliki</translation>
<translation id="2709516037105925701">Samodejno izpolnjevanje</translation>
<translation id="2723001399770238859">zvok</translation>
<translation id="2746543609216772311">Vrednost mora biti <ph name="MINIMUM_DATE_OR_TIME" /> ali pozneje.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Prikaz naslednjega meseca</translation>
<translation id="512758898067543763">glava vrstice</translation>
<translation id="5143125788380636750">epilog</translation>
-<translation id="5153163864850940242">Ta videoposnetek se predvaja v načinu slike v sliki</translation>
<translation id="5164977714490026579">Vrednost mora biti večja od <ph name="MINIMUM" /> ali enaka.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Vnesite nekaj in nato <ph name="ATSIGN" />. Naslov »<ph name="INVALIDADDRESS" />« je nepopoln.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofon</translation>
<translation id="6934078000481955284">daljši citat</translation>
<translation id="6941933287844615239">prenos predstavnosti</translation>
+<translation id="6981594929165378967">vstavljanje</translation>
<translation id="6989848892321993519">Podaljšajte to besedilo na toliko znakov ali več: <ph name="MIN_CHARACTERS" /> (trenutno uporabljate en znak).</translation>
<translation id="709897737746224366">Poskrbite za ujemanje z zahtevano obliko.</translation>
<translation id="7139483182332611405">predgovor</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">preostali čas</translation>
<translation id="7740016676195725605">ustavitev prikazovanja podnapisov</translation>
<translation id="7740050170769002709">Vsebina HTML</translation>
+<translation id="7750228210027921155">Slika v sliki</translation>
<translation id="7789962463072032349">premor</translation>
<translation id="7802800022689234070">trikotnik z dodatno vsebino</translation>
<translation id="7888071071722539607">V e-poštnem naslovu mora biti znak »<ph name="ATSIGN" />«. V naslovu »<ph name="INVALIDADDRESS" />« manjka »<ph name="ATSIGN" />«.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">kazalo</translation>
<translation id="8613126697340063924">upravljanje oddaljenega predvajanja</translation>
<translation id="862370744433916922">podnaslov</translation>
-<translation id="8741316211671074806">Slika v sliki</translation>
<translation id="8750798805984357768">Izberite eno od teh možnosti.</translation>
<translation id="8785498733064193001">začetek predvajanja</translation>
<translation id="8808573423886751634">poglavje</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">krmarjenje</translation>
<translation id="9050748414552849310">prikaz podnapisov</translation>
<translation id="9062295712474918030">dokument</translation>
+<translation id="9093215626363556771">zapiranje načina slike v sliki</translation>
<translation id="9108370397979208512">matematika</translation>
<translation id="9132465097189459683">Drugo ...</translation>
<translation id="9138385573473225930">opozorilo</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, začne se <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Slika v sliki</translation>
<translation id="9168329111483466115">sprotna opomba</translation>
-<translation id="947831847158436616">celica</translation>
+<translation id="954003015749068518">odpiranje načina slike v sliki</translation>
<translation id="966787709310836684">meni</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_sr.xtb b/chromium/content/app/strings/translations/content_strings_sr.xtb
index 80a786e21be..676581cd90b 100644
--- a/chromium/content/app/strings/translations/content_strings_sr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sr.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">клизач</translation>
<translation id="1211441953136645838">завршна напомена</translation>
<translation id="1281252709823657822">дијалог</translation>
+<translation id="1289247557029249093">Изађи из режима слике у слици</translation>
<translation id="1335095011850992622">заслуге</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">банер</translation>
+<translation id="1548116112524424341">пустите видео у режиму слике у слици</translation>
<translation id="1589122976691792535">регион</translation>
<translation id="1591562245178063882">Овај месец</translation>
<translation id="1637811476055996098">Избор датотека</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">мрежа стабла</translation>
<translation id="1822429046913737220">пре подне/по подне</translation>
<translation id="1832974991323546415">пуштајте на удаљеном уређају</translation>
+<translation id="190587075670221089">брисање</translation>
<translation id="1907737156431278478">пример</translation>
<translation id="1921819250265091946">дд</translation>
<translation id="1930711995431081526">статус</translation>
<translation id="1938124657309484470">Вредност мора да буде <ph name="MAXIMUM_DATE_OR_TIME" /> или старија.</translation>
+<translation id="1946271899482435442">Прикажи бирач датума</translation>
<translation id="1993104285338243655">Пребачено је на пресликавање</translation>
<translation id="2060505056492490888">„<ph name="DOT" />“ је стављено на погрешно место у „<ph name="INVALIDDOMAIN" />“.</translation>
<translation id="2148716181193084225">Данас</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Пошаљи</translation>
<translation id="2657045182931379222">графички објекат</translation>
<translation id="2674318244760992338">подножје</translation>
+<translation id="2706474812903655270">Видео се репродукује у режиму слике у слици</translation>
<translation id="2709516037105925701">Аутоматско попуњавање</translation>
<translation id="2723001399770238859">аудио</translation>
<translation id="2746543609216772311">Вредност мора да буде <ph name="MINIMUM_DATE_OR_TIME" /> или новија.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Прикажи следећи месец</translation>
<translation id="512758898067543763">заглавље реда</translation>
<translation id="5143125788380636750">епилог</translation>
-<translation id="5153163864850940242">Видео се репродукује у режиму слике у слици</translation>
<translation id="5164977714490026579">Вредност сме да буде најмање <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Унесите неки део пре „<ph name="ATSIGN" />“. Адреса „<ph name="INVALIDADDRESS" />“ је непотпуна.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">знак издавача</translation>
<translation id="6934078000481955284">издвојени цитат</translation>
<translation id="6941933287844615239">преузми медије</translation>
+<translation id="6981594929165378967">уметање</translation>
<translation id="6989848892321993519">Продужите овај текст на бар <ph name="MIN_CHARACTERS" /> знак(ов)а (тренутно користите 1 знак).</translation>
<translation id="709897737746224366">Изаберите захтевани формат.</translation>
<translation id="7139483182332611405">предговор</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">преостало време</translation>
<translation id="7740016676195725605">зауставите приказивање опционалног титла</translation>
<translation id="7740050170769002709">HTML садржај</translation>
+<translation id="7750228210027921155">Слика у слици</translation>
<translation id="7789962463072032349">паузирај</translation>
<translation id="7802800022689234070">троугао за откривање</translation>
<translation id="7888071071722539607">Уврстите „<ph name="ATSIGN" />“ у имејл адресу. У адреси е-поште „<ph name="INVALIDADDRESS" />“ недостаје „<ph name="ATSIGN" />“.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">садржај</translation>
<translation id="8613126697340063924">контролишите репродукцију на удаљеном уређају</translation>
<translation id="862370744433916922">титл</translation>
-<translation id="8741316211671074806">Слика у слици</translation>
<translation id="8750798805984357768">Изаберите неку од ових опција.</translation>
<translation id="8785498733064193001">започните репродукцију</translation>
<translation id="8808573423886751634">поглавље</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">навигација</translation>
<translation id="9050748414552849310">приказивање опционалног титла</translation>
<translation id="9062295712474918030">документ</translation>
+<translation id="9093215626363556771">изађи из режима слике у слици</translation>
<translation id="9108370397979208512">математички</translation>
<translation id="9132465097189459683">Друго...</translation>
<translation id="9138385573473225930">обавештење</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, од <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Слика у слици</translation>
<translation id="9168329111483466115">фуснота</translation>
-<translation id="947831847158436616">ћелија</translation>
+<translation id="954003015749068518">уђи у режим слике у слици</translation>
<translation id="966787709310836684">мени</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_sv.xtb b/chromium/content/app/strings/translations/content_strings_sv.xtb
index 570a7a56037..3f94cd192e0 100644
--- a/chromium/content/app/strings/translations/content_strings_sv.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sv.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">skjutreglage</translation>
<translation id="1211441953136645838">slutnot</translation>
<translation id="1281252709823657822">dialogruta</translation>
+<translation id="1289247557029249093">Avsluta bild-i-bild-läge</translation>
<translation id="1335095011850992622">medverkande</translation>
<translation id="1342835525016946179">artikel</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">spela upp video i bild-i-bild-läge</translation>
<translation id="1589122976691792535">område</translation>
<translation id="1591562245178063882">Den här månaden</translation>
<translation id="1637811476055996098">Välj filer</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">träddiagram</translation>
<translation id="1822429046913737220">FM/EM</translation>
<translation id="1832974991323546415">spela på en fjärrenhet</translation>
+<translation id="190587075670221089">borttagning</translation>
<translation id="1907737156431278478">exempel</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">status</translation>
<translation id="1938124657309484470">Värdet måste vara <ph name="MAXIMUM_DATE_OR_TIME" /> eller tidigare.</translation>
+<translation id="1946271899482435442">Visa datumväljaren</translation>
<translation id="1993104285338243655">Bytte till spegling</translation>
<translation id="2060505056492490888"><ph name="DOT" /> används på fel plats i <ph name="INVALIDDOMAIN" />.</translation>
<translation id="2148716181193084225">Idag</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Skicka</translation>
<translation id="2657045182931379222">grafiskt objekt</translation>
<translation id="2674318244760992338">sidfot</translation>
+<translation id="2706474812903655270">Videon spelas upp i bild-i-bild-läge</translation>
<translation id="2709516037105925701">Autofyll</translation>
<translation id="2723001399770238859">ljud</translation>
<translation id="2746543609216772311">Värdet måste vara <ph name="MINIMUM_DATE_OR_TIME" /> eller senare.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Visa nästa månad</translation>
<translation id="512758898067543763">radrubrik</translation>
<translation id="5143125788380636750">epilog</translation>
-<translation id="5153163864850940242">Videon spelas upp i läget bild-i-bild</translation>
<translation id="5164977714490026579">Värdet måste vara större än eller lika med <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Ange en del följt av <ph name="ATSIGN" />. <ph name="INVALIDADDRESS" /> är ofullständig.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofon</translation>
<translation id="6934078000481955284">citatblock</translation>
<translation id="6941933287844615239">ladda ned media</translation>
+<translation id="6981594929165378967">infogning</translation>
<translation id="6989848892321993519">Lägg till minst <ph name="MIN_CHARACTERS" /> tecken (för närvarande har du angett 1 tecken).</translation>
<translation id="709897737746224366">Matcha det format som anges.</translation>
<translation id="7139483182332611405">företal</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">återstående tid</translation>
<translation id="7740016676195725605">sluta visa textning</translation>
<translation id="7740050170769002709">HTML-innehåll</translation>
+<translation id="7750228210027921155">Bild-i-bild</translation>
<translation id="7789962463072032349">paus</translation>
<translation id="7802800022689234070">expanderingstriangel</translation>
<translation id="7888071071722539607">Inkludera ett <ph name="ATSIGN" /> i e-postadressen. <ph name="INVALIDADDRESS" /> saknar ett <ph name="ATSIGN" />.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">innehållsförteckning</translation>
<translation id="8613126697340063924">styra fjärruppspelning</translation>
<translation id="862370744433916922">undertext</translation>
-<translation id="8741316211671074806">Bild i bild</translation>
<translation id="8750798805984357768">Välj ett av följande alternativ.</translation>
<translation id="8785498733064193001">starta uppspelning</translation>
<translation id="8808573423886751634">kapitel</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">navigering</translation>
<translation id="9050748414552849310">visa textning</translation>
<translation id="9062295712474918030">dokument</translation>
+<translation id="9093215626363556771">avsluta bild-i-bild-läge</translation>
<translation id="9108370397979208512">matte</translation>
<translation id="9132465097189459683">Annat ...</translation>
<translation id="9138385573473225930">varning</translation>
<translation id="9155987714137265666"><ph name="WEEK" /> som börjar den <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Bild-i-bild</translation>
<translation id="9168329111483466115">fotnot</translation>
-<translation id="947831847158436616">cell</translation>
+<translation id="954003015749068518">öppna bild-i-bild-läge</translation>
<translation id="966787709310836684">meny</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_sw.xtb b/chromium/content/app/strings/translations/content_strings_sw.xtb
index 810a58adb8b..686d61b6184 100644
--- a/chromium/content/app/strings/translations/content_strings_sw.xtb
+++ b/chromium/content/app/strings/translations/content_strings_sw.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">kitelezi</translation>
<translation id="1211441953136645838">maelezo ya mwisho wa kitabu</translation>
<translation id="1281252709823657822">kidirisha</translation>
+<translation id="1289247557029249093">Funga hali ya picha ndani ya picha</translation>
<translation id="1335095011850992622">walioshiriki</translation>
<translation id="1342835525016946179">makala</translation>
<translation id="1359897965706325498">bango</translation>
+<translation id="1548116112524424341">cheza video katika hali ya picha ndani ya picha</translation>
<translation id="1589122976691792535">eneo</translation>
<translation id="1591562245178063882">Mwezi huu</translation>
<translation id="1637811476055996098">Chagua Faili</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">gridi ya mti</translation>
<translation id="1822429046913737220">AM / PM</translation>
<translation id="1832974991323546415">cheza kwenye kifaa cha mbali</translation>
+<translation id="190587075670221089">ufutaji</translation>
<translation id="1907737156431278478">mfano</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">hali</translation>
<translation id="1938124657309484470">Thamani lazima iwe <ph name="MAXIMUM_DATE_OR_TIME" /> au mapema.</translation>
+<translation id="1946271899482435442">Onyesha kiteua tarehe</translation>
<translation id="1993104285338243655">Inatumia hali ya kuakisi</translation>
<translation id="2060505056492490888">' <ph name="DOT" /> 'imetumika kwenye nafasi isiyostahili katika '<ph name="INVALIDDOMAIN" />'.</translation>
<translation id="2148716181193084225">Leo</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Wasilisha</translation>
<translation id="2657045182931379222">kipengee cha michoro</translation>
<translation id="2674318244760992338">kijachini</translation>
+<translation id="2706474812903655270">Video hii inacheza katika hali ya picha ndani ya picha</translation>
<translation id="2709516037105925701">Kujaza Kiotomatiki</translation>
<translation id="2723001399770238859">sauti</translation>
<translation id="2746543609216772311">Thamani lazima iwe <ph name="MINIMUM_DATE_OR_TIME" /> au baadaye.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Onyesha mwezi unaofuata</translation>
<translation id="512758898067543763">kichwa cha safu mlalo</translation>
<translation id="5143125788380636750">hitimisho</translation>
-<translation id="5153163864850940242">Video hii inacheza katika hali ya Picha Ndani ya Picha</translation>
<translation id="5164977714490026579">Lazima thamani iwe kubwa kuliko au sawa na <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650">PB <ph name="QUANTITY" /></translation>
<translation id="5307600278924710095">Tafadhali ingiza sehemu ikifuatiwa na '<ph name="ATSIGN" />'. '<ph name="INVALIDADDRESS" />' haijakamilika.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">kolofoni</translation>
<translation id="6934078000481955284">nukuu la msingi</translation>
<translation id="6941933287844615239">pakua maudhui</translation>
+<translation id="6981594929165378967">uwekaji</translation>
<translation id="6989848892321993519">Tafadhali refusha maandishi haya hadi herufi <ph name="MIN_CHARACTERS" /> au zaidi (kwa sasa unatumia herufi 1).</translation>
<translation id="709897737746224366">Tafadhali linganisha umbizo lililoombwa.</translation>
<translation id="7139483182332611405">dibaji</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">muda unaosalia</translation>
<translation id="7740016676195725605">koma kuonyesha manukuu yanaweza kufichwa</translation>
<translation id="7740050170769002709">Maudhui ya HTML</translation>
+<translation id="7750228210027921155">Picha ndani ya picha</translation>
<translation id="7789962463072032349">Sitisha</translation>
<translation id="7802800022689234070">pembe tatu ya ufafanuzi</translation>
<translation id="7888071071722539607">Tafadhali jumuisha '<ph name="ATSIGN" />' katika anwani ya barua pepe. '<ph name="INVALIDADDRESS" />' inakosa '<ph name="ATSIGN" />'.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">jedwali la yaliyomo</translation>
<translation id="8613126697340063924">dhibiti kucheza kwa mbali</translation>
<translation id="862370744433916922">kichwa kidogo</translation>
-<translation id="8741316211671074806">Picha ndani ya picha</translation>
<translation id="8750798805984357768">Tafadhali chagua moja wapo ya chaguo hizi.</translation>
<translation id="8785498733064193001">anza kucheza</translation>
<translation id="8808573423886751634">sura</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">kuvinjari</translation>
<translation id="9050748414552849310">onyesha manakuu yaliyofichwa</translation>
<translation id="9062295712474918030">hati</translation>
+<translation id="9093215626363556771">funga hali ya picha ndani ya picha</translation>
<translation id="9108370397979208512">hisabati</translation>
<translation id="9132465097189459683">Nyingine...</translation>
<translation id="9138385573473225930">arifa</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, itaanza tarehe <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Picha ndani ya Picha</translation>
<translation id="9168329111483466115">tanbihi</translation>
-<translation id="947831847158436616">kisanduku</translation>
+<translation id="954003015749068518">washa hali ya picha ndani ya picha</translation>
<translation id="966787709310836684">menyu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_ta.xtb b/chromium/content/app/strings/translations/content_strings_ta.xtb
index 450fea855b3..a7768b9296e 100644
--- a/chromium/content/app/strings/translations/content_strings_ta.xtb
+++ b/chromium/content/app/strings/translations/content_strings_ta.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">ஸ்லைடர்</translation>
<translation id="1211441953136645838">முடிவுக்குறிப்பு</translation>
<translation id="1281252709823657822">உரையாடல்</translation>
+<translation id="1289247557029249093">பிக்ச்சர்-இன்-பிக்ச்சர் பயன்முறையிலிருந்து வெளியேறு</translation>
<translation id="1335095011850992622">பங்களித்தவர்கள்</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">பேனர்</translation>
+<translation id="1548116112524424341">பிக்ச்சர்-இன்-பிக்ச்சர் பயன்முறையில் வீடியோவை இயக்கும்</translation>
<translation id="1589122976691792535">மண்டலம்</translation>
<translation id="1591562245178063882">இந்த மாதம்</translation>
<translation id="1637811476055996098">கோப்புகளைத் தேர்வுசெய்க</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">ட்ரீ கிரிட்</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">தொலைநிலைச் சாதனத்தில் இயக்கு</translation>
+<translation id="190587075670221089">நீக்கும்</translation>
<translation id="1907737156431278478">உதாரணம்</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">நிலை</translation>
<translation id="1938124657309484470">மதிப்பு <ph name="MAXIMUM_DATE_OR_TIME" /> அல்லது அதற்கு முன்பு இருக்க வேண்டும்.</translation>
+<translation id="1946271899482435442">தேதித் தேர்ந்தெடுப்பானைக் காட்டும்</translation>
<translation id="1993104285338243655">பிரதிபலித்தலுக்கு மாற்றியது</translation>
<translation id="2060505056492490888"><ph name="INVALIDDOMAIN" /> இல் தவறான இடத்தில் '<ph name="DOT" />' பயன்படுத்தபட்டுள்ளது.</translation>
<translation id="2148716181193084225">இன்று</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">சமர்ப்பி</translation>
<translation id="2657045182931379222">கிராஃபிக்ஸ் பொருள்</translation>
<translation id="2674318244760992338">அடிக்குறிப்பு</translation>
+<translation id="2706474812903655270">பிக்ச்சர்-இன்-பிக்ச்சர் பயன்முறையில் இந்த வீடியோ இயக்கப்படுகிறது</translation>
<translation id="2709516037105925701">தானாகநிரப்பு</translation>
<translation id="2723001399770238859">ஆடியோ</translation>
<translation id="2746543609216772311">மதிப்பானது <ph name="MINIMUM_DATE_OR_TIME" /> அல்லது அதற்குப் பின்பு இருக்க வேண்டும்.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">அடுத்த மாதத்தைக் காட்டு</translation>
<translation id="512758898067543763">வரிசை மேற்தலைப்பு</translation>
<translation id="5143125788380636750">முடிவுரை</translation>
-<translation id="5153163864850940242">பிக்ச்சர்-இன்-பிக்ச்சர் பயன்முறையில் இந்த வீடியோ இயக்கப்படுகிறது</translation>
<translation id="5164977714490026579">மதிப்பானது, கண்டிப்பாக <ph name="MINIMUM" /> ஐ விட அதிகமாக அல்லது அதற்குச் சமமாக இருக்க வேண்டும்.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> பெ.பை</translation>
<translation id="5307600278924710095">'<ph name="ATSIGN" />' ஐத் தொடர்ந்து ஒரு பகுதியை உள்ளிடவும். '<ph name="INVALIDADDRESS" />' முழுமைப் பெறாமல் உள்ளது.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">முத்திரை</translation>
<translation id="6934078000481955284">பிளாக்கோட்</translation>
<translation id="6941933287844615239">மீடியாவைப் பதிவிறக்கு</translation>
+<translation id="6981594929165378967">செருகும்</translation>
<translation id="6989848892321993519">இந்த உரையில் <ph name="MIN_CHARACTERS" /> அல்லது அதற்கு மேற்பட்ட எழுத்துக்குறிகளைப் பயன்படுத்தவும் (தற்போது 1 எழுத்துக்குறியைப் பயன்படுத்துகிறீர்கள்).</translation>
<translation id="709897737746224366">கோரிய வடிவமைப்பில் தருக.</translation>
<translation id="7139483182332611405">முன்னுரை</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">மீதமுள்ள நேரம்</translation>
<translation id="7740016676195725605">மூடப்பட்ட தலைப்புகளைக் காட்டுவதை நிறுத்து</translation>
<translation id="7740050170769002709">HTML உள்ளடக்கம்</translation>
+<translation id="7750228210027921155">பிக்ச்சர்-இன்-பிக்ச்சர்</translation>
<translation id="7789962463072032349">இடைநிறுத்து</translation>
<translation id="7802800022689234070">கூடுதல் உள்ளடக்க முக்கோணம்</translation>
<translation id="7888071071722539607">மின்னஞ்சல் முகவரியில் '<ph name="ATSIGN" />' ஐச் சேர்க்கவும். '<ph name="ATSIGN" />' இல் '<ph name="INVALIDADDRESS" />' இல்லை.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">உள்ளடக்க அட்டவணை</translation>
<translation id="8613126697340063924">தொலைநிலை இயக்கத்தைக் கட்டுப்படுத்தவும்</translation>
<translation id="862370744433916922">துணை தலைப்பு</translation>
-<translation id="8741316211671074806">பிக்ச்சர்-இன்-பிக்ச்சர்</translation>
<translation id="8750798805984357768">தயவுசெய்து இந்த விருப்பங்களில் ஒன்றைத் தேர்ந்தெடுங்கள்.</translation>
<translation id="8785498733064193001">மறுஇயக்கத்தைத் தொடங்கு</translation>
<translation id="8808573423886751634">அத்தியாயம்</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">வழிசெலுத்தல்</translation>
<translation id="9050748414552849310">மூடப்பட்ட தலைப்புகளைக் காட்டு</translation>
<translation id="9062295712474918030">ஆவணம்</translation>
+<translation id="9093215626363556771">பிக்ச்சர்-இன்-பிக்ச்சர் பயன்முறையிலிருந்து வெளியேறும்</translation>
<translation id="9108370397979208512">கணிதம்</translation>
<translation id="9132465097189459683">மற்றவை…</translation>
<translation id="9138385573473225930">விழிப்பூட்டல்</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, <ph name="WEEK_START_DATE" /> அன்று தொடங்குவது</translation>
+<translation id="916607977885256133">பிக்ச்சர்-இன்-பிக்ச்சர்</translation>
<translation id="9168329111483466115">அடிக்குறிப்பு</translation>
-<translation id="947831847158436616">கலம்</translation>
+<translation id="954003015749068518">பிக்ச்சர்-இன்-பிக்ச்சர் பயன்முறைக்குச் செல்லும்</translation>
<translation id="966787709310836684">மெனு</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_te.xtb b/chromium/content/app/strings/translations/content_strings_te.xtb
index ece107bc6e9..53351a20428 100644
--- a/chromium/content/app/strings/translations/content_strings_te.xtb
+++ b/chromium/content/app/strings/translations/content_strings_te.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">స్లయిడర్</translation>
<translation id="1211441953136645838">ఎండ్‌నోట్</translation>
<translation id="1281252709823657822">డైలాగ్</translation>
+<translation id="1289247557029249093">చిత్రంలో చిత్రం మోడ్ నుంచి నిష్క్రమించు</translation>
<translation id="1335095011850992622">సహకారులు</translation>
<translation id="1342835525016946179">కథనం</translation>
<translation id="1359897965706325498">బ్యానర్</translation>
+<translation id="1548116112524424341">వీడియోను చిత్రంలో చిత్రం మోడ్‌లో ప్లే చేయండి</translation>
<translation id="1589122976691792535">ప్రాంతం</translation>
<translation id="1591562245178063882">ఈ నెల</translation>
<translation id="1637811476055996098">ఫైల్‌లను ఎంచుకోండి</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">వృక్షాంశ గ్రిడ్</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">రిమోట్ పరికరంలో ప్లే చేస్తుంది</translation>
+<translation id="190587075670221089">తొలగింపు</translation>
<translation id="1907737156431278478">ఉదాహరణ</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">స్థితి</translation>
<translation id="1938124657309484470">విలువ తప్పనిసరిగా <ph name="MAXIMUM_DATE_OR_TIME" /> లేదా అంతకంటే మునుపటిది అయి ఉండాలి.</translation>
+<translation id="1946271899482435442">తేదీ ఎంపికను చూపుతుంది</translation>
<translation id="1993104285338243655">మిర్రరింగ్‌కు మార్చబడింది</translation>
<translation id="2060505056492490888">'<ph name="INVALIDDOMAIN" />'లో '<ph name="DOT" />' తప్పు స్థానంలో ఉపయోగించబడింది.</translation>
<translation id="2148716181193084225">ఈ రోజు</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">సమర్పించు</translation>
<translation id="2657045182931379222">గ్రాఫిక్స్ ఆబ్జెక్ట్</translation>
<translation id="2674318244760992338">ఫుటర్</translation>
+<translation id="2706474812903655270">ఈ వీడియో చిత్రంలో చిత్రం మోడ్‌లో ప్లే అవుతోంది</translation>
<translation id="2709516037105925701">స్వయంపూర్తి</translation>
<translation id="2723001399770238859">ఆడియో</translation>
<translation id="2746543609216772311">విలువ తప్పనిసరిగా <ph name="MINIMUM_DATE_OR_TIME" /> లేదా అంతకంటే తదుపరిది అయి ఉండాలి.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">తదుపరి నెలను చూపుతుంది</translation>
<translation id="512758898067543763">అడ్డు వరుస శీర్షిక</translation>
<translation id="5143125788380636750">ఉపసంహారం</translation>
-<translation id="5153163864850940242">ఈ వీడియో చిత్రంలో-చిత్రంలో ప్లే అవుతోంది</translation>
<translation id="5164977714490026579">విలువ ఖచ్చితంగా <ph name="MINIMUM" /> కంటే ఎక్కువగా లేదా సమానంగా ఉండాలి.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">దయచేసి '<ph name="ATSIGN" />'కి ముందు ఉన్న భాగాన్ని నమోదు చేయండి. '<ph name="INVALIDADDRESS" />' అసంపూర్ణంగా ఉంది.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">ఆఖరిమాట</translation>
<translation id="6934078000481955284">బ్లాక్‌కోట్</translation>
<translation id="6941933287844615239">మీడియా అంశం డౌన్‌లోడ్ చేయి</translation>
+<translation id="6981594929165378967">చొప్పించడం</translation>
<translation id="6989848892321993519">దయచేసి ఈ వచనాన్ని <ph name="MIN_CHARACTERS" /> లేదా అంతకంటే ఎక్కువ అక్షరాలకు పొడిగించండి (ప్రస్తుతం మీరు 1 అక్షరాన్ని ఉపయోగిస్తున్నారు).</translation>
<translation id="709897737746224366">దయచేసి అభ్యర్థించిన ఆకృతీకరణను సరిపోల్చండి.</translation>
<translation id="7139483182332611405">ముందుమాట</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">మిగిలి ఉన్న సమయం</translation>
<translation id="7740016676195725605">సంవృత శీర్షికలను ప్రదర్శించడం ఆపివేయి</translation>
<translation id="7740050170769002709">HTML కంటెంట్</translation>
+<translation id="7750228210027921155">చిత్రంలో చిత్రం</translation>
<translation id="7789962463072032349">నిలిపివేయి</translation>
<translation id="7802800022689234070">కంటెంట్‌ను విస్తరింపజేసే లేదా కుదించే త్రిభుజం</translation>
<translation id="7888071071722539607">దయచేసి ఇమెయిల్ చిరునామాలో '<ph name="ATSIGN" />'ని చేర్చండి. '<ph name="INVALIDADDRESS" />'లో '<ph name="ATSIGN" />' లేదు.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">విషయ పట్టిక</translation>
<translation id="8613126697340063924">రిమోట్ ప్లేబ్యాక్‌ను నియంత్రిస్తుంది</translation>
<translation id="862370744433916922">ఉపశీర్షిక</translation>
-<translation id="8741316211671074806">చిత్రంలో చిత్రం</translation>
<translation id="8750798805984357768">దయచేసి ఈ ఎంపికలలో ఒకదాన్ని ఎంచుకోండి.</translation>
<translation id="8785498733064193001">ప్లేబ్యాక్‌ను ప్రారంభించు</translation>
<translation id="8808573423886751634">అధ్యాయం</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">నావిగేషన్</translation>
<translation id="9050748414552849310">సంవృత శీర్షికలను చూపు</translation>
<translation id="9062295712474918030">పత్రం</translation>
+<translation id="9093215626363556771">చిత్రంలో చిత్రం మోడ్ నుండి నిష్క్రమింపజేస్తుంది</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">ఇతర...</translation>
<translation id="9138385573473225930">హెచ్చరిక</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, <ph name="WEEK_START_DATE" /> నుండి ప్రారంభమవుతుంది</translation>
+<translation id="916607977885256133">చిత్రంలో చిత్రం</translation>
<translation id="9168329111483466115">ఫుట్‌నోట్</translation>
-<translation id="947831847158436616">గడి</translation>
+<translation id="954003015749068518">చిత్రంలో చిత్రం మోడ్‌లోకి ప్రవేశిస్తుంది</translation>
<translation id="966787709310836684">మెను</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_th.xtb b/chromium/content/app/strings/translations/content_strings_th.xtb
index b7ec11b7cc2..c805447d181 100644
--- a/chromium/content/app/strings/translations/content_strings_th.xtb
+++ b/chromium/content/app/strings/translations/content_strings_th.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">แถบเลื่อน</translation>
<translation id="1211441953136645838">อ้างอิงท้ายเรื่อง</translation>
<translation id="1281252709823657822">กล่องโต้ตอบ</translation>
+<translation id="1289247557029249093">ออกจากโหมดการแสดงภาพซ้อนภาพ</translation>
<translation id="1335095011850992622">เครดิต</translation>
<translation id="1342835525016946179">บทความ</translation>
<translation id="1359897965706325498">แบนเนอร์</translation>
+<translation id="1548116112524424341">เล่นวิดีโอในโหมดการแสดงภาพซ้อนภาพ</translation>
<translation id="1589122976691792535">ภูมิภาค</translation>
<translation id="1591562245178063882">เดือนนี้</translation>
<translation id="1637811476055996098">เลือกไฟล์</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">แผนผังต้นไม้</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">เล่นในอุปกรณ์ระยะไกล</translation>
+<translation id="190587075670221089">การลบ</translation>
<translation id="1907737156431278478">ตัวอย่าง</translation>
<translation id="1921819250265091946">วว</translation>
<translation id="1930711995431081526">สถานะ</translation>
<translation id="1938124657309484470">ค่าต้องเป็น <ph name="MAXIMUM_DATE_OR_TIME" /> หรือก่อนหน้านั้น</translation>
+<translation id="1946271899482435442">แสดงเครื่องมือเลือกวันที่</translation>
<translation id="1993104285338243655">เปลี่ยนเป็นการมิเรอร์</translation>
<translation id="2060505056492490888">"<ph name="DOT" />" ถูกใช้งานในตำแหน่งที่ไม่ถูกต้องใน "<ph name="INVALIDDOMAIN" />"</translation>
<translation id="2148716181193084225">วันนี้</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">ส่ง</translation>
<translation id="2657045182931379222">ออบเจ็กต์กราฟิก</translation>
<translation id="2674318244760992338">ส่วนท้าย</translation>
+<translation id="2706474812903655270">กำลังเล่นวิดีโอในโหมดการแสดงภาพซ้อนภาพ</translation>
<translation id="2709516037105925701">ป้อนอัตโนมัติ</translation>
<translation id="2723001399770238859">เสียง</translation>
<translation id="2746543609216772311">ค่าต้องเป็น <ph name="MINIMUM_DATE_OR_TIME" /> หรือหลังจากนั้น</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">แสดงเดือนถัดไป</translation>
<translation id="512758898067543763">ส่วนหัวของแถว</translation>
<translation id="5143125788380636750">ปัจฉิมบท</translation>
-<translation id="5153163864850940242">กำลังเล่นวิดีโอในโหมดการแสดงภาพซ้อนภาพ</translation>
<translation id="5164977714490026579">ค่าต้องมากกว่าหรือเท่ากับ <ph name="MINIMUM" /></translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">โปรดป้อนส่วนหนึ่งโดยตามด้วย "<ph name="ATSIGN" />" "<ph name="INVALIDADDRESS" />" นั้นไม่สมบูรณ์</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">ข้อมูลทางบรรณานุกรม</translation>
<translation id="6934078000481955284">ข้อความที่ยกมา</translation>
<translation id="6941933287844615239">ดาวน์โหลดสื่อ</translation>
+<translation id="6981594929165378967">การแทรก</translation>
<translation id="6989848892321993519">โปรดกรอกข้อความนี้ให้มีอักขระอย่างน้อย <ph name="MIN_CHARACTERS" /> ตัว (ตอนนี้คุณมี 1 ตัว)</translation>
<translation id="709897737746224366">โปรดจับคู่รูปแบบที่ร้องขอ</translation>
<translation id="7139483182332611405">ส่วนนำ</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">เวลาที่เหลือ</translation>
<translation id="7740016676195725605">หยุดแสดงคำอธิบายภาพ</translation>
<translation id="7740050170769002709">เนื้อหา HTML</translation>
+<translation id="7750228210027921155">การแสดงภาพซ้อนภาพ</translation>
<translation id="7789962463072032349">หยุดชั่วคราว</translation>
<translation id="7802800022689234070">สามเหลี่ยมซ่อนเนื้อหา</translation>
<translation id="7888071071722539607">โปรดใส่ "<ph name="ATSIGN" />" ในที่อยู่อีเมล "<ph name="INVALIDADDRESS" />" ขาด "<ph name="ATSIGN" />"</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">สารบัญ</translation>
<translation id="8613126697340063924">ควบคุมการเล่นระยะไกล</translation>
<translation id="862370744433916922">คำบรรยาย</translation>
-<translation id="8741316211671074806">การแสดงภาพซ้อนภาพ</translation>
<translation id="8750798805984357768">โปรดเลือกตัวเลือกอย่างหนึ่งอย่างใดเหล่านี้</translation>
<translation id="8785498733064193001">เริ่มเล่น</translation>
<translation id="8808573423886751634">บท</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">การนำทาง</translation>
<translation id="9050748414552849310">แสดงคำอธิบายภาพ</translation>
<translation id="9062295712474918030">เอกสาร</translation>
+<translation id="9093215626363556771">ออกจากการแสดงภาพซ้อนภาพ</translation>
<translation id="9108370397979208512">คณิตศาสตร์</translation>
<translation id="9132465097189459683">อื่นๆ...</translation>
<translation id="9138385573473225930">การแจ้งเตือน</translation>
<translation id="9155987714137265666"><ph name="WEEK" /> เริ่มวันที่ <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">การแสดงภาพซ้อนภาพ</translation>
<translation id="9168329111483466115">เชิงอรรถ</translation>
-<translation id="947831847158436616">เซลล์</translation>
+<translation id="954003015749068518">เข้าสู่การแสดงภาพซ้อนภาพ</translation>
<translation id="966787709310836684">เมนู</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_tr.xtb b/chromium/content/app/strings/translations/content_strings_tr.xtb
index 109fca3bd36..3f4ee0731a4 100644
--- a/chromium/content/app/strings/translations/content_strings_tr.xtb
+++ b/chromium/content/app/strings/translations/content_strings_tr.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">kaydırma çubuğu</translation>
<translation id="1211441953136645838">son not</translation>
<translation id="1281252709823657822">iletişim kutusu</translation>
+<translation id="1289247557029249093">Pencere içinde pencere modundan çık</translation>
<translation id="1335095011850992622">katkıda bulunanlar</translation>
<translation id="1342835525016946179">article</translation>
<translation id="1359897965706325498">banner</translation>
+<translation id="1548116112524424341">videoyu pencere içinde pencere modunda oynatın</translation>
<translation id="1589122976691792535">bölge</translation>
<translation id="1591562245178063882">Bu ay</translation>
<translation id="1637811476055996098">Dosyaları Seç</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">ağaç tablo</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">uzaktan cihazda oynat</translation>
+<translation id="190587075670221089">silme</translation>
<translation id="1907737156431278478">örnek</translation>
<translation id="1921819250265091946">gg</translation>
<translation id="1930711995431081526">durum</translation>
<translation id="1938124657309484470">Değer <ph name="MAXIMUM_DATE_OR_TIME" /> veya daha geri olmalıdır.</translation>
+<translation id="1946271899482435442">Tarih seçiciyi göster</translation>
<translation id="1993104285338243655">Yansıtmaya geçildi</translation>
<translation id="2060505056492490888">"<ph name="DOT" />", "<ph name="INVALIDDOMAIN" />" adı içinde yanlış bir konumda kullanılmış.</translation>
<translation id="2148716181193084225">Bugün</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Gönder</translation>
<translation id="2657045182931379222">grafik nesnesi</translation>
<translation id="2674318244760992338">altbilgi</translation>
+<translation id="2706474812903655270">Bu video pencere içinde pencere modunda oynatılıyor</translation>
<translation id="2709516037105925701">Otomatik doldurma</translation>
<translation id="2723001399770238859">ses</translation>
<translation id="2746543609216772311">Değer <ph name="MINIMUM_DATE_OR_TIME" /> veya daha ileri olmalıdır.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Sonraki ayı göster</translation>
<translation id="512758898067543763">satır başlığı</translation>
<translation id="5143125788380636750">son söz</translation>
-<translation id="5153163864850940242">Bu video Pencere İçinde Pencere modunda oynatılıyor</translation>
<translation id="5164977714490026579">Değer <ph name="MINIMUM" /> veya daha büyük olmalıdır.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Lütfen başına "<ph name="ATSIGN" />" ekleyin. "<ph name="INVALIDADDRESS" />" adresi eksik.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">künye</translation>
<translation id="6934078000481955284">blok alıntı</translation>
<translation id="6941933287844615239">medyayı indir</translation>
+<translation id="6981594929165378967">ekleme</translation>
<translation id="6989848892321993519">Lütfen bu metni <ph name="MIN_CHARACTERS" /> karakter veya daha fazla olacak şekilde uzatın (şu anda 1 karakter kullanıyorsunuz).</translation>
<translation id="709897737746224366">Lütfen istenen biçimi eşleştirin.</translation>
<translation id="7139483182332611405">önsöz</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">kalan süre</translation>
<translation id="7740016676195725605">altyazıların görüntülenmesini durdur</translation>
<translation id="7740050170769002709">HTML içeriği</translation>
+<translation id="7750228210027921155">Pencere içinde pencere</translation>
<translation id="7789962463072032349">duraklat</translation>
<translation id="7802800022689234070">açıklama üçgeni</translation>
<translation id="7888071071722539607">Lütfen e-posta adresine bir "<ph name="ATSIGN" />" işareti ekleyin. "<ph name="INVALIDADDRESS" />" adresinde "<ph name="ATSIGN" />" eksik.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">içindekiler</translation>
<translation id="8613126697340063924">uzaktan oynatmayı kontrol et</translation>
<translation id="862370744433916922">alt başlık</translation>
-<translation id="8741316211671074806">Pencere İçinde Pencere</translation>
<translation id="8750798805984357768">Lütfen bu seçeneklerden birini belirleyin.</translation>
<translation id="8785498733064193001">oynatmayı başlat</translation>
<translation id="8808573423886751634">bölüm</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">gezinme</translation>
<translation id="9050748414552849310">alt yazıları göster</translation>
<translation id="9062295712474918030">doküman</translation>
+<translation id="9093215626363556771">pencere içinde pencere modundan çıkın</translation>
<translation id="9108370397979208512">math</translation>
<translation id="9132465097189459683">Diğer...</translation>
<translation id="9138385573473225930">uyarı</translation>
<translation id="9155987714137265666"><ph name="WEEK_START_DATE" /> tarihinde başlayan <ph name="WEEK" /></translation>
+<translation id="916607977885256133">Pencere içinde Pencere</translation>
<translation id="9168329111483466115">dipnot</translation>
-<translation id="947831847158436616">hücre</translation>
+<translation id="954003015749068518">pencere içinde pencere moduna gir</translation>
<translation id="966787709310836684">menü</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_uk.xtb b/chromium/content/app/strings/translations/content_strings_uk.xtb
index 1c2f2e07482..0b0bfbb02f5 100644
--- a/chromium/content/app/strings/translations/content_strings_uk.xtb
+++ b/chromium/content/app/strings/translations/content_strings_uk.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">повзунок</translation>
<translation id="1211441953136645838">кінцева виноска</translation>
<translation id="1281252709823657822">діалогове вікно</translation>
+<translation id="1289247557029249093">Вийти з режиму "картинка в картинці"</translation>
<translation id="1335095011850992622">подяки</translation>
<translation id="1342835525016946179">стаття</translation>
<translation id="1359897965706325498">банер</translation>
+<translation id="1548116112524424341">відтворювати відео в режимі "Картинка в картинці"</translation>
<translation id="1589122976691792535">регіон</translation>
<translation id="1591562245178063882">Цей місяць</translation>
<translation id="1637811476055996098">Вибрати файли</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">сітка дерева</translation>
<translation id="1822429046913737220">д.п./п.п.</translation>
<translation id="1832974991323546415">відтворити на віддаленому пристрої</translation>
+<translation id="190587075670221089">видалення</translation>
<translation id="1907737156431278478">приклад</translation>
<translation id="1921819250265091946">дд</translation>
<translation id="1930711995431081526">статус</translation>
<translation id="1938124657309484470">Має бути <ph name="MAXIMUM_DATE_OR_TIME" /> або раніша дата.</translation>
+<translation id="1946271899482435442">Показує засіб вибору дати</translation>
<translation id="1993104285338243655">Змінено на дзеркалювання</translation>
<translation id="2060505056492490888">Символ "<ph name="DOT" />" у "<ph name="INVALIDDOMAIN" />" використано неправильно.</translation>
<translation id="2148716181193084225">Сьогодні</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Надіслати</translation>
<translation id="2657045182931379222">графічний об’єкт</translation>
<translation id="2674318244760992338">нижній колонтитул</translation>
+<translation id="2706474812903655270">Це відео відтворюється в режимі "картинка в картинці"</translation>
<translation id="2709516037105925701">Автозаповнення</translation>
<translation id="2723001399770238859">аудіо</translation>
<translation id="2746543609216772311">Має бути <ph name="MINIMUM_DATE_OR_TIME" /> або пізніша дата.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Показати наступний місяць</translation>
<translation id="512758898067543763">заголовок рядка</translation>
<translation id="5143125788380636750">епілог</translation>
-<translation id="5153163864850940242">Це відео відтворюється в режимі "Картинка в картинці"</translation>
<translation id="5164977714490026579">Значення має бути більшим або дорівнювати <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> Пб</translation>
<translation id="5307600278924710095">Введіть частину електронної адреси до знака "<ph name="ATSIGN" />". Електронна адреса "<ph name="INVALIDADDRESS" />" неповна.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">емблема видавництва</translation>
<translation id="6934078000481955284">цитата</translation>
<translation id="6941933287844615239">завантажити медіафайл</translation>
+<translation id="6981594929165378967">вставлення</translation>
<translation id="6989848892321993519">У тексті має бути не менше стількох символів: <ph name="MIN_CHARACTERS" />. Наразі ви ввели 1 символ.</translation>
<translation id="709897737746224366">Виберіть потрібний формат.</translation>
<translation id="7139483182332611405">передмова</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">залишилось часу</translation>
<translation id="7740016676195725605">сховати приховані субтитри</translation>
<translation id="7740050170769002709">Вміст HTML</translation>
+<translation id="7750228210027921155">Картинка в картинці</translation>
<translation id="7789962463072032349">призупинити</translation>
<translation id="7802800022689234070">трикутник відкривання</translation>
<translation id="7888071071722539607">Електронна адреса має містити знак "<ph name="ATSIGN" />". В електронній адресі "<ph name="INVALIDADDRESS" />" знака "<ph name="ATSIGN" />" немає.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">зміст</translation>
<translation id="8613126697340063924">керувати віддаленим відтворенням</translation>
<translation id="862370744433916922">підзаголовок</translation>
-<translation id="8741316211671074806">Картинка в картинці</translation>
<translation id="8750798805984357768">Виберіть один із запропонованих варіантів.</translation>
<translation id="8785498733064193001">розпочати відтворення</translation>
<translation id="8808573423886751634">розділ</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">навігація</translation>
<translation id="9050748414552849310">показати приховані субтитри</translation>
<translation id="9062295712474918030">документ</translation>
+<translation id="9093215626363556771">вийти з режиму "Картинка в картинці"</translation>
<translation id="9108370397979208512">математика</translation>
<translation id="9132465097189459683">Інші...</translation>
<translation id="9138385573473225930">сповіщення</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, починається <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Картинка в картинці</translation>
<translation id="9168329111483466115">виноска</translation>
-<translation id="947831847158436616">клітинка</translation>
+<translation id="954003015749068518">увімкнути режим "Картинка в картинці"</translation>
<translation id="966787709310836684">меню</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/app/strings/translations/content_strings_vi.xtb b/chromium/content/app/strings/translations/content_strings_vi.xtb
index 92c65db3683..b3129498b79 100644
--- a/chromium/content/app/strings/translations/content_strings_vi.xtb
+++ b/chromium/content/app/strings/translations/content_strings_vi.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">thanh trượt</translation>
<translation id="1211441953136645838">chú thích cuối</translation>
<translation id="1281252709823657822">hộp thoại</translation>
+<translation id="1289247557029249093">Thoát khỏi chế độ hình trong hình</translation>
<translation id="1335095011850992622">ghi nhận tác giả</translation>
<translation id="1342835525016946179">bài viết</translation>
<translation id="1359897965706325498">biểu ngữ</translation>
+<translation id="1548116112524424341">phát video ở chế độ hình trong hình</translation>
<translation id="1589122976691792535">khu vực</translation>
<translation id="1591562245178063882">Tháng này</translation>
<translation id="1637811476055996098">Chọn tệp</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">lưới dạng cây</translation>
<translation id="1822429046913737220">SA/CH</translation>
<translation id="1832974991323546415">phát trên thiết bị từ xa</translation>
+<translation id="190587075670221089">xóa</translation>
<translation id="1907737156431278478">ví dụ</translation>
<translation id="1921819250265091946">dd</translation>
<translation id="1930711995431081526">trạng thái</translation>
<translation id="1938124657309484470">Giá trị phải là <ph name="MAXIMUM_DATE_OR_TIME" /> hoặc sớm hơn.</translation>
+<translation id="1946271899482435442">Hiển thị bộ chọn ngày</translation>
<translation id="1993104285338243655">Đã chuyển sang chế độ phản chiếu</translation>
<translation id="2060505056492490888">'<ph name="DOT" />' bị sử dụng sai vị trí trong '<ph name="INVALIDDOMAIN" />'.</translation>
<translation id="2148716181193084225">Hôm nay</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">Gửi</translation>
<translation id="2657045182931379222">đối tượng đồ họa</translation>
<translation id="2674318244760992338">chân trang</translation>
+<translation id="2706474812903655270">Video này đang phát ở chế độ hình trong hình</translation>
<translation id="2709516037105925701">Tự động điền</translation>
<translation id="2723001399770238859">âm thanh</translation>
<translation id="2746543609216772311">Giá trị phải là <ph name="MINIMUM_DATE_OR_TIME" /> hoặc muộn hơn.</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">Hiển thị tháng tiếp theo</translation>
<translation id="512758898067543763">tiêu đề hàng</translation>
<translation id="5143125788380636750">lời kết</translation>
-<translation id="5153163864850940242">Video này đang phát ở chế độ Hình trong hình</translation>
<translation id="5164977714490026579">Giá trị phải lớn hơn hoặc bằng <ph name="MINIMUM" />.</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">Vui lòng nhập phần đứng trước '<ph name="ATSIGN" />'. '<ph name="INVALIDADDRESS" />' không hoàn chỉnh.</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">lời ghi cuối sách</translation>
<translation id="6934078000481955284">khung trích dẫn</translation>
<translation id="6941933287844615239">tải xuống phương tiện</translation>
+<translation id="6981594929165378967">chèn</translation>
<translation id="6989848892321993519">Vui lòng kéo dài văn bản này thành <ph name="MIN_CHARACTERS" /> ký tự trở lên (bạn hiện đang sử dụng 1 ký tự).</translation>
<translation id="709897737746224366">Vui lòng khớp với định dạng được yêu cầu.</translation>
<translation id="7139483182332611405">lời nói đầu</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">thời gian còn lại</translation>
<translation id="7740016676195725605">ngừng hiển thị phụ đề chi tiết</translation>
<translation id="7740050170769002709">Nội dung HTML</translation>
+<translation id="7750228210027921155">Hình trong hình</translation>
<translation id="7789962463072032349">tạm dừng</translation>
<translation id="7802800022689234070">tam giác hiển thị</translation>
<translation id="7888071071722539607">Vui lòng bao gồm '<ph name="ATSIGN" />' trong địa chỉ email. '<ph name="INVALIDADDRESS" />' bị thiếu '<ph name="ATSIGN" />'.</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">mục lục</translation>
<translation id="8613126697340063924">điều khiển phát lại từ xa</translation>
<translation id="862370744433916922">phụ đề</translation>
-<translation id="8741316211671074806">Chế độ hình trong hình</translation>
<translation id="8750798805984357768">Vui lòng chọn một trong các tùy chọn sau.</translation>
<translation id="8785498733064193001">bắt đầu phát lại</translation>
<translation id="8808573423886751634">chương</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">điều hướng</translation>
<translation id="9050748414552849310">hiển thị phụ đề chi tiết</translation>
<translation id="9062295712474918030">tài liệu</translation>
+<translation id="9093215626363556771">thoát chế độ hình trong hình</translation>
<translation id="9108370397979208512">toán học</translation>
<translation id="9132465097189459683">Khác...</translation>
<translation id="9138385573473225930">thông báo</translation>
<translation id="9155987714137265666"><ph name="WEEK" />, bắt đầu vào <ph name="WEEK_START_DATE" /></translation>
+<translation id="916607977885256133">Ảnh trong ảnh</translation>
<translation id="9168329111483466115">chú thích cuối trang</translation>
-<translation id="947831847158436616">ô</translation>
+<translation id="954003015749068518">vào chế độ hình trong hình</translation>
<translation id="966787709310836684">menu</translation>
</translationbundle> \ No newline at end of file
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 d6d7b75efc6..1cee8ea1c59 100644
--- a/chromium/content/app/strings/translations/content_strings_zh-CN.xtb
+++ b/chromium/content/app/strings/translations/content_strings_zh-CN.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">滑块</translation>
<translation id="1211441953136645838">尾注</translation>
<translation id="1281252709823657822">对话框</translation>
+<translation id="1289247557029249093">退出“画中画”模式</translation>
<translation id="1335095011850992622">参与者名单</translation>
<translation id="1342835525016946179">文章标记</translation>
<translation id="1359897965706325498">横幅</translation>
+<translation id="1548116112524424341">在“画中画”模式中播放视频</translation>
<translation id="1589122976691792535">区域</translation>
<translation id="1591562245178063882">本月</translation>
<translation id="1637811476055996098">选择文件</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">树状网格</translation>
<translation id="1822429046913737220">上午/下午</translation>
<translation id="1832974991323546415">在远程设备上播放</translation>
+<translation id="190587075670221089">删除</translation>
<translation id="1907737156431278478">示例</translation>
<translation id="1921819250265091946">日</translation>
<translation id="1930711995431081526">状态</translation>
<translation id="1938124657309484470">指定的值不得晚于<ph name="MAXIMUM_DATE_OR_TIME" />。</translation>
+<translation id="1946271899482435442">显示日期选择器</translation>
<translation id="1993104285338243655">已切换到镜像</translation>
<translation id="2060505056492490888">“<ph name="INVALIDDOMAIN" />”中“<ph name="DOT" />”的位置不正确。</translation>
<translation id="2148716181193084225">今天</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">提交</translation>
<translation id="2657045182931379222">图形对象</translation>
<translation id="2674318244760992338">页脚</translation>
+<translation id="2706474812903655270">此视频正在“画中画”模式中播放</translation>
<translation id="2709516037105925701">自动填充</translation>
<translation id="2723001399770238859">音频</translation>
<translation id="2746543609216772311">指定的值不得早于<ph name="MINIMUM_DATE_OR_TIME" />。</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">显示下一个月</translation>
<translation id="512758898067543763">行标题</translation>
<translation id="5143125788380636750">结语</translation>
-<translation id="5153163864850940242">此视频正在“画中画”模式中播放</translation>
<translation id="5164977714490026579">值必须大于或等于 <ph name="MINIMUM" />。</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">请在“<ph name="ATSIGN" />”前面输入内容。“<ph name="INVALIDADDRESS" />”不完整。</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">版权页</translation>
<translation id="6934078000481955284">引用标记</translation>
<translation id="6941933287844615239">下载媒体</translation>
+<translation id="6981594929165378967">插入</translation>
<translation id="6989848892321993519">请将该内容增加到 <ph name="MIN_CHARACTERS" /> 个或更多字符(目前您使用了 1 个字符)。</translation>
<translation id="709897737746224366">请与所请求的格式保持一致。</translation>
<translation id="7139483182332611405">序言</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">剩余时间</translation>
<translation id="7740016676195725605">停止显示可选字幕</translation>
<translation id="7740050170769002709">HTML 内容</translation>
+<translation id="7750228210027921155">画中画</translation>
<translation id="7789962463072032349">暂停</translation>
<translation id="7802800022689234070">开合三角标记</translation>
<translation id="7888071071722539607">请在电子邮件地址中包括“<ph name="ATSIGN" />”。“<ph name="INVALIDADDRESS" />”中缺少“<ph name="ATSIGN" />”。</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">目录</translation>
<translation id="8613126697340063924">控制远程播放</translation>
<translation id="862370744433916922">副标题</translation>
-<translation id="8741316211671074806">画中画</translation>
<translation id="8750798805984357768">请从这些选项中选择一个。</translation>
<translation id="8785498733064193001">开始播放</translation>
<translation id="8808573423886751634">章节</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">导航</translation>
<translation id="9050748414552849310">显示可选字幕</translation>
<translation id="9062295712474918030">文档</translation>
+<translation id="9093215626363556771">退出“画中画”模式</translation>
<translation id="9108370397979208512">数学</translation>
<translation id="9132465097189459683">其他...</translation>
<translation id="9138385573473225930">提醒</translation>
<translation id="9155987714137265666"><ph name="WEEK" />,从 <ph name="WEEK_START_DATE" />开始</translation>
+<translation id="916607977885256133">画中画</translation>
<translation id="9168329111483466115">脚注</translation>
-<translation id="947831847158436616">单元格</translation>
+<translation id="954003015749068518">进入“画中画”模式</translation>
<translation id="966787709310836684">菜单</translation>
</translationbundle> \ No newline at end of file
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 06fcccba466..0f1c53576b2 100644
--- a/chromium/content/app/strings/translations/content_strings_zh-TW.xtb
+++ b/chromium/content/app/strings/translations/content_strings_zh-TW.xtb
@@ -12,9 +12,11 @@
<translation id="1206693055195146388">滑桿</translation>
<translation id="1211441953136645838">章節附註</translation>
<translation id="1281252709823657822">對話方塊</translation>
+<translation id="1289247557029249093">離開子母畫面模式</translation>
<translation id="1335095011850992622">參與名單</translation>
<translation id="1342835525016946179">文章</translation>
<translation id="1359897965706325498">橫幅</translation>
+<translation id="1548116112524424341">在子母畫面模式中播放影片</translation>
<translation id="1589122976691792535">區域</translation>
<translation id="1591562245178063882">本月</translation>
<translation id="1637811476055996098">選擇檔案</translation>
@@ -25,10 +27,12 @@
<translation id="1821985195704844674">樹狀目錄網格</translation>
<translation id="1822429046913737220">AM/PM</translation>
<translation id="1832974991323546415">在遠端裝置上播放</translation>
+<translation id="190587075670221089">刪除</translation>
<translation id="1907737156431278478">範例</translation>
<translation id="1921819250265091946">日</translation>
<translation id="1930711995431081526">狀態</translation>
<translation id="1938124657309484470">必須輸入 <ph name="MAXIMUM_DATE_OR_TIME" /> 或之前的值。</translation>
+<translation id="1946271899482435442">顯示日期選擇器</translation>
<translation id="1993104285338243655">已切換至鏡像模式</translation>
<translation id="2060505056492490888">「<ph name="DOT" />」未放在「<ph name="INVALIDDOMAIN" />」的正確位置。</translation>
<translation id="2148716181193084225">今天</translation>
@@ -48,6 +52,7 @@
<translation id="2653659639078652383">提交</translation>
<translation id="2657045182931379222">圖形物件</translation>
<translation id="2674318244760992338">頁尾</translation>
+<translation id="2706474812903655270">目前在子母畫面模式中播放這部影片</translation>
<translation id="2709516037105925701">自動填入</translation>
<translation id="2723001399770238859">音訊</translation>
<translation id="2746543609216772311">必須輸入 <ph name="MINIMUM_DATE_OR_TIME" /> 或之後的值。</translation>
@@ -111,7 +116,6 @@
<translation id="5117590920725113268">顯示下一個月</translation>
<translation id="512758898067543763">列標題</translation>
<translation id="5143125788380636750">結尾</translation>
-<translation id="5153163864850940242">目前在子母畫面模式中播放這部影片</translation>
<translation id="5164977714490026579">值必須大於或等於 <ph name="MINIMUM" />。</translation>
<translation id="520299402983819650"><ph name="QUANTITY" /> PB</translation>
<translation id="5307600278924710095">請輸入「<ph name="ATSIGN" />」後面的部分。「<ph name="INVALIDADDRESS" />」不是完整值。</translation>
@@ -165,6 +169,7 @@
<translation id="689129560213475294">版權頁標記</translation>
<translation id="6934078000481955284">引用標記</translation>
<translation id="6941933287844615239">下載媒體</translation>
+<translation id="6981594929165378967">插入</translation>
<translation id="6989848892321993519">請將這段文字加長到 <ph name="MIN_CHARACTERS" /> 個字元以上 (目前已有 1 個字元)。</translation>
<translation id="709897737746224366">請符合要求的格式。</translation>
<translation id="7139483182332611405">前言</translation>
@@ -186,6 +191,7 @@
<translation id="7720026100085573005">剩餘時間</translation>
<translation id="7740016676195725605">停止顯示字幕</translation>
<translation id="7740050170769002709">HTML 內容</translation>
+<translation id="7750228210027921155">子母畫面</translation>
<translation id="7789962463072032349">暫停</translation>
<translation id="7802800022689234070">顯示/隱藏三角標記</translation>
<translation id="7888071071722539607">請在電子郵件地址中包含「<ph name="ATSIGN" />」。「<ph name="INVALIDADDRESS" />」未包含「<ph name="ATSIGN" />」。</translation>
@@ -215,7 +221,6 @@
<translation id="860475260694818407">目錄</translation>
<translation id="8613126697340063924">控制遠端播放</translation>
<translation id="862370744433916922">副標題</translation>
-<translation id="8741316211671074806">子母畫面</translation>
<translation id="8750798805984357768">請選取其中一個選項。</translation>
<translation id="8785498733064193001">開始播放</translation>
<translation id="8808573423886751634">章節</translation>
@@ -228,11 +233,13 @@
<translation id="9048119486235211610">導覽</translation>
<translation id="9050748414552849310">顯示字幕</translation>
<translation id="9062295712474918030">文件</translation>
+<translation id="9093215626363556771">離開子母畫面</translation>
<translation id="9108370397979208512">數學</translation>
<translation id="9132465097189459683">其他...</translation>
<translation id="9138385573473225930">警示</translation>
<translation id="9155987714137265666"><ph name="WEEK" />,從 <ph name="WEEK_START_DATE" />開始</translation>
+<translation id="916607977885256133">子母畫面</translation>
<translation id="9168329111483466115">註腳</translation>
-<translation id="947831847158436616">儲存格</translation>
+<translation id="954003015749068518">進入子母畫面</translation>
<translation id="966787709310836684">選單</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/content/browser/BUILD.gn b/chromium/content/browser/BUILD.gn
index 5747496dc5f..abaa573b8f1 100644
--- a/chromium/content/browser/BUILD.gn
+++ b/chromium/content/browser/BUILD.gn
@@ -39,11 +39,12 @@ jumbo_source_set("browser") {
"//base/third_party/dynamic_annotations",
"//cc",
"//cc/animation",
+ "//cc/mojo_embedder",
"//cc/paint",
"//components/cbor",
"//components/discardable_memory/common",
"//components/discardable_memory/service",
- "//components/download/downloader/in_progress",
+ "//components/download/database",
"//components/download/public/common:public",
"//components/download/quarantine",
"//components/filename_generation",
@@ -84,17 +85,17 @@ jumbo_source_set("browser") {
"//content/common:mojo_bindings",
"//content/public/common:common_sources",
"//crypto",
+ "//device/base",
"//device/bluetooth",
"//device/fido",
"//device/gamepad",
- "//device/geolocation/public/cpp",
"//device/vr/public/mojom",
"//google_apis",
"//gpu",
"//gpu/command_buffer/client:gles2_implementation",
"//gpu/command_buffer/client:gles2_interface",
"//gpu/command_buffer/client:raster_interface",
- "//gpu/ipc/common:gpu_preferences_util",
+ "//gpu/ipc:gl_in_process_context",
"//gpu/ipc/host",
"//gpu/vulkan:buildflags",
"//jingle:jingle_glue",
@@ -108,12 +109,14 @@ jumbo_source_set("browser") {
"//media/mojo/interfaces",
"//media/mojo/interfaces:constants",
"//media/mojo/services",
- "//mojo/edk",
+ "//mojo/core/embedder",
"//mojo/public/cpp/bindings",
+ "//mojo/public/cpp/platform",
+ "//mojo/public/cpp/system",
"//mojo/public/js:resources",
"//net",
"//net:extras",
- "//net:http_server",
+ "//net/server:http_server",
"//ppapi/buildflags",
"//printing/buildflags",
"//services/audio:lib",
@@ -122,10 +125,13 @@ jumbo_source_set("browser") {
"//services/catalog:constants",
"//services/catalog/public/cpp",
"//services/catalog/public/mojom:constants",
+ "//services/content:impl",
+ "//services/content/public/mojom",
"//services/data_decoder/public/cpp",
"//services/data_decoder/public/mojom",
"//services/device:lib",
"//services/device/public/cpp:device_features",
+ "//services/device/public/cpp/geolocation",
"//services/device/public/mojom",
"//services/device/public/mojom:generic_sensor",
"//services/file:lib",
@@ -310,8 +316,6 @@ jumbo_source_set("browser") {
"android/content_protocol_handler_impl.h",
"android/content_startup_flags.cc",
"android/content_startup_flags.h",
- "android/content_video_view.cc",
- "android/content_video_view.h",
"android/devtools_auth.cc",
"android/dialog_overlay_impl.cc",
"android/dialog_overlay_impl.h",
@@ -435,10 +439,10 @@ jumbo_source_set("browser") {
"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_initialization_data_task.cc",
+ "background_fetch/storage/get_initialization_data_task.h",
"background_fetch/storage/get_metadata_task.cc",
"background_fetch/storage/get_metadata_task.h",
- "background_fetch/storage/get_num_requests_task.cc",
- "background_fetch/storage/get_num_requests_task.h",
"background_fetch/storage/get_settled_fetches_task.cc",
"background_fetch/storage/get_settled_fetches_task.h",
"background_fetch/storage/mark_registration_for_deletion_task.cc",
@@ -472,8 +476,6 @@ jumbo_source_set("browser") {
"blob_storage/blob_internals_url_loader.h",
"blob_storage/blob_registry_wrapper.cc",
"blob_storage/blob_registry_wrapper.h",
- "blob_storage/blob_url_loader_factory.cc",
- "blob_storage/blob_url_loader_factory.h",
"blob_storage/chrome_blob_storage_context.cc",
"blob_storage/chrome_blob_storage_context.h",
"bluetooth/bluetooth_allowed_devices.cc",
@@ -571,12 +573,18 @@ jumbo_source_set("browser") {
"cocoa/system_hotkey_helper_mac.mm",
"cocoa/system_hotkey_map.h",
"cocoa/system_hotkey_map.mm",
+ "code_cache/generated_code_cache.cc",
+ "code_cache/generated_code_cache.h",
+ "startup_data_impl.cc",
+ "startup_data_impl.h",
# NOTE: These files are here instead of in compositor_browser_sources
# because the latter is not built on Android, whereas these files are
# needed on all platforms.
"compositor/surface_utils.cc",
"compositor/surface_utils.h",
+ "content_service_delegate_impl.cc",
+ "content_service_delegate_impl.h",
"cookie_store/cookie_change_subscription.cc",
"cookie_store/cookie_change_subscription.h",
"cookie_store/cookie_store_context.cc",
@@ -684,7 +692,12 @@ jumbo_source_set("browser") {
"devtools/shared_worker_devtools_agent_host.h",
"devtools/shared_worker_devtools_manager.cc",
"devtools/shared_worker_devtools_manager.h",
+ "devtools/target_registry.cc",
+ "devtools/target_registry.h",
"discardable_shared_memory_manager.cc",
+ "display_cutout/display_cutout_constants.h",
+ "display_cutout/display_cutout_host_impl.cc",
+ "display_cutout/display_cutout_host_impl.h",
"dom_storage/dom_storage_area.cc",
"dom_storage/dom_storage_area.h",
"dom_storage/dom_storage_context_impl.cc",
@@ -704,6 +717,8 @@ jumbo_source_set("browser") {
"dom_storage/dom_storage_task_runner.h",
"dom_storage/local_storage_context_mojo.cc",
"dom_storage/local_storage_context_mojo.h",
+ "dom_storage/session_storage_area_impl.cc",
+ "dom_storage/session_storage_area_impl.h",
"dom_storage/session_storage_context_mojo.cc",
"dom_storage/session_storage_context_mojo.h",
"dom_storage/session_storage_data_map.cc",
@@ -712,16 +727,14 @@ jumbo_source_set("browser") {
"dom_storage/session_storage_database.h",
"dom_storage/session_storage_database_adapter.cc",
"dom_storage/session_storage_database_adapter.h",
- "dom_storage/session_storage_leveldb_wrapper.cc",
- "dom_storage/session_storage_leveldb_wrapper.h",
"dom_storage/session_storage_metadata.cc",
"dom_storage/session_storage_metadata.h",
"dom_storage/session_storage_namespace_impl.cc",
"dom_storage/session_storage_namespace_impl.h",
"dom_storage/session_storage_namespace_impl_mojo.cc",
"dom_storage/session_storage_namespace_impl_mojo.h",
- "download/blob_download_url_loader_factory_getter.cc",
- "download/blob_download_url_loader_factory_getter.h",
+ "dom_storage/storage_area_impl.cc",
+ "dom_storage/storage_area_impl.h",
"download/byte_stream_input_stream.cc",
"download/byte_stream_input_stream.h",
"download/download_item_utils.cc",
@@ -742,6 +755,8 @@ jumbo_source_set("browser") {
"download/drag_download_file.h",
"download/drag_download_util.cc",
"download/drag_download_util.h",
+ "download/file_download_url_loader_factory_getter.cc",
+ "download/file_download_url_loader_factory_getter.h",
"download/mhtml_extra_parts_impl.cc",
"download/mhtml_extra_parts_impl.h",
"download/mhtml_generation_manager.cc",
@@ -762,6 +777,8 @@ jumbo_source_set("browser") {
"download/url_downloader.h",
"download/url_downloader_factory.cc",
"download/url_downloader_factory.h",
+ "download/web_ui_download_url_loader_factory_getter.cc",
+ "download/web_ui_download_url_loader_factory_getter.h",
"field_trial_recorder.cc",
"field_trial_recorder.h",
"file_url_loader_factory.cc",
@@ -824,6 +841,8 @@ jumbo_source_set("browser") {
"frame_host/navigator_delegate.h",
"frame_host/navigator_impl.cc",
"frame_host/navigator_impl.h",
+ "frame_host/origin_policy_throttle.cc",
+ "frame_host/origin_policy_throttle.h",
"frame_host/popup_menu_helper_mac.h",
"frame_host/popup_menu_helper_mac.mm",
"frame_host/render_frame_host_delegate.cc",
@@ -968,16 +987,14 @@ jumbo_source_set("browser") {
"keyboard_lock/keyboard_lock_metrics.h",
"keyboard_lock/keyboard_lock_service_impl.cc",
"keyboard_lock/keyboard_lock_service_impl.h",
- "leveldb_wrapper_impl.cc",
- "leveldb_wrapper_impl.h",
"loader/cross_site_document_resource_handler.cc",
"loader/cross_site_document_resource_handler.h",
"loader/data_pipe_to_source_stream.cc",
"loader/data_pipe_to_source_stream.h",
"loader/detachable_resource_handler.cc",
"loader/detachable_resource_handler.h",
- "loader/downloaded_temp_file_impl.cc",
- "loader/downloaded_temp_file_impl.h",
+ "loader/download_utils_impl.cc",
+ "loader/download_utils_impl.h",
"loader/global_routing_id.h",
"loader/intercepting_resource_handler.cc",
"loader/intercepting_resource_handler.h",
@@ -994,8 +1011,6 @@ jumbo_source_set("browser") {
"loader/mojo_async_resource_handler.h",
"loader/navigation_loader_interceptor.cc",
"loader/navigation_loader_interceptor.h",
- "loader/navigation_loader_util.cc",
- "loader/navigation_loader_util.h",
"loader/navigation_url_loader.cc",
"loader/navigation_url_loader.h",
"loader/navigation_url_loader_delegate.h",
@@ -1008,10 +1023,6 @@ jumbo_source_set("browser") {
"loader/prefetch_url_loader.h",
"loader/prefetch_url_loader_service.cc",
"loader/prefetch_url_loader_service.h",
- "loader/redirect_to_file_resource_handler.cc",
- "loader/redirect_to_file_resource_handler.h",
- "loader/resource_buffer.cc",
- "loader/resource_buffer.h",
"loader/resource_controller.h",
"loader/resource_dispatcher_host_impl.cc",
"loader/resource_dispatcher_host_impl.h",
@@ -1035,16 +1046,12 @@ jumbo_source_set("browser") {
"loader/stream_resource_handler.h",
"loader/stream_writer.cc",
"loader/stream_writer.h",
- "loader/temporary_file_stream.cc",
- "loader/temporary_file_stream.h",
"loader/throttling_resource_handler.cc",
"loader/throttling_resource_handler.h",
"loader/upload_data_stream_builder.cc",
"loader/upload_data_stream_builder.h",
"loader/url_loader_factory_impl.cc",
"loader/url_loader_factory_impl.h",
- "loader/wake_lock_resource_throttle.cc",
- "loader/wake_lock_resource_throttle.h",
"loader_delegate_impl.cc",
"loader_delegate_impl.h",
"locks/lock_manager.cc",
@@ -1052,13 +1059,10 @@ jumbo_source_set("browser") {
"mach_broker_mac.h",
"mach_broker_mac.mm",
"manifest/manifest_icon_downloader.cc",
- "manifest/manifest_icon_selector.cc",
"manifest/manifest_manager_host.cc",
"manifest/manifest_manager_host.h",
"media/android/browser_media_player_manager.cc",
"media/android/browser_media_player_manager.h",
- "media/android/browser_surface_view_manager.cc",
- "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",
@@ -1071,6 +1075,8 @@ jumbo_source_set("browser") {
"media/audible_metrics.h",
"media/audio_input_stream_broker.cc",
"media/audio_input_stream_broker.h",
+ "media/audio_log_factory.cc",
+ "media/audio_log_factory.h",
"media/audio_loopback_stream_broker.cc",
"media/audio_loopback_stream_broker.h",
"media/audio_muting_session.cc",
@@ -1115,8 +1121,6 @@ jumbo_source_set("browser") {
"media/media_web_contents_observer.h",
"media/midi_host.cc",
"media/midi_host.h",
- "media/mojo_audio_logging_adapter.cc",
- "media/mojo_audio_logging_adapter.h",
"media/session/audio_focus_delegate.h",
"media/session/audio_focus_delegate_android.cc",
"media/session/audio_focus_delegate_android.h",
@@ -1191,8 +1195,6 @@ jumbo_source_set("browser") {
"notifications/notification_id_generator.h",
"notifications/platform_notification_context_impl.cc",
"notifications/platform_notification_context_impl.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",
@@ -1207,6 +1209,8 @@ jumbo_source_set("browser") {
"payments/payment_instrument_icon_fetcher.h",
"payments/payment_manager.cc",
"payments/payment_manager.h",
+ "permissions/permission_controller_impl.cc",
+ "permissions/permission_controller_impl.h",
"permissions/permission_service_context.cc",
"permissions/permission_service_context.h",
"permissions/permission_service_impl.cc",
@@ -1247,8 +1251,6 @@ jumbo_source_set("browser") {
"renderer_host/event_with_latency_info.h",
"renderer_host/file_utilities_host_impl.cc",
"renderer_host/file_utilities_host_impl.h",
- "renderer_host/font_utils_linux.cc",
- "renderer_host/font_utils_linux.h",
"renderer_host/frame_connector_delegate.cc",
"renderer_host/frame_connector_delegate.h",
"renderer_host/frame_metadata_util.cc",
@@ -1261,6 +1263,7 @@ jumbo_source_set("browser") {
"renderer_host/input/fling_controller.h",
"renderer_host/input/fling_scheduler.cc",
"renderer_host/input/fling_scheduler.h",
+ "renderer_host/input/fling_scheduler_base.h",
"renderer_host/input/fling_scheduler_mac.h",
"renderer_host/input/fling_scheduler_mac.mm",
"renderer_host/input/gesture_event_queue.cc",
@@ -1340,6 +1343,8 @@ jumbo_source_set("browser") {
"renderer_host/input/touch_selection_controller_client_child_frame.h",
"renderer_host/input/touch_timeout_handler.cc",
"renderer_host/input/touch_timeout_handler.h",
+ "renderer_host/input/touchpad_pinch_event_queue.cc",
+ "renderer_host/input/touchpad_pinch_event_queue.h",
"renderer_host/input/touchpad_tap_suppression_controller.cc",
"renderer_host/input/touchpad_tap_suppression_controller.h",
"renderer_host/input/touchscreen_tap_suppression_controller.cc",
@@ -1407,11 +1412,11 @@ jumbo_source_set("browser") {
"renderer_host/media/video_capture_controller.cc",
"renderer_host/media/video_capture_controller.h",
"renderer_host/media/video_capture_controller_event_handler.h",
+ "renderer_host/media/video_capture_dependencies.cc",
+ "renderer_host/media/video_capture_dependencies.h",
"renderer_host/media/video_capture_device_launch_observer.h",
"renderer_host/media/video_capture_factory_delegate.cc",
"renderer_host/media/video_capture_factory_delegate.h",
- "renderer_host/media/video_capture_gpu_jpeg_decoder.cc",
- "renderer_host/media/video_capture_gpu_jpeg_decoder.h",
"renderer_host/media/video_capture_host.cc",
"renderer_host/media/video_capture_host.h",
"renderer_host/media/video_capture_manager.cc",
@@ -1548,8 +1553,6 @@ jumbo_source_set("browser") {
"service_worker/service_worker_dispatcher_host.h",
"service_worker/service_worker_fetch_dispatcher.cc",
"service_worker/service_worker_fetch_dispatcher.h",
- "service_worker/service_worker_handle.cc",
- "service_worker/service_worker_handle.h",
"service_worker/service_worker_info.cc",
"service_worker/service_worker_info.h",
"service_worker/service_worker_installed_script_loader.cc",
@@ -1574,6 +1577,10 @@ jumbo_source_set("browser") {
"service_worker/service_worker_navigation_loader.h",
"service_worker/service_worker_new_script_loader.cc",
"service_worker/service_worker_new_script_loader.h",
+ "service_worker/service_worker_object_host.cc",
+ "service_worker/service_worker_object_host.h",
+ "service_worker/service_worker_ping_controller.cc",
+ "service_worker/service_worker_ping_controller.h",
"service_worker/service_worker_process_manager.cc",
"service_worker/service_worker_process_manager.h",
"service_worker/service_worker_provider_host.cc",
@@ -1728,12 +1735,22 @@ jumbo_source_set("browser") {
"web_package/signed_exchange_consts.h",
"web_package/signed_exchange_devtools_proxy.cc",
"web_package/signed_exchange_devtools_proxy.h",
+ "web_package/signed_exchange_envelope.cc",
+ "web_package/signed_exchange_envelope.h",
+ "web_package/signed_exchange_error.cc",
+ "web_package/signed_exchange_error.h",
"web_package/signed_exchange_handler.cc",
"web_package/signed_exchange_handler.h",
- "web_package/signed_exchange_header.cc",
- "web_package/signed_exchange_header.h",
- "web_package/signed_exchange_header_parser.cc",
- "web_package/signed_exchange_header_parser.h",
+ "web_package/signed_exchange_loader.cc",
+ "web_package/signed_exchange_loader.h",
+ "web_package/signed_exchange_prefetch_handler.cc",
+ "web_package/signed_exchange_prefetch_handler.h",
+ "web_package/signed_exchange_prologue.cc",
+ "web_package/signed_exchange_prologue.h",
+ "web_package/signed_exchange_request_handler.cc",
+ "web_package/signed_exchange_request_handler.h",
+ "web_package/signed_exchange_signature_header_field.cc",
+ "web_package/signed_exchange_signature_header_field.h",
"web_package/signed_exchange_signature_verifier.cc",
"web_package/signed_exchange_signature_verifier.h",
"web_package/signed_exchange_url_loader_factory_for_non_network_service.cc",
@@ -1742,12 +1759,6 @@ jumbo_source_set("browser") {
"web_package/signed_exchange_utils.h",
"web_package/web_package_context_impl.cc",
"web_package/web_package_context_impl.h",
- "web_package/web_package_loader.cc",
- "web_package/web_package_loader.h",
- "web_package/web_package_prefetch_handler.cc",
- "web_package/web_package_prefetch_handler.h",
- "web_package/web_package_request_handler.cc",
- "web_package/web_package_request_handler.h",
"webrtc/webrtc_internals.cc",
"webrtc/webrtc_internals.h",
"webrtc/webrtc_internals_message_handler.cc",
@@ -1789,7 +1800,11 @@ jumbo_source_set("browser") {
}
if (is_linux) {
- deps += [ "//services/service_manager/zygote" ]
+ deps += [
+ "//components/services/font:lib",
+ "//components/services/font/public/interfaces",
+ "//services/service_manager/zygote",
+ ]
}
# ChromeOS also defines linux but their memory-monitors conflict.
@@ -1842,6 +1857,14 @@ jumbo_source_set("browser") {
deps += [ "//printing" ]
}
+ if (is_mac) {
+ sources += [
+ "gpu/ca_transaction_gpu_coordinator.cc",
+ "gpu/ca_transaction_gpu_coordinator.h",
+ ]
+ deps += [ "//ui/events:dom_keyboard_layout" ]
+ }
+
if (!is_mac) {
deps += [ "//sandbox" ]
}
@@ -1868,8 +1891,6 @@ jumbo_source_set("browser") {
"media/capture/cursor_renderer.h",
"media/capture/desktop_capture_device.cc",
"media/capture/desktop_capture_device.h",
- "media/capture/fake_webcontent_capture_machine.cc",
- "media/capture/fake_webcontent_capture_machine.h",
"media/capture/frame_sink_video_capture_device.cc",
"media/capture/frame_sink_video_capture_device.h",
"media/capture/web_contents_video_capture_device.cc",
@@ -1879,14 +1900,10 @@ jumbo_source_set("browser") {
deps += [ "//third_party/webrtc/modules/desktop_capture" ]
if (use_aura) {
sources += [
- "media/capture/aura_window_capture_machine.cc",
- "media/capture/aura_window_capture_machine.h",
"media/capture/aura_window_video_capture_device.cc",
"media/capture/aura_window_video_capture_device.h",
"media/capture/cursor_renderer_aura.cc",
"media/capture/cursor_renderer_aura.h",
- "media/capture/desktop_capture_device_aura.cc",
- "media/capture/desktop_capture_device_aura.h",
]
}
if (is_chromeos) {
@@ -1998,12 +2015,10 @@ jumbo_source_set("browser") {
"renderer_host/pepper/pepper_tcp_socket_message_filter.cc",
"renderer_host/pepper/pepper_tcp_socket_message_filter.h",
"renderer_host/pepper/pepper_truetype_font.h",
- "renderer_host/pepper/pepper_truetype_font_android.cc",
"renderer_host/pepper/pepper_truetype_font_host.cc",
"renderer_host/pepper/pepper_truetype_font_host.h",
"renderer_host/pepper/pepper_truetype_font_linux.cc",
"renderer_host/pepper/pepper_truetype_font_list.h",
- "renderer_host/pepper/pepper_truetype_font_list_android.cc",
"renderer_host/pepper/pepper_truetype_font_list_host.cc",
"renderer_host/pepper/pepper_truetype_font_list_host.h",
"renderer_host/pepper/pepper_truetype_font_list_mac.mm",
@@ -2018,6 +2033,8 @@ jumbo_source_set("browser") {
"renderer_host/pepper/quota_reservation.h",
"renderer_host/pepper/ssl_context_helper.cc",
"renderer_host/pepper/ssl_context_helper.h",
+ "renderer_host/plugin_registry_impl.cc",
+ "renderer_host/plugin_registry_impl.h",
]
deps += [
"//ppapi/host",
@@ -2031,6 +2048,9 @@ jumbo_source_set("browser") {
if (use_pangocairo) {
sources += [ "renderer_host/pepper/pepper_truetype_font_list_pango.cc" ]
}
+ if (is_linux) {
+ deps += [ "//components/services/font:ppapi_fontconfig_matching" ]
+ }
}
if (enable_library_cdms) {
@@ -2086,10 +2106,6 @@ jumbo_source_set("browser") {
"accessibility/web_contents_accessibility_android.h",
"android/content_ui_event_handler.cc",
"android/content_ui_event_handler.h",
- "android/content_view_core.cc",
- "android/content_view_core.h",
- "android/content_view_render_view.cc",
- "android/content_view_render_view.h",
"android/content_view_statics.cc",
"android/date_time_chooser_android.cc",
"android/date_time_chooser_android.h",
@@ -2144,14 +2160,14 @@ jumbo_source_set("browser") {
"android/tracing_controller_android.h",
"android/web_contents_observer_proxy.cc",
"android/web_contents_observer_proxy.h",
- "compositor/in_process_display_client.cc",
- "compositor/in_process_display_client.h",
"frame_host/render_frame_host_android.cc",
"frame_host/render_frame_host_android.h",
"media/capture/screen_capture_device_android.cc",
"media/capture/screen_capture_device_android.h",
"renderer_host/compositor_impl_android.cc",
"renderer_host/compositor_impl_android.h",
+ "renderer_host/input/fling_scheduler_android.cc",
+ "renderer_host/input/fling_scheduler_android.h",
"renderer_host/input/synthetic_gesture_target_android.cc",
"renderer_host/input/synthetic_gesture_target_android.h",
"renderer_host/input/touch_selection_controller_client_manager_android.cc",
@@ -2199,7 +2215,11 @@ jumbo_source_set("browser") {
"//ui/accessibility/mojom",
"//ui/android",
"//ui/compositor",
+ "//ui/compositor/host",
]
+ if (enable_vulkan) {
+ deps += [ "//gpu/vulkan/init" ]
+ }
defines += [
"APPCACHE_USE_SIMPLE_CACHE",
"ENABLE_SCREEN_CAPTURE=1",
@@ -2265,8 +2285,8 @@ jumbo_source_set("browser") {
sources += [
"renderer_host/popup_window_mac.h",
"renderer_host/popup_window_mac.mm",
- "renderer_host/render_widget_host_ns_view_bridge.h",
- "renderer_host/render_widget_host_ns_view_bridge.mm",
+ "renderer_host/render_widget_host_ns_view_bridge_local.h",
+ "renderer_host/render_widget_host_ns_view_bridge_local.mm",
"renderer_host/render_widget_host_ns_view_client.h",
"renderer_host/render_widget_host_view_cocoa.h",
"renderer_host/render_widget_host_view_cocoa.mm",
@@ -2325,8 +2345,6 @@ jumbo_source_set("browser") {
sources += [
"compositor/browser_compositor_output_surface.cc",
"compositor/browser_compositor_output_surface.h",
- "compositor/external_begin_frame_controller_client_impl.cc",
- "compositor/external_begin_frame_controller_client_impl.h",
"compositor/gpu_browser_compositor_output_surface.cc",
"compositor/gpu_browser_compositor_output_surface.h",
"compositor/gpu_output_surface_mac.cc",
@@ -2335,12 +2353,8 @@ jumbo_source_set("browser") {
"compositor/gpu_process_transport_factory.h",
"compositor/gpu_surfaceless_browser_compositor_output_surface.cc",
"compositor/gpu_surfaceless_browser_compositor_output_surface.h",
- "compositor/gpu_vsync_begin_frame_source.cc",
- "compositor/gpu_vsync_begin_frame_source.h",
"compositor/image_transport_factory.cc",
"compositor/image_transport_factory.h",
- "compositor/in_process_display_client.cc",
- "compositor/in_process_display_client.h",
"compositor/offscreen_browser_compositor_output_surface.cc",
"compositor/offscreen_browser_compositor_output_surface.h",
"compositor/owned_mailbox.cc",
@@ -2379,6 +2393,7 @@ jumbo_source_set("browser") {
deps += [
"//components/viz/service",
"//ui/compositor",
+ "//ui/compositor/host",
]
}
diff --git a/chromium/content/browser/DEPS b/chromium/content/browser/DEPS
index 59cc7c497cd..afd8cb019fb 100644
--- a/chromium/content/browser/DEPS
+++ b/chromium/content/browser/DEPS
@@ -3,11 +3,13 @@ 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/download/database",
"+components/download/public/common",
"+components/download/quarantine/quarantine.h",
"+components/filename_generation",
+ "+components/services/font",
"+components/services/filesystem",
+ "+components/services/font/ppapi_fontconfig_matching.h",
"+components/services/leveldb",
"+components/link_header_util",
"+components/metrics",
@@ -28,7 +30,6 @@ include_rules = [
"+content/public/browser",
"+device/base/synchronization",
"+device/gamepad", # For gamepad API
- "+device/geolocation/public/cpp",
"+device/nfc",
"+device/vr", # For WebVR API
# This can only be used on POSIX, in particular it mustn't be used on Windows
@@ -61,6 +62,13 @@ include_rules = [
"+chromeos",
"+third_party/cros_system_api",
+ # Limit visibility into Content Service internals.
+ "-services/content",
+ "+services/content/public",
+ "+services/content/navigable_contents_delegate.h",
+ "+services/content/service.h",
+ "+services/content/service_delegate.h",
+
# No inclusion of WebKit from the browser, other than the ones in
# WebKit/public/{mojom,common}, or the ones that are strictly enum/POD,
# header-only types, and some selected common code.
@@ -97,7 +105,7 @@ include_rules = [
"+third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h",
"+third_party/blink/public/platform/modules/indexeddb/web_idb_types.h",
"+third_party/blink/public/platform/modules/notifications/web_notification_constants.h",
- "+third_party/blink/public/platform/modules/serviceworker/web_service_worker_error.h",
+ "+third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h",
"+third_party/blink/public/public_buildflags.h",
"+third_party/blink/public/web/web_ax_enums.h",
"+third_party/blink/public/web/web_console_message.h",
diff --git a/chromium/content/browser/OWNERS b/chromium/content/browser/OWNERS
index 76478df0021..223a5fa2d14 100644
--- a/chromium/content/browser/OWNERS
+++ b/chromium/content/browser/OWNERS
@@ -28,8 +28,3 @@ per-file sandbox_host_linux.*=jln@chromium.org
per-file sandbox_host_linux.*=jorgelo@chromium.org
per-file sandbox_ipc_linux.*=jln@chromium.org
per-file sandbox_ipc_linux.*=jorgelo@chromium.org
-
-# LevelDBWrapperImpl used in LocalStorage
-per-file leveldb_wrapper_impl*=mek@chromium.org
-per-file leveldb_wrapper_impl*=dmurph@chromium.org
-per-file leveldb_wrapper_impl*=pwnall@chromium.org
diff --git a/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc b/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
index b1f5295d639..a71a156a72e 100644
--- a/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
+++ b/chromium/content/browser/accessibility/accessibility_event_recorder_win.cc
@@ -258,12 +258,13 @@ void AccessibilityEventRecorderWin::OnWinEventHook(
AccessibleStates ia2_state = 0;
Microsoft::WRL::ComPtr<IAccessible2> iaccessible2;
hr = QueryIAccessible2(iaccessible.Get(), iaccessible2.GetAddressOf());
+ bool has_ia2 = SUCCEEDED(hr) && iaccessible2;
base::string16 html_tag;
base::string16 obj_class;
base::string16 html_id;
- if (SUCCEEDED(hr)) {
+ if (has_ia2) {
iaccessible2->get_states(&ia2_state);
base::win::ScopedBstr attributes_bstr;
if (S_OK == iaccessible2->get_attributes(attributes_bstr.Receive())) {
@@ -307,6 +308,19 @@ void AccessibilityEventRecorderWin::OnWinEventHook(
log += " ";
log += base::UTF16ToUTF8(IAccessible2StateToString(ia2_state));
+ // Group position, e.g. L3, 5 of 7
+ LONG group_level, similar_items_in_group, position_in_group;
+ if (has_ia2 &&
+ iaccessible2->get_groupPosition(&group_level, &similar_items_in_group,
+ &position_in_group) == S_OK) {
+ if (group_level)
+ log += base::StringPrintf(" level=%ld", group_level);
+ if (similar_items_in_group) {
+ log += base::StringPrintf(" %ld of %ld", position_in_group,
+ similar_items_in_group);
+ }
+ }
+
// For TEXT_REMOVED and TEXT_INSERTED events, query the text that was
// inserted or removed and include that in the log.
Microsoft::WRL::ComPtr<IAccessibleText> accessible_text;
diff --git a/chromium/content/browser/accessibility/accessibility_ipc_error_browsertest.cc b/chromium/content/browser/accessibility/accessibility_ipc_error_browsertest.cc
index a85dba33883..c91e712b57c 100644
--- a/chromium/content/browser/accessibility/accessibility_ipc_error_browsertest.cc
+++ b/chromium/content/browser/accessibility/accessibility_ipc_error_browsertest.cc
@@ -159,9 +159,9 @@ IN_PROC_BROWSER_TEST_F(AccessibilityIpcErrorBrowserTest,
// Construct a bad accessibility message that BrowserAccessibilityManager
// will reject.
- std::vector<AXEventNotificationDetails> bad_accessibility_event_list;
- bad_accessibility_event_list.push_back(AXEventNotificationDetails());
- bad_accessibility_event_list[0].update.node_id_to_clear = -2;
+ AXEventNotificationDetails bad_accessibility_event;
+ bad_accessibility_event.updates.resize(1);
+ bad_accessibility_event.updates[0].node_id_to_clear = -2;
// We should be able to reset accessibility |max_iterations-1| times
// (see render_frame_host_impl.cc - kMaxAccessibilityResets),
@@ -172,7 +172,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityIpcErrorBrowserTest,
// Send the browser accessibility the bad message.
BrowserAccessibilityManager* manager =
frame->GetOrCreateBrowserAccessibilityManager();
- manager->OnAccessibilityEvents(bad_accessibility_event_list);
+ manager->OnAccessibilityEvents(bad_accessibility_event);
// Now the frame should have deleted the BrowserAccessibilityManager.
ASSERT_EQ(nullptr, frame->browser_accessibility_manager());
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter.cc
index d5cfe4df644..5236a97ee06 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter.cc
@@ -107,16 +107,20 @@ bool AccessibilityTreeFormatter::MatchesFilters(
const std::vector<Filter>& filters,
const base::string16& text,
bool default_result) {
- std::vector<Filter>::const_iterator iter = filters.begin();
bool allow = default_result;
- for (iter = filters.begin(); iter != filters.end(); ++iter) {
- if (base::MatchPattern(text, iter->match_str)) {
- if (iter->type == Filter::ALLOW_EMPTY)
- allow = true;
- else if (iter->type == Filter::ALLOW)
- allow = (!base::MatchPattern(text, base::UTF8ToUTF16("*=''")));
- else
- allow = false;
+ for (const auto& filter : filters) {
+ if (base::MatchPattern(text, filter.match_str)) {
+ switch (filter.type) {
+ case Filter::ALLOW_EMPTY:
+ allow = true;
+ break;
+ case Filter::ALLOW:
+ allow = (!base::MatchPattern(text, base::UTF8ToUTF16("*=''")));
+ break;
+ case Filter::DENY:
+ allow = false;
+ break;
+ }
}
}
return allow;
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm b/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm
index 1402f8eb016..a63ae0b7b07 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_mac.mm
@@ -170,6 +170,8 @@ NSArray* BuildAllAttributesArray() {
@"AXARIARowIndex",
@"AXARIASetSize",
@"AXARIAPosInSet",
+ @"AXAutocomplete",
+ @"AXAutocompleteValue",
NSAccessibilityColumnHeaderUIElementsAttribute,
NSAccessibilityColumnIndexRangeAttribute,
@"AXDOMIdentifier",
@@ -177,9 +179,12 @@ NSArray* BuildAllAttributesArray() {
@"AXEditableAncestor",
NSAccessibilityEnabledAttribute,
NSAccessibilityExpandedAttribute,
+ @"AXFocusableAncestor",
NSAccessibilityFocusedAttribute,
@"AXGrabbed",
NSAccessibilityHeaderAttribute,
+ @"AXHasPopup",
+ @"AXHasPopupValue",
@"AXHighestEditableAncestor",
NSAccessibilityIndexAttribute,
@"AXLanguage",
@@ -192,6 +197,7 @@ NSArray* BuildAllAttributesArray() {
@"AXRequired",
NSAccessibilityRowHeaderUIElementsAttribute,
NSAccessibilityRowIndexRangeAttribute,
+ NSAccessibilitySelectedAttribute,
NSAccessibilitySelectedChildrenAttribute,
NSAccessibilityTitleUIElementAttribute,
NSAccessibilityURLAttribute,
diff --git a/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc b/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
index f5281e28968..a54957c628f 100644
--- a/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
+++ b/chromium/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
@@ -131,7 +131,10 @@ CONTENT_EXPORT base::string16 IAccessible2RoleToString(int32_t ia2_role) {
QUOTE(IA2_ROLE_VIEW_PORT),
QUOTE(IA2_ROLE_COMPLEMENTARY_CONTENT),
QUOTE(IA2_ROLE_LANDMARK),
- QUOTE(IA2_ROLE_LEVEL_BAR)};
+ QUOTE(IA2_ROLE_LEVEL_BAR),
+ QUOTE(IA2_ROLE_CONTENT_DELETION),
+ QUOTE(IA2_ROLE_CONTENT_INSERTION),
+ };
return GetNameForPlatformConstant(ia2_table, arraysize(ia2_table), ia2_role);
}
diff --git a/chromium/content/browser/accessibility/accessibility_ui.cc b/chromium/content/browser/accessibility/accessibility_ui.cc
index 945acc066ab..4dada7363d2 100644
--- a/chromium/content/browser/accessibility/accessibility_ui.cc
+++ b/chromium/content/browser/accessibility/accessibility_ui.cc
@@ -39,6 +39,7 @@
#include "content/public/common/url_constants.h"
#include "net/base/escape.h"
#include "ui/accessibility/platform/ax_platform_node.h"
+#include "ui/base/webui/web_ui_util.h"
static const char kTargetsDataFile[] = "targets-data.json";
@@ -105,8 +106,13 @@ std::unique_ptr<base::DictionaryValue> BuildTargetDescriptor(
title = base::UTF16ToUTF8(web_contents->GetTitle());
NavigationController& controller = web_contents->GetController();
NavigationEntry* entry = controller.GetVisibleEntry();
- if (entry != nullptr && entry->GetURL().is_valid())
- favicon_url = entry->GetFavicon().url;
+ if (entry != nullptr && entry->GetURL().is_valid()) {
+ gfx::Image favicon_image = entry->GetFavicon().image;
+ if (!favicon_image.IsEmpty()) {
+ const SkBitmap* favicon_bitmap = favicon_image.ToSkBitmap();
+ favicon_url = GURL(webui::GetBitmapDataUrl(*favicon_bitmap));
+ }
+ }
accessibility_mode = web_contents->GetAccessibilityMode();
}
@@ -131,7 +137,7 @@ bool HandleAccessibilityRequestCallback(
while (RenderWidgetHost* widget = widgets->GetNextHost()) {
// Ignore processes that don't have a connection, such as crashed tabs.
- if (!widget->GetProcess()->HasConnection())
+ if (!widget->GetProcess()->IsInitializedAndNotDead())
continue;
RenderViewHost* rvh = RenderViewHost::From(widget);
if (!rvh)
diff --git a/chromium/content/browser/accessibility/accessibility_win_browsertest.cc b/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
index 089946e6c50..4ab51921d62 100644
--- a/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
+++ b/chromium/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -192,7 +192,7 @@ void AccessibilityWinBrowserTest::SetUpScrollableInputField(
R"HTML(<!DOCTYPE html>
<html>
<body>
- <input type="text" style="width: 30px;" value=")HTML") +
+ <input type="text" style="width: 150px;" value=")HTML") +
net::EscapeForHTML(kInputContents) +
std::string(R"HTML(">
</body>
@@ -240,7 +240,9 @@ void AccessibilityWinBrowserTest::SetUpInputFieldHelper(
ExecuteScript(std::wstring(L"let textField = document.querySelector('input');"
L"textField.focus();"
L"textField.setSelectionRange(") +
- caret_offset + L"," + caret_offset + L");");
+ caret_offset + L"," + caret_offset +
+ L");"
+ L"textField.scrollLeft = 1000;");
waiter.WaitForNotification();
}
@@ -1314,11 +1316,11 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
}
IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
- DISABLED_TestCharacterExtentsInScrollableInputField) {
+ TestCharacterExtentsInScrollableInputField) {
Microsoft::WRL::ComPtr<IAccessibleText> input_text;
SetUpScrollableInputField(&input_text);
- constexpr LONG visible_characters_start = 20;
+ constexpr LONG visible_characters_start = 21;
LONG n_characters;
ASSERT_HRESULT_SUCCEEDED(input_text->get_nCharacters(&n_characters));
ASSERT_EQ(kContentsLength, n_characters);
@@ -1338,7 +1340,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
// of 0 is not used because it signifies an invalid size.
EXPECT_HRESULT_SUCCEEDED(input_text->get_characterExtents(
0, coordinate_type, &x, &y, &width, &height));
- EXPECT_LT(0, x) << "at offset 0";
+ EXPECT_LT(0, x + width) << "at offset 0";
EXPECT_LT(0, y) << "at offset 0";
EXPECT_EQ(1, width) << "at offset 0";
EXPECT_LT(1, height) << "at offset 0";
@@ -1346,7 +1348,8 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
// Test that characters at the start of the input field are offscreen by
// checking that their x coordinate is at the start of the field and their
// width is 1.
- for (LONG offset = 1; offset < visible_characters_start; ++offset) {
+ // Exclude the character that is partly visible.
+ for (LONG offset = 1; offset < (visible_characters_start - 1); ++offset) {
previous_x = x;
previous_y = y;
previous_height = height;
@@ -1356,7 +1359,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
EXPECT_EQ(previous_x, x) << "at offset " << offset;
EXPECT_EQ(previous_y, y) << "at offset " << offset;
EXPECT_EQ(1, width) << "at offset " << offset;
- EXPECT_LT(previous_height, height) << "at offset " << offset;
+ EXPECT_EQ(previous_height, height) << "at offset " << offset;
}
// Test that non offscreen characters have increasing x coordinates and a
@@ -1369,8 +1372,10 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
EXPECT_EQ(previous_height, height)
<< "at offset " << visible_characters_start;
- for (LONG offset = visible_characters_start + 1; offset < n_characters;
- ++offset) {
+ // Exclude the dot at the end of the text field, because it has a width of
+ // one anyway.
+ for (LONG offset = visible_characters_start + 1;
+ offset < (n_characters - 1); ++offset) {
previous_x = x;
previous_y = y;
previous_height = height;
diff --git a/chromium/content/browser/accessibility/browser_accessibility.cc b/chromium/content/browser/accessibility/browser_accessibility.cc
index 64868046c9a..68e62b1db86 100644
--- a/chromium/content/browser/accessibility/browser_accessibility.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility.cc
@@ -426,47 +426,52 @@ gfx::Rect BrowserAccessibility::GetPageBoundsForRange(int start, int len)
local_start > 0 ? character_offsets[local_start - 1] : 0;
int end_pixel_offset =
local_end > 0 ? character_offsets[local_end - 1] : 0;
+ int max_pixel_offset = character_offsets_length > 0
+ ? character_offsets[character_offsets_length - 1]
+ : 0;
- gfx::Rect child_rect = child->GetPageBoundsRect();
auto text_direction = static_cast<ax::mojom::TextDirection>(
child->GetIntAttribute(ax::mojom::IntAttribute::kTextDirection));
- gfx::Rect child_overlap_rect;
+ gfx::RectF child_overlap_rect;
switch (text_direction) {
case ax::mojom::TextDirection::kNone:
case ax::mojom::TextDirection::kLtr: {
- int left = child_rect.x() + start_pixel_offset;
- int right = child_rect.x() + end_pixel_offset;
- child_overlap_rect = gfx::Rect(left, child_rect.y(),
- right - left, child_rect.height());
+ int height = child->GetLocation().height();
+ child_overlap_rect =
+ gfx::RectF(start_pixel_offset, 0,
+ end_pixel_offset - start_pixel_offset, height);
break;
}
case ax::mojom::TextDirection::kRtl: {
- int right = child_rect.right() - start_pixel_offset;
- int left = child_rect.right() - end_pixel_offset;
- child_overlap_rect = gfx::Rect(left, child_rect.y(),
- right - left, child_rect.height());
+ int right = max_pixel_offset - start_pixel_offset;
+ int left = max_pixel_offset - end_pixel_offset;
+ int height = child->GetLocation().height();
+ child_overlap_rect = gfx::RectF(left, 0, right - left, height);
break;
}
case ax::mojom::TextDirection::kTtb: {
- int top = child_rect.y() + start_pixel_offset;
- int bottom = child_rect.y() + end_pixel_offset;
- child_overlap_rect = gfx::Rect(child_rect.x(), top,
- child_rect.width(), bottom - top);
+ int width = child->GetLocation().width();
+ child_overlap_rect = gfx::RectF(0, start_pixel_offset, width,
+ end_pixel_offset - start_pixel_offset);
break;
}
case ax::mojom::TextDirection::kBtt: {
- int bottom = child_rect.bottom() - start_pixel_offset;
- int top = child_rect.bottom() - end_pixel_offset;
- child_overlap_rect = gfx::Rect(child_rect.x(), top,
- child_rect.width(), bottom - top);
+ int bottom = max_pixel_offset - start_pixel_offset;
+ int top = max_pixel_offset - end_pixel_offset;
+ int width = child->GetLocation().width();
+ child_overlap_rect = gfx::RectF(0, top, width, bottom - top);
break;
}
}
- if (bounds.width() == 0 && bounds.height() == 0)
- bounds = child_overlap_rect;
- else
- bounds.Union(child_overlap_rect);
+ gfx::Rect absolute_child_rect = child->RelativeToAbsoluteBounds(
+ child_overlap_rect, false /* frame_only */, nullptr /* offscreen */,
+ true /* clip_bounds */);
+ if (bounds.width() == 0 && bounds.height() == 0) {
+ bounds = absolute_child_rect;
+ } else {
+ bounds.Union(absolute_child_rect);
+ }
}
return bounds;
@@ -974,26 +979,54 @@ int BrowserAccessibility::GetTableColCount() const {
return table_info->col_count;
}
+std::vector<int32_t> BrowserAccessibility::GetColHeaderNodeIds() const {
+ ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
+ if (!table_info)
+ return {};
+
+ std::vector<std::vector<int32_t>> headers = table_info->col_headers;
+ std::vector<int32_t> all_ids;
+ for (const auto& col_ids : headers) {
+ all_ids.insert(all_ids.end(), col_ids.begin(), col_ids.end());
+ }
+
+ return all_ids;
+}
+
std::vector<int32_t> BrowserAccessibility::GetColHeaderNodeIds(
int32_t col_index) const {
ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
if (!table_info)
- return std::vector<int32_t>();
+ return {};
if (col_index < 0 || col_index >= table_info->col_count)
- return std::vector<int32_t>();
+ return {};
return table_info->col_headers[col_index];
}
+std::vector<int32_t> BrowserAccessibility::GetRowHeaderNodeIds() const {
+ ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
+ if (!table_info)
+ return {};
+
+ std::vector<std::vector<int32_t>> headers = table_info->row_headers;
+ std::vector<int32_t> all_ids;
+ for (const auto& col_ids : headers) {
+ all_ids.insert(all_ids.end(), col_ids.begin(), col_ids.end());
+ }
+
+ return all_ids;
+}
+
std::vector<int32_t> BrowserAccessibility::GetRowHeaderNodeIds(
int32_t row_index) const {
ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
if (!table_info)
- return std::vector<int32_t>();
+ return {};
if (row_index < 0 || row_index >= table_info->row_count)
- return std::vector<int32_t>();
+ return {};
return table_info->row_headers[row_index];
}
diff --git a/chromium/content/browser/accessibility/browser_accessibility.h b/chromium/content/browser/accessibility/browser_accessibility.h
index 83f78a21604..f3d85b39061 100644
--- a/chromium/content/browser/accessibility/browser_accessibility.h
+++ b/chromium/content/browser/accessibility/browser_accessibility.h
@@ -73,7 +73,7 @@ class CONTENT_EXPORT BrowserAccessibility : public ui::AXPlatformNodeDelegate {
// caller.
static BrowserAccessibility* Create();
- virtual ~BrowserAccessibility();
+ ~BrowserAccessibility() override;
// Called only once, immediately after construction. The constructor doesn't
// take any arguments because in the Windows subclass we use a special
@@ -116,11 +116,11 @@ class CONTENT_EXPORT BrowserAccessibility : public ui::AXPlatformNodeDelegate {
// Returns the number of children of this object, or 0 if PlatformIsLeaf()
// returns true.
- uint32_t PlatformChildCount() const;
+ virtual uint32_t PlatformChildCount() const;
// Return a pointer to the child at the given index, or NULL for an
// invalid index. Returns NULL if PlatformIsLeaf() returns true.
- BrowserAccessibility* PlatformGetChild(uint32_t child_index) const;
+ virtual BrowserAccessibility* PlatformGetChild(uint32_t child_index) const;
// Returns true if an ancestor of this node (not including itself) is a
// leaf node, meaning that this node is not actually exposed to the
@@ -343,7 +343,9 @@ class CONTENT_EXPORT BrowserAccessibility : public ui::AXPlatformNodeDelegate {
gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
int GetTableRowCount() const override;
int GetTableColCount() const override;
+ std::vector<int32_t> GetColHeaderNodeIds() const override;
std::vector<int32_t> GetColHeaderNodeIds(int32_t col_index) const override;
+ std::vector<int32_t> GetRowHeaderNodeIds() const override;
std::vector<int32_t> GetRowHeaderNodeIds(int32_t row_index) const override;
int32_t GetCellId(int32_t row_index, int32_t col_index) const override;
int32_t CellIdToIndex(int32_t cell_id) const override;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_android.cc b/chromium/content/browser/accessibility/browser_accessibility_android.cc
index 0bce59cad23..3dd224bd18d 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_android.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_android.cc
@@ -18,6 +18,7 @@
#include "third_party/skia/include/core/SkColor.h"
#include "ui/accessibility/ax_assistant_structure.h"
#include "ui/accessibility/ax_role_properties.h"
+#include "ui/accessibility/ax_table_info.h"
#include "ui/accessibility/platform/ax_android_constants.h"
#include "ui/accessibility/platform/ax_unique_id.h"
@@ -510,7 +511,7 @@ base::string16 BrowserAccessibilityAndroid::GetRoleDescription() const {
// No role description.
break;
case ax::mojom::Role::kCell:
- message_id = IDS_AX_ROLE_CELL;
+ // No role description.
break;
case ax::mojom::Role::kCheckBox:
message_id = IDS_AX_ROLE_CHECK_BOX;
@@ -536,6 +537,12 @@ base::string16 BrowserAccessibilityAndroid::GetRoleDescription() const {
case ax::mojom::Role::kComplementary:
message_id = IDS_AX_ROLE_COMPLEMENTARY;
break;
+ case ax::mojom::Role::kContentDeletion:
+ message_id = IDS_AX_ROLE_CONTENT_DELETION;
+ break;
+ case ax::mojom::Role::kContentInsertion:
+ message_id = IDS_AX_ROLE_CONTENT_INSERTION;
+ break;
case ax::mojom::Role::kContentInfo:
message_id = IDS_AX_ROLE_CONTENT_INFO;
break;
@@ -787,9 +794,6 @@ base::string16 BrowserAccessibilityAndroid::GetRoleDescription() const {
case ax::mojom::Role::kList:
// No role description.
break;
- case ax::mojom::Role::kLocationBar:
- // No role description.
- break;
case ax::mojom::Role::kLog:
message_id = IDS_AX_ROLE_LOG;
break;
@@ -1320,7 +1324,9 @@ int BrowserAccessibilityAndroid::AndroidRangeType() const {
int BrowserAccessibilityAndroid::RowCount() const {
if (ui::IsTableLikeRole(GetRole())) {
- return CountChildrenWithRole(ax::mojom::Role::kRow);
+ ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
+ if (table_info)
+ return table_info->row_count;
}
if (GetRole() == ax::mojom::Role::kList ||
@@ -1335,7 +1341,9 @@ int BrowserAccessibilityAndroid::RowCount() const {
int BrowserAccessibilityAndroid::ColumnCount() const {
if (ui::IsTableLikeRole(GetRole())) {
- return CountChildrenWithRole(ax::mojom::Role::kColumn);
+ ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
+ if (table_info)
+ return table_info->col_count;
}
return 0;
}
diff --git a/chromium/content/browser/accessibility/browser_accessibility_cocoa.h b/chromium/content/browser/accessibility/browser_accessibility_cocoa.h
index a03585269db..44c85b5ad57 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_cocoa.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -35,7 +35,7 @@ struct AXTextEdit {
// This class converts it into a format Cocoa can query.
@interface BrowserAccessibilityCocoa : NSObject {
@private
- content::BrowserAccessibility* browserAccessibility_;
+ content::BrowserAccessibility* owner_;
base::scoped_nsobject<NSMutableArray> children_;
// Stores the previous value of an edit field.
base::string16 oldValue_;
@@ -62,7 +62,7 @@ struct AXTextEdit {
- (content::BrowserAccessibilityDelegate*)delegate;
// Get the BrowserAccessibility that this object wraps.
-- (content::BrowserAccessibility*)browserAccessibility;
+- (content::BrowserAccessibility*)owner;
// Computes the text that was added or deleted in a text field after an edit.
- (content::AXTextEdit)computeTextEdit;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm b/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
index bc4b972f9c7..07e9862b76a 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -30,6 +30,7 @@
#include "ui/accessibility/ax_range.h"
#include "ui/accessibility/ax_role_properties.h"
#include "ui/accessibility/ax_table_info.h"
+#include "ui/accessibility/platform/ax_platform_node.h"
#import "ui/accessibility/platform/ax_platform_node_mac.h"
@@ -65,12 +66,17 @@ NSString* const NSAccessibilityARIARowCountAttribute = @"AXARIARowCount";
NSString* const NSAccessibilityARIARowIndexAttribute = @"AXARIARowIndex";
NSString* const NSAccessibilityARIASetSizeAttribute = @"AXARIASetSize";
NSString* const NSAccessibilityAccessKeyAttribute = @"AXAccessKey";
+NSString* const NSAccessibilityAutocompleteValueAttribute =
+ @"AXAutocompleteValue";
NSString* const NSAccessibilityDOMIdentifierAttribute = @"AXDOMIdentifier";
NSString* const NSAccessibilityDropEffectsAttribute = @"AXDropEffects";
NSString* const NSAccessibilityEditableAncestorAttribute =
@"AXEditableAncestor";
+NSString* const NSAccessibilityFocusableAncestorAttribute =
+ @"AXFocusableAncestor";
NSString* const NSAccessibilityGrabbedAttribute = @"AXGrabbed";
NSString* const NSAccessibilityHasPopupAttribute = @"AXHasPopup";
+NSString* const NSAccessibilityHasPopupValueAttribute = @"AXHasPopupValue";
NSString* const NSAccessibilityHighestEditableAncestorAttribute =
@"AXHighestEditableAncestor";
NSString* const NSAccessibilityInvalidAttribute = @"AXInvalid";
@@ -112,6 +118,13 @@ NSString* const NSAccessibilityTextMarkerRangeForUnorderedTextMarkersParameteriz
@"AXTextMarkerRangeForUnorderedTextMarkers";
NSString* const NSAccessibilityIndexForChildUIElementParameterizedAttribute =
@"AXIndexForChildUIElement";
+NSString* const NSAccessibilityValueAutofillAvailableAttribute =
+ @"AXValueAutofillAvailable";
+// Not currently supported by Chrome -- information not stored:
+// NSString* const NSAccessibilityValueAutofilledAttribute =
+// @"AXValueAutofilled"; Not currently supported by Chrome -- mismatch of types
+// supported: NSString* const NSAccessibilityValueAutofillTypeAttribute =
+// @"AXValueAutofillType";
// Actions.
NSString* const NSAccessibilityScrollToVisibleAction = @"AXScrollToVisible";
@@ -460,7 +473,7 @@ bool InitializeAccessibilityTreeSearch(
if ([startElementParameter isKindOfClass:[BrowserAccessibilityCocoa class]]) {
BrowserAccessibilityCocoa* startNodeCocoa =
(BrowserAccessibilityCocoa*)startElementParameter;
- search->SetStartNode([startNodeCocoa browserAccessibility]);
+ search->SetStartNode([startNodeCocoa owner]);
}
bool immediateDescendantsOnly = false;
@@ -567,6 +580,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
{NSAccessibilityARIARowIndexAttribute, @"ariaRowIndex"},
{NSAccessibilityARIASetSizeAttribute, @"ariaSetSize"},
{NSAccessibilityAccessKeyAttribute, @"accessKey"},
+ {NSAccessibilityAutocompleteValueAttribute, @"autocompleteValue"},
{NSAccessibilityChildrenAttribute, @"children"},
{NSAccessibilityColumnsAttribute, @"columns"},
{NSAccessibilityColumnHeaderUIElementsAttribute, @"columnHeaders"},
@@ -583,10 +597,12 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
{NSAccessibilityEnabledAttribute, @"enabled"},
{NSAccessibilityEndTextMarkerAttribute, @"endTextMarker"},
{NSAccessibilityExpandedAttribute, @"expanded"},
+ {NSAccessibilityFocusableAncestorAttribute, @"focusableAncestor"},
{NSAccessibilityFocusedAttribute, @"focused"},
{NSAccessibilityGrabbedAttribute, @"grabbed"},
{NSAccessibilityHeaderAttribute, @"header"},
{NSAccessibilityHasPopupAttribute, @"hasPopup"},
+ {NSAccessibilityHasPopupValueAttribute, @"hasPopupValue"},
{NSAccessibilityHelpAttribute, @"help"},
{NSAccessibilityHighestEditableAncestorAttribute,
@"highestEditableAncestor"},
@@ -630,6 +646,12 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
{NSAccessibilityTopLevelUIElementAttribute, @"window"},
{NSAccessibilityURLAttribute, @"url"},
{NSAccessibilityValueAttribute, @"value"},
+ {NSAccessibilityValueAutofillAvailableAttribute,
+ @"valueAutofillAvailable"},
+ // Not currently supported by Chrome -- information not stored:
+ // {NSAccessibilityValueAutofilledAttribute, @"valueAutofilled"},
+ // Not currently supported by Chrome -- mismatch of types supported:
+ // {NSAccessibilityValueAutofillTypeAttribute, @"valueAutofillType"},
{NSAccessibilityValueDescriptionAttribute, @"valueDescription"},
{NSAccessibilityVisibleCharacterRangeAttribute, @"visibleCharacterRange"},
{NSAccessibilityVisibleCellsAttribute, @"visibleCells"},
@@ -654,57 +676,57 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (instancetype)initWithObject:(BrowserAccessibility*)accessibility {
if ((self = [super init]))
- browserAccessibility_ = accessibility;
+ owner_ = accessibility;
return self;
}
- (void)detach {
- if (!browserAccessibility_)
+ if (!owner_)
return;
NSAccessibilityPostNotification(
self, NSAccessibilityUIElementDestroyedNotification);
- browserAccessibility_ = nullptr;
+ owner_ = nullptr;
}
- (NSString*)accessKey {
if (![self instanceActive])
return nil;
- return NSStringForStringAttribute(browserAccessibility_,
+ return NSStringForStringAttribute(owner_,
ax::mojom::StringAttribute::kAccessKey);
}
- (NSNumber*)ariaAtomic {
if (![self instanceActive])
return nil;
- bool boolValue = browserAccessibility_->GetBoolAttribute(
- ax::mojom::BoolAttribute::kLiveAtomic);
+ bool boolValue =
+ owner_->GetBoolAttribute(ax::mojom::BoolAttribute::kLiveAtomic);
return [NSNumber numberWithBool:boolValue];
}
- (NSNumber*)ariaBusy {
if (![self instanceActive])
return nil;
- return [NSNumber numberWithBool:browserAccessibility_->GetBoolAttribute(
- ax::mojom::BoolAttribute::kBusy)];
+ return [NSNumber
+ numberWithBool:owner_->GetBoolAttribute(ax::mojom::BoolAttribute::kBusy)];
}
- (NSNumber*)ariaColumnCount {
- if (!ui::IsTableLikeRole(browserAccessibility_->GetRole()))
+ if (!ui::IsTableLikeRole(owner_->GetRole()))
return nil;
int count = -1;
- if (!browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kAriaColumnCount, &count)) {
+ if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kAriaColumnCount,
+ &count)) {
return nil;
}
return [NSNumber numberWithInt:count];
}
- (NSNumber*)ariaColumnIndex {
- if (!ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole()))
+ if (!ui::IsCellOrTableHeaderRole(owner_->GetRole()))
return nil;
int index = -1;
- if (!browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kAriaCellColumnIndex, &index)) {
+ if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kAriaCellColumnIndex,
+ &index)) {
return nil;
}
return [NSNumber numberWithInt:index];
@@ -713,41 +735,41 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSString*)ariaLive {
if (![self instanceActive])
return nil;
- return NSStringForStringAttribute(browserAccessibility_,
+ return NSStringForStringAttribute(owner_,
ax::mojom::StringAttribute::kLiveStatus);
}
- (NSNumber*)ariaPosInSet {
if (![self instanceActive])
return nil;
- return [NSNumber numberWithInt:browserAccessibility_->GetIntAttribute(
+ return [NSNumber numberWithInt:owner_->GetIntAttribute(
ax::mojom::IntAttribute::kPosInSet)];
}
- (NSString*)ariaRelevant {
if (![self instanceActive])
return nil;
- return NSStringForStringAttribute(browserAccessibility_,
+ return NSStringForStringAttribute(owner_,
ax::mojom::StringAttribute::kLiveRelevant);
}
- (NSNumber*)ariaRowCount {
- if (!ui::IsTableLikeRole(browserAccessibility_->GetRole()))
+ if (!ui::IsTableLikeRole(owner_->GetRole()))
return nil;
int count = -1;
- if (!browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kAriaRowCount, &count)) {
+ if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kAriaRowCount,
+ &count)) {
return nil;
}
return [NSNumber numberWithInt:count];
}
- (NSNumber*)ariaRowIndex {
- if (!ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole()))
+ if (!ui::IsCellOrTableHeaderRole(owner_->GetRole()))
return nil;
int index = -1;
- if (!browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kAriaCellRowIndex, &index)) {
+ if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kAriaCellRowIndex,
+ &index)) {
return nil;
}
return [NSNumber numberWithInt:index];
@@ -756,8 +778,15 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)ariaSetSize {
if (![self instanceActive])
return nil;
- return [NSNumber numberWithInt:browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kSetSize)];
+ return [NSNumber
+ numberWithInt:owner_->GetIntAttribute(ax::mojom::IntAttribute::kSetSize)];
+}
+
+- (NSString*)autocompleteValue {
+ if (![self instanceActive])
+ return nil;
+ return NSStringForStringAttribute(owner_,
+ ax::mojom::StringAttribute::kAutoComplete);
}
// Returns an array of BrowserAccessibilityCocoa objects, representing the
@@ -768,12 +797,11 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if ([self internalRole] == ax::mojom::Role::kLayoutTableColumn)
return nil;
if (!children_) {
- uint32_t childCount = browserAccessibility_->PlatformChildCount();
+ uint32_t childCount = owner_->PlatformChildCount();
children_.reset([[NSMutableArray alloc] initWithCapacity:childCount]);
for (uint32_t index = 0; index < childCount; ++index) {
BrowserAccessibilityCocoa* child =
- ToBrowserAccessibilityCocoa(
- browserAccessibility_->PlatformGetChild(index));
+ ToBrowserAccessibilityCocoa(owner_->PlatformGetChild(index));
if ([child isIgnored])
[children_ addObjectsFromArray:[child children]];
else
@@ -781,13 +809,11 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
// Also, add indirect children (if any).
- const std::vector<int32_t>& indirectChildIds =
- browserAccessibility_->GetIntListAttribute(
- ax::mojom::IntListAttribute::kIndirectChildIds);
+ const std::vector<int32_t>& indirectChildIds = owner_->GetIntListAttribute(
+ ax::mojom::IntListAttribute::kIndirectChildIds);
for (uint32_t i = 0; i < indirectChildIds.size(); ++i) {
int32_t child_id = indirectChildIds[i];
- BrowserAccessibility* child =
- browserAccessibility_->manager()->GetFromID(child_id);
+ BrowserAccessibility* child = owner_->manager()->GetFromID(child_id);
// This only became necessary as a result of crbug.com/93095. It should be
// a DCHECK in the future.
@@ -807,24 +833,23 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self isIgnored]) {
children_.reset();
} else {
- [ToBrowserAccessibilityCocoa(browserAccessibility_->PlatformGetParent())
- childrenChanged];
+ [ToBrowserAccessibilityCocoa(owner_->PlatformGetParent()) childrenChanged];
}
}
- (BOOL)isColumnHeaderForCurrentCell:(BrowserAccessibility*)header {
int cell_first_col = -1;
int cell_colspan = -1;
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kAriaCellColumnIndex, &cell_first_col);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kAriaCellColumnIndex,
+ &cell_first_col);
if (cell_first_col < 0) {
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableCellColumnIndex, &cell_first_col);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex,
+ &cell_first_col);
}
if (cell_first_col < 0)
return false;
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableCellColumnSpan, &cell_colspan);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnSpan,
+ &cell_colspan);
if (cell_colspan <= 0)
cell_colspan = 1;
int cell_last_col = cell_first_col + cell_colspan - 1;
@@ -857,9 +882,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
- bool is_cell_or_table_header =
- ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole());
- bool is_table_like = ui::IsTableLikeRole(browserAccessibility_->GetRole());
+ bool is_cell_or_table_header = ui::IsCellOrTableHeaderRole(owner_->GetRole());
+ bool is_table_like = ui::IsTableLikeRole(owner_->GetRole());
if (!is_table_like && !is_cell_or_table_header)
return nil;
BrowserAccessibility* table = [self containingTable];
@@ -877,21 +901,19 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
std::inserter(headerIds, headerIds.end()));
}
for (int32_t id : headerIds) {
- BrowserAccessibility* cell =
- browserAccessibility_->manager()->GetFromID(id);
+ BrowserAccessibility* cell = owner_->manager()->GetFromID(id);
if (cell)
[ret addObject:ToBrowserAccessibilityCocoa(cell)];
}
} else {
// Otherwise this is a cell, return the column headers for this cell.
int column = -1;
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableCellColumnIndex, &column);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex,
+ &column);
std::vector<int32_t> colHeaderIds = table->GetColHeaderNodeIds(column);
for (int32_t id : colHeaderIds) {
- BrowserAccessibility* cell =
- browserAccessibility_->manager()->GetFromID(id);
+ BrowserAccessibility* cell = owner_->manager()->GetFromID(id);
if (cell)
[ret addObject:ToBrowserAccessibilityCocoa(cell)];
}
@@ -903,15 +925,15 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSValue*)columnIndexRange {
if (![self instanceActive])
return nil;
- if (!ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole()))
+ if (!ui::IsCellOrTableHeaderRole(owner_->GetRole()))
return nil;
int column = -1;
int colspan = -1;
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableCellColumnIndex, &column);
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableCellColumnSpan, &colspan);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex,
+ &column);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnSpan,
+ &colspan);
if (column >= 0 && colspan >= 1)
return [NSValue valueWithRange:NSMakeRange(column, colspan)];
return nil;
@@ -929,7 +951,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
- (BrowserAccessibility*)containingTable {
- BrowserAccessibility* table = browserAccessibility_;
+ BrowserAccessibility* table = owner_;
while (table && !ui::IsTableLikeRole(table->GetRole())) {
table = table->PlatformGetParent();
}
@@ -949,18 +971,21 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if ([self shouldExposeTitleUIElement])
return @"";
- ax::mojom::NameFrom nameFrom =
- static_cast<ax::mojom::NameFrom>(browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kNameFrom));
- std::string name = browserAccessibility_->GetStringAttribute(
- ax::mojom::StringAttribute::kName);
+ ax::mojom::NameFrom nameFrom = static_cast<ax::mojom::NameFrom>(
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kNameFrom));
+ std::string name =
+ owner_->GetStringAttribute(ax::mojom::StringAttribute::kName);
if (!name.empty()) {
// On Mac OS X, the accessible name of an object is exposed as its
// title if it comes from visible text, and as its description
// otherwise, but never both.
- if (nameFrom == ax::mojom::NameFrom::kContents ||
- nameFrom == ax::mojom::NameFrom::kRelatedElement ||
- nameFrom == ax::mojom::NameFrom::kValue) {
+
+ // Group, radiogroup etc.
+ if ([self shouldExposeNameInDescription]) {
+ return base::SysUTF8ToNSString(name);
+ } else if (nameFrom == ax::mojom::NameFrom::kContents ||
+ nameFrom == ax::mojom::NameFrom::kRelatedElement ||
+ nameFrom == ax::mojom::NameFrom::kValue) {
return @"";
} else {
return base::SysUTF8ToNSString(name);
@@ -974,8 +999,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return @"";
std::string url;
- if (browserAccessibility_->GetStringAttribute(
- ax::mojom::StringAttribute::kUrl, &url)) {
+ if (owner_->GetStringAttribute(ax::mojom::StringAttribute::kUrl, &url)) {
// Given a url like http://foo.com/bar/baz.png, just return the
// base name, e.g., "baz.png".
size_t leftIndex = url.rfind('/');
@@ -987,14 +1011,14 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// If it's focusable but didn't have any other name or value, compute a name
// from its descendants.
- base::string16 value = browserAccessibility_->GetValue();
- if (browserAccessibility_->HasState(ax::mojom::State::kFocusable) &&
- !ui::IsControl(browserAccessibility_->GetRole()) && value.empty() &&
+ base::string16 value = owner_->GetValue();
+ if (owner_->HasState(ax::mojom::State::kFocusable) &&
+ !ui::IsControl(owner_->GetRole()) && value.empty() &&
[self internalRole] != ax::mojom::Role::kDateTime &&
[self internalRole] != ax::mojom::Role::kWebArea &&
[self internalRole] != ax::mojom::Role::kRootWebArea) {
return base::SysUTF8ToNSString(
- browserAccessibility_->ComputeAccessibleNameFromDescendants());
+ owner_->ComputeAccessibleNameFromDescendants());
}
return @"";
@@ -1004,8 +1028,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
if ([self internalRole] == ax::mojom::Role::kTreeItem) {
- return [NSNumber numberWithBool:GetState(browserAccessibility_,
- ax::mojom::State::kExpanded)];
+ return
+ [NSNumber numberWithBool:GetState(owner_, ax::mojom::State::kExpanded)];
} else {
return nil;
}
@@ -1025,8 +1049,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return nil;
ax::mojom::Role role = [self internalRole];
if (role == ax::mojom::Role::kRow || role == ax::mojom::Role::kTreeItem) {
- int level = browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kHierarchicalLevel);
+ int level =
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel);
// Mac disclosureLevel is 0-based, but web levels are 1-based.
if (level > 0)
level--;
@@ -1049,7 +1073,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return nil;
std::string dropEffects;
- if (browserAccessibility_->GetHtmlAttribute("aria-dropeffect", &dropEffects))
+ if (owner_->GetHtmlAttribute("aria-dropeffect", &dropEffects))
return base::SysUTF8ToNSString(dropEffects);
return nil;
@@ -1060,7 +1084,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return nil;
std::string id;
- if (browserAccessibility_->GetHtmlAttribute("id", &id))
+ if (owner_->GetHtmlAttribute("id", &id))
return base::SysUTF8ToNSString(id);
return nil;
@@ -1071,7 +1095,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return nil;
BrowserAccessibilityCocoa* editableRoot = self;
- while (![editableRoot browserAccessibility]->GetBoolAttribute(
+ while (![editableRoot owner]->GetBoolAttribute(
ax::mojom::BoolAttribute::kEditableRoot)) {
BrowserAccessibilityCocoa* parent = [editableRoot parent];
if (!parent || ![parent isKindOfClass:[self class]] ||
@@ -1086,16 +1110,14 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)enabled {
if (![self instanceActive])
return nil;
- return [NSNumber
- numberWithBool:browserAccessibility_->GetData().GetRestriction() !=
- ax::mojom::Restriction::kDisabled];
+ return [NSNumber numberWithBool:owner_->GetData().GetRestriction() !=
+ ax::mojom::Restriction::kDisabled];
}
// Returns a text marker that points to the last character in the document that
// can be selected with VoiceOver.
- (id)endTextMarker {
- const BrowserAccessibility* root =
- browserAccessibility_->manager()->GetRoot();
+ const BrowserAccessibility* root = owner_->manager()->GetRoot();
if (!root)
return nil;
@@ -1106,16 +1128,31 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)expanded {
if (![self instanceActive])
return nil;
- return [NSNumber numberWithBool:GetState(browserAccessibility_,
- ax::mojom::State::kExpanded)];
+ return
+ [NSNumber numberWithBool:GetState(owner_, ax::mojom::State::kExpanded)];
+}
+
+- (id)focusableAncestor {
+ if (![self instanceActive])
+ return nil;
+
+ BrowserAccessibilityCocoa* focusableRoot = self;
+ while (![focusableRoot owner]->HasState(ax::mojom::State::kFocusable)) {
+ BrowserAccessibilityCocoa* parent = [focusableRoot parent];
+ if (!parent || ![parent isKindOfClass:[self class]] ||
+ ![parent instanceActive]) {
+ return nil;
+ }
+ focusableRoot = parent;
+ }
+ return focusableRoot;
}
- (NSNumber*)focused {
if (![self instanceActive])
return nil;
- BrowserAccessibilityManager* manager = browserAccessibility_->manager();
- NSNumber* ret = [NSNumber numberWithBool:
- manager->GetFocus() == browserAccessibility_];
+ BrowserAccessibilityManager* manager = owner_->manager();
+ NSNumber* ret = [NSNumber numberWithBool:manager->GetFocus() == owner_];
return ret;
}
@@ -1123,8 +1160,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
std::string grabbed;
- if (browserAccessibility_->GetHtmlAttribute("aria-grabbed", &grabbed) &&
- grabbed == "true")
+ if (owner_->GetHtmlAttribute("aria-grabbed", &grabbed) && grabbed == "true")
return [NSNumber numberWithBool:YES];
return [NSNumber numberWithBool:NO];
@@ -1133,28 +1169,60 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)hasPopup {
if (![self instanceActive])
return nil;
- return browserAccessibility_->HasState(ax::mojom::State::kHasPopup) ? @YES
- : @NO;
+ return @(owner_->HasIntAttribute(ax::mojom::IntAttribute::kHasPopup));
+}
+
+- (NSString*)hasPopupValue {
+ if (![self instanceActive])
+ return nil;
+ int hasPopup = owner_->GetIntAttribute(ax::mojom::IntAttribute::kHasPopup);
+ switch (static_cast<ax::mojom::HasPopup>(hasPopup)) {
+ case ax::mojom::HasPopup::kFalse:
+ return @"false";
+ case ax::mojom::HasPopup::kTrue:
+ return @"true";
+ case ax::mojom::HasPopup::kMenu:
+ return @"menu";
+ case ax::mojom::HasPopup::kListbox:
+ return @"listbox";
+ case ax::mojom::HasPopup::kTree:
+ return @"tree";
+ case ax::mojom::HasPopup::kGrid:
+ return @"grid";
+ case ax::mojom::HasPopup::kDialog:
+ return @"dialog";
+ }
}
- (id)header {
if (![self instanceActive])
return nil;
int headerElementId = -1;
- if (ui::IsTableLikeRole(browserAccessibility_->GetRole())) {
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableHeaderId, &headerElementId);
+ if (ui::IsTableLikeRole(owner_->GetRole())) {
+ // The table header container is always the last child of the table,
+ // if it exists. The table header container is a special node in the
+ // accessibility tree only used on macOS. It has all of the table
+ // headers as its children, even though those cells are also children
+ // of rows in the table. Internally this is implemented using
+ // AXTableInfo and indirect_child_ids.
+ uint32_t childCount = owner_->PlatformChildCount();
+ if (childCount > 0) {
+ BrowserAccessibility* tableHeader =
+ owner_->PlatformGetChild(childCount - 1);
+ if (tableHeader->GetRole() == ax::mojom::Role::kTableHeaderContainer)
+ return ToBrowserAccessibilityCocoa(tableHeader);
+ }
} else if ([self internalRole] == ax::mojom::Role::kColumn) {
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableColumnHeaderId, &headerElementId);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableColumnHeaderId,
+ &headerElementId);
} else if ([self internalRole] == ax::mojom::Role::kRow) {
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableRowHeaderId, &headerElementId);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableRowHeaderId,
+ &headerElementId);
}
if (headerElementId > 0) {
BrowserAccessibility* headerObject =
- browserAccessibility_->manager()->GetFromID(headerElementId);
+ owner_->manager()->GetFromID(headerElementId);
if (headerObject)
return ToBrowserAccessibilityCocoa(headerObject);
}
@@ -1164,7 +1232,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSString*)help {
if (![self instanceActive])
return nil;
- return NSStringForStringAttribute(browserAccessibility_,
+ return NSStringForStringAttribute(owner_,
ax::mojom::StringAttribute::kDescription);
}
@@ -1192,12 +1260,12 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
if ([self internalRole] == ax::mojom::Role::kColumn) {
- int columnIndex = browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableColumnIndex);
+ int columnIndex =
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableColumnIndex);
return [NSNumber numberWithInt:columnIndex];
} else if ([self internalRole] == ax::mojom::Role::kRow) {
- int rowIndex = browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableRowIndex);
+ int rowIndex =
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableRowIndex);
return [NSNumber numberWithInt:rowIndex];
}
@@ -1210,18 +1278,16 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// TODO(nektar): Deprecate sel_start and sel_end attributes.
int selStart, selEnd;
- if (!browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTextSelStart, &selStart) ||
- !browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTextSelEnd, &selEnd)) {
+ if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart,
+ &selStart) ||
+ !owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &selEnd)) {
return nil;
}
if (selStart > selEnd)
std::swap(selStart, selEnd);
- const std::vector<int> line_breaks =
- browserAccessibility_->GetLineStartOffsets();
+ const std::vector<int> line_breaks = owner_->GetLineStartOffsets();
for (int i = 0; i < static_cast<int>(line_breaks.size()); ++i) {
if (line_breaks[i] > selStart)
return [NSNumber numberWithInt:i];
@@ -1242,8 +1308,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
int invalidState;
- if (!browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kInvalidState, &invalidState))
+ if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kInvalidState,
+ &invalidState))
return @"false";
switch (static_cast<ax::mojom::InvalidState>(invalidState)) {
@@ -1257,7 +1323,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return @"grammar";
case ax::mojom::InvalidState::kOther: {
std::string ariaInvalidValue;
- if (browserAccessibility_->GetStringAttribute(
+ if (owner_->GetStringAttribute(
ax::mojom::StringAttribute::kAriaInvalidValue, &ariaInvalidValue))
return base::SysUTF8ToNSString(ariaInvalidValue);
// Return @"true" since we cannot be more specific about the value.
@@ -1273,50 +1339,47 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)isMultiSelectable {
if (![self instanceActive])
return nil;
- return [NSNumber numberWithBool:GetState(browserAccessibility_,
- ax::mojom::State::kMultiselectable)];
+ return [NSNumber
+ numberWithBool:GetState(owner_, ax::mojom::State::kMultiselectable)];
}
- (NSString*)placeholderValue {
if (![self instanceActive])
return nil;
- ax::mojom::NameFrom nameFrom =
- static_cast<ax::mojom::NameFrom>(browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kNameFrom));
+ ax::mojom::NameFrom nameFrom = static_cast<ax::mojom::NameFrom>(
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kNameFrom));
if (nameFrom == ax::mojom::NameFrom::kPlaceholder) {
- return NSStringForStringAttribute(browserAccessibility_,
+ return NSStringForStringAttribute(owner_,
ax::mojom::StringAttribute::kName);
}
ax::mojom::DescriptionFrom descriptionFrom =
static_cast<ax::mojom::DescriptionFrom>(
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kDescriptionFrom));
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kDescriptionFrom));
if (descriptionFrom == ax::mojom::DescriptionFrom::kPlaceholder) {
- return NSStringForStringAttribute(browserAccessibility_,
+ return NSStringForStringAttribute(owner_,
ax::mojom::StringAttribute::kDescription);
}
- return NSStringForStringAttribute(browserAccessibility_,
+ return NSStringForStringAttribute(owner_,
ax::mojom::StringAttribute::kPlaceholder);
}
- (NSString*)language {
if (![self instanceActive])
return nil;
- return base::SysUTF8ToNSString(
- browserAccessibility_->GetInheritedStringAttribute(
- ax::mojom::StringAttribute::kLanguage));
+ return base::SysUTF8ToNSString(owner_->GetInheritedStringAttribute(
+ ax::mojom::StringAttribute::kLanguage));
}
// private
- (void)addLinkedUIElementsFromAttribute:(ax::mojom::IntListAttribute)attribute
addTo:(NSMutableArray*)outArray {
const std::vector<int32_t>& attributeValues =
- browserAccessibility_->GetIntListAttribute(attribute);
+ owner_->GetIntListAttribute(attribute);
for (size_t i = 0; i < attributeValues.size(); ++i) {
BrowserAccessibility* element =
- browserAccessibility_->manager()->GetFromID(attributeValues[i]);
+ owner_->manager()->GetFromID(attributeValues[i]);
if (element)
[outArray addObject:ToBrowserAccessibilityCocoa(element)];
}
@@ -1332,10 +1395,10 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
addTo:ret];
int target_id;
- if (browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kInPageLinkTargetId, &target_id)) {
- BrowserAccessibility* target = browserAccessibility_->manager()->GetFromID(
- static_cast<int32_t>(target_id));
+ if (owner_->GetIntAttribute(ax::mojom::IntAttribute::kInPageLinkTargetId,
+ &target_id)) {
+ BrowserAccessibility* target =
+ owner_->manager()->GetFromID(static_cast<int32_t>(target_id));
if (target)
[ret addObject:ToBrowserAccessibilityCocoa(target)];
}
@@ -1357,7 +1420,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)loadingProgress {
if (![self instanceActive])
return nil;
- BrowserAccessibilityManager* manager = browserAccessibility_->manager();
+ BrowserAccessibilityManager* manager = owner_->manager();
float floatValue = manager->GetTreeData().loading_progress;
return [NSNumber numberWithFloat:floatValue];
}
@@ -1365,25 +1428,25 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)maxValue {
if (![self instanceActive])
return nil;
- float floatValue = browserAccessibility_->GetFloatAttribute(
- ax::mojom::FloatAttribute::kMaxValueForRange);
+ float floatValue =
+ owner_->GetFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange);
return [NSNumber numberWithFloat:floatValue];
}
- (NSNumber*)minValue {
if (![self instanceActive])
return nil;
- float floatValue = browserAccessibility_->GetFloatAttribute(
- ax::mojom::FloatAttribute::kMinValueForRange);
+ float floatValue =
+ owner_->GetFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange);
return [NSNumber numberWithFloat:floatValue];
}
- (NSString*)orientation {
if (![self instanceActive])
return nil;
- if (GetState(browserAccessibility_, ax::mojom::State::kVertical))
+ if (GetState(owner_, ax::mojom::State::kVertical))
return NSAccessibilityVerticalOrientationValue;
- else if (GetState(browserAccessibility_, ax::mojom::State::kHorizontal))
+ else if (GetState(owner_, ax::mojom::State::kHorizontal))
return NSAccessibilityHorizontalOrientationValue;
return @"";
@@ -1401,11 +1464,11 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
//
int activeDescendantId;
- if (!browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kActivedescendantId, &activeDescendantId))
+ if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
+ &activeDescendantId))
return nil;
- BrowserAccessibilityManager* manager = browserAccessibility_->manager();
+ BrowserAccessibilityManager* manager = owner_->manager();
BrowserAccessibility* activeDescendant =
manager->GetFromID(activeDescendantId);
if (!activeDescendant)
@@ -1426,7 +1489,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)numberOfCharacters {
if (![self instanceActive])
return nil;
- base::string16 value = browserAccessibility_->GetValue();
+ base::string16 value = owner_->GetValue();
return [NSNumber numberWithUnsignedInt:value.size()];
}
@@ -1436,7 +1499,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSPoint)origin {
if (![self instanceActive])
return NSMakePoint(0, 0);
- gfx::Rect bounds = browserAccessibility_->GetPageBoundsRect();
+ gfx::Rect bounds = owner_->GetPageBoundsRect();
return NSMakePoint(bounds.x(), bounds.y());
}
@@ -1444,14 +1507,13 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
// A nil parent means we're the root.
- if (browserAccessibility_->PlatformGetParent()) {
- return NSAccessibilityUnignoredAncestor(ToBrowserAccessibilityCocoa(
- browserAccessibility_->PlatformGetParent()));
+ if (owner_->PlatformGetParent()) {
+ return NSAccessibilityUnignoredAncestor(
+ ToBrowserAccessibilityCocoa(owner_->PlatformGetParent()));
} else {
// Hook back up to RenderWidgetHostViewCocoa.
BrowserAccessibilityManagerMac* manager =
- browserAccessibility_->manager()->GetRootManager()
- ->ToBrowserAccessibilityManagerMac();
+ owner_->manager()->GetRootManager()->ToBrowserAccessibilityManagerMac();
if (manager)
return manager->GetParentView();
return nil;
@@ -1470,14 +1532,26 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)required {
if (![self instanceActive])
return nil;
- return [NSNumber numberWithBool:GetState(browserAccessibility_,
- ax::mojom::State::kRequired)];
+ return
+ [NSNumber numberWithBool:GetState(owner_, ax::mojom::State::kRequired)];
}
-// Returns an enum indicating the role from browserAccessibility_.
+// Returns an enum indicating the role from owner_.
// internal
- (ax::mojom::Role)internalRole {
- return static_cast<ax::mojom::Role>(browserAccessibility_->GetRole());
+ return static_cast<ax::mojom::Role>(owner_->GetRole());
+}
+
+- (BOOL)shouldExposeNameInDescription {
+ // VoiceOver will not read the label of a fieldset or radiogroup unless it is
+ // exposed in the description instead of the title.
+ switch (owner_->GetRole()) {
+ case ax::mojom::Role::kGroup:
+ case ax::mojom::Role::kRadioGroup:
+ return true;
+ default:
+ return false;
+ }
}
// Returns true if this object should expose its accessible name using
@@ -1487,23 +1561,20 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// internal
- (BOOL)shouldExposeTitleUIElement {
// VoiceOver ignores TitleUIElement if the element isn't a control.
- if (!ui::IsControl(browserAccessibility_->GetRole()))
+ if (!ui::IsControl(owner_->GetRole()))
return false;
- ax::mojom::NameFrom nameFrom =
- static_cast<ax::mojom::NameFrom>(browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kNameFrom));
+ ax::mojom::NameFrom nameFrom = static_cast<ax::mojom::NameFrom>(
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kNameFrom));
if (nameFrom != ax::mojom::NameFrom::kRelatedElement)
return false;
std::vector<int32_t> labelledby_ids =
- browserAccessibility_->GetIntListAttribute(
- ax::mojom::IntListAttribute::kLabelledbyIds);
+ owner_->GetIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds);
if (labelledby_ids.size() != 1)
return false;
- BrowserAccessibility* label =
- browserAccessibility_->manager()->GetFromID(labelledby_ids[0]);
+ BrowserAccessibility* label = owner_->manager()->GetFromID(labelledby_ids[0]);
if (!label)
return false;
@@ -1514,12 +1585,11 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// internal
- (content::BrowserAccessibilityDelegate*)delegate {
- return [self instanceActive] ? browserAccessibility_->manager()->delegate()
- : nil;
+ return [self instanceActive] ? owner_->manager()->delegate() : nil;
}
-- (content::BrowserAccessibility*)browserAccessibility {
- return browserAccessibility_;
+- (content::BrowserAccessibility*)owner {
+ return owner_;
}
// Assumes that there is at most one insertion, deletion or replacement at once.
@@ -1530,7 +1600,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// dispatch the actual text that changed on the value changed notification.
// We run this code on all macOS versions to get the highest test coverage.
base::string16 oldValue = oldValue_;
- base::string16 newValue = browserAccessibility_->GetValue();
+ base::string16 newValue = owner_->GetValue();
oldValue_ = newValue;
if (oldValue.empty() && newValue.empty())
return content::AXTextEdit();
@@ -1562,7 +1632,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
- (BOOL)instanceActive {
- return browserAccessibility_ && browserAccessibility_->instance_active();
+ return owner_ && owner_->instance_active();
}
// internal
@@ -1574,7 +1644,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// Get the delegate for the topmost BrowserAccessibilityManager, because
// that's the only one that can convert points to their origin in the screen.
BrowserAccessibilityDelegate* delegate =
- browserAccessibility_->manager()->GetDelegateFromRootManager();
+ owner_->manager()->GetDelegateFromRootManager();
if (delegate) {
gfx::Rect bounds(origin.x, origin.y, size.width, size.height);
gfx::Point point = delegate->AccessibilityOriginInScreen(bounds);
@@ -1591,25 +1661,23 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
ax::mojom::Role role = [self internalRole];
if (role == ax::mojom::Role::kCanvas &&
- browserAccessibility_->GetBoolAttribute(
- ax::mojom::BoolAttribute::kCanvasHasFallback)) {
+ owner_->GetBoolAttribute(ax::mojom::BoolAttribute::kCanvasHasFallback)) {
return NSAccessibilityGroupRole;
}
- if ((browserAccessibility_->IsPlainTextField() &&
- browserAccessibility_->HasState(ax::mojom::State::kMultiline)) ||
- browserAccessibility_->IsRichTextField()) {
+ if ((owner_->IsPlainTextField() &&
+ owner_->HasState(ax::mojom::State::kMultiline)) ||
+ owner_->IsRichTextField()) {
return NSAccessibilityTextAreaRole;
}
- if (role == ax::mojom::Role::kImage &&
- browserAccessibility_->HasExplicitlyEmptyName())
+ if (role == ax::mojom::Role::kImage && owner_->HasExplicitlyEmptyName())
return NSAccessibilityUnknownRole;
// If this is a web area for a presentational iframe, give it a role of
// something other than WebArea so that the fact that it's a separate doc
// is not exposed to AT.
- if (browserAccessibility_->IsWebAreaForPresentationalIframe())
+ if (owner_->IsWebAreaForPresentationalIframe())
return NSAccessibilityGroupRole;
return [AXPlatformNodeCocoa nativeRoleFromAXRole:role];
@@ -1620,10 +1688,10 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
- if (browserAccessibility_->HasStringAttribute(
+ if (owner_->HasStringAttribute(
ax::mojom::StringAttribute::kRoleDescription)) {
return NSStringForStringAttribute(
- browserAccessibility_, ax::mojom::StringAttribute::kRoleDescription);
+ owner_, ax::mojom::StringAttribute::kRoleDescription);
}
NSString* role = [self role];
@@ -1648,9 +1716,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (([role isEqualToString:NSAccessibilityGroupRole] ||
[role isEqualToString:NSAccessibilityRadioButtonRole]) &&
- !browserAccessibility_->IsWebAreaForPresentationalIframe()) {
+ !owner_->IsWebAreaForPresentationalIframe()) {
std::string role_attribute;
- if (browserAccessibility_->GetHtmlAttribute("role", &role_attribute)) {
+ if (owner_->GetHtmlAttribute("role", &role_attribute)) {
ax::mojom::Role internalRole = [self internalRole];
if ((internalRole != ax::mojom::Role::kGroup &&
internalRole != ax::mojom::Role::kListItem) ||
@@ -1742,17 +1810,17 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (BOOL)isRowHeaderForCurrentCell:(BrowserAccessibility*)header {
int cell_first_row = -1;
int cell_rowspan = -1;
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kAriaCellRowIndex, &cell_first_row);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kAriaCellRowIndex,
+ &cell_first_row);
if (cell_first_row < 0) {
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableCellRowIndex, &cell_first_row);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex,
+ &cell_first_row);
}
if (cell_first_row < 0)
return false;
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableCellRowSpan, &cell_rowspan);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowSpan,
+ &cell_rowspan);
if (cell_rowspan <= 0)
cell_rowspan = 1;
@@ -1787,9 +1855,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
- bool is_cell_or_table_header =
- ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole());
- bool is_table_like = ui::IsTableLikeRole(browserAccessibility_->GetRole());
+ bool is_cell_or_table_header = ui::IsCellOrTableHeaderRole(owner_->GetRole());
+ bool is_table_like = ui::IsTableLikeRole(owner_->GetRole());
if (!is_table_like && !is_cell_or_table_header)
return nil;
BrowserAccessibility* table = [self containingTable];
@@ -1807,21 +1874,18 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
headerIds.insert(id);
}
for (int32_t id : headerIds) {
- BrowserAccessibility* cell =
- browserAccessibility_->manager()->GetFromID(id);
+ BrowserAccessibility* cell = owner_->manager()->GetFromID(id);
if (cell)
[ret addObject:ToBrowserAccessibilityCocoa(cell)];
}
} else {
// Otherwise this is a cell, return the row headers for this cell.
int row = -1;
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableCellRowIndex, &row);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex, &row);
std::vector<int32_t> rowHeaderIds = table->GetRowHeaderNodeIds(row);
for (int32_t id : rowHeaderIds) {
- BrowserAccessibility* cell =
- browserAccessibility_->manager()->GetFromID(id);
+ BrowserAccessibility* cell = owner_->manager()->GetFromID(id);
if (cell)
[ret addObject:ToBrowserAccessibilityCocoa(cell)];
}
@@ -1833,15 +1897,13 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSValue*)rowIndexRange {
if (![self instanceActive])
return nil;
- if (!ui::IsCellOrTableHeaderRole(browserAccessibility_->GetRole()))
+ if (!ui::IsCellOrTableHeaderRole(owner_->GetRole()))
return nil;
int row = -1;
int rowspan = -1;
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableCellRowIndex, &row);
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableCellRowSpan, &rowspan);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex, &row);
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowSpan, &rowspan);
if (row >= 0 && rowspan >= 1)
return [NSValue valueWithRange:NSMakeRange(row, rowspan)];
return nil;
@@ -1859,13 +1921,11 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
[ret addObject:child];
}
} else if ([self internalRole] == ax::mojom::Role::kColumn) {
- const std::vector<int32_t>& indirectChildIds =
- browserAccessibility_->GetIntListAttribute(
- ax::mojom::IntListAttribute::kIndirectChildIds);
+ const std::vector<int32_t>& indirectChildIds = owner_->GetIntListAttribute(
+ ax::mojom::IntListAttribute::kIndirectChildIds);
for (uint32_t i = 0; i < indirectChildIds.size(); ++i) {
int id = indirectChildIds[i];
- BrowserAccessibility* rowElement =
- browserAccessibility_->manager()->GetFromID(id);
+ BrowserAccessibility* rowElement = owner_->manager()->GetFromID(id);
if (rowElement)
[ret addObject:ToBrowserAccessibilityCocoa(rowElement)];
}
@@ -1877,33 +1937,32 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)selected {
if (![self instanceActive])
return nil;
- // TODO(nektar): Implement.
- return [NSNumber numberWithBool:NO];
+ return [NSNumber numberWithBool:owner_->GetBoolAttribute(
+ ax::mojom::BoolAttribute::kSelected)];
}
- (NSArray*)selectedChildren {
if (![self instanceActive])
return nil;
NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
- BrowserAccessibilityManager* manager = browserAccessibility_->manager();
+ BrowserAccessibilityManager* manager = owner_->manager();
BrowserAccessibility* focusedChild = manager->GetFocus();
- if (!focusedChild->IsDescendantOf(browserAccessibility_))
+ if (!focusedChild->IsDescendantOf(owner_))
focusedChild = nullptr;
// If it's not multiselectable, try to skip iterating over the
// children.
- if (!GetState(browserAccessibility_, ax::mojom::State::kMultiselectable)) {
+ if (!GetState(owner_, ax::mojom::State::kMultiselectable)) {
// First try the focused child.
- if (focusedChild && focusedChild != browserAccessibility_) {
+ if (focusedChild && focusedChild != owner_) {
[ret addObject:ToBrowserAccessibilityCocoa(focusedChild)];
return ret;
}
// Next try the active descendant.
int activeDescendantId;
- if (browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kActivedescendantId,
- &activeDescendantId)) {
+ if (owner_->GetIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
+ &activeDescendantId)) {
BrowserAccessibility* activeDescendant =
manager->GetFromID(activeDescendantId);
if (activeDescendant) {
@@ -1916,18 +1975,15 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// If it's multiselectable or if the previous attempts failed,
// return any children with the "selected" state, which may
// come from aria-selected.
- uint32_t childCount = browserAccessibility_->PlatformChildCount();
+ uint32_t childCount = owner_->PlatformChildCount();
for (uint32_t index = 0; index < childCount; ++index) {
- BrowserAccessibility* child =
- browserAccessibility_->PlatformGetChild(index);
+ BrowserAccessibility* child = owner_->PlatformGetChild(index);
if (child->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected))
[ret addObject:ToBrowserAccessibilityCocoa(child)];
}
// And if nothing's selected but one has focus, use the focused one.
- if ([ret count] == 0 &&
- focusedChild &&
- focusedChild != browserAccessibility_) {
+ if ([ret count] == 0 && focusedChild && focusedChild != owner_) {
[ret addObject:ToBrowserAccessibilityCocoa(focusedChild)];
}
@@ -1940,10 +1996,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// TODO(nektar): Deprecate sel_start and sel_end attributes.
int selStart, selEnd;
- if (!browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTextSelStart, &selStart) ||
- !browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTextSelEnd, &selEnd)) {
+ if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart,
+ &selStart) ||
+ !owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &selEnd)) {
return nil;
}
@@ -1951,7 +2006,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
std::swap(selStart, selEnd);
int selLength = selEnd - selStart;
- base::string16 value = browserAccessibility_->GetValue();
+ base::string16 value = owner_->GetValue();
return base::SysUTF16ToNSString(value.substr(selStart, selLength));
}
@@ -1961,10 +2016,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// TODO(nektar): Deprecate sel_start and sel_end attributes.
int selStart, selEnd;
- if (!browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTextSelStart, &selStart) ||
- !browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTextSelEnd, &selEnd)) {
+ if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart,
+ &selStart) ||
+ !owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &selEnd)) {
return nil;
}
@@ -1979,7 +2033,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
- BrowserAccessibilityManager* manager = browserAccessibility_->manager();
+ BrowserAccessibilityManager* manager = owner_->manager();
if (!manager)
return nil;
@@ -2011,7 +2065,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSValue*)size {
if (![self instanceActive])
return nil;
- gfx::Rect bounds = browserAccessibility_->GetPageBoundsRect();
+ gfx::Rect bounds = owner_->GetPageBoundsRect();
return [NSValue valueWithSize:NSMakeSize(bounds.width(), bounds.height())];
}
@@ -2019,8 +2073,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
int sortDirection;
- if (!browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kSortDirection, &sortDirection))
+ if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kSortDirection,
+ &sortDirection))
return nil;
switch (static_cast<ax::mojom::SortDirection>(sortDirection)) {
@@ -2042,8 +2096,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// Returns a text marker that points to the first character in the document that
// can be selected with VoiceOver.
- (id)startTextMarker {
- const BrowserAccessibility* root =
- browserAccessibility_->manager()->GetRoot();
+ const BrowserAccessibility* root = owner_->manager()->GetRoot();
if (!root)
return nil;
@@ -2056,8 +2109,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
- if (browserAccessibility_->IsPlainTextField() &&
- GetState(browserAccessibility_, ax::mojom::State::kProtected)) {
+ if (owner_->IsPlainTextField() &&
+ GetState(owner_, ax::mojom::State::kProtected)) {
return NSAccessibilitySecureTextFieldSubrole;
}
@@ -2095,14 +2148,16 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (ui::IsNameExposedInAXValueForRole([self internalRole]))
return @"";
+ if ([self shouldExposeNameInDescription])
+ return @"";
+
// If we're exposing the title in TitleUIElement, don't also redundantly
// expose it in AXDescription.
if ([self shouldExposeTitleUIElement])
return @"";
- ax::mojom::NameFrom nameFrom =
- static_cast<ax::mojom::NameFrom>(browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kNameFrom));
+ ax::mojom::NameFrom nameFrom = static_cast<ax::mojom::NameFrom>(
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kNameFrom));
// On Mac OS X, cell titles are "" if it it came from content.
NSString* role = [self role];
@@ -2116,7 +2171,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (nameFrom == ax::mojom::NameFrom::kContents ||
nameFrom == ax::mojom::NameFrom::kRelatedElement ||
nameFrom == ax::mojom::NameFrom::kValue) {
- return NSStringForStringAttribute(browserAccessibility_,
+ return NSStringForStringAttribute(owner_,
ax::mojom::StringAttribute::kName);
}
@@ -2130,15 +2185,13 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return nil;
std::vector<int32_t> labelledby_ids =
- browserAccessibility_->GetIntListAttribute(
- ax::mojom::IntListAttribute::kLabelledbyIds);
- ax::mojom::NameFrom nameFrom =
- static_cast<ax::mojom::NameFrom>(browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kNameFrom));
+ owner_->GetIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds);
+ ax::mojom::NameFrom nameFrom = static_cast<ax::mojom::NameFrom>(
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kNameFrom));
if (nameFrom == ax::mojom::NameFrom::kRelatedElement &&
labelledby_ids.size() == 1) {
BrowserAccessibility* titleElement =
- browserAccessibility_->manager()->GetFromID(labelledby_ids[0]);
+ owner_->manager()->GetFromID(labelledby_ids[0]);
if (titleElement)
return ToBrowserAccessibilityCocoa(titleElement);
}
@@ -2151,10 +2204,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return nil;
std::string url;
if ([[self role] isEqualToString:@"AXWebArea"])
- url = browserAccessibility_->manager()->GetTreeData().url;
+ url = owner_->manager()->GetTreeData().url;
else
- url = browserAccessibility_->GetStringAttribute(
- ax::mojom::StringAttribute::kUrl);
+ url = owner_->GetStringAttribute(ax::mojom::StringAttribute::kUrl);
if (url.empty())
return nil;
@@ -2167,26 +2219,24 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return nil;
if (ui::IsNameExposedInAXValueForRole([self internalRole]))
- return NSStringForStringAttribute(browserAccessibility_,
+ return NSStringForStringAttribute(owner_,
ax::mojom::StringAttribute::kName);
NSString* role = [self role];
if ([role isEqualToString:@"AXHeading"]) {
int level = 0;
- if (browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kHierarchicalLevel, &level)) {
+ if (owner_->GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel,
+ &level)) {
return [NSNumber numberWithInt:level];
}
} else if ([role isEqualToString:NSAccessibilityButtonRole]) {
// AXValue does not make sense for pure buttons.
return @"";
- } else if (browserAccessibility_->HasIntAttribute(
- ax::mojom::IntAttribute::kCheckedState) ||
+ } else if (owner_->HasIntAttribute(ax::mojom::IntAttribute::kCheckedState) ||
[role isEqualToString:NSAccessibilityRadioButtonRole]) {
int value;
const auto checkedState = static_cast<ax::mojom::CheckedState>(
- browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kCheckedState));
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kCheckedState));
switch (checkedState) {
case ax::mojom::CheckedState::kTrue:
value = 1;
@@ -2195,8 +2245,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
value = 2;
break;
default:
- value = browserAccessibility_->GetBoolAttribute(
- ax::mojom::BoolAttribute::kSelected)
+ value = owner_->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected)
? 1
: 0;
break;
@@ -2207,16 +2256,15 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
[role isEqualToString:NSAccessibilityIncrementorRole] ||
[role isEqualToString:NSAccessibilityScrollBarRole] ||
([role isEqualToString:NSAccessibilitySplitterRole] &&
- browserAccessibility_->HasState(ax::mojom::State::kFocusable))) {
+ owner_->HasState(ax::mojom::State::kFocusable))) {
float floatValue;
- if (browserAccessibility_->GetFloatAttribute(
- ax::mojom::FloatAttribute::kValueForRange, &floatValue)) {
+ if (owner_->GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange,
+ &floatValue)) {
return [NSNumber numberWithFloat:floatValue];
}
} else if ([role isEqualToString:NSAccessibilityColorWellRole]) {
- unsigned int color =
- static_cast<unsigned int>(browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kColorValue));
+ unsigned int color = static_cast<unsigned int>(
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kColorValue));
unsigned int red = SkColorGetR(color);
unsigned int green = SkColorGetG(color);
unsigned int blue = SkColorGetB(color);
@@ -2225,21 +2273,47 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
red / 255., green / 255., blue / 255.];
}
- return base::SysUTF16ToNSString(browserAccessibility_->GetValue());
+ return base::SysUTF16ToNSString(owner_->GetValue());
}
+- (BOOL)isFocusedInputWithSuggestions {
+ if (!owner_->IsPlainTextField())
+ return false;
+ BrowserAccessibilityManager* manager = owner_->manager();
+ if (manager->GetFocus() != owner_)
+ return false;
+ return ui::AXPlatformNode::HasInputSuggestions();
+}
+
+- (NSNumber*)valueAutofillAvailable {
+ if (![self instanceActive])
+ return nil;
+ return [self isFocusedInputWithSuggestions] ? @YES : @NO;
+}
+
+// Not currently supported, as Chrome does not store whether an autofill
+// occurred. We could have autofill fire an event, however, and set an
+// "is_autofilled" flag until the next edit. - (NSNumber*)valueAutofilled {
+// return @NO;
+// }
+
+// Not currently supported, as Chrome's autofill types aren't like Safari's.
+// - (NSString*)valueAutofillType {
+// return @"none";
+//}
+
- (NSString*)valueDescription {
if (![self instanceActive])
return nil;
- if (browserAccessibility_)
- return base::SysUTF16ToNSString(browserAccessibility_->GetValue());
+ if (owner_)
+ return base::SysUTF16ToNSString(owner_->GetValue());
return nil;
}
- (NSValue*)visibleCharacterRange {
if (![self instanceActive])
return nil;
- base::string16 value = browserAccessibility_->GetValue();
+ base::string16 value = owner_->GetValue();
return [NSValue valueWithRange:NSMakeRange(0, value.size())];
}
@@ -2248,16 +2322,14 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return nil;
ui::AXTableInfo* table_info =
- browserAccessibility_->manager()->ax_tree()->GetTableInfo(
- browserAccessibility_->node());
+ owner_->manager()->ax_tree()->GetTableInfo(owner_->node());
if (!table_info)
return nil;
NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease];
for (size_t i = 0; i < table_info->unique_cell_ids.size(); ++i) {
int id = table_info->unique_cell_ids[i];
- BrowserAccessibility* cell =
- browserAccessibility_->manager()->GetFromID(id);
+ BrowserAccessibility* cell = owner_->manager()->GetFromID(id);
if (cell)
[ret addObject:ToBrowserAccessibilityCocoa(cell)];
}
@@ -2285,8 +2357,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
- (NSNumber*)visited {
if (![self instanceActive])
return nil;
- return [NSNumber numberWithBool:GetState(browserAccessibility_,
- ax::mojom::State::kVisited)];
+ return [NSNumber numberWithBool:GetState(owner_, ax::mojom::State::kVisited)];
}
- (id)window {
@@ -2294,8 +2365,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return nil;
BrowserAccessibilityManagerMac* manager =
- browserAccessibility_->manager()->GetRootManager()
- ->ToBrowserAccessibilityManagerMac();
+ owner_->manager()->GetRootManager()->ToBrowserAccessibilityManagerMac();
if (!manager || !manager->GetParentView())
return nil;
@@ -2314,7 +2384,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
- base::string16 value = browserAccessibility_->GetValue();
+ base::string16 value = owner_->GetValue();
if (NSMaxRange(range) > value.length())
return nil;
@@ -2325,9 +2395,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
- base::string16 text = browserAccessibility_->GetValue();
- if (browserAccessibility_->IsTextOnlyObject() && text.empty())
- text = browserAccessibility_->GetText();
+ base::string16 text = owner_->GetValue();
+ if (owner_->IsTextOnlyObject() && text.empty())
+ text = owner_->GetText();
// We need to get the whole text because a spelling mistake might start or end
// outside our range.
@@ -2335,10 +2405,10 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
NSMutableAttributedString* attributedValue =
[[[NSMutableAttributedString alloc] initWithString:value] autorelease];
- if (!browserAccessibility_->IsTextOnlyObject()) {
+ if (!owner_->IsTextOnlyObject()) {
std::vector<const BrowserAccessibility*> textOnlyObjects =
- BrowserAccessibilityManager::FindTextOnlyObjectsInRange(
- *browserAccessibility_, *browserAccessibility_);
+ BrowserAccessibilityManager::FindTextOnlyObjectsInRange(*owner_,
+ *owner_);
AddMisspelledTextAttributes(textOnlyObjects, attributedValue);
}
@@ -2366,9 +2436,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
- const std::vector<int> line_breaks =
- browserAccessibility_->GetLineStartOffsets();
- base::string16 value = browserAccessibility_->GetValue();
+ const std::vector<int> line_breaks = owner_->GetLineStartOffsets();
+ base::string16 value = owner_->GetValue();
int len = static_cast<int>(value.size());
if ([attribute isEqualToString:
@@ -2417,18 +2486,16 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
NSArray* array = parameter;
int column = [[array objectAtIndex:0] intValue];
int row = [[array objectAtIndex:1] intValue];
- int num_columns = browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableColumnCount);
- int num_rows = browserAccessibility_->GetIntAttribute(
- ax::mojom::IntAttribute::kTableRowCount);
+ int num_columns =
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount);
+ int num_rows =
+ owner_->GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount);
if (column < 0 || column >= num_columns ||
row < 0 || row >= num_rows) {
return nil;
}
- for (size_t i = 0;
- i < browserAccessibility_->PlatformChildCount();
- ++i) {
- BrowserAccessibility* child = browserAccessibility_->PlatformGetChild(i);
+ for (size_t i = 0; i < owner_->PlatformChildCount(); ++i) {
+ BrowserAccessibility* child = owner_->PlatformGetChild(i);
if (child->GetRole() != ax::mojom::Role::kRow)
continue;
int rowIndex;
@@ -2471,7 +2538,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if ([attribute isEqualToString:@"AXTextMarkerRangeForUIElement"]) {
BrowserAccessibilityPositionInstance startPosition =
- browserAccessibility_->CreatePositionAt(0);
+ owner_->CreatePositionAt(0);
BrowserAccessibilityPositionInstance endPosition =
startPosition->CreatePositionAtEndOfAnchor();
AXPlatformRange range =
@@ -2643,8 +2710,8 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if ([self internalRole] != ax::mojom::Role::kStaticText)
return nil;
NSRange range = [(NSValue*)parameter rangeValue];
- gfx::Rect rect = browserAccessibility_->GetScreenBoundsForRange(
- range.location, range.length);
+ gfx::Rect rect =
+ owner_->GetScreenBoundsForRange(range.location, range.length);
NSPoint origin = NSMakePoint(rect.x(), rect.y());
NSSize size = NSMakeSize(rect.width(), rect.height());
NSPoint pointInScreen = [self pointInScreen:origin size:size];
@@ -2654,14 +2721,14 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
if ([attribute isEqualToString:@"AXUIElementCountForSearchPredicate"]) {
- OneShotAccessibilityTreeSearch search(browserAccessibility_);
+ OneShotAccessibilityTreeSearch search(owner_);
if (InitializeAccessibilityTreeSearch(&search, parameter))
return [NSNumber numberWithInt:search.CountMatches()];
return nil;
}
if ([attribute isEqualToString:@"AXUIElementsForSearchPredicate"]) {
- OneShotAccessibilityTreeSearch search(browserAccessibility_);
+ OneShotAccessibilityTreeSearch search(owner_);
if (InitializeAccessibilityTreeSearch(&search, parameter)) {
size_t count = search.CountMatches();
NSMutableArray* result = [NSMutableArray arrayWithCapacity:count];
@@ -2744,11 +2811,11 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
BrowserAccessibilityCocoa* childCocoaObj =
(BrowserAccessibilityCocoa*)parameter;
- BrowserAccessibility* child = [childCocoaObj browserAccessibility];
+ BrowserAccessibility* child = [childCocoaObj owner];
if (!child)
return nil;
- if (child->PlatformGetParent() != browserAccessibility_)
+ if (child->PlatformGetParent() != owner_)
return nil;
return @(child->GetIndexInParent());
@@ -2806,7 +2873,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
]];
}
- if (browserAccessibility_->HasState(ax::mojom::State::kEditable)) {
+ if (owner_->HasState(ax::mojom::State::kEditable)) {
[ret addObjectsFromArray:@[
NSAccessibilityLineForIndexParameterizedAttribute,
NSAccessibilityRangeForLineParameterizedAttribute,
@@ -2847,10 +2914,10 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
NSAccessibilityScrollToVisibleAction, nil];
// VoiceOver expects the "press" action to be first.
- if (browserAccessibility_->IsClickable())
+ if (owner_->IsClickable())
[actions insertObject:NSAccessibilityPressAction atIndex:0];
- if (ui::IsMenuRelated(browserAccessibility_->GetRole()))
+ if (ui::IsMenuRelated(owner_->GetRole()))
[actions addObject:NSAccessibilityCancelAction];
if ([self internalRole] == ax::mojom::Role::kSlider ||
@@ -2910,12 +2977,10 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
NSAccessibilityChildrenAttribute,
NSAccessibilityDescriptionAttribute,
NSAccessibilityDOMIdentifierAttribute,
- NSAccessibilityEditableAncestorAttribute,
NSAccessibilityEnabledAttribute,
NSAccessibilityEndTextMarkerAttribute,
NSAccessibilityFocusedAttribute,
NSAccessibilityHelpAttribute,
- NSAccessibilityHighestEditableAncestorAttribute,
NSAccessibilityInvalidAttribute,
NSAccessibilityLinkedUIElementsAttribute,
NSAccessibilityParentAttribute,
@@ -2981,7 +3046,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
[role isEqualToString:NSAccessibilityIncrementorRole] ||
[role isEqualToString:NSAccessibilityScrollBarRole] ||
([role isEqualToString:NSAccessibilitySplitterRole] &&
- browserAccessibility_->HasState(ax::mojom::State::kFocusable))) {
+ owner_->HasState(ax::mojom::State::kFocusable))) {
[ret addObjectsFromArray:@[
NSAccessibilityMaxValueAttribute, NSAccessibilityMinValueAttribute,
NSAccessibilityValueDescriptionAttribute
@@ -2994,10 +3059,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
NSAccessibilityDisclosedRowsAttribute
]];
} else if ([role isEqualToString:NSAccessibilityRowRole]) {
- if (browserAccessibility_->PlatformGetParent()) {
+ if (owner_->PlatformGetParent()) {
base::string16 parentRole;
- browserAccessibility_->PlatformGetParent()->GetHtmlAttribute("role",
- &parentRole);
+ owner_->PlatformGetParent()->GetHtmlAttribute("role", &parentRole);
const base::string16 treegridRole(base::ASCIIToUTF16("treegrid"));
if (parentRole == treegridRole) {
[ret addObjectsFromArray:@[
@@ -3018,13 +3082,28 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
// Caret navigation and text selection attributes.
- if (browserAccessibility_->HasState(ax::mojom::State::kEditable)) {
+ if (owner_->HasState(ax::mojom::State::kEditable)) {
[ret addObjectsFromArray:@[
+ NSAccessibilityAutocompleteValueAttribute,
NSAccessibilityInsertionPointLineNumberAttribute,
NSAccessibilityNumberOfCharactersAttribute,
NSAccessibilitySelectedTextAttribute,
NSAccessibilitySelectedTextRangeAttribute,
- NSAccessibilityVisibleCharacterRangeAttribute
+ NSAccessibilityVisibleCharacterRangeAttribute,
+ NSAccessibilityValueAutofillAvailableAttribute,
+ // Not currently supported by Chrome:
+ // NSAccessibilityValueAutofilledAttribute,
+ // Not currently supported by Chrome:
+ // NSAccessibilityValueAutofillTypeAttribute
+ ]];
+ }
+
+ // Add ancestor attributes if not a web area.
+ if (![role isEqualToString:@"AXWebArea"]) {
+ [ret addObjectsFromArray:@[
+ NSAccessibilityEditableAncestorAttribute,
+ NSAccessibilityFocusableAncestorAttribute,
+ NSAccessibilityHighestEditableAncestorAttribute
]];
}
@@ -3034,69 +3113,67 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
// Position in set and Set size
- if (browserAccessibility_->HasIntAttribute(
- ax::mojom::IntAttribute::kPosInSet)) {
+ if (owner_->HasIntAttribute(ax::mojom::IntAttribute::kPosInSet)) {
[ret addObjectsFromArray:@[ NSAccessibilityARIAPosInSetAttribute ]];
}
- if (browserAccessibility_->HasIntAttribute(
- ax::mojom::IntAttribute::kSetSize)) {
+ if (owner_->HasIntAttribute(ax::mojom::IntAttribute::kSetSize)) {
[ret addObjectsFromArray:@[ NSAccessibilityARIASetSizeAttribute ]];
}
// Live regions.
- if (browserAccessibility_->HasStringAttribute(
- ax::mojom::StringAttribute::kLiveStatus)) {
+ if (owner_->HasStringAttribute(ax::mojom::StringAttribute::kLiveStatus)) {
[ret addObjectsFromArray:@[ NSAccessibilityARIALiveAttribute ]];
}
- if (browserAccessibility_->HasStringAttribute(
- ax::mojom::StringAttribute::kLiveRelevant)) {
+ if (owner_->HasStringAttribute(ax::mojom::StringAttribute::kLiveRelevant)) {
[ret addObjectsFromArray:@[ NSAccessibilityARIARelevantAttribute ]];
}
- if (browserAccessibility_->HasBoolAttribute(
- ax::mojom::BoolAttribute::kLiveAtomic)) {
+ if (owner_->HasBoolAttribute(ax::mojom::BoolAttribute::kLiveAtomic)) {
[ret addObjectsFromArray:@[ NSAccessibilityARIAAtomicAttribute ]];
}
- if (browserAccessibility_->HasBoolAttribute(
- ax::mojom::BoolAttribute::kBusy)) {
+ if (owner_->HasBoolAttribute(ax::mojom::BoolAttribute::kBusy)) {
[ret addObjectsFromArray:@[ NSAccessibilityARIABusyAttribute ]];
}
std::string dropEffect;
- if (browserAccessibility_->GetHtmlAttribute("aria-dropeffect", &dropEffect)) {
+ if (owner_->GetHtmlAttribute("aria-dropeffect", &dropEffect)) {
[ret addObjectsFromArray:@[ NSAccessibilityDropEffectsAttribute ]];
}
std::string grabbed;
- if (browserAccessibility_->GetHtmlAttribute("aria-grabbed", &grabbed)) {
+ if (owner_->GetHtmlAttribute("aria-grabbed", &grabbed)) {
[ret addObjectsFromArray:@[ NSAccessibilityGrabbedAttribute ]];
}
- if (browserAccessibility_->HasState(ax::mojom::State::kHasPopup)) {
- [ret addObjectsFromArray:@[ NSAccessibilityHasPopupAttribute ]];
+ if (owner_->HasIntAttribute(ax::mojom::IntAttribute::kHasPopup)) {
+ [ret addObjectsFromArray:@[
+ NSAccessibilityHasPopupAttribute, NSAccessibilityHasPopupValueAttribute
+ ]];
+ }
+
+ if (owner_->HasBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
+ [ret addObjectsFromArray:@[ NSAccessibilitySelectedAttribute ]];
}
// Add expanded attribute only if it has expanded or collapsed state.
- if (GetState(browserAccessibility_, ax::mojom::State::kExpanded) ||
- GetState(browserAccessibility_, ax::mojom::State::kCollapsed)) {
+ if (GetState(owner_, ax::mojom::State::kExpanded) ||
+ GetState(owner_, ax::mojom::State::kCollapsed)) {
[ret addObjectsFromArray:@[ NSAccessibilityExpandedAttribute ]];
}
- if (GetState(browserAccessibility_, ax::mojom::State::kVertical) ||
- GetState(browserAccessibility_, ax::mojom::State::kHorizontal)) {
+ if (GetState(owner_, ax::mojom::State::kVertical) ||
+ GetState(owner_, ax::mojom::State::kHorizontal)) {
[ret addObjectsFromArray:@[ NSAccessibilityOrientationAttribute ]];
}
- if (browserAccessibility_->HasStringAttribute(
- ax::mojom::StringAttribute::kPlaceholder)) {
+ if (owner_->HasStringAttribute(ax::mojom::StringAttribute::kPlaceholder)) {
[ret addObjectsFromArray:@[ NSAccessibilityPlaceholderValueAttribute ]];
}
- if (GetState(browserAccessibility_, ax::mojom::State::kRequired)) {
+ if (GetState(owner_, ax::mojom::State::kRequired)) {
[ret addObjectsFromArray:@[ @"AXRequired" ]];
}
- if (browserAccessibility_->HasStringAttribute(
- ax::mojom::StringAttribute::kLanguage)) {
+ if (owner_->HasStringAttribute(ax::mojom::StringAttribute::kLanguage)) {
[ret addObjectsFromArray:@[ NSAccessibilityLanguageAttribute ]];
}
@@ -3107,10 +3184,9 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
}
// Title UI Element.
- if (browserAccessibility_->HasIntListAttribute(
+ if (owner_->HasIntListAttribute(
ax::mojom::IntListAttribute::kLabelledbyIds) &&
- browserAccessibility_
- ->GetIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds)
+ owner_->GetIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds)
.size() > 0) {
[ret addObjectsFromArray:@[ NSAccessibilityTitleUIElementAttribute ]];
}
@@ -3144,14 +3220,14 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if ([self internalRole] == ax::mojom::Role::kDateTime)
return NO;
- return GetState(browserAccessibility_, ax::mojom::State::kFocusable);
+ return GetState(owner_, ax::mojom::State::kFocusable);
}
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
- return browserAccessibility_->HasAction(ax::mojom::Action::kSetValue);
+ return owner_->HasAction(ax::mojom::Action::kSetValue);
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute] &&
- browserAccessibility_->HasState(ax::mojom::State::kEditable)) {
+ owner_->HasState(ax::mojom::State::kEditable)) {
return YES;
}
@@ -3174,18 +3250,17 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return;
// TODO(dmazzoni): Support more actions.
- BrowserAccessibilityManager* manager = browserAccessibility_->manager();
+ BrowserAccessibilityManager* manager = owner_->manager();
if ([action isEqualToString:NSAccessibilityPressAction]) {
- manager->DoDefaultAction(*browserAccessibility_);
+ manager->DoDefaultAction(*owner_);
} else if ([action isEqualToString:NSAccessibilityShowMenuAction]) {
- manager->ShowContextMenu(*browserAccessibility_);
+ manager->ShowContextMenu(*owner_);
} else if ([action isEqualToString:NSAccessibilityScrollToVisibleAction]) {
- manager->ScrollToMakeVisible(
- *browserAccessibility_, gfx::Rect());
+ manager->ScrollToMakeVisible(*owner_, gfx::Rect());
} else if ([action isEqualToString:NSAccessibilityIncrementAction]) {
- manager->Increment(*browserAccessibility_);
+ manager->Increment(*owner_);
} else if ([action isEqualToString:NSAccessibilityDecrementAction]) {
- manager->Decrement(*browserAccessibility_);
+ manager->Decrement(*owner_);
}
}
@@ -3212,18 +3287,18 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
return;
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
- BrowserAccessibilityManager* manager = browserAccessibility_->manager();
+ BrowserAccessibilityManager* manager = owner_->manager();
NSNumber* focusedNumber = value;
BOOL focused = [focusedNumber intValue];
if (focused)
- manager->SetFocus(*browserAccessibility_);
+ manager->SetFocus(*owner_);
}
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
NSRange range = [(NSValue*)value rangeValue];
- BrowserAccessibilityManager* manager = browserAccessibility_->manager();
- manager->SetSelection(AXPlatformRange(
- browserAccessibility_->CreatePositionAt(range.location),
- browserAccessibility_->CreatePositionAt(NSMaxRange(range))));
+ BrowserAccessibilityManager* manager = owner_->manager();
+ manager->SetSelection(
+ AXPlatformRange(owner_->CreatePositionAt(range.location),
+ owner_->CreatePositionAt(NSMaxRange(range))));
}
}
@@ -3235,7 +3310,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
if (![self instanceActive])
return nil;
- BrowserAccessibilityManager* manager = browserAccessibility_->manager();
+ BrowserAccessibilityManager* manager = owner_->manager();
gfx::Point screen_point(point.x, point.y);
screen_point += manager->GetViewBounds().OffsetFromOrigin();
@@ -3256,7 +3331,7 @@ NSString* const NSAccessibilityRequiredAttributeChrome = @"AXRequired";
// Potentially called during dealloc.
if (![self instanceActive])
return [super hash];
- return browserAccessibility_->GetId();
+ return owner_->GetId();
}
- (BOOL)accessibilityNotifiesWhenDestroyed {
diff --git a/chromium/content/browser/accessibility/browser_accessibility_com_win.cc b/chromium/content/browser/accessibility/browser_accessibility_com_win.cc
index 0cd7fd5a2d0..ce687913fb2 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -4,9 +4,6 @@
#include "content/browser/accessibility/browser_accessibility_com_win.h"
-#include <UIAutomationClient.h>
-#include <UIAutomationCoreApi.h>
-
#include <algorithm>
#include <iterator>
#include <utility>
@@ -1550,97 +1547,10 @@ STDMETHODIMP BrowserAccessibilityComWin::QueryService(REFGUID guid_service,
return QueryInterface(riid, object);
}
- // We only support the IAccessibleEx interface on Windows 8 and above. This
- // is needed for the on-screen Keyboard to show up in metro mode, when the
- // user taps an editable portion on the page.
- // All methods in the IAccessibleEx interface are unimplemented.
- if (riid == IID_IAccessibleEx &&
- base::win::GetVersion() >= base::win::VERSION_WIN8) {
- return QueryInterface(riid, object);
- }
-
*object = NULL;
return E_FAIL;
}
-STDMETHODIMP
-BrowserAccessibilityComWin::GetObjectForChild(long child_id,
- IAccessibleEx** ret) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_OBJECT_FOR_CHILD);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP
-BrowserAccessibilityComWin::GetIAccessiblePair(IAccessible** acc,
- long* child_id) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_IACCESSIBLE_PAIR);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP BrowserAccessibilityComWin::GetRuntimeId(SAFEARRAY** runtime_id) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_RUNTIME_ID);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP
-BrowserAccessibilityComWin::ConvertReturnedElement(
- IRawElementProviderSimple* element,
- IAccessibleEx** acc) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_CONVERT_RETURNED_ELEMENT);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP BrowserAccessibilityComWin::GetPatternProvider(
- PATTERNID id,
- IUnknown** provider) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PATTERN_PROVIDER);
- DVLOG(1) << "In Function: " << __func__ << " for pattern id: " << id;
- if (!owner())
- return E_FAIL;
-
- if (id == UIA_ValuePatternId || id == UIA_TextPatternId) {
- if (owner()->HasState(ax::mojom::State::kEditable)) {
- DVLOG(1) << "Returning UIA text provider";
- base::win::UIATextProvider::CreateTextProvider(GetRangeValueText(), true,
- provider);
- return S_OK;
- }
- }
- return E_NOTIMPL;
-}
-
-STDMETHODIMP BrowserAccessibilityComWin::GetPropertyValue(PROPERTYID id,
- VARIANT* ret) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PROPERTY_VALUE);
- DVLOG(1) << "In Function: " << __func__ << " for property id: " << id;
- if (!owner())
- return E_FAIL;
-
- V_VT(ret) = VT_EMPTY;
- if (id == UIA_ControlTypePropertyId) {
- if (owner()->HasState(ax::mojom::State::kEditable)) {
- V_VT(ret) = VT_I4;
- ret->lVal = UIA_EditControlTypeId;
- DVLOG(1) << "Returning Edit control type";
- } else {
- DVLOG(1) << "Returning empty control type";
- }
- }
- return S_OK;
-}
-
-STDMETHODIMP BrowserAccessibilityComWin::get_ProviderOptions(
- ProviderOptions* ret) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_PROVIDER_OPTIONS);
- return E_NOTIMPL;
-}
-
-STDMETHODIMP BrowserAccessibilityComWin::get_HostRawElementProvider(
- IRawElementProviderSimple** provider) {
- WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_GET_HOST_RAW_ELEMENT_PROVIDER);
- return E_NOTIMPL;
-}
-
//
// CComObjectRootEx methods.
//
@@ -1807,16 +1717,26 @@ void BrowserAccessibilityComWin::UpdateStep2ComputeHypertext() {
void BrowserAccessibilityComWin::UpdateStep3FireEvents(
bool is_subtree_creation) {
+ int32_t state = MSAAState();
+
// Fire an event when a new subtree is created.
if (is_subtree_creation)
FireNativeEvent(EVENT_OBJECT_SHOW);
// The rest of the events only fire on changes, not on new objects.
+
+ bool did_fire_namechange = false;
+
if (old_win_attributes_->ia_role != 0 ||
!old_win_attributes_->role_name.empty()) {
// Fire an event if the name, description, help, or value changes.
- if (name() != old_win_attributes_->name)
+ if (name() != old_win_attributes_->name &&
+ GetData().GetNameFrom() != ax::mojom::NameFrom::kContents) {
+ // Only fire name changes when the name comes from an attribute, otherwise
+ // name changes are redundant with text removed/inserted events.
FireNativeEvent(EVENT_OBJECT_NAMECHANGE);
+ did_fire_namechange = true;
+ }
if (description() != old_win_attributes_->description)
FireNativeEvent(EVENT_OBJECT_DESCRIPTIONCHANGE);
if (value() != old_win_attributes_->value)
@@ -1824,14 +1744,14 @@ void BrowserAccessibilityComWin::UpdateStep3FireEvents(
// Do not fire EVENT_OBJECT_STATECHANGE if the change was due to a focus
// change.
- if ((MSAAState() & ~STATE_SYSTEM_FOCUSED) !=
+ if ((state & ~STATE_SYSTEM_FOCUSED) !=
(old_win_attributes_->ia_state & ~STATE_SYSTEM_FOCUSED) ||
ComputeIA2State() != old_win_attributes_->ia2_state) {
FireNativeEvent(EVENT_OBJECT_STATECHANGE);
}
// Handle selection being added or removed.
- bool is_selected_now = (MSAAState() & STATE_SYSTEM_SELECTED) != 0;
+ bool is_selected_now = (state & STATE_SYSTEM_SELECTED) != 0;
bool was_selected_before =
(old_win_attributes_->ia_state & STATE_SYSTEM_SELECTED) != 0;
if (is_selected_now || was_selected_before) {
@@ -1866,17 +1786,22 @@ void BrowserAccessibilityComWin::UpdateStep3FireEvents(
}
// Fire hypertext-related events.
- int start, old_len, new_len;
- ComputeHypertextRemovedAndInserted(&start, &old_len, &new_len);
- if (old_len > 0) {
- // In-process screen readers may call IAccessibleText::get_oldText
- // in reaction to this event to retrieve the text that was removed.
- FireNativeEvent(IA2_EVENT_TEXT_REMOVED);
- }
- if (new_len > 0) {
- // In-process screen readers may call IAccessibleText::get_newText
- // in reaction to this event to retrieve the text that was inserted.
- FireNativeEvent(IA2_EVENT_TEXT_INSERTED);
+ // Do not fire removed/inserted when a name change event was also fired, as
+ // they are providing redundant information and will lead to duplicate
+ // announcements.
+ if (!did_fire_namechange) {
+ int start, old_len, new_len;
+ ComputeHypertextRemovedAndInserted(&start, &old_len, &new_len);
+ if (old_len > 0) {
+ // In-process screen readers may call IAccessibleText::get_oldText
+ // in reaction to this event to retrieve the text that was removed.
+ FireNativeEvent(IA2_EVENT_TEXT_REMOVED);
+ }
+ if (new_len > 0) {
+ // In-process screen readers may call IAccessibleText::get_newText
+ // in reaction to this event to retrieve the text that was inserted.
+ FireNativeEvent(IA2_EVENT_TEXT_INSERTED);
+ }
}
// Changing a static text node can affect the IA2 hypertext of its parent
diff --git a/chromium/content/browser/accessibility/browser_accessibility_com_win.h b/chromium/content/browser/accessibility/browser_accessibility_com_win.h
index debd107f060..4ce9c39ccf7 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_com_win.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_com_win.h
@@ -12,8 +12,6 @@
#include <stdint.h>
#include <vector>
-#include <UIAutomationCore.h>
-
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
@@ -69,19 +67,15 @@ class __declspec(uuid("562072fe-3390-43b1-9e2c-dd4118f5ac79"))
public IAccessibleValue,
public ISimpleDOMDocument,
public ISimpleDOMNode,
- public ISimpleDOMText,
- public IAccessibleEx,
- public IRawElementProviderSimple {
+ public ISimpleDOMText {
public:
BEGIN_COM_MAP(BrowserAccessibilityComWin)
COM_INTERFACE_ENTRY(IAccessibleAction)
COM_INTERFACE_ENTRY(IAccessibleApplication)
- COM_INTERFACE_ENTRY(IAccessibleEx)
COM_INTERFACE_ENTRY(IAccessibleHyperlink)
COM_INTERFACE_ENTRY(IAccessibleHypertext)
COM_INTERFACE_ENTRY(IAccessibleImage)
COM_INTERFACE_ENTRY(IAccessibleValue)
- COM_INTERFACE_ENTRY(IRawElementProviderSimple)
COM_INTERFACE_ENTRY(ISimpleDOMDocument)
COM_INTERFACE_ENTRY(ISimpleDOMNode)
COM_INTERFACE_ENTRY(ISimpleDOMText)
@@ -378,37 +372,6 @@ class __declspec(uuid("562072fe-3390-43b1-9e2c-dd4118f5ac79"))
REFIID riid,
void** object) override;
- // IAccessibleEx methods not implemented.
- CONTENT_EXPORT STDMETHODIMP GetObjectForChild(long child_id,
- IAccessibleEx** ret) override;
-
- CONTENT_EXPORT STDMETHODIMP GetIAccessiblePair(IAccessible** acc,
- long* child_id) override;
-
- CONTENT_EXPORT STDMETHODIMP GetRuntimeId(SAFEARRAY** runtime_id) override;
-
- CONTENT_EXPORT STDMETHODIMP
- ConvertReturnedElement(IRawElementProviderSimple* element,
- IAccessibleEx** acc) override;
-
- //
- // IRawElementProviderSimple methods.
- //
- // The GetPatternProvider/GetPropertyValue methods need to be implemented for
- // the on-screen keyboard to show up in Windows 8 metro.
- CONTENT_EXPORT STDMETHODIMP GetPatternProvider(PATTERNID id,
- IUnknown** provider) override;
- CONTENT_EXPORT STDMETHODIMP GetPropertyValue(PROPERTYID id,
- VARIANT* ret) override;
-
- //
- // IRawElementProviderSimple methods not implemented
- //
- CONTENT_EXPORT STDMETHODIMP
- get_ProviderOptions(enum ProviderOptions* ret) override;
- CONTENT_EXPORT STDMETHODIMP
- get_HostRawElementProvider(IRawElementProviderSimple** provider) override;
-
//
// CComObjectRootEx methods.
//
diff --git a/chromium/content/browser/accessibility/browser_accessibility_mac.h b/chromium/content/browser/accessibility/browser_accessibility_mac.h
index d5160243274..d2cc8d75974 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_mac.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_mac.h
@@ -30,6 +30,8 @@ class BrowserAccessibilityMac : public BrowserAccessibility {
void NativeReleaseReference() override;
bool IsNative() const override;
void OnDataChanged() override;
+ uint32_t PlatformChildCount() const override;
+ BrowserAccessibility* PlatformGetChild(uint32_t child_index) const override;
// The BrowserAccessibilityCocoa associated with us.
BrowserAccessibilityCocoa* native_view() const {
diff --git a/chromium/content/browser/accessibility/browser_accessibility_mac.mm b/chromium/content/browser/accessibility/browser_accessibility_mac.mm
index 34475bdc309..1c5d9171a4f 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_mac.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_mac.mm
@@ -8,6 +8,7 @@
#import "content/browser/accessibility/browser_accessibility_cocoa.h"
#include "content/browser/accessibility/browser_accessibility_manager_mac.h"
+#include "ui/accessibility/ax_table_info.h"
namespace content {
@@ -48,6 +49,39 @@ void BrowserAccessibilityMac::OnDataChanged() {
[[BrowserAccessibilityCocoa alloc] initWithObject:this];
}
+uint32_t BrowserAccessibilityMac::PlatformChildCount() const {
+ uint32_t child_count = BrowserAccessibility::PlatformChildCount();
+
+ // If this is a table, include the extra fake nodes generated by
+ // AXTableInfo, for the column nodes and the table header container, all of
+ // which are only important on macOS.
+ ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
+ if (!table_info)
+ return child_count;
+
+ return child_count + table_info->extra_mac_nodes.size();
+}
+
+BrowserAccessibility* BrowserAccessibilityMac::PlatformGetChild(
+ uint32_t child_index) const {
+ uint32_t child_count = BrowserAccessibility::PlatformChildCount();
+ if (child_index < child_count)
+ return BrowserAccessibility::PlatformGetChild(child_index);
+
+ // If this is a table, include the extra fake nodes generated by
+ // AXTableInfo, for the column nodes and the table header container, all of
+ // which are only important on macOS.
+ ui::AXTableInfo* table_info = manager()->ax_tree()->GetTableInfo(node());
+ if (!table_info)
+ return nullptr;
+
+ child_index -= child_count;
+ if (child_index < table_info->extra_mac_nodes.size())
+ return manager_->GetFromAXNode(table_info->extra_mac_nodes[child_index]);
+
+ return nullptr;
+}
+
void BrowserAccessibilityMac::RecreateNativeObject() {
if (!browser_accessibility_cocoa_)
return;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_mac_unittest.mm b/chromium/content/browser/accessibility/browser_accessibility_mac_unittest.mm
index 217faec21d1..afdf10051f3 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_mac_unittest.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_mac_unittest.mm
@@ -23,7 +23,51 @@
namespace content {
-class BrowserAccessibilityTest : public ui::CocoaTest {
+namespace {
+
+void MakeTable(ui::AXNodeData* table, int id, int row_count, int col_count) {
+ table->id = id;
+ table->role = ax::mojom::Role::kTable;
+ table->AddIntAttribute(ax::mojom::IntAttribute::kTableRowCount, row_count);
+ table->AddIntAttribute(ax::mojom::IntAttribute::kTableColumnCount, col_count);
+}
+
+void MakeRow(ui::AXNodeData* row, int id) {
+ row->id = id;
+ row->role = ax::mojom::Role::kRow;
+}
+
+void MakeCell(ui::AXNodeData* cell,
+ int id,
+ int row_index,
+ int col_index,
+ int row_span = 1,
+ int col_span = 1) {
+ cell->id = id;
+ cell->role = ax::mojom::Role::kCell;
+ cell->AddIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex, row_index);
+ cell->AddIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex,
+ col_index);
+ if (row_span > 1)
+ cell->AddIntAttribute(ax::mojom::IntAttribute::kTableCellRowSpan, row_span);
+ if (col_span > 1)
+ cell->AddIntAttribute(ax::mojom::IntAttribute::kTableCellColumnSpan,
+ col_span);
+}
+
+void MakeColumnHeader(ui::AXNodeData* cell,
+ int id,
+ int row_index,
+ int col_index,
+ int row_span = 1,
+ int col_span = 1) {
+ MakeCell(cell, id, row_index, col_index, row_span, col_span);
+ cell->role = ax::mojom::Role::kColumnHeader;
+}
+
+} // namespace
+
+class BrowserAccessibilityMacTest : public ui::CocoaTest {
public:
void SetUp() override {
CocoaTest::SetUp();
@@ -68,12 +112,10 @@ class BrowserAccessibilityTest : public ui::CocoaTest {
if (!manager_)
return;
root_.SetValue(value);
- AXEventNotificationDetails param;
- param.update.nodes.push_back(root_);
- param.event_type = ax::mojom::Event::kValueChanged;
- param.id = root_.id;
- std::vector<AXEventNotificationDetails> events{param};
- manager_->OnAccessibilityEvents(events);
+ AXEventNotificationDetails event_bundle;
+ event_bundle.updates.resize(1);
+ event_bundle.updates[0].nodes.push_back(root_);
+ manager_->OnAccessibilityEvents(event_bundle);
}
ui::AXNodeData root_;
@@ -82,7 +124,7 @@ class BrowserAccessibilityTest : public ui::CocoaTest {
};
// Standard hit test.
-TEST_F(BrowserAccessibilityTest, HitTestTest) {
+TEST_F(BrowserAccessibilityMacTest, HitTestTest) {
BrowserAccessibilityCocoa* firstChild =
[accessibility_ accessibilityHitTest:NSMakePoint(50, 50)];
EXPECT_NSEQ(@"Child1",
@@ -91,7 +133,7 @@ TEST_F(BrowserAccessibilityTest, HitTestTest) {
}
// Test doing a hit test on the edge of a child.
-TEST_F(BrowserAccessibilityTest, EdgeHitTest) {
+TEST_F(BrowserAccessibilityMacTest, EdgeHitTest) {
BrowserAccessibilityCocoa* firstChild =
[accessibility_ accessibilityHitTest:NSZeroPoint];
EXPECT_NSEQ(@"Child1",
@@ -102,27 +144,27 @@ TEST_F(BrowserAccessibilityTest, EdgeHitTest) {
// This will test a hit test with invalid coordinates. It is assumed that
// the hit test has been narrowed down to this object or one of its children
// so it should return itself since it has no better hit result.
-TEST_F(BrowserAccessibilityTest, InvalidHitTestCoordsTest) {
+TEST_F(BrowserAccessibilityMacTest, InvalidHitTestCoordsTest) {
BrowserAccessibilityCocoa* hitTestResult =
[accessibility_ accessibilityHitTest:NSMakePoint(-50, 50)];
EXPECT_NSEQ(accessibility_, hitTestResult);
}
// Test to ensure querying standard attributes works.
-TEST_F(BrowserAccessibilityTest, BasicAttributeTest) {
+TEST_F(BrowserAccessibilityMacTest, BasicAttributeTest) {
NSString* helpText = [accessibility_
accessibilityAttributeValue:NSAccessibilityHelpAttribute];
EXPECT_NSEQ(@"HelpText", helpText);
}
// Test querying for an invalid attribute to ensure it doesn't crash.
-TEST_F(BrowserAccessibilityTest, InvalidAttributeTest) {
+TEST_F(BrowserAccessibilityMacTest, InvalidAttributeTest) {
NSString* shouldBeNil = [accessibility_
accessibilityAttributeValue:@"NSAnInvalidAttribute"];
EXPECT_TRUE(shouldBeNil == nil);
}
-TEST_F(BrowserAccessibilityTest, RetainedDetachedObjectsReturnNil) {
+TEST_F(BrowserAccessibilityMacTest, RetainedDetachedObjectsReturnNil) {
// Get the first child.
BrowserAccessibilityCocoa* retainedFirstChild =
[accessibility_ accessibilityHitTest:NSMakePoint(50, 50)];
@@ -144,9 +186,9 @@ TEST_F(BrowserAccessibilityTest, RetainedDetachedObjectsReturnNil) {
[retainedFirstChild release];
}
-TEST_F(BrowserAccessibilityTest, TestComputeTextEdit) {
- BrowserAccessibility* wrapper = [accessibility_ browserAccessibility];
- ASSERT_NE(nullptr, wrapper);
+TEST_F(BrowserAccessibilityMacTest, TestComputeTextEdit) {
+ BrowserAccessibility* owner = [accessibility_ owner];
+ ASSERT_NE(nullptr, owner);
// Insertion but no deletion.
@@ -212,4 +254,51 @@ TEST_F(BrowserAccessibilityTest, TestComputeTextEdit) {
EXPECT_EQ(base::UTF8ToUTF16("old"), text_edit.inserted_text);
}
+// Test Mac-specific table APIs.
+TEST_F(BrowserAccessibilityMacTest, TableAPIs) {
+ ui::AXTreeUpdate initial_state;
+ initial_state.root_id = 1;
+ initial_state.nodes.resize(7);
+ MakeTable(&initial_state.nodes[0], 1, 0, 0);
+ initial_state.nodes[0].child_ids = {2, 3};
+ MakeRow(&initial_state.nodes[1], 2);
+ initial_state.nodes[1].child_ids = {4, 5};
+ MakeRow(&initial_state.nodes[2], 3);
+ initial_state.nodes[2].child_ids = {6, 7};
+ MakeColumnHeader(&initial_state.nodes[3], 4, 0, 0);
+ MakeColumnHeader(&initial_state.nodes[4], 5, 0, 1);
+ MakeCell(&initial_state.nodes[5], 6, 1, 0);
+ MakeCell(&initial_state.nodes[6], 7, 1, 1);
+
+ manager_.reset(new BrowserAccessibilityManagerMac(initial_state, nullptr));
+ base::scoped_nsobject<BrowserAccessibilityCocoa> ax_table_(
+ [ToBrowserAccessibilityCocoa(manager_->GetRoot()) retain]);
+ id children = [ax_table_ children];
+ EXPECT_EQ(5U, [children count]);
+
+ EXPECT_NSEQ(@"AXRow", [children[0] role]);
+ EXPECT_EQ(2U, [[children[0] children] count]);
+
+ EXPECT_NSEQ(@"AXRow", [children[1] role]);
+ EXPECT_EQ(2U, [[children[1] children] count]);
+
+ EXPECT_NSEQ(@"AXColumn", [children[2] role]);
+ EXPECT_EQ(2U, [[children[2] children] count]);
+ id col_children = [children[2] children];
+ EXPECT_NSEQ(@"AXCell", [col_children[0] role]);
+ EXPECT_NSEQ(@"AXCell", [col_children[1] role]);
+
+ EXPECT_NSEQ(@"AXColumn", [children[3] role]);
+ EXPECT_EQ(2U, [[children[3] children] count]);
+ col_children = [children[3] children];
+ EXPECT_NSEQ(@"AXCell", [col_children[0] role]);
+ EXPECT_NSEQ(@"AXCell", [col_children[1] role]);
+
+ EXPECT_NSEQ(@"AXGroup", [children[4] role]);
+ EXPECT_EQ(2U, [[children[4] children] count]);
+ col_children = [children[4] children];
+ EXPECT_NSEQ(@"AXCell", [col_children[0] role]);
+ EXPECT_NSEQ(@"AXCell", [col_children[1] role]);
+}
+
} // namespace content
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager.cc b/chromium/content/browser/accessibility/browser_accessibility_manager.cc
index f15f0305256..2cfe76080a1 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager.cc
@@ -351,7 +351,7 @@ bool BrowserAccessibilityManager::UseRootScrollOffsetsWhenComputingBounds() {
}
void BrowserAccessibilityManager::OnAccessibilityEvents(
- const std::vector<AXEventNotificationDetails>& details) {
+ const AXEventNotificationDetails& details) {
TRACE_EVENT0("accessibility",
"BrowserAccessibilityManager::OnAccessibilityEvents");
@@ -360,9 +360,8 @@ void BrowserAccessibilityManager::OnAccessibilityEvents(
device_scale_factor_ = delegate_->AccessibilityGetDeviceScaleFactor();
// Process all changes to the accessibility tree first.
- for (uint32_t index = 0; index < details.size(); ++index) {
- const AXEventNotificationDetails& detail = details[index];
- if (!tree_->Unserialize(detail.update)) {
+ for (uint32_t index = 0; index < details.updates.size(); ++index) {
+ if (!tree_->Unserialize(details.updates[index])) {
if (delegate_) {
LOG(ERROR) << tree_->error();
delegate_->AccessibilityFatalError();
@@ -405,23 +404,23 @@ void BrowserAccessibilityManager::OnAccessibilityEvents(
if (!event_target)
continue;
- FireGeneratedEvent(targeted_event.event, event_target);
+ FireGeneratedEvent(targeted_event.event_params.event, event_target);
}
ClearEvents();
// Fire events from Blink.
- for (uint32_t index = 0; index < details.size(); index++) {
- const AXEventNotificationDetails& detail = details[index];
+ for (uint32_t index = 0; index < details.events.size(); index++) {
+ const ui::AXEvent& event = details.events[index];
// Fire the native event.
- BrowserAccessibility* event_target = GetFromID(detail.id);
+ BrowserAccessibility* event_target = GetFromID(event.id);
if (!event_target)
return;
- if (detail.event_type == ax::mojom::Event::kHover)
+ if (event.event_type == ax::mojom::Event::kHover)
GetRootManager()->CacheHitTestResult(event_target);
- FireBlinkEvent(detail.event_type, event_target);
+ FireBlinkEvent(event.event_type, event_target);
}
}
@@ -674,9 +673,8 @@ void BrowserAccessibilityManager::SetScrollOffset(
delegate_->AccessibilityPerformAction(action_data);
}
-void BrowserAccessibilityManager::SetValue(
- const BrowserAccessibility& node,
- const base::string16& value) {
+void BrowserAccessibilityManager::SetValue(const BrowserAccessibility& node,
+ const std::string& value) {
if (!delegate_)
return;
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager.h b/chromium/content/browser/accessibility/browser_accessibility_manager.h
index b1b47d25878..6279fdbe5f5 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <memory>
+#include <string>
#include <vector>
#include "base/callback_forward.h"
@@ -218,8 +219,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXEventGenerator {
void SetAccessibilityFocus(const BrowserAccessibility& node);
void SetFocus(const BrowserAccessibility& node);
void SetScrollOffset(const BrowserAccessibility& node, gfx::Point offset);
- void SetValue(
- const BrowserAccessibility& node, const base::string16& value);
+ void SetValue(const BrowserAccessibility& node, const std::string& value);
void SetSelection(
ui::AXRange<
BrowserAccessibilityPosition::AXPositionInstance::element_type>
@@ -234,8 +234,7 @@ class CONTENT_EXPORT BrowserAccessibilityManager : public ui::AXEventGenerator {
void ActivateFindInPageResult(int request_id, int match_index);
// Called when the renderer process has notified us of about tree changes.
- virtual void OnAccessibilityEvents(
- const std::vector<AXEventNotificationDetails>& details);
+ virtual void OnAccessibilityEvents(const AXEventNotificationDetails& details);
// Called when the renderer process updates the location of accessibility
// objects. Calls SendLocationChangeEvents(), which can be overridden.
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h
index 8f88334ea98..2d97c89fa38 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.h
@@ -41,7 +41,7 @@ class CONTENT_EXPORT BrowserAccessibilityManagerMac
BrowserAccessibility* node) override;
void OnAccessibilityEvents(
- const std::vector<AXEventNotificationDetails>& details) override;
+ const AXEventNotificationDetails& details) override;
NSView* GetParentView();
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
index 134f855de65..8e32a082260 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -125,6 +125,7 @@ BrowserAccessibilityManagerMac::BrowserAccessibilityManagerMac(
BrowserAccessibilityFactory* factory)
: BrowserAccessibilityManager(delegate, factory) {
Initialize(initial_tree);
+ tree_->SetEnableExtraMacNodes(true);
}
BrowserAccessibilityManagerMac::~BrowserAccessibilityManagerMac() {}
@@ -144,15 +145,10 @@ ui::AXTreeUpdate
BrowserAccessibility* BrowserAccessibilityManagerMac::GetFocus() {
BrowserAccessibility* focus = BrowserAccessibilityManager::GetFocus();
- // On Mac, list boxes should always get focus on the whole list, otherwise
- // information about the number of selected items will never be reported.
// 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() == ax::mojom::Role::kListBox ||
- (focus->GetRole() == ax::mojom::Role::kTextFieldWithComboBox))) {
+ if (focus && focus->GetRole() == ax::mojom::Role::kTextFieldWithComboBox)
return focus;
- }
// For other roles, follow the active descendant.
return GetActiveDescendant(focus);
@@ -386,7 +382,7 @@ void BrowserAccessibilityManagerMac::FireNativeMacNotification(
}
void BrowserAccessibilityManagerMac::OnAccessibilityEvents(
- const std::vector<AXEventNotificationDetails>& details) {
+ const AXEventNotificationDetails& details) {
text_edits_.clear();
// Call the base method last as it might delete the tree if it receives an
// invalid message.
@@ -415,7 +411,7 @@ void BrowserAccessibilityManagerMac::OnAtomicUpdateFinished(
DCHECK(obj);
const AXTextEdit text_edit = [obj computeTextEdit];
if (!text_edit.IsEmpty())
- text_edits_[[obj browserAccessibility]->GetId()] = text_edit;
+ text_edits_[[obj owner]->GetId()] = text_edit;
}
}
@@ -489,10 +485,7 @@ BrowserAccessibilityManagerMac::GetUserInfoForValueChangedNotification(
}
NSView* BrowserAccessibilityManagerMac::GetParentView() {
- gfx::AcceleratedWidget accelerated_widget =
- delegate() ? delegate()->AccessibilityGetAcceleratedWidget()
- : gfx::kNullAcceleratedWidget;
- return ui::AcceleratedWidgetMac::GetNSView(accelerated_widget);
+ return delegate()->AccessibilityGetNativeViewAccessible();
}
} // namespace content
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc
index dcd5699b675..80c55653e84 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_unittest.cc
@@ -238,14 +238,11 @@ TEST(BrowserAccessibilityManagerTest, TestReuseBrowserAccessibilityObjects) {
EXPECT_EQ(2, child3_accessible->GetIndexInParent());
// Process a notification containing the changed subtree.
- std::vector<AXEventNotificationDetails> params;
- params.push_back(AXEventNotificationDetails());
- AXEventNotificationDetails* msg = &params[0];
- msg->event_type = ax::mojom::Event::kChildrenChanged;
- msg->update.nodes.push_back(tree2_root);
- msg->update.nodes.push_back(tree2_child0);
- msg->id = tree2_root.id;
- manager->OnAccessibilityEvents(params);
+ AXEventNotificationDetails notification;
+ notification.updates.resize(1);
+ notification.updates[0].nodes.push_back(tree2_root);
+ notification.updates[0].nodes.push_back(tree2_child0);
+ manager->OnAccessibilityEvents(notification);
// There should be 5 objects now: the 4 from the new tree, plus the
// reference to child3 we kept.
@@ -403,15 +400,12 @@ TEST(BrowserAccessibilityManagerTest, TestReuseBrowserAccessibilityObjects2) {
// Process a notification containing the changed subtree rooted at
// the container.
- std::vector<AXEventNotificationDetails> params;
- params.push_back(AXEventNotificationDetails());
- AXEventNotificationDetails* msg = &params[0];
- msg->event_type = ax::mojom::Event::kChildrenChanged;
- msg->update.nodes.push_back(tree2_container);
- msg->update.nodes.push_back(tree2_child0);
- msg->update.nodes.push_back(tree2_grandchild0);
- msg->id = tree2_container.id;
- manager->OnAccessibilityEvents(params);
+ AXEventNotificationDetails notification;
+ notification.updates.resize(1);
+ notification.updates[0].nodes.push_back(tree2_container);
+ notification.updates[0].nodes.push_back(tree2_child0);
+ notification.updates[0].nodes.push_back(tree2_grandchild0);
+ manager->OnAccessibilityEvents(notification);
// There should be 9 objects now: the 8 from the new tree, plus the
// reference to child3 we kept.
@@ -501,16 +495,13 @@ TEST(BrowserAccessibilityManagerTest, TestMoveChildUp) {
ASSERT_EQ(4, CountedBrowserAccessibility::global_obj_count_);
// Process a notification containing the changed subtree.
- std::vector<AXEventNotificationDetails> params;
- params.push_back(AXEventNotificationDetails());
- AXEventNotificationDetails* msg = &params[0];
- msg->event_type = ax::mojom::Event::kChildrenChanged;
- msg->update.nodes.push_back(tree2_1);
- msg->update.nodes.push_back(tree2_4);
- msg->update.nodes.push_back(tree2_5);
- msg->update.nodes.push_back(tree2_6);
- msg->id = tree2_1.id;
- manager->OnAccessibilityEvents(params);
+ AXEventNotificationDetails notification;
+ notification.updates.resize(1);
+ notification.updates[0].nodes.push_back(tree2_1);
+ notification.updates[0].nodes.push_back(tree2_4);
+ notification.updates[0].nodes.push_back(tree2_5);
+ notification.updates[0].nodes.push_back(tree2_6);
+ manager->OnAccessibilityEvents(notification);
// There should be 4 objects now.
EXPECT_EQ(4, CountedBrowserAccessibility::global_obj_count_);
@@ -1515,11 +1506,9 @@ TEST(BrowserAccessibilityManagerTest, DeletingFocusedNodeDoesNotCrash) {
root2.id = 3;
root2.role = ax::mojom::Role::kRootWebArea;
- std::vector<AXEventNotificationDetails> events2;
- events2.push_back(AXEventNotificationDetails());
- events2[0].update = MakeAXTreeUpdate(root2);
- events2[0].id = -1;
- events2[0].event_type = ax::mojom::Event::kNone;
+ AXEventNotificationDetails events2;
+ events2.updates.resize(1);
+ events2.updates[0] = MakeAXTreeUpdate(root2);
manager->OnAccessibilityEvents(events2);
// Make sure that the focused node was updated to the new root and
@@ -1562,12 +1551,10 @@ TEST(BrowserAccessibilityManagerTest, DeletingFocusedNodeDoesNotCrash2) {
root2.role = ax::mojom::Role::kRootWebArea;
// Make an update the explicitly clears the previous root.
- std::vector<AXEventNotificationDetails> events2;
- events2.push_back(AXEventNotificationDetails());
- events2[0].update = MakeAXTreeUpdate(root2);
- events2[0].update.node_id_to_clear = 1;
- events2[0].id = -1;
- events2[0].event_type = ax::mojom::Event::kNone;
+ AXEventNotificationDetails events2;
+ events2.updates.resize(1);
+ events2.updates[0] = MakeAXTreeUpdate(root2);
+ events2.updates[0].node_id_to_clear = 1;
manager->OnAccessibilityEvents(events2);
// Make sure that the focused node was updated to the new root and
diff --git a/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc b/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
index ea5cf31693a..2251fd1696d 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -151,7 +151,10 @@ void BrowserAccessibilityManagerWin::FireGeneratedEvent(
FireWinAccessibilityEvent(EVENT_OBJECT_REORDER, node);
break;
case Event::LIVE_REGION_CHANGED:
- FireWinAccessibilityEvent(EVENT_OBJECT_LIVEREGIONCHANGED, node);
+ // NVDA and JAWS are inconsistent about speaking this event in content.
+ // Because of this, and because Firefox does not currently fire it, we
+ // are avoiding this event for now.
+ // FireWinAccessibilityEvent(EVENT_OBJECT_LIVEREGIONCHANGED, node);
break;
case Event::LOAD_COMPLETE:
FireWinAccessibilityEvent(IA2_EVENT_DOCUMENT_LOAD_COMPLETE, node);
diff --git a/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc b/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc
index f81b59ee00a..611d6959723 100644
--- a/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc
+++ b/chromium/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -166,13 +166,10 @@ TEST_F(BrowserAccessibilityTest, TestChildrenChange) {
text2.id = 2;
text2.role = ax::mojom::Role::kStaticText;
text2.SetName("new text");
- AXEventNotificationDetails param;
- param.event_type = ax::mojom::Event::kChildrenChanged;
- param.update.nodes.push_back(text2);
- param.id = text2.id;
- std::vector<AXEventNotificationDetails> events;
- events.push_back(param);
- manager->OnAccessibilityEvents(events);
+ AXEventNotificationDetails event_bundle;
+ event_bundle.updates.resize(1);
+ event_bundle.updates[0].nodes.push_back(text2);
+ manager->OnAccessibilityEvents(event_bundle);
// Query for the text IAccessible and verify that it now returns "new text"
// as its value.
@@ -232,13 +229,10 @@ TEST_F(BrowserAccessibilityTest, TestChildrenChangeNoLeaks) {
// Notify the BrowserAccessibilityManager that the div node and its children
// were removed and ensure that only one BrowserAccessibility instance exists.
root.child_ids.clear();
- AXEventNotificationDetails param;
- param.event_type = ax::mojom::Event::kChildrenChanged;
- param.update.nodes.push_back(root);
- param.id = root.id;
- std::vector<AXEventNotificationDetails> events;
- events.push_back(param);
- manager->OnAccessibilityEvents(events);
+ AXEventNotificationDetails event_bundle;
+ event_bundle.updates.resize(1);
+ event_bundle.updates[0].nodes.push_back(root);
+ manager->OnAccessibilityEvents(event_bundle);
// Delete the manager and test that all BrowserAccessibility instances are
// deleted.
@@ -659,15 +653,12 @@ TEST_F(BrowserAccessibilityTest, TestCreateEmptyDocument) {
tree1_2.role = ax::mojom::Role::kTextField;
// Process a load complete.
- std::vector<AXEventNotificationDetails> params;
- params.push_back(AXEventNotificationDetails());
- AXEventNotificationDetails* msg = &params[0];
- msg->event_type = ax::mojom::Event::kLoadComplete;
- msg->update.root_id = tree1_1.id;
- msg->update.nodes.push_back(tree1_1);
- msg->update.nodes.push_back(tree1_2);
- msg->id = tree1_1.id;
- manager->OnAccessibilityEvents(params);
+ AXEventNotificationDetails event_bundle;
+ event_bundle.updates.resize(1);
+ event_bundle.updates[0].root_id = tree1_1.id;
+ event_bundle.updates[0].nodes.push_back(tree1_1);
+ event_bundle.updates[0].nodes.push_back(tree1_2);
+ manager->OnAccessibilityEvents(event_bundle);
// Save for later comparison.
BrowserAccessibility* acc1_2 = manager->GetFromID(2);
@@ -689,13 +680,12 @@ TEST_F(BrowserAccessibilityTest, TestCreateEmptyDocument) {
tree2_2.id = 3;
tree2_2.role = ax::mojom::Role::kButton;
- msg->update.nodes.clear();
- msg->update.nodes.push_back(tree2_1);
- msg->update.nodes.push_back(tree2_2);
- msg->id = tree2_1.id;
+ event_bundle.updates[0].nodes.clear();
+ event_bundle.updates[0].nodes.push_back(tree2_1);
+ event_bundle.updates[0].nodes.push_back(tree2_2);
// Fire another load complete.
- manager->OnAccessibilityEvents(params);
+ manager->OnAccessibilityEvents(event_bundle);
BrowserAccessibility* acc2_2 = manager->GetFromID(3);
@@ -2491,12 +2481,10 @@ TEST_F(BrowserAccessibilityTest, TestIAccessible2Relations) {
std::vector<int32_t> labelledby_ids = {3};
child1.AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
labelledby_ids);
- AXEventNotificationDetails event;
- event.event_type = ax::mojom::Event::kAriaAttributeChanged;
- event.update.nodes.push_back(child1);
- event.id = child1.id;
- std::vector<AXEventNotificationDetails> events = {event};
- manager->OnAccessibilityEvents(events);
+ AXEventNotificationDetails event_bundle;
+ event_bundle.updates.resize(1);
+ event_bundle.updates[0].nodes.push_back(child1);
+ manager->OnAccessibilityEvents(event_bundle);
EXPECT_HRESULT_SUCCEEDED(ax_child1->GetCOM()->get_nRelations(&n_relations));
EXPECT_EQ(2, n_relations);
diff --git a/chromium/content/browser/accessibility/captioning_controller.cc b/chromium/content/browser/accessibility/captioning_controller.cc
index f0511fc03ae..0bd9b69d539 100644
--- a/chromium/content/browser/accessibility/captioning_controller.cc
+++ b/chromium/content/browser/accessibility/captioning_controller.cc
@@ -23,7 +23,7 @@ int GetRenderProcessIdFromRenderViewHost(RenderViewHost* host) {
DCHECK(host);
RenderProcessHost* render_process = host->GetProcess();
DCHECK(render_process);
- if (render_process->HasConnection())
+ if (render_process->IsInitializedAndNotDead())
return render_process->GetProcess().Handle();
return 0;
}
diff --git a/chromium/content/browser/accessibility/cross_platform_accessibility_browsertest.cc b/chromium/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
index 6a812bdaa34..4541b57ade6 100644
--- a/chromium/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
+++ b/chromium/content/browser/accessibility/cross_platform_accessibility_browsertest.cc
@@ -254,54 +254,8 @@ IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest,
}
IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest,
- MultipleInheritanceAccessibility) {
- // In a WebKit accessibility render tree for a table, each cell is a
- // child of both a row and a column, so it appears to use multiple
- // inheritance. Make sure that the ui::AXNodeDataObject tree only
- // keeps one copy of each cell, and uses an indirect child id for the
- // additional reference to it.
- const char url_str[] =
- "data:text/html,"
- "<!doctype html>"
- "<table border=1><tr><td>1</td><td>2</td></tr></table>";
- GURL url(url_str);
- NavigateToURL(shell(), url);
-
- const ui::AXTree& tree = GetAXTree();
- const ui::AXNode* root = tree.root();
- ASSERT_EQ(1, root->child_count());
- const ui::AXNode* table = root->ChildAtIndex(0);
- EXPECT_EQ(ax::mojom::Role::kTable, table->data().role);
- const ui::AXNode* row = table->ChildAtIndex(0);
- EXPECT_EQ(ax::mojom::Role::kRow, row->data().role);
- const ui::AXNode* cell1 = row->ChildAtIndex(0);
- EXPECT_EQ(ax::mojom::Role::kCell, cell1->data().role);
- const ui::AXNode* cell2 = row->ChildAtIndex(1);
- EXPECT_EQ(ax::mojom::Role::kCell, cell2->data().role);
- const ui::AXNode* column1 = table->ChildAtIndex(1);
- EXPECT_EQ(ax::mojom::Role::kColumn, column1->data().role);
- EXPECT_EQ(0, column1->child_count());
- EXPECT_EQ(1U, column1->data().intlist_attributes.size());
- EXPECT_EQ(ax::mojom::IntListAttribute::kIndirectChildIds,
- column1->data().intlist_attributes[0].first);
- const std::vector<int32_t> column1_indirect_child_ids =
- column1->data().intlist_attributes[0].second;
- EXPECT_EQ(1U, column1_indirect_child_ids.size());
- EXPECT_EQ(cell1->id(), column1_indirect_child_ids[0]);
- const ui::AXNode* column2 = table->ChildAtIndex(2);
- EXPECT_EQ(ax::mojom::Role::kColumn, column2->data().role);
- EXPECT_EQ(0, column2->child_count());
- EXPECT_EQ(ax::mojom::IntListAttribute::kIndirectChildIds,
- column2->data().intlist_attributes[0].first);
- const std::vector<int32_t> column2_indirect_child_ids =
- column2->data().intlist_attributes[0].second;
- EXPECT_EQ(1U, column2_indirect_child_ids.size());
- EXPECT_EQ(cell2->id(), column2_indirect_child_ids[0]);
-}
-
-IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest,
MultipleInheritanceAccessibility2) {
- // Here's another html snippet where WebKit puts the same node as a child
+ // Here's a html snippet where Blink puts the same node as a child
// of two different parents. Instead of checking the exact output, just
// make sure that no id is reused in the resulting tree.
const char url_str[] =
@@ -416,12 +370,9 @@ IN_PROC_BROWSER_TEST_F(CrossPlatformAccessibilityBrowserTest,
const ui::AXNode* root = tree.root();
const ui::AXNode* table = root->ChildAtIndex(0);
EXPECT_EQ(ax::mojom::Role::kTable, table->data().role);
- ASSERT_GE(table->child_count(), 5);
+ ASSERT_GE(table->child_count(), 2);
EXPECT_EQ(ax::mojom::Role::kRow, table->ChildAtIndex(0)->data().role);
EXPECT_EQ(ax::mojom::Role::kRow, table->ChildAtIndex(1)->data().role);
- EXPECT_EQ(ax::mojom::Role::kColumn, table->ChildAtIndex(2)->data().role);
- EXPECT_EQ(ax::mojom::Role::kColumn, table->ChildAtIndex(3)->data().role);
- EXPECT_EQ(ax::mojom::Role::kColumn, table->ChildAtIndex(4)->data().role);
EXPECT_EQ(3, GetIntAttr(table, ax::mojom::IntAttribute::kTableColumnCount));
EXPECT_EQ(2, GetIntAttr(table, ax::mojom::IntAttribute::kTableRowCount));
diff --git a/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index 4d30edf5a69..bc91d524e85 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/chromium/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -195,6 +195,16 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
+ AccessibilityEventsAriaComboBoxDelayAddList) {
+ RunEventTest(FILE_PATH_LITERAL("aria-combo-box-delay-add-list.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
+ AccessibilityEventsAriaComboBoxDelayShowList) {
+ RunEventTest(FILE_PATH_LITERAL("aria-combo-box-delay-show-list.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityEventsTest,
AccessibilityEventsAriaComboBoxNext) {
RunEventTest(FILE_PATH_LITERAL("aria-combo-box-next.html"));
}
diff --git a/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index 263cc2387f5..b0c2af3f667 100644
--- a/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/chromium/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -194,7 +194,11 @@ void DumpAccessibilityTreeTest::AddDefaultFilters(
AddFilter(filters, "FOCUSED", Filter::DENY);
AddFilter(filters, "HOTTRACKED", Filter::DENY);
AddFilter(filters, "OFFSCREEN", Filter::DENY);
- // Object attributes.
+ AddFilter(filters, "value='*'");
+ // The value attribute on the document object contains the URL of the current
+ // page which will not be the same every time the test is run.
+ AddFilter(filters, "value='http*'", Filter::DENY);
+ // Object attributes.value
AddFilter(filters, "layout-guess:*", Filter::ALLOW);
//
@@ -235,12 +239,14 @@ void DumpAccessibilityTreeTest::AddDefaultFilters(
AddFilter(filters, "invalidState=*");
AddFilter(filters, "invalidState=false",
Filter::DENY); // Don't show false value
+ AddFilter(filters, "roleDescription=*");
//
// OS X
//
- AddFilter(filters, "roleDescription=*");
+ AddFilter(filters, "AXValueAutofill*");
+ AddFilter(filters, "AXAutocomplete*");
//
// Android
@@ -287,6 +293,10 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
RunCSSTest(FILE_PATH_LITERAL("table-incomplete.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityCSSTransform) {
+ RunCSSTest(FILE_PATH_LITERAL("transform.html"));
+}
+
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityA) {
RunHtmlTest(FILE_PATH_LITERAL("a.html"));
}
@@ -548,6 +558,11 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityAriaGrid) {
}
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityAriaGridDynamicAddRow) {
+ RunAriaTest(FILE_PATH_LITERAL("aria-grid-dynamic-add-row.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
AccessibilityAriaGridExtraWrapElems) {
RunAriaTest(FILE_PATH_LITERAL("aria-grid-extra-wrap-elems.html"));
}
@@ -980,7 +995,7 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityBoundsInherits) {
RunHtmlTest(FILE_PATH_LITERAL("bounds-inherits.html"));
}
-IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibiltyBoundsClips) {
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityBoundsClips) {
RunHtmlTest(FILE_PATH_LITERAL("bounds-clips.html"));
}
@@ -1000,6 +1015,16 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityButton) {
RunHtmlTest(FILE_PATH_LITERAL("button.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityButtonAltChanged) {
+ RunHtmlTest(FILE_PATH_LITERAL("button-alt-changed.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityButtonContentChanged) {
+ RunHtmlTest(FILE_PATH_LITERAL("button-content-changed.html"));
+}
+
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityButtonNameCalc) {
RunHtmlTest(FILE_PATH_LITERAL("button-name-calc.html"));
}
@@ -1471,6 +1496,11 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityLandmark) {
RunHtmlTest(FILE_PATH_LITERAL("landmark.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
+ AccessibilityLayoutTableInButton) {
+ RunHtmlTest(FILE_PATH_LITERAL("layout-table-in-button.html"));
+}
+
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityLegend) {
RunHtmlTest(FILE_PATH_LITERAL("legend.html"));
}
@@ -1609,6 +1639,10 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityQ) {
RunHtmlTest(FILE_PATH_LITERAL("q.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityReparentCrash) {
+ RunHtmlTest(FILE_PATH_LITERAL("reparent-crash.html"));
+}
+
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityReplaceData) {
RunHtmlTest(FILE_PATH_LITERAL("replace-data.html"));
}
@@ -1729,6 +1763,10 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityTitle) {
RunHtmlTest(FILE_PATH_LITERAL("title.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityTitleChanged) {
+ RunHtmlTest(FILE_PATH_LITERAL("title-changed.html"));
+}
+
#if defined(OS_WIN) || defined(OS_MACOSX)
// Flaky on Win/Mac: crbug.com/508532
#define MAYBE_AccessibilityTransition DISABLED_AccessibilityTransition
@@ -1740,6 +1778,10 @@ IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest,
RunHtmlTest(FILE_PATH_LITERAL("transition.html"));
}
+IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityTruncateLabel) {
+ RunHtmlTest(FILE_PATH_LITERAL("truncate-label.html"));
+}
+
IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityUl) {
RunHtmlTest(FILE_PATH_LITERAL("ul.html"));
}
diff --git a/chromium/content/browser/accessibility/hit_testing_browsertest.cc b/chromium/content/browser/accessibility/hit_testing_browsertest.cc
index acecaaec8b1..1e2e9d6959d 100644
--- a/chromium/content/browser/accessibility/hit_testing_browsertest.cc
+++ b/chromium/content/browser/accessibility/hit_testing_browsertest.cc
@@ -3,9 +3,11 @@
// found in the LICENSE file.
#include "base/logging.h"
+#include "build/build_config.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/browser/web_contents.h"
#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
@@ -59,6 +61,28 @@ class AccessibilityHitTestingBrowserTest : public ContentBrowserTest {
return HitTestAndWaitForResultWithEvent(point, ax::mojom::Event::kHover);
}
+ BrowserAccessibility* TapAndWaitForResult(const gfx::Point& point) {
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ FrameTree* frame_tree = web_contents->GetFrameTree();
+
+ AccessibilityNotificationWaiter event_waiter(shell()->web_contents(),
+ ui::kAXModeComplete,
+ ax::mojom::Event::kClicked);
+ for (FrameTreeNode* node : frame_tree->Nodes())
+ event_waiter.ListenToAdditionalFrame(node->current_frame_host());
+
+ SimulateTapAt(shell()->web_contents(), point);
+ event_waiter.WaitForNotification();
+
+ RenderFrameHostImpl* target_frame = event_waiter.event_render_frame_host();
+ BrowserAccessibilityManager* target_manager =
+ target_frame->browser_accessibility_manager();
+ int event_target_id = event_waiter.event_target_id();
+ BrowserAccessibility* hit_node = target_manager->GetFromID(event_target_id);
+ return hit_node;
+ }
+
BrowserAccessibility* CallCachingAsyncHitTest(const gfx::Point& point) {
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
@@ -78,6 +102,18 @@ class AccessibilityHitTestingBrowserTest : public ContentBrowserTest {
hover_waiter.WaitForNotification();
return result;
}
+
+ RenderWidgetHostImpl* GetRenderWidgetHost() {
+ return RenderWidgetHostImpl::From(shell()
+ ->web_contents()
+ ->GetRenderWidgetHostView()
+ ->GetRenderWidgetHost());
+ }
+
+ void SynchronizeThreads() {
+ MainThreadFrameObserver observer(GetRenderWidgetHost());
+ observer.Wait();
+ }
};
IN_PROC_BROWSER_TEST_F(AccessibilityHitTestingBrowserTest,
@@ -129,8 +165,15 @@ IN_PROC_BROWSER_TEST_F(AccessibilityHitTestingBrowserTest,
// wait for the hover event in response, verifying we hit the
// correct object.
- // (50, 50) -> "Button"
+ // (26, 26) -> "Button"
BrowserAccessibility* hit_node;
+ hit_node = HitTestAndWaitForResult(gfx::Point(26, 26));
+ ASSERT_TRUE(hit_node != nullptr);
+ ASSERT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ ASSERT_EQ("Button",
+ hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
+
+ // (50, 50) -> "Button"
hit_node = HitTestAndWaitForResult(gfx::Point(50, 50));
ASSERT_TRUE(hit_node != nullptr);
ASSERT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
@@ -199,42 +242,197 @@ IN_PROC_BROWSER_TEST_F(AccessibilityHitTestingBrowserTest,
BrowserAccessibility* hit_node;
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 50));
ASSERT_TRUE(hit_node != nullptr);
- ASSERT_NE(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_NE(ax::mojom::Role::kButton, hit_node->GetRole());
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 50));
- ASSERT_EQ("Button",
+ EXPECT_EQ("Button",
hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
// (50, 305) -> div in first iframe
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 305));
ASSERT_TRUE(hit_node != nullptr);
- ASSERT_NE(ax::mojom::Role::kGenericContainer, hit_node->GetRole());
+ EXPECT_NE(ax::mojom::Role::kGenericContainer, hit_node->GetRole());
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 305));
- ASSERT_EQ(ax::mojom::Role::kGenericContainer, hit_node->GetRole());
+ EXPECT_EQ(ax::mojom::Role::kGenericContainer, hit_node->GetRole());
// (50, 350) -> "Ordinary Button"
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 350));
ASSERT_TRUE(hit_node != nullptr);
- ASSERT_NE(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_NE(ax::mojom::Role::kButton, hit_node->GetRole());
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 350));
- ASSERT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
- ASSERT_EQ("Ordinary Button",
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Ordinary Button",
hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
// (50, 455) -> "Scrolled Button"
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 455));
ASSERT_TRUE(hit_node != nullptr);
- ASSERT_NE(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_NE(ax::mojom::Role::kButton, hit_node->GetRole());
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 455));
- ASSERT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
- ASSERT_EQ("Scrolled Button",
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Scrolled Button",
hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
// (50, 505) -> div in second iframe
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 505));
ASSERT_TRUE(hit_node != nullptr);
- ASSERT_NE(ax::mojom::Role::kGenericContainer, hit_node->GetRole());
+ EXPECT_NE(ax::mojom::Role::kGenericContainer, hit_node->GetRole());
hit_node = CallCachingAsyncHitTest(gfx::Point(50, 505));
- ASSERT_EQ(ax::mojom::Role::kGenericContainer, hit_node->GetRole());
+ EXPECT_EQ(ax::mojom::Role::kGenericContainer, hit_node->GetRole());
}
+#if !defined(OS_ANDROID) && !defined(OS_MACOSX)
+IN_PROC_BROWSER_TEST_F(AccessibilityHitTestingBrowserTest,
+ HitTestingWithPinchZoom) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ NavigateToURL(shell(), GURL(url::kAboutBlankURL));
+
+ AccessibilityNotificationWaiter waiter(shell()->web_contents(),
+ ui::kAXModeComplete,
+ ax::mojom::Event::kLoadComplete);
+
+ const char url_str[] =
+ "data:text/html,"
+ "<!doctype html>"
+ "<html>"
+ "<head><title>Accessibility Test</title>"
+ "<style>body {margin: 0px;}"
+ "button {display: block; height: 50px; width: 50px}</style>"
+ "</head>"
+ "<body>"
+ "<button>Button 1</button>"
+ "<button>Button 2</button>"
+ "</body></html>";
+
+ GURL url(url_str);
+ NavigateToURL(shell(), url);
+ SynchronizeThreads();
+ waiter.WaitForNotification();
+
+ BrowserAccessibility* hit_node;
+
+ // Use a tap event instead of a hittest to make sure that we are using
+ // px as input, rather than dips.
+
+ // (10, 10) -> "Button 1"
+ hit_node = TapAndWaitForResult(gfx::Point(10, 10));
+ ASSERT_TRUE(hit_node != nullptr);
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Button 1",
+ hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
+
+ // (60, 60) -> No button there
+ hit_node = TapAndWaitForResult(gfx::Point(60, 60));
+ EXPECT_TRUE(hit_node == nullptr);
+
+ // (10, 60) -> "Button 2"
+ hit_node = TapAndWaitForResult(gfx::Point(10, 60));
+ ASSERT_TRUE(hit_node != nullptr);
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Button 2",
+ hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
+
+ content::TestPageScaleObserver scale_observer(shell()->web_contents());
+ const gfx::Rect contents_rect = shell()->web_contents()->GetContainerBounds();
+ const gfx::Point pinch_position(contents_rect.x(), contents_rect.y());
+ SimulateGesturePinchSequence(shell()->web_contents(), pinch_position, 2.0f,
+ blink::kWebGestureDeviceTouchscreen);
+ scale_observer.WaitForPageScaleUpdate();
+
+ // (10, 10) -> "Button 1"
+ hit_node = TapAndWaitForResult(gfx::Point(10, 10));
+ ASSERT_TRUE(hit_node != nullptr);
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Button 1",
+ hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
+
+ // (60, 60) -> "Button 1"
+ hit_node = TapAndWaitForResult(gfx::Point(60, 60));
+ ASSERT_TRUE(hit_node != nullptr);
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Button 1",
+ hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
+
+ // (10, 60) -> "Button 1"
+ hit_node = TapAndWaitForResult(gfx::Point(10, 60));
+ ASSERT_TRUE(hit_node != nullptr);
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Button 1",
+ hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
+
+ // (10, 110) -> "Button 2"
+ hit_node = TapAndWaitForResult(gfx::Point(10, 110));
+ ASSERT_TRUE(hit_node != nullptr);
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Button 2",
+ hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
+
+ // (190, 190) -> "Button 2"
+ hit_node = TapAndWaitForResult(gfx::Point(90, 190));
+ ASSERT_TRUE(hit_node != nullptr);
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Button 2",
+ hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
+}
+
+IN_PROC_BROWSER_TEST_F(AccessibilityHitTestingBrowserTest,
+ HitTestingWithPinchZoomAndIframes) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ NavigateToURL(shell(), GURL(url::kAboutBlankURL));
+
+ AccessibilityNotificationWaiter waiter(shell()->web_contents(),
+ ui::kAXModeComplete,
+ ax::mojom::Event::kLoadComplete);
+
+ GURL url(embedded_test_server()->GetURL(
+ "/accessibility/html/iframe-coordinates.html"));
+ NavigateToURL(shell(), url);
+ SynchronizeThreads();
+ waiter.WaitForNotification();
+
+ WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(),
+ "Ordinary Button");
+ WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(),
+ "Scrolled Button");
+
+ content::TestPageScaleObserver scale_observer(shell()->web_contents());
+ const gfx::Rect contents_rect = shell()->web_contents()->GetContainerBounds();
+ const gfx::Point pinch_position(contents_rect.x(), contents_rect.y());
+
+ SimulateGesturePinchSequence(shell()->web_contents(), pinch_position, 1.25f,
+ blink::kWebGestureDeviceTouchscreen);
+ scale_observer.WaitForPageScaleUpdate();
+
+ BrowserAccessibility* hit_node;
+
+ // (26, 26) -> No button because of pinch.
+ hit_node = TapAndWaitForResult(gfx::Point(26, 26));
+ ASSERT_TRUE(hit_node != nullptr);
+ EXPECT_NE(ax::mojom::Role::kButton, hit_node->GetRole());
+
+ // (63, 63) -> "Button"
+ hit_node = TapAndWaitForResult(gfx::Point(63, 63));
+ ASSERT_TRUE(hit_node != nullptr);
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Button",
+ hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
+
+ // (63, 438) -> "Ordinary Button"
+ hit_node = TapAndWaitForResult(gfx::Point(63, 438));
+ ASSERT_TRUE(hit_node != nullptr);
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Ordinary Button",
+ hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
+
+ // (63, 569) -> "Scrolled Button"
+ hit_node = TapAndWaitForResult(gfx::Point(63, 569));
+ ASSERT_TRUE(hit_node != nullptr);
+ EXPECT_EQ(ax::mojom::Role::kButton, hit_node->GetRole());
+ EXPECT_EQ("Scrolled Button",
+ hit_node->GetStringAttribute(ax::mojom::StringAttribute::kName));
+}
+
+#endif // !defined(OS_ANDROID) && !defined(OS_MACOSX)
+
} // namespace content
diff --git a/chromium/content/browser/accessibility/line_layout_browsertest.cc b/chromium/content/browser/accessibility/line_layout_browsertest.cc
new file mode 100644
index 00000000000..e6d0bd40311
--- /dev/null
+++ b/chromium/content/browser/accessibility/line_layout_browsertest.cc
@@ -0,0 +1,97 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "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 AccessibilityLineLayoutBrowserTest : public ContentBrowserTest {
+ public:
+ AccessibilityLineLayoutBrowserTest() = default;
+ ~AccessibilityLineLayoutBrowserTest() override = default;
+
+ protected:
+ BrowserAccessibility* FindButton(BrowserAccessibility* node) {
+ if (node->GetRole() == ax::mojom::Role::kButton)
+ return node;
+ for (unsigned i = 0; i < node->PlatformChildCount(); i++) {
+ if (BrowserAccessibility* button = FindButton(node->PlatformGetChild(i)))
+ return button;
+ }
+ return nullptr;
+ }
+
+ int CountNextPreviousOnLineLinks(BrowserAccessibility* node) {
+ int line_link_count = 0;
+
+ int next_on_line_id =
+ node->GetIntAttribute(ax::mojom::IntAttribute::kNextOnLineId);
+ if (next_on_line_id) {
+ BrowserAccessibility* other = node->manager()->GetFromID(next_on_line_id);
+ EXPECT_TRUE(other) << "Next on line link is invalid.";
+ line_link_count++;
+ }
+ int previous_on_line_id =
+ node->GetIntAttribute(ax::mojom::IntAttribute::kPreviousOnLineId);
+ if (previous_on_line_id) {
+ BrowserAccessibility* other =
+ node->manager()->GetFromID(previous_on_line_id);
+ EXPECT_TRUE(other) << "Previous on line link is invalid.";
+ line_link_count++;
+ }
+
+ for (unsigned i = 0; i < node->InternalChildCount(); i++)
+ line_link_count +=
+ CountNextPreviousOnLineLinks(node->InternalGetChild(i));
+
+ return line_link_count;
+ }
+};
+
+// http://crbug.com/868830 - the patch that enabled this test to pass
+// caused a performance regression.
+IN_PROC_BROWSER_TEST_F(AccessibilityLineLayoutBrowserTest,
+ DISABLED_WholeBlockIsUpdated) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ AccessibilityNotificationWaiter waiter(shell()->web_contents(),
+ ui::kAXModeComplete,
+ ax::mojom::Event::kLoadComplete);
+ GURL url(embedded_test_server()->GetURL("/accessibility/lines/lines.html"));
+ NavigateToURL(shell(), url);
+ waiter.WaitForNotification();
+
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ BrowserAccessibilityManager* manager =
+ web_contents->GetRootBrowserAccessibilityManager();
+
+ // There should be at least 2 links between nodes on the same line.
+ int line_link_count = CountNextPreviousOnLineLinks(manager->GetRoot());
+ ASSERT_GE(line_link_count, 2);
+
+ // Find the button and click it.
+ BrowserAccessibility* button = FindButton(manager->GetRoot());
+ ASSERT_NE(nullptr, button);
+ manager->DoDefaultAction(*button);
+
+ // When done the page will change the button text to "Done".
+ WaitForAccessibilityTreeToContainNodeWithName(web_contents, "Done");
+
+ // There should be at least 2 links between nodes on the same line,
+ // though not necessarily the same as before.
+ line_link_count = CountNextPreviousOnLineLinks(manager->GetRoot());
+ ASSERT_GE(line_link_count, 2);
+}
+
+} // namespace content
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 a088ec91be7..0a80995df02 100644
--- a/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc
+++ b/chromium/content/browser/accessibility/one_shot_accessibility_tree_search.cc
@@ -443,7 +443,7 @@ bool AccessibilityTextStyleItalicPredicate(
BrowserAccessibility* start, BrowserAccessibility* node) {
int32_t style = node->GetIntAttribute(ax::mojom::IntAttribute::kTextStyle);
return 0 !=
- (style & static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleBold));
+ (style & static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleItalic));
}
bool AccessibilityTextStyleUnderlinePredicate(
diff --git a/chromium/content/browser/accessibility/touch_accessibility_aura_browsertest.cc b/chromium/content/browser/accessibility/touch_accessibility_aura_browsertest.cc
index 94d6a730b04..0ec7810518f 100644
--- a/chromium/content/browser/accessibility/touch_accessibility_aura_browsertest.cc
+++ b/chromium/content/browser/accessibility/touch_accessibility_aura_browsertest.cc
@@ -10,6 +10,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/hit_test_region_observer.h"
#include "content/shell/browser/shell.h"
#include "content/test/accessibility_browser_test_utils.h"
#include "content/test/content_browser_test_utils_internal.h"
@@ -169,10 +170,11 @@ IN_PROC_BROWSER_TEST_F(TouchAccessibilityBrowserTest,
child_frame->GetOrCreateBrowserAccessibilityManager();
ASSERT_NE(nullptr, child_manager);
- // If OOPIFs are enabled, wait until compositor frames are all properly
- // displayed, otherwise the touch event will not get sent to the correct
- // renderer process.
- WaitForChildFrameSurfaceReady(child_frame);
+ // If OOPIFs are enabled, wait until hit testing data is ready, otherwise the
+ // touch event will not get sent to the correct renderer process. However the
+ // |child_frame| being used here is not actually a
+ // RenderWidgetHostViewChildFrame.
+ WaitForHitTestDataOrChildSurfaceReady(child_frame);
// Send a touch exploration event to the button in the first iframe.
// A touch exploration event is just a mouse move event with
diff --git a/chromium/content/browser/accessibility/web_contents_accessibility_android.cc b/chromium/content/browser/accessibility/web_contents_accessibility_android.cc
index c1be0a5d63f..ee2bfb27fd3 100644
--- a/chromium/content/browser/accessibility/web_contents_accessibility_android.cc
+++ b/chromium/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -855,7 +855,7 @@ void WebContentsAccessibilityAndroid::SetTextFieldValue(
BrowserAccessibilityAndroid* node = GetAXFromUniqueID(unique_id);
if (node) {
node->manager()->SetValue(
- *node, base::android::ConvertJavaStringToUTF16(env, value));
+ *node, base::android::ConvertJavaStringToUTF8(env, value));
}
}
@@ -909,7 +909,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::NumberToString16(value));
+ node->manager()->SetValue(*node, base::NumberToString(value));
return true;
}
return false;
diff --git a/chromium/content/browser/android/browser_startup_controller.cc b/chromium/content/browser/android/browser_startup_controller.cc
index 67c5bb1167e..7ca03b04ad9 100644
--- a/chromium/content/browser/android/browser_startup_controller.cc
+++ b/chromium/content/browser/android/browser_startup_controller.cc
@@ -10,7 +10,7 @@
#include "content/browser/browser_main_loop.h"
#include "ppapi/buildflags/buildflags.h"
-#include "jni/BrowserStartupController_jni.h"
+#include "jni/BrowserStartupControllerImpl_jni.h"
using base::android::JavaParamRef;
@@ -18,28 +18,28 @@ namespace content {
void BrowserStartupComplete(int result) {
JNIEnv* env = base::android::AttachCurrentThread();
- Java_BrowserStartupController_browserStartupComplete(env, result);
+ Java_BrowserStartupControllerImpl_browserStartupComplete(env, result);
+}
+
+void ServiceManagerStartupComplete() {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_BrowserStartupControllerImpl_serviceManagerStartupComplete(env);
}
bool ShouldStartGpuProcessOnBrowserStartup() {
JNIEnv* env = base::android::AttachCurrentThread();
- return Java_BrowserStartupController_shouldStartGpuProcessOnBrowserStartup(
+ return Java_BrowserStartupControllerImpl_shouldStartGpuProcessOnBrowserStartup(
env);
}
-static void JNI_BrowserStartupController_SetCommandLineFlags(
+static void JNI_BrowserStartupControllerImpl_SetCommandLineFlags(
JNIEnv* env,
const JavaParamRef<jclass>& clazz,
- jboolean single_process,
- const JavaParamRef<jstring>& plugin_descriptor) {
- std::string plugin_str =
- (plugin_descriptor == NULL
- ? std::string()
- : base::android::ConvertJavaStringToUTF8(env, plugin_descriptor));
- SetContentCommandLineFlags(static_cast<bool>(single_process), plugin_str);
+ jboolean single_process) {
+ SetContentCommandLineFlags(static_cast<bool>(single_process));
}
-static jboolean JNI_BrowserStartupController_IsOfficialBuild(
+static jboolean JNI_BrowserStartupControllerImpl_IsOfficialBuild(
JNIEnv* env,
const JavaParamRef<jclass>& clazz) {
#if defined(OFFICIAL_BUILD)
@@ -49,17 +49,7 @@ static jboolean JNI_BrowserStartupController_IsOfficialBuild(
#endif
}
-static jboolean JNI_BrowserStartupController_IsPluginEnabled(
- JNIEnv* env,
- const JavaParamRef<jclass>& clazz) {
-#if BUILDFLAG(ENABLE_PLUGINS)
- return true;
-#else
- return false;
-#endif
-}
-
-static void JNI_BrowserStartupController_FlushStartupTasks(
+static void JNI_BrowserStartupControllerImpl_FlushStartupTasks(
JNIEnv* env,
const JavaParamRef<jclass>& clazz) {
BrowserMainLoop::GetInstance()->SynchronouslyFlushStartupTasks();
diff --git a/chromium/content/browser/android/browser_startup_controller.h b/chromium/content/browser/android/browser_startup_controller.h
index 162f1e82501..6db34d157da 100644
--- a/chromium/content/browser/android/browser_startup_controller.h
+++ b/chromium/content/browser/android/browser_startup_controller.h
@@ -9,6 +9,7 @@ namespace content {
void BrowserStartupComplete(int result);
bool ShouldStartGpuProcessOnBrowserStartup();
+void ServiceManagerStartupComplete();
} // namespace content
#endif // CONTENT_BROWSER_ANDROID_BROWSER_STARTUP_CONTROLLER_H_
diff --git a/chromium/content/browser/android/content_feature_list.cc b/chromium/content/browser/android/content_feature_list.cc
index 2cff63192ea..a3b57a91db0 100644
--- a/chromium/content/browser/android/content_feature_list.cc
+++ b/chromium/content/browser/android/content_feature_list.cc
@@ -22,6 +22,7 @@ namespace {
// this array may either refer to features defined in the header of this file or
// in other locations in the code base (e.g. content_features.h).
const base::Feature* kFeaturesExposedToJava[] = {
+ &features::kBackgroundMediaRendererHasModerateBinding,
&kEnhancedSelectionInsertionHandle,
};
diff --git a/chromium/content/browser/android/content_startup_flags.cc b/chromium/content/browser/android/content_startup_flags.cc
index 9fbc4f0adb6..dfd962dbef9 100644
--- a/chromium/content/browser/android/content_startup_flags.cc
+++ b/chromium/content/browser/android/content_startup_flags.cc
@@ -17,8 +17,7 @@
namespace content {
-void SetContentCommandLineFlags(bool single_process,
- const std::string& plugin_descriptor) {
+void SetContentCommandLineFlags(bool single_process) {
// May be called multiple times, to cover all possible program entry points.
static bool already_initialized = false;
if (already_initialized)
@@ -59,11 +58,6 @@ void SetContentCommandLineFlags(bool single_process,
// Disable anti-aliasing.
parsed_command_line->AppendSwitch(
cc::switches::kDisableCompositedAntialiasing);
-
- if (!plugin_descriptor.empty()) {
- parsed_command_line->AppendSwitchNative(
- switches::kRegisterPepperPlugins, plugin_descriptor);
- }
}
} // namespace content
diff --git a/chromium/content/browser/android/content_startup_flags.h b/chromium/content/browser/android/content_startup_flags.h
index 8f55a0c2cf4..0f90db8cef6 100644
--- a/chromium/content/browser/android/content_startup_flags.h
+++ b/chromium/content/browser/android/content_startup_flags.h
@@ -12,8 +12,7 @@ namespace content {
// Force-appends flags to the command line turning on Android-specific
// features owned by Content. This is called as soon as possible during
// initialization to make sure code sees the new flags.
-void SetContentCommandLineFlags(bool single_process,
- const std::string& plugin_descriptor);
+void SetContentCommandLineFlags(bool single_process);
} // namespace content
diff --git a/chromium/content/browser/android/content_video_view.cc b/chromium/content/browser/android/content_video_view.cc
deleted file mode 100644
index 15011da9bd3..00000000000
--- a/chromium/content/browser/android/content_video_view.cc
+++ /dev/null
@@ -1,172 +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/android/content_video_view.h"
-
-#include "base/metrics/histogram_macros.h"
-#include "content/public/browser/web_contents.h"
-#include "jni/ContentVideoViewImpl_jni.h"
-
-using base::android::AttachCurrentThread;
-using base::android::JavaParamRef;
-using base::android::JavaRef;
-using base::android::ScopedJavaGlobalRef;
-using base::android::ScopedJavaLocalRef;
-
-namespace content {
-
-namespace {
-// There can only be one content video view at a time, this holds onto that
-// singleton instance.
-ContentVideoView* g_content_video_view = NULL;
-
-} // namespace
-
-static ScopedJavaLocalRef<jobject>
-JNI_ContentVideoViewImpl_GetSingletonJavaContentVideoView(
- JNIEnv* env,
- const JavaParamRef<jclass>&) {
- if (g_content_video_view)
- return g_content_video_view->GetJavaObject(env);
- else
- return ScopedJavaLocalRef<jobject>();
-}
-
-ContentVideoView* ContentVideoView::GetInstance() {
- return g_content_video_view;
-}
-
-ContentVideoView::ContentVideoView(Client* client,
- WebContents* web_contents,
- const JavaRef<jobject>& video_embedder,
- const gfx::Size& video_natural_size)
- : client_(client), weak_factory_(this) {
- DCHECK(!g_content_video_view);
- j_content_video_view_ =
- CreateJavaObject(web_contents, video_embedder, video_natural_size);
- g_content_video_view = this;
-}
-
-ContentVideoView::~ContentVideoView() {
- DCHECK(g_content_video_view);
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
- if (!content_video_view.is_null()) {
- Java_ContentVideoViewImpl_destroyContentVideoView(env, content_video_view,
- true);
- j_content_video_view_.reset();
- }
- g_content_video_view = NULL;
-}
-
-void ContentVideoView::OpenVideo() {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
- if (!content_video_view.is_null()) {
- Java_ContentVideoViewImpl_openVideo(env, content_video_view);
- }
-}
-
-void ContentVideoView::OnMediaPlayerError(int error_type) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
- if (!content_video_view.is_null()) {
- Java_ContentVideoViewImpl_onMediaPlayerError(env, content_video_view,
- error_type);
- }
-}
-
-void ContentVideoView::OnVideoSizeChanged(int width, int height) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
- if (!content_video_view.is_null()) {
- Java_ContentVideoViewImpl_onVideoSizeChanged(env, content_video_view, width,
- height);
- }
-}
-
-void ContentVideoView::ExitFullscreen() {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobject> content_video_view = GetJavaObject(env);
- bool release_media_player = false;
- if (!content_video_view.is_null())
- Java_ContentVideoViewImpl_exitFullscreen(env, content_video_view,
- release_media_player);
-}
-
-ScopedJavaLocalRef<jobject> ContentVideoView::GetJavaObject(JNIEnv* env) {
- return j_content_video_view_.get(env);
-}
-
-void ContentVideoView::SetSurface(JNIEnv*,
- const JavaParamRef<jobject>&,
- const JavaParamRef<jobject>& surface) {
- client_->SetVideoSurface(
- gl::ScopedJavaSurface::AcquireExternalSurface(surface));
-}
-
-void ContentVideoView::DidExitFullscreen(JNIEnv*,
- const JavaParamRef<jobject>&,
- jboolean release_media_player) {
- j_content_video_view_.reset();
- client_->DidExitFullscreen(release_media_player);
-}
-
-void ContentVideoView::RecordFullscreenPlayback(JNIEnv*,
- const JavaParamRef<jobject>&,
- bool is_portrait_video,
- bool is_orientation_portrait) {
- UMA_HISTOGRAM_BOOLEAN("MobileFullscreenVideo.OrientationPortrait",
- is_orientation_portrait);
- UMA_HISTOGRAM_BOOLEAN("MobileFullscreenVideo.VideoPortrait",
- is_portrait_video);
-}
-
-void ContentVideoView::RecordExitFullscreenPlayback(
- JNIEnv*,
- const JavaParamRef<jobject>&,
- bool is_portrait_video,
- long playback_duration_in_milliseconds_before_orientation_change,
- long playback_duration_in_milliseconds_after_orientation_change) {
- bool orientation_changed = (
- playback_duration_in_milliseconds_after_orientation_change != 0);
- if (is_portrait_video) {
- UMA_HISTOGRAM_COUNTS(
- "MobileFullscreenVideo.PortraitDuration",
- playback_duration_in_milliseconds_before_orientation_change);
- UMA_HISTOGRAM_COUNTS(
- "MobileFullscreenVideo.PortraitRotation", orientation_changed);
- if (orientation_changed) {
- UMA_HISTOGRAM_COUNTS(
- "MobileFullscreenVideo.DurationAfterPotraitRotation",
- playback_duration_in_milliseconds_after_orientation_change);
- }
- } else {
- UMA_HISTOGRAM_COUNTS(
- "MobileFullscreenVideo.LandscapeDuration",
- playback_duration_in_milliseconds_before_orientation_change);
- UMA_HISTOGRAM_COUNTS(
- "MobileFullscreenVideo.LandscapeRotation", orientation_changed);
- }
-}
-
-JavaObjectWeakGlobalRef ContentVideoView::CreateJavaObject(
- WebContents* web_contents,
- const JavaRef<jobject>& j_content_video_view_embedder,
- const gfx::Size& video_natural_size) {
- JNIEnv* env = AttachCurrentThread();
- base::android::ScopedJavaLocalRef<jobject> j_web_contents =
- web_contents->GetJavaWebContents();
-
- if (j_web_contents.is_null())
- return JavaObjectWeakGlobalRef(env, nullptr);
-
- return JavaObjectWeakGlobalRef(
- env, Java_ContentVideoViewImpl_createContentVideoView(
- env, j_web_contents, j_content_video_view_embedder,
- reinterpret_cast<intptr_t>(this), video_natural_size.width(),
- video_natural_size.height())
- .obj());
-}
-} // namespace content
diff --git a/chromium/content/browser/android/content_video_view.h b/chromium/content/browser/android/content_video_view.h
deleted file mode 100644
index e070327c1a7..00000000000
--- a/chromium/content/browser/android/content_video_view.h
+++ /dev/null
@@ -1,115 +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_ANDROID_CONTENT_VIDEO_VIEW_H_
-#define CONTENT_BROWSER_ANDROID_CONTENT_VIDEO_VIEW_H_
-
-#include <jni.h>
-
-#include "base/android/jni_weak_ref.h"
-#include "base/android/scoped_java_ref.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "ui/gl/android/scoped_java_surface.h"
-
-namespace gfx {
-class Size;
-}
-
-namespace content {
-
-class WebContents;
-
-// Native mirror of ContentVideoView.java. This class is responsible for
-// creating the Java video view and passing changes in player status to it.
-// This class must be used on the UI thread.
-class ContentVideoView {
- public:
- // Returns the singleton object or NULL.
- static ContentVideoView* GetInstance();
-
- class Client {
- public:
- Client() {}
- // For receiving notififcations when the SurfaceView surface is created and
- // destroyed. When |surface.IsEmpty()| the surface was destroyed and
- // the client should not hold any references to it once this returns.
- virtual void SetVideoSurface(gl::ScopedJavaSurface surface) = 0;
-
- // Called after the ContentVideoView has been hidden because we're exiting
- // fullscreen.
- virtual void DidExitFullscreen(bool release_media_player) = 0;
-
- protected:
- ~Client() {}
-
- DISALLOW_COPY_AND_ASSIGN(Client);
- };
-
- explicit ContentVideoView(Client* client,
- WebContents* web_contents,
- const base::android::JavaRef<jobject>& embedder,
- const gfx::Size& video_natural_size);
- ~ContentVideoView();
-
- // To open another video on existing ContentVideoView.
- void OpenVideo();
-
- // Display an error dialog to the user.
- void OnMediaPlayerError(int error_type);
-
- // Update the video size.
- void OnVideoSizeChanged(int width, int height);
-
- // Exit fullscreen and notify |client_| with |DidExitFullscreen|.
- void ExitFullscreen();
-
- // Returns the corresponding ContentVideoView Java object if any.
- base::android::ScopedJavaLocalRef<jobject> GetJavaObject(JNIEnv* env);
-
- // Called by the Java class when the surface changes.
- void SetSurface(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
- const base::android::JavaParamRef<jobject>& surface);
-
- // Called when the Java fullscreen view is destroyed. If
- // |release_media_player| is true, |client_| needs to release the player
- // as we are quitting the app.
- void DidExitFullscreen(JNIEnv*,
- const base::android::JavaParamRef<jobject>&,
- jboolean release_media_player);
-
- // Functions called to record fullscreen playback UMA metrics.
- void RecordFullscreenPlayback(JNIEnv*,
- const base::android::JavaParamRef<jobject>&,
- bool is_portrait_video,
- bool is_orientation_portrait);
- void RecordExitFullscreenPlayback(
- JNIEnv*,
- const base::android::JavaParamRef<jobject>&,
- bool is_portrait_video,
- long playback_duration_in_milliseconds_before_orientation_change,
- long playback_duration_in_milliseconds_after_orientation_change);
-
- private:
- // Creates the corresponding ContentVideoView Java object.
- JavaObjectWeakGlobalRef CreateJavaObject(
- WebContents* web_contents,
- const base::android::JavaRef<jobject>& j_content_video_view_embedder,
- const gfx::Size& video_natural_size);
-
- Client* client_;
-
- // Weak reference to corresponding Java object.
- JavaObjectWeakGlobalRef j_content_video_view_;
-
- // Weak pointer for posting tasks.
- base::WeakPtrFactory<ContentVideoView> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ContentVideoView);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_CONTENT_VIDEO_VIEW_H_
diff --git a/chromium/content/browser/android/content_view_core.cc b/chromium/content/browser/android/content_view_core.cc
deleted file mode 100644
index abcb9272529..00000000000
--- a/chromium/content/browser/android/content_view_core.cc
+++ /dev/null
@@ -1,153 +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/android/content_view_core.h"
-
-#include "content/browser/frame_host/interstitial_page_impl.h"
-#include "content/browser/renderer_host/render_widget_host_view_android.h"
-#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/browser/web_contents/web_contents_view_android.h"
-#include "content/public/browser/render_view_host.h"
-#include "content/public/common/content_client.h"
-#include "content/public/common/user_agent.h"
-#include "jni/ContentViewCoreImpl_jni.h"
-#include "ui/android/window_android.h"
-
-using base::android::AttachCurrentThread;
-using base::android::JavaParamRef;
-using base::android::JavaRef;
-using base::android::ScopedJavaLocalRef;
-
-namespace content {
-
-namespace {
-
-RenderWidgetHostViewAndroid* GetRenderWidgetHostViewFromHost(
- RenderViewHost* host) {
- return static_cast<RenderWidgetHostViewAndroid*>(
- host->GetWidget()->GetView());
-}
-
-} // namespace
-
-ContentViewCore::ContentViewCore(JNIEnv* env,
- const JavaRef<jobject>& obj,
- WebContents* web_contents)
- : WebContentsObserver(web_contents),
- java_ref_(env, obj),
- web_contents_(static_cast<WebContentsImpl*>(web_contents)) {
- // Currently, the only use case we have for overriding a user agent involves
- // spoofing a desktop Linux user agent for "Request desktop site".
- // Automatically set it for all WebContents so that it is available when a
- // NavigationEntry requires the user agent to be overridden.
- const char kLinuxInfoStr[] = "X11; Linux x86_64";
- std::string product = content::GetContentClient()->GetProduct();
- std::string spoofed_ua =
- BuildUserAgentFromOSAndProduct(kLinuxInfoStr, product);
- web_contents->SetUserAgentOverride(spoofed_ua, false);
-}
-
-ContentViewCore::~ContentViewCore() {
- JNIEnv* env = base::android::AttachCurrentThread();
- ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
- java_ref_.reset();
- if (!j_obj.is_null()) {
- Java_ContentViewCoreImpl_onNativeContentViewCoreDestroyed(
- env, j_obj, reinterpret_cast<intptr_t>(this));
- }
-}
-
-void ContentViewCore::OnJavaContentViewCoreDestroyed(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- DCHECK(env->IsSameObject(java_ref_.get(env).obj(), obj));
- java_ref_.reset();
- // Java peer has gone, ContentViewCore is not functional and waits to
- // be destroyed with WebContents.
- DCHECK(web_contents_);
-}
-
-void ContentViewCore::RenderViewReady() {
- WebContentsViewAndroid* view =
- static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
- if (view->device_orientation() == 0)
- return;
- RenderWidgetHostViewAndroid* rwhva = GetRenderWidgetHostViewAndroid();
- if (rwhva)
- rwhva->UpdateScreenInfo(GetViewAndroid());
-
- web_contents_->OnScreenOrientationChange();
-}
-
-void ContentViewCore::WebContentsDestroyed() {
- delete this;
-}
-
-void ContentViewCore::RenderViewHostChanged(RenderViewHost* old_host,
- RenderViewHost* new_host) {
- if (old_host) {
- auto* view = GetRenderWidgetHostViewFromHost(old_host);
- if (view)
- view->UpdateNativeViewTree(nullptr);
-
- view = GetRenderWidgetHostViewFromHost(new_host);
- if (view)
- view->UpdateNativeViewTree(GetViewAndroid());
- }
- SetFocusInternal(GetViewAndroid()->HasFocus());
-}
-
-RenderWidgetHostViewAndroid* ContentViewCore::GetRenderWidgetHostViewAndroid()
- const {
- 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);
-}
-
-ui::ViewAndroid* ContentViewCore::GetViewAndroid() const {
- return web_contents_->GetView()->GetNativeView();
-}
-
-// ----------------------------------------------------------------------------
-// Methods called from Java via JNI
-// ----------------------------------------------------------------------------
-
-void ContentViewCore::SetFocus(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- jboolean focused) {
- SetFocusInternal(focused);
-}
-
-void ContentViewCore::SetFocusInternal(bool focused) {
- if (!GetRenderWidgetHostViewAndroid())
- return;
-
- if (focused)
- GetRenderWidgetHostViewAndroid()->GotFocus();
- else
- GetRenderWidgetHostViewAndroid()->LostFocus();
-}
-
-// This is called for each ContentView.
-jlong JNI_ContentViewCoreImpl_Init(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jweb_contents) {
- WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
- WebContents::FromJavaWebContents(jweb_contents));
- CHECK(web_contents)
- << "A ContentViewCore should be created with a valid WebContents.";
- return reinterpret_cast<intptr_t>(
- new ContentViewCore(env, obj, web_contents));
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/content_view_core.h b/chromium/content/browser/android/content_view_core.h
deleted file mode 100644
index f41a9a56497..00000000000
--- a/chromium/content/browser/android/content_view_core.h
+++ /dev/null
@@ -1,74 +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_ANDROID_CONTENT_VIEW_CORE_H_
-#define CONTENT_BROWSER_ANDROID_CONTENT_VIEW_CORE_H_
-
-#include "base/android/jni_android.h"
-#include "base/android/jni_weak_ref.h"
-#include "base/android/scoped_java_ref.h"
-#include "base/macros.h"
-#include "content/public/browser/web_contents_observer.h"
-
-namespace ui {
-class ViewAndroid;
-}
-
-namespace content {
-
-class RenderWidgetHostViewAndroid;
-class WebContentsImpl;
-
-class ContentViewCore : public WebContentsObserver {
- public:
- ContentViewCore(JNIEnv* env,
- const base::android::JavaRef<jobject>& obj,
- WebContents* web_contents);
-
- ~ContentViewCore() override;
-
- // --------------------------------------------------------------------------
- // Methods called from Java via JNI
- // --------------------------------------------------------------------------
-
- void OnJavaContentViewCoreDestroyed(
- JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj);
-
- void SetFocus(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
- jboolean focused);
-
- private:
-
- // WebContentsObserver implementation.
- void RenderViewReady() override;
- void RenderViewHostChanged(RenderViewHost* old_host,
- RenderViewHost* new_host) override;
- void WebContentsDestroyed() override;
-
- // --------------------------------------------------------------------------
- // Other private methods and data
- // --------------------------------------------------------------------------
-
- ui::ViewAndroid* GetViewAndroid() const;
-
- RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid() const;
-
- // Update focus state of the RenderWidgetHostView.
- void SetFocusInternal(bool focused);
-
- // A weak reference to the Java ContentViewCore object.
- JavaObjectWeakGlobalRef java_ref_;
-
- // Reference to the current WebContents used to determine how and what to
- // display in the ContentViewCore.
- WebContentsImpl* web_contents_;
-
- DISALLOW_COPY_AND_ASSIGN(ContentViewCore);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_ANDROID_CONTENT_VIEW_CORE_H_
diff --git a/chromium/content/browser/android/content_view_render_view.cc b/chromium/content/browser/android/content_view_render_view.cc
deleted file mode 100644
index afaefd7c88b..00000000000
--- a/chromium/content/browser/android/content_view_render_view.cc
+++ /dev/null
@@ -1,138 +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/android/content_view_render_view.h"
-
-#include <android/bitmap.h>
-#include <android/native_window_jni.h>
-
-#include <memory>
-
-#include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
-#include "base/android/scoped_java_ref.h"
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "cc/layers/layer.h"
-#include "content/public/browser/android/compositor.h"
-#include "content/public/browser/android/content_view_layer_renderer.h"
-#include "content/public/browser/web_contents.h"
-#include "jni/ContentViewRenderView_jni.h"
-#include "ui/android/view_android.h"
-#include "ui/android/window_android.h"
-#include "ui/gfx/android/java_bitmap.h"
-#include "ui/gfx/geometry/size.h"
-
-using base::android::JavaParamRef;
-using base::android::ScopedJavaLocalRef;
-
-namespace content {
-
-ContentViewRenderView::ContentViewRenderView(JNIEnv* env,
- jobject obj,
- gfx::NativeWindow root_window)
- : root_window_(root_window), current_surface_format_(0) {
- java_obj_.Reset(env, obj);
-}
-
-ContentViewRenderView::~ContentViewRenderView() {
-}
-
-// static
-static jlong JNI_ContentViewRenderView_Init(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jroot_window_android) {
- gfx::NativeWindow root_window =
- ui::WindowAndroid::FromJavaWindowAndroid(jroot_window_android);
- ContentViewRenderView* content_view_render_view =
- new ContentViewRenderView(env, obj, root_window);
- return reinterpret_cast<intptr_t>(content_view_render_view);
-}
-
-void ContentViewRenderView::Destroy(JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- delete this;
-}
-
-void ContentViewRenderView::SetCurrentWebContents(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jweb_contents) {
- InitCompositor();
- WebContents* web_contents = WebContents::FromJavaWebContents(jweb_contents);
- compositor_->SetRootLayer(web_contents
- ? web_contents->GetNativeView()->GetLayer()
- : scoped_refptr<cc::Layer>());
-}
-
-void ContentViewRenderView::OnPhysicalBackingSizeChanged(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& jweb_contents,
- jint width,
- jint height) {
- WebContents* web_contents = WebContents::FromJavaWebContents(jweb_contents);
- gfx::Size size(width, height);
- web_contents->GetNativeView()->OnPhysicalBackingSizeChanged(size);
-}
-
-void ContentViewRenderView::SurfaceCreated(JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- current_surface_format_ = 0;
- InitCompositor();
-}
-
-void ContentViewRenderView::SurfaceDestroyed(JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- compositor_->SetSurface(NULL);
- current_surface_format_ = 0;
-}
-
-void ContentViewRenderView::SurfaceChanged(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- jint format,
- jint width,
- jint height,
- const JavaParamRef<jobject>& surface) {
- if (current_surface_format_ != format) {
- current_surface_format_ = format;
- compositor_->SetSurface(surface);
- }
- compositor_->SetWindowBounds(gfx::Size(width, height));
-}
-
-void ContentViewRenderView::SetOverlayVideoMode(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- bool enabled) {
- compositor_->SetRequiresAlphaChannel(enabled);
- compositor_->SetBackgroundColor(enabled ? SK_ColorTRANSPARENT
- : SK_ColorWHITE);
- compositor_->SetNeedsComposite();
-}
-
-void ContentViewRenderView::SetNeedsComposite(
- JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj) {
- compositor_->SetNeedsComposite();
-}
-
-void ContentViewRenderView::UpdateLayerTreeHost() {
- // TODO(wkorman): Rename Layout to UpdateLayerTreeHost in all Android
- // Compositor related classes.
-}
-
-void ContentViewRenderView::DidSwapFrame(int pending_frames) {
- JNIEnv* env = base::android::AttachCurrentThread();
- Java_ContentViewRenderView_didSwapFrame(env, java_obj_);
-}
-
-void ContentViewRenderView::InitCompositor() {
- if (!compositor_)
- compositor_.reset(Compositor::Create(this, root_window_));
-}
-
-} // namespace content
diff --git a/chromium/content/browser/android/content_view_render_view.h b/chromium/content/browser/android/content_view_render_view.h
deleted file mode 100644
index 97916d3a300..00000000000
--- a/chromium/content/browser/android/content_view_render_view.h
+++ /dev/null
@@ -1,77 +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_ANDROID_CONTENT_VIEW_RENDER_VIEW_H_
-#define CONTENT_BROWSER_ANDROID_CONTENT_VIEW_RENDER_VIEW_H_
-
-#include <memory>
-
-#include "base/android/jni_weak_ref.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "content/public/browser/android/compositor_client.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace content {
-class Compositor;
-
-class ContentViewRenderView : public CompositorClient {
- public:
- ContentViewRenderView(JNIEnv* env,
- jobject obj,
- gfx::NativeWindow root_window);
-
- // Methods called from Java via JNI -----------------------------------------
- void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
- void SetCurrentWebContents(
- JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
- const base::android::JavaParamRef<jobject>& jweb_contents);
- void OnPhysicalBackingSizeChanged(
- JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
- const base::android::JavaParamRef<jobject>& jweb_contents,
- jint width,
- jint height);
- void SurfaceCreated(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj);
- void SurfaceDestroyed(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj);
- void SurfaceChanged(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
- jint format,
- jint width,
- jint height,
- const base::android::JavaParamRef<jobject>& surface);
- void SetOverlayVideoMode(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
- bool enabled);
- void SetNeedsComposite(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj);
-
- // CompositorClient implementation
- void UpdateLayerTreeHost() override;
- void DidSwapFrame(int pending_frames) override;
-
- private:
- ~ContentViewRenderView() override;
-
- void InitCompositor();
-
- base::android::ScopedJavaGlobalRef<jobject> java_obj_;
-
- std::unique_ptr<content::Compositor> compositor_;
-
- gfx::NativeWindow root_window_;
- int current_surface_format_;
-
- DISALLOW_COPY_AND_ASSIGN(ContentViewRenderView);
-};
-
-
-
-}
-
-#endif // CONTENT_BROWSER_ANDROID_CONTENT_VIEW_RENDER_VIEW_H_
diff --git a/chromium/content/browser/android/dialog_overlay_impl.cc b/chromium/content/browser/android/dialog_overlay_impl.cc
index 8335d3bf14e..70457ba7490 100644
--- a/chromium/content/browser/android/dialog_overlay_impl.cc
+++ b/chromium/content/browser/android/dialog_overlay_impl.cc
@@ -38,14 +38,14 @@ static jlong JNI_DialogOverlayImpl_Init(JNIEnv* env,
// reprojection video surface.
RenderWidgetHostViewBase* rwhvb =
static_cast<RenderWidgetHostViewBase*>(rfhi->GetView());
- if (rwhvb->IsInVR())
+ if (!rwhvb || rwhvb->IsInVR())
return 0;
WebContentsImpl* web_contents_impl = static_cast<WebContentsImpl*>(
content::WebContents::FromRenderFrameHost(rfhi));
// If the overlay would not be immediately used, fail the request.
- if (!rfhi->IsCurrent() || web_contents_impl->IsHidden())
+ if (!rfhi->IsCurrent() || !web_contents_impl || web_contents_impl->IsHidden())
return 0;
// Dialog-based overlays are not supported for persistent video.
diff --git a/chromium/content/browser/android/gesture_listener_manager.cc b/chromium/content/browser/android/gesture_listener_manager.cc
index 2cee9bf9e34..676329795a4 100644
--- a/chromium/content/browser/android/gesture_listener_manager.cc
+++ b/chromium/content/browser/android/gesture_listener_manager.cc
@@ -114,11 +114,6 @@ GestureListenerManager::~GestureListenerManager() {
Java_GestureListenerManagerImpl_onDestroy(env, j_obj);
}
-void GestureListenerManager::Reset(JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- java_ref_.reset();
-}
-
void GestureListenerManager::ResetGestureDetection(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
@@ -145,52 +140,17 @@ void GestureListenerManager::SetMultiTouchZoomSupportEnabled(
void GestureListenerManager::GestureEventAck(
const blink::WebGestureEvent& event,
InputEventAckState ack_result) {
+ // This is called to fix crash happening while WebContents is being
+ // destroyed. See https://crbug.com/803244#c20
+ if (web_contents_->IsBeingDestroyed())
+ return;
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
if (j_obj.is_null())
return;
-
- // TODO(jinsukkim): Define WebInputEvent in Java.
- switch (event.GetType()) {
- case WebInputEvent::kGestureFlingStart:
- if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) {
- // The view expects the fling velocity in pixels/s.
- Java_GestureListenerManagerImpl_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_GestureListenerManagerImpl_onScrollEndEventAck(env, j_obj);
- }
- break;
- case WebInputEvent::kGestureScrollBegin:
- Java_GestureListenerManagerImpl_onScrollBeginEventAck(env, j_obj);
- break;
- case WebInputEvent::kGestureScrollUpdate:
- if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
- Java_GestureListenerManagerImpl_onScrollUpdateGestureConsumed(env,
- j_obj);
- break;
- case WebInputEvent::kGestureScrollEnd:
- Java_GestureListenerManagerImpl_onScrollEndEventAck(env, j_obj);
- break;
- case WebInputEvent::kGesturePinchBegin:
- Java_GestureListenerManagerImpl_onPinchBeginEventAck(env, j_obj);
- break;
- case WebInputEvent::kGesturePinchEnd:
- Java_GestureListenerManagerImpl_onPinchEndEventAck(env, j_obj);
- break;
- case WebInputEvent::kGestureTap:
- Java_GestureListenerManagerImpl_onSingleTapEventAck(
- env, j_obj, ack_result == INPUT_EVENT_ACK_STATE_CONSUMED);
- break;
- case WebInputEvent::kGestureLongPress:
- if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
- Java_GestureListenerManagerImpl_onLongPressAck(env, j_obj);
- break;
- default:
- break;
- }
+ Java_GestureListenerManagerImpl_onEventAck(
+ env, j_obj, event.GetType(),
+ ack_result == INPUT_EVENT_ACK_STATE_CONSUMED);
}
void GestureListenerManager::DidStopFlinging() {
diff --git a/chromium/content/browser/android/gesture_listener_manager.h b/chromium/content/browser/android/gesture_listener_manager.h
index 59121618e4c..90bd6e43c1d 100644
--- a/chromium/content/browser/android/gesture_listener_manager.h
+++ b/chromium/content/browser/android/gesture_listener_manager.h
@@ -33,7 +33,6 @@ class GestureListenerManager : public RenderWidgetHostConnector {
WebContentsImpl* web_contents);
~GestureListenerManager() override;
- void Reset(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
void ResetGestureDetection(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
void SetDoubleTapSupportEnabled(
diff --git a/chromium/content/browser/android/overscroll_controller_android.cc b/chromium/content/browser/android/overscroll_controller_android.cc
index c9d2bd85183..6c843ed9c1c 100644
--- a/chromium/content/browser/android/overscroll_controller_android.cc
+++ b/chromium/content/browser/android/overscroll_controller_android.cc
@@ -287,26 +287,30 @@ bool OverscrollControllerAndroid::Animate(base::TimeTicks current_time,
}
void OverscrollControllerAndroid::OnFrameMetadataUpdated(
- const viz::CompositorFrameMetadata& frame_metadata) {
+ float page_scale_factor,
+ float device_scale_factor,
+ const gfx::SizeF& scrollable_viewport_size,
+ const gfx::SizeF& root_layer_size,
+ const gfx::Vector2dF& root_scroll_offset,
+ bool root_overflow_y_hidden) {
if (!refresh_effect_ && !glow_effect_)
return;
// When use-zoom-for-dsf is enabled, frame_metadata.page_scale_factor was
// already scaled by the device scale factor.
- float scale_factor = frame_metadata.page_scale_factor;
+ float scale_factor = page_scale_factor;
if (!IsUseZoomForDSFEnabled()) {
- scale_factor *= frame_metadata.device_scale_factor;
+ scale_factor *= device_scale_factor;
}
gfx::SizeF viewport_size =
- gfx::ScaleSize(frame_metadata.scrollable_viewport_size, scale_factor);
- gfx::SizeF content_size =
- gfx::ScaleSize(frame_metadata.root_layer_size, scale_factor);
+ gfx::ScaleSize(scrollable_viewport_size, scale_factor);
+ gfx::SizeF content_size = gfx::ScaleSize(root_layer_size, scale_factor);
gfx::Vector2dF content_scroll_offset =
- gfx::ScaleVector2d(frame_metadata.root_scroll_offset, scale_factor);
+ gfx::ScaleVector2d(root_scroll_offset, scale_factor);
if (refresh_effect_) {
refresh_effect_->OnFrameUpdated(content_scroll_offset,
- frame_metadata.root_overflow_y_hidden);
+ root_overflow_y_hidden);
}
if (glow_effect_) {
diff --git a/chromium/content/browser/android/overscroll_controller_android.h b/chromium/content/browser/android/overscroll_controller_android.h
index d3def7a5443..42bbdd76aee 100644
--- a/chromium/content/browser/android/overscroll_controller_android.h
+++ b/chromium/content/browser/android/overscroll_controller_android.h
@@ -29,10 +29,6 @@ class WindowAndroidCompositor;
struct DidOverscrollParams;
}
-namespace viz {
-class CompositorFrameMetadata;
-}
-
namespace content {
// Glue class for handling all inputs into Android-specific overscroll effects,
@@ -70,7 +66,12 @@ class CONTENT_EXPORT OverscrollControllerAndroid
bool Animate(base::TimeTicks current_time, cc::Layer* parent_layer);
// To be called whenever the content frame has been updated.
- void OnFrameMetadataUpdated(const viz::CompositorFrameMetadata& metadata);
+ void OnFrameMetadataUpdated(float page_scale_factor,
+ float device_scale_factor,
+ const gfx::SizeF& scrollable_viewport_size,
+ const gfx::SizeF& root_layer_size,
+ const gfx::Vector2dF& root_scroll_offset,
+ bool root_overflow_y_hidden);
// Toggle activity of any overscroll effects. When disabled, events will be
// ignored until the controller is re-enabled.
diff --git a/chromium/content/browser/android/selection/composited_touch_handle_drawable.cc b/chromium/content/browser/android/selection/composited_touch_handle_drawable.cc
index 30651710d63..2fa5bb83c66 100644
--- a/chromium/content/browser/android/selection/composited_touch_handle_drawable.cc
+++ b/chromium/content/browser/android/selection/composited_touch_handle_drawable.cc
@@ -7,11 +7,10 @@
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/macros.h"
-#include "base/trace_event/trace_event.h"
#include "cc/layers/ui_resource_layer.h"
#include "content/public/browser/android/compositor.h"
-#include "jni/HandleViewResources_jni.h"
-#include "ui/gfx/android/java_bitmap.h"
+#include "ui/android/handle_view_resources.h"
+#include "ui/android/view_android.h"
using base::android::JavaRef;
@@ -19,88 +18,21 @@ namespace content {
namespace {
-static SkBitmap CreateSkBitmapFromJavaBitmap(
- base::android::ScopedJavaLocalRef<jobject> jbitmap) {
- return jbitmap.is_null()
- ? SkBitmap()
- : CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(jbitmap));
-}
-
-class HandleResources {
- public:
- HandleResources() : loaded_(false) {
- }
-
- void LoadIfNecessary(const JavaRef<jobject>& context) {
- if (loaded_)
- return;
-
- loaded_ = true;
-
- TRACE_EVENT0("browser", "HandleResources::Create");
- JNIEnv* env = base::android::AttachCurrentThread();
-
- left_bitmap_ = CreateSkBitmapFromJavaBitmap(
- Java_HandleViewResources_getLeftHandleBitmap(env, context));
- right_bitmap_ = CreateSkBitmapFromJavaBitmap(
- Java_HandleViewResources_getRightHandleBitmap(env, context));
- center_bitmap_ = CreateSkBitmapFromJavaBitmap(
- Java_HandleViewResources_getCenterHandleBitmap(env, context));
-
- left_bitmap_.setImmutable();
- right_bitmap_.setImmutable();
- center_bitmap_.setImmutable();
-
- drawable_horizontal_padding_ratio_ =
- Java_HandleViewResources_getHandleHorizontalPaddingRatio(env);
- }
-
- const SkBitmap& GetBitmap(ui::TouchHandleOrientation orientation) {
- DCHECK(loaded_);
- switch (orientation) {
- case ui::TouchHandleOrientation::LEFT:
- return left_bitmap_;
- case ui::TouchHandleOrientation::RIGHT:
- return right_bitmap_;
- case ui::TouchHandleOrientation::CENTER:
- return center_bitmap_;
- case ui::TouchHandleOrientation::UNDEFINED:
- NOTREACHED() << "Invalid touch handle orientation.";
- };
- return center_bitmap_;
- }
-
- float GetDrawableHorizontalPaddingRatio() const {
- DCHECK(loaded_);
- return drawable_horizontal_padding_ratio_;
- }
-
- private:
- SkBitmap left_bitmap_;
- SkBitmap right_bitmap_;
- SkBitmap center_bitmap_;
- float drawable_horizontal_padding_ratio_;
- bool loaded_;
-
- DISALLOW_COPY_AND_ASSIGN(HandleResources);
-};
-
-base::LazyInstance<HandleResources>::Leaky g_selection_resources;
+base::LazyInstance<ui::HandleViewResources>::Leaky g_selection_resources;
} // namespace
CompositedTouchHandleDrawable::CompositedTouchHandleDrawable(
- cc::Layer* root_layer,
- float dpi_scale,
+ gfx::NativeView view,
const JavaRef<jobject>& context)
- : dpi_scale_(dpi_scale),
+ : view_(view),
orientation_(ui::TouchHandleOrientation::UNDEFINED),
layer_(cc::UIResourceLayer::Create()) {
g_selection_resources.Get().LoadIfNecessary(context);
drawable_horizontal_padding_ratio_ =
g_selection_resources.Get().GetDrawableHorizontalPaddingRatio();
- DCHECK(root_layer);
- root_layer->AddChild(layer_.get());
+ DCHECK(view->GetLayer());
+ view->GetLayer()->AddChild(layer_.get());
}
CompositedTouchHandleDrawable::~CompositedTouchHandleDrawable() {
@@ -146,7 +78,7 @@ void CompositedTouchHandleDrawable::SetOrientation(
}
void CompositedTouchHandleDrawable::SetOrigin(const gfx::PointF& origin) {
- origin_position_ = gfx::ScalePoint(origin, dpi_scale_);
+ origin_position_ = origin;
UpdateLayerPosition();
}
@@ -159,11 +91,10 @@ void CompositedTouchHandleDrawable::SetAlpha(float alpha) {
}
gfx::RectF CompositedTouchHandleDrawable::GetVisibleBounds() const {
- return gfx::ScaleRect(gfx::RectF(layer_->position().x(),
- layer_->position().y(),
- layer_->bounds().width(),
- layer_->bounds().height()),
- 1.f / dpi_scale_);
+ return gfx::ScaleRect(
+ gfx::RectF(layer_->position().x(), layer_->position().y(),
+ layer_->bounds().width(), layer_->bounds().height()),
+ 1.f / view_->GetDipScale());
}
float CompositedTouchHandleDrawable::GetDrawableHorizontalPaddingRatio() const {
@@ -175,7 +106,7 @@ void CompositedTouchHandleDrawable::DetachLayer() {
}
void CompositedTouchHandleDrawable::UpdateLayerPosition() {
- layer_->SetPosition(origin_position_);
+ layer_->SetPosition(gfx::ScalePoint(origin_position_, view_->GetDipScale()));
}
} // namespace content
diff --git a/chromium/content/browser/android/selection/composited_touch_handle_drawable.h b/chromium/content/browser/android/selection/composited_touch_handle_drawable.h
index 0e4b6a23933..e16b8065a68 100644
--- a/chromium/content/browser/android/selection/composited_touch_handle_drawable.h
+++ b/chromium/content/browser/android/selection/composited_touch_handle_drawable.h
@@ -5,20 +5,22 @@
#ifndef CONTENT_BROWSER_ANDROID_SELECTION_COMPOSITED_TOUCH_HANDLE_DRAWABLE_H_
#define CONTENT_BROWSER_ANDROID_SELECTION_COMPOSITED_TOUCH_HANDLE_DRAWABLE_H_
-#include "ui/touch_selection/touch_handle.h"
-
-#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
-#include "cc/layers/ui_resource_layer.h"
+#include "base/memory/scoped_refptr.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/touch_selection/touch_handle.h"
+
+namespace cc {
+class UIResourceLayer;
+} // namespace cc
namespace content {
// Touch handle drawable implementation backed by a cc layer.
class CompositedTouchHandleDrawable : public ui::TouchHandleDrawable {
public:
- CompositedTouchHandleDrawable(cc::Layer* root_layer,
- float dpi_scale,
+ CompositedTouchHandleDrawable(gfx::NativeView view,
const base::android::JavaRef<jobject>& context);
~CompositedTouchHandleDrawable() override;
@@ -36,7 +38,7 @@ class CompositedTouchHandleDrawable : public ui::TouchHandleDrawable {
void DetachLayer();
void UpdateLayerPosition();
- const float dpi_scale_;
+ gfx::NativeView view_;
float drawable_horizontal_padding_ratio_;
ui::TouchHandleOrientation orientation_;
gfx::PointF origin_position_;
diff --git a/chromium/content/browser/android/selection/selection_popup_controller.cc b/chromium/content/browser/android/selection/selection_popup_controller.cc
index b36782f64f8..8a30f1a2d9f 100644
--- a/chromium/content/browser/android/selection/selection_popup_controller.cc
+++ b/chromium/content/browser/android/selection/selection_popup_controller.cc
@@ -74,8 +74,7 @@ SelectionPopupController::CreateTouchHandleDrawable() {
// the java side in CompositedTouchHandleDrawable.
auto* view = web_contents()->GetNativeView();
return std::unique_ptr<ui::TouchHandleDrawable>(
- new CompositedTouchHandleDrawable(view->GetLayer(), view->GetDipScale(),
- activityContext));
+ new CompositedTouchHandleDrawable(view, activityContext));
}
void SelectionPopupController::MoveRangeSelectionExtent(
diff --git a/chromium/content/browser/android/synchronous_compositor_host.cc b/chromium/content/browser/android/synchronous_compositor_host.cc
index 39672258292..953c10ab3a4 100644
--- a/chromium/content/browser/android/synchronous_compositor_host.cc
+++ b/chromium/content/browser/android/synchronous_compositor_host.cc
@@ -119,6 +119,7 @@ SynchronousCompositorHost::SynchronousCompositorHost(
renderer_param_version_(0u),
need_animate_scroll_(false),
need_invalidate_count_(0u),
+ invalidate_needs_draw_(false),
did_activate_pending_tree_count_(0u) {
client_->DidInitializeCompositor(this, process_id_, routing_id_);
bridge_ = new SynchronousCompositorSyncCallBridge(this);
@@ -158,6 +159,7 @@ SynchronousCompositorHost::DemandDrawHwAsync(
const gfx::Size& viewport_size,
const gfx::Rect& viewport_rect_for_tile_priority,
const gfx::Transform& transform_for_tile_priority) {
+ invalidate_needs_draw_ = false;
scoped_refptr<FrameFuture> frame_future = new FrameFuture();
if (compute_scroll_needs_synchronous_draw_ || !allow_async_draw_) {
allow_async_draw_ = allow_async_draw_ || IsReadyForSynchronousCall();
@@ -258,6 +260,7 @@ bool SynchronousCompositorHost::DemandDrawSwInProc(SkCanvas* canvas) {
ScopedSetSkCanvas set_sk_canvas(canvas);
SyncCompositorDemandDrawSwParams params; // Unused.
uint32_t metadata_version = 0u;
+ invalidate_needs_draw_ = false;
if (!IsReadyForSynchronousCall() ||
!GetSynchronousCompositor()->DemandDrawSw(params, &common_renderer_params,
&metadata_version, &metadata))
@@ -501,10 +504,15 @@ void SynchronousCompositorHost::UpdateState(
renderer_param_version_ = params.version;
need_animate_scroll_ = params.need_animate_scroll;
root_scroll_offset_ = params.total_scroll_offset;
+ invalidate_needs_draw_ |= params.invalidate_needs_draw;
if (need_invalidate_count_ != params.need_invalidate_count) {
need_invalidate_count_ = params.need_invalidate_count;
- client_->PostInvalidate(this);
+ if (invalidate_needs_draw_) {
+ client_->PostInvalidate(this);
+ } else {
+ GetSynchronousCompositor()->WillSkipDraw();
+ }
}
if (did_activate_pending_tree_count_ !=
diff --git a/chromium/content/browser/android/synchronous_compositor_host.h b/chromium/content/browser/android/synchronous_compositor_host.h
index 7333ee6a263..6990380f9c5 100644
--- a/chromium/content/browser/android/synchronous_compositor_host.h
+++ b/chromium/content/browser/android/synchronous_compositor_host.h
@@ -141,6 +141,7 @@ class SynchronousCompositorHost : public SynchronousCompositor,
uint32_t renderer_param_version_;
bool need_animate_scroll_;
uint32_t need_invalidate_count_;
+ bool invalidate_needs_draw_;
uint32_t did_activate_pending_tree_count_;
uint32_t frame_metadata_version_ = 0u;
diff --git a/chromium/content/browser/android/url_request_content_job.cc b/chromium/content/browser/android/url_request_content_job.cc
index 7ea404b10e2..cebe3e0455e 100644
--- a/chromium/content/browser/android/url_request_content_job.cc
+++ b/chromium/content/browser/android/url_request_content_job.cc
@@ -81,8 +81,10 @@ int URLRequestContentJob::ReadRawData(net::IOBuffer* dest, int dest_size) {
return rv;
}
-bool URLRequestContentJob::IsRedirectResponse(GURL* location,
- int* http_status_code) {
+bool URLRequestContentJob::IsRedirectResponse(
+ GURL* location,
+ int* http_status_code,
+ bool* insecure_scheme_was_upgraded) {
return false;
}
diff --git a/chromium/content/browser/android/url_request_content_job.h b/chromium/content/browser/android/url_request_content_job.h
index 9f6b379b2c8..40a97470a83 100644
--- a/chromium/content/browser/android/url_request_content_job.h
+++ b/chromium/content/browser/android/url_request_content_job.h
@@ -43,7 +43,9 @@ class CONTENT_EXPORT URLRequestContentJob : public net::URLRequestJob {
void Start() override;
void Kill() override;
int ReadRawData(net::IOBuffer* buf, int buf_size) override;
- bool IsRedirectResponse(GURL* location, int* http_status_code) override;
+ bool IsRedirectResponse(GURL* location,
+ int* http_status_code,
+ bool* insecure_scheme_was_upgraded) override;
bool GetMimeType(std::string* mime_type) const override;
void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
diff --git a/chromium/content/browser/android/web_contents_observer_proxy.cc b/chromium/content/browser/android/web_contents_observer_proxy.cc
index 2aa3ab1f1ba..988ede89422 100644
--- a/chromium/content/browser/android/web_contents_observer_proxy.cc
+++ b/chromium/content/browser/android/web_contents_observer_proxy.cc
@@ -270,4 +270,11 @@ void WebContentsObserverProxy::SetToBaseURLForDataURLIfNeeded(
}
}
+void WebContentsObserverProxy::ViewportFitChanged(
+ blink::mojom::ViewportFit value) {
+ JNIEnv* env = AttachCurrentThread();
+ Java_WebContentsObserverProxy_viewportFitChanged(
+ env, java_observer_, as_jint(static_cast<int>(value)));
+}
+
} // namespace content
diff --git a/chromium/content/browser/android/web_contents_observer_proxy.h b/chromium/content/browser/android/web_contents_observer_proxy.h
index 2278b030e92..e79ad3edb59 100644
--- a/chromium/content/browser/android/web_contents_observer_proxy.h
+++ b/chromium/content/browser/android/web_contents_observer_proxy.h
@@ -58,6 +58,7 @@ class WebContentsObserverProxy : public WebContentsObserver {
void DidChangeThemeColor(SkColor color) override;
void MediaEffectivelyFullscreenChanged(bool is_fullscreen) override;
void SetToBaseURLForDataURLIfNeeded(std::string* url);
+ void ViewportFitChanged(blink::mojom::ViewportFit value) override;
base::android::ScopedJavaGlobalRef<jobject> java_observer_;
GURL base_url_of_last_started_data_url_;
diff --git a/chromium/content/browser/appcache/appcache_backend_impl.cc b/chromium/content/browser/appcache/appcache_backend_impl.cc
index f0150fb78aa..c2d1dee5f0e 100644
--- a/chromium/content/browser/appcache/appcache_backend_impl.cc
+++ b/chromium/content/browser/appcache/appcache_backend_impl.cc
@@ -126,39 +126,8 @@ void AppCacheBackendImpl::GetResourceList(
host->GetResourceList(resource_infos);
}
-std::unique_ptr<AppCacheHost> AppCacheBackendImpl::TransferHostOut(
- int host_id) {
- auto found = hosts_.find(host_id);
- if (found == hosts_.end()) {
- NOTREACHED();
- return std::unique_ptr<AppCacheHost>();
- }
-
- std::unique_ptr<AppCacheHost> transferree = std::move(found->second);
-
- // Put a new empty host in its place.
- found->second = std::make_unique<AppCacheHost>(host_id, frontend_, service_);
-
- // We give up ownership.
- transferree->PrepareForTransfer();
- return transferree;
-}
-
-void AppCacheBackendImpl::TransferHostIn(int new_host_id,
- std::unique_ptr<AppCacheHost> host) {
- auto found = hosts_.find(new_host_id);
- if (found == hosts_.end()) {
- NOTREACHED();
- return;
- }
-
- host->CompleteTransfer(new_host_id, frontend_);
- found->second = std::move(host);
-}
-
void AppCacheBackendImpl::RegisterPrecreatedHost(
std::unique_ptr<AppCacheHost> host) {
- DCHECK(IsBrowserSideNavigationEnabled());
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(host.get());
diff --git a/chromium/content/browser/appcache/appcache_backend_impl.h b/chromium/content/browser/appcache/appcache_backend_impl.h
index cf6d4352546..cf5b8e8e737 100644
--- a/chromium/content/browser/appcache/appcache_backend_impl.h
+++ b/chromium/content/browser/appcache/appcache_backend_impl.h
@@ -59,13 +59,6 @@ class CONTENT_EXPORT AppCacheBackendImpl {
using HostMap = base::hash_map<int, std::unique_ptr<AppCacheHost>>;
const HostMap& hosts() { return hosts_; }
- // Methods to support cross site navigations. Hosts are transferred
- // from process to process accordingly, deparented from the old
- // processes backend and reparented to the new.
- std::unique_ptr<AppCacheHost> TransferHostOut(int host_id);
- void TransferHostIn(int new_host_id, std::unique_ptr<AppCacheHost> host);
-
- // PlzNavigate
// The AppCacheHost is precreated by the AppCacheNavigationHandleCore class
// when a navigation is initiated. We register the host with the backend in
// this function and ignore registrations for this host id from the renderer.
diff --git a/chromium/content/browser/appcache/appcache_database.cc b/chromium/content/browser/appcache/appcache_database.cc
index 8e21b82f900..0f747557abb 100644
--- a/chromium/content/browser/appcache/appcache_database.cc
+++ b/chromium/content/browser/appcache/appcache_database.cc
@@ -250,8 +250,7 @@ bool AppCacheDatabase::FindOriginsWithGroups(std::set<url::Origin>* origins) {
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
- "SELECT DISTINCT(origin) FROM Groups";
+ static const char kSql[] = "SELECT DISTINCT(origin) FROM Groups";
sql::Statement statement(db_->GetUniqueStatement(kSql));
@@ -277,13 +276,13 @@ bool AppCacheDatabase::FindLastStorageIds(
if (!LazyOpen(kDontCreate))
return false;
- const char kMaxGroupIdSql[] = "SELECT MAX(group_id) FROM Groups";
- const char kMaxCacheIdSql[] = "SELECT MAX(cache_id) FROM Caches";
- const char kMaxResponseIdFromEntriesSql[] =
+ static const char kMaxGroupIdSql[] = "SELECT MAX(group_id) FROM Groups";
+ static const char kMaxCacheIdSql[] = "SELECT MAX(cache_id) FROM Caches";
+ static const char kMaxResponseIdFromEntriesSql[] =
"SELECT MAX(response_id) FROM Entries";
- const char kMaxResponseIdFromDeletablesSql[] =
+ static const char kMaxResponseIdFromDeletablesSql[] =
"SELECT MAX(response_id) FROM DeletableResponseIds";
- const char kMaxDeletableResponseRowIdSql[] =
+ static const char kMaxDeletableResponseRowIdSql[] =
"SELECT MAX(rowid) FROM DeletableResponseIds";
int64_t max_group_id;
int64_t max_cache_id;
@@ -314,7 +313,7 @@ bool AppCacheDatabase::FindGroup(int64_t group_id, GroupRecord* record) {
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT group_id, origin, manifest_url,"
" creation_time, last_access_time,"
" last_full_update_check_time,"
@@ -338,7 +337,7 @@ bool AppCacheDatabase::FindGroupForManifestUrl(
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT group_id, origin, manifest_url,"
" creation_time, last_access_time,"
" last_full_update_check_time,"
@@ -362,7 +361,7 @@ bool AppCacheDatabase::FindGroupsForOrigin(const url::Origin& origin,
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT group_id, origin, manifest_url,"
" creation_time, last_access_time,"
" last_full_update_check_time,"
@@ -387,7 +386,7 @@ bool AppCacheDatabase::FindGroupForCache(int64_t cache_id,
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT g.group_id, g.origin, g.manifest_url,"
" g.creation_time, g.last_access_time,"
" g.last_full_update_check_time,"
@@ -409,7 +408,7 @@ bool AppCacheDatabase::InsertGroup(const GroupRecord* record) {
if (!LazyOpen(kCreateIfNeeded))
return false;
- const char kSql[] =
+ static const char kSql[] =
"INSERT INTO Groups"
" (group_id, origin, manifest_url, creation_time, last_access_time,"
" last_full_update_check_time, first_evictable_error_time)"
@@ -429,8 +428,7 @@ bool AppCacheDatabase::DeleteGroup(int64_t group_id) {
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
- "DELETE FROM Groups WHERE group_id = ?";
+ static const char kSql[] = "DELETE FROM Groups WHERE group_id = ?";
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
statement.BindInt64(0, group_id);
return statement.Run();
@@ -460,7 +458,7 @@ bool AppCacheDatabase::CommitLazyLastAccessTimes() {
if (!transaction.Begin())
return false;
for (const auto& pair : lazy_last_access_times_) {
- const char kSql[] =
+ static const char kSql[] =
"UPDATE Groups SET last_access_time = ? WHERE group_id = ?";
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
statement.BindInt64(0, pair.second.ToInternalValue()); // time
@@ -478,7 +476,7 @@ bool AppCacheDatabase::UpdateEvictionTimes(
if (!LazyOpen(kCreateIfNeeded))
return false;
- const char kSql[] =
+ static const char kSql[] =
"UPDATE Groups"
" SET last_full_update_check_time = ?, first_evictable_error_time = ?"
" WHERE group_id = ?";
@@ -494,7 +492,7 @@ bool AppCacheDatabase::FindCache(int64_t cache_id, CacheRecord* record) {
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT cache_id, group_id, online_wildcard, update_time, cache_size"
" FROM Caches WHERE cache_id = ?";
@@ -514,7 +512,7 @@ bool AppCacheDatabase::FindCacheForGroup(int64_t group_id,
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT cache_id, group_id, online_wildcard, update_time, cache_size"
" FROM Caches WHERE group_id = ?";
@@ -547,7 +545,7 @@ bool AppCacheDatabase::InsertCache(const CacheRecord* record) {
if (!LazyOpen(kCreateIfNeeded))
return false;
- const char kSql[] =
+ static const char kSql[] =
"INSERT INTO Caches (cache_id, group_id, online_wildcard,"
" update_time, cache_size)"
" VALUES(?, ?, ?, ?, ?)";
@@ -566,8 +564,7 @@ bool AppCacheDatabase::DeleteCache(int64_t cache_id) {
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
- "DELETE FROM Caches WHERE cache_id = ?";
+ static const char kSql[] = "DELETE FROM Caches WHERE cache_id = ?";
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
statement.BindInt64(0, cache_id);
@@ -581,7 +578,7 @@ bool AppCacheDatabase::FindEntriesForCache(int64_t cache_id,
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT cache_id, url, flags, response_id, response_size FROM Entries"
" WHERE cache_id = ?";
@@ -603,7 +600,7 @@ bool AppCacheDatabase::FindEntriesForUrl(
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT cache_id, url, flags, response_id, response_size FROM Entries"
" WHERE url = ?";
@@ -626,7 +623,7 @@ bool AppCacheDatabase::FindEntry(int64_t cache_id,
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT cache_id, url, flags, response_id, response_size FROM Entries"
" WHERE cache_id = ? AND url = ?";
@@ -647,7 +644,7 @@ bool AppCacheDatabase::InsertEntry(const EntryRecord* record) {
if (!LazyOpen(kCreateIfNeeded))
return false;
- const char kSql[] =
+ static const char kSql[] =
"INSERT INTO Entries (cache_id, url, flags, response_id, response_size)"
" VALUES(?, ?, ?, ?, ?)";
@@ -679,8 +676,7 @@ bool AppCacheDatabase::DeleteEntriesForCache(int64_t cache_id) {
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
- "DELETE FROM Entries WHERE cache_id = ?";
+ static const char kSql[] = "DELETE FROM Entries WHERE cache_id = ?";
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
statement.BindInt64(0, cache_id);
@@ -694,7 +690,7 @@ bool AppCacheDatabase::AddEntryFlags(const GURL& entry_url,
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"UPDATE Entries SET flags = flags | ? WHERE cache_id = ? AND url = ?";
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
@@ -714,7 +710,7 @@ bool AppCacheDatabase::FindNamespacesForOrigin(
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT cache_id, origin, type, namespace_url, target_url, is_pattern"
" FROM Namespaces WHERE origin = ?";
@@ -735,7 +731,7 @@ bool AppCacheDatabase::FindNamespacesForCache(
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT cache_id, origin, type, namespace_url, target_url, is_pattern"
" FROM Namespaces WHERE cache_id = ?";
@@ -752,7 +748,7 @@ bool AppCacheDatabase::InsertNamespace(
if (!LazyOpen(kCreateIfNeeded))
return false;
- const char kSql[] =
+ static const char kSql[] =
"INSERT INTO Namespaces"
" (cache_id, origin, type, namespace_url, target_url, is_pattern)"
" VALUES (?, ?, ?, ?, ?, ?)";
@@ -785,8 +781,7 @@ bool AppCacheDatabase::DeleteNamespacesForCache(int64_t cache_id) {
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
- "DELETE FROM Namespaces WHERE cache_id = ?";
+ static const char kSql[] = "DELETE FROM Namespaces WHERE cache_id = ?";
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
statement.BindInt64(0, cache_id);
@@ -801,7 +796,7 @@ bool AppCacheDatabase::FindOnlineWhiteListForCache(
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT cache_id, namespace_url, is_pattern FROM OnlineWhiteLists"
" WHERE cache_id = ?";
@@ -821,7 +816,7 @@ bool AppCacheDatabase::InsertOnlineWhiteList(
if (!LazyOpen(kCreateIfNeeded))
return false;
- const char kSql[] =
+ static const char kSql[] =
"INSERT INTO OnlineWhiteLists (cache_id, namespace_url, is_pattern)"
" VALUES (?, ?, ?)";
@@ -851,8 +846,7 @@ bool AppCacheDatabase::DeleteOnlineWhiteListForCache(int64_t cache_id) {
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
- "DELETE FROM OnlineWhiteLists WHERE cache_id = ?";
+ static const char kSql[] = "DELETE FROM OnlineWhiteLists WHERE cache_id = ?";
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
statement.BindInt64(0, cache_id);
@@ -867,7 +861,7 @@ bool AppCacheDatabase::GetDeletableResponseIds(
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT response_id FROM DeletableResponseIds "
" WHERE rowid <= ?"
" LIMIT ?";
@@ -883,20 +877,20 @@ bool AppCacheDatabase::GetDeletableResponseIds(
bool AppCacheDatabase::InsertDeletableResponseIds(
const std::vector<int64_t>& response_ids) {
- const char kSql[] =
+ static const char kSql[] =
"INSERT INTO DeletableResponseIds (response_id) VALUES (?)";
return RunCachedStatementWithIds(SQL_FROM_HERE, kSql, response_ids);
}
bool AppCacheDatabase::DeleteDeletableResponseIds(
const std::vector<int64_t>& response_ids) {
- const char kSql[] =
+ static const char kSql[] =
"DELETE FROM DeletableResponseIds WHERE response_id = ?";
return RunCachedStatementWithIds(SQL_FROM_HERE, kSql, response_ids);
}
bool AppCacheDatabase::RunCachedStatementWithIds(
- const sql::StatementID& statement_id,
+ sql::StatementID statement_id,
const char* sql,
const std::vector<int64_t>& ids) {
DCHECK(sql);
@@ -939,7 +933,7 @@ bool AppCacheDatabase::FindResponseIdsForCacheHelper(
if (!LazyOpen(kDontCreate))
return false;
- const char kSql[] =
+ static const char kSql[] =
"SELECT response_id FROM Entries WHERE cache_id = ?";
sql::Statement statement(db_->GetCachedStatement(SQL_FROM_HERE, kSql));
diff --git a/chromium/content/browser/appcache/appcache_database.h b/chromium/content/browser/appcache/appcache_database.h
index 1150724619e..164f6b58772 100644
--- a/chromium/content/browser/appcache/appcache_database.h
+++ b/chromium/content/browser/appcache/appcache_database.h
@@ -18,6 +18,7 @@
#include "base/time/time.h"
#include "content/common/appcache_interfaces.h"
#include "content/common/content_export.h"
+#include "sql/statement_id.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -25,7 +26,6 @@ namespace sql {
class Connection;
class MetaTable;
class Statement;
-class StatementID;
}
namespace content {
@@ -196,7 +196,7 @@ class CONTENT_EXPORT AppCacheDatabase {
}
private:
- bool RunCachedStatementWithIds(const sql::StatementID& statement_id,
+ bool RunCachedStatementWithIds(sql::StatementID statement_id,
const char* sql,
const std::vector<int64_t>& ids);
bool RunUniqueStatementWithInt64Result(const char* sql, int64_t* result);
diff --git a/chromium/content/browser/appcache/appcache_disk_cache.cc b/chromium/content/browser/appcache/appcache_disk_cache.cc
index d718034f704..8c28d1862d7 100644
--- a/chromium/content/browser/appcache/appcache_disk_cache.cc
+++ b/chromium/content/browser/appcache/appcache_disk_cache.cc
@@ -126,7 +126,7 @@ class AppCacheDiskCache::ActiveCall
scoped_refptr<ActiveCall> active_call(
new ActiveCall(owner, entry, callback));
int rv = owner->disk_cache()->CreateEntry(
- base::Int64ToString(key), &active_call->entry_ptr_,
+ base::Int64ToString(key), net::HIGHEST, &active_call->entry_ptr_,
base::Bind(&ActiveCall::OnAsyncCompletion, active_call));
return active_call->HandleImmediateReturnValue(rv);
}
@@ -138,7 +138,7 @@ class AppCacheDiskCache::ActiveCall
scoped_refptr<ActiveCall> active_call(
new ActiveCall(owner, entry, callback));
int rv = owner->disk_cache()->OpenEntry(
- base::Int64ToString(key), &active_call->entry_ptr_,
+ base::Int64ToString(key), net::HIGHEST, &active_call->entry_ptr_,
base::Bind(&ActiveCall::OnAsyncCompletion, active_call));
return active_call->HandleImmediateReturnValue(rv);
}
@@ -149,7 +149,7 @@ class AppCacheDiskCache::ActiveCall
scoped_refptr<ActiveCall> active_call(
new ActiveCall(owner, nullptr, callback));
int rv = owner->disk_cache()->DoomEntry(
- base::Int64ToString(key),
+ base::Int64ToString(key), net::HIGHEST,
base::Bind(&ActiveCall::OnAsyncCompletion, active_call));
return active_call->HandleImmediateReturnValue(rv);
}
diff --git a/chromium/content/browser/appcache/appcache_dispatcher_host.cc b/chromium/content/browser/appcache/appcache_dispatcher_host.cc
index d5c6a6f1266..966ab0e1271 100644
--- a/chromium/content/browser/appcache/appcache_dispatcher_host.cc
+++ b/chromium/content/browser/appcache/appcache_dispatcher_host.cc
@@ -32,24 +32,30 @@ AppCacheDispatcherHost::~AppCacheDispatcherHost() = default;
void AppCacheDispatcherHost::Create(ChromeAppCacheService* appcache_service,
int process_id,
mojom::AppCacheBackendRequest request) {
+ // The process_id is the id of the RenderProcessHost, which can be reused for
+ // a new renderer process if the previous renderer process was shutdown.
+ // It can take some time after shutdown for the pipe error to propagate
+ // and unregister the previous backend. Since the AppCacheService assumes
+ // that there is one backend per process_id, we need to ensure that the
+ // previous backend is unregistered by eagerly unbinding the pipe.
+ appcache_service->Unbind(process_id);
+
appcache_service->Bind(
std::make_unique<AppCacheDispatcherHost>(appcache_service, process_id),
- std::move(request));
+ std::move(request), process_id);
}
void AppCacheDispatcherHost::RegisterHost(int32_t host_id) {
if (appcache_service_) {
- // PlzNavigate
// The AppCacheHost could have been precreated in which case we want to
// register it with the backend here.
- if (IsBrowserSideNavigationEnabled()) {
- std::unique_ptr<content::AppCacheHost> host =
- AppCacheNavigationHandleCore::GetPrecreatedHost(host_id);
- if (host.get()) {
- backend_impl_.RegisterPrecreatedHost(std::move(host));
- return;
- }
+ std::unique_ptr<content::AppCacheHost> host =
+ AppCacheNavigationHandleCore::GetPrecreatedHost(host_id);
+ if (host.get()) {
+ backend_impl_.RegisterPrecreatedHost(std::move(host));
+ return;
}
+
if (!backend_impl_.RegisterHost(host_id)) {
mojo::ReportBadMessage("ACDH_REGISTER");
}
diff --git a/chromium/content/browser/appcache/appcache_host.cc b/chromium/content/browser/appcache/appcache_host.cc
index eb88a3b00d8..2b27d83d316 100644
--- a/chromium/content/browser/appcache/appcache_host.cc
+++ b/chromium/content/browser/appcache/appcache_host.cc
@@ -509,20 +509,6 @@ void AppCacheHost::NotifyMainResourceBlocked(const GURL& manifest_url) {
blocked_manifest_url_ = manifest_url;
}
-void AppCacheHost::PrepareForTransfer() {
- // This can only happen prior to the document having been loaded.
- DCHECK(!associated_cache());
- DCHECK(!is_selection_pending());
- DCHECK(!group_being_updated_.get());
- host_id_ = kAppCacheNoHostId;
- frontend_ = nullptr;
-}
-
-void AppCacheHost::CompleteTransfer(int host_id, AppCacheFrontend* frontend) {
- host_id_ = host_id;
- frontend_ = frontend;
-}
-
base::WeakPtr<AppCacheHost> AppCacheHost::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
@@ -539,7 +525,8 @@ void AppCacheHost::MaybePassSubresourceFactory() {
network::mojom::URLLoaderFactoryPtr factory_ptr = nullptr;
AppCacheSubresourceURLFactory::CreateURLLoaderFactory(
- service()->url_loader_factory_getter(), GetWeakPtr(), &factory_ptr);
+ service()->url_loader_factory_getter()->GetNetworkFactory(), GetWeakPtr(),
+ &factory_ptr);
frontend_->OnSetSubresourceFactory(host_id(), std::move(factory_ptr));
}
diff --git a/chromium/content/browser/appcache/appcache_host.h b/chromium/content/browser/appcache/appcache_host.h
index 7da6f38ede7..e5d29763fda 100644
--- a/chromium/content/browser/appcache/appcache_host.h
+++ b/chromium/content/browser/appcache/appcache_host.h
@@ -191,10 +191,6 @@ class CONTENT_EXPORT AppCacheHost
const GURL& first_party_url() const { return first_party_url_; }
- // Methods to support cross site navigations.
- void PrepareForTransfer();
- void CompleteTransfer(int host_id, AppCacheFrontend* frontend);
-
// Returns a weak pointer reference to the host.
base::WeakPtr<AppCacheHost> GetWeakPtr();
diff --git a/chromium/content/browser/appcache/appcache_internals_ui.cc b/chromium/content/browser/appcache/appcache_internals_ui.cc
index 3a34269fbc0..f33713440f4 100644
--- a/chromium/content/browser/appcache/appcache_internals_ui.cc
+++ b/chromium/content/browser/appcache/appcache_internals_ui.cc
@@ -350,6 +350,8 @@ AppCacheInternalsUI::AppCacheInternalsUI(WebUI* web_ui)
WebUIDataSource* source =
WebUIDataSource::Create(kChromeUIAppCacheInternalsHost);
+ source->OverrideContentSecurityPolicyScriptSrc(
+ "script-src chrome://resources 'self' 'unsafe-eval';");
source->SetJsonPath("strings.js");
source->AddResourcePath("appcache_internals.js", IDR_APPCACHE_INTERNALS_JS);
diff --git a/chromium/content/browser/appcache/appcache_navigation_handle.cc b/chromium/content/browser/appcache/appcache_navigation_handle.cc
index 6c47bf8a415..b6bf5de3d8f 100644
--- a/chromium/content/browser/appcache/appcache_navigation_handle.cc
+++ b/chromium/content/browser/appcache/appcache_navigation_handle.cc
@@ -8,11 +8,10 @@
#include "content/browser/appcache/appcache_navigation_handle_core.h"
#include "content/browser/appcache/chrome_appcache_service.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/common/appcache_info.h"
namespace {
-// PlzNavigate: Used to generate the host id for a navigation initiated by the
-// browser. Starts at -2 and keeps going down.
+// Used to generate the host id for a navigation initiated by the browser.
+// Starts at -1 and keeps going down.
static int g_next_appcache_host_id = -1;
}
@@ -20,13 +19,10 @@ namespace content {
AppCacheNavigationHandle::AppCacheNavigationHandle(
ChromeAppCacheService* appcache_service)
- : appcache_host_id_(kAppCacheNoHostId),
- core_(nullptr),
- weak_factory_(this) {
+ : appcache_host_id_(g_next_appcache_host_id--),
+ core_(std::make_unique<AppCacheNavigationHandleCore>(appcache_service,
+ appcache_host_id_)) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- appcache_host_id_ = g_next_appcache_host_id--;
- core_.reset(new AppCacheNavigationHandleCore(
- weak_factory_.GetWeakPtr(), appcache_service, appcache_host_id_));
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&AppCacheNavigationHandleCore::Initialize,
diff --git a/chromium/content/browser/appcache/appcache_navigation_handle.h b/chromium/content/browser/appcache/appcache_navigation_handle.h
index 535849a7144..0b910604307 100644
--- a/chromium/content/browser/appcache/appcache_navigation_handle.h
+++ b/chromium/content/browser/appcache/appcache_navigation_handle.h
@@ -7,8 +7,6 @@
#include <memory>
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
namespace content {
@@ -42,7 +40,7 @@ class ChromeAppCacheService;
// update the RequestNavigationParams based on the id from the
// AppCacheNavigationHandle.
//
-// 6. The commit leads to AppCache registrations happening from the renderer.
+// 6) The commit leads to AppCache registrations happening from the renderer.
// This is via the IPC message AppCacheHostMsg_RegisterHost. The
// AppCacheDispatcherHost class which handles these IPCs will be informed
// about these hosts when the navigation commits. It will ignore the
@@ -52,24 +50,19 @@ class ChromeAppCacheService;
// 7) When the navigation finishes, the AppCacheNavigationHandle is
// destroyed. The destructor of the AppCacheNavigationHandle posts a
-// task to destroy the AppacheNavigationHandleCore on the IO thread.
+// task to destroy the AppCacheNavigationHandleCore on the IO thread.
class AppCacheNavigationHandle {
public:
- AppCacheNavigationHandle(ChromeAppCacheService* appcache_service);
+ explicit AppCacheNavigationHandle(ChromeAppCacheService* appcache_service);
~AppCacheNavigationHandle();
int appcache_host_id() const { return appcache_host_id_; }
AppCacheNavigationHandleCore* core() const { return core_.get(); }
- // Called when a navigation is committed. The |process_id| parameter is
- // is the process id of the renderer.
- void CommitNavigation(int process_id);
-
private:
- int appcache_host_id_;
+ const int appcache_host_id_;
std::unique_ptr<AppCacheNavigationHandleCore> core_;
- base::WeakPtrFactory<AppCacheNavigationHandle> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AppCacheNavigationHandle);
};
diff --git a/chromium/content/browser/appcache/appcache_navigation_handle_core.cc b/chromium/content/browser/appcache/appcache_navigation_handle_core.cc
index 1121e40975e..0c20a8fd7a7 100644
--- a/chromium/content/browser/appcache/appcache_navigation_handle_core.cc
+++ b/chromium/content/browser/appcache/appcache_navigation_handle_core.cc
@@ -28,14 +28,10 @@ base::LazyInstance<AppCacheHandleMap>::DestructorAtExit g_appcache_handle_map =
namespace content {
-
AppCacheNavigationHandleCore::AppCacheNavigationHandleCore(
- base::WeakPtr<AppCacheNavigationHandle> ui_handle,
ChromeAppCacheService* appcache_service,
int appcache_host_id)
- : appcache_service_(appcache_service),
- appcache_host_id_(appcache_host_id),
- ui_handle_(ui_handle) {
+ : appcache_service_(appcache_service), appcache_host_id_(appcache_host_id) {
// The AppCacheNavigationHandleCore is created on the UI thread but
// should only be accessed from the IO thread afterwards.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chromium/content/browser/appcache/appcache_navigation_handle_core.h b/chromium/content/browser/appcache/appcache_navigation_handle_core.h
index 93561916a65..b50429269f8 100644
--- a/chromium/content/browser/appcache/appcache_navigation_handle_core.h
+++ b/chromium/content/browser/appcache/appcache_navigation_handle_core.h
@@ -29,7 +29,6 @@ class ChromeAppCacheService;
class AppCacheNavigationHandleCore : public AppCacheFrontend {
public:
AppCacheNavigationHandleCore(
- base::WeakPtr<AppCacheNavigationHandle> ui_handle,
ChromeAppCacheService* appcache_service,
int appcache_host_id);
~AppCacheNavigationHandleCore() override;
@@ -73,7 +72,6 @@ class AppCacheNavigationHandleCore : public AppCacheFrontend {
std::unique_ptr<AppCacheHost> precreated_host_;
scoped_refptr<ChromeAppCacheService> appcache_service_;
int appcache_host_id_;
- base::WeakPtr<AppCacheNavigationHandle> ui_handle_;
DISALLOW_COPY_AND_ASSIGN(AppCacheNavigationHandleCore);
};
diff --git a/chromium/content/browser/appcache/appcache_request_handler.cc b/chromium/content/browser/appcache/appcache_request_handler.cc
index 07d2b0573e4..7f291f904b0 100644
--- a/chromium/content/browser/appcache/appcache_request_handler.cc
+++ b/chromium/content/browser/appcache/appcache_request_handler.cc
@@ -225,13 +225,13 @@ std::unique_ptr<AppCacheRequestHandler>
AppCacheRequestHandler::InitializeForNavigationNetworkService(
const network::ResourceRequest& request,
AppCacheNavigationHandleCore* appcache_handle_core,
- URLLoaderFactoryGetter* url_loader_factory_getter) {
+ scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory) {
std::unique_ptr<AppCacheRequestHandler> handler =
appcache_handle_core->host()->CreateRequestHandler(
AppCacheURLLoaderRequest::Create(request),
static_cast<ResourceType>(request.resource_type),
request.should_reset_appcache);
- handler->network_url_loader_factory_getter_ = url_loader_factory_getter;
+ handler->network_loader_factory_ = std::move(network_loader_factory);
handler->appcache_host_ = appcache_handle_core->host()->GetWeakPtr();
return handler;
}
@@ -600,7 +600,7 @@ AppCacheRequestHandler::MaybeCreateSubresourceLoaderParams() {
// The factory is destroyed when the renderer drops the connection.
network::mojom::URLLoaderFactoryPtr factory_ptr;
AppCacheSubresourceURLFactory::CreateURLLoaderFactory(
- network_url_loader_factory_getter_.get(), appcache_host_, &factory_ptr);
+ network_loader_factory_, appcache_host_, &factory_ptr);
SubresourceLoaderParams params;
params.loader_factory_info = factory_ptr.PassInterface();
diff --git a/chromium/content/browser/appcache/appcache_request_handler.h b/chromium/content/browser/appcache/appcache_request_handler.h
index cea61697ba8..b8b82668b0e 100644
--- a/chromium/content/browser/appcache/appcache_request_handler.h
+++ b/chromium/content/browser/appcache/appcache_request_handler.h
@@ -18,9 +18,9 @@
#include "content/browser/appcache/appcache_request_handler.h"
#include "content/browser/appcache/appcache_service_impl.h"
#include "content/browser/loader/navigation_loader_interceptor.h"
-#include "content/browser/url_loader_factory_getter.h"
#include "content/common/content_export.h"
#include "content/public/common/resource_type.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace net {
class NetworkDelegate;
@@ -109,7 +109,7 @@ class CONTENT_EXPORT AppCacheRequestHandler
InitializeForNavigationNetworkService(
const network::ResourceRequest& request,
AppCacheNavigationHandleCore* appcache_handle_core,
- URLLoaderFactoryGetter* url_loader_factory_getter);
+ scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory);
static bool IsMainResourceType(ResourceType type) {
return IsResourceTypeFrame(type) || type == RESOURCE_TYPE_SHARED_WORKER;
@@ -257,8 +257,8 @@ class CONTENT_EXPORT AppCacheRequestHandler
// RequestHandler 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_;
+ // The network URL loader factory.
+ scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory_;
// The AppCache host instance. We pass this to the
// AppCacheSubresourceURLFactory instance on creation.
diff --git a/chromium/content/browser/appcache/appcache_request_handler_unittest.cc b/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
index 3e742cdca67..bd3494c4aa9 100644
--- a/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_request_handler_unittest.cc
@@ -22,7 +22,6 @@
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/scoped_feature_list.h"
-#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/appcache/appcache.h"
@@ -34,6 +33,7 @@
#include "content/browser/appcache/appcache_url_request_job.h"
#include "content/browser/appcache/mock_appcache_policy.h"
#include "content/browser/appcache/mock_appcache_service.h"
+#include "content/public/test/test_browser_thread_bundle.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/http/http_response_headers.h"
@@ -202,15 +202,14 @@ class AppCacheRequestHandlerTest
};
static void SetUpTestCase() {
- scoped_task_environment_.reset(new base::test::ScopedTaskEnvironment);
- io_thread_.reset(new base::Thread("AppCacheRequestHandlerTest Thread"));
- base::Thread::Options options(base::MessageLoop::TYPE_IO, 0);
- io_thread_->StartWithOptions(options);
+ thread_bundle_.reset(
+ new TestBrowserThreadBundle(TestBrowserThreadBundle::REAL_IO_THREAD));
+ io_task_runner_ = BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
}
static void TearDownTestCase() {
- io_thread_.reset();
- scoped_task_environment_.reset();
+ thread_bundle_.reset();
+ io_task_runner_ = nullptr;
}
// Test harness --------------------------------------------------
@@ -231,7 +230,7 @@ class AppCacheRequestHandlerTest
test_finished_event_.reset(new base::WaitableEvent(
base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED));
- io_thread_->task_runner()->PostTask(
+ io_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&AppCacheRequestHandlerTest::MethodWrapper<Method>,
base::Unretained(this), method));
@@ -239,7 +238,7 @@ class AppCacheRequestHandlerTest
}
void SetUpTest() {
- DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
+ DCHECK(io_task_runner_->BelongsToCurrentThread());
mock_service_.reset(new MockAppCacheService);
// Initializes URLRequestContext on the IO thread.
empty_context_.reset(new net::URLRequestContext);
@@ -258,7 +257,7 @@ class AppCacheRequestHandlerTest
}
void TearDownTest() {
- DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
+ DCHECK(io_task_runner_->BelongsToCurrentThread());
appcache_url_request_job_.reset();
appcache_url_loader_job_.reset();
handler_.reset();
@@ -276,7 +275,7 @@ class AppCacheRequestHandlerTest
void TestFinished() {
// We unwind the stack prior to finishing up to let stack
// based objects get deleted.
- DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
+ DCHECK(io_task_runner_->BelongsToCurrentThread());
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&AppCacheRequestHandlerTest::TestFinishedUnwound,
@@ -293,7 +292,7 @@ class AppCacheRequestHandlerTest
}
void ScheduleNextTask() {
- DCHECK(io_thread_->task_runner()->BelongsToCurrentThread());
+ DCHECK(io_task_runner_->BelongsToCurrentThread());
if (task_stack_.empty()) {
TestFinished();
return;
@@ -969,18 +968,18 @@ class AppCacheRequestHandlerTest
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>
- scoped_task_environment_;
+ static std::unique_ptr<TestBrowserThreadBundle> thread_bundle_;
+ static scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
RequestHandlerType request_handler_type_;
base::test::ScopedFeatureList feature_list_;
};
// static
-std::unique_ptr<base::Thread> AppCacheRequestHandlerTest::io_thread_;
-std::unique_ptr<base::test::ScopedTaskEnvironment>
- AppCacheRequestHandlerTest::scoped_task_environment_;
+std::unique_ptr<TestBrowserThreadBundle>
+ AppCacheRequestHandlerTest::thread_bundle_;
+scoped_refptr<base::SingleThreadTaskRunner>
+ AppCacheRequestHandlerTest::io_task_runner_;
TEST_P(AppCacheRequestHandlerTest, MainResource_Miss) {
RunTestOnIOThread(&AppCacheRequestHandlerTest::MainResource_Miss);
diff --git a/chromium/content/browser/appcache/appcache_service_impl.h b/chromium/content/browser/appcache/appcache_service_impl.h
index ff3bcd5153d..bf6fabe30ff 100644
--- a/chromium/content/browser/appcache/appcache_service_impl.h
+++ b/chromium/content/browser/appcache/appcache_service_impl.h
@@ -153,7 +153,7 @@ class CONTENT_EXPORT AppCacheServiceImpl
// Each child process in chrome uses a distinct backend instance.
// See chrome/browser/AppCacheDispatcherHost.
void RegisterBackend(AppCacheBackendImpl* backend_impl);
- void UnregisterBackend(AppCacheBackendImpl* backend_impl);
+ virtual void UnregisterBackend(AppCacheBackendImpl* backend_impl);
AppCacheBackendImpl* GetBackend(int id) const {
BackendMap::const_iterator it = backends_.find(id);
return (it != backends_.end()) ? it->second : NULL;
diff --git a/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc b/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
index 43400a1f726..03237c227d3 100644
--- a/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_storage_impl_unittest.cc
@@ -375,7 +375,9 @@ class AppCacheStorageImplTest : public testing::Test {
// Test harness --------------------------------------------------
- AppCacheStorageImplTest() { request_delegate_.set_quit_on_complete(false); }
+ AppCacheStorageImplTest() {
+ request_delegate_.set_on_complete(base::DoNothing());
+ }
template <class Method>
void RunTestOnIOThread(Method method) {
diff --git a/chromium/content/browser/appcache/appcache_subresource_url_factory.cc b/chromium/content/browser/appcache/appcache_subresource_url_factory.cc
index 72bb381ee93..08336328e4e 100644
--- a/chromium/content/browser/appcache/appcache_subresource_url_factory.cc
+++ b/chromium/content/browser/appcache/appcache_subresource_url_factory.cc
@@ -10,7 +10,6 @@
#include "content/browser/appcache/appcache_request_handler.h"
#include "content/browser/appcache/appcache_url_loader_job.h"
#include "content/browser/appcache/appcache_url_loader_request.h"
-#include "content/browser/url_loader_factory_getter.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
@@ -38,15 +37,16 @@ namespace {
class SubresourceLoader : public network::mojom::URLLoader,
public network::mojom::URLLoaderClient {
public:
- SubresourceLoader(network::mojom::URLLoaderRequest url_loader_request,
- int32_t routing_id,
- int32_t request_id,
- uint32_t options,
- const network::ResourceRequest& request,
- network::mojom::URLLoaderClientPtr client,
- const net::MutableNetworkTrafficAnnotationTag& annotation,
- base::WeakPtr<AppCacheHost> appcache_host,
- scoped_refptr<URLLoaderFactoryGetter> net_factory_getter)
+ SubresourceLoader(
+ network::mojom::URLLoaderRequest url_loader_request,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const network::ResourceRequest& request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag& annotation,
+ base::WeakPtr<AppCacheHost> appcache_host,
+ scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory)
: remote_binding_(this, std::move(url_loader_request)),
remote_client_(std::move(client)),
request_(request),
@@ -54,7 +54,7 @@ class SubresourceLoader : public network::mojom::URLLoader,
request_id_(request_id),
options_(options),
traffic_annotation_(annotation),
- network_loader_factory_(std::move(net_factory_getter)),
+ network_loader_factory_(std::move(network_loader_factory)),
local_client_binding_(this),
host_(appcache_host),
weak_factory_(this) {
@@ -116,7 +116,7 @@ class SubresourceLoader : public network::mojom::URLLoader,
DCHECK(!appcache_loader_);
network::mojom::URLLoaderClientPtr client_ptr;
local_client_binding_.Bind(mojo::MakeRequest(&client_ptr));
- network_loader_factory_->GetNetworkFactory()->CreateLoaderAndStart(
+ network_loader_factory_->CreateLoaderAndStart(
mojo::MakeRequest(&network_loader_), routing_id_, request_id_, options_,
request_, std::move(client_ptr), traffic_annotation_);
if (has_set_priority_)
@@ -127,13 +127,15 @@ class SubresourceLoader : public network::mojom::URLLoader,
// network::mojom::URLLoader implementation
// Called by the remote client in the renderer.
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override {
DCHECK(!modified_request_headers.has_value())
<< "Redirect with modified headers was not supported yet. "
"crbug.com/845683";
if (!handler_) {
- network_loader_->FollowRedirect(base::nullopt);
+ network_loader_->FollowRedirect(base::nullopt, base::nullopt);
return;
}
DCHECK(network_loader_);
@@ -152,7 +154,7 @@ class SubresourceLoader : public network::mojom::URLLoader,
if (handler)
CreateAndStartAppCacheLoader(std::move(handler));
else
- network_loader_->FollowRedirect(base::nullopt);
+ network_loader_->FollowRedirect(base::nullopt, base::nullopt);
}
void SetPriority(net::RequestPriority priority,
@@ -179,12 +181,10 @@ class SubresourceLoader : public network::mojom::URLLoader,
// network::mojom::URLLoaderClient implementation
// Called by either the appcache or network loader, whichever is in use.
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override {
+ const network::ResourceResponseHead& response_head) override {
// Don't MaybeFallback for appcache produced responses.
if (appcache_loader_ || !handler_) {
- remote_client_->OnReceiveResponse(response_head,
- std::move(downloaded_file));
+ remote_client_->OnReceiveResponse(response_head);
return;
}
@@ -192,19 +192,16 @@ class SubresourceLoader : public network::mojom::URLLoader,
handler_->MaybeFallbackForSubresourceResponse(
response_head,
base::BindOnce(&SubresourceLoader::ContinueOnReceiveResponse,
- weak_factory_.GetWeakPtr(), response_head,
- std::move(downloaded_file)));
+ weak_factory_.GetWeakPtr(), response_head));
}
void ContinueOnReceiveResponse(
const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file,
SingleRequestURLLoaderFactory::RequestHandler handler) {
if (handler) {
CreateAndStartAppCacheLoader(std::move(handler));
} else {
- remote_client_->OnReceiveResponse(response_head,
- std::move(downloaded_file));
+ remote_client_->OnReceiveResponse(response_head);
}
}
@@ -237,10 +234,6 @@ class SubresourceLoader : public network::mojom::URLLoader,
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 {
@@ -291,7 +284,7 @@ class SubresourceLoader : public network::mojom::URLLoader,
int32_t request_id_;
uint32_t options_;
net::MutableNetworkTrafficAnnotationTag traffic_annotation_;
- scoped_refptr<URLLoaderFactoryGetter> network_loader_factory_;
+ scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory_;
net::RedirectInfo redirect_info_;
int redirect_limit_ = net::URLRequest::kMaxRedirects;
bool did_receive_network_response_ = false;
@@ -319,9 +312,9 @@ class SubresourceLoader : public network::mojom::URLLoader,
// Implements the URLLoaderFactory mojom for AppCache requests.
AppCacheSubresourceURLFactory::AppCacheSubresourceURLFactory(
- URLLoaderFactoryGetter* default_url_loader_factory_getter,
+ scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory,
base::WeakPtr<AppCacheHost> host)
- : default_url_loader_factory_getter_(default_url_loader_factory_getter),
+ : network_loader_factory_(std::move(network_loader_factory)),
appcache_host_(host),
weak_factory_(this) {
bindings_.set_connection_error_handler(
@@ -333,7 +326,7 @@ AppCacheSubresourceURLFactory::~AppCacheSubresourceURLFactory() {}
// static
void AppCacheSubresourceURLFactory::CreateURLLoaderFactory(
- URLLoaderFactoryGetter* default_url_loader_factory_getter,
+ scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory,
base::WeakPtr<AppCacheHost> host,
network::mojom::URLLoaderFactoryPtr* loader_factory) {
DCHECK(host.get());
@@ -341,7 +334,7 @@ void AppCacheSubresourceURLFactory::CreateURLLoaderFactory(
// 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);
+ std::move(network_loader_factory), host);
impl->Clone(mojo::MakeRequest(loader_factory));
// Save the factory in the host to ensure that we don't create it again when
@@ -360,7 +353,7 @@ void AppCacheSubresourceURLFactory::CreateLoaderAndStart(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
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_);
+ appcache_host_, network_loader_factory_);
}
void AppCacheSubresourceURLFactory::Clone(
diff --git a/chromium/content/browser/appcache/appcache_subresource_url_factory.h b/chromium/content/browser/appcache/appcache_subresource_url_factory.h
index 9ed9fc82161..c2ecf3420cd 100644
--- a/chromium/content/browser/appcache/appcache_subresource_url_factory.h
+++ b/chromium/content/browser/appcache/appcache_subresource_url_factory.h
@@ -13,13 +13,16 @@
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "url/gurl.h"
+namespace network {
+class SharedURLLoaderFactory;
+}
+
namespace content {
class AppCacheHost;
class AppCacheJob;
class AppCacheRequestHandler;
class AppCacheServiceImpl;
-class URLLoaderFactoryGetter;
// Implements the URLLoaderFactory mojom for AppCache subresource requests.
class CONTENT_EXPORT AppCacheSubresourceURLFactory
@@ -28,13 +31,12 @@ class CONTENT_EXPORT AppCacheSubresourceURLFactory
~AppCacheSubresourceURLFactory() override;
// Factory function to create an instance of the factory.
- // 1. The |factory_getter| parameter is used to query the network service
- // to pass network requests to.
- // 2. The |host| parameter contains the appcache host instance. This is used
- // to create the AppCacheRequestHandler instances for handling subresource
- // requests.
+ // The |host| parameter contains the appcache host instance. This is used
+ // to create the AppCacheRequestHandler instances for handling subresource
+ // requests.
+ // |network_loader_factory| is a factory to the Network Service.
static void CreateURLLoaderFactory(
- URLLoaderFactoryGetter* factory_getter,
+ scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory,
base::WeakPtr<AppCacheHost> host,
network::mojom::URLLoaderFactoryPtr* loader_factory);
@@ -56,12 +58,13 @@ class CONTENT_EXPORT AppCacheSubresourceURLFactory
// TODO(michaeln): Declare SubresourceLoader here and add unittests.
- AppCacheSubresourceURLFactory(URLLoaderFactoryGetter* factory_getter,
- base::WeakPtr<AppCacheHost> host);
+ AppCacheSubresourceURLFactory(
+ scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory,
+ base::WeakPtr<AppCacheHost> host);
void OnConnectionError();
mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
- scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_;
+ scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory_;
base::WeakPtr<AppCacheHost> appcache_host_;
base::WeakPtrFactory<AppCacheSubresourceURLFactory> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(AppCacheSubresourceURLFactory);
diff --git a/chromium/content/browser/appcache/appcache_update_job_unittest.cc b/chromium/content/browser/appcache/appcache_update_job_unittest.cc
index c02b0f17956..d801ffce9a4 100644
--- a/chromium/content/browser/appcache/appcache_update_job_unittest.cc
+++ b/chromium/content/browser/appcache/appcache_update_job_unittest.cc
@@ -624,7 +624,7 @@ class MockURLLoaderFactory : public network::mojom::URLLoaderFactory {
response.headers = info.headers;
response.headers->GetMimeType(&response.mime_type);
- client->OnReceiveResponse(response, nullptr);
+ client->OnReceiveResponse(response);
mojo::DataPipe data_pipe;
@@ -831,10 +831,8 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
expected = 2; // 2 hosts using frontend1
EXPECT_EQ(expected, events[0].first.size());
MockFrontend::HostIds& host_ids = events[0].first;
- EXPECT_TRUE(std::find(host_ids.begin(), host_ids.end(), host1.host_id())
- != host_ids.end());
- EXPECT_TRUE(std::find(host_ids.begin(), host_ids.end(), host3.host_id())
- != host_ids.end());
+ EXPECT_TRUE(base::ContainsValue(host_ids, host1.host_id()));
+ EXPECT_TRUE(base::ContainsValue(host_ids, host3.host_id()));
EXPECT_EQ(AppCacheEventID::APPCACHE_CHECKING_EVENT, events[0].second);
events = mock_frontend2.raised_events_;
@@ -3644,8 +3642,7 @@ class AppCacheUpdateJobTest : public testing::TestWithParam<RequestHandlerType>,
for (size_t k = 0; k < expected_ids.size(); ++k) {
int id = expected_ids[k];
- EXPECT_TRUE(std::find(actual_ids.begin(), actual_ids.end(), id) !=
- actual_ids.end());
+ EXPECT_TRUE(base::ContainsValue(actual_ids, id));
}
}
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 321e4fad8ba..3f5051c2d8c 100644
--- a/chromium/content/browser/appcache/appcache_update_url_loader_request.cc
+++ b/chromium/content/browser/appcache/appcache_update_url_loader_request.cc
@@ -94,8 +94,7 @@ int AppCacheUpdateJob::UpdateURLLoaderRequest::Cancel() {
}
void AppCacheUpdateJob::UpdateURLLoaderRequest::OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) {
+ const network::ResourceResponseHead& response_head) {
response_ = response_head;
// TODO(ananta/michaeln)
@@ -123,12 +122,6 @@ void AppCacheUpdateJob::UpdateURLLoaderRequest::OnReceiveRedirect(
fetcher_->OnReceivedRedirect(redirect_info);
}
-void AppCacheUpdateJob::UpdateURLLoaderRequest::OnDataDownloaded(
- int64_t data_len,
- int64_t encoded_data_len) {
- NOTIMPLEMENTED();
-}
-
void AppCacheUpdateJob::UpdateURLLoaderRequest::OnUploadProgress(
int64_t current_position,
int64_t total_size,
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 e7279f62572..d826fc30fa4 100644
--- a/chromium/content/browser/appcache/appcache_update_url_loader_request.h
+++ b/chromium/content/browser/appcache/appcache_update_url_loader_request.h
@@ -54,12 +54,10 @@ class AppCacheUpdateJob::UpdateURLLoaderRequest
// network::mojom::URLLoaderClient implementation.
// These methods are called by the network loader.
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override;
+ const network::ResourceResponseHead& response_head) override;
void OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const network::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;
diff --git a/chromium/content/browser/appcache/appcache_url_loader_job.cc b/chromium/content/browser/appcache/appcache_url_loader_job.cc
index b3969898ae2..1455c9f3f23 100644
--- a/chromium/content/browser/appcache/appcache_url_loader_job.cc
+++ b/chromium/content/browser/appcache/appcache_url_loader_job.cc
@@ -106,6 +106,8 @@ base::WeakPtr<AppCacheURLLoaderJob> AppCacheURLLoaderJob::GetDerivedWeakPtr() {
}
void AppCacheURLLoaderJob::FollowRedirect(
+ const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
NOTREACHED() << "appcache never produces redirects";
}
@@ -287,8 +289,7 @@ void AppCacheURLLoaderJob::SendResponseInfo() {
response_head.ssl_info = http_info->ssl_info;
response_head.load_timing = load_timing_info_;
- client_->OnReceiveResponse(response_head,
- network::mojom::DownloadedTempFilePtr());
+ client_->OnReceiveResponse(response_head);
client_->OnStartLoadingResponseBody(std::move(data_pipe_.consumer_handle));
}
diff --git a/chromium/content/browser/appcache/appcache_url_loader_job.h b/chromium/content/browser/appcache/appcache_url_loader_job.h
index d116c91d890..1cc9ae22816 100644
--- a/chromium/content/browser/appcache/appcache_url_loader_job.h
+++ b/chromium/content/browser/appcache/appcache_url_loader_job.h
@@ -55,7 +55,9 @@ class CONTENT_EXPORT AppCacheURLLoaderJob : public AppCacheJob,
base::WeakPtr<AppCacheURLLoaderJob> GetDerivedWeakPtr();
// network::mojom::URLLoader implementation:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
diff --git a/chromium/content/browser/appcache/appcache_url_loader_request.cc b/chromium/content/browser/appcache/appcache_url_loader_request.cc
index 68b55a93369..03e37c05688 100644
--- a/chromium/content/browser/appcache/appcache_url_loader_request.cc
+++ b/chromium/content/browser/appcache/appcache_url_loader_request.cc
@@ -77,9 +77,10 @@ base::WeakPtr<AppCacheURLLoaderRequest> AppCacheURLLoaderRequest::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);
+ net::RedirectUtil::UpdateHttpRequest(
+ request_.url, request_.method, redirect_info,
+ base::nullopt /* modified_request_headers */, &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);
diff --git a/chromium/content/browser/appcache/chrome_appcache_service.cc b/chromium/content/browser/appcache/chrome_appcache_service.cc
index 89ccb9a8250..5c95cb9ee21 100644
--- a/chromium/content/browser/appcache/chrome_appcache_service.cc
+++ b/chromium/content/browser/appcache/chrome_appcache_service.cc
@@ -45,8 +45,26 @@ void ChromeAppCacheService::InitializeOnIOThread(
void ChromeAppCacheService::Bind(
std::unique_ptr<mojom::AppCacheBackend> backend,
- mojom::AppCacheBackendRequest request) {
- bindings_.AddBinding(std::move(backend), std::move(request));
+ mojom::AppCacheBackendRequest request,
+ int process_id) {
+ DCHECK(process_bindings_.find(process_id) == process_bindings_.end());
+ process_bindings_[process_id] =
+ bindings_.AddBinding(std::move(backend), std::move(request));
+}
+
+void ChromeAppCacheService::Unbind(int process_id) {
+ auto it = process_bindings_.find(process_id);
+ if (it != process_bindings_.end()) {
+ bindings_.RemoveBinding(it->second);
+ DCHECK(process_bindings_.find(process_id) == process_bindings_.end());
+ }
+}
+
+void ChromeAppCacheService::UnregisterBackend(
+ AppCacheBackendImpl* backend_impl) {
+ int process_id = backend_impl->process_id();
+ process_bindings_.erase(process_bindings_.find(process_id));
+ AppCacheServiceImpl::UnregisterBackend(backend_impl);
}
void ChromeAppCacheService::Shutdown() {
diff --git a/chromium/content/browser/appcache/chrome_appcache_service.h b/chromium/content/browser/appcache/chrome_appcache_service.h
index 7845936ea43..316f2c4c83d 100644
--- a/chromium/content/browser/appcache/chrome_appcache_service.h
+++ b/chromium/content/browser/appcache/chrome_appcache_service.h
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner_helpers.h"
+#include "content/browser/appcache/appcache_backend_impl.h"
#include "content/browser/appcache/appcache_policy.h"
#include "content/browser/appcache/appcache_service_impl.h"
#include "content/common/appcache.mojom.h"
@@ -56,7 +57,14 @@ class CONTENT_EXPORT ChromeAppCacheService
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy);
void Bind(std::unique_ptr<mojom::AppCacheBackend> backend,
- mojom::AppCacheBackendRequest request);
+ mojom::AppCacheBackendRequest request,
+ int process_id);
+ // Unbinds the pipe corresponding to the given process_id. Unbinding
+ // unregisters and destroys the existing backend for that process_id.
+ // The function must be called before a new backend is created for the given
+ // process_id to ensure that there is at most one backend per process_id.
+ // The function does nothing if no pipe was bound.
+ void Unbind(int process_id);
void Shutdown();
@@ -66,6 +74,9 @@ class CONTENT_EXPORT ChromeAppCacheService
bool CanCreateAppCache(const GURL& manifest_url,
const GURL& first_party) override;
+ // AppCacheServiceImpl override
+ void UnregisterBackend(AppCacheBackendImpl* backend_impl) override;
+
protected:
~ChromeAppCacheService() override;
@@ -81,6 +92,9 @@ class CONTENT_EXPORT ChromeAppCacheService
base::FilePath cache_path_;
mojo::StrongBindingSet<mojom::AppCacheBackend> bindings_;
+ // A map from a process_id to a binding_id.
+ std::map<int, mojo::BindingId> process_bindings_;
+
DISALLOW_COPY_AND_ASSIGN(ChromeAppCacheService);
};
diff --git a/chromium/content/browser/background_fetch/background_fetch.proto b/chromium/content/browser/background_fetch/background_fetch.proto
index ec387edd7b8..c8708770309 100644
--- a/chromium/content/browser/background_fetch/background_fetch.proto
+++ b/chromium/content/browser/background_fetch/background_fetch.proto
@@ -28,31 +28,36 @@ message BackgroundFetchRegistration {
// Developer provided options.
// https://wicg.github.io/background-fetch/#background-fetch-manager
//
-// Next Tag: 4
+// Next Tag: 3
message BackgroundFetchOptions {
optional string title = 1;
- // https://w3c.github.io/manifest/#icons-member
- // Note that sizes can have multiple values (e.g. "32x32 64x64").
+ // https://w3c.github.io/manifest/#dom-imageresource
//
- // Next Tag: 4
- message IconDefinition {
+ // Next Tag: 5
+ message ImageResource {
optional string src = 1;
- optional string sizes = 2;
- optional string type = 3;
+
+ // Next Tag: 3
+ message Size {
+ optional int32 width = 1;
+ optional int32 height = 2;
+ }
+
+ repeated Size sizes = 2;
+ optional bytes type = 3;
+
+ // https://w3c.github.io/manifest/#purpose-member
+ enum Purpose {
+ ANY = 1;
+ BADGE = 2;
+ }
+
+ // blink::Manifest::ImageResource::Purpose enum.
+ repeated Purpose purpose = 4;
}
- // Example value:
- // icons: {
- // src: "icon/lowres.webp"
- // sizes: "48x48"
- // type: "image/webp"
- // }
- // icons: {
- // src: "icon/hd_hi.ico"
- // sizes: "72x72 96x96 128x128 256x256"
- // }
- repeated IconDefinition icons = 2;
+ repeated ImageResource icons = 2;
optional uint64 download_total = 3;
}
@@ -71,6 +76,10 @@ message BackgroundFetchMetadata {
// Number of fetches initiated by the developer.
optional int32 num_fetches = 5;
+
+ // Raw bytes needed to deserialize into a PNG icon. Only used if the icon
+ // has a max resolution of 256x256. This means this is at most ~256KB.
+ optional bytes icon = 6;
}
// A background fetch request that is still in a pending state.
@@ -103,4 +112,4 @@ message BackgroundFetchCompletedRequest {
optional string serialized_request = 3;
optional string download_guid = 4;
optional bool succeeded = 5;
-} \ No newline at end of file
+}
diff --git a/chromium/content/browser/background_fetch/background_fetch_context.cc b/chromium/content/browser/background_fetch/background_fetch_context.cc
index 0ddea261409..38bdb10727d 100644
--- a/chromium/content/browser/background_fetch/background_fetch_context.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_context.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/bind_helpers.h"
+#include "content/browser/background_fetch/background_fetch_data_manager.h"
#include "content/browser/background_fetch/background_fetch_job_controller.h"
#include "content/browser/background_fetch/background_fetch_metrics.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
@@ -22,21 +23,61 @@ namespace content {
BackgroundFetchContext::BackgroundFetchContext(
BrowserContext* browser_context,
- const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
+ const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context,
+ const scoped_refptr<content::CacheStorageContextImpl>&
+ cache_storage_context)
: browser_context_(browser_context),
- data_manager_(browser_context, service_worker_context),
+ service_worker_context_(service_worker_context),
event_dispatcher_(service_worker_context),
registration_notifier_(
std::make_unique<BackgroundFetchRegistrationNotifier>()),
delegate_proxy_(browser_context_->GetBackgroundFetchDelegate()),
- scheduler_(std::make_unique<BackgroundFetchScheduler>(&data_manager_)),
weak_factory_(this) {
// Although this lives only on the IO thread, it is constructed on UI thread.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(service_worker_context_);
+
+ data_manager_ = std::make_unique<BackgroundFetchDataManager>(
+ browser_context_, service_worker_context, cache_storage_context);
+ scheduler_ = std::make_unique<BackgroundFetchScheduler>(data_manager_.get());
+ delegate_proxy_.SetClickEventDispatcher(base::BindRepeating(
+ &BackgroundFetchContext::DispatchClickEvent, weak_factory_.GetWeakPtr()));
}
BackgroundFetchContext::~BackgroundFetchContext() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ service_worker_context_->RemoveObserver(this);
+ data_manager_->RemoveObserver(this);
+}
+
+void BackgroundFetchContext::InitializeOnIOThread() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ service_worker_context_->AddObserver(this);
+
+ data_manager_->AddObserver(this);
+ data_manager_->InitializeOnIOThread();
+ data_manager_->GetInitializationData(
+ base::BindOnce(&BackgroundFetchContext::DidGetInitializationData,
+ weak_factory_.GetWeakPtr()));
+}
+
+void BackgroundFetchContext::DidGetInitializationData(
+ blink::mojom::BackgroundFetchError error,
+ std::vector<background_fetch::BackgroundFetchInitializationData>
+ initialization_data) {
+ if (error != blink::mojom::BackgroundFetchError::NONE) {
+ // TODO(crbug.com/780025): Log failures to UMA.
+ return;
+ }
+
+ for (auto& data : initialization_data) {
+ CreateController(data.registration_id, data.options, data.icon,
+ data.ui_title, data.num_completed_requests,
+ data.num_requests, data.active_fetch_guids,
+ std::make_unique<BackgroundFetchRegistration>(
+ std::move(data.registration)));
+ }
}
void BackgroundFetchContext::GetRegistration(
@@ -46,7 +87,7 @@ void BackgroundFetchContext::GetRegistration(
blink::mojom::BackgroundFetchService::GetRegistrationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- data_manager_.GetRegistration(
+ data_manager_->GetRegistration(
service_worker_registration_id, origin, developer_id,
base::BindOnce(&BackgroundFetchContext::DidGetRegistration,
weak_factory_.GetWeakPtr(), std::move(callback)));
@@ -56,8 +97,8 @@ 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));
+ data_manager_->GetDeveloperIdsForServiceWorker(service_worker_registration_id,
+ origin, std::move(callback));
}
void BackgroundFetchContext::DidGetRegistration(
@@ -67,7 +108,8 @@ void BackgroundFetchContext::DidGetRegistration(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (error != blink::mojom::BackgroundFetchError::NONE) {
- std::move(callback).Run(error, base::nullopt);
+ std::move(callback).Run(error,
+ base::nullopt /* BackgroundFetchRegistration */);
return;
}
@@ -88,11 +130,18 @@ void BackgroundFetchContext::StartFetch(
blink::mojom::BackgroundFetchService::FetchCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- data_manager_.CreateRegistration(
+ // |registration_id| should be unique even if developer id has been
+ // duplicated, because the caller of this function generates a new unique_id
+ // every time, which is what BackgroundFetchRegistrationId's comparison
+ // operator uses.
+ DCHECK_EQ(0u, fetch_callbacks_.count(registration_id));
+ fetch_callbacks_[registration_id] = std::move(callback);
+
+ data_manager_->CreateRegistration(
registration_id, requests, options, icon,
base::BindOnce(&BackgroundFetchContext::DidCreateRegistration,
weak_factory_.GetWeakPtr(), registration_id, options, icon,
- requests.size(), std::move(callback)));
+ requests.size()));
}
void BackgroundFetchContext::GetIconDisplaySize(
@@ -107,33 +156,32 @@ void BackgroundFetchContext::DidCreateRegistration(
const BackgroundFetchOptions& options,
const SkBitmap& icon,
size_t num_requests,
- blink::mojom::BackgroundFetchService::FetchCallback callback,
blink::mojom::BackgroundFetchError error,
std::unique_ptr<BackgroundFetchRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
background_fetch::RecordRegistrationCreatedError(error);
if (error != blink::mojom::BackgroundFetchError::NONE) {
- std::move(callback).Run(error, base::nullopt);
+ DCHECK(fetch_callbacks_.count(registration_id));
+ std::move(fetch_callbacks_[registration_id])
+ .Run(error, base::nullopt /* BackgroundFetchRegistration */);
+ fetch_callbacks_.erase(registration_id);
return;
}
- DCHECK(registration);
+ if (hang_registration_creation_for_testing_) {
+ // Hang here, to allow time for testing races. For instance, this helps us
+ // test the behavior when a service worker gets unregistered before the
+ // controller can be created.
+ return;
+ }
- BackgroundFetchRegistration* registration_ptr = registration.get();
- // The closure takes ownership of |registration|, and it's guaranteed to
- // outlive CreateController, which uses the underlying pointer.
- base::OnceClosure done_closure = base::BindOnce(
- [](blink::mojom::BackgroundFetchService::FetchCallback callback,
- blink::mojom::BackgroundFetchError error,
- std::unique_ptr<BackgroundFetchRegistration> registration) {
- std::move(callback).Run(error, *registration);
- },
- std::move(callback), error, std::move(registration));
+ DCHECK(registration);
// Create the BackgroundFetchJobController to do the actual fetching.
- CreateController(registration_id, options, icon, num_requests,
- *registration_ptr, std::move(done_closure));
+ CreateController(registration_id, options, icon, options.title,
+ 0u /* num_completed_requests */, num_requests,
+ {} /* outstanding_guids */, std::move(registration));
}
void BackgroundFetchContext::AddRegistrationObserver(
@@ -155,43 +203,88 @@ void BackgroundFetchContext::UpdateUI(
return;
}
- data_manager_.UpdateRegistrationUI(
- registration_id, title,
- base::BindOnce(&BackgroundFetchContext::DidUpdateStoredUI,
- weak_factory_.GetWeakPtr(), registration_id.unique_id(),
- title, std::move(callback)));
+ data_manager_->UpdateRegistrationUI(registration_id, title,
+ std::move(callback));
}
-void BackgroundFetchContext::DidUpdateStoredUI(
- const std::string& unique_id,
- const std::string& title,
- blink::mojom::BackgroundFetchService::UpdateUICallback callback,
- blink::mojom::BackgroundFetchError error) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+void BackgroundFetchContext::OnServiceWorkerDatabaseCorrupted(
+ int64_t service_worker_registration_id) {
+ AbandonFetches(service_worker_registration_id);
+}
- // 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);
+void BackgroundFetchContext::AbandonFetches(
+ int64_t service_worker_registration_id) {
+ // Abandon all active fetches associated with this service worker.
+ // BackgroundFetchJobController::Abort() will eventually lead to deletion of
+ // the controller from job_controllers, hence we can't use a range based
+ // for-loop here.
+ for (auto iter = job_controllers_.begin(); iter != job_controllers_.end();
+ /* no_increment */) {
+ auto saved_iter = iter;
+ iter++;
+ if (service_worker_registration_id ==
+ blink::mojom::kInvalidServiceWorkerRegistrationId ||
+ saved_iter->second->registration_id()
+ .service_worker_registration_id() ==
+ service_worker_registration_id) {
+ DCHECK(saved_iter->second);
+ saved_iter->second->Abort(
+ BackgroundFetchReasonToAbort::SERVICE_WORKER_UNAVAILABLE);
+ }
}
- std::move(callback).Run(error);
+ for (auto iter = fetch_callbacks_.begin(); iter != fetch_callbacks_.end();
+ /* no increment */) {
+ if (service_worker_registration_id ==
+ blink::mojom::kInvalidServiceWorkerRegistrationId ||
+ iter->first.service_worker_registration_id() ==
+ service_worker_registration_id) {
+ DCHECK(iter->second);
+ std::move(iter->second)
+ .Run(blink::mojom::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE,
+ base::nullopt /* BackgroundFetchRegistration */);
+ iter = fetch_callbacks_.erase(iter);
+ } else
+ iter++;
+ }
+}
+
+void BackgroundFetchContext::OnUpdatedUI(
+ const BackgroundFetchRegistrationId& registration_id,
+ const std::string& title) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ auto iter = job_controllers_.find(registration_id.unique_id());
+ if (iter != job_controllers_.end())
+ iter->second->UpdateUI(title);
+}
+
+void BackgroundFetchContext::OnRegistrationDeleted(
+ int64_t service_worker_registration_id,
+ const GURL& pattern) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ AbandonFetches(service_worker_registration_id);
+}
+
+void BackgroundFetchContext::OnStorageWiped() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ AbandonFetches(blink::mojom::kInvalidServiceWorkerRegistrationId);
}
void BackgroundFetchContext::CreateController(
const BackgroundFetchRegistrationId& registration_id,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
+ const std::string& ui_title,
+ size_t num_completed_requests,
size_t num_requests,
- const BackgroundFetchRegistration& registration,
- base::OnceClosure done_closure) {
+ const std::vector<std::string>& outstanding_guids,
+ std::unique_ptr<BackgroundFetchRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
auto controller = std::make_unique<BackgroundFetchJobController>(
- &delegate_proxy_, registration_id, options, icon, registration,
- scheduler_.get(),
+ &delegate_proxy_, registration_id, options, icon,
+ registration->downloaded, scheduler_.get(),
// Safe because JobControllers are destroyed before RegistrationNotifier.
base::BindRepeating(&BackgroundFetchRegistrationNotifier::Notify,
base::Unretained(registration_notifier_.get())),
@@ -199,27 +292,17 @@ void BackgroundFetchContext::CreateController(
&BackgroundFetchContext::DidFinishJob, weak_factory_.GetWeakPtr(),
base::Bind(&background_fetch::RecordSchedulerFinishedError)));
- data_manager_.GetNumCompletedRequests(
- registration_id,
- base::BindOnce(&BackgroundFetchContext::InitializeController,
- weak_factory_.GetWeakPtr(), registration_id.unique_id(),
- std::move(controller), std::move(done_closure),
- num_requests));
-}
-
-void BackgroundFetchContext::InitializeController(
- const std::string& unique_id,
- std::unique_ptr<BackgroundFetchJobController> controller,
- base::OnceClosure done_closure,
- size_t total_downloads,
- size_t completed_downloads) {
- controller->InitializeRequestStatus(completed_downloads, total_downloads,
- {} /* outstanding download GUIDs */);
-
+ controller->InitializeRequestStatus(num_completed_requests, num_requests,
+ outstanding_guids, ui_title);
scheduler_->AddJobController(controller.get());
+ job_controllers_.emplace(registration_id.unique_id(), std::move(controller));
- job_controllers_.insert({unique_id, std::move(controller)});
- std::move(done_closure).Run();
+ auto fetch_callback_iter = fetch_callbacks_.find(registration_id);
+ if (fetch_callback_iter != fetch_callbacks_.end()) {
+ std::move(fetch_callback_iter->second)
+ .Run(blink::mojom::BackgroundFetchError::NONE, *registration);
+ fetch_callbacks_.erase(fetch_callback_iter);
+ }
}
void BackgroundFetchContext::Abort(
@@ -239,7 +322,7 @@ void BackgroundFetchContext::DidFinishJob(
// 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(
+ data_manager_->MarkRegistrationForDeletion(
registration_id,
base::BindOnce(&BackgroundFetchContext::DidMarkForDeletion,
weak_factory_.GetWeakPtr(), registration_id,
@@ -251,6 +334,7 @@ void BackgroundFetchContext::DidMarkForDeletion(
BackgroundFetchReasonToAbort reason_to_abort,
base::OnceCallback<void(blink::mojom::BackgroundFetchError)> callback,
blink::mojom::BackgroundFetchError error) {
+ DCHECK(callback);
std::move(callback).Run(error);
// It's normal to get INVALID_ID errors here - it means the registration was
@@ -268,15 +352,17 @@ void BackgroundFetchContext::DidMarkForDeletion(
switch (reason_to_abort) {
case BackgroundFetchReasonToAbort::ABORTED_BY_DEVELOPER:
case BackgroundFetchReasonToAbort::CANCELLED_FROM_UI:
- CleanupRegistration(registration_id, {});
+ CleanupRegistration(registration_id, {},
+ mojom::BackgroundFetchState::FAILED);
// TODO(rayankans): Send fetches to the event dispatcher.
event_dispatcher_.DispatchBackgroundFetchAbortEvent(
registration_id, {} /* settled_fetches */, base::DoNothing());
return;
case BackgroundFetchReasonToAbort::TOTAL_DOWNLOAD_SIZE_EXCEEDED:
+ case BackgroundFetchReasonToAbort::SERVICE_WORKER_UNAVAILABLE:
case BackgroundFetchReasonToAbort::NONE:
// This will send a BackgroundFetchFetched or BackgroundFetchFail event.
- data_manager_.GetSettledFetchesForRegistration(
+ data_manager_->GetSettledFetchesForRegistration(
registration_id,
base::BindOnce(&BackgroundFetchContext::DidGetSettledFetches,
weak_factory_.GetWeakPtr(), registration_id));
@@ -293,7 +379,9 @@ void BackgroundFetchContext::DidGetSettledFetches(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (error != blink::mojom::BackgroundFetchError::NONE) {
- CleanupRegistration(registration_id, {} /* fetches */);
+ CleanupRegistration(registration_id, {} /* fetches */,
+ mojom::BackgroundFetchState::FAILED,
+ true /* preserve_info_to_dispatch_click_event */);
return;
}
@@ -309,7 +397,9 @@ void BackgroundFetchContext::DidGetSettledFetches(
// 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)));
+ std::move(blob_data_handles),
+ mojom::BackgroundFetchState::SUCCEEDED,
+ true /* preserve_info_to_dispatch_click_event */));
} else {
event_dispatcher_.DispatchBackgroundFetchFailEvent(
registration_id, std::move(settled_fetches),
@@ -319,19 +409,28 @@ void BackgroundFetchContext::DidGetSettledFetches(
// 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)));
+ std::move(blob_data_handles), mojom::BackgroundFetchState::FAILED,
+ true /* preserve_info_to_dispatch_click_event */));
}
}
void BackgroundFetchContext::CleanupRegistration(
const BackgroundFetchRegistrationId& registration_id,
- const std::vector<std::unique_ptr<storage::BlobDataHandle>>& blob_handles) {
+ const std::vector<std::unique_ptr<storage::BlobDataHandle>>& blob_handles,
+ mojom::BackgroundFetchState background_fetch_state,
+ bool preserve_info_to_dispatch_click_event) {
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.
+ // event has been resolved. Store the information we want to persist after
+ // the controller is gone, in completed_fetches_.
+ scheduler_->RemoveJobController(registration_id);
+ if (preserve_info_to_dispatch_click_event) {
+ completed_fetches_[registration_id.unique_id()] = {registration_id,
+ background_fetch_state};
+ }
job_controllers_.erase(registration_id.unique_id());
// At this point, JavaScript can no longer obtain BackgroundFetchRegistration
@@ -348,13 +447,54 @@ void BackgroundFetchContext::CleanupRegistration(
weak_factory_.GetWeakPtr(), registration_id));
}
+void BackgroundFetchContext::DispatchClickEvent(const std::string& unique_id) {
+ auto iter = completed_fetches_.find(unique_id);
+ if (iter != completed_fetches_.end()) {
+ // The fetch has succeeded or failed. (not aborted/cancelled).
+ event_dispatcher_.DispatchBackgroundFetchClickEvent(
+ iter->second.first /* registration_id */,
+ iter->second.second /* background_fetch_state */, base::DoNothing());
+ completed_fetches_.erase(iter);
+ return;
+ }
+
+ // The fetch is active, or has been aborted/cancelled.
+ auto controllers_iter = job_controllers_.find(unique_id);
+ if (controllers_iter == job_controllers_.end())
+ return;
+ event_dispatcher_.DispatchBackgroundFetchClickEvent(
+ controllers_iter->second->registration_id(),
+ mojom::BackgroundFetchState::PENDING, base::DoNothing());
+}
+
void BackgroundFetchContext::LastObserverGarbageCollected(
const BackgroundFetchRegistrationId& registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- data_manager_.DeleteRegistration(
+ data_manager_->DeleteRegistration(
registration_id,
base::BindOnce(&background_fetch::RecordRegistrationDeletedError));
}
+void BackgroundFetchContext::Shutdown() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&BackgroundFetchContext::ShutdownOnIO, this));
+}
+
+void BackgroundFetchContext::ShutdownOnIO() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ data_manager_->ShutdownOnIO();
+}
+
+void BackgroundFetchContext::SetDataManagerForTesting(
+ std::unique_ptr<BackgroundFetchDataManager> data_manager) {
+ DCHECK(data_manager);
+ data_manager_ = std::move(data_manager);
+ scheduler_ = std::make_unique<BackgroundFetchScheduler>(data_manager_.get());
+}
+
} // 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 fe0892dd021..a6b05e1267a 100644
--- a/chromium/content/browser/background_fetch/background_fetch_context.h
+++ b/chromium/content/browser/background_fetch/background_fetch_context.h
@@ -13,9 +13,11 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "content/browser/background_fetch/background_fetch_data_manager.h"
+#include "content/browser/background_fetch/background_fetch_data_manager_observer.h"
#include "content/browser/background_fetch/background_fetch_delegate_proxy.h"
#include "content/browser/background_fetch/background_fetch_event_dispatcher.h"
+#include "content/browser/background_fetch/storage/get_initialization_data_task.h"
+#include "content/browser/service_worker/service_worker_context_core_observer.h"
#include "content/common/content_export.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
@@ -27,11 +29,13 @@ class BlobDataHandle;
namespace content {
class BackgroundFetchJobController;
+class BackgroundFetchDataManager;
struct BackgroundFetchOptions;
class BackgroundFetchRegistrationId;
class BackgroundFetchRegistrationNotifier;
class BackgroundFetchScheduler;
class BrowserContext;
+class CacheStorageContextImpl;
class ServiceWorkerContextWrapper;
struct ServiceWorkerFetchRequest;
@@ -40,14 +44,23 @@ struct ServiceWorkerFetchRequest;
// Background Fetch requests function similarly to normal fetches except that
// they are persistent across Chromium or service worker shutdown.
class CONTENT_EXPORT BackgroundFetchContext
- : public base::RefCountedThreadSafe<BackgroundFetchContext,
+ : public BackgroundFetchDataManagerObserver,
+ public ServiceWorkerContextCoreObserver,
+ public base::RefCountedThreadSafe<BackgroundFetchContext,
BrowserThread::DeleteOnIOThread> {
public:
// The BackgroundFetchContext will watch the ServiceWorkerContextWrapper so
// that it can respond to service worker events such as unregister.
BackgroundFetchContext(
BrowserContext* browser_context,
- const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context);
+ const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context,
+ const scoped_refptr<content::CacheStorageContextImpl>&
+ cache_storage_context);
+
+ void InitializeOnIOThread();
+
+ // Called by the StoragePartitionImpl destructor.
+ void Shutdown();
// Gets the active Background Fetch registration identified by |developer_id|
// for the given |service_worker_id| and |origin|. The |callback| will be
@@ -100,30 +113,40 @@ class CONTENT_EXPORT BackgroundFetchContext
const std::string& title,
blink::mojom::BackgroundFetchService::UpdateUICallback callback);
+ // BackgroundFetchDataManagerObserver implementation.
+ void OnUpdatedUI(const BackgroundFetchRegistrationId& registration_id,
+ const std::string& title) override;
+ void OnServiceWorkerDatabaseCorrupted(
+ int64_t service_worker_registration_id) override;
+
+ // ServiceWorkerContextCoreObserver implementation.
+ void OnRegistrationDeleted(int64_t registration_id,
+ const GURL& pattern) override;
+ void OnStorageWiped() override;
+
private:
+ friend class BackgroundFetchServiceTest;
+ friend class BackgroundFetchJobControllerTest;
friend class base::DeleteHelper<BackgroundFetchContext>;
- friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
friend class base::RefCountedThreadSafe<BackgroundFetchContext,
BrowserThread::DeleteOnIOThread>;
+ friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
- ~BackgroundFetchContext();
+ ~BackgroundFetchContext() override;
+
+ void ShutdownOnIO();
// Creates a new Job Controller for the given |registration_id| and |options|,
// which will start fetching the files that are part of the registration.
- void CreateController(const BackgroundFetchRegistrationId& registration_id,
- const BackgroundFetchOptions& options,
- const SkBitmap& icon,
- size_t num_requests,
- const BackgroundFetchRegistration& registration,
- base::OnceClosure done_closure);
-
- // Initializes the new Job Controller.
- void InitializeController(
- const std::string& unique_id,
- std::unique_ptr<BackgroundFetchJobController> controller,
- base::OnceClosure done_closure,
- size_t total_downloads,
- size_t completed_downloads);
+ void CreateController(
+ const BackgroundFetchRegistrationId& registration_id,
+ const BackgroundFetchOptions& options,
+ const SkBitmap& icon,
+ const std::string& ui_title,
+ size_t num_completed_requests,
+ size_t num_requests,
+ const std::vector<std::string>& outstanding_guids,
+ std::unique_ptr<BackgroundFetchRegistration> registration);
// Called when an existing registration has been retrieved from the data
// manager. If the registration does not exist then |registration| is nullptr.
@@ -138,17 +161,9 @@ class CONTENT_EXPORT BackgroundFetchContext
const BackgroundFetchOptions& options,
const SkBitmap& icon,
size_t num_requests,
- blink::mojom::BackgroundFetchService::FetchCallback callback,
blink::mojom::BackgroundFetchError error,
std::unique_ptr<BackgroundFetchRegistration> registration);
- // 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(
@@ -172,13 +187,29 @@ class CONTENT_EXPORT BackgroundFetchContext
std::vector<BackgroundFetchSettledFetch> settled_fetches,
std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles);
+ // Called when the notification UI for the background fetch job associated
+ // with |unique_id| is activated.
+ void DispatchClickEvent(const std::string& unique_id);
+
+ // Called when the data manager finishes getting the initialization data.
+ void DidGetInitializationData(
+ blink::mojom::BackgroundFetchError error,
+ std::vector<background_fetch::BackgroundFetchInitializationData>
+ initialization_data);
+
// Called when all processing for the |registration_id| has been finished and
// the job is ready to be deleted. |blob_handles| are unused, but some callers
// use it to keep blobs alive for the right duration.
+ // |partial cleanup|, when set, preserves the registration ID, and the state
+ // of Fetch when it completed, in |completed_fetches_|. This is not done when
+ // fetch is aborted or cancelled. We use this information to propagate
+ // BackgroundFetchClicked event to the developer, when the user taps the UI.
void CleanupRegistration(
const BackgroundFetchRegistrationId& registration_id,
const std::vector<std::unique_ptr<storage::BlobDataHandle>>&
- blob_data_handles);
+ blob_data_handles,
+ mojom::BackgroundFetchState background_fetch_state,
+ bool preserve_info_to_dispatch_click_event = false);
// Called when the last JavaScript BackgroundFetchRegistration object has been
// garbage collected for a registration marked for deletion, and so it is now
@@ -186,10 +217,21 @@ class CONTENT_EXPORT BackgroundFetchContext
void LastObserverGarbageCollected(
const BackgroundFetchRegistrationId& registration_id);
+ // Switches out |data_manager_| with a DataManager configured for testing
+ // environments. Must be called directly after the constructor.
+ void SetDataManagerForTesting(
+ std::unique_ptr<BackgroundFetchDataManager> data_manager);
+
+ // Helper method to abandon ongoing fetches for a given service worker.
+ // Abandons all of them if |service_worker_registration_id| is set to
+ // blink::mojom::kInvalidServiceWorkerRegistrationId.
+ void AbandonFetches(int64_t service_worker_registration_id);
+
// |this| is owned, indirectly, by the BrowserContext.
BrowserContext* browser_context_;
- BackgroundFetchDataManager data_manager_;
+ std::unique_ptr<BackgroundFetchDataManager> data_manager_;
+ scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
BackgroundFetchEventDispatcher event_dispatcher_;
std::unique_ptr<BackgroundFetchRegistrationNotifier> registration_notifier_;
BackgroundFetchDelegateProxy delegate_proxy_;
@@ -201,6 +243,28 @@ class CONTENT_EXPORT BackgroundFetchContext
std::map<std::string, std::unique_ptr<BackgroundFetchJobController>>
job_controllers_;
+ // Map from background fetch registration |unique_ids|s to {background fetch
+ // registration id, fetch state}. An entry in here means the fetch has
+ // completed. This information is needed after the fetch has completed.
+ // TODO(crbug.com/857122): Clean this up when the UI is no longer showing.
+ std::map<
+ std::string,
+ std::pair<BackgroundFetchRegistrationId, mojom::BackgroundFetchState>>
+ completed_fetches_;
+
+ // Map from BackgroundFetchRegistrationIds to FetchCallbacks for active
+ // fetches. Must be destroyed before |data_manager_| and
+ // |registration_notifier_|. Since FetchCallback is a OnceCallback, please
+ // erase the map entry once the calback has been invoked.
+ std::map<BackgroundFetchRegistrationId,
+ blink::mojom::BackgroundFetchService::FetchCallback>
+ fetch_callbacks_;
+
+ // This is used to hang the fetch logic for testing. For instance, this helps
+ // us test the behavior when a service worker gets unregistered before the
+ // controller has been created.
+ bool hang_registration_creation_for_testing_ = false;
+
base::WeakPtrFactory<BackgroundFetchContext> weak_factory_; // Must be last.
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchContext);
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 a8cb4f6d5fc..c326cdc1da3 100644
--- a/chromium/content/browser/background_fetch/background_fetch_data_manager.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_data_manager.cc
@@ -8,10 +8,9 @@
#include "base/command_line.h"
#include "base/containers/queue.h"
-#include "base/guid.h"
#include "base/time/time.h"
#include "content/browser/background_fetch/background_fetch_constants.h"
-#include "content/browser/background_fetch/background_fetch_cross_origin_filter.h"
+#include "content/browser/background_fetch/background_fetch_data_manager_observer.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_metadata_task.h"
@@ -19,34 +18,22 @@
#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_metadata_task.h"
-#include "content/browser/background_fetch/storage/get_num_requests_task.h"
#include "content/browser/background_fetch/storage/get_settled_fetches_task.h"
#include "content/browser/background_fetch/storage/mark_registration_for_deletion_task.h"
#include "content/browser/background_fetch/storage/mark_request_complete_task.h"
#include "content/browser/background_fetch/storage/start_next_pending_request_task.h"
#include "content/browser/background_fetch/storage/update_registration_ui_task.h"
-#include "content/browser/blob_storage/chrome_blob_storage_context.h"
+#include "content/browser/cache_storage/cache_storage_manager.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_features.h"
-#include "content/public/common/content_switches.h"
-#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/blink/public/mojom/blob/blob.mojom.h"
namespace content {
namespace {
-// 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.
-bool IsOK(const BackgroundFetchRequestInfo& request) {
- int status = request.GetResponseCode();
- return status >= 200 && status < 300;
-}
-
// Helper function to convert a BackgroundFetchRegistration proto into a
// BackgroundFetchRegistration struct, and call the appropriate callback.
void GetRegistrationFromMetadata(
@@ -73,106 +60,12 @@ void GetRegistrationFromMetadata(
} // 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 BackgroundFetchRegistrationId& registration_id,
- const std::vector<ServiceWorkerFetchRequest>& requests,
- const BackgroundFetchOptions& options,
- const SkBitmap& icon)
- : registration_id_(registration_id), options_(options), icon_(icon) {
- int request_index = 0;
-
- // Convert the given |requests| to BackgroundFetchRequestInfo objects.
- for (const ServiceWorkerFetchRequest& fetch_request : requests) {
- pending_requests_.push(base::MakeRefCounted<BackgroundFetchRequestInfo>(
- request_index++, fetch_request));
- }
- }
-
- ~RegistrationData() = default;
-
- // Returns whether there are remaining requests on the request queue.
- bool HasPendingRequests() const { return !pending_requests_.empty(); }
-
- // Consumes a request from the queue that is to be fetched.
- scoped_refptr<BackgroundFetchRequestInfo> PopNextPendingRequest() {
- DCHECK(!pending_requests_.empty());
-
- auto request = pending_requests_.front();
- pending_requests_.pop();
-
- request->InitializeDownloadGuid();
-
- // The |request| is considered to be active now.
- active_requests_.push_back(request);
-
- return request;
- }
-
- // Marks the |request| as having completed. Verifies that the |request| is
- // currently active and moves it to the |completed_requests_| vector.
- void MarkRequestAsComplete(BackgroundFetchRequestInfo* request) {
- const auto iter = std::find_if(
- active_requests_.begin(), active_requests_.end(),
- [&request](scoped_refptr<BackgroundFetchRequestInfo> active_request) {
- return active_request->request_index() == request->request_index();
- });
-
- // The |request| must have been consumed from this RegistrationData.
- DCHECK(iter != active_requests_.end());
-
- completed_requests_.push_back(*iter);
- active_requests_.erase(iter);
-
- complete_requests_downloaded_bytes_ += request->GetFileSize();
- }
-
- // Returns the vector with all completed requests part of this registration.
- const std::vector<scoped_refptr<BackgroundFetchRequestInfo>>&
- GetCompletedRequests() const {
- return completed_requests_;
- }
-
- 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() const { return complete_requests_downloaded_bytes_; }
-
- size_t GetNumCompletedRequests() const { return completed_requests_.size(); }
-
- private:
- BackgroundFetchRegistrationId registration_id_;
- BackgroundFetchOptions options_;
- SkBitmap icon_;
- // 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_;
- std::vector<scoped_refptr<BackgroundFetchRequestInfo>> active_requests_;
-
- // TODO(peter): Right now it's safe for this to be a vector because we only
- // allow a single parallel request. That stops when we start allowing more.
- static_assert(kMaximumBackgroundFetchParallelRequests == 1,
- "RegistrationData::completed_requests_ assumes no parallelism");
-
- std::vector<scoped_refptr<BackgroundFetchRequestInfo>> completed_requests_;
-
- DISALLOW_COPY_AND_ASSIGN(RegistrationData);
-};
-
BackgroundFetchDataManager::BackgroundFetchDataManager(
BrowserContext* browser_context,
- scoped_refptr<ServiceWorkerContextWrapper> service_worker_context)
+ scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
+ scoped_refptr<CacheStorageContextImpl> cache_storage_context)
: service_worker_context_(std::move(service_worker_context)),
+ cache_storage_context_(std::move(cache_storage_context)),
weak_ptr_factory_(this) {
// Constructed on the UI thread, then used on the IO thread.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -182,26 +75,48 @@ BackgroundFetchDataManager::BackgroundFetchDataManager(
blob_storage_context_ =
base::WrapRefCounted(ChromeBlobStorageContext::GetFor(browser_context));
DCHECK(blob_storage_context_);
+}
+
+void BackgroundFetchDataManager::InitializeOnIOThread() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // The CacheStorageManager can only be accessed from the IO thread.
+ cache_manager_ =
+ base::WrapRefCounted(cache_storage_context_->cache_manager());
+
+ // TODO(crbug.com/855199): Persist which registrations to cleanup on startup.
+ Cleanup();
+
+ DCHECK(cache_manager_);
+}
- 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::BindOnce(&BackgroundFetchDataManager::Cleanup,
- weak_ptr_factory_.GetWeakPtr()));
+void BackgroundFetchDataManager::AddObserver(
+ BackgroundFetchDataManagerObserver* observer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ observers_.AddObserver(observer);
+}
+
+void BackgroundFetchDataManager::RemoveObserver(
+ BackgroundFetchDataManagerObserver* observer) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ observers_.RemoveObserver(observer);
}
void BackgroundFetchDataManager::Cleanup() {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBackgroundFetchPersistence)) {
- AddDatabaseTask(std::make_unique<background_fetch::CleanupTask>(this));
- }
+ AddDatabaseTask(std::make_unique<background_fetch::CleanupTask>(this));
}
BackgroundFetchDataManager::~BackgroundFetchDataManager() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
+void BackgroundFetchDataManager::GetInitializationData(
+ GetInitializationDataCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ AddDatabaseTask(std::make_unique<background_fetch::GetInitializationDataTask>(
+ this, std::move(callback)));
+}
+
void BackgroundFetchDataManager::CreateRegistration(
const BackgroundFetchRegistrationId& registration_id,
const std::vector<ServiceWorkerFetchRequest>& requests,
@@ -210,47 +125,11 @@ void BackgroundFetchDataManager::CreateRegistration(
GetRegistrationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBackgroundFetchPersistence)) {
- auto registration_callback =
- base::BindOnce(&GetRegistrationFromMetadata, std::move(callback));
- AddDatabaseTask(std::make_unique<background_fetch::CreateMetadataTask>(
- this, registration_id, requests, options,
- std::move(registration_callback)));
- return;
- }
-
- // New registrations should never re-use a |unique_id|.
- DCHECK_EQ(0u, registrations_.count(registration_id.unique_id()));
-
- auto developer_id_tuple =
- std::make_tuple(registration_id.service_worker_registration_id(),
- registration_id.origin(), registration_id.developer_id());
-
- if (active_registration_unique_ids_.count(developer_id_tuple)) {
- std::move(callback).Run(
- blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID, nullptr);
- return;
- }
-
- // Mark |unique_id| as the currently active registration for
- // |developer_id_tuple|.
- 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>(
- registration_id, requests, options, icon));
-
- // Re-use GetRegistration to compile the BackgroundFetchRegistration object.
- // WARNING: GetRegistration doesn't use the |unique_id| when looking up the
- // registration data. That's fine here, since we are calling it synchronously
- // immediately after writing the |unique_id| to |active_unique_ids_|. But if
- // GetRegistation becomes async, it will no longer be safe to do this.
- GetRegistration(registration_id.service_worker_registration_id(),
- registration_id.origin(), registration_id.developer_id(),
- std::move(callback));
+ auto registration_callback =
+ base::BindOnce(&GetRegistrationFromMetadata, std::move(callback));
+ AddDatabaseTask(std::make_unique<background_fetch::CreateMetadataTask>(
+ this, registration_id, requests, options, icon,
+ std::move(registration_callback)));
}
void BackgroundFetchDataManager::GetMetadata(
@@ -259,10 +138,7 @@ void BackgroundFetchDataManager::GetMetadata(
const std::string& developer_id,
GetMetadataCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBackgroundFetchPersistence)) {
- return;
- }
+
AddDatabaseTask(std::make_unique<background_fetch::GetMetadataTask>(
this, service_worker_registration_id, origin, developer_id,
std::move(callback)));
@@ -275,42 +151,10 @@ void BackgroundFetchDataManager::GetRegistration(
GetRegistrationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBackgroundFetchPersistence)) {
- auto registration_callback =
- base::BindOnce(&GetRegistrationFromMetadata, std::move(callback));
- GetMetadata(service_worker_registration_id, origin, developer_id,
- std::move(registration_callback));
- return;
- }
-
- auto developer_id_tuple =
- std::make_tuple(service_worker_registration_id, origin, developer_id);
-
- 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,
- nullptr /* registration */);
- return;
- }
-
- const std::string& unique_id = iter->second;
-
- DCHECK_EQ(1u, registrations_.count(unique_id));
- RegistrationData* data = registrations_[unique_id].get();
-
- // Compile the BackgroundFetchRegistration object for the developer.
- 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();
-
- std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE,
- std::move(registration));
+ auto registration_callback =
+ base::BindOnce(&GetRegistrationFromMetadata, std::move(callback));
+ GetMetadata(service_worker_registration_id, origin, developer_id,
+ std::move(registration_callback));
}
void BackgroundFetchDataManager::UpdateRegistrationUI(
@@ -319,24 +163,8 @@ void BackgroundFetchDataManager::UpdateRegistrationUI(
blink::mojom::BackgroundFetchService::UpdateUICallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBackgroundFetchPersistence)) {
- AddDatabaseTask(
- std::make_unique<background_fetch::UpdateRegistrationUITask>(
- this, registration_id, title, std::move(callback)));
- return;
- }
-
- auto registrations_iter = registrations_.find(registration_id.unique_id());
- if (registrations_iter == registrations_.end()) { // Not found.
- std::move(callback).Run(blink::mojom::BackgroundFetchError::INVALID_ID);
- return;
- }
-
- // Update stored registration.
- registrations_iter->second->SetTitle(title);
-
- std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE);
+ AddDatabaseTask(std::make_unique<background_fetch::UpdateRegistrationUITask>(
+ this, registration_id, title, std::move(callback)));
}
void BackgroundFetchDataManager::PopNextRequest(
@@ -344,38 +172,15 @@ void BackgroundFetchDataManager::PopNextRequest(
NextRequestCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBackgroundFetchPersistence)) {
- auto start_next_request = base::BindOnce(
- &BackgroundFetchDataManager::AddStartNextPendingRequestTask,
- weak_ptr_factory_.GetWeakPtr(),
- registration_id.service_worker_registration_id(), std::move(callback));
-
- // Get the associated metadata, and add a StartNextPendingRequestTask.
- GetMetadata(registration_id.service_worker_registration_id(),
- registration_id.origin(), registration_id.developer_id(),
- std::move(start_next_request));
-
- return;
- }
-
- if (!IsActive(registration_id)) {
- // Stop giving out requests as registration was aborted (or otherwise
- // finished).
- std::move(callback).Run(nullptr /* request */);
- return;
- }
-
- 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())
- next_request = registration_data->PopNextPendingRequest();
+ auto start_next_request = base::BindOnce(
+ &BackgroundFetchDataManager::AddStartNextPendingRequestTask,
+ weak_ptr_factory_.GetWeakPtr(),
+ registration_id.service_worker_registration_id(), std::move(callback));
- std::move(callback).Run(std::move(next_request));
+ // Get the associated metadata, and add a StartNextPendingRequestTask.
+ GetMetadata(registration_id.service_worker_registration_id(),
+ registration_id.origin(), registration_id.developer_id(),
+ std::move(start_next_request));
}
void BackgroundFetchDataManager::AddStartNextPendingRequestTask(
@@ -402,20 +207,8 @@ void BackgroundFetchDataManager::MarkRequestAsComplete(
BackgroundFetchScheduler::MarkedCompleteCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBackgroundFetchPersistence)) {
- AddDatabaseTask(std::make_unique<background_fetch::MarkRequestCompleteTask>(
- this, registration_id, request, std::move(callback)));
- return;
- }
-
- auto iter = registrations_.find(registration_id.unique_id());
- DCHECK(iter != registrations_.end());
-
- RegistrationData* registration_data = iter->second.get();
- registration_data->MarkRequestAsComplete(request);
-
- std::move(callback).Run();
+ AddDatabaseTask(std::make_unique<background_fetch::MarkRequestCompleteTask>(
+ this, registration_id, request, std::move(callback)));
}
void BackgroundFetchDataManager::GetSettledFetchesForRegistration(
@@ -423,103 +216,8 @@ void BackgroundFetchDataManager::GetSettledFetchesForRegistration(
SettledFetchesCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBackgroundFetchPersistence)) {
- AddDatabaseTask(std::make_unique<background_fetch::GetSettledFetchesTask>(
- this, registration_id, std::move(callback)));
- return;
- }
-
- auto iter = registrations_.find(registration_id.unique_id());
- DCHECK(iter != registrations_.end());
-
- RegistrationData* registration_data = iter->second.get();
- DCHECK(!registration_data->HasPendingRequests());
-
- const std::vector<scoped_refptr<BackgroundFetchRequestInfo>>& requests =
- registration_data->GetCompletedRequests();
-
- bool background_fetch_succeeded = true;
-
- std::vector<BackgroundFetchSettledFetch> settled_fetches;
- settled_fetches.reserve(requests.size());
-
- std::vector<std::unique_ptr<storage::BlobDataHandle>> blob_data_handles;
-
- for (const auto& request : requests) {
- BackgroundFetchSettledFetch settled_fetch;
- settled_fetch.request = request->fetch_request();
-
- // The |filter| decides which values can be passed on to the Service Worker.
- BackgroundFetchCrossOriginFilter filter(registration_id.origin(), *request);
-
- background_fetch_succeeded =
- FillServiceWorkerResponse(*request, registration_id.origin(),
- &settled_fetch.response) &&
- background_fetch_succeeded;
-
- settled_fetches.push_back(settled_fetch);
- }
-
- std::move(callback).Run(
- blink::mojom::BackgroundFetchError::NONE, background_fetch_succeeded,
- std::move(settled_fetches), std::move(blob_data_handles));
-}
-
-bool BackgroundFetchDataManager::FillServiceWorkerResponse(
- const BackgroundFetchRequestInfo& request,
- const url::Origin& origin,
- ServiceWorkerResponse* response) {
- DCHECK(response);
-
- response->url_list = request.GetURLChain();
- response->response_type = network::mojom::FetchResponseType::kDefault;
- // TODO(crbug.com/838837): settled_fetch.response.error
- response->response_time = request.GetResponseTime();
- // TODO(crbug.com/838837): settled_fetch.response.cors_exposed_header_names
-
- BackgroundFetchCrossOriginFilter filter(origin, request);
- if (!filter.CanPopulateBody()) {
- // TODO(crbug.com/711354): Consider Background Fetches as failed when the
- // response cannot be relayed to the developer.
- return false;
- }
-
- // Include the status code, status text and the response's body as a blob
- // when this is allowed by the CORS protocol.
- response->status_code = request.GetResponseCode();
- response->status_text = request.GetResponseText();
- response->headers.insert(request.GetResponseHeaders().begin(),
- request.GetResponseHeaders().end());
-
- if (request.GetFileSize() > 0) {
- DCHECK(!request.GetFilePath().empty());
- DCHECK(blob_storage_context_);
-
- auto blob_builder =
- std::make_unique<storage::BlobDataBuilder>(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(std::move(blob_builder));
-
- // TODO(peter): Appropriately handle !blob_data_handle
- if (blob_data_handle) {
- response->blob_uuid = blob_data_handle->uuid();
- response->blob_size = blob_data_handle->size();
- blink::mojom::BlobPtr blob_ptr;
- storage::BlobImpl::Create(
- std::make_unique<storage::BlobDataHandle>(*blob_data_handle),
- MakeRequest(&blob_ptr));
-
- response->blob =
- base::MakeRefCounted<storage::BlobHandle>(std::move(blob_ptr));
- }
- }
-
- return IsOK(request);
+ AddDatabaseTask(std::make_unique<background_fetch::GetSettledFetchesTask>(
+ this, registration_id, std::move(callback)));
}
void BackgroundFetchDataManager::MarkRegistrationForDeletion(
@@ -527,33 +225,9 @@ void BackgroundFetchDataManager::MarkRegistrationForDeletion(
HandleBackgroundFetchErrorCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBackgroundFetchPersistence)) {
- AddDatabaseTask(
- std::make_unique<background_fetch::MarkRegistrationForDeletionTask>(
- this, registration_id, std::move(callback)));
- return;
- }
-
- 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).
- 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;
- }
-
- active_registration_unique_ids_.erase(active_unique_id_iter);
-
- std::move(callback).Run(blink::mojom::BackgroundFetchError::NONE);
+ AddDatabaseTask(
+ std::make_unique<background_fetch::MarkRegistrationForDeletionTask>(
+ this, registration_id, std::move(callback)));
}
void BackgroundFetchDataManager::DeleteRegistration(
@@ -561,20 +235,10 @@ void BackgroundFetchDataManager::DeleteRegistration(
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);
+ AddDatabaseTask(std::make_unique<background_fetch::DeleteRegistrationTask>(
+ this, registration_id.service_worker_registration_id(),
+ registration_id.origin(), registration_id.unique_id(),
+ std::move(callback)));
}
void BackgroundFetchDataManager::GetDeveloperIdsForServiceWorker(
@@ -583,66 +247,32 @@ void BackgroundFetchDataManager::GetDeveloperIdsForServiceWorker(
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_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);
+ AddDatabaseTask(std::make_unique<background_fetch::GetDeveloperIdsTask>(
+ this, service_worker_registration_id, origin, std::move(callback)));
}
-void BackgroundFetchDataManager::GetNumCompletedRequests(
- const BackgroundFetchRegistrationId& registration_id,
- NumRequestsCallback callback) {
+void BackgroundFetchDataManager::ShutdownOnIO() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableBackgroundFetchPersistence)) {
- AddDatabaseTask(std::make_unique<background_fetch::GetNumRequestsTask>(
- this, registration_id, background_fetch::RequestType::kCompleted,
- std::move(callback)));
- return;
- }
+ // Release reference to CacheStorageManager. DatabaseTasks that need it
+ // hold their own copy, so they can continue their work.
+ cache_manager_ = nullptr;
- std::move(callback).Run(registrations_.find(registration_id.unique_id())
- ->second->GetNumCompletedRequests());
-}
-
-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();
+ shutting_down_ = true;
}
void BackgroundFetchDataManager::AddDatabaseTask(
std::unique_ptr<background_fetch::DatabaseTask> task) {
+ // If Shutdown was called don't add any new tasks.
+ if (shutting_down_)
+ return;
+
database_tasks_.push(std::move(task));
if (database_tasks_.size() == 1)
database_tasks_.front()->Start();
}
-void BackgroundFetchDataManager::OnDatabaseTaskFinished(
+void BackgroundFetchDataManager::OnTaskFinished(
background_fetch::DatabaseTask* task) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -654,4 +284,8 @@ void BackgroundFetchDataManager::OnDatabaseTaskFinished(
database_tasks_.front()->Start();
}
+BackgroundFetchDataManager* BackgroundFetchDataManager::data_manager() {
+ return this;
+}
+
} // 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 6b70bbf5715..56119296c98 100644
--- a/chromium/content/browser/background_fetch/background_fetch_data_manager.h
+++ b/chromium/content/browser/background_fetch/background_fetch_data_manager.h
@@ -16,10 +16,14 @@
#include "base/containers/queue.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/observer_list.h"
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/browser/background_fetch/background_fetch_scheduler.h"
#include "content/browser/background_fetch/storage/database_task.h"
+#include "content/browser/background_fetch/storage/get_initialization_data_task.h"
+#include "content/browser/cache_storage/cache_storage_context_impl.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
#include "url/origin.h"
@@ -30,9 +34,11 @@ class BlobDataHandle;
namespace content {
+class BackgroundFetchDataManagerObserver;
class BackgroundFetchRequestInfo;
struct BackgroundFetchSettledFetch;
class BrowserContext;
+class CacheStorageManager;
class ChromeBlobStorageContext;
class ServiceWorkerContextWrapper;
@@ -48,8 +54,12 @@ class ServiceWorkerContextWrapper;
//
// Storage schema is documented in storage/README.md
class CONTENT_EXPORT BackgroundFetchDataManager
- : public BackgroundFetchScheduler::RequestProvider {
+ : public BackgroundFetchScheduler::RequestProvider,
+ public background_fetch::DatabaseTaskHost {
public:
+ using GetInitializationDataCallback = base::OnceCallback<void(
+ blink::mojom::BackgroundFetchError,
+ std::vector<background_fetch::BackgroundFetchInitializationData>)>;
using SettledFetchesCallback = base::OnceCallback<void(
blink::mojom::BackgroundFetchError,
bool /* background_fetch_succeeded */,
@@ -67,10 +77,23 @@ class CONTENT_EXPORT BackgroundFetchDataManager
BackgroundFetchDataManager(
BrowserContext* browser_context,
- scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
+ scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
+ scoped_refptr<CacheStorageContextImpl> cache_storage_context);
~BackgroundFetchDataManager() override;
+ // Grabs a reference to CacheStorageManager.
+ virtual void InitializeOnIOThread();
+
+ // Adds or removes the given |observer| to this data manager instance.
+ void AddObserver(BackgroundFetchDataManagerObserver* observer);
+ void RemoveObserver(BackgroundFetchDataManagerObserver* observer);
+
+ // Gets the required data to initialize BackgroundFetchContext with the
+ // appropriate JobControllers. This will be called when BackgroundFetchContext
+ // is being intialized on the IO thread.
+ void GetInitializationData(GetInitializationDataCallback callback);
+
// Creates and stores a new registration with the given properties. Will
// invoke the |callback| when the registration has been created, which may
// fail due to invalid input or storage errors.
@@ -134,11 +157,9 @@ class CONTENT_EXPORT BackgroundFetchDataManager
const url::Origin& origin,
blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback);
- // Gets the number of fetch requests that have been completed for a given
- // registration.
- void GetNumCompletedRequests(
- const BackgroundFetchRegistrationId& registration_id,
- NumRequestsCallback callback);
+ const base::ObserverList<BackgroundFetchDataManagerObserver>& observers() {
+ return observers_;
+ }
// BackgroundFetchScheduler::RequestProvider implementation:
void PopNextRequest(const BackgroundFetchRegistrationId& registration_id,
@@ -149,18 +170,27 @@ class CONTENT_EXPORT BackgroundFetchDataManager
BackgroundFetchRequestInfo* request,
BackgroundFetchScheduler::MarkedCompleteCallback callback) override;
- // TODO(rayankans): Move this function to MarkRequestCompleteTask after
- // non-persistent background fetch support is removed.
- bool FillServiceWorkerResponse(const BackgroundFetchRequestInfo& request,
- const url::Origin& origin,
- ServiceWorkerResponse* response);
+ void ShutdownOnIO();
private:
FRIEND_TEST_ALL_PREFIXES(BackgroundFetchDataManagerTest, Cleanup);
friend class BackgroundFetchDataManagerTest;
+ friend class BackgroundFetchTestDataManager;
friend class background_fetch::DatabaseTask;
- class RegistrationData;
+ // Accessors for tests and DatabaseTasks.
+ ServiceWorkerContextWrapper* service_worker_context() const {
+ return service_worker_context_.get();
+ }
+ scoped_refptr<CacheStorageManager> cache_manager() const {
+ return cache_manager_;
+ }
+ std::set<std::string>& ref_counted_unique_ids() {
+ return ref_counted_unique_ids_;
+ }
+ ChromeBlobStorageContext* blob_storage_context() const {
+ return blob_storage_context_.get();
+ }
void AddStartNextPendingRequestTask(
int64_t service_worker_registration_id,
@@ -170,33 +200,32 @@ class CONTENT_EXPORT BackgroundFetchDataManager
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);
+ // DatabaseTaskHost implementation.
+ void OnTaskFinished(background_fetch::DatabaseTask* task) override;
+ BackgroundFetchDataManager* data_manager() override;
void Cleanup();
+ // Whether Shutdown was called on BackgroundFetchContext.
+ bool shutting_down_ = false;
+
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
- // The blob storage request with which response information will be stored.
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
+ scoped_refptr<CacheStorageContextImpl> cache_storage_context_;
- // Map from {service_worker_registration_id, origin, developer_id} tuples to
- // the |unique_id|s of active background fetch registrations (not
- // 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_registration_unique_ids_;
+ // The BackgroundFetch stores its own reference to CacheStorageManager
+ // in case StoragePartitionImpl is destoyed, which releases the reference.
+ scoped_refptr<CacheStorageManager> cache_manager_;
- // 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_;
+ // The blob storage request with which response information will be stored.
+ scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
// Pending database operations, serialized to ensure consistency.
// Invariant: the frontmost task, if any, has already been started.
base::queue<std::unique_ptr<background_fetch::DatabaseTask>> database_tasks_;
+ base::ObserverList<BackgroundFetchDataManagerObserver> observers_;
+
// 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
diff --git a/chromium/content/browser/background_fetch/background_fetch_data_manager_observer.h b/chromium/content/browser/background_fetch/background_fetch_data_manager_observer.h
new file mode 100644
index 00000000000..12981a841ba
--- /dev/null
+++ b/chromium/content/browser/background_fetch/background_fetch_data_manager_observer.h
@@ -0,0 +1,31 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DATA_MANAGER_OBSERVER_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DATA_MANAGER_OBSERVER_H_
+
+namespace content {
+
+class BackgroundFetchRegistrationId;
+
+// Observer interface for objects that would like to be notified about changes
+// committed to storage through the Background Fetch data manager. All methods
+// will be invoked on the IO thread.
+class BackgroundFetchDataManagerObserver {
+ public:
+ // Called when the |title| for the Background Fetch |registration_id| has been
+ // updated in the data store.
+ virtual void OnUpdatedUI(const BackgroundFetchRegistrationId& registration_id,
+ const std::string& title) = 0;
+
+ // Called if corrupted data is found in the Service Worker database.
+ virtual void OnServiceWorkerDatabaseCorrupted(
+ int64_t service_worker_registration_id) = 0;
+
+ virtual ~BackgroundFetchDataManagerObserver() {}
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_DATA_MANAGER_OBSERVER_H_
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 8a1cd9a985e..acd1d25f874 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
@@ -15,25 +15,29 @@
#include "base/command_line.h"
#include "base/guid.h"
#include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "content/browser/background_fetch/background_fetch_data_manager_observer.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/background_fetch_test_data_manager.h"
#include "content/browser/background_fetch/storage/database_helpers.h"
-#include "content/browser/background_fetch/storage/get_num_requests_task.h"
+#include "content/browser/cache_storage/cache_storage_manager.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/background_fetch_response.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_switches.h"
+#include "content/public/browser/storage_partition.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkColor.h"
namespace content {
namespace {
+using background_fetch::BackgroundFetchInitializationData;
using ::testing::UnorderedElementsAre;
using ::testing::IsEmpty;
-enum class BackgroundFetchRegistrationStorage { kPersistent, kNonPersistent };
-
const char kUserDataPrefix[] = "bgfetch_";
const char kExampleDeveloperId[] = "my-example-id";
@@ -44,6 +48,18 @@ const char kAlternativeUniqueId[] = "bb48a9fb-c21f-4c2d-a9ae-58bd48a9fb53";
const char kInitialTitle[] = "Initial Title";
const char kUpdatedTitle[] = "Updated Title";
+constexpr size_t kResponseFileSize = 42u;
+
+void DidGetInitializationData(
+ base::Closure quit_closure,
+ std::vector<BackgroundFetchInitializationData>* out_result,
+ blink::mojom::BackgroundFetchError error,
+ std::vector<BackgroundFetchInitializationData> result) {
+ DCHECK_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ *out_result = std::move(result);
+ std::move(quit_closure).Run();
+}
+
void DidCreateRegistration(
base::Closure quit_closure,
blink::mojom::BackgroundFetchError* out_error,
@@ -60,31 +76,48 @@ void DidGetError(base::Closure quit_closure,
std::move(quit_closure).Run();
}
-void DidGetRegistrationUserDataByKeyPrefix(base::Closure quit_closure,
- std::vector<std::string>* out_data,
- const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+void DidGetRegistrationUserDataByKeyPrefix(
+ base::OnceClosure quit_closure,
+ std::vector<std::string>* out_data,
+ const std::vector<std::string>& data,
+ blink::ServiceWorkerStatusCode status) {
DCHECK(out_data);
- DCHECK_EQ(SERVICE_WORKER_OK, status);
+ DCHECK_EQ(blink::ServiceWorkerStatusCode::kOk, status);
*out_data = data;
std::move(quit_closure).Run();
}
void AnnotateRequestInfoWithFakeDownloadManagerData(
- BackgroundFetchRequestInfo* request_info) {
- // Fill |request_info| with a failed result.
+ BackgroundFetchRequestInfo* request_info,
+ bool success = false) {
+ DCHECK(request_info);
+
+ std::string headers =
+ success ? "HTTP/1.1 200 OK\n" : "HTTP/1.1 404 Not found\n";
+ request_info->PopulateWithResponse(std::make_unique<BackgroundFetchResponse>(
+ std::vector<GURL>(1u, request_info->fetch_request().url),
+ base::MakeRefCounted<net::HttpResponseHeaders>(headers)));
+
+ if (!success) {
+ // Fill |request_info| with a failed result.
+ request_info->SetResult(std::make_unique<BackgroundFetchResult>(
+ base::Time::Now(), BackgroundFetchResult::FailureReason::UNKNOWN));
+ return;
+ }
+
+ // This is treated as an empty response, but the size is set to
+ // |kResponseFileSize| for tests that use filesize.
request_info->SetResult(std::make_unique<BackgroundFetchResult>(
- base::Time::Now(), BackgroundFetchResult::FailureReason::UNKNOWN));
- request_info->PopulateWithResponse(
- std::make_unique<BackgroundFetchResponse>(std::vector<GURL>(1), nullptr));
+ base::Time::Now(), base::FilePath(), base::nullopt /* blob_handle */,
+ kResponseFileSize));
}
void GetNumUserData(base::Closure quit_closure,
int* out_size,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK(out_size);
- DCHECK_EQ(SERVICE_WORKER_OK, status);
+ DCHECK_EQ(blink::ServiceWorkerStatusCode::kOk, status);
*out_size = data.size();
std::move(quit_closure).Run();
}
@@ -101,38 +134,57 @@ bool operator==(const ResponseStateStats& s1, const ResponseStateStats& s2) {
s1.completed_requests == s2.completed_requests;
}
+std::vector<ServiceWorkerFetchRequest> CreateValidRequests(
+ const url::Origin& origin,
+ size_t num_requests = 1u) {
+ std::vector<ServiceWorkerFetchRequest> requests(num_requests);
+ for (size_t i = 0; i < requests.size(); i++) {
+ // Creates a URL of the form: `http://example.com/x`
+ requests[i].url = GURL(origin.GetURL().spec() + base::NumberToString(i));
+ }
+ return requests;
+}
+
} // namespace
class BackgroundFetchDataManagerTest
: public BackgroundFetchTestBase,
- public ::testing::WithParamInterface<BackgroundFetchRegistrationStorage> {
+ public BackgroundFetchDataManagerObserver {
public:
BackgroundFetchDataManagerTest() {
- registration_storage_ = GetParam();
- if (registration_storage_ ==
- BackgroundFetchRegistrationStorage::kPersistent) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableBackgroundFetchPersistence);
- }
RestartDataManagerFromPersistentStorage();
}
- ~BackgroundFetchDataManagerTest() override = default;
+ ~BackgroundFetchDataManagerTest() override {
+ background_fetch_data_manager_->RemoveObserver(this);
+ }
// 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_ =
- std::make_unique<BackgroundFetchDataManager>(
- browser_context(),
- embedded_worker_test_helper()->context_wrapper());
+ std::make_unique<BackgroundFetchTestDataManager>(
+ browser_context(), storage_partition(),
+ embedded_worker_test_helper()->context_wrapper(),
+ true /* mock_fill_response */);
+
+ background_fetch_data_manager_->AddObserver(this);
+ background_fetch_data_manager_->InitializeOnIOThread();
+ }
+
+ // Synchronous version of BackgroundFetchDataManager::GetInitializationData().
+ std::vector<BackgroundFetchInitializationData> GetInitializationData() {
+ // Simulate browser restart. This re-initializes |data_manager_|, since
+ // this DatabaseTask should only be called on browser startup.
+ RestartDataManagerFromPersistentStorage();
+
+ std::vector<BackgroundFetchInitializationData> result;
+
+ base::RunLoop run_loop;
+ background_fetch_data_manager_->GetInitializationData(base::BindOnce(
+ &DidGetInitializationData, run_loop.QuitClosure(), &result));
+ run_loop.Run();
+
+ return result;
}
// Synchronous version of BackgroundFetchDataManager::CreateRegistration().
@@ -140,12 +192,13 @@ class BackgroundFetchDataManagerTest
const BackgroundFetchRegistrationId& registration_id,
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
+ const SkBitmap& icon,
blink::mojom::BackgroundFetchError* out_error) {
DCHECK(out_error);
base::RunLoop run_loop;
background_fetch_data_manager_->CreateRegistration(
- registration_id, requests, options, SkBitmap(),
+ registration_id, requests, options, icon,
base::BindOnce(&DidCreateRegistration, run_loop.QuitClosure(),
out_error));
run_loop.Run();
@@ -299,38 +352,6 @@ class BackgroundFetchDataManagerTest
}
// Synchronous version of
- // BackgroundFetchDataManager::GetNumCompletedRequests().
- void GetNumCompletedRequests(
- const BackgroundFetchRegistrationId& registration_id,
- size_t* out_size) {
- DCHECK(out_size);
-
- base::RunLoop run_loop;
- background_fetch_data_manager_->GetNumCompletedRequests(
- registration_id,
- base::BindOnce(&BackgroundFetchDataManagerTest::DidGetNumRequests,
- base::Unretained(this), run_loop.QuitClosure(),
- out_size));
- run_loop.Run();
- }
-
- // Synchronous version of GetNumRequestsTask::Start().
- void GetNumRequestsTask(const BackgroundFetchRegistrationId& registration_id,
- background_fetch::RequestType type,
- size_t* out_size) {
- DCHECK(out_size);
-
- base::RunLoop run_loop;
- background_fetch_data_manager_->AddDatabaseTask(
- std::make_unique<background_fetch::GetNumRequestsTask>(
- background_fetch_data_manager_.get(), registration_id, type,
- base::BindOnce(&BackgroundFetchDataManagerTest::DidGetNumRequests,
- base::Unretained(this), run_loop.QuitClosure(),
- out_size)));
- run_loop.Run();
- }
-
- // Synchronous version of
// ServiceWorkerContextWrapper::GetRegistrationUserDataByKeyPrefix.
std::vector<std::string> GetRegistrationUserDataByKeyPrefix(
int64_t service_worker_registration_id,
@@ -349,6 +370,38 @@ class BackgroundFetchDataManagerTest
return data;
}
+ // Synchronous version of CacheStorageManager::HasCache().
+ bool HasCache(const std::string& cache_name) {
+ bool result = false;
+
+ base::RunLoop run_loop;
+ background_fetch_data_manager_->cache_manager()->HasCache(
+ origin(), CacheStorageOwner::kBackgroundFetch, cache_name,
+ base::BindOnce(&BackgroundFetchDataManagerTest::DidFindCache,
+ base::Unretained(this), run_loop.QuitClosure(),
+ &result));
+ run_loop.Run();
+
+ return result;
+ }
+
+ // Synchronous version of CacheStorageManager::MatchCache().
+ bool MatchCache(const ServiceWorkerFetchRequest& request) {
+ bool result = false;
+ auto request_ptr = std::make_unique<ServiceWorkerFetchRequest>(request);
+
+ base::RunLoop run_loop;
+ background_fetch_data_manager_->cache_manager()->MatchCache(
+ origin(), CacheStorageOwner::kBackgroundFetch, kExampleUniqueId,
+ std::move(request_ptr), nullptr /* match_params */,
+ base::BindOnce(&BackgroundFetchDataManagerTest::DidMatchCache,
+ base::Unretained(this), run_loop.QuitClosure(),
+ &result));
+ run_loop.Run();
+
+ return result;
+ }
+
// Gets information about the number of background fetch requests by state.
ResponseStateStats GetRequestStats(int64_t service_worker_registration_id) {
ResponseStateStats stats;
@@ -388,6 +441,13 @@ class BackgroundFetchDataManagerTest
return stats;
}
+ // BackgroundFetchDataManagerObserver mocks:
+ MOCK_METHOD2(OnUpdatedUI,
+ void(const BackgroundFetchRegistrationId& registration,
+ const std::string& title));
+ MOCK_METHOD1(OnServiceWorkerDatabaseCorrupted,
+ void(int64_t service_worker_registration_id));
+
protected:
void DidGetRegistration(
base::Closure quit_closure,
@@ -465,28 +525,33 @@ class BackgroundFetchDataManagerTest
std::move(quit_closure).Run();
}
- void DidGetNumRequests(base::OnceClosure quit_closure,
- size_t* out_size,
- size_t size) {
- *out_size = size;
+ void DidFindCache(base::OnceClosure quit_closure,
+ bool* out_result,
+ bool has_cache,
+ blink::mojom::CacheStorageError error) {
+ DCHECK_EQ(error, blink::mojom::CacheStorageError::kSuccess);
+ *out_result = has_cache;
std::move(quit_closure).Run();
}
- BackgroundFetchRegistrationStorage registration_storage_;
- std::unique_ptr<BackgroundFetchDataManager> background_fetch_data_manager_;
-};
-
-INSTANTIATE_TEST_CASE_P(
- Persistent,
- BackgroundFetchDataManagerTest,
- ::testing::Values(BackgroundFetchRegistrationStorage::kPersistent));
+ void DidMatchCache(base::OnceClosure quit_closure,
+ bool* out_result,
+ blink::mojom::CacheStorageError error,
+ std::unique_ptr<ServiceWorkerResponse> response) {
+ if (error == blink::mojom::CacheStorageError::kSuccess) {
+ DCHECK(response);
+ *out_result = true;
+ } else {
+ *out_result = false;
+ }
+ std::move(quit_closure).Run();
+ }
-INSTANTIATE_TEST_CASE_P(
- NonPersistent,
- BackgroundFetchDataManagerTest,
- ::testing::Values(BackgroundFetchRegistrationStorage::kNonPersistent));
+ std::unique_ptr<BackgroundFetchTestDataManager>
+ background_fetch_data_manager_;
+};
-TEST_P(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
+TEST_F(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
// Tests that the BackgroundFetchDataManager correctly rejects creating a
// registration with a |developer_id| for which there is already an active
// registration.
@@ -509,7 +574,7 @@ TEST_P(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);
// Creating the initial registration should succeed.
- CreateRegistration(registration_id1, requests, options, &error);
+ CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
// Different |unique_id|, since this is a new Background Fetch registration,
@@ -520,7 +585,7 @@ TEST_P(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
// Attempting to create a second registration with the same |developer_id| and
// |service_worker_registration_id| should yield an error.
- CreateRegistration(registration_id2, requests, options, &error);
+ CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID);
// Deactivating the second registration that failed to be created should fail.
@@ -534,11 +599,11 @@ TEST_P(BackgroundFetchDataManagerTest, NoDuplicateRegistrations) {
// 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);
+ CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
-TEST_P(BackgroundFetchDataManagerTest, GetDeveloperIds) {
+TEST_F(BackgroundFetchDataManagerTest, GetDeveloperIds) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
@@ -554,7 +619,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetDeveloperIds) {
// Create a single registration.
BackgroundFetchRegistrationId registration_id1(
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
- CreateRegistration(registration_id1, requests, options, &error);
+ CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
// Verify that the developer ID can be found.
@@ -572,7 +637,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetDeveloperIds) {
// Create another registration.
BackgroundFetchRegistrationId registration_id2(
sw_id, origin(), kAlternativeDeveloperId, kAlternativeUniqueId);
- CreateRegistration(registration_id2, requests, options, &error);
+ CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
// Verify that both developer IDs can be found.
@@ -589,7 +654,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetDeveloperIds) {
kAlternativeDeveloperId));
}
-TEST_P(BackgroundFetchDataManagerTest, GetRegistration) {
+TEST_F(BackgroundFetchDataManagerTest, GetRegistration) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
@@ -601,7 +666,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetRegistration) {
blink::mojom::BackgroundFetchError error;
// Create a single registration.
- CreateRegistration(registration_id, requests, options, &error);
+ CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
// Verify that the registration can be retrieved.
@@ -628,12 +693,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetRegistration) {
EXPECT_EQ(kExampleDeveloperId, registration->developer_id);
}
-TEST_P(BackgroundFetchDataManagerTest, GetMetadata) {
- // This test only applies to persistent storage.
- if (registration_storage_ ==
- BackgroundFetchRegistrationStorage::kNonPersistent)
- return;
-
+TEST_F(BackgroundFetchDataManagerTest, GetMetadata) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
@@ -645,7 +705,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetMetadata) {
blink::mojom::BackgroundFetchError error;
// Create a single registration.
- CreateRegistration(registration_id, requests, options, &error);
+ CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
// Verify that the metadata can be retrieved.
@@ -672,12 +732,36 @@ TEST_P(BackgroundFetchDataManagerTest, GetMetadata) {
EXPECT_EQ(metadata->num_fetches(), static_cast<int>(requests.size()));
}
-TEST_P(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
- // This test only applies to persistent storage.
- if (registration_storage_ ==
- BackgroundFetchRegistrationStorage::kNonPersistent)
- return;
+TEST_F(BackgroundFetchDataManagerTest, LargeIconNotPersisted) {
+ 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;
+
+ SkBitmap icon;
+ icon.allocN32Pixels(512, 512);
+ icon.eraseColor(SK_ColorGREEN);
+
+ // Create a single registration.
+ CreateRegistration(registration_id, requests, options, icon, &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ // Verify that the metadata can be retrieved.
+ auto metadata = GetMetadata(sw_id, origin(), kExampleDeveloperId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ ASSERT_TRUE(metadata);
+ EXPECT_EQ(metadata->origin(), origin().Serialize());
+ EXPECT_NE(metadata->creation_microseconds_since_unix_epoch(), 0);
+ EXPECT_EQ(metadata->num_fetches(), static_cast<int>(requests.size()));
+ EXPECT_TRUE(metadata->icon().empty());
+}
+
+TEST_F(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
@@ -695,7 +779,7 @@ TEST_P(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
EXPECT_TRUE(title.empty());
// Create a single registration.
- CreateRegistration(registration_id, requests, options, &error);
+ CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
// Verify that the title can be retrieved.
@@ -705,7 +789,12 @@ TEST_P(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
ASSERT_EQ(title.front(), kInitialTitle);
// Update the title.
- UpdateRegistrationUI(registration_id, kUpdatedTitle, &error);
+ {
+ EXPECT_CALL(*this, OnUpdatedUI(registration_id, kUpdatedTitle));
+
+ UpdateRegistrationUI(registration_id, kUpdatedTitle, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ }
RestartDataManagerFromPersistentStorage();
@@ -716,7 +805,7 @@ TEST_P(BackgroundFetchDataManagerTest, UpdateRegistrationUI) {
ASSERT_EQ(title.front(), kUpdatedTitle);
}
-TEST_P(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
+TEST_F(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
@@ -727,7 +816,7 @@ TEST_P(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
- CreateRegistration(registration_id1, requests, options, &error);
+ CreateRegistration(registration_id1, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
RestartDataManagerFromPersistentStorage();
@@ -740,7 +829,7 @@ TEST_P(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
// Attempting to create a second registration with the same |developer_id| and
// |service_worker_registration_id| should yield an error, even after
// restarting.
- CreateRegistration(registration_id2, requests, options, &error);
+ CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID);
// Verify that the registration can be retrieved before deletion.
@@ -772,7 +861,7 @@ TEST_P(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
// 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);
+ CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
RestartDataManagerFromPersistentStorage();
@@ -782,12 +871,7 @@ TEST_P(BackgroundFetchDataManagerTest, CreateAndDeleteRegistration) {
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
}
-TEST_P(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
- // This test only applies to persistent storage.
- if (registration_storage_ ==
- BackgroundFetchRegistrationStorage::kNonPersistent)
- return;
-
+TEST_F(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
@@ -809,7 +893,7 @@ TEST_P(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
- CreateRegistration(registration_id, requests, options, &error);
+ CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_EQ(
GetRequestStats(sw_id),
@@ -862,12 +946,132 @@ TEST_P(BackgroundFetchDataManagerTest, PopNextRequestAndMarkAsComplete) {
2 /* completed_requests */}));
}
-TEST_P(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
- // This test only applies to persistent storage.
- if (registration_storage_ ==
- BackgroundFetchRegistrationStorage::kNonPersistent)
- return;
+TEST_F(BackgroundFetchDataManagerTest, DownloadTotalUpdated) {
+ int64_t sw_id = RegisterServiceWorker();
+ ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
+
+ BackgroundFetchRegistrationId registration_id(
+ sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
+ auto requests = CreateValidRequests(origin(), 3u /* num_requests */);
+
+ BackgroundFetchOptions options;
+ blink::mojom::BackgroundFetchError error;
+ CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ auto registration =
+ GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_EQ(registration->download_total, 0u);
+
+ scoped_refptr<BackgroundFetchRequestInfo> request_info;
+ PopNextRequest(registration_id, &request_info);
+ AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
+ true /* succeeded */);
+ MarkRequestAsComplete(registration_id, request_info.get());
+
+ registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_EQ(registration->download_total, kResponseFileSize);
+
+ PopNextRequest(registration_id, &request_info);
+ AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
+ true /* succeeded */);
+ MarkRequestAsComplete(registration_id, request_info.get());
+
+ registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_EQ(registration->download_total, 2 * kResponseFileSize);
+ PopNextRequest(registration_id, &request_info);
+ AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
+ false /* succeeded */);
+ MarkRequestAsComplete(registration_id, request_info.get());
+
+ registration = GetRegistration(sw_id, origin(), kExampleDeveloperId, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ // |download_total| is unchanged.
+ EXPECT_EQ(registration->download_total, 2 * kResponseFileSize);
+}
+
+TEST_F(BackgroundFetchDataManagerTest, WriteToCache) {
+ int64_t sw_id = RegisterServiceWorker();
+ ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
+
+ BackgroundFetchRegistrationId registration_id(
+ sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
+ auto requests = CreateValidRequests(origin(), 2u /* num_requests */);
+
+ BackgroundFetchOptions options;
+ blink::mojom::BackgroundFetchError error;
+
+ CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ scoped_refptr<BackgroundFetchRequestInfo> request_info;
+ PopNextRequest(registration_id, &request_info);
+ ASSERT_TRUE(request_info);
+
+ AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
+ true /* success */);
+ MarkRequestAsComplete(registration_id, request_info.get());
+
+ EXPECT_TRUE(HasCache(kExampleUniqueId));
+ EXPECT_FALSE(HasCache("foo"));
+
+ EXPECT_TRUE(MatchCache(requests[0]));
+ EXPECT_FALSE(MatchCache(requests[1]));
+
+ PopNextRequest(registration_id, &request_info);
+ ASSERT_TRUE(request_info);
+
+ AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
+ true /* success */);
+ MarkRequestAsComplete(registration_id, request_info.get());
+ EXPECT_TRUE(MatchCache(requests[0]));
+ EXPECT_TRUE(MatchCache(requests[1]));
+
+ RestartDataManagerFromPersistentStorage();
+ EXPECT_TRUE(MatchCache(requests[0]));
+ EXPECT_TRUE(MatchCache(requests[1]));
+}
+
+TEST_F(BackgroundFetchDataManagerTest, CacheDeleted) {
+ int64_t sw_id = RegisterServiceWorker();
+ ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
+
+ BackgroundFetchRegistrationId registration_id(
+ sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
+
+ ServiceWorkerFetchRequest request;
+ request.url = GURL(origin().GetURL().spec());
+
+ BackgroundFetchOptions options;
+ blink::mojom::BackgroundFetchError error;
+
+ CreateRegistration(registration_id, {request}, options, SkBitmap(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ scoped_refptr<BackgroundFetchRequestInfo> request_info;
+ PopNextRequest(registration_id, &request_info);
+ ASSERT_TRUE(request_info);
+
+ AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
+ true /* success */);
+ MarkRequestAsComplete(registration_id, request_info.get());
+
+ EXPECT_TRUE(HasCache(kExampleUniqueId));
+ EXPECT_TRUE(MatchCache(request));
+
+ MarkRegistrationForDeletion(registration_id, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ DeleteRegistration(registration_id, &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+ EXPECT_FALSE(HasCache(kExampleUniqueId));
+}
+
+TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
@@ -877,7 +1081,7 @@ TEST_P(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
BackgroundFetchRegistrationId registration_id(
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
- CreateRegistration(registration_id, requests, options, &error);
+ CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
EXPECT_EQ(
GetRequestStats(sw_id),
@@ -917,126 +1121,73 @@ TEST_P(BackgroundFetchDataManagerTest, GetSettledFetchesForRegistration) {
EXPECT_EQ(settled_fetches.size(), requests.size());
}
-TEST_P(BackgroundFetchDataManagerTest, GetNumCompletedRequests) {
+TEST_F(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
int64_t sw_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
BackgroundFetchRegistrationId registration_id(
sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
+ auto requests = CreateValidRequests(origin(), 2u /* num_requests */);
- // The requests are default-initialized, but valid.
- std::vector<ServiceWorkerFetchRequest> requests(2u);
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
+ CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- CreateRegistration(registration_id, requests, options, &error);
-
- size_t num_completed = 0u;
-
- GetNumCompletedRequests(registration_id, &num_completed);
- EXPECT_EQ(num_completed, 0u);
+ bool succeeded = false;
+ std::vector<BackgroundFetchSettledFetch> settled_fetches;
+ // Nothing is downloaded yet.
+ GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
+ &settled_fetches);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_TRUE(succeeded);
+ EXPECT_EQ(settled_fetches.size(), 0u);
scoped_refptr<BackgroundFetchRequestInfo> request_info;
- // Download and store first request.
PopNextRequest(registration_id, &request_info);
ASSERT_TRUE(request_info);
- AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
+ AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
+ true /* success */);
MarkRequestAsComplete(registration_id, request_info.get());
- GetNumCompletedRequests(registration_id, &num_completed);
- EXPECT_EQ(num_completed, 1u);
-
- RestartDataManagerFromPersistentStorage();
-
- GetNumCompletedRequests(registration_id, &num_completed);
- EXPECT_EQ(num_completed, 1u);
+ GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
+ &settled_fetches);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_TRUE(succeeded);
+ EXPECT_EQ(settled_fetches.size(), 1u);
- // Download and store second request.
PopNextRequest(registration_id, &request_info);
ASSERT_TRUE(request_info);
- AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
+ AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
+ true /* success */);
MarkRequestAsComplete(registration_id, request_info.get());
- GetNumCompletedRequests(registration_id, &num_completed);
- EXPECT_EQ(num_completed, 2u);
-}
-
-TEST_P(BackgroundFetchDataManagerTest, GetNumRequestsTask) {
- // This test only applies to persistent storage.
- if (registration_storage_ ==
- BackgroundFetchRegistrationStorage::kNonPersistent)
- return;
-
- int64_t sw_id = RegisterServiceWorker();
- ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
-
- BackgroundFetchRegistrationId registration_id(
- sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
- BackgroundFetchOptions options;
- blink::mojom::BackgroundFetchError error;
-
- CreateRegistration(registration_id, {ServiceWorkerFetchRequest()}, options,
- &error);
-
- size_t size = 0u;
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kAny,
- &size);
- EXPECT_EQ(size, 1u); // Total requests is 1.
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kPending,
- &size);
- EXPECT_EQ(size, 1u); // Total pending requests is 1.
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kActive,
- &size);
- EXPECT_EQ(size, 0u); // No active requests.
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kCompleted,
- &size);
- EXPECT_EQ(size, 0u); // No complete requests.
-
- scoped_refptr<BackgroundFetchRequestInfo> request_info;
- // Download and store first request.
- PopNextRequest(registration_id, &request_info);
- ASSERT_TRUE(request_info);
-
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kAny,
- &size);
- EXPECT_EQ(size, 1u); // Total requests is 1.
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kPending,
- &size);
- EXPECT_EQ(size, 0u); // Pending requests moved to active.
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kActive,
- &size);
- EXPECT_EQ(size, 1u); // Request is active.
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kCompleted,
- &size);
- EXPECT_EQ(size, 0u); // No complete requests.
-
- AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
- MarkRequestAsComplete(registration_id, request_info.get());
+ GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
+ &settled_fetches);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_TRUE(succeeded);
+ ASSERT_EQ(settled_fetches.size(), 2u);
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kActive,
- &size);
- EXPECT_EQ(size, 0u); // No active requests.
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kCompleted,
- &size);
- EXPECT_EQ(size, 1u); // Request is complete.
+ // Sanity check that the responses are written to / read from the cache.
+ EXPECT_TRUE(MatchCache(requests[0]));
+ EXPECT_TRUE(MatchCache(requests[1]));
+ EXPECT_EQ(settled_fetches[0].response.cache_storage_cache_name,
+ kExampleUniqueId);
+ EXPECT_EQ(settled_fetches[1].response.cache_storage_cache_name,
+ kExampleUniqueId);
RestartDataManagerFromPersistentStorage();
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kCompleted,
- &size);
- EXPECT_EQ(size, 1u);
- GetNumRequestsTask(registration_id, background_fetch::RequestType::kAny,
- &size);
- EXPECT_EQ(size, 1u); // Total requests is still 1.
+ GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
+ &settled_fetches);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_TRUE(succeeded);
+ EXPECT_EQ(settled_fetches.size(), 2u);
}
-TEST_P(BackgroundFetchDataManagerTest, Cleanup) {
+TEST_F(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);
@@ -1048,24 +1199,17 @@ TEST_P(BackgroundFetchDataManagerTest, Cleanup) {
BackgroundFetchOptions options;
blink::mojom::BackgroundFetchError error;
- if (registration_storage_ ==
- BackgroundFetchRegistrationStorage::kPersistent) {
- EXPECT_EQ(
- 0u, GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
- }
-
+ EXPECT_EQ(0u,
+ GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
// Create a registration.
- CreateRegistration(registration_id, requests, options, &error);
+ CreateRegistration(registration_id, requests, options, SkBitmap(), &error);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- if (registration_storage_ ==
- BackgroundFetchRegistrationStorage::kPersistent) {
- // We expect as many pending entries as there are requests.
- EXPECT_EQ(requests.size(),
- GetRegistrationUserDataByKeyPrefix(
- sw_id, background_fetch::kPendingRequestKeyPrefix)
- .size());
- }
+ // We expect as many pending entries as there are requests.
+ EXPECT_EQ(requests.size(),
+ GetRegistrationUserDataByKeyPrefix(
+ sw_id, background_fetch::kPendingRequestKeyPrefix)
+ .size());
// And deactivate it.
MarkRegistrationForDeletion(registration_id, &error);
@@ -1073,45 +1217,119 @@ TEST_P(BackgroundFetchDataManagerTest, Cleanup) {
RestartDataManagerFromPersistentStorage();
- if (registration_storage_ ==
- BackgroundFetchRegistrationStorage::kPersistent) {
- // Pending Requests should be deleted after marking a registration for
- // deletion.
- EXPECT_EQ(0u, GetRegistrationUserDataByKeyPrefix(
- sw_id, background_fetch::kPendingRequestKeyPrefix)
- .size());
- EXPECT_EQ(
- 2u, // Metadata proto + title.
- GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
- }
+ // Pending Requests should be deleted after marking a registration for
+ // deletion.
+ EXPECT_EQ(0u, GetRegistrationUserDataByKeyPrefix(
+ sw_id, background_fetch::kPendingRequestKeyPrefix)
+ .size());
+ EXPECT_EQ(2u, // Metadata proto + title.
+ 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());
- }
+ thread_bundle_.RunUntilIdle();
+ 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());
+ EXPECT_EQ(0u,
+ GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size());
+}
+
+TEST_F(BackgroundFetchDataManagerTest, GetInitializationData) {
+ {
+ // No registered ServiceWorkers.
+ std::vector<BackgroundFetchInitializationData> data =
+ GetInitializationData();
+ EXPECT_TRUE(data.empty());
+ }
+
+ int64_t sw_id = RegisterServiceWorker();
+ ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
+ {
+ // Register ServiceWorker with no Background Fetch Registrations.
+ std::vector<BackgroundFetchInitializationData> data =
+ GetInitializationData();
+ EXPECT_TRUE(data.empty());
+ }
+
+ std::vector<ServiceWorkerFetchRequest> requests(2u);
+ BackgroundFetchOptions options;
+ options.title = kInitialTitle;
+ options.download_total = 42u;
+ blink::mojom::BackgroundFetchError error;
+ // Register a Background Fetch.
+ BackgroundFetchRegistrationId registration_id(
+ sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
+ SkBitmap icon;
+ icon.allocN32Pixels(42, 42);
+ icon.eraseColor(SK_ColorGREEN);
+ CreateRegistration(registration_id, requests, options, icon, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ UpdateRegistrationUI(registration_id, kUpdatedTitle, &error);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ {
+ std::vector<BackgroundFetchInitializationData> data =
+ GetInitializationData();
+ ASSERT_EQ(data.size(), 1u);
+ const BackgroundFetchInitializationData& init = data[0];
+
+ EXPECT_EQ(init.registration_id, registration_id);
+ EXPECT_EQ(init.registration.unique_id, kExampleUniqueId);
+ EXPECT_EQ(init.registration.developer_id, kExampleDeveloperId);
+ EXPECT_EQ(init.options.title, kInitialTitle);
+ EXPECT_EQ(init.options.download_total, 42u);
+ EXPECT_EQ(init.ui_title, kUpdatedTitle);
+ EXPECT_EQ(init.num_requests, requests.size());
+ EXPECT_EQ(init.num_completed_requests, 0u);
+ EXPECT_TRUE(init.active_fetch_guids.empty());
+
+ // Check icon.
+ ASSERT_FALSE(init.icon.drawsNothing());
+ EXPECT_EQ(icon.width(), init.icon.width());
+ EXPECT_EQ(icon.height(), init.icon.height());
+ for (int i = 0; i < icon.width(); i++) {
+ for (int j = 0; j < icon.height(); j++)
+ EXPECT_EQ(init.icon.getColor(i, j), SK_ColorGREEN);
+ }
+ }
+
+ // Mark one request as complete and start another.
+ scoped_refptr<BackgroundFetchRequestInfo> request_info;
+ PopNextRequest(registration_id, &request_info);
+ ASSERT_TRUE(request_info);
+ AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get());
+ MarkRequestAsComplete(registration_id, request_info.get());
+ PopNextRequest(registration_id, &request_info);
+ ASSERT_TRUE(request_info);
+ {
+ std::vector<BackgroundFetchInitializationData> data =
+ GetInitializationData();
+ ASSERT_EQ(data.size(), 1u);
+
+ EXPECT_EQ(data[0].num_requests, requests.size());
+ EXPECT_EQ(data[0].num_completed_requests, 1u);
+ EXPECT_EQ(data[0].active_fetch_guids.size(), 1u);
+ }
+
+ // Create another registration.
+ BackgroundFetchRegistrationId registration_id2(
+ sw_id, origin(), kAlternativeDeveloperId, kAlternativeUniqueId);
+ CreateRegistration(registration_id2, requests, options, SkBitmap(), &error);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ {
+ std::vector<BackgroundFetchInitializationData> data =
+ GetInitializationData();
+ ASSERT_EQ(data.size(), 2u);
}
}
-TEST_P(BackgroundFetchDataManagerTest, CreateInParallel) {
+TEST_F(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.
-
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableBackgroundFetchPersistence);
-
int64_t service_worker_registration_id = RegisterServiceWorker();
ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
service_worker_registration_id);
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 99679a6d0f1..90f63f92b31 100644
--- a/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.cc
@@ -143,6 +143,13 @@ class BackgroundFetchDelegateProxy::Core
delegate_->Abort(job_unique_id);
}
+ void UpdateUI(const std::string& job_unique_id, const std::string& title) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (delegate_)
+ delegate_->UpdateUI(job_unique_id, title);
+ }
+
// BackgroundFetchDelegate::Client implementation:
void OnJobCancelled(const std::string& job_unique_id,
BackgroundFetchReasonToAbort reason_to_abort) override;
@@ -157,6 +164,7 @@ class BackgroundFetchDelegateProxy::Core
const std::string& job_unique_id,
const std::string& guid,
std::unique_ptr<content::BackgroundFetchResponse> response) override;
+ void OnUIActivated(const std::string& unique_id) override;
void OnDelegateShutdown() override;
private:
@@ -216,6 +224,16 @@ void BackgroundFetchDelegateProxy::Core::OnDownloadStarted(
job_unique_id, guid, std::move(response)));
}
+void BackgroundFetchDelegateProxy::Core::OnUIActivated(
+ const std::string& job_unique_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&BackgroundFetchDelegateProxy::DidActivateUI, io_parent_,
+ job_unique_id));
+}
+
void BackgroundFetchDelegateProxy::Core::OnDelegateShutdown() {
delegate_ = nullptr;
}
@@ -248,6 +266,11 @@ BackgroundFetchDelegateProxy::~BackgroundFetchDelegateProxy() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
+void BackgroundFetchDelegateProxy::SetClickEventDispatcher(
+ const DispatchClickEventCallback callback) {
+ click_event_dispatcher_callback_ = std::move(callback);
+}
+
void BackgroundFetchDelegateProxy::GetIconDisplaySize(
BackgroundFetchDelegate::GetIconDisplaySizeCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -294,7 +317,9 @@ 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|.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&Core::UpdateUI, ui_core_ptr_, job_unique_id, title));
}
void BackgroundFetchDelegateProxy::Abort(const std::string& job_unique_id) {
@@ -350,6 +375,12 @@ void BackgroundFetchDelegateProxy::DidStartRequest(
job_details.controller->DidStartRequest(request_info);
}
+void BackgroundFetchDelegateProxy::DidActivateUI(
+ const std::string& job_unique_id) {
+ DCHECK(click_event_dispatcher_callback_);
+ click_event_dispatcher_callback_.Run(job_unique_id);
+}
+
void BackgroundFetchDelegateProxy::OnDownloadUpdated(
const std::string& job_unique_id,
const std::string& guid,
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 744278a5d18..1084985b3be 100644
--- a/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.h
+++ b/chromium/content/browser/background_fetch/background_fetch_delegate_proxy.h
@@ -28,6 +28,8 @@ class CONTENT_EXPORT BackgroundFetchDelegateProxy {
public:
// Subclasses must only be destroyed on the IO thread, since these methods
// will be called on the IO thread.
+ using DispatchClickEventCallback =
+ base::RepeatingCallback<void(const std::string& /* unique_id */)>;
class Controller {
public:
// Called when the given |request| has started fetching.
@@ -54,6 +56,11 @@ class CONTENT_EXPORT BackgroundFetchDelegateProxy {
~BackgroundFetchDelegateProxy();
+ // Set BackgroundFetchClick event dispatcher callback, which is a method on
+ // the background fetch context.
+ void SetClickEventDispatcher(
+ const DispatchClickEventCallback click_event_callback);
+
// Gets size of the icon to display with the Background Fetch UI.
void GetIconDisplaySize(
BackgroundFetchDelegate::GetIconDisplaySizeCallback callback);
@@ -113,6 +120,9 @@ class CONTENT_EXPORT BackgroundFetchDelegateProxy {
const std::string& guid,
std::unique_ptr<BackgroundFetchResponse> response);
+ // Should only be called from the BackgroundFetchDelegate (on the IO thread).
+ void DidActivateUI(const std::string& job_unique_id);
+
std::unique_ptr<Core, BrowserThread::DeleteOnUIThread> ui_core_;
base::WeakPtr<Core> ui_core_ptr_;
@@ -135,6 +145,7 @@ class CONTENT_EXPORT BackgroundFetchDelegateProxy {
// GUIDs and the controller that started the download.
std::map<std::string, JobDetails> job_details_map_;
+ DispatchClickEventCallback click_event_dispatcher_callback_;
base::WeakPtrFactory<BackgroundFetchDelegateProxy> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchDelegateProxy);
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 788e87a46a8..3b3a88a0e2a 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
@@ -62,10 +62,17 @@ class FakeBackgroundFetchDelegate : public BackgroundFetchDelegate {
aborted_jobs_.insert(job_unique_id);
}
+ void UpdateUI(const std::string& job_unique_id,
+ const std::string& title) override {
+ ++title_update_count_;
+ }
+
void set_complete_downloads(bool complete_downloads) {
complete_downloads_ = complete_downloads;
}
+ int title_update_count_ = 0;
+
private:
void CompleteDownload(const std::string& job_unique_id,
const std::string& guid) {
@@ -77,7 +84,8 @@ class FakeBackgroundFetchDelegate : public BackgroundFetchDelegate {
client()->OnDownloadComplete(job_unique_id, guid,
std::make_unique<BackgroundFetchResult>(
- base::Time::Now(), base::FilePath(), 10u));
+ base::Time::Now(), base::FilePath(),
+ base::nullopt /* blob_handle */, 10u));
}
std::set<std::string> aborted_jobs_;
@@ -239,4 +247,29 @@ TEST_F(BackgroundFetchDelegateProxyTest, GetIconDisplaySize) {
EXPECT_EQ(out_display_size.height(), kIconDisplaySize);
}
+TEST_F(BackgroundFetchDelegateProxyTest, UpdateUI) {
+ FakeController controller;
+ ServiceWorkerFetchRequest fetch_request;
+
+ auto request = CreateRequestInfo(0 /* request_index */, fetch_request);
+ auto fetch_description = std::make_unique<BackgroundFetchDescription>(
+ kExampleUniqueId, "Job 1 Started.", url::Origin(), SkBitmap(),
+ 0 /* completed_parts */, 1 /* total_parts */,
+ 0 /* completed_parts_size */, 0 /* total_parts_size */,
+ std::vector<std::string>());
+
+ delegate_proxy_.CreateDownloadJob(controller.weak_ptr_factory_.GetWeakPtr(),
+ std::move(fetch_description));
+
+ delegate_proxy_.StartRequest(kExampleUniqueId, url::Origin(), request);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(controller.request_started_);
+ EXPECT_TRUE(controller.request_completed_);
+
+ delegate_proxy_.UpdateUI(kExampleUniqueId, "Job 1 Complete!");
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(delegate_.title_update_count_, 1);
+}
+
} // namespace content
diff --git a/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc b/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc
index 4f7182d5511..81b2e3ae092 100644
--- a/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.cc
@@ -7,7 +7,7 @@
#include "base/callback.h"
#include "base/time/time.h"
#include "content/common/background_fetch/background_fetch_types.h"
-#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
namespace content {
@@ -23,8 +23,7 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchAbortEventCallback callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback) {
last_developer_id_ = developer_id;
last_unique_id_ = unique_id;
last_fetches_ = fetches;
@@ -44,8 +43,7 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent(
void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent(
const std::string& developer_id,
mojom::BackgroundFetchState state,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchClickEventCallback callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback) {
last_developer_id_ = developer_id;
last_state_ = state;
@@ -65,8 +63,7 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchFailEventCallback callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback) {
last_developer_id_ = developer_id;
last_unique_id_ = unique_id;
last_fetches_ = fetches;
@@ -87,8 +84,7 @@ void BackgroundFetchEmbeddedWorkerTestHelper::OnBackgroundFetchedEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::DispatchBackgroundFetchedEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchedEventCallback callback) {
last_developer_id_ = developer_id;
last_unique_id_ = unique_id;
last_fetches_ = fetches;
diff --git a/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h b/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h
index 248b9113586..312debdfb4e 100644
--- a/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h
+++ b/chromium/content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h
@@ -70,25 +70,25 @@ class BackgroundFetchEmbeddedWorkerTestHelper
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchAbortEventCallback callback) override;
+ mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback)
+ override;
void OnBackgroundFetchClickEvent(
const std::string& developer_id,
mojom::BackgroundFetchState state,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchClickEventCallback callback) override;
+ mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback)
+ override;
void OnBackgroundFetchFailEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchFailEventCallback callback) override;
+ mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback)
+ override;
void OnBackgroundFetchedEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchedEventCallback callback) override;
+ mojom::ServiceWorker::DispatchBackgroundFetchedEventCallback callback)
+ override;
private:
bool fail_abort_event_ = false;
diff --git a/chromium/content/browser/background_fetch/background_fetch_event_dispatcher.cc b/chromium/content/browser/background_fetch/background_fetch_event_dispatcher.cc
index 452c9524c84..e80dd43eb28 100644
--- a/chromium/content/browser/background_fetch/background_fetch_event_dispatcher.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_event_dispatcher.cc
@@ -51,14 +51,13 @@ void RecordDispatchResult(
// Records the failure reason of a failed dispatch for |metric_name|.
void RecordFailureResult(ServiceWorkerMetrics::EventType event,
const char* metric_name,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
std::string histogram_name = base::StringPrintf(
"BackgroundFetch.EventDispatchFailure.%s.%s", metric_name,
HistogramSuffixForEventType(event).c_str());
// Used because the |histogram_name| is not a constant.
- base::UmaHistogramEnumeration(histogram_name, service_worker_status,
- SERVICE_WORKER_ERROR_MAX_VALUE);
+ base::UmaHistogramEnumeration(histogram_name, service_worker_status);
}
} // namespace
@@ -95,7 +94,7 @@ void BackgroundFetchEventDispatcher::DoDispatchBackgroundFetchAbortEvent(
scoped_refptr<ServiceWorkerVersion> service_worker_version,
int request_id) {
DCHECK(service_worker_version);
- service_worker_version->event_dispatcher()->DispatchBackgroundFetchAbortEvent(
+ service_worker_version->endpoint()->DispatchBackgroundFetchAbortEvent(
developer_id, unique_id, fetches,
service_worker_version->CreateSimpleEventCallback(request_id));
}
@@ -119,7 +118,7 @@ void BackgroundFetchEventDispatcher::DoDispatchBackgroundFetchClickEvent(
scoped_refptr<ServiceWorkerVersion> service_worker_version,
int request_id) {
DCHECK(service_worker_version);
- service_worker_version->event_dispatcher()->DispatchBackgroundFetchClickEvent(
+ service_worker_version->endpoint()->DispatchBackgroundFetchClickEvent(
developer_id, state,
service_worker_version->CreateSimpleEventCallback(request_id));
}
@@ -145,7 +144,7 @@ void BackgroundFetchEventDispatcher::DoDispatchBackgroundFetchFailEvent(
scoped_refptr<ServiceWorkerVersion> service_worker_version,
int request_id) {
DCHECK(service_worker_version);
- service_worker_version->event_dispatcher()->DispatchBackgroundFetchFailEvent(
+ service_worker_version->endpoint()->DispatchBackgroundFetchFailEvent(
developer_id, unique_id, fetches,
service_worker_version->CreateSimpleEventCallback(request_id));
}
@@ -171,7 +170,7 @@ void BackgroundFetchEventDispatcher::DoDispatchBackgroundFetchedEvent(
scoped_refptr<ServiceWorkerVersion> service_worker_version,
int request_id) {
DCHECK(service_worker_version);
- service_worker_version->event_dispatcher()->DispatchBackgroundFetchedEvent(
+ service_worker_version->endpoint()->DispatchBackgroundFetchedEvent(
developer_id, unique_id, fetches,
service_worker_version->CreateSimpleEventCallback(request_id));
}
@@ -193,9 +192,9 @@ void BackgroundFetchEventDispatcher::StartActiveWorkerForDispatch(
ServiceWorkerMetrics::EventType event,
base::OnceClosure finished_closure,
ServiceWorkerLoadedCallback loaded_callback,
- ServiceWorkerStatusCode service_worker_status,
+ blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> registration) {
- if (service_worker_status != SERVICE_WORKER_OK) {
+ if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
DidDispatchEvent(event, std::move(finished_closure), DispatchPhase::FINDING,
service_worker_status);
return;
@@ -216,8 +215,8 @@ void BackgroundFetchEventDispatcher::DispatchEvent(
base::OnceClosure finished_closure,
ServiceWorkerLoadedCallback loaded_callback,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
- ServiceWorkerStatusCode start_worker_status) {
- if (start_worker_status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode start_worker_status) {
+ if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) {
DidDispatchEvent(event, std::move(finished_closure),
DispatchPhase::STARTING, start_worker_status);
return;
@@ -235,7 +234,7 @@ void BackgroundFetchEventDispatcher::DidDispatchEvent(
ServiceWorkerMetrics::EventType event,
base::OnceClosure finished_closure,
DispatchPhase dispatch_phase,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
// Record the histograms tracking event dispatching success.
switch (dispatch_phase) {
case DispatchPhase::FINDING:
@@ -247,7 +246,7 @@ void BackgroundFetchEventDispatcher::DidDispatchEvent(
RecordFailureResult(event, "StartWorker", service_worker_status);
break;
case DispatchPhase::DISPATCHING:
- if (service_worker_status != SERVICE_WORKER_OK) {
+ if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
RecordDispatchResult(event, DISPATCH_RESULT_CANNOT_DISPATCH_EVENT);
RecordFailureResult(event, "Dispatch", service_worker_status);
} else {
diff --git a/chromium/content/browser/background_fetch/background_fetch_event_dispatcher.h b/chromium/content/browser/background_fetch/background_fetch_event_dispatcher.h
index 7194e67e967..f5358207186 100644
--- a/chromium/content/browser/background_fetch/background_fetch_event_dispatcher.h
+++ b/chromium/content/browser/background_fetch/background_fetch_event_dispatcher.h
@@ -13,7 +13,7 @@
#include "base/memory/ref_counted.h"
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker.mojom.h"
namespace content {
@@ -94,7 +94,7 @@ class CONTENT_EXPORT BackgroundFetchEventDispatcher {
ServiceWorkerMetrics::EventType event,
base::OnceClosure finished_closure,
ServiceWorkerLoadedCallback loaded_callback,
- ServiceWorkerStatusCode service_worker_status,
+ blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> registration);
// Dispatches the actual event after the Service Worker has been started.
@@ -103,13 +103,14 @@ class CONTENT_EXPORT BackgroundFetchEventDispatcher {
base::OnceClosure finished_closure,
ServiceWorkerLoadedCallback loaded_callback,
scoped_refptr<ServiceWorkerVersion> service_worker_version,
- ServiceWorkerStatusCode start_worker_status);
+ blink::ServiceWorkerStatusCode start_worker_status);
// Called when an event of type |event| has finished dispatching.
- static void DidDispatchEvent(ServiceWorkerMetrics::EventType event,
- base::OnceClosure finished_closure,
- DispatchPhase dispatch_phase,
- ServiceWorkerStatusCode service_worker_status);
+ static void DidDispatchEvent(
+ ServiceWorkerMetrics::EventType event,
+ base::OnceClosure finished_closure,
+ DispatchPhase dispatch_phase,
+ blink::ServiceWorkerStatusCode service_worker_status);
// Methods that actually invoke the event on an activated Service Worker.
static void DoDispatchBackgroundFetchAbortEvent(
diff --git a/chromium/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc b/chromium/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
index aac9e2f1f68..dd6655ef7b2 100644
--- a/chromium/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_event_dispatcher_unittest.cc
@@ -10,7 +10,7 @@
#include "base/guid.h"
#include "base/macros.h"
#include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "content/browser/background_fetch/background_fetch_embedded_worker_test_helper.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/browser/background_fetch/background_fetch_test_base.h"
@@ -54,7 +54,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchInvalidRegistration) {
BackgroundFetchEventDispatcher::DISPATCH_RESULT_CANNOT_FIND_WORKER, 1);
histogram_tester_.ExpectBucketCount(
"BackgroundFetch.EventDispatchFailure.FindWorker.AbortEvent",
- SERVICE_WORKER_ERROR_NOT_FOUND, 1);
+ blink::ServiceWorkerStatusCode::kErrorNotFound, 1);
}
TEST_F(BackgroundFetchEventDispatcherTest, DispatchAbortEvent) {
@@ -119,7 +119,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchAbortEvent) {
BackgroundFetchEventDispatcher::DISPATCH_RESULT_CANNOT_DISPATCH_EVENT, 1);
histogram_tester_.ExpectUniqueSample(
"BackgroundFetch.EventDispatchFailure.Dispatch.AbortEvent",
- SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, 1);
+ blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected, 1);
}
TEST_F(BackgroundFetchEventDispatcherTest, DispatchClickEvent) {
@@ -183,7 +183,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchClickEvent) {
BackgroundFetchEventDispatcher::DISPATCH_RESULT_CANNOT_DISPATCH_EVENT, 1);
histogram_tester_.ExpectUniqueSample(
"BackgroundFetch.EventDispatchFailure.Dispatch.ClickEvent",
- SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, 1);
+ blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected, 1);
}
TEST_F(BackgroundFetchEventDispatcherTest, DispatchFailEvent) {
@@ -250,7 +250,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchFailEvent) {
BackgroundFetchEventDispatcher::DISPATCH_RESULT_CANNOT_DISPATCH_EVENT, 1);
histogram_tester_.ExpectUniqueSample(
"BackgroundFetch.EventDispatchFailure.Dispatch.FailEvent",
- SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, 1);
+ blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected, 1);
}
TEST_F(BackgroundFetchEventDispatcherTest, DispatchFetchedEvent) {
@@ -325,7 +325,7 @@ TEST_F(BackgroundFetchEventDispatcherTest, DispatchFetchedEvent) {
BackgroundFetchEventDispatcher::DISPATCH_RESULT_CANNOT_DISPATCH_EVENT, 1);
histogram_tester_.ExpectUniqueSample(
"BackgroundFetch.EventDispatchFailure.Dispatch.FetchedEvent",
- SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, 1);
+ blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected, 1);
}
} // namespace
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 aac1856ce92..2b9a7e6681a 100644
--- a/chromium/content/browser/background_fetch/background_fetch_job_controller.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_job_controller.cc
@@ -16,7 +16,7 @@ BackgroundFetchJobController::BackgroundFetchJobController(
const BackgroundFetchRegistrationId& registration_id,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
- const BackgroundFetchRegistration& registration,
+ uint64_t bytes_downloaded,
BackgroundFetchRequestManager* request_manager,
ProgressCallback progress_callback,
BackgroundFetchScheduler::FinishedCallback finished_callback)
@@ -24,7 +24,7 @@ BackgroundFetchJobController::BackgroundFetchJobController(
std::move(finished_callback)),
options_(options),
icon_(icon),
- complete_requests_downloaded_bytes_cache_(registration.downloaded),
+ complete_requests_downloaded_bytes_cache_(bytes_downloaded),
request_manager_(request_manager),
delegate_proxy_(delegate_proxy),
progress_callback_(std::move(progress_callback)),
@@ -35,7 +35,8 @@ BackgroundFetchJobController::BackgroundFetchJobController(
void BackgroundFetchJobController::InitializeRequestStatus(
int completed_downloads,
int total_downloads,
- const std::vector<std::string>& outstanding_guids) {
+ const std::vector<std::string>& outstanding_guids,
+ const std::string& ui_title) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Don't allow double initialization.
@@ -49,7 +50,7 @@ void BackgroundFetchJobController::InitializeRequestStatus(
int total_downloads_size = options_.download_total;
auto fetch_description = std::make_unique<BackgroundFetchDescription>(
- registration_id().unique_id(), options_.title, registration_id().origin(),
+ registration_id().unique_id(), ui_title, registration_id().origin(),
icon_, completed_downloads, total_downloads,
complete_requests_downloaded_bytes_cache_, total_downloads_size,
outstanding_guids);
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 bc7eb93c844..780791dda8b 100644
--- a/chromium/content/browser/background_fetch/background_fetch_job_controller.h
+++ b/chromium/content/browser/background_fetch/background_fetch_job_controller.h
@@ -51,18 +51,20 @@ class CONTENT_EXPORT BackgroundFetchJobController final
const BackgroundFetchRegistrationId& registration_id,
const BackgroundFetchOptions& options,
const SkBitmap& icon,
- const BackgroundFetchRegistration& registration,
+ uint64_t bytes_downloaded,
BackgroundFetchRequestManager* request_manager,
ProgressCallback progress_callback,
BackgroundFetchScheduler::FinishedCallback finished_callback);
~BackgroundFetchJobController() override;
// Initializes the job controller with the status of the active and completed
- // downloads. Only called when this has been loaded from the database.
+ // downloads, as well as the title to use.
+ // 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);
+ const std::vector<std::string>& outstanding_guids,
+ const std::string& ui_title);
// Gets the number of bytes downloaded for jobs that are currently running.
uint64_t GetInProgressDownloadedBytes();
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 f504d14b912..423fc1eb36d 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
@@ -17,10 +17,12 @@
#include "base/run_loop.h"
#include "components/download/public/common/download_item.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_data_manager.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/browser/background_fetch/background_fetch_test_base.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/storage_partition_impl.h"
#include "content/public/browser/background_fetch_delegate.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/fake_download_item.h"
@@ -88,6 +90,8 @@ class FakeBackgroundFetchRequestManager : public BackgroundFetchRequestManager {
std::map<std::string, RegistrationState> registration_status_map_;
};
+} // namespace
+
class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
public:
BackgroundFetchJobControllerTest() = default;
@@ -150,25 +154,49 @@ class BackgroundFetchJobControllerTest : public BackgroundFetchTestBase {
DCHECK(delegate_);
delegate_proxy_ = std::make_unique<BackgroundFetchDelegateProxy>(delegate_);
- BackgroundFetchRegistration registration;
- registration.developer_id = registration_id.developer_id();
- registration.unique_id = registration_id.unique_id();
-
auto controller = std::make_unique<BackgroundFetchJobController>(
delegate_proxy_.get(), registration_id, BackgroundFetchOptions(),
- SkBitmap(), registration, &request_manager_,
+ SkBitmap(), 0 /* bytes_downloaded */, &request_manager_,
base::BindRepeating(
&BackgroundFetchJobControllerTest::DidUpdateProgress,
base::Unretained(this)),
base::BindOnce(&BackgroundFetchJobControllerTest::OnJobFinished));
- controller->InitializeRequestStatus(0, total_downloads,
- std::vector<std::string>());
+ controller->InitializeRequestStatus(
+ 0, total_downloads, {} /* outstanding_guids */, "" /* ui_title */);
return controller;
}
+ void AddControllerToContextMap(
+ const std::string& unique_id,
+ std::unique_ptr<BackgroundFetchJobController> controller) {
+ context_->job_controllers_[unique_id] = std::move(controller);
+ }
+
+ // BackgroundFetchTestBase overrides:
+ void SetUp() override {
+ BackgroundFetchTestBase::SetUp();
+
+ StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>(
+ BrowserContext::GetDefaultStoragePartition(browser_context()));
+
+ context_ = new BackgroundFetchContext(
+ browser_context(),
+ base::WrapRefCounted(embedded_worker_test_helper()->context_wrapper()),
+ base::WrapRefCounted(partition->GetCacheStorageContext()));
+ }
+
+ void TearDown() override {
+ BackgroundFetchTestBase::TearDown();
+ context_ = nullptr;
+
+ // Give pending shutdown operations a chance to finish.
+ base::RunLoop().RunUntilIdle();
+ }
+
protected:
FakeBackgroundFetchRequestManager request_manager_;
+ scoped_refptr<BackgroundFetchContext> context_;
uint64_t last_downloaded_ = 0;
@@ -269,9 +297,6 @@ TEST_F(BackgroundFetchJobControllerTest, Abort) {
controller->StartRequest(requests[0]);
controller->Abort(BackgroundFetchReasonToAbort::CANCELLED_FROM_UI);
- // Tell the delegate to abort the job as well so it doesn't send completed
- // messages to the JobController.
- delegate_->Abort(registration_id.unique_id());
base::RunLoop().RunUntilIdle();
@@ -312,5 +337,50 @@ TEST_F(BackgroundFetchJobControllerTest, Progress) {
EXPECT_EQ(last_downloaded_, strlen(kExampleResponseData));
}
-} // namespace
+TEST_F(BackgroundFetchJobControllerTest, ServiceWorkerRegistrationDeleted) {
+ BackgroundFetchRegistrationId registration_id;
+
+ auto requests = CreateRegistrationForRequests(
+ &registration_id, {{GURL("https://example.com/funny_cat.png"), "GET"}},
+ true /* auto_complete_requests */);
+
+ EXPECT_EQ(JobCompletionStatus::kRunning,
+ request_manager_.GetCompletionStatus(registration_id));
+
+ std::unique_ptr<BackgroundFetchJobController> controller =
+ CreateJobController(registration_id, requests.size());
+
+ AddControllerToContextMap(registration_id.unique_id(), std::move(controller));
+ context_->OnRegistrationDeleted(kExampleServiceWorkerRegistrationId,
+ GURL("https://example.com/funny_cat.png"));
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(JobCompletionStatus::kAborted,
+ request_manager_.GetCompletionStatus(registration_id));
+}
+
+TEST_F(BackgroundFetchJobControllerTest, ServiceWorkerDatabaseDeleted) {
+ BackgroundFetchRegistrationId registration_id;
+
+ auto requests = CreateRegistrationForRequests(
+ &registration_id, {{GURL("https://example.com/funny_cat.png"), "GET"}},
+ true /* auto_complete_requests */);
+
+ EXPECT_EQ(JobCompletionStatus::kRunning,
+ request_manager_.GetCompletionStatus(registration_id));
+
+ std::unique_ptr<BackgroundFetchJobController> controller =
+ CreateJobController(registration_id, requests.size());
+
+ AddControllerToContextMap(registration_id.unique_id(), std::move(controller));
+
+ context_->OnStorageWiped();
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(JobCompletionStatus::kAborted,
+ request_manager_.GetCompletionStatus(registration_id));
+}
+
} // 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 25a471ccadd..e13df709f2f 100644
--- a/chromium/content/browser/background_fetch/background_fetch_request_info.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_request_info.cc
@@ -91,6 +91,13 @@ const std::vector<GURL>& BackgroundFetchRequestInfo::GetURLChain() const {
return url_chain_;
}
+const base::Optional<storage::BlobDataHandle>&
+BackgroundFetchRequestInfo::GetBlobDataHandle() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(result_);
+ return result_->blob_handle;
+}
+
const base::FilePath& BackgroundFetchRequestInfo::GetFilePath() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(result_);
@@ -109,4 +116,10 @@ const base::Time& BackgroundFetchRequestInfo::GetResponseTime() const {
return result_->response_time;
}
+bool BackgroundFetchRequestInfo::IsResultSuccess() const {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(result_);
+ return result_->failure_reason == BackgroundFetchResult::FailureReason::NONE;
+}
+
} // namespace content
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 a8d12425349..1a796748e4e 100644
--- a/chromium/content/browser/background_fetch/background_fetch_request_info.h
+++ b/chromium/content/browser/background_fetch/background_fetch_request_info.h
@@ -13,6 +13,7 @@
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted_delete_on_sequence.h"
+#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "components/download/public/common/download_item.h"
@@ -21,6 +22,10 @@
#include "content/common/service_worker/service_worker_types.h"
#include "url/gurl.h"
+namespace storage {
+class BlobDataHandle;
+}
+
namespace content {
struct BackgroundFetchResponse;
@@ -75,6 +80,10 @@ class CONTENT_EXPORT BackgroundFetchRequestInfo
// Returns the URL chain for the response, including redirects.
const std::vector<GURL>& GetURLChain() const;
+ // Returns the blob data handle for the response. Only available when dealing
+ // with in-memory downloads.
+ const base::Optional<storage::BlobDataHandle>& GetBlobDataHandle() const;
+
// Returns the absolute path to the file in which the response is stored.
const base::FilePath& GetFilePath() const;
@@ -84,6 +93,9 @@ class CONTENT_EXPORT BackgroundFetchRequestInfo
// Returns the time at which the response was completed.
const base::Time& GetResponseTime() const;
+ // Whether the BackgroundFetchResult was successful.
+ bool IsResultSuccess() const;
+
private:
friend class base::RefCountedDeleteOnSequence<BackgroundFetchRequestInfo>;
friend class base::DeleteHelper<BackgroundFetchRequestInfo>;
diff --git a/chromium/content/browser/background_fetch/background_fetch_scheduler.cc b/chromium/content/browser/background_fetch/background_fetch_scheduler.cc
index 62309d66bba..ba39a99d590 100644
--- a/chromium/content/browser/background_fetch/background_fetch_scheduler.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_scheduler.cc
@@ -33,12 +33,23 @@ BackgroundFetchScheduler::BackgroundFetchScheduler(
BackgroundFetchScheduler::~BackgroundFetchScheduler() = default;
+void BackgroundFetchScheduler::RemoveJobController(
+ const BackgroundFetchRegistrationId& registration_id) {
+ for (auto iter = controller_queue_.begin(); iter != controller_queue_.end();
+ /* no increment */) {
+ if ((**iter).registration_id() == registration_id)
+ iter = controller_queue_.erase(iter);
+ else
+ iter++;
+ }
+}
+
void BackgroundFetchScheduler::AddJobController(
BackgroundFetchScheduler::Controller* controller) {
controller_queue_.push_back(controller);
- while (!controller_queue_.empty() &&
- download_controller_map_.size() < max_concurrent_downloads_) {
+ if (!controller_queue_.empty() &&
+ download_controller_map_.size() < max_concurrent_downloads_) {
ScheduleDownload();
}
}
@@ -46,12 +57,14 @@ void BackgroundFetchScheduler::AddJobController(
void BackgroundFetchScheduler::ScheduleDownload() {
DCHECK(download_controller_map_.size() < max_concurrent_downloads_);
- if (controller_queue_.empty())
+ if (lock_scheduler_ || controller_queue_.empty())
return;
auto* controller = controller_queue_.front();
controller_queue_.pop_front();
+ // Making an async call, `ScheduleDownload` shouldn't be called anymore.
+ lock_scheduler_ = true;
request_provider_->PopNextRequest(
controller->registration_id(),
base::BindOnce(&BackgroundFetchScheduler::DidPopNextRequest,
@@ -61,8 +74,20 @@ void BackgroundFetchScheduler::ScheduleDownload() {
void BackgroundFetchScheduler::DidPopNextRequest(
BackgroundFetchScheduler::Controller* controller,
scoped_refptr<BackgroundFetchRequestInfo> request_info) {
+ DCHECK(controller);
+ lock_scheduler_ = false; // Can schedule downloads again.
+
+ // Storage error, fetch might have been aborted.
+ if (!request_info) {
+ ScheduleDownload();
+ return;
+ }
+
download_controller_map_[request_info->download_guid()] = controller;
controller->StartRequest(request_info);
+
+ if (download_controller_map_.size() < max_concurrent_downloads_)
+ ScheduleDownload();
}
void BackgroundFetchScheduler::MarkRequestAsComplete(
diff --git a/chromium/content/browser/background_fetch/background_fetch_scheduler.h b/chromium/content/browser/background_fetch/background_fetch_scheduler.h
index 8527582c520..243bb95e705 100644
--- a/chromium/content/browser/background_fetch/background_fetch_scheduler.h
+++ b/chromium/content/browser/background_fetch/background_fetch_scheduler.h
@@ -88,6 +88,13 @@ class CONTENT_EXPORT BackgroundFetchScheduler
// schedule jobs for |controller|.
void AddJobController(Controller* controller);
+ // Removes a job controller from the scheduler. Abort ongoing fetches on the
+ // controller before calling this.
+ // TODO(crbug.com/850075): Move management of active fetches to
+ // BackgroundFetchScheduler.
+ void RemoveJobController(
+ const BackgroundFetchRegistrationId& registration_id);
+
void set_max_concurrent_downloads(size_t new_max) {
max_concurrent_downloads_ = new_max;
}
@@ -115,6 +122,7 @@ class CONTENT_EXPORT BackgroundFetchScheduler
base::circular_deque<Controller*> controller_queue_;
std::map<std::string, Controller*> download_controller_map_;
+ bool lock_scheduler_ = false;
size_t max_concurrent_downloads_ = 1;
DISALLOW_COPY_AND_ASSIGN(BackgroundFetchScheduler);
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 984a94c034a..c61095e1a3c 100644
--- a/chromium/content/browser/background_fetch/background_fetch_service_impl.h
+++ b/chromium/content/browser/background_fetch/background_fetch_service_impl.h
@@ -12,6 +12,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "content/browser/background_fetch/background_fetch_context.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
#include "url/origin.h"
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 839e8eee9a7..6e2a9c67992 100644
--- a/chromium/content/browser/background_fetch/background_fetch_service_unittest.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_service_unittest.cc
@@ -9,19 +9,25 @@
#include "base/auto_reset.h"
#include "base/macros.h"
#include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "content/browser/background_fetch/background_fetch_context.h"
#include "content/browser/background_fetch/background_fetch_embedded_worker_test_helper.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_service_impl.h"
#include "content/browser/background_fetch/background_fetch_test_base.h"
+#include "content/browser/background_fetch/background_fetch_test_data_manager.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "mojo/edk/embedder/embedder.h"
+#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/message.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
+#include "third_party/blink/public/common/manifest/manifest.h"
+#include "ui/gfx/geometry/size.h"
namespace content {
namespace {
@@ -30,13 +36,13 @@ const char kExampleUniqueId[] = "7e57ab1e-c0de-a150-ca75-1e75f005ba11";
const char kExampleDeveloperId[] = "my-background-fetch";
const char kAlternativeDeveloperId[] = "my-alternative-fetch";
-IconDefinition CreateIcon(std::string src,
- std::string sizes,
- std::string type) {
- IconDefinition icon;
- icon.src = std::move(src);
+blink::Manifest::ImageResource CreateIcon(const std::string& src,
+ std::vector<gfx::Size> sizes,
+ const std::string& type) {
+ blink::Manifest::ImageResource icon;
+ icon.src = GURL(src);
icon.sizes = std::move(sizes);
- icon.type = std::move(type);
+ icon.type = base::ASCIIToUTF16(type);
return icon;
}
@@ -45,13 +51,13 @@ class BadMessageObserver {
public:
BadMessageObserver()
: dummy_message_(0, 0, 0, 0, nullptr), context_(&dummy_message_) {
- mojo::edk::SetDefaultProcessErrorCallback(base::BindRepeating(
+ mojo::core::SetDefaultProcessErrorCallback(base::BindRepeating(
&BadMessageObserver::ReportBadMessage, base::Unretained(this)));
}
~BadMessageObserver() {
- mojo::edk::SetDefaultProcessErrorCallback(
- mojo::edk::ProcessErrorCallback());
+ mojo::core::SetDefaultProcessErrorCallback(
+ mojo::core::ProcessErrorCallback());
}
const std::string& last_error() const { return last_error_; }
@@ -66,6 +72,8 @@ class BadMessageObserver {
DISALLOW_COPY_AND_ASSIGN(BadMessageObserver);
};
+} // namespace
+
class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
public:
BackgroundFetchServiceTest() = default;
@@ -121,6 +129,50 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
out_registration->unique_id);
}
+ // Starts the Fetch without completing it. Only creates a registration.
+ void StartFetch(int64_t service_worker_registration_id,
+ const std::string& developer_id,
+ const std::vector<ServiceWorkerFetchRequest>& requests,
+ const BackgroundFetchOptions& options,
+ const SkBitmap& icon) {
+ BackgroundFetchRegistrationId registration_id(
+ service_worker_registration_id, origin(), developer_id,
+ kExampleUniqueId);
+
+ base::RunLoop run_loop;
+ context_->data_manager_->CreateRegistration(
+ registration_id, requests, options, icon,
+ base::BindOnce(&BackgroundFetchServiceTest::DidStartFetch,
+ base::Unretained(this), run_loop.QuitClosure()));
+ run_loop.Run();
+ }
+
+ // Calls BackgroundFetchServiceImpl::Fetch() and unregisters the service
+ // worker before Fetch has completed but after the controller has been
+ // initialized.
+ void FetchAndUnregisterServiceWorker(
+ int64_t service_worker_registration_id,
+ const std::string& developer_id,
+ const std::vector<ServiceWorkerFetchRequest>& requests,
+ const BackgroundFetchOptions& options,
+ const SkBitmap& icon,
+ blink::mojom::BackgroundFetchError* out_error,
+ BackgroundFetchRegistration* out_registration) {
+ DCHECK(out_error);
+ DCHECK(out_registration);
+
+ base::AutoReset<bool> hang_registration_creation_for_testing(
+ &context_->hang_registration_creation_for_testing_, true);
+ base::RunLoop run_loop;
+ service_->Fetch(
+ service_worker_registration_id, developer_id, requests, options, icon,
+ base::BindOnce(&BackgroundFetchServiceTest::DidGetRegistration,
+ base::Unretained(this), run_loop.QuitClosure(),
+ out_error, out_registration));
+ UnregisterServiceWorker();
+ run_loop.Run();
+ }
+
// Synchronous wrapper for BackgroundFetchServiceImpl::UpdateUI().
void UpdateUI(int64_t service_worker_registration_id,
const std::string& developer_id,
@@ -156,6 +208,8 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
// We only delete the registration if we successfully abort.
if (*out_error == blink::mojom::BackgroundFetchError::NONE) {
+ // TODO(crbug.com/850894): The Abort callback is being resolved early.
+ base::RunLoop().RunUntilIdle();
// The error passed to the histogram counter is not related to this
// |*out_error|, but the result of
// BackgroundFetchDataManager::DeleteRegistration. For the purposes these
@@ -201,14 +255,27 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
run_loop.Run();
}
+ std::set<std::string> GetJobIDs() {
+ std::set<std::string> job_ids;
+ for (const auto& it : context_->job_controllers_)
+ job_ids.insert(it.first);
+ return job_ids;
+ }
+
// BackgroundFetchTestBase overrides:
void SetUp() override {
BackgroundFetchTestBase::SetUp();
context_ = new BackgroundFetchContext(
browser_context(),
- base::WrapRefCounted(embedded_worker_test_helper()->context_wrapper()));
-
+ base::WrapRefCounted(embedded_worker_test_helper()->context_wrapper()),
+ nullptr /* cache_storage_context */);
+ context_->SetDataManagerForTesting(
+ std::make_unique<BackgroundFetchTestDataManager>(
+ browser_context(), storage_partition(),
+ embedded_worker_test_helper()->context_wrapper()));
+
+ context_->InitializeOnIOThread();
service_ = std::make_unique<BackgroundFetchServiceImpl>(context_, origin());
}
@@ -238,6 +305,14 @@ class BackgroundFetchServiceTest : public BackgroundFetchTestBase {
std::move(quit_closure).Run();
}
+ void DidStartFetch(
+ base::Closure quit_closure,
+ blink::mojom::BackgroundFetchError error,
+ std::unique_ptr<BackgroundFetchRegistration> registration) {
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ std::move(quit_closure).Run();
+ }
+
void DidGetError(base::Closure quit_closure,
blink::mojom::BackgroundFetchError* out_error,
blink::mojom::BackgroundFetchError error) {
@@ -313,8 +388,10 @@ TEST_F(BackgroundFetchServiceTest, FetchRegistrationProperties) {
requests.emplace_back(); // empty, but valid
BackgroundFetchOptions options;
- options.icons.push_back(CreateIcon("funny_cat.png", "256x256", "image/png"));
- options.icons.push_back(CreateIcon("silly_cat.gif", "512x512", "image/gif"));
+ options.icons.push_back(
+ CreateIcon("funny_cat.png", {{256, 256}}, "image/png"));
+ options.icons.push_back(
+ CreateIcon("silly_cat.gif", {{512, 512}}, "image/gif"));
options.title = "My Background Fetch!";
options.download_total = 9001;
@@ -947,7 +1024,10 @@ TEST_F(BackgroundFetchServiceTest, GetDeveloperIds) {
GetDeveloperIds(service_worker_registration_id, &error, &developer_ids);
ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
- ASSERT_EQ(developer_ids.size(), 0u);
+ // TODO(crbug.com/850076): The Storage Worker Database access is not
+ // checking the origin. In a non-test environment this won't happen since a
+ // ServiceWorker registration ID is tied to the origin.
+ ASSERT_EQ(developer_ids.size(), 2u);
}
// Verify that using the wrong service worker id does not return developer ids
@@ -967,5 +1047,78 @@ TEST_F(BackgroundFetchServiceTest, GetDeveloperIds) {
}
}
-} // namespace
+TEST_F(BackgroundFetchServiceTest, UnregisterServiceWorker) {
+ // This test registers a service worker, and calls fetch, but unregisters the
+ // service worker before fetch has finished. We then verify that the
+ // appropriate error is returned from Fetch().
+
+ int64_t service_worker_registration_id = RegisterServiceWorker();
+ ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
+ service_worker_registration_id);
+
+ std::vector<ServiceWorkerFetchRequest> requests;
+ requests.emplace_back(); // empty, but valid
+
+ BackgroundFetchOptions options;
+ options.icons.push_back(
+ CreateIcon("funny_cat.png", {{256, 256}}, "image/png"));
+ options.icons.push_back(
+ CreateIcon("silly_cat.gif", {{512, 512}}, "image/gif"));
+ options.title = "My Background Fetch!";
+ options.download_total = 9001;
+
+ blink::mojom::BackgroundFetchError error;
+ BackgroundFetchRegistration registration;
+
+ FetchAndUnregisterServiceWorker(service_worker_registration_id,
+ kExampleDeveloperId, requests, options,
+ SkBitmap(), &error, &registration);
+ ASSERT_EQ(error,
+ blink::mojom::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE);
+ EXPECT_TRUE(registration.developer_id.empty());
+}
+
+TEST_F(BackgroundFetchServiceTest, JobsInitializedOnBrowserRestart) {
+ // Initially there are no jobs in the JobController map.
+ EXPECT_TRUE(GetJobIDs().empty());
+
+ int64_t service_worker_registration_id = RegisterServiceWorker();
+ ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId,
+ service_worker_registration_id);
+
+ std::vector<ServiceWorkerFetchRequest> requests;
+ requests.push_back(CreateRequestWithProvidedResponse(
+ "GET", GURL("https://example.com/mildly_funny_cat.txt"),
+ TestResponseBuilder(200)
+ .SetResponseData("A mildly funny cat.")
+ .AddResponseHeader("Content-Type", "text/plain")
+ .Build()));
+ BackgroundFetchOptions options;
+
+ // Only register the Fetch.
+ StartFetch(service_worker_registration_id, kExampleDeveloperId, requests,
+ options, SkBitmap());
+
+ // Simulate browser restart by re-creating |context_| and |service_|.
+ SetUp();
+
+ // Queue up a GetRegistration DatabaseTask to run right after the
+ // initialization, but before the fetch is resumed.
+ BackgroundFetchRegistration registration;
+ blink::mojom::BackgroundFetchError error;
+ GetRegistration(service_worker_registration_id, kExampleDeveloperId, &error,
+ &registration);
+ ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+ EXPECT_EQ(registration.developer_id, kExampleDeveloperId);
+
+ // Allow the fetch to completely finish.
+ thread_bundle_.RunUntilIdle();
+
+ // At this point the fetch ran to completion.
+ EXPECT_TRUE(GetJobIDs().empty());
+ GetRegistration(service_worker_registration_id, kExampleDeveloperId, &error,
+ &registration);
+ EXPECT_EQ(error, blink::mojom::BackgroundFetchError::INVALID_ID);
+}
+
} // namespace content
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 7c08e174d5b..fc5366e5abd 100644
--- a/chromium/content/browser/background_fetch/background_fetch_test_base.cc
+++ b/chromium/content/browser/background_fetch/background_fetch_test_base.cc
@@ -21,9 +21,9 @@
#include "content/browser/background_fetch/background_fetch_registration_id.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/browser/browser_thread.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"
namespace content {
@@ -35,11 +35,11 @@ const char kTestScriptUrl[] = "https://example.com/sw.js";
void DidRegisterServiceWorker(int64_t* out_service_worker_registration_id,
base::Closure quit_closure,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t service_worker_registration_id) {
DCHECK(out_service_worker_registration_id);
- EXPECT_EQ(SERVICE_WORKER_OK, status) << status_message;
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status) << status_message;
*out_service_worker_registration_id = service_worker_registration_id;
@@ -49,16 +49,24 @@ void DidRegisterServiceWorker(int64_t* out_service_worker_registration_id,
void DidFindServiceWorkerRegistration(
scoped_refptr<ServiceWorkerRegistration>* out_service_worker_registration,
base::Closure quit_closure,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
DCHECK(out_service_worker_registration);
- EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
+ << blink::ServiceWorkerStatusToString(status);
*out_service_worker_registration = service_worker_registration;
std::move(quit_closure).Run();
}
+// Callback for UnregisterServiceWorker.
+void DidUnregisterServiceWorker(base::Closure quit_closure,
+ blink::ServiceWorkerStatusCode status) {
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
+ std::move(quit_closure).Run();
+}
+
} // namespace
BackgroundFetchTestBase::BackgroundFetchTestBase()
@@ -66,7 +74,9 @@ BackgroundFetchTestBase::BackgroundFetchTestBase()
// at time of writing EmbeddedWorkerTestHelper didn't seem to support that.
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
delegate_(browser_context_.GetBackgroundFetchDelegate()),
- origin_(url::Origin::Create(GURL(kTestOrigin))) {}
+ origin_(url::Origin::Create(GURL(kTestOrigin))),
+ storage_partition_(
+ BrowserContext::GetDefaultStoragePartition(browser_context())) {}
BackgroundFetchTestBase::~BackgroundFetchTestBase() {
DCHECK(set_up_called_);
@@ -84,7 +94,6 @@ void BackgroundFetchTestBase::TearDown() {
int64_t BackgroundFetchTestBase::RegisterServiceWorker() {
GURL script_url(kTestScriptUrl);
-
int64_t service_worker_registration_id =
blink::mojom::kInvalidServiceWorkerRegistrationId;
@@ -133,6 +142,14 @@ int64_t BackgroundFetchTestBase::RegisterServiceWorker() {
return service_worker_registration_id;
}
+void BackgroundFetchTestBase::UnregisterServiceWorker() {
+ base::RunLoop run_loop;
+ embedded_worker_test_helper_.context()->UnregisterServiceWorker(
+ origin_.GetURL(),
+ base::BindOnce(&DidUnregisterServiceWorker, run_loop.QuitClosure()));
+ run_loop.Run();
+}
+
ServiceWorkerFetchRequest
BackgroundFetchTestBase::CreateRequestWithProvidedResponse(
const std::string& method,
diff --git a/chromium/content/browser/background_fetch/background_fetch_test_base.h b/chromium/content/browser/background_fetch/background_fetch_test_base.h
index 7d2341b1bee..a2bcc7365bd 100644
--- a/chromium/content/browser/background_fetch/background_fetch_test_base.h
+++ b/chromium/content/browser/background_fetch/background_fetch_test_base.h
@@ -23,6 +23,7 @@
namespace content {
class ServiceWorkerRegistration;
+class StoragePartition;
// Base class containing common functionality needed in unit tests written for
// the Background Fetch feature.
@@ -44,6 +45,10 @@ class BackgroundFetchTestBase : public ::testing::Test {
// ServiceWorkerRegistration will be kept alive for the test's lifetime.
int64_t RegisterServiceWorker();
+ // Unregisters the test Service Worker and verifies that the unregistration
+ // succeeded.
+ void UnregisterServiceWorker();
+
// Creates a ServiceWorkerFetchRequest instance for the given details and
// provides a faked |response|.
ServiceWorkerFetchRequest CreateRequestWithProvidedResponse(
@@ -60,6 +65,9 @@ class BackgroundFetchTestBase : public ::testing::Test {
// Returns the browser context that should be used for the tests.
BrowserContext* browser_context() { return &browser_context_; }
+ // Returns the once-initialized default storage partition to be used in tests.
+ StoragePartition* storage_partition() { return storage_partition_; }
+
// Returns the origin that should be used for Background Fetch tests.
const url::Origin& origin() const { return origin_; }
@@ -75,6 +83,8 @@ class BackgroundFetchTestBase : public ::testing::Test {
url::Origin origin_;
+ StoragePartition* storage_partition_;
+
// Vector of ServiceWorkerRegistration instances that have to be kept alive
// for the lifetime of this test.
std::vector<scoped_refptr<ServiceWorkerRegistration>>
diff --git a/chromium/content/browser/background_fetch/background_fetch_test_data_manager.cc b/chromium/content/browser/background_fetch/background_fetch_test_data_manager.cc
new file mode 100644
index 00000000000..b081be6b97c
--- /dev/null
+++ b/chromium/content/browser/background_fetch/background_fetch_test_data_manager.cc
@@ -0,0 +1,76 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/background_fetch_test_data_manager.h"
+
+#include "content/browser/blob_storage/chrome_blob_storage_context.h"
+#include "content/browser/cache_storage/cache_storage_manager.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
+#include "storage/browser/blob/blob_storage_context.h"
+#include "storage/browser/test/mock_quota_manager.h"
+#include "storage/browser/test/mock_quota_manager_proxy.h"
+#include "storage/browser/test/mock_special_storage_policy.h"
+
+namespace content {
+
+namespace {
+
+class MockBGFQuotaManagerProxy : public MockQuotaManagerProxy {
+ public:
+ MockBGFQuotaManagerProxy(MockQuotaManager* quota_manager)
+ : MockQuotaManagerProxy(quota_manager,
+ base::ThreadTaskRunnerHandle::Get().get()) {}
+
+ // Ignore quota client, it is irrelevant for these tests.
+ void RegisterClient(QuotaClient* client) override {
+ delete client; // Directly delete, to avoid memory leak.
+ }
+
+ protected:
+ ~MockBGFQuotaManagerProxy() override = default;
+};
+
+} // namespace
+
+BackgroundFetchTestDataManager::BackgroundFetchTestDataManager(
+ BrowserContext* browser_context,
+ StoragePartition* storage_partition,
+ scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
+ bool mock_fill_response)
+ : BackgroundFetchDataManager(browser_context,
+ service_worker_context,
+ nullptr /* cache_storage_context */),
+ browser_context_(browser_context),
+ storage_partition_(storage_partition),
+ mock_fill_response_(mock_fill_response) {}
+
+void BackgroundFetchTestDataManager::InitializeOnIOThread() {
+ ChromeBlobStorageContext* blob_storage_context(
+ ChromeBlobStorageContext::GetFor(browser_context_));
+ // Wait for ChromeBlobStorageContext to finish initializing.
+ base::RunLoop().RunUntilIdle();
+
+ mock_quota_manager_ = base::MakeRefCounted<MockQuotaManager>(
+ storage_partition_->GetPath().empty(), storage_partition_->GetPath(),
+ base::ThreadTaskRunnerHandle::Get().get(),
+ base::MakeRefCounted<MockSpecialStoragePolicy>());
+ mock_quota_manager_->SetQuota(GURL("https://example.com/"),
+ StorageType::kTemporary, 1024 * 1024 * 100);
+
+ cache_manager_ = CacheStorageManager::Create(
+ storage_partition_->GetPath(), base::ThreadTaskRunnerHandle::Get(),
+ base::MakeRefCounted<MockBGFQuotaManagerProxy>(
+ mock_quota_manager_.get()));
+ DCHECK(cache_manager_);
+
+ cache_manager_->SetBlobParametersForCache(
+ storage_partition_->GetURLRequestContext(),
+ blob_storage_context->context()->AsWeakPtr());
+}
+
+BackgroundFetchTestDataManager::~BackgroundFetchTestDataManager() = default;
+
+} // namespace content
diff --git a/chromium/content/browser/background_fetch/background_fetch_test_data_manager.h b/chromium/content/browser/background_fetch/background_fetch_test_data_manager.h
new file mode 100644
index 00000000000..9596d3f84d8
--- /dev/null
+++ b/chromium/content/browser/background_fetch/background_fetch_test_data_manager.h
@@ -0,0 +1,51 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_TEST_DATA_MANAGER_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_TEST_DATA_MANAGER_H_
+
+#include <memory>
+
+#include "base/memory/scoped_refptr.h"
+#include "content/browser/background_fetch/background_fetch_data_manager.h"
+#include "content/browser/background_fetch/background_fetch_request_info.h"
+#include "url/origin.h"
+
+namespace content {
+
+class BrowserContext;
+class CacheStorageManager;
+class MockQuotaManager;
+class ServiceWorkerContextWrapper;
+class StoragePartition;
+
+// Test DataManager that sets up a CacheStorageManager suited for test
+// environments. Tests can also optionally override FillServiceWorkerResponse by
+// setting |mock_fill_response| to true.
+class BackgroundFetchTestDataManager : public BackgroundFetchDataManager {
+ public:
+ BackgroundFetchTestDataManager(
+ BrowserContext* browser_context,
+ StoragePartition* storage_partition,
+ scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
+ bool mock_fill_response = false);
+
+ ~BackgroundFetchTestDataManager() override;
+
+ void InitializeOnIOThread() override;
+
+ private:
+ friend class BackgroundFetchDataManagerTest;
+
+ scoped_refptr<MockQuotaManager> mock_quota_manager_;
+ BrowserContext* browser_context_;
+ StoragePartition* storage_partition_;
+ bool mock_fill_response_;
+
+ DISALLOW_COPY_AND_ASSIGN(BackgroundFetchTestDataManager);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_TEST_DATA_MANAGER_H_
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 753d955a839..72a098529cc 100644
--- a/chromium/content/browser/background_fetch/mock_background_fetch_delegate.cc
+++ b/chromium/content/browser/background_fetch/mock_background_fetch_delegate.cc
@@ -130,7 +130,8 @@ void MockBackgroundFetchDelegate::DownloadUrl(
&BackgroundFetchDelegate::Client::OnDownloadComplete, client(),
job_unique_id, guid,
std::make_unique<BackgroundFetchResult>(
- base::Time::Now(), response_path, test_response->data.size())));
+ base::Time::Now(), response_path,
+ base::nullopt /* blob_handle */, test_response->data.size())));
} else {
PostAbortCheckingTask(
job_unique_id,
@@ -148,6 +149,9 @@ void MockBackgroundFetchDelegate::Abort(const std::string& job_unique_id) {
aborted_jobs_.insert(job_unique_id);
}
+void MockBackgroundFetchDelegate::UpdateUI(const std::string& job_unique_id,
+ const std::string& title) {}
+
void MockBackgroundFetchDelegate::RegisterResponse(
const GURL& url,
std::unique_ptr<TestResponse> response) {
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 bc685f96a56..587f07116a5 100644
--- a/chromium/content/browser/background_fetch/mock_background_fetch_delegate.h
+++ b/chromium/content/browser/background_fetch/mock_background_fetch_delegate.h
@@ -74,6 +74,8 @@ class MockBackgroundFetchDelegate : public BackgroundFetchDelegate {
const net::NetworkTrafficAnnotationTag& traffic_annotation,
const net::HttpRequestHeaders& headers) override;
void Abort(const std::string& job_unique_id) override;
+ void UpdateUI(const std::string& job_unique_id,
+ const std::string& title) override;
void RegisterResponse(const GURL& url,
std::unique_ptr<TestResponse> response);
diff --git a/chromium/content/browser/background_fetch/storage/README.md b/chromium/content/browser/background_fetch/storage/README.md
index e21e9c327e9..a21b6bc1a03 100644
--- a/chromium/content/browser/background_fetch/storage/README.md
+++ b/chromium/content/browser/background_fetch/storage/README.md
@@ -45,6 +45,19 @@ key: "bgfetch_completed_request_<unique_id>_<request_index>"
value: "<serialized content::proto::BackgroundFetchCompletedRequest>"
```
+## Cache Storage UserData schema
+
+The downloaded responses of every fetch will be stored in their own private cache.
+
+### Cache identifiers
+* `origin`: `<origin>`
+* `owner`: `CacheStorageOwner::kBackgroundFetch`
+* `cache_name`: `<unique_id>`
+
+The cache will contain all the Request/Response key/value pairs of the fetch.
+Note that the Request value stored isn't comprehensive, and only the url value is
+used to as a key to find the matching Response.
+
### Expansions
* `<unique_id>` is a GUID (v4) that identifies a background fetch registration.
E.g. `17467386-60b4-4c5b-b66c-aabf793fd39b`
diff --git a/chromium/content/browser/background_fetch/storage/cleanup_task.cc b/chromium/content/browser/background_fetch/storage/cleanup_task.cc
index 047ec4b9015..8940c09d09d 100644
--- a/chromium/content/browser/background_fetch/storage/cleanup_task.cc
+++ b/chromium/content/browser/background_fetch/storage/cleanup_task.cc
@@ -8,9 +8,11 @@
#include "base/containers/flat_set.h"
#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/background_fetch/storage/delete_registration_task.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "url/origin.h"
namespace content {
@@ -20,8 +22,8 @@ namespace {
void EmptyErrorHandler(blink::mojom::BackgroundFetchError) {}
} // namespace
-CleanupTask::CleanupTask(BackgroundFetchDataManager* data_manager)
- : DatabaseTask(data_manager), weak_factory_(this) {}
+CleanupTask::CleanupTask(DatabaseTaskHost* host)
+ : DatabaseTask(host), weak_factory_(this) {}
CleanupTask::~CleanupTask() = default;
@@ -33,10 +35,10 @@ void CleanupTask::Start() {
void CleanupTask::DidGetRegistrations(
const std::vector<std::pair<int64_t, std::string>>& registration_data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
if (ToDatabaseStatus(status) != DatabaseStatus::kOk ||
registration_data.empty()) {
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
@@ -49,13 +51,13 @@ void CleanupTask::DidGetRegistrations(
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) {
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kOk:
case DatabaseStatus::kNotFound:
break;
case DatabaseStatus::kFailed:
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
@@ -78,17 +80,22 @@ void CleanupTask::DidGetActiveUniqueIds(
// 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,
+ data_manager(), service_worker_registration_id,
+ url::Origin::Create(GURL(metadata_proto.origin())), unique_id,
base::BindOnce(&EmptyErrorHandler)));
}
}
}
}
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
return;
}
+void CleanupTask::FinishWithError(blink::mojom::BackgroundFetchError error) {
+ Finished(); // Destroys |this|.
+}
+
} // 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
index 92db4ae4266..e116f789a39 100644
--- a/chromium/content/browser/background_fetch/storage/cleanup_task.h
+++ b/chromium/content/browser/background_fetch/storage/cleanup_task.h
@@ -10,7 +10,7 @@
#include <vector>
#include "content/browser/background_fetch/storage/database_task.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
@@ -20,7 +20,7 @@ namespace background_fetch {
// TODO(crbug.com/780025): Log failed deletions to UMA.
class CleanupTask : public background_fetch::DatabaseTask {
public:
- explicit CleanupTask(BackgroundFetchDataManager* data_manager);
+ explicit CleanupTask(DatabaseTaskHost* host);
~CleanupTask() override;
@@ -29,13 +29,14 @@ class CleanupTask : public background_fetch::DatabaseTask {
private:
void DidGetRegistrations(
const std::vector<std::pair<int64_t, std::string>>& registration_data,
- ServiceWorkerStatusCode status);
+ blink::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);
+ blink::ServiceWorkerStatusCode status);
+
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override;
base::WeakPtrFactory<CleanupTask> weak_factory_; // Keep as last.
diff --git a/chromium/content/browser/background_fetch/storage/create_metadata_task.cc b/chromium/content/browser/background_fetch/storage/create_metadata_task.cc
index c070e9f817b..07fdeb13d8a 100644
--- a/chromium/content/browser/background_fetch/storage/create_metadata_task.cc
+++ b/chromium/content/browser/background_fetch/storage/create_metadata_task.cc
@@ -6,25 +6,49 @@
#include <utility>
+#include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_traits.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"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
+#include "ui/gfx/image/image.h"
namespace content {
namespace background_fetch {
+namespace {
+
+std::string ConvertAndSerializeIcon(const SkBitmap& icon) {
+ // Serialize the icon and copy the bytes over.
+ std::string serialized_icon;
+ auto icon_bytes = gfx::Image::CreateFrom1xBitmap(icon).As1xPNGBytes();
+ serialized_icon.assign(icon_bytes->front_as<char>(),
+ icon_bytes->front_as<char>() + icon_bytes->size());
+ return serialized_icon;
+}
+
+} // namespace
+
+// The max icon resolution, this is used as a threshold to decide
+// whether the icon should be persisted.
+constexpr int kMaxIconResolution = 256 * 256;
+
CreateMetadataTask::CreateMetadataTask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
const BackgroundFetchRegistrationId& registration_id,
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
+ const SkBitmap& icon,
CreateMetadataCallback callback)
- : DatabaseTask(data_manager),
+ : DatabaseTask(host),
registration_id_(registration_id),
requests_(requests),
options_(options),
+ icon_(icon),
callback_(std::move(callback)),
weak_factory_(this) {}
@@ -39,46 +63,62 @@ void CreateMetadataTask::Start() {
}
void CreateMetadataTask::DidGetUniqueId(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kNotFound:
- StoreMetadata();
+ InitializeMetadataProto();
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 /* metadata */);
- Finished(); // Destroys |this|.
+ FinishWithError(
+ blink::mojom::BackgroundFetchError::DUPLICATED_DEVELOPER_ID);
return;
case DatabaseStatus::kFailed:
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR,
- nullptr /* metadata */);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
}
void CreateMetadataTask::InitializeMetadataProto() {
metadata_proto_ = std::make_unique<proto::BackgroundFetchMetadata>();
+
// Set BackgroundFetchRegistration fields.
- // Upload/Download stats default to correct initial values.
auto* registration_proto = metadata_proto_->mutable_registration();
registration_proto->set_unique_id(registration_id_.unique_id());
registration_proto->set_developer_id(registration_id_.developer_id());
+ registration_proto->set_download_total(options_.download_total);
// Set Options fields.
auto* options_proto = metadata_proto_->mutable_options();
options_proto->set_title(options_.title);
options_proto->set_download_total(options_.download_total);
for (const auto& icon : options_.icons) {
- auto* icon_definition_proto = options_proto->add_icons();
- icon_definition_proto->set_src(icon.src);
- icon_definition_proto->set_sizes(icon.sizes);
- icon_definition_proto->set_type(icon.type);
+ auto* image_resource_proto = options_proto->add_icons();
+
+ image_resource_proto->set_src(icon.src.spec());
+
+ for (const auto& size : icon.sizes) {
+ auto* size_proto = image_resource_proto->add_sizes();
+ size_proto->set_width(size.width());
+ size_proto->set_height(size.height());
+ }
+
+ image_resource_proto->set_type(base::UTF16ToASCII(icon.type));
+
+ for (const auto& purpose : icon.purpose) {
+ switch (purpose) {
+ case blink::Manifest::ImageResource::Purpose::ANY:
+ image_resource_proto->add_purpose(
+ proto::BackgroundFetchOptions_ImageResource_Purpose_ANY);
+ break;
+ case blink::Manifest::ImageResource::Purpose::BADGE:
+ image_resource_proto->add_purpose(
+ proto::BackgroundFetchOptions_ImageResource_Purpose_BADGE);
+ break;
+ }
+ }
}
// Set other metadata fields.
@@ -86,20 +126,40 @@ void CreateMetadataTask::InitializeMetadataProto() {
metadata_proto_->set_creation_microseconds_since_unix_epoch(
(base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds());
metadata_proto_->set_num_fetches(requests_.size());
+
+ // Check if |icon_| should be persisted.
+ if (icon_.height() * icon_.width() > kMaxIconResolution) {
+ StoreMetadata();
+ return;
+ }
+
+ // Do the initialization on a seperate thread to avoid blocking on
+ // expensive operations (image conversions), then post back to IO thread
+ // and continue normally.
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE,
+ {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
+ base::TaskPriority::BACKGROUND},
+ base::BindOnce(&ConvertAndSerializeIcon, icon_),
+ base::BindOnce(&CreateMetadataTask::StoreIcon,
+ weak_factory_.GetWeakPtr()));
+}
+
+void CreateMetadataTask::StoreIcon(std::string serialized_icon) {
+ DCHECK(metadata_proto_);
+ metadata_proto_->set_icon(std::move(serialized_icon));
+ StoreMetadata();
}
void CreateMetadataTask::StoreMetadata() {
+ DCHECK(metadata_proto_);
std::vector<std::pair<std::string, std::string>> entries;
entries.reserve(requests_.size() * 2 + 1);
- InitializeMetadataProto();
std::string serialized_metadata_proto;
if (!metadata_proto_->SerializeToString(&serialized_metadata_proto)) {
- // TODO(crbug.com/780025): Log failures to UMA.
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::STORAGE_ERROR,
- nullptr /* metadata */);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
@@ -123,29 +183,32 @@ void CreateMetadataTask::StoreMetadata() {
service_worker_context()->StoreRegistrationUserData(
registration_id_.service_worker_registration_id(),
registration_id_.origin().GetURL(), entries,
- base::BindRepeating(&CreateMetadataTask::DidStoreMetadata,
- weak_factory_.GetWeakPtr()));
+ base::BindOnce(&CreateMetadataTask::DidStoreMetadata,
+ weak_factory_.GetWeakPtr()));
}
-void CreateMetadataTask::DidStoreMetadata(ServiceWorkerStatusCode status) {
- DCHECK(metadata_proto_);
-
+void CreateMetadataTask::DidStoreMetadata(
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kOk:
break;
case DatabaseStatus::kFailed:
case DatabaseStatus::kNotFound:
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR,
- nullptr /* metadata */);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE,
- std::move(metadata_proto_));
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
+}
+
+void CreateMetadataTask::FinishWithError(
+ blink::mojom::BackgroundFetchError error) {
+ if (error != blink::mojom::BackgroundFetchError::NONE)
+ metadata_proto_.reset();
+ std::move(callback_).Run(error, std::move(metadata_proto_));
Finished(); // Destroys |this|.
}
+
} // namespace background_fetch
} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/create_metadata_task.h b/chromium/content/browser/background_fetch/storage/create_metadata_task.h
index 433c265c38a..48bc0d59541 100644
--- a/chromium/content/browser/background_fetch/storage/create_metadata_task.h
+++ b/chromium/content/browser/background_fetch/storage/create_metadata_task.h
@@ -11,8 +11,9 @@
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/storage/database_task.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
+#include "third_party/skia/include/core/SkBitmap.h"
namespace content {
@@ -25,10 +26,11 @@ class CreateMetadataTask : public DatabaseTask {
base::OnceCallback<void(blink::mojom::BackgroundFetchError,
std::unique_ptr<proto::BackgroundFetchMetadata>)>;
- CreateMetadataTask(BackgroundFetchDataManager* data_manager,
+ CreateMetadataTask(DatabaseTaskHost* host,
const BackgroundFetchRegistrationId& registration_id,
const std::vector<ServiceWorkerFetchRequest>& requests,
const BackgroundFetchOptions& options,
+ const SkBitmap& icon,
CreateMetadataCallback callback);
~CreateMetadataTask() override;
@@ -37,17 +39,23 @@ class CreateMetadataTask : public DatabaseTask {
private:
void DidGetUniqueId(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
+
+ void StoreIcon(std::string serialized_icon);
void StoreMetadata();
- void DidStoreMetadata(ServiceWorkerStatusCode status);
+ void DidStoreMetadata(
+ blink::ServiceWorkerStatusCode status);
void InitializeMetadataProto();
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override;
+
BackgroundFetchRegistrationId registration_id_;
std::vector<ServiceWorkerFetchRequest> requests_;
BackgroundFetchOptions options_;
+ SkBitmap icon_;
CreateMetadataCallback callback_;
std::unique_ptr<proto::BackgroundFetchMetadata> metadata_proto_;
diff --git a/chromium/content/browser/background_fetch/storage/database_helpers.cc b/chromium/content/browser/background_fetch/storage/database_helpers.cc
index cb8348e731c..4e4fadf265c 100644
--- a/chromium/content/browser/background_fetch/storage/database_helpers.cc
+++ b/chromium/content/browser/background_fetch/storage/database_helpers.cc
@@ -52,36 +52,35 @@ std::string CompletedRequestKey(const std::string& unique_id,
return CompletedRequestKeyPrefix(unique_id) + std::to_string(request_index);
}
-DatabaseStatus ToDatabaseStatus(ServiceWorkerStatusCode status) {
+DatabaseStatus ToDatabaseStatus(blink::ServiceWorkerStatusCode status) {
switch (status) {
- case SERVICE_WORKER_OK:
+ case blink::ServiceWorkerStatusCode::kOk:
return DatabaseStatus::kOk;
- case SERVICE_WORKER_ERROR_FAILED:
- case SERVICE_WORKER_ERROR_ABORT:
+ case blink::ServiceWorkerStatusCode::kErrorFailed:
+ case blink::ServiceWorkerStatusCode::kErrorAbort:
// 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:
+ case blink::ServiceWorkerStatusCode::kErrorNotFound:
// 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:
+ case blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorProcessNotFound:
+ case blink::ServiceWorkerStatusCode::kErrorExists:
+ case blink::ServiceWorkerStatusCode::kErrorInstallWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorActivateWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorIpcFailed:
+ case blink::ServiceWorkerStatusCode::kErrorNetwork:
+ case blink::ServiceWorkerStatusCode::kErrorSecurity:
+ case blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected:
+ case blink::ServiceWorkerStatusCode::kErrorState:
+ case blink::ServiceWorkerStatusCode::kErrorTimeout:
+ case blink::ServiceWorkerStatusCode::kErrorScriptEvaluateFailed:
+ case blink::ServiceWorkerStatusCode::kErrorDiskCache:
+ case blink::ServiceWorkerStatusCode::kErrorRedundant:
+ case blink::ServiceWorkerStatusCode::kErrorDisallowed:
break;
}
NOTREACHED();
diff --git a/chromium/content/browser/background_fetch/storage/database_helpers.h b/chromium/content/browser/background_fetch/storage/database_helpers.h
index c81874378ce..a9741fe283c 100644
--- a/chromium/content/browser/background_fetch/storage/database_helpers.h
+++ b/chromium/content/browser/background_fetch/storage/database_helpers.h
@@ -7,8 +7,8 @@
#include <string>
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
@@ -50,7 +50,7 @@ std::string CompletedRequestKey(const std::string& unique_id,
enum class DatabaseStatus { kOk, kFailed, kNotFound };
-DatabaseStatus ToDatabaseStatus(ServiceWorkerStatusCode status);
+DatabaseStatus ToDatabaseStatus(blink::ServiceWorkerStatusCode status);
} // namespace background_fetch
diff --git a/chromium/content/browser/background_fetch/storage/database_task.cc b/chromium/content/browser/background_fetch/storage/database_task.cc
index d8139c4b842..62a5a758c1e 100644
--- a/chromium/content/browser/background_fetch/storage/database_task.cc
+++ b/chromium/content/browser/background_fetch/storage/database_task.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "content/browser/background_fetch/background_fetch_data_manager.h"
+#include "content/browser/background_fetch/background_fetch_data_manager_observer.h"
#include "content/browser/background_fetch/storage/database_helpers.h"
#include "content/public/browser/browser_thread.h"
@@ -14,23 +15,72 @@ namespace content {
namespace background_fetch {
+DatabaseTaskHost::DatabaseTaskHost() : weak_factory_(this) {}
+
+DatabaseTaskHost::~DatabaseTaskHost() = default;
+
+base::WeakPtr<DatabaseTaskHost> DatabaseTaskHost::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
+DatabaseTask::DatabaseTask(DatabaseTaskHost* host) : host_(host) {
+ DCHECK(host_);
+ // Hold a reference to the CacheStorageManager.
+ cache_manager_ = data_manager()->cache_manager();
+}
+
+DatabaseTask::~DatabaseTask() = default;
+
void DatabaseTask::Finished() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // Post the OnTaskFinished callback to the same thread, to allow the the
+ // DatabaseTask to finish execution before deallocating it.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(&DatabaseTaskHost::OnTaskFinished,
+ host_->GetWeakPtr(), this));
+}
- data_manager_->OnDatabaseTaskFinished(this);
+void DatabaseTask::OnTaskFinished(DatabaseTask* finished_subtask) {
+ size_t erased = active_subtasks_.erase(finished_subtask);
+ DCHECK_EQ(erased, 1u);
}
void DatabaseTask::AddDatabaseTask(std::unique_ptr<DatabaseTask> task) {
- data_manager_->AddDatabaseTask(std::move(task));
+ DCHECK_EQ(task->host_, data_manager());
+ data_manager()->AddDatabaseTask(std::move(task));
+}
+
+void DatabaseTask::AddSubTask(std::unique_ptr<DatabaseTask> task) {
+ DCHECK_EQ(task->host_, this);
+ auto insert_result = active_subtasks_.emplace(task.get(), std::move(task));
+ insert_result.first->second->Start(); // Start the subtask.
+}
+
+void DatabaseTask::AbandonFetches(int64_t service_worker_registration_id) {
+ for (auto& observer : data_manager()->observers())
+ observer.OnServiceWorkerDatabaseCorrupted(service_worker_registration_id);
}
ServiceWorkerContextWrapper* DatabaseTask::service_worker_context() {
- DCHECK(data_manager_->service_worker_context_);
- return data_manager_->service_worker_context_.get();
+ DCHECK(data_manager()->service_worker_context());
+ return data_manager()->service_worker_context();
+}
+
+CacheStorageManager* DatabaseTask::cache_manager() {
+ DCHECK(cache_manager_);
+ return cache_manager_.get();
}
std::set<std::string>& DatabaseTask::ref_counted_unique_ids() {
- return data_manager_->ref_counted_unique_ids_;
+ return data_manager()->ref_counted_unique_ids();
+}
+
+ChromeBlobStorageContext* DatabaseTask::blob_storage_context() {
+ return data_manager()->blob_storage_context();
+}
+
+BackgroundFetchDataManager* DatabaseTask::data_manager() {
+ return host_->data_manager();
}
} // namespace background_fetch
diff --git a/chromium/content/browser/background_fetch/storage/database_task.h b/chromium/content/browser/background_fetch/storage/database_task.h
index 3d46a0fb358..3d5742cfa6e 100644
--- a/chromium/content/browser/background_fetch/storage/database_task.h
+++ b/chromium/content/browser/background_fetch/storage/database_task.h
@@ -11,12 +11,16 @@
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
#include "content/browser/background_fetch/background_fetch_registration_id.h"
+#include "content/browser/cache_storage/cache_storage_manager.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
namespace content {
class BackgroundFetchDataManager;
+class CacheStorageManager;
+class ChromeBlobStorageContext;
class ServiceWorkerContextWrapper;
// Note that this also handles non-error cases where the NONE is NONE.
@@ -25,6 +29,26 @@ using HandleBackgroundFetchErrorCallback =
namespace background_fetch {
+class DatabaseTask;
+
+// A DatabaseTaskHost is the entity responsible for scheduling and running
+// DatabaseTasks, usually the BackgroundFetchDataManager. Note that a
+// DatabaseTask can be a DatabaseTaskHost, in order to run subtasks.
+class DatabaseTaskHost {
+ public:
+ virtual void OnTaskFinished(DatabaseTask* task) = 0;
+ virtual BackgroundFetchDataManager* data_manager() = 0;
+ virtual ~DatabaseTaskHost();
+
+ base::WeakPtr<DatabaseTaskHost> GetWeakPtr();
+
+ protected:
+ DatabaseTaskHost();
+
+ private:
+ base::WeakPtrFactory<DatabaseTaskHost> weak_factory_;
+};
+
// A DatabaseTask is an asynchronous "transaction" that needs to read/write the
// Service Worker Database.
//
@@ -32,32 +56,57 @@ namespace background_fetch {
// 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 {
+//
+// A DatabaseTask can also optionally run other DatabaseTasks as subtasks. This
+// allows us to re-use commonly used DatabaseTasks. Subtasks are started as soon
+// as they are added, and cannot outlive the parent DatabaseTask.
+class DatabaseTask : public DatabaseTaskHost {
public:
- virtual ~DatabaseTask() = default;
+ ~DatabaseTask() override;
virtual void Start() = 0;
protected:
- explicit DatabaseTask(BackgroundFetchDataManager* data_manager)
- : data_manager_(data_manager) {
- DCHECK(data_manager_);
- }
+ explicit DatabaseTask(DatabaseTaskHost* host);
// Each task MUST call this once finished, even if exceptions occur, to
// release their lock and allow the next task to execute.
+ // This should be called in FinishWithError() for consistency.
void Finished();
void AddDatabaseTask(std::unique_ptr<DatabaseTask> task);
+ void AddSubTask(std::unique_ptr<DatabaseTask> task);
+
+ // Abandon all fetches for a given service worker.
+ void AbandonFetches(int64_t service_worker_registration_id);
ServiceWorkerContextWrapper* service_worker_context();
+ CacheStorageManager* cache_manager();
+
std::set<std::string>& ref_counted_unique_ids();
- BackgroundFetchDataManager* data_manager() { return data_manager_; }
+ ChromeBlobStorageContext* blob_storage_context();
+
+ // DatabaseTaskHost implementation.
+ void OnTaskFinished(DatabaseTask* finished_subtask) override;
+ BackgroundFetchDataManager* data_manager() override;
private:
- BackgroundFetchDataManager* data_manager_; // Owns this.
+ // Each task must override this function and perform the following steps:
+ // 1) Report error (UMA) if applicable.
+ // 2) Run the provided callback.
+ // 3) Call Finished().
+ virtual void FinishWithError(blink::mojom::BackgroundFetchError error) = 0;
+
+ DatabaseTaskHost* host_;
+
+ // Owns a reference to the CacheStorageManager in case Shutdown was
+ // called and the DatabaseTask needs to finish.
+ scoped_refptr<CacheStorageManager> cache_manager_;
+
+ // Map the raw pointer to its unique_ptr, to make lookups easier.
+ std::map<DatabaseTask*, std::unique_ptr<DatabaseTask>> active_subtasks_;
DISALLOW_COPY_AND_ASSIGN(DatabaseTask);
};
diff --git a/chromium/content/browser/background_fetch/storage/delete_registration_task.cc b/chromium/content/browser/background_fetch/storage/delete_registration_task.cc
index e5c2d759758..5734680a96d 100644
--- a/chromium/content/browser/background_fetch/storage/delete_registration_task.cc
+++ b/chromium/content/browser/background_fetch/storage/delete_registration_task.cc
@@ -6,8 +6,11 @@
#include <utility>
+#include "base/barrier_closure.h"
#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/cache_storage/cache_storage_manager.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
namespace content {
@@ -21,7 +24,7 @@ namespace {
// been already marked for deletion.
void DCheckRegistrationNotActive(const std::string& unique_id,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kOk:
DCHECK_EQ(1u, data.size());
@@ -38,12 +41,14 @@ void DCheckRegistrationNotActive(const std::string& unique_id,
} // namespace
DeleteRegistrationTask::DeleteRegistrationTask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
int64_t service_worker_registration_id,
+ const url::Origin& origin,
const std::string& unique_id,
HandleBackgroundFetchErrorCallback callback)
- : DatabaseTask(data_manager),
+ : DatabaseTask(host),
service_worker_registration_id_(service_worker_registration_id),
+ origin_(origin),
unique_id_(unique_id),
callback_(std::move(callback)),
weak_factory_(this) {}
@@ -51,20 +56,34 @@ DeleteRegistrationTask::DeleteRegistrationTask(
DeleteRegistrationTask::~DeleteRegistrationTask() = default;
void DeleteRegistrationTask::Start() {
+ base::RepeatingClosure barrier_closure = base::BarrierClosure(
+ 2u, base::BindOnce(
+ [](base::WeakPtr<DeleteRegistrationTask> task) {
+ if (task)
+ task->FinishWithError(task->error_);
+ },
+ weak_factory_.GetWeakPtr()));
+
#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::BindOnce(&DeleteRegistrationTask::DidGetRegistration,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr(), barrier_closure));
#else
- DidGetRegistration({}, SERVICE_WORKER_OK);
+ DidGetRegistration(barrier_closure, {}, blink::ServiceWorkerStatusCode::kOk);
#endif // DCHECK_IS_ON()
+
+ cache_manager()->DeleteCache(
+ origin_, CacheStorageOwner::kBackgroundFetch, unique_id_ /* cache_name */,
+ base::BindOnce(&DeleteRegistrationTask::DidDeleteCache,
+ weak_factory_.GetWeakPtr(), barrier_closure));
}
void DeleteRegistrationTask::DidGetRegistration(
+ base::OnceClosure done_closure,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
#if DCHECK_IS_ON()
if (ToDatabaseStatus(status) == DatabaseStatus::kOk) {
DCHECK_EQ(1u, data.size());
@@ -77,35 +96,55 @@ void DeleteRegistrationTask::DidGetRegistration(
metadata_proto.registration().developer_id())},
base::BindOnce(&DCheckRegistrationNotActive, unique_id_));
} else {
- NOTREACHED()
- << "Database is corrupt"; // TODO(crbug.com/780027): Nuke it.
+ // Service worker database has been corrupted. Abandon all fetches.
+ error_ = blink::mojom::BackgroundFetchError::STORAGE_ERROR;
+ AbandonFetches(service_worker_registration_id_);
+ std::move(done_closure).Run();
}
} else {
// TODO(crbug.com/780025): Log failure to UMA.
}
#endif // DCHECK_IS_ON()
+ std::vector<std::string> deletion_key_prefixes{
+ RegistrationKey(unique_id_), TitleKey(unique_id_),
+ PendingRequestKeyPrefix(unique_id_), ActiveRequestKeyPrefix(unique_id_),
+ CompletedRequestKeyPrefix(unique_id_)};
+
service_worker_context()->ClearRegistrationUserDataByKeyPrefixes(
- service_worker_registration_id_,
- {RegistrationKey(unique_id_), TitleKey(unique_id_)},
+ service_worker_registration_id_, std::move(deletion_key_prefixes),
base::BindOnce(&DeleteRegistrationTask::DidDeleteRegistration,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr(), std::move(done_closure)));
}
void DeleteRegistrationTask::DidDeleteRegistration(
- ServiceWorkerStatusCode status) {
+ base::OnceClosure done_closure,
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kOk:
case DatabaseStatus::kNotFound:
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE);
- Finished(); // Destroys |this|.
- return;
+ break;
case DatabaseStatus::kFailed:
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR);
- Finished(); // Destroys |this|.
- return;
+ error_ = blink::mojom::BackgroundFetchError::STORAGE_ERROR;
+ break;
}
+ std::move(done_closure).Run();
+}
+
+void DeleteRegistrationTask::DidDeleteCache(
+ base::OnceClosure done_closure,
+ blink::mojom::CacheStorageError error) {
+ if (error != blink::mojom::CacheStorageError::kSuccess &&
+ error != blink::mojom::CacheStorageError::kErrorNotFound) {
+ error_ = blink::mojom::BackgroundFetchError::STORAGE_ERROR;
+ }
+ std::move(done_closure).Run();
+}
+
+void DeleteRegistrationTask::FinishWithError(
+ blink::mojom::BackgroundFetchError error) {
+ std::move(callback_).Run(error);
+ Finished(); // Destroys |this|.
}
} // namespace background_fetch
diff --git a/chromium/content/browser/background_fetch/storage/delete_registration_task.h b/chromium/content/browser/background_fetch/storage/delete_registration_task.h
index 4ac2bb5da35..b25a7d19955 100644
--- a/chromium/content/browser/background_fetch/storage/delete_registration_task.h
+++ b/chromium/content/browser/background_fetch/storage/delete_registration_task.h
@@ -9,7 +9,9 @@
#include <vector>
#include "content/browser/background_fetch/storage/database_task.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h"
+#include "url/origin.h"
namespace content {
@@ -18,8 +20,9 @@ namespace background_fetch {
// Deletes Background Fetch registration entries from the database.
class DeleteRegistrationTask : public background_fetch::DatabaseTask {
public:
- DeleteRegistrationTask(BackgroundFetchDataManager* data_manager,
+ DeleteRegistrationTask(DatabaseTaskHost* host,
int64_t service_worker_registration_id,
+ const url::Origin& origin,
const std::string& unique_id,
HandleBackgroundFetchErrorCallback callback);
@@ -28,15 +31,27 @@ class DeleteRegistrationTask : public background_fetch::DatabaseTask {
void Start() override;
private:
- void DidGetRegistration(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ void DidGetRegistration(base::OnceClosure done_closure,
+ const std::vector<std::string>& data,
+ blink::ServiceWorkerStatusCode status);
- void DidDeleteRegistration(ServiceWorkerStatusCode status);
+ void DidDeleteRegistration(base::OnceClosure done_closure,
+ blink::ServiceWorkerStatusCode status);
+
+ void DidDeleteCache(base::OnceClosure done_closure,
+ blink::mojom::CacheStorageError error);
+
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override;
int64_t service_worker_registration_id_;
+ url::Origin origin_;
std::string unique_id_;
HandleBackgroundFetchErrorCallback callback_;
+ // The error to report once all async work is completed.
+ blink::mojom::BackgroundFetchError error_ =
+ blink::mojom::BackgroundFetchError::NONE;
+
base::WeakPtrFactory<DeleteRegistrationTask> weak_factory_; // Keep as last.
DISALLOW_COPY_AND_ASSIGN(DeleteRegistrationTask);
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
index 03b9c849ee6..1f170218d83 100644
--- a/chromium/content/browser/background_fetch/storage/get_developer_ids_task.cc
+++ b/chromium/content/browser/background_fetch/storage/get_developer_ids_task.cc
@@ -14,11 +14,11 @@ namespace content {
namespace background_fetch {
GetDeveloperIdsTask::GetDeveloperIdsTask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
int64_t service_worker_registration_id,
const url::Origin& origin,
blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback)
- : DatabaseTask(data_manager),
+ : DatabaseTask(host),
service_worker_registration_id_(service_worker_registration_id),
origin_(origin),
callback_(std::move(callback)),
@@ -35,26 +35,27 @@ void GetDeveloperIdsTask::Start() {
void GetDeveloperIdsTask::DidGetUniqueIds(
const base::flat_map<std::string, std::string>& data_map,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kNotFound:
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE,
- {} /* No results */);
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
break;
case DatabaseStatus::kOk: {
- auto ids = std::vector<std::string>();
- ids.reserve(data_map.size());
+ developer_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);
+ developer_ids_.push_back(pair.first);
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
break;
}
case DatabaseStatus::kFailed:
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR,
- {} /* No results */);
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
break;
}
+}
+
+void GetDeveloperIdsTask::FinishWithError(
+ blink::mojom::BackgroundFetchError error) {
+ std::move(callback_).Run(error, std::move(developer_ids_));
Finished(); // Destroys |this|.
}
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
index b205c712794..e9db0880fcc 100644
--- a/chromium/content/browser/background_fetch/storage/get_developer_ids_task.h
+++ b/chromium/content/browser/background_fetch/storage/get_developer_ids_task.h
@@ -11,7 +11,7 @@
#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/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
#include "url/origin.h"
@@ -24,7 +24,7 @@ namespace background_fetch {
class GetDeveloperIdsTask : public DatabaseTask {
public:
GetDeveloperIdsTask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
int64_t service_worker_registration_id,
const url::Origin& origin,
blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback);
@@ -36,13 +36,17 @@ class GetDeveloperIdsTask : public DatabaseTask {
private:
void DidGetUniqueIds(const base::flat_map<std::string, std::string>& data_map,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
+
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override;
int64_t service_worker_registration_id_;
url::Origin origin_;
blink::mojom::BackgroundFetchService::GetDeveloperIdsCallback callback_;
+ std::vector<std::string> developer_ids_;
+
base::WeakPtrFactory<GetDeveloperIdsTask> weak_factory_; // Keep as last.
DISALLOW_COPY_AND_ASSIGN(GetDeveloperIdsTask);
diff --git a/chromium/content/browser/background_fetch/storage/get_initialization_data_task.cc b/chromium/content/browser/background_fetch/storage/get_initialization_data_task.cc
new file mode 100644
index 00000000000..10db38fcd96
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/get_initialization_data_task.cc
@@ -0,0 +1,536 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/background_fetch/storage/get_initialization_data_task.h"
+
+#include "base/barrier_closure.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_traits.h"
+#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/background_fetch/storage/mark_registration_for_deletion_task.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "third_party/blink/public/common/manifest/manifest.h"
+#include "ui/gfx/image/image.h"
+#include "url/origin.h"
+
+namespace content {
+
+namespace background_fetch {
+
+namespace {
+
+// Base class with all the common implementation for the SubTasks
+// needed in this file.
+class InitializationSubTask : public DatabaseTask {
+ public:
+ // Holds data used by all SubTasks.
+ struct SubTaskInit {
+ SubTaskInit() = delete;
+ ~SubTaskInit() = default;
+
+ // Service Worker Database metadata.
+ int64_t service_worker_registration_id;
+ std::string unique_id;
+
+ // The results to report.
+ BackgroundFetchInitializationData* initialization_data;
+ };
+
+ InitializationSubTask(DatabaseTaskHost* host,
+ const SubTaskInit& sub_task_init,
+ base::OnceClosure done_closure)
+ : DatabaseTask(host),
+ sub_task_init_(sub_task_init),
+ done_closure_(std::move(done_closure)) {
+ DCHECK(sub_task_init_.initialization_data);
+ }
+
+ ~InitializationSubTask() override = default;
+
+ protected:
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override {
+ if (error != blink::mojom::BackgroundFetchError::NONE)
+ sub_task_init_.initialization_data->error = error;
+ std::move(done_closure_).Run();
+ Finished(); // Destroys |this|.
+ }
+
+ SubTaskInit& sub_task_init() { return sub_task_init_; }
+
+ private:
+ SubTaskInit sub_task_init_;
+ base::OnceClosure done_closure_;
+
+ DISALLOW_COPY_AND_ASSIGN(InitializationSubTask);
+};
+
+// Fills the BackgroundFetchInitializationData with the most recent UI title.
+class GetTitleTask : public InitializationSubTask {
+ public:
+ GetTitleTask(DatabaseTaskHost* host,
+ const SubTaskInit& sub_task_init,
+ base::OnceClosure done_closure)
+ : InitializationSubTask(host, sub_task_init, std::move(done_closure)),
+ weak_factory_(this) {}
+
+ ~GetTitleTask() override = default;
+
+ void Start() override {
+ service_worker_context()->GetRegistrationUserData(
+ sub_task_init().service_worker_registration_id,
+ {TitleKey(sub_task_init().unique_id)},
+ base::BindOnce(&GetTitleTask::DidGetTitle, weak_factory_.GetWeakPtr()));
+ }
+
+ private:
+ void DidGetTitle(const std::vector<std::string>& data,
+ blink::ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kFailed:
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ case DatabaseStatus::kNotFound:
+ case DatabaseStatus::kOk:
+ break;
+ }
+
+ if (!data.empty())
+ sub_task_init().initialization_data->ui_title = data.front();
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
+ }
+
+ base::WeakPtrFactory<GetTitleTask> weak_factory_; // Keep as last.
+};
+
+// Gets the number of completed fetches, the number of active fetches,
+// and deletes inconsistencies in state transitions.
+// 1. Get all completed requests.
+// 2. Delete matching active requests.
+// 3. Get active requests.
+// 4. Delete matching pending requests.
+class GetRequestsTask : public InitializationSubTask {
+ public:
+ GetRequestsTask(DatabaseTaskHost* host,
+ const SubTaskInit& sub_task_init,
+ base::OnceClosure done_closure)
+ : InitializationSubTask(host, sub_task_init, std::move(done_closure)),
+ weak_factory_(this) {}
+
+ ~GetRequestsTask() override = default;
+
+ void Start() override {
+ service_worker_context()->GetRegistrationUserDataByKeyPrefix(
+ sub_task_init().service_worker_registration_id,
+ CompletedRequestKeyPrefix(sub_task_init().unique_id),
+ base::BindOnce(&GetRequestsTask::DidGetCompletedRequests,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ private:
+ void DidGetCompletedRequests(const std::vector<std::string>& data,
+ blink::ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kFailed:
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ case DatabaseStatus::kNotFound:
+ case DatabaseStatus::kOk:
+ break;
+ }
+
+ sub_task_init().initialization_data->num_completed_requests = data.size();
+
+ std::vector<std::string> active_requests_to_delete;
+ active_requests_to_delete.reserve(data.size());
+ for (const std::string& serialized_completed_request : data) {
+ proto::BackgroundFetchCompletedRequest completed_request;
+ if (!completed_request.ParseFromString(serialized_completed_request) ||
+ sub_task_init().unique_id != completed_request.unique_id()) {
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ }
+
+ active_requests_to_delete.push_back(ActiveRequestKey(
+ completed_request.unique_id(), completed_request.request_index()));
+ }
+
+ if (active_requests_to_delete.empty()) {
+ DidClearActiveRequests(blink::ServiceWorkerStatusCode::kOk);
+ return;
+ }
+
+ service_worker_context()->ClearRegistrationUserData(
+ sub_task_init().service_worker_registration_id,
+ std::move(active_requests_to_delete),
+ base::BindOnce(&GetRequestsTask::DidClearActiveRequests,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ void DidClearActiveRequests(blink::ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kFailed:
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ case DatabaseStatus::kNotFound:
+ case DatabaseStatus::kOk:
+ break;
+ }
+
+ service_worker_context()->GetRegistrationUserDataByKeyPrefix(
+ sub_task_init().service_worker_registration_id,
+ ActiveRequestKeyPrefix(sub_task_init().unique_id),
+ base::BindOnce(&GetRequestsTask::DidGetRemainingActiveRequests,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ void DidGetRemainingActiveRequests(const std::vector<std::string>& data,
+ blink::ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kFailed:
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ case DatabaseStatus::kNotFound:
+ case DatabaseStatus::kOk:
+ break;
+ }
+
+ std::vector<std::string> pending_requests_to_delete;
+ pending_requests_to_delete.reserve(data.size());
+ for (const std::string& serialized_active_request : data) {
+ proto::BackgroundFetchActiveRequest active_request;
+ if (!active_request.ParseFromString(serialized_active_request)) {
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ }
+ DCHECK_EQ(sub_task_init().unique_id, active_request.unique_id());
+ sub_task_init().initialization_data->active_fetch_guids.push_back(
+ active_request.download_guid());
+ pending_requests_to_delete.push_back(PendingRequestKey(
+ active_request.unique_id(), active_request.request_index()));
+ }
+
+ if (pending_requests_to_delete.empty()) {
+ DidClearPendingRequests(blink::ServiceWorkerStatusCode::kOk);
+ return;
+ }
+
+ service_worker_context()->ClearRegistrationUserData(
+ sub_task_init().service_worker_registration_id,
+ std::move(pending_requests_to_delete),
+ base::BindOnce(&GetRequestsTask::DidClearPendingRequests,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ void DidClearPendingRequests(blink::ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kFailed:
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ case DatabaseStatus::kNotFound:
+ case DatabaseStatus::kOk:
+ break;
+ }
+
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
+ }
+
+ base::WeakPtrFactory<GetRequestsTask> weak_factory_; // Keep as last.
+
+ DISALLOW_COPY_AND_ASSIGN(GetRequestsTask);
+};
+
+// Deserializes the icon and creates an SkBitmap from it.
+class DeserializeIconTask : public InitializationSubTask {
+ public:
+ DeserializeIconTask(DatabaseTaskHost* host,
+ const SubTaskInit& sub_task_init,
+ base::OnceClosure done_closure,
+ std::string* serialized_icon)
+ : InitializationSubTask(host, sub_task_init, std::move(done_closure)),
+ serialized_icon_(serialized_icon),
+ weak_factory_(this) {}
+
+ ~DeserializeIconTask() override = default;
+
+ void Start() override {
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE,
+ {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
+ base::TaskPriority::BACKGROUND},
+ base::BindOnce(&DeserializeIcon, std::move(serialized_icon_)),
+ base::BindOnce(&DeserializeIconTask::StoreIcon,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ private:
+ static SkBitmap DeserializeIcon(
+ std::unique_ptr<std::string> serialized_icon) {
+ return gfx::Image::CreateFrom1xPNGBytes(
+ reinterpret_cast<const unsigned char*>(serialized_icon->c_str()),
+ serialized_icon->size())
+ .AsBitmap();
+ }
+
+ void StoreIcon(SkBitmap icon) {
+ sub_task_init().initialization_data->icon = std::move(icon);
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
+ }
+
+ std::unique_ptr<std::string> serialized_icon_;
+
+ base::WeakPtrFactory<DeserializeIconTask> weak_factory_; // Keep as last.
+};
+
+// Fills the BackgroundFetchInitializationData with all the relevant information
+// stored in the BackgroundFetchMetadata proto.
+class FillFromMetadataTask : public InitializationSubTask {
+ public:
+ FillFromMetadataTask(DatabaseTaskHost* host,
+ const SubTaskInit& sub_task_init,
+ base::OnceClosure done_closure)
+ : InitializationSubTask(host, sub_task_init, std::move(done_closure)),
+ weak_factory_(this) {}
+
+ ~FillFromMetadataTask() override = default;
+
+ void Start() override {
+ service_worker_context()->GetRegistrationUserDataByKeyPrefix(
+ sub_task_init().service_worker_registration_id,
+ {RegistrationKey(sub_task_init().unique_id)},
+ base::BindOnce(&FillFromMetadataTask::DidGetMetadata,
+ weak_factory_.GetWeakPtr()));
+ }
+
+ private:
+ void DidGetMetadata(const std::vector<std::string>& data,
+ blink::ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kFailed:
+ case DatabaseStatus::kNotFound:
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ case DatabaseStatus::kOk:
+ break;
+ }
+
+ if (data.size() != 1u) {
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ }
+
+ proto::BackgroundFetchMetadata metadata;
+ if (!metadata.ParseFromString(data[0])) {
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ }
+
+ if (sub_task_init().unique_id != metadata.registration().unique_id()) {
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ }
+
+ // Fill BackgroundFetchRegistrationId.
+ sub_task_init().initialization_data->registration_id =
+ BackgroundFetchRegistrationId(
+ sub_task_init().service_worker_registration_id,
+ url::Origin::Create(GURL(metadata.origin())),
+ metadata.registration().developer_id(),
+ metadata.registration().unique_id());
+
+ // Fill BackgroundFetchRegistration.
+ auto& registration = sub_task_init().initialization_data->registration;
+ // TODO(crbug.com/853874): Unify conversion logic.
+ registration.developer_id = metadata.registration().developer_id();
+ registration.unique_id = metadata.registration().unique_id();
+ registration.upload_total = metadata.registration().upload_total();
+ registration.uploaded = metadata.registration().uploaded();
+ registration.download_total = metadata.registration().download_total();
+ registration.downloaded = metadata.registration().downloaded();
+
+ // Total number of requests.
+ sub_task_init().initialization_data->num_requests = metadata.num_fetches();
+
+ // Fill BackgroundFetchOptions.
+ auto& options = sub_task_init().initialization_data->options;
+ options.title = metadata.options().title();
+ options.download_total = metadata.options().download_total();
+ options.icons.reserve(metadata.options().icons_size());
+ for (const auto& icon : metadata.options().icons()) {
+ blink::Manifest::ImageResource ir;
+ ir.src = GURL(icon.src());
+ ir.type = base::ASCIIToUTF16(icon.type());
+
+ ir.sizes.reserve(icon.sizes_size());
+ for (const auto& size : icon.sizes())
+ ir.sizes.emplace_back(size.width(), size.height());
+
+ ir.purpose.reserve(icon.purpose_size());
+ for (auto purpose : icon.purpose()) {
+ switch (purpose) {
+ case proto::BackgroundFetchOptions_ImageResource_Purpose_ANY:
+ ir.purpose.push_back(blink::Manifest::ImageResource::Purpose::ANY);
+ break;
+ case proto::BackgroundFetchOptions_ImageResource_Purpose_BADGE:
+ ir.purpose.push_back(
+ blink::Manifest::ImageResource::Purpose::BADGE);
+ break;
+ }
+ }
+ }
+
+ if (!metadata.icon().empty()) {
+ // Start an icon deserialization SubTask on another thread, then finish.
+ AddSubTask(std::make_unique<DeserializeIconTask>(
+ this, sub_task_init(),
+ base::BindOnce(&FillFromMetadataTask::FinishWithError,
+ weak_factory_.GetWeakPtr(),
+ blink::mojom::BackgroundFetchError::NONE),
+ metadata.release_icon()));
+ } else {
+ // Immediately finish.
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
+ }
+ }
+
+ base::WeakPtrFactory<FillFromMetadataTask> weak_factory_; // Keep as last.
+
+ DISALLOW_COPY_AND_ASSIGN(FillFromMetadataTask);
+};
+
+// Asynchronously calls the SubTasks required to collect all the information for
+// the BackgroundFetchInitializationData.
+class FillBackgroundFetchInitializationDataTask : public InitializationSubTask {
+ public:
+ FillBackgroundFetchInitializationDataTask(DatabaseTaskHost* host,
+ const SubTaskInit& sub_task_init,
+ base::OnceClosure done_closure)
+ : InitializationSubTask(host, sub_task_init, std::move(done_closure)),
+ weak_factory_(this) {}
+
+ ~FillBackgroundFetchInitializationDataTask() override = default;
+
+ void Start() override {
+ // We need 3 queries to get the initialization data. These are wrapped
+ // in a BarrierClosure to avoid querying them serially.
+ // 1. Metadata (+ icon deserialization)
+ // 2. Request statuses and state sanitization
+ // 3. UI Title
+ base::RepeatingClosure barrier_closure = base::BarrierClosure(
+ 3u,
+ base::BindOnce(
+ [](base::WeakPtr<FillBackgroundFetchInitializationDataTask> task) {
+ if (task)
+ task->FinishWithError(
+ task->sub_task_init().initialization_data->error);
+ },
+ weak_factory_.GetWeakPtr()));
+ AddSubTask(std::make_unique<FillFromMetadataTask>(this, sub_task_init(),
+ barrier_closure));
+ AddSubTask(std::make_unique<GetRequestsTask>(this, sub_task_init(),
+ barrier_closure));
+ AddSubTask(
+ std::make_unique<GetTitleTask>(this, sub_task_init(), barrier_closure));
+ }
+
+ private:
+ base::WeakPtrFactory<FillBackgroundFetchInitializationDataTask>
+ weak_factory_; // Keep as last.
+
+ DISALLOW_COPY_AND_ASSIGN(FillBackgroundFetchInitializationDataTask);
+};
+
+} // namespace
+
+BackgroundFetchInitializationData::BackgroundFetchInitializationData() =
+ default;
+
+BackgroundFetchInitializationData::BackgroundFetchInitializationData(
+ BackgroundFetchInitializationData&&) = default;
+
+BackgroundFetchInitializationData::~BackgroundFetchInitializationData() =
+ default;
+
+GetInitializationDataTask::GetInitializationDataTask(
+ DatabaseTaskHost* host,
+ GetInitializationDataCallback callback)
+ : DatabaseTask(host), callback_(std::move(callback)), weak_factory_(this) {}
+
+GetInitializationDataTask::~GetInitializationDataTask() = default;
+
+void GetInitializationDataTask::Start() {
+ service_worker_context()->GetUserDataForAllRegistrationsByKeyPrefix(
+ kActiveRegistrationUniqueIdKeyPrefix,
+ base::BindOnce(&GetInitializationDataTask::DidGetRegistrations,
+ weak_factory_.GetWeakPtr()));
+}
+
+void GetInitializationDataTask::DidGetRegistrations(
+ const std::vector<std::pair<int64_t, std::string>>& user_data,
+ blink::ServiceWorkerStatusCode status) {
+ switch (ToDatabaseStatus(status)) {
+ case DatabaseStatus::kFailed:
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
+ case DatabaseStatus::kNotFound:
+ case DatabaseStatus::kOk:
+ break;
+ }
+
+ if (user_data.empty()) {
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
+ return;
+ }
+
+ base::RepeatingClosure barrier_closure = base::BarrierClosure(
+ user_data.size(),
+ base::BindOnce(&GetInitializationDataTask::FinishWithError,
+ weak_factory_.GetWeakPtr(),
+ blink::mojom::BackgroundFetchError::NONE));
+
+ for (const auto& ud : user_data) {
+ auto insertion_result = initialization_data_map_.emplace(
+ ud.second, BackgroundFetchInitializationData());
+ DCHECK(insertion_result.second); // Check unique_id is in fact unique.
+
+ AddSubTask(std::make_unique<FillBackgroundFetchInitializationDataTask>(
+ this,
+ InitializationSubTask::SubTaskInit{
+ ud.first, ud.second,
+ &insertion_result.first->second /* initialization_data */},
+ barrier_closure));
+ }
+}
+void GetInitializationDataTask::FinishWithError(
+ blink::mojom::BackgroundFetchError error) {
+ std::vector<BackgroundFetchInitializationData> results;
+ results.reserve(initialization_data_map_.size());
+
+ for (auto& data : initialization_data_map_) {
+ if (data.second.error == blink::mojom::BackgroundFetchError::NONE) {
+ // If we successfully extracted all the data, move it to the
+ // initialization vector to be handed over to create a controller.
+ results.emplace_back(std::move(data.second));
+ } else if (!data.second.registration_id.developer_id().empty()) {
+ // There was an error in getting the initialization data
+ // (e.g. corrupt data, SWDB error). If the Developer ID of the fetch
+ // is available, mark the registration for deletion.
+ // Note that the Developer ID isn't available if the metadata extraction
+ // failed.
+ // TODO(crbug.com/865388): Getting the Developer ID should be possible
+ // since it is part of the key for when we got the Unique ID.
+ AddDatabaseTask(std::make_unique<MarkRegistrationForDeletionTask>(
+ data_manager(), data.second.registration_id, base::DoNothing()));
+ }
+ }
+
+ std::move(callback_).Run(error, std::move(results));
+ Finished(); // Destroys |this|.
+}
+
+} // namespace background_fetch
+
+} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/get_initialization_data_task.h b/chromium/content/browser/background_fetch/storage/get_initialization_data_task.h
new file mode 100644
index 00000000000..7946ba0a1f6
--- /dev/null
+++ b/chromium/content/browser/background_fetch/storage/get_initialization_data_task.h
@@ -0,0 +1,100 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_INITIALIZATION_DATA_TASK_H_
+#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_INITIALIZATION_DATA_TASK_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "content/browser/background_fetch/background_fetch_registration_id.h"
+#include "content/browser/background_fetch/storage/database_task.h"
+#include "content/browser/service_worker/service_worker_info.h"
+#include "content/common/background_fetch/background_fetch_types.h"
+#include "content/common/content_export.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+namespace content {
+
+namespace background_fetch {
+
+// All the information needed to create a JobController and resume the fetch
+// after start-up.
+struct CONTENT_EXPORT BackgroundFetchInitializationData {
+ BackgroundFetchInitializationData();
+ BackgroundFetchInitializationData(BackgroundFetchInitializationData&&);
+ ~BackgroundFetchInitializationData();
+
+ BackgroundFetchRegistrationId registration_id;
+ BackgroundFetchOptions options;
+ SkBitmap icon;
+ BackgroundFetchRegistration registration;
+ size_t num_requests;
+ size_t num_completed_requests;
+ std::vector<std::string> active_fetch_guids;
+ std::string ui_title;
+
+ // The error, if any, when getting the registration data.
+ blink::mojom::BackgroundFetchError error =
+ blink::mojom::BackgroundFetchError::NONE;
+
+ DISALLOW_COPY_AND_ASSIGN(BackgroundFetchInitializationData);
+};
+
+using GetInitializationDataCallback =
+ base::OnceCallback<void(blink::mojom::BackgroundFetchError,
+ std::vector<BackgroundFetchInitializationData>)>;
+
+// Gets all the data needed to resume fetches. The task starts by getting
+// all the <ServiceWorker Registration ID, Background Fetch Unique ID>
+// pairs available.
+// * TODO(crbug.com/853060): Consider persisting which SWIDs contain BGF
+// info.
+// Then for every Background Fetch Unique ID the required information is
+// queried from the ServiceWorker Database to fill an instance of
+// BackgroundFetchInitializationData.
+//
+// Note: All of this must run in one DatabaseTask, to ensure the
+// BackgroundFetchContext is properly initialized with JobControllers before
+// running any additional DatabaseTasks and reaching an incorrect state.
+class GetInitializationDataTask : public DatabaseTask {
+ public:
+ using InitializationDataMap =
+ std::map<std::string, BackgroundFetchInitializationData>;
+
+ GetInitializationDataTask(DatabaseTaskHost* host,
+ GetInitializationDataCallback callback);
+
+ ~GetInitializationDataTask() override;
+
+ // DatabaseTask implementation:
+ void Start() override;
+
+ private:
+ void DidGetRegistrations(
+ const std::vector<std::pair<int64_t, std::string>>& user_data,
+ blink::ServiceWorkerStatusCode status);
+
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override;
+
+ GetInitializationDataCallback callback_;
+
+ // Map from the unique_id to the initialization data.
+ InitializationDataMap initialization_data_map_;
+
+ base::WeakPtrFactory<GetInitializationDataTask>
+ weak_factory_; // Keep as last.
+
+ DISALLOW_COPY_AND_ASSIGN(GetInitializationDataTask);
+};
+
+} // namespace background_fetch
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_INITIALIZATION_DATA_TASK_H_
diff --git a/chromium/content/browser/background_fetch/storage/get_metadata_task.cc b/chromium/content/browser/background_fetch/storage/get_metadata_task.cc
index e80738b9b2e..f6888b1cd44 100644
--- a/chromium/content/browser/background_fetch/storage/get_metadata_task.cc
+++ b/chromium/content/browser/background_fetch/storage/get_metadata_task.cc
@@ -14,12 +14,12 @@ namespace content {
namespace background_fetch {
-GetMetadataTask::GetMetadataTask(BackgroundFetchDataManager* data_manager,
+GetMetadataTask::GetMetadataTask(DatabaseTaskHost* host,
int64_t service_worker_registration_id,
const url::Origin& origin,
const std::string& developer_id,
GetMetadataCallback callback)
- : DatabaseTask(data_manager),
+ : DatabaseTask(host),
service_worker_registration_id_(service_worker_registration_id),
origin_(origin),
developer_id_(developer_id),
@@ -37,12 +37,10 @@ void GetMetadataTask::Start() {
}
void GetMetadataTask::DidGetUniqueId(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kNotFound:
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::INVALID_ID,
- nullptr /* metadata */);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::INVALID_ID);
return;
case DatabaseStatus::kOk:
DCHECK_EQ(1u, data.size());
@@ -52,34 +50,25 @@ void GetMetadataTask::DidGetUniqueId(const std::vector<std::string>& data,
weak_factory_.GetWeakPtr()));
return;
case DatabaseStatus::kFailed:
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR,
- nullptr /* metadata */);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
}
void GetMetadataTask::DidGetMetadata(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::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 /* metadata */);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
case DatabaseStatus::kOk:
DCHECK_EQ(1u, data.size());
ProcessMetadata(data[0]);
return;
case DatabaseStatus::kFailed:
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR,
- nullptr /* metadata */);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
}
@@ -87,9 +76,7 @@ void GetMetadataTask::DidGetMetadata(const std::vector<std::string>& data,
void GetMetadataTask::ProcessMetadata(const std::string& metadata) {
metadata_proto_ = std::make_unique<proto::BackgroundFetchMetadata>();
if (!metadata_proto_->ParseFromString(metadata)) {
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::STORAGE_ERROR,
- nullptr /* metadata */);
- Finished();
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
@@ -97,14 +84,20 @@ void GetMetadataTask::ProcessMetadata(const std::string& metadata) {
if (registration_proto.developer_id() != developer_id_ ||
!origin_.IsSameOriginWith(
url::Origin::Create(GURL(metadata_proto_->origin())))) {
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::STORAGE_ERROR,
- nullptr /* metadata */);
- Finished();
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE,
- std::move(metadata_proto_));
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
+}
+
+void GetMetadataTask::FinishWithError(
+ blink::mojom::BackgroundFetchError error) {
+ // We want to return a nullptr instead of an empty proto in case of an error.
+ if (error != blink::mojom::BackgroundFetchError::NONE)
+ metadata_proto_.reset();
+
+ std::move(callback_).Run(error, std::move(metadata_proto_));
Finished();
}
diff --git a/chromium/content/browser/background_fetch/storage/get_metadata_task.h b/chromium/content/browser/background_fetch/storage/get_metadata_task.h
index bf51554aa3d..68cb068ade6 100644
--- a/chromium/content/browser/background_fetch/storage/get_metadata_task.h
+++ b/chromium/content/browser/background_fetch/storage/get_metadata_task.h
@@ -12,7 +12,7 @@
#include "base/callback_forward.h"
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/storage/database_task.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/origin.h"
namespace content {
@@ -26,7 +26,7 @@ class GetMetadataTask : public DatabaseTask {
base::OnceCallback<void(blink::mojom::BackgroundFetchError,
std::unique_ptr<proto::BackgroundFetchMetadata>)>;
- GetMetadataTask(BackgroundFetchDataManager* data_manager,
+ GetMetadataTask(DatabaseTaskHost* host,
int64_t service_worker_registration_id,
const url::Origin& origin,
const std::string& developer_id,
@@ -39,13 +39,15 @@ class GetMetadataTask : public DatabaseTask {
private:
void DidGetUniqueId(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void DidGetMetadata(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void ProcessMetadata(const std::string& metadata);
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override;
+
int64_t service_worker_registration_id_;
url::Origin origin_;
std::string developer_id_;
diff --git a/chromium/content/browser/background_fetch/storage/get_num_requests_task.cc b/chromium/content/browser/background_fetch/storage/get_num_requests_task.cc
deleted file mode 100644
index 6e4fbf2f566..00000000000
--- a/chromium/content/browser/background_fetch/storage/get_num_requests_task.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/background_fetch/storage/get_num_requests_task.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/get_metadata_task.h"
-#include "content/browser/service_worker/service_worker_context_wrapper.h"
-
-namespace content {
-
-namespace background_fetch {
-
-namespace {
-
-void HandleGetMetadataCallback(
- GetNumRequestsTask::NumRequestsCallback callback,
- blink::mojom::BackgroundFetchError error,
- std::unique_ptr<proto::BackgroundFetchMetadata> metadata) {
- if (error != blink::mojom::BackgroundFetchError::NONE) {
- std::move(callback).Run(0u);
- return;
- }
-
- DCHECK(metadata);
- std::move(callback).Run(metadata->num_fetches());
-}
-
-} // namespace
-
-GetNumRequestsTask::GetNumRequestsTask(
- BackgroundFetchDataManager* data_manager,
- const BackgroundFetchRegistrationId& registration_id,
- RequestType type,
- NumRequestsCallback callback)
- : DatabaseTask(data_manager),
- registration_id_(registration_id),
- type_(type),
- callback_(std::move(callback)),
- weak_factory_(this) {}
-
-GetNumRequestsTask::~GetNumRequestsTask() = default;
-
-void GetNumRequestsTask::Start() {
- switch (type_) {
- case RequestType::kAny:
- GetMetadata();
- return;
- case RequestType::kPending:
- GetRequests(PendingRequestKeyPrefix(registration_id_.unique_id()));
- return;
- case RequestType::kActive:
- GetRequests(ActiveRequestKeyPrefix(registration_id_.unique_id()));
- return;
- case RequestType::kCompleted:
- GetRequests(CompletedRequestKeyPrefix(registration_id_.unique_id()));
- return;
- }
- NOTREACHED();
-}
-
-void GetNumRequestsTask::GetMetadata() {
- AddDatabaseTask(std::make_unique<GetMetadataTask>(
- data_manager(), registration_id_.service_worker_registration_id(),
- registration_id_.origin(), registration_id_.developer_id(),
- base::BindOnce(&HandleGetMetadataCallback, std::move(callback_))));
- Finished(); // Destroys |this|.
-}
-
-void GetNumRequestsTask::GetRequests(const std::string& key_prefix) {
- service_worker_context()->GetRegistrationUserDataByKeyPrefix(
- registration_id_.service_worker_registration_id(), key_prefix,
- base::BindOnce(&GetNumRequestsTask::DidGetRequests,
- weak_factory_.GetWeakPtr()));
-}
-
-void GetNumRequestsTask::DidGetRequests(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
- DCHECK_EQ(ToDatabaseStatus(status), DatabaseStatus::kOk);
- std::move(callback_).Run(data.size());
- Finished(); // Destroys |this|.
-}
-
-} // namespace background_fetch
-
-} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/get_num_requests_task.h b/chromium/content/browser/background_fetch/storage/get_num_requests_task.h
deleted file mode 100644
index fe4857b4b91..00000000000
--- a/chromium/content/browser/background_fetch/storage/get_num_requests_task.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_NUM_REQUESTS_TASK_H_
-#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_NUM_REQUESTS_TASK_H_
-
-#include "base/callback_forward.h"
-#include "content/browser/background_fetch/storage/database_task.h"
-#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_status_code.h"
-
-namespace content {
-
-namespace background_fetch {
-
-enum class RequestType { kAny, kPending, kActive, kCompleted };
-
-// Gets the number of requests per registration of the given type.
-class CONTENT_EXPORT GetNumRequestsTask : public DatabaseTask {
- public:
- using NumRequestsCallback = base::OnceCallback<void(size_t)>;
-
- GetNumRequestsTask(BackgroundFetchDataManager* data_manager,
- const BackgroundFetchRegistrationId& registration_id,
- RequestType type,
- NumRequestsCallback callback);
-
- ~GetNumRequestsTask() override;
-
- // DatabaseTask implementation:
- void Start() override;
-
- private:
- void GetMetadata();
- void GetRequests(const std::string& key_prefix);
- void DidGetRequests(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
-
- BackgroundFetchRegistrationId registration_id_;
- RequestType type_;
- NumRequestsCallback callback_;
-
- base::WeakPtrFactory<GetNumRequestsTask> weak_factory_; // Keep as last.
-
- DISALLOW_COPY_AND_ASSIGN(GetNumRequestsTask);
-};
-
-} // namespace background_fetch
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_NUM_REQUESTS_TASK_H_
diff --git a/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.cc b/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.cc
index 9ea3c390098..d74d797949a 100644
--- a/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.cc
+++ b/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.cc
@@ -5,8 +5,9 @@
#include "content/browser/background_fetch/storage/get_settled_fetches_task.h"
#include "base/barrier_closure.h"
-#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/cache_storage/cache_storage_manager.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
namespace content {
@@ -14,10 +15,10 @@ namespace content {
namespace background_fetch {
GetSettledFetchesTask::GetSettledFetchesTask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
BackgroundFetchRegistrationId registration_id,
SettledFetchesCallback callback)
- : DatabaseTask(data_manager),
+ : DatabaseTask(host),
registration_id_(registration_id),
settled_fetches_callback_(std::move(callback)),
weak_factory_(this) {}
@@ -25,80 +26,140 @@ GetSettledFetchesTask::GetSettledFetchesTask(
GetSettledFetchesTask::~GetSettledFetchesTask() = default;
void GetSettledFetchesTask::Start() {
+ base::RepeatingClosure barrier_closure = base::BarrierClosure(
+ 2u, base::BindOnce(&GetSettledFetchesTask::GetResponses,
+ weak_factory_.GetWeakPtr()));
+
+ cache_manager()->OpenCache(
+ registration_id_.origin(), CacheStorageOwner::kBackgroundFetch,
+ registration_id_.unique_id() /* cache_name */,
+ base::BindOnce(&GetSettledFetchesTask::DidOpenCache,
+ weak_factory_.GetWeakPtr(), barrier_closure));
+
service_worker_context()->GetRegistrationUserDataByKeyPrefix(
registration_id_.service_worker_registration_id(),
{CompletedRequestKeyPrefix(registration_id_.unique_id())},
base::BindOnce(&GetSettledFetchesTask::DidGetCompletedRequests,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr(), barrier_closure));
+}
+
+void GetSettledFetchesTask::DidOpenCache(
+ base::OnceClosure done_closure,
+ CacheStorageCacheHandle handle,
+ blink::mojom::CacheStorageError error) {
+ if (error != blink::mojom::CacheStorageError::kSuccess) {
+ // TODO(crbug.com/780025): Log failures to UMA.
+ error_ = blink::mojom::BackgroundFetchError::STORAGE_ERROR;
+ } else {
+ DCHECK(handle.value());
+ handle_ = std::move(handle);
+ }
+ std::move(done_closure).Run();
}
void GetSettledFetchesTask::DidGetCompletedRequests(
+ base::OnceClosure done_closure,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kOk:
break;
// TODO(crbug.com/780025): Log failures to UMA.
case DatabaseStatus::kFailed:
- FinishTaskWithErrorCode(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR);
- return;
+ error_ = blink::mojom::BackgroundFetchError::STORAGE_ERROR;
+ break;
case DatabaseStatus::kNotFound:
background_fetch_succeeded_ = false;
- FinishTaskWithErrorCode(blink::mojom::BackgroundFetchError::INVALID_ID);
- return;
+ error_ = blink::mojom::BackgroundFetchError::INVALID_ID;
+ break;
}
- // Nothing failed yet so the default state is success.
- if (data.empty()) {
- FinishTaskWithErrorCode(blink::mojom::BackgroundFetchError::NONE);
+ completed_requests_.reserve(data.size());
+ for (const std::string& serialized_completed_request : data) {
+ completed_requests_.emplace_back();
+ if (!completed_requests_.back().ParseFromString(
+ serialized_completed_request)) {
+ // Service worker database has been corrupted. Abandon fetches.
+ error_ = blink::mojom::BackgroundFetchError::STORAGE_ERROR;
+ background_fetch_succeeded_ = false;
+ AbandonFetches(registration_id_.service_worker_registration_id());
+ break;
+ }
+ if (!completed_requests_.back().succeeded())
+ background_fetch_succeeded_ = false;
+ }
+ std::move(done_closure).Run();
+}
+
+void GetSettledFetchesTask::GetResponses() {
+ if (error_ != blink::mojom::BackgroundFetchError::NONE) {
+ FinishWithError(error_);
+ return;
+ }
+ if (completed_requests_.empty()) {
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
return;
}
base::RepeatingClosure barrier_closure = base::BarrierClosure(
- data.size(),
- base::BindOnce(&GetSettledFetchesTask::FinishTaskWithErrorCode,
+ completed_requests_.size(),
+ base::BindOnce(&GetSettledFetchesTask::FinishWithError,
weak_factory_.GetWeakPtr(),
blink::mojom::BackgroundFetchError::NONE));
- settled_fetches_.reserve(data.size());
- for (const std::string& serialized_completed_request : data) {
- proto::BackgroundFetchCompletedRequest completed_request;
- if (!completed_request.ParseFromString(serialized_completed_request)) {
- NOTREACHED()
- << "Database is corrupt"; // TODO(crbug.com/780027): Nuke it.
- }
-
- settled_fetches_.emplace_back(BackgroundFetchSettledFetch());
+ settled_fetches_.reserve(completed_requests_.size());
+ for (const auto& completed_request : completed_requests_) {
+ settled_fetches_.emplace_back();
settled_fetches_.back().request =
std::move(ServiceWorkerFetchRequest::ParseFromString(
completed_request.serialized_request()));
- if (!completed_request.succeeded()) {
- FillFailedResponse(&settled_fetches_.back().response, barrier_closure);
- continue;
- }
- FillSuccessfulResponse(&settled_fetches_.back().response, barrier_closure);
+ FillResponse(&settled_fetches_.back(), barrier_closure);
}
}
-void GetSettledFetchesTask::FillFailedResponse(
- ServiceWorkerResponse* response,
- const base::RepeatingClosure& callback) {
- DCHECK(response);
- background_fetch_succeeded_ = false;
- // TODO(rayankans): Fill failed response with error reports.
+void GetSettledFetchesTask::FillResponse(
+ BackgroundFetchSettledFetch* settled_fetch,
+ base::OnceClosure callback) {
+ DCHECK(settled_fetch);
+ DCHECK(handle_.value());
+
+ auto request =
+ std::make_unique<ServiceWorkerFetchRequest>(settled_fetch->request);
+
+ handle_.value()->Match(std::move(request), nullptr /* match_params */,
+ base::BindOnce(&GetSettledFetchesTask::DidMatchRequest,
+ weak_factory_.GetWeakPtr(),
+ settled_fetch, std::move(callback)));
+}
+
+void GetSettledFetchesTask::DidMatchRequest(
+ BackgroundFetchSettledFetch* settled_fetch,
+ base::OnceClosure callback,
+ blink::mojom::CacheStorageError error,
+ std::unique_ptr<ServiceWorkerResponse> cache_response) {
+ if (error != blink::mojom::CacheStorageError::kSuccess) {
+ DCHECK(settled_fetch);
+ FillUncachedResponse(settled_fetch, std::move(callback));
+ return;
+ }
+ settled_fetch->response = std::move(*cache_response);
std::move(callback).Run();
}
-void GetSettledFetchesTask::FillSuccessfulResponse(
- ServiceWorkerResponse* response,
- const base::RepeatingClosure& callback) {
- DCHECK(response);
- // TODO(rayankans): Get the response stored in Cache Storage.
+void GetSettledFetchesTask::FillUncachedResponse(
+ BackgroundFetchSettledFetch* settled_fetch,
+ base::OnceClosure callback) {
+ background_fetch_succeeded_ = false;
+
+ // TODO(rayankans): Fill unmatched response with error reports.
+ settled_fetch->response.response_type =
+ network::mojom::FetchResponseType::kError;
+ settled_fetch->response.url_list.push_back(settled_fetch->request.url);
+
std::move(callback).Run();
}
-void GetSettledFetchesTask::FinishTaskWithErrorCode(
+void GetSettledFetchesTask::FinishWithError(
blink::mojom::BackgroundFetchError error) {
std::move(settled_fetches_callback_)
.Run(error, background_fetch_succeeded_, std::move(settled_fetches_),
diff --git a/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.h b/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.h
index 7fba53179fc..6830c21d924 100644
--- a/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.h
+++ b/chromium/content/browser/background_fetch/storage/get_settled_fetches_task.h
@@ -6,9 +6,12 @@
#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_SETTLED_FETCHES_TASK_H_
#include "base/callback_forward.h"
+#include "base/memory/scoped_refptr.h"
+#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/storage/database_task.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "content/browser/cache_storage/cache_storage_cache_handle.h"
#include "storage/browser/blob/blob_data_handle.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
@@ -22,7 +25,7 @@ class GetSettledFetchesTask : public DatabaseTask {
std::vector<BackgroundFetchSettledFetch>,
std::vector<std::unique_ptr<storage::BlobDataHandle>>)>;
- GetSettledFetchesTask(BackgroundFetchDataManager* data_manager,
+ GetSettledFetchesTask(DatabaseTaskHost* host,
BackgroundFetchRegistrationId registration_id,
SettledFetchesCallback callback);
@@ -32,23 +35,42 @@ class GetSettledFetchesTask : public DatabaseTask {
void Start() override;
private:
- void DidGetCompletedRequests(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ void DidOpenCache(base::OnceClosure done_closure,
+ CacheStorageCacheHandle handle,
+ blink::mojom::CacheStorageError error);
- void FillFailedResponse(ServiceWorkerResponse* response,
- const base::RepeatingClosure& callback);
+ void DidGetCompletedRequests(base::OnceClosure done_closure,
+ const std::vector<std::string>& data,
+ blink::ServiceWorkerStatusCode status);
- void FillSuccessfulResponse(ServiceWorkerResponse* response,
- const base::RepeatingClosure& callback);
+ void GetResponses();
- void FinishTaskWithErrorCode(blink::mojom::BackgroundFetchError error);
+ void FillUncachedResponse(BackgroundFetchSettledFetch* settled_fetch,
+ base::OnceClosure callback);
+
+ void FillResponse(BackgroundFetchSettledFetch* settled_fetch,
+ base::OnceClosure callback);
+
+ void DidMatchRequest(BackgroundFetchSettledFetch* settled_fetch,
+ base::OnceClosure callback,
+ blink::mojom::CacheStorageError error,
+ std::unique_ptr<ServiceWorkerResponse> cache_response);
+
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override;
BackgroundFetchRegistrationId registration_id_;
SettledFetchesCallback settled_fetches_callback_;
+ // SettledFetchesCallback params.
std::vector<BackgroundFetchSettledFetch> settled_fetches_;
bool background_fetch_succeeded_ = true;
+ // Storage params.
+ CacheStorageCacheHandle handle_;
+ std::vector<proto::BackgroundFetchCompletedRequest> completed_requests_;
+ blink::mojom::BackgroundFetchError error_ =
+ blink::mojom::BackgroundFetchError::NONE;
+
base::WeakPtrFactory<GetSettledFetchesTask> weak_factory_; // Keep as last.
DISALLOW_COPY_AND_ASSIGN(GetSettledFetchesTask);
diff --git a/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc b/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc
index 576d8fb64ab..1f12e1a190d 100644
--- a/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc
+++ b/chromium/content/browser/background_fetch/storage/mark_registration_for_deletion_task.cc
@@ -16,10 +16,10 @@ namespace content {
namespace background_fetch {
MarkRegistrationForDeletionTask::MarkRegistrationForDeletionTask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
const BackgroundFetchRegistrationId& registration_id,
HandleBackgroundFetchErrorCallback callback)
- : DatabaseTask(data_manager),
+ : DatabaseTask(host),
registration_id_(registration_id),
callback_(std::move(callback)),
weak_factory_(this) {}
@@ -39,18 +39,15 @@ void MarkRegistrationForDeletionTask::Start() {
void MarkRegistrationForDeletionTask::DidGetActiveUniqueId(
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kOk:
break;
case DatabaseStatus::kNotFound:
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::INVALID_ID);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::INVALID_ID);
return;
case DatabaseStatus::kFailed:
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
@@ -59,8 +56,7 @@ void MarkRegistrationForDeletionTask::DidGetActiveUniqueId(
// 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|.
+ FinishWithError(blink::mojom::BackgroundFetchError::INVALID_ID);
return;
}
@@ -77,20 +73,21 @@ void MarkRegistrationForDeletionTask::DidGetActiveUniqueId(
base::BindOnce(&MarkRegistrationForDeletionTask::DidDeactivate,
weak_factory_.GetWeakPtr()));
} else {
- NOTREACHED() << "Database is corrupt"; // TODO(crbug.com/780027): Nuke it.
+ // Service worker database has been corrupted. Abandon fetches.
+ AbandonFetches(registration_id_.service_worker_registration_id());
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
}
}
void MarkRegistrationForDeletionTask::DidDeactivate(
- ServiceWorkerStatusCode status) {
+ blink::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|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
@@ -98,7 +95,12 @@ void MarkRegistrationForDeletionTask::DidDeactivate(
// |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);
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
+}
+
+void MarkRegistrationForDeletionTask::FinishWithError(
+ blink::mojom::BackgroundFetchError error) {
+ std::move(callback_).Run(error);
Finished(); // Destroys |this|.
}
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
index d43a587fe86..0c78c17f2b2 100644
--- 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
@@ -9,7 +9,7 @@
#include <vector>
#include "content/browser/background_fetch/storage/database_task.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
@@ -21,7 +21,7 @@ namespace background_fetch {
class MarkRegistrationForDeletionTask : public background_fetch::DatabaseTask {
public:
MarkRegistrationForDeletionTask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
const BackgroundFetchRegistrationId& registration_id,
HandleBackgroundFetchErrorCallback callback);
@@ -31,9 +31,11 @@ class MarkRegistrationForDeletionTask : public background_fetch::DatabaseTask {
private:
void DidGetActiveUniqueId(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
- void DidDeactivate(ServiceWorkerStatusCode status);
+ void DidDeactivate(blink::ServiceWorkerStatusCode status);
+
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override;
BackgroundFetchRegistrationId registration_id_;
HandleBackgroundFetchErrorCallback callback_;
diff --git a/chromium/content/browser/background_fetch/storage/mark_request_complete_task.cc b/chromium/content/browser/background_fetch/storage/mark_request_complete_task.cc
index 63884ce938d..f416b06e4a6 100644
--- a/chromium/content/browser/background_fetch/storage/mark_request_complete_task.cc
+++ b/chromium/content/browser/background_fetch/storage/mark_request_complete_task.cc
@@ -4,21 +4,43 @@
#include "content/browser/background_fetch/storage/mark_request_complete_task.h"
+#include "base/barrier_closure.h"
+#include "base/guid.h"
+#include "content/browser/background_fetch/background_fetch_cross_origin_filter.h"
#include "content/browser/background_fetch/background_fetch_data_manager.h"
#include "content/browser/background_fetch/storage/database_helpers.h"
+#include "content/browser/background_fetch/storage/get_metadata_task.h"
+#include "content/browser/blob_storage/chrome_blob_storage_context.h"
+#include "content/browser/cache_storage/cache_storage_manager.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "services/network/public/cpp/cors/cors.h"
+#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/blink/public/mojom/blob/blob.mojom.h"
namespace content {
namespace background_fetch {
+namespace {
+
+// 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.
+bool IsOK(const BackgroundFetchRequestInfo& request) {
+ int status = request.GetResponseCode();
+ return network::cors::IsOkStatus(status);
+}
+
+} // namespace
+
MarkRequestCompleteTask::MarkRequestCompleteTask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
BackgroundFetchRegistrationId registration_id,
scoped_refptr<BackgroundFetchRequestInfo> request_info,
MarkedCompleteCallback callback)
- : DatabaseTask(data_manager),
+ : DatabaseTask(host),
registration_id_(registration_id),
request_info_(std::move(request_info)),
callback_(std::move(callback)),
@@ -27,31 +49,134 @@ MarkRequestCompleteTask::MarkRequestCompleteTask(
MarkRequestCompleteTask::~MarkRequestCompleteTask() = default;
void MarkRequestCompleteTask::Start() {
- StoreResponse();
+ base::RepeatingClosure barrier_closure = base::BarrierClosure(
+ 2u, base::BindOnce(&MarkRequestCompleteTask::FinishWithError,
+ weak_factory_.GetWeakPtr(),
+ blink::mojom::BackgroundFetchError::NONE));
+
+ StoreResponse(barrier_closure);
+ UpdateMetadata(barrier_closure);
}
-void MarkRequestCompleteTask::StoreResponse() {
- ServiceWorkerResponse response;
- bool is_response_valid = data_manager()->FillServiceWorkerResponse(
- *request_info_, registration_id_.origin(), &response);
+void MarkRequestCompleteTask::StoreResponse(base::OnceClosure done_closure) {
+ auto response = std::make_unique<ServiceWorkerResponse>();
+ response->url_list = request_info_->GetURLChain();
+ // TODO(crbug.com/838837): fill error and cors_exposed_header_names in
+ // response.
+ response->response_type = network::mojom::FetchResponseType::kDefault;
+ response->response_time = request_info_->GetResponseTime();
+
+ BackgroundFetchCrossOriginFilter filter(registration_id_.origin(),
+ *request_info_);
+ if (filter.CanPopulateBody())
+ PopulateResponseBody(response.get());
+ else
+ is_response_successful_ = false;
+
+ if (!IsOK(*request_info_))
+ is_response_successful_ = false;
- if (!is_response_valid) {
- // No point in caching the response, just do the request state transition.
- CreateAndStoreCompletedRequest(false);
+ // A valid non-empty url is needed if we want to write to the cache.
+ if (!request_info_->fetch_request().url.is_valid()) {
+ CreateAndStoreCompletedRequest(std::move(done_closure));
return;
}
- // TODO(rayankans): Store the request/response pair in cache storage, and call
- // `CreateAndStoreActiveRequest` via a callback.
- CreateAndStoreCompletedRequest(true);
+
+ cache_manager()->OpenCache(
+ registration_id_.origin(), CacheStorageOwner::kBackgroundFetch,
+ registration_id_.unique_id() /* cache_name */,
+ base::BindOnce(&MarkRequestCompleteTask::DidOpenCache,
+ weak_factory_.GetWeakPtr(), std::move(response),
+ std::move(done_closure)));
+}
+
+void MarkRequestCompleteTask::PopulateResponseBody(
+ ServiceWorkerResponse* response) {
+ // Include the status code, status text and the response's body as a blob
+ // when this is allowed by the CORS protocol.
+ response->status_code = request_info_->GetResponseCode();
+ response->status_text = request_info_->GetResponseText();
+ response->headers.insert(request_info_->GetResponseHeaders().begin(),
+ request_info_->GetResponseHeaders().end());
+
+ DCHECK(blob_storage_context());
+ std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
+
+ // Prefer the blob data handle provided by the |request_info_| if one is
+ // available. Otherwise create one based on the file path and size.
+ if (request_info_->GetBlobDataHandle()) {
+ blob_data_handle = std::make_unique<storage::BlobDataHandle>(
+ request_info_->GetBlobDataHandle().value());
+
+ } else if (request_info_->GetFileSize() > 0 &&
+ !request_info_->GetFilePath().empty()) {
+ // TODO(rayankans): Simplify this code by making either the download service
+ // or the BackgroundFetchRequestInfo responsible for files vs. blobs.
+ auto blob_builder =
+ std::make_unique<storage::BlobDataBuilder>(base::GenerateGUID());
+ blob_builder->AppendFile(request_info_->GetFilePath(), 0 /* offset */,
+ request_info_->GetFileSize(),
+ base::Time() /* expected_modification_time */);
+
+ blob_data_handle = GetBlobStorageContext(blob_storage_context())
+ ->AddFinishedBlob(std::move(blob_builder));
+ }
+
+ // TODO(rayankans): Appropriately handle !blob_data_handle
+ if (!blob_data_handle)
+ return;
+
+ response->blob_uuid = blob_data_handle->uuid();
+ response->blob_size = blob_data_handle->size();
+ blink::mojom::BlobPtr blob_ptr;
+ storage::BlobImpl::Create(
+ std::make_unique<storage::BlobDataHandle>(*blob_data_handle),
+ MakeRequest(&blob_ptr));
+
+ response->blob =
+ base::MakeRefCounted<storage::BlobHandle>(std::move(blob_ptr));
+}
+
+void MarkRequestCompleteTask::DidOpenCache(
+ std::unique_ptr<ServiceWorkerResponse> response,
+ base::OnceClosure done_closure,
+ CacheStorageCacheHandle handle,
+ blink::mojom::CacheStorageError error) {
+ if (error != blink::mojom::CacheStorageError::kSuccess) {
+ // TODO(crbug.com/780025): Log failures to UMA.
+ CreateAndStoreCompletedRequest(std::move(done_closure));
+ return;
+ }
+ DCHECK(handle.value());
+
+ auto request = std::make_unique<ServiceWorkerFetchRequest>(
+ request_info_->fetch_request());
+
+ // We need to keep the handle refcounted while the write is happening,
+ // so it's passed along to the callback.
+ handle.value()->Put(
+ std::move(request), std::move(response),
+ base::BindOnce(&MarkRequestCompleteTask::DidWriteToCache,
+ weak_factory_.GetWeakPtr(), std::move(handle),
+ std::move(done_closure)));
}
-void MarkRequestCompleteTask::CreateAndStoreCompletedRequest(bool succeeded) {
+void MarkRequestCompleteTask::DidWriteToCache(
+ CacheStorageCacheHandle handle,
+ base::OnceClosure done_closure,
+ blink::mojom::CacheStorageError error) {
+ // TODO(crbug.com/780025): Log failures to UMA.
+ CreateAndStoreCompletedRequest(std::move(done_closure));
+}
+
+void MarkRequestCompleteTask::CreateAndStoreCompletedRequest(
+ base::OnceClosure done_closure) {
completed_request_.set_unique_id(registration_id_.unique_id());
completed_request_.set_request_index(request_info_->request_index());
completed_request_.set_serialized_request(
request_info_->fetch_request().Serialize());
completed_request_.set_download_guid(request_info_->download_guid());
- completed_request_.set_succeeded(succeeded);
+ completed_request_.set_succeeded(is_response_successful_);
service_worker_context()->StoreRegistrationUserData(
registration_id_.service_worker_registration_id(),
@@ -59,19 +184,20 @@ void MarkRequestCompleteTask::CreateAndStoreCompletedRequest(bool succeeded) {
{{CompletedRequestKey(completed_request_.unique_id(),
completed_request_.request_index()),
completed_request_.SerializeAsString()}},
- base::BindRepeating(&MarkRequestCompleteTask::DidStoreCompletedRequest,
- weak_factory_.GetWeakPtr()));
+ base::BindOnce(&MarkRequestCompleteTask::DidStoreCompletedRequest,
+ weak_factory_.GetWeakPtr(), std::move(done_closure)));
}
void MarkRequestCompleteTask::DidStoreCompletedRequest(
- ServiceWorkerStatusCode status) {
+ base::OnceClosure done_closure,
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kOk:
break;
case DatabaseStatus::kFailed:
case DatabaseStatus::kNotFound:
// TODO(crbug.com/780025): Log failures to UMA.
- Finished(); // Destroys |this|.
+ std::move(done_closure).Run();
return;
}
@@ -81,26 +207,64 @@ void MarkRequestCompleteTask::DidStoreCompletedRequest(
{ActiveRequestKey(completed_request_.unique_id(),
completed_request_.request_index())},
base::BindOnce(&MarkRequestCompleteTask::DidDeleteActiveRequest,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr(), std::move(done_closure)));
}
void MarkRequestCompleteTask::DidDeleteActiveRequest(
- ServiceWorkerStatusCode status) {
- switch (ToDatabaseStatus(status)) {
- case DatabaseStatus::kNotFound:
- case DatabaseStatus::kFailed:
- // TODO(crbug.com/780025): Log failures to UMA.
- break;
- case DatabaseStatus::kOk:
- std::move(callback_).Run();
- break;
+ base::OnceClosure done_closure,
+ blink::ServiceWorkerStatusCode status) {
+ // TODO(crbug.com/780025): Log failures to UMA.
+ std::move(done_closure).Run();
+}
+
+void MarkRequestCompleteTask::UpdateMetadata(base::OnceClosure done_closure) {
+ if (!request_info_->IsResultSuccess() || request_info_->GetFileSize() == 0u) {
+ std::move(done_closure).Run();
+ return;
}
- Finished(); // Destroys |this|.
+ AddSubTask(std::make_unique<GetMetadataTask>(
+ this, registration_id_.service_worker_registration_id(),
+ registration_id_.origin(), registration_id_.developer_id(),
+ base::BindOnce(&MarkRequestCompleteTask::DidGetMetadata,
+ weak_factory_.GetWeakPtr(), std::move(done_closure))));
+}
+
+void MarkRequestCompleteTask::DidGetMetadata(
+ base::OnceClosure done_closure,
+ blink::mojom::BackgroundFetchError error,
+ std::unique_ptr<proto::BackgroundFetchMetadata> metadata) {
+ if (!metadata || error != blink::mojom::BackgroundFetchError::NONE) {
+ // TODO(crbug.com/780025): Log failures to UMA.
+ std::move(done_closure).Run();
+ return;
+ }
+
+ metadata->mutable_registration()->set_download_total(
+ metadata->registration().download_total() + request_info_->GetFileSize());
+
+ service_worker_context()->StoreRegistrationUserData(
+ registration_id_.service_worker_registration_id(),
+ registration_id_.origin().GetURL(),
+ {{RegistrationKey(registration_id_.unique_id()),
+ metadata->SerializeAsString()}},
+ base::BindOnce(&MarkRequestCompleteTask::DidStoreMetadata,
+ weak_factory_.GetWeakPtr(), std::move(done_closure)));
+}
+
+void MarkRequestCompleteTask::DidStoreMetadata(
+ base::OnceClosure done_closure,
+ blink::ServiceWorkerStatusCode status) {
+ // TODO(crbug.com/780025): Log failures to UMA.
+ std::move(done_closure).Run();
+}
- // TODO(rayankans): Update download stats.
+void MarkRequestCompleteTask::FinishWithError(
+ blink::mojom::BackgroundFetchError error) {
+ std::move(callback_).Run();
+ Finished();
}
} // namespace background_fetch
-} // namespace content \ No newline at end of file
+} // namespace content
diff --git a/chromium/content/browser/background_fetch/storage/mark_request_complete_task.h b/chromium/content/browser/background_fetch/storage/mark_request_complete_task.h
index b36c836ba04..9e96d1db298 100644
--- a/chromium/content/browser/background_fetch/storage/mark_request_complete_task.h
+++ b/chromium/content/browser/background_fetch/storage/mark_request_complete_task.h
@@ -10,7 +10,8 @@
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/background_fetch_request_info.h"
#include "content/browser/background_fetch/storage/database_task.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "content/browser/cache_storage/cache_storage_cache_handle.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
@@ -23,7 +24,7 @@ class MarkRequestCompleteTask : public DatabaseTask {
using MarkedCompleteCallback = base::OnceCallback<void()>;
MarkRequestCompleteTask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
BackgroundFetchRegistrationId registration_id,
scoped_refptr<BackgroundFetchRequestInfo> request_info,
MarkedCompleteCallback callback);
@@ -34,19 +35,44 @@ class MarkRequestCompleteTask : public DatabaseTask {
void Start() override;
private:
- void StoreResponse();
+ void StoreResponse(base::OnceClosure done_closure);
- void CreateAndStoreCompletedRequest(bool succeeded);
+ void PopulateResponseBody(ServiceWorkerResponse* response);
- void DidStoreCompletedRequest(ServiceWorkerStatusCode status);
+ void DidOpenCache(std::unique_ptr<ServiceWorkerResponse> response,
+ base::OnceClosure done_closure,
+ CacheStorageCacheHandle handle,
+ blink::mojom::CacheStorageError error);
- void DidDeleteActiveRequest(ServiceWorkerStatusCode status);
+ void DidWriteToCache(CacheStorageCacheHandle handle,
+ base::OnceClosure done_closure,
+ blink::mojom::CacheStorageError error);
+
+ void CreateAndStoreCompletedRequest(base::OnceClosure done_closure);
+
+ void DidStoreCompletedRequest(base::OnceClosure done_closure,
+ blink::ServiceWorkerStatusCode status);
+
+ void DidDeleteActiveRequest(base::OnceClosure done_closure,
+ blink::ServiceWorkerStatusCode status);
+
+ void UpdateMetadata(base::OnceClosure done_closure);
+
+ void DidGetMetadata(base::OnceClosure done_closure,
+ blink::mojom::BackgroundFetchError error,
+ std::unique_ptr<proto::BackgroundFetchMetadata> metadata);
+
+ void DidStoreMetadata(base::OnceClosure done_closure,
+ blink::ServiceWorkerStatusCode status);
+
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override;
BackgroundFetchRegistrationId registration_id_;
scoped_refptr<BackgroundFetchRequestInfo> request_info_;
MarkedCompleteCallback callback_;
proto::BackgroundFetchCompletedRequest completed_request_;
+ bool is_response_successful_ = true;
base::WeakPtrFactory<MarkRequestCompleteTask> weak_factory_; // Keep as last.
diff --git a/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.cc b/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.cc
index 107bb160409..1cc5c796f32 100644
--- a/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.cc
+++ b/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.cc
@@ -5,6 +5,7 @@
#include "content/browser/background_fetch/storage/start_next_pending_request_task.h"
#include "base/guid.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"
@@ -13,11 +14,11 @@ namespace content {
namespace background_fetch {
StartNextPendingRequestTask::StartNextPendingRequestTask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
int64_t service_worker_registration_id,
std::unique_ptr<proto::BackgroundFetchMetadata> metadata,
NextRequestCallback callback)
- : DatabaseTask(data_manager),
+ : DatabaseTask(host),
service_worker_registration_id_(service_worker_registration_id),
metadata_(std::move(metadata)),
callback_(std::move(callback)),
@@ -41,25 +42,26 @@ void StartNextPendingRequestTask::GetPendingRequests() {
void StartNextPendingRequestTask::DidGetPendingRequests(
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kNotFound:
case DatabaseStatus::kFailed:
// TODO(crbug.com/780025): Log failures to UMA.
- std::move(callback_).Run(nullptr /* request */);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
case DatabaseStatus::kOk:
if (data.empty()) {
// There are no pending requests.
- std::move(callback_).Run(nullptr /* request */);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
return;
}
}
if (!pending_request_.ParseFromString(data.front())) {
- NOTREACHED() << "Database is corrupt"; // TODO(crbug.com/780027): Nuke it.
+ // Service Worker database has been corrupted. Abandon fetches.
+ AbandonFetches(service_worker_registration_id_);
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
}
// Make sure there isn't already an Active Request.
@@ -74,12 +76,10 @@ void StartNextPendingRequestTask::DidGetPendingRequests(
void StartNextPendingRequestTask::DidFindActiveRequest(
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kFailed:
- // TODO(crbug.com/780025): Log failures to UMA.
- std::move(callback_).Run(nullptr /* request */);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
case DatabaseStatus::kNotFound:
CreateAndStoreActiveRequest();
@@ -87,8 +87,10 @@ void StartNextPendingRequestTask::DidFindActiveRequest(
case DatabaseStatus::kOk:
// We already stored the active request.
if (!active_request_.ParseFromString(data.front())) {
- NOTREACHED()
- << "Database is corrupt"; // TODO(crbug.com/780027): Nuke it.
+ // Service worker database has been corrupted. Abandon fetches.
+ AbandonFetches(service_worker_registration_id_);
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
+ return;
}
StartDownload();
return;
@@ -116,15 +118,13 @@ void StartNextPendingRequestTask::CreateAndStoreActiveRequest() {
}
void StartNextPendingRequestTask::DidStoreActiveRequest(
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kOk:
break;
case DatabaseStatus::kFailed:
case DatabaseStatus::kNotFound:
- // TODO(crbug.com/780025): Log failures to UMA.
- std::move(callback_).Run(nullptr /* request */);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
return;
}
StartDownload();
@@ -151,8 +151,15 @@ void StartNextPendingRequestTask::StartDownload() {
}
void StartNextPendingRequestTask::DidDeletePendingRequest(
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
// TODO(crbug.com/780025): Log failures to UMA.
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
+}
+
+void StartNextPendingRequestTask::FinishWithError(
+ blink::mojom::BackgroundFetchError error) {
+ if (callback_)
+ std::move(callback_).Run(nullptr /* request */);
Finished(); // Destroys |this|.
}
diff --git a/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.h b/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.h
index 476db6aa670..89ae0fb1bdf 100644
--- a/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.h
+++ b/chromium/content/browser/background_fetch/storage/start_next_pending_request_task.h
@@ -9,7 +9,7 @@
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/background_fetch_request_info.h"
#include "content/browser/background_fetch/storage/database_task.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
@@ -23,7 +23,7 @@ class StartNextPendingRequestTask : public DatabaseTask {
base::OnceCallback<void(scoped_refptr<BackgroundFetchRequestInfo>)>;
StartNextPendingRequestTask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
int64_t service_worker_registration_id,
std::unique_ptr<proto::BackgroundFetchMetadata> metadata,
NextRequestCallback callback);
@@ -37,18 +37,20 @@ class StartNextPendingRequestTask : public DatabaseTask {
void GetPendingRequests();
void DidGetPendingRequests(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void DidFindActiveRequest(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void CreateAndStoreActiveRequest();
- void DidStoreActiveRequest(ServiceWorkerStatusCode status);
+ void DidStoreActiveRequest(blink::ServiceWorkerStatusCode status);
void StartDownload();
- void DidDeletePendingRequest(ServiceWorkerStatusCode status);
+ void DidDeletePendingRequest(blink::ServiceWorkerStatusCode status);
+
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override;
int64_t service_worker_registration_id_;
std::unique_ptr<proto::BackgroundFetchMetadata> metadata_;
diff --git a/chromium/content/browser/background_fetch/storage/update_registration_ui_task.cc b/chromium/content/browser/background_fetch/storage/update_registration_ui_task.cc
index 5927855db09..38ad299080f 100644
--- a/chromium/content/browser/background_fetch/storage/update_registration_ui_task.cc
+++ b/chromium/content/browser/background_fetch/storage/update_registration_ui_task.cc
@@ -4,6 +4,8 @@
#include "content/browser/background_fetch/storage/update_registration_ui_task.h"
+#include "content/browser/background_fetch/background_fetch_data_manager.h"
+#include "content/browser/background_fetch/background_fetch_data_manager_observer.h"
#include "content/browser/background_fetch/storage/database_helpers.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
@@ -13,11 +15,11 @@ namespace content {
namespace background_fetch {
UpdateRegistrationUITask::UpdateRegistrationUITask(
- BackgroundFetchDataManager* data_manager,
+ DatabaseTaskHost* host,
const BackgroundFetchRegistrationId& registration_id,
const std::string& updated_title,
UpdateRegistrationUICallback callback)
- : DatabaseTask(data_manager),
+ : DatabaseTask(host),
registration_id_(registration_id),
updated_title_(updated_title),
callback_(std::move(callback)),
@@ -34,20 +36,26 @@ void UpdateRegistrationUITask::Start() {
weak_factory_.GetWeakPtr()));
}
-void UpdateRegistrationUITask::DidUpdateTitle(ServiceWorkerStatusCode status) {
+void UpdateRegistrationUITask::DidUpdateTitle(
+ blink::ServiceWorkerStatusCode status) {
switch (ToDatabaseStatus(status)) {
case DatabaseStatus::kOk:
break;
case DatabaseStatus::kFailed:
case DatabaseStatus::kNotFound:
- // TODO(crbug.com/780025): Log failures to UMA.
- std::move(callback_).Run(
- blink::mojom::BackgroundFetchError::STORAGE_ERROR);
- Finished(); // Destroys |this|.
+ FinishWithError(blink::mojom::BackgroundFetchError::STORAGE_ERROR);
return;
}
- std::move(callback_).Run(blink::mojom::BackgroundFetchError::NONE);
+ for (auto& observer : data_manager()->observers())
+ observer.OnUpdatedUI(registration_id_, updated_title_);
+
+ FinishWithError(blink::mojom::BackgroundFetchError::NONE);
+}
+
+void UpdateRegistrationUITask::FinishWithError(
+ blink::mojom::BackgroundFetchError error) {
+ std::move(callback_).Run(error);
Finished(); // Destroys |this|.
}
diff --git a/chromium/content/browser/background_fetch/storage/update_registration_ui_task.h b/chromium/content/browser/background_fetch/storage/update_registration_ui_task.h
index 08167977bd2..45a0a0fe8c5 100644
--- a/chromium/content/browser/background_fetch/storage/update_registration_ui_task.h
+++ b/chromium/content/browser/background_fetch/storage/update_registration_ui_task.h
@@ -11,7 +11,7 @@
#include "content/browser/background_fetch/background_fetch.pb.h"
#include "content/browser/background_fetch/storage/database_task.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
@@ -23,7 +23,7 @@ class UpdateRegistrationUITask : public DatabaseTask {
using UpdateRegistrationUICallback =
base::OnceCallback<void(blink::mojom::BackgroundFetchError)>;
- UpdateRegistrationUITask(BackgroundFetchDataManager* data_manager,
+ UpdateRegistrationUITask(DatabaseTaskHost* host,
const BackgroundFetchRegistrationId& registration_id,
const std::string& updated_title,
UpdateRegistrationUICallback callback);
@@ -33,7 +33,9 @@ class UpdateRegistrationUITask : public DatabaseTask {
void Start() override;
private:
- void DidUpdateTitle(ServiceWorkerStatusCode status);
+ void DidUpdateTitle(blink::ServiceWorkerStatusCode status);
+
+ void FinishWithError(blink::mojom::BackgroundFetchError error) override;
BackgroundFetchRegistrationId registration_id_;
std::string updated_title_;
diff --git a/chromium/content/browser/background_sync/background_sync_browsertest.cc b/chromium/content/browser/background_sync/background_sync_browsertest.cc
index e7afc3f8759..678766f9341 100644
--- a/chromium/content/browser/background_sync/background_sync_browsertest.cc
+++ b/chromium/content/browser/background_sync/background_sync_browsertest.cc
@@ -93,9 +93,9 @@ void RegistrationPendingDidGetSWRegistration(
const scoped_refptr<BackgroundSyncContext> sync_context,
const std::string& tag,
base::OnceCallback<void(bool)> callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
- ASSERT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
int64_t service_worker_id = registration->id();
BackgroundSyncManager* sync_manager = sync_context->background_sync_manager();
sync_manager->GetRegistrations(
@@ -111,9 +111,8 @@ void RegistrationPendingOnIOThread(
const GURL& url,
base::OnceCallback<void(bool)> callback) {
sw_context->FindReadyRegistrationForDocument(
- url, base::AdaptCallbackForRepeating(
- base::BindOnce(&RegistrationPendingDidGetSWRegistration,
- sync_context, tag, std::move(callback))));
+ url, base::BindOnce(&RegistrationPendingDidGetSWRegistration,
+ sync_context, tag, std::move(callback)));
}
void SetMaxSyncAttemptsOnIOThread(
diff --git a/chromium/content/browser/background_sync/background_sync_manager.cc b/chromium/content/browser/background_sync/background_sync_manager.cc
index 62d6f5a2d7d..0b5b90e9d39 100644
--- a/chromium/content/browser/background_sync/background_sync_manager.cc
+++ b/chromium/content/browser/background_sync/background_sync_manager.cc
@@ -21,15 +21,15 @@
#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_storage.h"
-#include "content/browser/service_worker/service_worker_type_converters.h"
#include "content/browser/storage_partition_impl.h"
-#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker.mojom.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/background_sync_controller.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/permission_manager.h"
+#include "content/public/browser/permission_controller.h"
#include "content/public/browser/permission_type.h"
+#include "third_party/blink/public/common/service_worker/service_worker_type_converters.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#if defined(OS_ANDROID)
@@ -80,8 +80,6 @@ BackgroundSyncController* GetBackgroundSyncControllerOnUIThread(
return browser_context->GetBackgroundSyncController();
}
-// Returns PermissionStatus::DENIED if the permission manager cannot be
-// accessed for any reason.
blink::mojom::PermissionStatus GetBackgroundSyncPermissionOnUIThread(
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
const GURL& origin) {
@@ -92,13 +90,12 @@ blink::mojom::PermissionStatus GetBackgroundSyncPermissionOnUIThread(
if (!browser_context)
return blink::mojom::PermissionStatus::DENIED;
- PermissionManager* permission_manager =
- browser_context->GetPermissionManager();
- if (!permission_manager)
- return blink::mojom::PermissionStatus::DENIED;
+ PermissionController* permission_controller =
+ BrowserContext::GetPermissionController(browser_context);
+ DCHECK(permission_controller);
// The requesting origin always matches the embedding origin.
- return permission_manager->GetPermissionStatus(
+ return permission_controller->GetPermissionStatus(
PermissionType::BACKGROUND_SYNC, origin, origin);
}
@@ -159,14 +156,15 @@ void OnSyncEventFinished(scoped_refptr<ServiceWorkerVersion> active_version,
dispatch_event_time)) {
return;
}
- std::move(callback).Run(mojo::ConvertTo<ServiceWorkerStatusCode>(status));
+ std::move(callback).Run(
+ mojo::ConvertTo<blink::ServiceWorkerStatusCode>(status));
}
void DidStartWorkerForSyncEvent(
base::OnceCallback<void(ServiceWorkerVersion::StatusCallback)> task,
ServiceWorkerVersion::StatusCallback callback,
- ServiceWorkerStatusCode start_worker_status) {
- if (start_worker_status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode start_worker_status) {
+ if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(start_worker_status);
return;
}
@@ -279,8 +277,8 @@ void BackgroundSyncManager::EmulateDispatchSyncEvent(
bool last_chance,
ServiceWorkerVersion::StatusCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- ServiceWorkerStatusCode code = CanEmulateSyncEvent(active_version);
- if (code != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode code = CanEmulateSyncEvent(active_version);
+ if (code != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(code);
return;
}
@@ -367,19 +365,20 @@ void BackgroundSyncManager::InitDidGetControllerParameters(
return;
}
- GetDataFromBackend(kBackgroundSyncUserDataKey,
- base::AdaptCallbackForRepeating(base::BindOnce(
- &BackgroundSyncManager::InitDidGetDataFromBackend,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback))));
+ GetDataFromBackend(
+ kBackgroundSyncUserDataKey,
+ base::BindOnce(&BackgroundSyncManager::InitDidGetDataFromBackend,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void BackgroundSyncManager::InitDidGetDataFromBackend(
base::OnceClosure callback,
const std::vector<std::pair<int64_t, std::string>>& user_data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
+ if (status != blink::ServiceWorkerStatusCode::kOk &&
+ status != blink::ServiceWorkerStatusCode::kErrorNotFound) {
LOG(ERROR) << "BackgroundSync failed to init due to backend failure.";
DisableAndClearManager(std::move(callback));
return;
@@ -597,18 +596,17 @@ void BackgroundSyncManager::DisableAndClearManager(base::OnceClosure callback) {
// loading from storage), so reload the registrations from storage again.
GetDataFromBackend(
kBackgroundSyncUserDataKey,
- base::AdaptCallbackForRepeating(base::BindOnce(
- &BackgroundSyncManager::DisableAndClearDidGetRegistrations,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback))));
+ base::BindOnce(&BackgroundSyncManager::DisableAndClearDidGetRegistrations,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void BackgroundSyncManager::DisableAndClearDidGetRegistrations(
base::OnceClosure callback,
const std::vector<std::pair<int64_t, std::string>>& user_data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK || user_data.empty()) {
+ if (status != blink::ServiceWorkerStatusCode::kOk || user_data.empty()) {
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
std::move(callback));
return;
@@ -620,15 +618,14 @@ void BackgroundSyncManager::DisableAndClearDidGetRegistrations(
for (const auto& sw_id_and_regs : user_data) {
service_worker_context_->ClearRegistrationUserData(
sw_id_and_regs.first, {kBackgroundSyncUserDataKey},
- base::AdaptCallbackForRepeating(base::BindOnce(
- &BackgroundSyncManager::DisableAndClearManagerClearedOne,
- weak_ptr_factory_.GetWeakPtr(), barrier_closure)));
+ base::BindOnce(&BackgroundSyncManager::DisableAndClearManagerClearedOne,
+ weak_ptr_factory_.GetWeakPtr(), barrier_closure));
}
}
void BackgroundSyncManager::DisableAndClearManagerClearedOne(
base::OnceClosure barrier_closure,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// The status doesn't matter at this point, there is nothing else to be done.
@@ -695,10 +692,10 @@ void BackgroundSyncManager::RegisterDidStore(
int64_t sw_registration_id,
const BackgroundSyncRegistration& new_registration,
StatusAndRegistrationCallback callback,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status == SERVICE_WORKER_ERROR_NOT_FOUND) {
+ if (status == blink::ServiceWorkerStatusCode::kErrorNotFound) {
// The service worker registration is gone.
active_registrations_.erase(sw_registration_id);
RecordFailureAndPostError(BACKGROUND_SYNC_STATUS_STORAGE_ERROR,
@@ -706,7 +703,7 @@ void BackgroundSyncManager::RegisterDidStore(
return;
}
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
LOG(ERROR) << "BackgroundSync failed to store registration due to backend "
"failure.";
BackgroundSyncMetrics::CountRegisterFailure(
@@ -767,8 +764,7 @@ void BackgroundSyncManager::StoreDataInBackend(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_worker_context_->StoreRegistrationUserData(
- sw_registration_id, origin, {{backend_key, data}},
- base::AdaptCallbackForRepeating(std::move(callback)));
+ sw_registration_id, origin, {{backend_key, data}}, std::move(callback));
}
void BackgroundSyncManager::GetDataFromBackend(
@@ -794,7 +790,7 @@ void BackgroundSyncManager::DispatchSyncEvent(
base::BindOnce(&DidStartWorkerForSyncEvent,
base::BindOnce(&BackgroundSyncManager::DispatchSyncEvent,
weak_ptr_factory_.GetWeakPtr(), tag,
- std::move(active_version), last_chance),
+ active_version, last_chance),
std::move(callback)));
return;
}
@@ -807,10 +803,10 @@ void BackgroundSyncManager::DispatchSyncEvent(
parameters_->max_sync_event_duration,
ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
- active_version->event_dispatcher()->DispatchSyncEvent(
+ active_version->endpoint()->DispatchSyncEvent(
tag, last_chance, parameters_->max_sync_event_duration,
- base::BindOnce(&OnSyncEventFinished, std::move(active_version),
- request_id, std::move(repeating_callback)));
+ base::BindOnce(&OnSyncEventFinished, active_version, request_id,
+ std::move(repeating_callback)));
}
void BackgroundSyncManager::ScheduleDelayedTask(base::OnceClosure callback,
@@ -821,8 +817,8 @@ void BackgroundSyncManager::ScheduleDelayedTask(base::OnceClosure callback,
void BackgroundSyncManager::HasMainFrameProviderHost(const GURL& origin,
BoolCallback callback) {
- service_worker_context_->HasMainFrameProviderHost(
- origin, base::AdaptCallbackForRepeating(std::move(callback)));
+ service_worker_context_->HasMainFrameProviderHost(origin,
+ std::move(callback));
}
void BackgroundSyncManager::GetRegistrationsImpl(
@@ -1012,10 +1008,10 @@ void BackgroundSyncManager::FireReadyEventsDidFindRegistration(
BackgroundSyncRegistration::RegistrationId registration_id,
base::OnceClosure event_fired_callback,
base::OnceClosure event_completed_callback,
- ServiceWorkerStatusCode service_worker_status,
+ blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (service_worker_status != SERVICE_WORKER_OK) {
+ if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, std::move(event_fired_callback));
base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -1063,7 +1059,7 @@ void BackgroundSyncManager::EventComplete(
int64_t service_worker_id,
const std::string& tag,
base::OnceClosure callback,
- ServiceWorkerStatusCode status_code) {
+ blink::ServiceWorkerStatusCode status_code) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (disabled_) {
@@ -1081,7 +1077,7 @@ void BackgroundSyncManager::EventComplete(
void BackgroundSyncManager::EventCompleteImpl(
int64_t service_worker_id,
const std::string& tag,
- ServiceWorkerStatusCode status_code,
+ blink::ServiceWorkerStatusCode status_code,
base::OnceClosure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -1114,7 +1110,7 @@ void BackgroundSyncManager::EventCompleteImpl(
HasMainFrameProviderHost(
sw_registration->pattern().GetOrigin(),
base::BindOnce(&BackgroundSyncMetrics::RecordEventResult,
- status_code == SERVICE_WORKER_OK));
+ status_code == blink::ServiceWorkerStatusCode::kOk));
}
bool registration_completed = true;
@@ -1126,7 +1122,7 @@ void BackgroundSyncManager::EventCompleteImpl(
registration->set_sync_state(blink::mojom::BackgroundSyncState::PENDING);
registration->set_num_attempts(0);
registration_completed = false;
- } else if (status_code != SERVICE_WORKER_OK &&
+ } else if (status_code != blink::ServiceWorkerStatusCode::kOk &&
can_retry) { // Sync failed but can retry
registration->set_sync_state(blink::mojom::BackgroundSyncState::PENDING);
registration->set_delay_until(clock_->Now() +
@@ -1156,10 +1152,10 @@ void BackgroundSyncManager::EventCompleteImpl(
void BackgroundSyncManager::EventCompleteDidStore(
int64_t service_worker_id,
base::OnceClosure callback,
- ServiceWorkerStatusCode status_code) {
+ blink::ServiceWorkerStatusCode status_code) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status_code == SERVICE_WORKER_ERROR_NOT_FOUND) {
+ if (status_code == blink::ServiceWorkerStatusCode::kErrorNotFound) {
// The registration is gone.
active_registrations_.erase(service_worker_id);
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
@@ -1167,7 +1163,7 @@ void BackgroundSyncManager::EventCompleteDidStore(
return;
}
- if (status_code != SERVICE_WORKER_OK) {
+ if (status_code != blink::ServiceWorkerStatusCode::kOk) {
LOG(ERROR) << "BackgroundSync failed to store registration due to backend "
"failure.";
DisableAndClearManager(std::move(callback));
@@ -1227,16 +1223,16 @@ base::OnceClosure BackgroundSyncManager::MakeEmptyCompletion() {
return op_scheduler_.WrapCallbackToRunNext(base::DoNothing::Once());
}
-ServiceWorkerStatusCode BackgroundSyncManager::CanEmulateSyncEvent(
+blink::ServiceWorkerStatusCode BackgroundSyncManager::CanEmulateSyncEvent(
scoped_refptr<ServiceWorkerVersion> active_version) {
if (!active_version)
- return SERVICE_WORKER_ERROR_FAILED;
+ return blink::ServiceWorkerStatusCode::kErrorFailed;
if (!network_observer_->NetworkSufficient(NETWORK_STATE_ONLINE))
- return SERVICE_WORKER_ERROR_NETWORK;
+ return blink::ServiceWorkerStatusCode::kErrorNetwork;
int64_t registration_id = active_version->registration_id();
if (base::ContainsKey(emulated_offline_sw_, registration_id))
- return SERVICE_WORKER_ERROR_NETWORK;
- return SERVICE_WORKER_OK;
+ return blink::ServiceWorkerStatusCode::kErrorNetwork;
+ return blink::ServiceWorkerStatusCode::kOk;
}
} // namespace content
diff --git a/chromium/content/browser/background_sync/background_sync_manager.h b/chromium/content/browser/background_sync/background_sync_manager.h
index 38091eaa269..84449a91006 100644
--- a/chromium/content/browser/background_sync/background_sync_manager.h
+++ b/chromium/content/browser/background_sync/background_sync_manager.h
@@ -26,9 +26,9 @@
#include "content/browser/service_worker/service_worker_context_core_observer.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/public/browser/background_sync_parameters.h"
#include "content/public/browser/browser_thread.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/platform/modules/background_sync/background_sync.mojom.h"
#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
#include "url/gurl.h"
@@ -166,9 +166,9 @@ class CONTENT_EXPORT BackgroundSyncManager
void DisableAndClearDidGetRegistrations(
base::OnceClosure callback,
const std::vector<std::pair<int64_t, std::string>>& user_data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void DisableAndClearManagerClearedOne(base::OnceClosure barrier_closure,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// Returns the existing registration or nullptr if it cannot be found.
BackgroundSyncRegistration* LookupActiveRegistration(
@@ -196,7 +196,7 @@ class CONTENT_EXPORT BackgroundSyncManager
void InitDidGetDataFromBackend(
base::OnceClosure callback,
const std::vector<std::pair<int64_t, std::string>>& user_data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// Register callbacks
void RegisterCheckIfHasMainFrame(
@@ -219,7 +219,7 @@ class CONTENT_EXPORT BackgroundSyncManager
void RegisterDidStore(int64_t sw_registration_id,
const BackgroundSyncRegistration& new_registration,
StatusAndRegistrationCallback callback,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// GetRegistrations callbacks
void GetRegistrationsImpl(int64_t sw_registration_id,
@@ -247,7 +247,7 @@ class CONTENT_EXPORT BackgroundSyncManager
BackgroundSyncRegistration::RegistrationId registration_id,
base::OnceClosure event_fired_callback,
base::OnceClosure event_completed_callback,
- ServiceWorkerStatusCode service_worker_status,
+ blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> service_worker_registration);
void FireReadyEventsAllEventsFiring(base::OnceClosure callback);
@@ -257,14 +257,14 @@ class CONTENT_EXPORT BackgroundSyncManager
int64_t service_worker_id,
const std::string& tag,
base::OnceClosure callback,
- ServiceWorkerStatusCode status_code);
+ blink::ServiceWorkerStatusCode status_code);
void EventCompleteImpl(int64_t service_worker_id,
const std::string& tag,
- ServiceWorkerStatusCode status_code,
+ blink::ServiceWorkerStatusCode status_code,
base::OnceClosure callback);
void EventCompleteDidStore(int64_t service_worker_id,
base::OnceClosure callback,
- ServiceWorkerStatusCode status_code);
+ blink::ServiceWorkerStatusCode status_code);
// Called when all sync events have completed.
static void OnAllSyncEventsCompleted(const base::TimeTicks& start_time,
@@ -285,7 +285,7 @@ class CONTENT_EXPORT BackgroundSyncManager
base::OnceClosure MakeEmptyCompletion();
- ServiceWorkerStatusCode CanEmulateSyncEvent(
+ blink::ServiceWorkerStatusCode CanEmulateSyncEvent(
scoped_refptr<ServiceWorkerVersion> active_version);
SWIdToRegistrationsMap active_registrations_;
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 5fc543bee78..077a39c679d 100644
--- a/chromium/content/browser/background_sync/background_sync_manager_unittest.cc
+++ b/chromium/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -25,7 +25,6 @@
#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_dispatcher_host.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"
@@ -58,25 +57,27 @@ const char kScript2[] = "https://example.com/b/script.js";
void RegisterServiceWorkerCallback(bool* called,
int64_t* store_registration_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id) {
- EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
+ << blink::ServiceWorkerStatusToString(status);
*called = true;
*store_registration_id = registration_id;
}
void FindServiceWorkerRegistrationCallback(
scoped_refptr<ServiceWorkerRegistration>* out_registration,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
- EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
+ << blink::ServiceWorkerStatusToString(status);
*out_registration = std::move(registration);
}
void UnregisterServiceWorkerCallback(bool* called,
- ServiceWorkerStatusCode code) {
- EXPECT_EQ(SERVICE_WORKER_OK, code);
+ blink::ServiceWorkerStatusCode code) {
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, code);
*called = true;
}
@@ -108,7 +109,7 @@ class BackgroundSyncManagerTest : public testing::Test {
ON_CALL(*mock_permission_manager,
GetPermissionStatus(PermissionType::BACKGROUND_SYNC, _, _))
.WillByDefault(Return(blink::mojom::PermissionStatus::GRANTED));
- helper_->browser_context()->SetPermissionManager(
+ helper_->browser_context()->SetPermissionControllerDelegate(
std::move(mock_permission_manager));
// Create a StoragePartition with the correct BrowserContext so that the
@@ -140,15 +141,13 @@ class BackgroundSyncManagerTest : public testing::Test {
options2.scope = GURL(kPattern2);
helper_->context()->RegisterServiceWorker(
GURL(kScript1), options1,
- base::AdaptCallbackForRepeating(
- base::BindOnce(&RegisterServiceWorkerCallback, &called_1,
- &sw_registration_id_1_)));
+ base::BindOnce(&RegisterServiceWorkerCallback, &called_1,
+ &sw_registration_id_1_));
helper_->context()->RegisterServiceWorker(
GURL(kScript2), options2,
- base::AdaptCallbackForRepeating(
- base::BindOnce(&RegisterServiceWorkerCallback, &called_2,
- &sw_registration_id_2_)));
+ base::BindOnce(&RegisterServiceWorkerCallback, &called_2,
+ &sw_registration_id_2_));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called_1);
EXPECT_TRUE(called_2);
@@ -157,13 +156,13 @@ class BackgroundSyncManagerTest : public testing::Test {
// calling BackgroundSyncManager::Register.
helper_->context_wrapper()->FindReadyRegistrationForId(
sw_registration_id_1_, GURL(kPattern1).GetOrigin(),
- base::AdaptCallbackForRepeating(base::BindOnce(
- FindServiceWorkerRegistrationCallback, &sw_registration_1_)));
+ base::BindOnce(FindServiceWorkerRegistrationCallback,
+ &sw_registration_1_));
helper_->context_wrapper()->FindReadyRegistrationForId(
sw_registration_id_2_, GURL(kPattern1).GetOrigin(),
- base::AdaptCallbackForRepeating(base::BindOnce(
- FindServiceWorkerRegistrationCallback, &sw_registration_2_)));
+ base::BindOnce(FindServiceWorkerRegistrationCallback,
+ &sw_registration_2_));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(sw_registration_1_);
EXPECT_TRUE(sw_registration_2_);
@@ -265,9 +264,9 @@ class BackgroundSyncManagerTest : public testing::Test {
return callback_status_ == BACKGROUND_SYNC_STATUS_OK;
}
- MockPermissionManager* GetPermissionManager() {
+ MockPermissionManager* GetPermissionControllerDelegate() {
return static_cast<MockPermissionManager*>(
- helper_->browser_context()->GetPermissionManager());
+ helper_->browser_context()->GetPermissionControllerDelegate());
}
bool GetRegistration(
@@ -325,7 +324,7 @@ class BackgroundSyncManagerTest : public testing::Test {
helper_->browser_context()->GetBackgroundSyncController());
}
- void StorageRegistrationCallback(ServiceWorkerStatusCode result) {
+ void StorageRegistrationCallback(blink::ServiceWorkerStatusCode result) {
callback_sw_status_code_ = result;
}
@@ -333,8 +332,7 @@ class BackgroundSyncManagerTest : public testing::Test {
bool called = false;
helper_->context()->UnregisterServiceWorker(
PatternForSWId(sw_registration_id),
- base::AdaptCallbackForRepeating(
- base::BindOnce(&UnregisterServiceWorkerCallback, &called)));
+ base::BindOnce(&UnregisterServiceWorkerCallback, &called));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
}
@@ -352,7 +350,7 @@ class BackgroundSyncManagerTest : public testing::Test {
}
void DispatchSyncStatusCallback(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerVersion> active_version,
ServiceWorkerVersion::StatusCallback callback) {
sync_events_called_++;
@@ -362,13 +360,13 @@ class BackgroundSyncManagerTest : public testing::Test {
void InitSyncEventTest() {
SetupForSyncEvent(base::BindRepeating(
&BackgroundSyncManagerTest::DispatchSyncStatusCallback,
- base::Unretained(this), SERVICE_WORKER_OK));
+ base::Unretained(this), blink::ServiceWorkerStatusCode::kOk));
}
void InitFailedSyncEventTest() {
SetupForSyncEvent(base::BindRepeating(
&BackgroundSyncManagerTest::DispatchSyncStatusCallback,
- base::Unretained(this), SERVICE_WORKER_ERROR_FAILED));
+ base::Unretained(this), blink::ServiceWorkerStatusCode::kErrorFailed));
}
void DispatchSyncDelayedCallback(
@@ -433,7 +431,8 @@ class BackgroundSyncManagerTest : public testing::Test {
std::unique_ptr<BackgroundSyncRegistration> callback_registration_;
std::vector<std::unique_ptr<BackgroundSyncRegistration>>
callback_registrations_;
- ServiceWorkerStatusCode callback_sw_status_code_ = SERVICE_WORKER_OK;
+ blink::ServiceWorkerStatusCode callback_sw_status_code_ =
+ blink::ServiceWorkerStatusCode::kOk;
int sync_events_called_ = 0;
ServiceWorkerVersion::StatusCallback sync_fired_callback_;
};
@@ -485,7 +484,8 @@ TEST_F(BackgroundSyncManagerTest, RegisterBadBackend) {
TEST_F(BackgroundSyncManagerTest, RegisterPermissionDenied) {
GURL expected_origin = GURL(kPattern1).GetOrigin();
- MockPermissionManager* mock_permission_manager = GetPermissionManager();
+ MockPermissionManager* mock_permission_manager =
+ GetPermissionControllerDelegate();
EXPECT_CALL(*mock_permission_manager,
GetPermissionStatus(PermissionType::BACKGROUND_SYNC,
@@ -496,7 +496,8 @@ TEST_F(BackgroundSyncManagerTest, RegisterPermissionDenied) {
TEST_F(BackgroundSyncManagerTest, RegisterPermissionGranted) {
GURL expected_origin = GURL(kPattern1).GetOrigin();
- MockPermissionManager* mock_permission_manager = GetPermissionManager();
+ MockPermissionManager* mock_permission_manager =
+ GetPermissionControllerDelegate();
EXPECT_CALL(*mock_permission_manager,
GetPermissionStatus(PermissionType::BACKGROUND_SYNC,
@@ -652,14 +653,12 @@ TEST_F(BackgroundSyncManagerTest, SequentialOperations) {
bool get_registrations_called = false;
test_background_sync_manager_->Register(
sw_registration_id_1_, sync_options_1_,
- base::AdaptCallbackForRepeating(base::BindOnce(
- &BackgroundSyncManagerTest::StatusAndRegistrationCallback,
- base::Unretained(this), &register_called)));
+ base::BindOnce(&BackgroundSyncManagerTest::StatusAndRegistrationCallback,
+ base::Unretained(this), &register_called));
test_background_sync_manager_->GetRegistrations(
sw_registration_id_1_,
- base::AdaptCallbackForRepeating(base::BindOnce(
- &BackgroundSyncManagerTest::StatusAndRegistrationsCallback,
- base::Unretained(this), &get_registrations_called)));
+ base::BindOnce(&BackgroundSyncManagerTest::StatusAndRegistrationsCallback,
+ base::Unretained(this), &get_registrations_called));
base::RunLoop().RunUntilIdle();
// Init should be blocked while loading from the backend.
@@ -694,9 +693,8 @@ TEST_F(BackgroundSyncManagerTest,
bool callback_called = false;
test_background_sync_manager_->Register(
sw_registration_id_1_, sync_options_2_,
- base::AdaptCallbackForRepeating(base::BindOnce(
- &BackgroundSyncManagerTest::StatusAndRegistrationCallback,
- base::Unretained(this), &callback_called)));
+ base::BindOnce(&BackgroundSyncManagerTest::StatusAndRegistrationCallback,
+ base::Unretained(this), &callback_called));
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(callback_called);
@@ -821,13 +819,14 @@ TEST_F(BackgroundSyncManagerTest, ReregisterMidSyncFirstAttemptFails) {
// The first sync attempt fails.
ASSERT_TRUE(sync_fired_callback_);
- std::move(sync_fired_callback_).Run(SERVICE_WORKER_ERROR_FAILED);
+ std::move(sync_fired_callback_)
+ .Run(blink::ServiceWorkerStatusCode::kErrorFailed);
base::RunLoop().RunUntilIdle();
// It should fire again since it was reregistered mid-sync.
EXPECT_TRUE(GetRegistration(sync_options_1_));
ASSERT_TRUE(sync_fired_callback_);
- std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
+ std::move(sync_fired_callback_).Run(blink::ServiceWorkerStatusCode::kOk);
EXPECT_FALSE(GetRegistration(sync_options_1_));
}
@@ -840,13 +839,13 @@ TEST_F(BackgroundSyncManagerTest, ReregisterMidSyncFirstAttemptSucceeds) {
// The first sync event succeeds.
ASSERT_TRUE(sync_fired_callback_);
- std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
+ std::move(sync_fired_callback_).Run(blink::ServiceWorkerStatusCode::kOk);
base::RunLoop().RunUntilIdle();
// It should fire again since it was reregistered mid-sync.
EXPECT_TRUE(GetRegistration(sync_options_1_));
ASSERT_TRUE(sync_fired_callback_);
- std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
+ std::move(sync_fired_callback_).Run(blink::ServiceWorkerStatusCode::kOk);
EXPECT_FALSE(GetRegistration(sync_options_1_));
}
@@ -900,7 +899,7 @@ 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.
ASSERT_TRUE(sync_fired_callback_);
- std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
+ std::move(sync_fired_callback_).Run(blink::ServiceWorkerStatusCode::kOk);
base::RunLoop().RunUntilIdle();
}
@@ -989,7 +988,7 @@ TEST_F(BackgroundSyncManagerTest, DelayMidSync) {
// Finish firing the event and verify that the registration is removed.
ASSERT_TRUE(sync_fired_callback_);
- std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
+ std::move(sync_fired_callback_).Run(blink::ServiceWorkerStatusCode::kOk);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, sync_events_called_);
EXPECT_FALSE(GetRegistration(sync_options_1_));
@@ -1002,7 +1001,7 @@ TEST_F(BackgroundSyncManagerTest, BadBackendMidSync) {
test_background_sync_manager_->set_corrupt_backend(true);
ASSERT_TRUE(sync_fired_callback_);
- std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
+ std::move(sync_fired_callback_).Run(blink::ServiceWorkerStatusCode::kOk);
base::RunLoop().RunUntilIdle();
// The backend should now be disabled because it couldn't unregister the
@@ -1019,7 +1018,7 @@ TEST_F(BackgroundSyncManagerTest, UnregisterServiceWorkerMidSync) {
UnregisterServiceWorker(sw_registration_id_1_);
ASSERT_TRUE(sync_fired_callback_);
- std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
+ std::move(sync_fired_callback_).Run(blink::ServiceWorkerStatusCode::kOk);
// The backend isn't disabled, but the first service worker registration is
// gone.
@@ -1158,7 +1157,7 @@ TEST_F(BackgroundSyncManagerTest, WakeBrowserCalled) {
// Finish the sync.
ASSERT_TRUE(sync_fired_callback_);
- std::move(sync_fired_callback_).Run(SERVICE_WORKER_OK);
+ std::move(sync_fired_callback_).Run(blink::ServiceWorkerStatusCode::kOk);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(GetController()->run_in_background_enabled());
}
@@ -1402,8 +1401,8 @@ TEST_F(BackgroundSyncManagerTest, EmulateOfflineMultipleClients) {
static void EmulateDispatchSyncEventCallback(
bool* was_called,
- ServiceWorkerStatusCode* code,
- ServiceWorkerStatusCode status_code) {
+ blink::ServiceWorkerStatusCode* code,
+ blink::ServiceWorkerStatusCode status_code) {
*was_called = true;
*code = status_code;
}
@@ -1411,13 +1410,14 @@ static void EmulateDispatchSyncEventCallback(
TEST_F(BackgroundSyncManagerTest, EmulateDispatchSyncEvent) {
InitSyncEventTest();
bool was_called = false;
- ServiceWorkerStatusCode code = SERVICE_WORKER_ERROR_MAX_VALUE;
+ blink::ServiceWorkerStatusCode code =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
background_sync_manager_->EmulateDispatchSyncEvent(
"emulated_tag", sw_registration_1_->active_version(), false,
base::BindOnce(EmulateDispatchSyncEventCallback, &was_called, &code));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- EXPECT_EQ(SERVICE_WORKER_OK, code);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, code);
EXPECT_EQ(1, sync_events_called_);
@@ -1425,36 +1425,34 @@ TEST_F(BackgroundSyncManagerTest, EmulateDispatchSyncEvent) {
true);
was_called = false;
- code = SERVICE_WORKER_ERROR_MAX_VALUE;
background_sync_manager_->EmulateDispatchSyncEvent(
"emulated_tag", sw_registration_1_->active_version(), false,
base::BindOnce(EmulateDispatchSyncEventCallback, &was_called, &code));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, code);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNetwork, code);
background_sync_manager_->EmulateServiceWorkerOffline(sw_registration_id_1_,
false);
SetNetwork(net::NetworkChangeNotifier::CONNECTION_NONE);
was_called = false;
- code = SERVICE_WORKER_ERROR_MAX_VALUE;
+ code = blink::ServiceWorkerStatusCode::kOk;
background_sync_manager_->EmulateDispatchSyncEvent(
"emulated_tag", sw_registration_1_->active_version(), false,
base::BindOnce(EmulateDispatchSyncEventCallback, &was_called, &code));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, code);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNetwork, code);
SetNetwork(net::NetworkChangeNotifier::CONNECTION_WIFI);
was_called = false;
- code = SERVICE_WORKER_ERROR_MAX_VALUE;
background_sync_manager_->EmulateDispatchSyncEvent(
"emulated_tag", sw_registration_1_->active_version(), false,
base::BindOnce(EmulateDispatchSyncEventCallback, &was_called, &code));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- EXPECT_EQ(SERVICE_WORKER_OK, code);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, code);
EXPECT_EQ(2, sync_events_called_);
}
diff --git a/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc b/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc
index aecf773c011..4f6d1aa3caf 100644
--- a/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc
+++ b/chromium/content/browser/background_sync/background_sync_service_impl_unittest.cc
@@ -41,19 +41,21 @@ const char kServiceWorkerScript[] = "https://example.com/a/script.js";
// Callbacks from SetUp methods
void RegisterServiceWorkerCallback(bool* called,
int64_t* store_registration_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id) {
- EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
+ << blink::ServiceWorkerStatusToString(status);
*called = true;
*store_registration_id = registration_id;
}
void FindServiceWorkerRegistrationCallback(
scoped_refptr<ServiceWorkerRegistration>* out_registration,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
- EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
+ << blink::ServiceWorkerStatusToString(status);
*out_registration = std::move(registration);
}
@@ -126,7 +128,7 @@ class BackgroundSyncServiceImplTest : public testing::Test {
GetPermissionStatus(PermissionType::BACKGROUND_SYNC, _, _))
.WillByDefault(
testing::Return(blink::mojom::PermissionStatus::GRANTED));
- embedded_worker_helper_->browser_context()->SetPermissionManager(
+ embedded_worker_helper_->browser_context()->SetPermissionControllerDelegate(
std::move(mock_permission_manager));
}
@@ -167,15 +169,15 @@ class BackgroundSyncServiceImplTest : public testing::Test {
options.scope = GURL(kServiceWorkerPattern);
embedded_worker_helper_->context()->RegisterServiceWorker(
GURL(kServiceWorkerScript), options,
- base::AdaptCallbackForRepeating(base::BindOnce(
- &RegisterServiceWorkerCallback, &called, &sw_registration_id_)));
+ base::BindOnce(&RegisterServiceWorkerCallback, &called,
+ &sw_registration_id_));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
embedded_worker_helper_->context_wrapper()->FindReadyRegistrationForId(
sw_registration_id_, GURL(kServiceWorkerPattern).GetOrigin(),
- base::AdaptCallbackForRepeating(base::BindOnce(
- FindServiceWorkerRegistrationCallback, &sw_registration_)));
+ base::BindOnce(FindServiceWorkerRegistrationCallback,
+ &sw_registration_));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(sw_registration_);
}
diff --git a/chromium/content/browser/bad_message.h b/chromium/content/browser/bad_message.h
index 20115161d55..f5e39320ca6 100644
--- a/chromium/content/browser/bad_message.h
+++ b/chromium/content/browser/bad_message.h
@@ -199,9 +199,9 @@ enum BadMessageReason {
RFH_BASE_URL_FOR_DATA_URL_SPECIFIED = 171,
RFPH_ILLEGAL_UPLOAD_PARAMS = 172,
OBSOLETE_SWDH_PROVIDER_CREATED_ILLEGAL_TYPE = 173,
- SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_NOT_WINDOW = 174,
- SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_SERVICE_WORKER = 175,
- SWDH_PROVIDER_CREATED_DUPLICATE_ID = 176,
+ OBSOLETE_SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_NOT_WINDOW = 174,
+ OBSOLETE_SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_SERVICE_WORKER = 175,
+ OBSOLETE_SWDH_PROVIDER_CREATED_DUPLICATE_ID = 176,
OBSOLETE_SWDH_PROVIDER_CREATED_BAD_ID = 177,
RFH_KEEP_ALIVE_HANDLE_REQUESTED_INCORRECTLY = 178,
BFSI_INVALID_UNIQUE_ID = 179,
diff --git a/chromium/content/browser/battery_monitor_browsertest.cc b/chromium/content/browser/battery_monitor_browsertest.cc
index 47fd0272c78..ebbad43bd15 100644
--- a/chromium/content/browser/battery_monitor_browsertest.cc
+++ b/chromium/content/browser/battery_monitor_browsertest.cc
@@ -71,9 +71,7 @@ class MockBatteryMonitor : public device::mojom::BatteryMonitor {
class BatteryMonitorTest : public ContentBrowserTest {
public:
- BatteryMonitorTest() = default;
-
- void SetUpOnMainThread() override {
+ BatteryMonitorTest() {
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
@@ -84,6 +82,11 @@ class BatteryMonitorTest : public ContentBrowserTest {
base::Unretained(mock_battery_monitor_.get())));
}
+ ~BatteryMonitorTest() override {
+ service_manager::ServiceContext::ClearGlobalBindersForTesting(
+ device::mojom::kServiceName);
+ }
+
protected:
MockBatteryMonitor* mock_battery_monitor() {
return mock_battery_monitor_.get();
diff --git a/chromium/content/browser/blob_storage/OWNERS b/chromium/content/browser/blob_storage/OWNERS
index e77e62a6a6f..49592325cf3 100644
--- a/chromium/content/browser/blob_storage/OWNERS
+++ b/chromium/content/browser/blob_storage/OWNERS
@@ -2,4 +2,4 @@ dmurph@chromium.org
mek@chromium.org
# TEAM: storage-dev@chromium.org
-# COMPONENT: Blink>FileAPI
+# COMPONENT: Blink>Storage>FileAPI
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 f41b5cdcf39..4c48d46dd28 100644
--- a/chromium/content/browser/blob_storage/blob_internals_url_loader.cc
+++ b/chromium/content/browser/blob_storage/blob_internals_url_loader.cc
@@ -22,7 +22,7 @@ void StartBlobInternalsURLLoader(
network::mojom::URLLoaderClientPtr client;
client.Bind(std::move(client_info));
- client->OnReceiveResponse(resource_response, nullptr);
+ client->OnReceiveResponse(resource_response);
std::string output = storage::ViewBlobInternalsJob::GenerateHTML(
blob_storage_context->context());
diff --git a/chromium/content/browser/blob_storage/blob_url_browsertest.cc b/chromium/content/browser/blob_storage/blob_url_browsertest.cc
index c74d2578ddf..dfb724f3c95 100644
--- a/chromium/content/browser/blob_storage/blob_url_browsertest.cc
+++ b/chromium/content/browser/blob_storage/blob_url_browsertest.cc
@@ -4,8 +4,10 @@
#include "base/macros.h"
#include "base/strings/pattern.h"
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/web_contents/web_contents_impl.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"
@@ -14,15 +16,20 @@
#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/blink/public/common/features.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace content {
// Tests of the blob: URL scheme.
-class BlobUrlBrowserTest : public ContentBrowserTest {
+class BlobUrlBrowserTest : public ContentBrowserTest,
+ public testing::WithParamInterface<bool> {
public:
- BlobUrlBrowserTest() {}
+ BlobUrlBrowserTest() {
+ if (GetParam())
+ scoped_feature_list_.InitAndEnableFeature(blink::features::kMojoBlobURLs);
+ }
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
@@ -31,10 +38,14 @@ class BlobUrlBrowserTest : public ContentBrowserTest {
}
private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
DISALLOW_COPY_AND_ASSIGN(BlobUrlBrowserTest);
};
-IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToUniqueOriginBlob) {
+INSTANTIATE_TEST_CASE_P(_, BlobUrlBrowserTest, ::testing::Bool());
+
+IN_PROC_BROWSER_TEST_P(BlobUrlBrowserTest, LinkToUniqueOriginBlob) {
// Use a data URL to obtain a test page in a unique origin. The page
// contains a link to a "blob:null/SOME-GUID-STRING" URL.
NavigateToURL(
@@ -68,7 +79,7 @@ IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToUniqueOriginBlob) {
EXPECT_EQ("null potato", page_content);
}
-IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToSameOriginBlob) {
+IN_PROC_BROWSER_TEST_P(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::Origin::Create(url);
@@ -100,7 +111,7 @@ IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToSameOriginBlob) {
}
// Regression test for https://crbug.com/646278
-IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToSameOriginBlobWithAuthority) {
+IN_PROC_BROWSER_TEST_P(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");
@@ -138,7 +149,7 @@ IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, LinkToSameOriginBlobWithAuthority) {
}
// Regression test for https://crbug.com/646278
-IN_PROC_BROWSER_TEST_F(BlobUrlBrowserTest, ReplaceStateToAddAuthorityToBlob) {
+IN_PROC_BROWSER_TEST_P(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");
diff --git a/chromium/content/browser/blob_storage/blob_url_loader_factory.cc b/chromium/content/browser/blob_storage/blob_url_loader_factory.cc
deleted file mode 100644
index 32904bea130..00000000000
--- a/chromium/content/browser/blob_storage/blob_url_loader_factory.cc
+++ /dev/null
@@ -1,88 +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/blob_storage/blob_url_loader_factory.h"
-
-#include <stddef.h>
-#include <utility>
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "content/public/browser/browser_thread.h"
-#include "storage/browser/blob/blob_data_handle.h"
-#include "storage/browser/blob/blob_storage_context.h"
-#include "storage/browser/blob/blob_url_loader.h"
-
-namespace content {
-
-// static
-scoped_refptr<BlobURLLoaderFactory> BlobURLLoaderFactory::Create(
- BlobContextGetter blob_storage_context_getter) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- auto factory = base::MakeRefCounted<BlobURLLoaderFactory>();
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&BlobURLLoaderFactory::InitializeOnIO, factory,
- std::move(blob_storage_context_getter)));
- return factory;
-}
-
-void BlobURLLoaderFactory::HandleRequest(
- network::mojom::URLLoaderFactoryRequest request) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&BlobURLLoaderFactory::BindOnIO, this,
- std::move(request)));
-}
-
-BlobURLLoaderFactory::BlobURLLoaderFactory() {}
-
-BlobURLLoaderFactory::~BlobURLLoaderFactory() {}
-
-void BlobURLLoaderFactory::InitializeOnIO(
- BlobContextGetter blob_storage_context_getter) {
- blob_storage_context_ = std::move(blob_storage_context_getter).Run();
-}
-
-void BlobURLLoaderFactory::BindOnIO(
- network::mojom::URLLoaderFactoryRequest request) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- loader_factory_bindings_.AddBinding(this, std::move(request));
-}
-
-// static
-void BlobURLLoaderFactory::CreateLoaderAndStart(
- network::mojom::URLLoaderRequest loader,
- const network::ResourceRequest& request,
- network::mojom::URLLoaderClientPtr client,
- std::unique_ptr<storage::BlobDataHandle> blob_handle) {
- storage::BlobURLLoader::CreateAndStart(
- std::move(loader), request, std::move(client), std::move(blob_handle));
-}
-
-void BlobURLLoaderFactory::CreateLoaderAndStart(
- network::mojom::URLLoaderRequest loader,
- int32_t routing_id,
- int32_t request_id,
- uint32_t options,
- const network::ResourceRequest& request,
- network::mojom::URLLoaderClientPtr client,
- const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
- DCHECK(!request.download_to_file);
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- std::unique_ptr<storage::BlobDataHandle> blob_handle;
- if (blob_storage_context_) {
- blob_handle = blob_storage_context_->GetBlobDataFromPublicURL(request.url);
- }
- CreateLoaderAndStart(std::move(loader), request, std::move(client),
- std::move(blob_handle));
-}
-
-void BlobURLLoaderFactory::Clone(
- network::mojom::URLLoaderFactoryRequest request) {
- loader_factory_bindings_.AddBinding(this, std::move(request));
-}
-
-} // namespace content
diff --git a/chromium/content/browser/blob_storage/blob_url_loader_factory.h b/chromium/content/browser/blob_storage/blob_url_loader_factory.h
deleted file mode 100644
index 5f69c439c7e..00000000000
--- a/chromium/content/browser/blob_storage/blob_url_loader_factory.h
+++ /dev/null
@@ -1,88 +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_BLOB_STORAGE_BLOB_URL_LOADER_FACTORY_H_
-#define CONTENT_BROWSER_BLOB_STORAGE_BLOB_URL_LOADER_FACTORY_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "content/common/content_export.h"
-#include "content/public/browser/browser_thread.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "services/network/public/mojom/url_loader_factory.mojom.h"
-
-namespace storage {
-class BlobDataHandle;
-class BlobStorageContext;
-}
-
-namespace content {
-
-// A class for creating URLLoaderFactory for blob scheme.
-// There should be one owned per StoragePartition.
-//
-// This class is deprecated, as it's impossible to use this to load blob URLs
-// without running into various race conditions between revoking blob URLs and
-// fetching them. Ultimately usage of this class will somehow be replaced with
-// usage of storage::BlobURLLoaderFactory.
-class BlobURLLoaderFactory
- : public base::RefCountedThreadSafe<BlobURLLoaderFactory,
- BrowserThread::DeleteOnIOThread>,
- public network::mojom::URLLoaderFactory {
- public:
- using BlobContextGetter =
- base::OnceCallback<base::WeakPtr<storage::BlobStorageContext>()>;
-
- static CONTENT_EXPORT scoped_refptr<BlobURLLoaderFactory> Create(
- BlobContextGetter blob_storage_context_getter);
-
- // Creates a URLLoaderFactory interface pointer for serving blob requests.
- // Called on the UI thread.
- void HandleRequest(network::mojom::URLLoaderFactoryRequest request);
-
- // Creates a URLLoader for given Blob UUID. This method is supposed to
- // be called on the IO thread.
- // Note that given |request|'s URL is not referenced, but only method and
- // range headers are used.
- static void CreateLoaderAndStart(
- network::mojom::URLLoaderRequest url_loader_request,
- const network::ResourceRequest& request,
- network::mojom::URLLoaderClientPtr client,
- std::unique_ptr<storage::BlobDataHandle> blob_handle);
-
- // network::mojom::URLLoaderFactory implementation:
- void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader,
- int32_t routing_id,
- int32_t request_id,
- uint32_t options,
- const network::ResourceRequest& request,
- network::mojom::URLLoaderClientPtr client,
- const net::MutableNetworkTrafficAnnotationTag&
- traffic_annotation) override;
- void Clone(network::mojom::URLLoaderFactoryRequest request) override;
-
- private:
- friend class base::DeleteHelper<BlobURLLoaderFactory>;
- friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
- template <typename T, typename... Args>
- friend scoped_refptr<T> base::MakeRefCounted(Args&&... args);
-
- BlobURLLoaderFactory();
- ~BlobURLLoaderFactory() override;
-
- void InitializeOnIO(BlobContextGetter blob_storage_context_getter);
- void BindOnIO(network::mojom::URLLoaderFactoryRequest request);
-
- base::WeakPtr<storage::BlobStorageContext> blob_storage_context_;
-
- // Used on the IO thread.
- mojo::BindingSet<network::mojom::URLLoaderFactory> loader_factory_bindings_;
-
- DISALLOW_COPY_AND_ASSIGN(BlobURLLoaderFactory);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_BLOB_STORAGE_BLOB_URL_LOADER_FACTORY_H_
diff --git a/chromium/content/browser/blob_storage/blob_url_unittest.cc b/chromium/content/browser/blob_storage/blob_url_unittest.cc
index e7d27de9650..702da3728bd 100644
--- a/chromium/content/browser/blob_storage/blob_url_unittest.cc
+++ b/chromium/content/browser/blob_storage/blob_url_unittest.cc
@@ -17,7 +17,6 @@
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
-#include "content/browser/blob_storage/blob_url_loader_factory.h"
#include "content/browser/url_loader_factory_getter.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/system/data_pipe_utils.h"
@@ -102,7 +101,8 @@ disk_cache::ScopedEntryPtr CreateDiskCacheEntry(disk_cache::Backend* cache,
const std::string& data) {
disk_cache::Entry* temp_entry = nullptr;
net::TestCompletionCallback callback;
- int rv = cache->CreateEntry(key, &temp_entry, callback.callback());
+ int rv =
+ cache->CreateEntry(key, net::HIGHEST, &temp_entry, callback.callback());
if (callback.GetResult(rv) != net::OK)
return nullptr;
disk_cache::ScopedEntryPtr entry(temp_entry);
@@ -130,7 +130,6 @@ disk_cache::ScopedEntryPtr CreateDiskCacheEntryWithSideData(
}
enum class RequestTestType {
- kNetworkServiceRequest,
kNetRequest,
kRequestFromBlobImpl
};
@@ -284,34 +283,6 @@ class BlobURLRequestJobTest : public testing::TestWithParam<RequestTestType> {
request.headers = extra_headers;
switch (GetParam()) {
- case RequestTestType::kNetworkServiceRequest: {
- GetHandleFromBuilder(); // To add to StorageContext.
- const_cast<storage::BlobStorageRegistry&>(blob_context_.registry())
- .CreateUrlMapping(url, blob_uuid_);
-
- network::mojom::URLLoaderPtr url_loader;
- network::TestURLLoaderClient url_loader_client;
- scoped_refptr<BlobURLLoaderFactory> factory =
- BlobURLLoaderFactory::Create(
- base::BindOnce(&BlobURLRequestJobTest::GetStorageContext,
- base::Unretained(this)));
- base::RunLoop().RunUntilIdle();
- factory->CreateLoaderAndStart(mojo::MakeRequest(&url_loader), 0, 0,
- network::mojom::kURLLoadOptionNone,
- request,
- url_loader_client.CreateInterfacePtr(),
- net::MutableNetworkTrafficAnnotationTag(
- TRAFFIC_ANNOTATION_FOR_TESTS));
- url_loader_client.RunUntilComplete();
-
- if (url_loader_client.response_body().is_valid()) {
- EXPECT_TRUE(mojo::BlockingCopyToString(
- url_loader_client.response_body_release(), &response_));
- }
- response_headers_ = url_loader_client.response_head().headers;
- response_metadata_ = url_loader_client.cached_metadata();
- response_error_code_ = url_loader_client.completion_status().error_code;
- } break;
case RequestTestType::kNetRequest: {
std::unique_ptr<net::URLRequest> request =
url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY,
@@ -719,8 +690,7 @@ TEST_P(BlobURLRequestJobTest, BrokenBlob) {
INSTANTIATE_TEST_CASE_P(
BlobURLRequestJobTest,
BlobURLRequestJobTest,
- ::testing::Values(RequestTestType::kNetworkServiceRequest,
- RequestTestType::kNetRequest,
+ ::testing::Values(RequestTestType::kNetRequest,
RequestTestType::kRequestFromBlobImpl));
} // namespace content
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 17347dbfd10..0900dbb6898 100644
--- a/chromium/content/browser/blob_storage/chrome_blob_storage_context.cc
+++ b/chromium/content/browser/blob_storage/chrome_blob_storage_context.cc
@@ -197,6 +197,49 @@ ChromeBlobStorageContext::URLLoaderFactoryForToken(
std::move(blob_url_loader_factory_ptr));
}
+// static
+scoped_refptr<network::SharedURLLoaderFactory>
+ChromeBlobStorageContext::URLLoaderFactoryForUrl(
+ BrowserContext* browser_context,
+ const GURL& url) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ network::mojom::URLLoaderFactoryPtr blob_url_loader_factory_ptr;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(
+ [](scoped_refptr<ChromeBlobStorageContext> context,
+ network::mojom::URLLoaderFactoryRequest request, const GURL& url) {
+ auto blob_handle =
+ context->context()->GetBlobDataFromPublicURL(url);
+ storage::BlobURLLoaderFactory::Create(std::move(blob_handle), url,
+ std::move(request));
+ },
+ base::WrapRefCounted(GetFor(browser_context)),
+ MakeRequest(&blob_url_loader_factory_ptr), url));
+ return base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
+ std::move(blob_url_loader_factory_ptr));
+}
+
+// static
+blink::mojom::BlobPtr ChromeBlobStorageContext::GetBlobPtr(
+ BrowserContext* browser_context,
+ const std::string& uuid) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ blink::mojom::BlobPtr blob_ptr;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(
+ [](scoped_refptr<ChromeBlobStorageContext> context,
+ blink::mojom::BlobRequest request, const std::string& uuid) {
+ auto handle = context->context()->GetBlobDataFromUUID(uuid);
+ if (handle)
+ storage::BlobImpl::Create(std::move(handle), std::move(request));
+ },
+ base::WrapRefCounted(GetFor(browser_context)), MakeRequest(&blob_ptr),
+ uuid));
+ return blob_ptr;
+}
+
ChromeBlobStorageContext::~ChromeBlobStorageContext() {}
void ChromeBlobStorageContext::DeleteOnCorrectThread() const {
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 812a6a5cebe..26cf1ebfdff 100644
--- a/chromium/content/browser/blob_storage/chrome_blob_storage_context.h
+++ b/chromium/content/browser/blob_storage/chrome_blob_storage_context.h
@@ -65,11 +65,32 @@ class CONTENT_EXPORT ChromeBlobStorageContext
size_t length,
const std::string& content_type);
+ // Returns a SharedURLLoaderFactory capable of creating URLLoaders for exactly
+ // the one URL associated with the passed in |token|. Attempting to load any
+ // other URL through the factory will result in an error. If the |token|
+ // itself is invalid all requests will result in errors.
// Must be called on the UI thread.
static scoped_refptr<network::SharedURLLoaderFactory>
URLLoaderFactoryForToken(BrowserContext* browser_context,
blink::mojom::BlobURLTokenPtr token);
+ // Similar to the above method this also returns a factory capable of loading
+ // a single (blob) URL. If the |url| isn't a valid/registered blob URL at the
+ // time this method is called, using the resulting factory will always result
+ // in an error.
+ // Generally you should prefer using the above method and pass around a
+ // BlobURLToken rather than a blob URL. This is because the BlobURLToken will
+ // ensure that the URL and the blob it refers to stay alive, while merely
+ // holding on to the URL has no such guarantees.
+ // Must be called on the UI thread.
+ static scoped_refptr<network::SharedURLLoaderFactory> URLLoaderFactoryForUrl(
+ BrowserContext* browser_context,
+ const GURL& url);
+
+ // Must be called on the UI thread.
+ static blink::mojom::BlobPtr GetBlobPtr(BrowserContext* browser_context,
+ const std::string& uuid);
+
protected:
virtual ~ChromeBlobStorageContext();
diff --git a/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc b/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
index 4d08d443e55..bea76778640 100644
--- a/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
+++ b/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
@@ -281,8 +281,7 @@ BluetoothDeviceChooserController::BluetoothDeviceChooserController(
base::Bind(&BluetoothDeviceChooserController::StopDeviceDiscovery,
// base::Timer guarantees it won't call back after its
// destructor starts.
- base::Unretained(this)),
- /*is_repeating=*/false),
+ base::Unretained(this))),
weak_ptr_factory_(this) {
CHECK(adapter_);
}
diff --git a/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.h b/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.h
index 54eb7a113e2..b2e16cb09f8 100644
--- a/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.h
+++ b/chromium/content/browser/bluetooth/bluetooth_device_chooser_controller.h
@@ -147,7 +147,7 @@ class CONTENT_EXPORT BluetoothDeviceChooserController final {
// Automatically stops Bluetooth discovery a set amount of time after it was
// started.
- base::Timer discovery_session_timer_;
+ base::RetainingOneShotTimer discovery_session_timer_;
// The last discovery session to be started.
// TODO(ortuno): This should be null unless there is an active discovery
diff --git a/chromium/content/browser/bluetooth/tools/BUILD.gn b/chromium/content/browser/bluetooth/tools/BUILD.gn
index 8615c6dfef0..4971caa1715 100644
--- a/chromium/content/browser/bluetooth/tools/BUILD.gn
+++ b/chromium/content/browser/bluetooth/tools/BUILD.gn
@@ -9,7 +9,6 @@ executable("bluetooth_metrics_hash") {
deps = [
"//base",
- "//build/config:exe_and_shlib_deps",
"//build/win:default_exe_manifest",
"//device/bluetooth",
]
diff --git a/chromium/content/browser/bluetooth/web_bluetooth_service_impl.cc b/chromium/content/browser/bluetooth/web_bluetooth_service_impl.cc
index cda94e43e86..f061eca7c86 100644
--- a/chromium/content/browser/bluetooth/web_bluetooth_service_impl.cc
+++ b/chromium/content/browser/bluetooth/web_bluetooth_service_impl.cc
@@ -1242,6 +1242,10 @@ BluetoothAllowedDevices& WebBluetoothServiceImpl::allowed_devices() {
}
void WebBluetoothServiceImpl::ClearState() {
+ // Releasing the adapter will drop references to callbacks that have not yet
+ // been executed. The binding must be closed first so that this is allowed.
+ binding_.Close();
+
characteristic_id_to_notify_session_.clear();
pending_primary_services_requests_.clear();
descriptor_id_to_characteristic_id_.clear();
diff --git a/chromium/content/browser/browser_child_process_host_impl.cc b/chromium/content/browser/browser_child_process_host_impl.cc
index 1686c7a9f2b..3fc3aa2f44c 100644
--- a/chromium/content/browser/browser_child_process_host_impl.cc
+++ b/chromium/content/browser/browser_child_process_host_impl.cc
@@ -47,7 +47,6 @@
#include "content/public/common/result_codes.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/common/service_manager_connection.h"
-#include "mojo/edk/embedder/embedder.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "services/service_manager/embedder/switches.h"
@@ -153,7 +152,6 @@ BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
const std::string& service_name)
: data_(process_type),
delegate_(delegate),
- broker_client_invitation_(new mojo::edk::OutgoingBrokerClientInvitation),
channel_(nullptr),
is_channel_connected_(false),
notify_child_disconnected_(false),
@@ -172,9 +170,10 @@ BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
service_name, service_manager::mojom::kInheritUserID,
base::StringPrintf("%d", data_.id));
child_connection_.reset(
- new ChildConnection(child_identity, broker_client_invitation_.get(),
+ new ChildConnection(child_identity, &mojo_invitation_,
ServiceManagerContext::GetConnectorForIOThread(),
base::ThreadTaskRunnerHandle::Get()));
+ data_.metrics_name = service_name;
}
// Create a persistent memory segment for subprocess histograms.
@@ -267,11 +266,13 @@ void BrowserChildProcessHostImpl::Launch(
child_connection_->service_token());
}
- DCHECK(broker_client_invitation_);
+ // All processes should have a non-empty metrics name.
+ DCHECK(!data_.metrics_name.empty());
+
notify_child_disconnected_ = true;
child_process_.reset(new ChildProcessLauncher(
std::move(delegate), std::move(cmd_line), data_.id, this,
- std::move(broker_client_invitation_),
+ std::move(mojo_invitation_),
base::Bind(&BrowserChildProcessHostImpl::OnMojoError,
weak_factory_.GetWeakPtr(),
base::ThreadTaskRunnerHandle::Get()),
@@ -307,6 +308,12 @@ void BrowserChildProcessHostImpl::SetName(const base::string16& name) {
data_.name = name;
}
+void BrowserChildProcessHostImpl::SetMetricsName(
+ const std::string& metrics_name) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ data_.metrics_name = metrics_name;
+}
+
void BrowserChildProcessHostImpl::SetHandle(base::ProcessHandle handle) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
data_.handle = handle;
@@ -314,11 +321,9 @@ void BrowserChildProcessHostImpl::SetHandle(base::ProcessHandle handle) {
service_manager::mojom::ServiceRequest
BrowserChildProcessHostImpl::TakeInProcessServiceRequest() {
- DCHECK(broker_client_invitation_);
- auto invitation = std::move(broker_client_invitation_);
+ auto invitation = std::move(mojo_invitation_);
return service_manager::mojom::ServiceRequest(
- invitation->ExtractInProcessMessagePipe(
- child_connection_->service_token()));
+ invitation.ExtractMessagePipe(child_connection_->service_token()));
}
void BrowserChildProcessHostImpl::ForceShutdown() {
diff --git a/chromium/content/browser/browser_child_process_host_impl.h b/chromium/content/browser/browser_child_process_host_impl.h
index ee21de31936..39c277f11ea 100644
--- a/chromium/content/browser/browser_child_process_host_impl.h
+++ b/chromium/content/browser/browser_child_process_host_impl.h
@@ -22,7 +22,7 @@
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/common/child_process_host_delegate.h"
-#include "mojo/edk/embedder/outgoing_broker_client_invitation.h"
+#include "mojo/public/cpp/system/invitation.h"
#if defined(OS_WIN)
#include "base/win/object_watcher.h"
@@ -79,6 +79,7 @@ class CONTENT_EXPORT BrowserChildProcessHostImpl
std::unique_ptr<base::SharedPersistentMemoryAllocator> TakeMetricsAllocator()
override;
void SetName(const base::string16& name) override;
+ void SetMetricsName(const std::string& metrics_name) override;
void SetHandle(base::ProcessHandle handle) override;
service_manager::mojom::ServiceRequest TakeInProcessServiceRequest() override;
@@ -111,9 +112,8 @@ class CONTENT_EXPORT BrowserChildProcessHostImpl
return child_connection_.get();
}
- mojo::edk::OutgoingBrokerClientInvitation*
- GetInProcessBrokerClientInvitation() {
- return broker_client_invitation_.get();
+ mojo::OutgoingInvitation* GetInProcessMojoInvitation() {
+ return &mojo_invitation_;
}
IPC::Channel* child_channel() const { return channel_; }
@@ -155,11 +155,11 @@ class CONTENT_EXPORT BrowserChildProcessHostImpl
#endif
ChildProcessData data_;
+ std::string metrics_name_;
BrowserChildProcessHostDelegate* delegate_;
std::unique_ptr<ChildProcessHost> child_process_host_;
- std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation>
- broker_client_invitation_;
+ mojo::OutgoingInvitation mojo_invitation_;
std::unique_ptr<ChildConnection> child_connection_;
std::unique_ptr<ChildProcessLauncher> child_process_;
diff --git a/chromium/content/browser/browser_context.cc b/chromium/content/browser/browser_context.cc
index 69271e39f27..199a676de55 100644
--- a/chromium/content/browser/browser_context.cc
+++ b/chromium/content/browser/browser_context.cc
@@ -23,14 +23,17 @@
#include "base/memory/ptr_util.h"
#include "base/rand_util.h"
#include "base/task_scheduler/post_task.h"
+#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/browsing_data/browsing_data_remover_impl.h"
+#include "content/browser/content_service_delegate_impl.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/browser/permissions/permission_controller_impl.h"
#include "content/browser/push_messaging/push_messaging_router.h"
#include "content/browser/service_manager/common_browser_interfaces.h"
#include "content/browser/storage_partition_impl_map.h"
@@ -51,6 +54,8 @@
#include "net/ssl/channel_id_store.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
+#include "services/content/public/mojom/constants.mojom.h"
+#include "services/content/service.h"
#include "services/file/file_service.h"
#include "services/file/public/mojom/constants.mojom.h"
#include "services/file/user_id_map.h"
@@ -84,8 +89,24 @@ class ServiceUserIdHolder : public base::SupportsUserData::Data {
DISALLOW_COPY_AND_ASSIGN(ServiceUserIdHolder);
};
+class ContentServiceDelegateHolder : public base::SupportsUserData::Data {
+ public:
+ explicit ContentServiceDelegateHolder(BrowserContext* browser_context)
+ : delegate_(browser_context) {}
+ ~ContentServiceDelegateHolder() override = default;
+
+ ContentServiceDelegateImpl* delegate() { return &delegate_; }
+
+ private:
+ ContentServiceDelegateImpl delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentServiceDelegateHolder);
+};
+
// Key names on BrowserContext.
const char kBrowsingDataRemoverKey[] = "browsing-data-remover";
+const char kContentServiceDelegateKey[] = "content-service-delegate";
+const char kPermissionControllerKey[] = "permission-controller";
const char kDownloadManagerKeyName[] = "download_manager";
const char kMojoWasInitialized[] = "mojo-was-initialized";
const char kServiceManagerConnection[] = "service-manager-connection";
@@ -269,6 +290,20 @@ content::BrowsingDataRemover* content::BrowserContext::GetBrowsingDataRemover(
context->GetUserData(kBrowsingDataRemoverKey));
}
+// static
+content::PermissionController* content::BrowserContext::GetPermissionController(
+ BrowserContext* context) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ if (!context->GetUserData(kPermissionControllerKey)) {
+ context->SetUserData(kPermissionControllerKey,
+ std::make_unique<PermissionControllerImpl>(context));
+ }
+
+ return static_cast<PermissionControllerImpl*>(
+ context->GetUserData(kPermissionControllerKey));
+}
+
StoragePartition* BrowserContext::GetStoragePartition(
BrowserContext* browser_context,
SiteInstance* site_instance,
@@ -349,6 +384,14 @@ BrowserContext::BlobContextGetter BrowserContext::GetBlobStorageContext(
}
// static
+blink::mojom::BlobPtr BrowserContext::GetBlobPtr(
+ BrowserContext* browser_context,
+ const std::string& uuid) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return ChromeBlobStorageContext::GetBlobPtr(browser_context, uuid);
+}
+
+// static
void BrowserContext::DeliverPushMessage(
BrowserContext* browser_context,
const GURL& origin,
@@ -371,6 +414,12 @@ void BrowserContext::NotifyWillBeDestroyed(BrowserContext* browser_context) {
return;
browser_context->was_notify_will_be_destroyed_called_ = true;
+ // Subclasses of BrowserContext may expect there to be no more
+ // RenderProcessHosts using them by the time this function returns. We
+ // therefore explicitly tear down embedded Content Service instances now to
+ // ensure that all their WebContents (and therefore RPHs) are torn down too.
+ browser_context->RemoveUserData(kContentServiceDelegateKey);
+
// Service Workers must shutdown before the browser context is destroyed,
// since they keep render process hosts alive and the codebase assumes that
// render process hosts die before their profile (browser context) dies.
@@ -419,13 +468,14 @@ void BrowserContext::SaveSessionState(BrowserContext* browser_context) {
BrowserThread::IO, FROM_HERE,
base::BindOnce(
&SaveSessionStateOnIOThread,
- base::WrapRefCounted(
- BrowserContext::GetDefaultStoragePartition(browser_context)
- ->GetURLRequestContext()),
+ base::WrapRefCounted(storage_partition->GetURLRequestContext()),
static_cast<AppCacheServiceImpl*>(
storage_partition->GetAppCacheService())));
}
+ storage_partition->GetCookieManagerForBrowserProcess()
+ ->SetForceKeepSessionState();
+
DOMStorageContextWrapper* dom_storage_context_proxy =
static_cast<DOMStorageContextWrapper*>(
storage_partition->GetDOMStorageContext());
@@ -502,9 +552,32 @@ void BrowserContext::Initialize(
// New embedded service factories should be added to |connection| here.
- service_manager::EmbeddedServiceInfo info;
- info.factory = base::BindRepeating(&file::CreateFileService);
- connection->AddEmbeddedService(file::mojom::kServiceName, info);
+ {
+ service_manager::EmbeddedServiceInfo info;
+ info.factory = base::BindRepeating(&file::CreateFileService);
+ connection->AddEmbeddedService(file::mojom::kServiceName, info);
+ }
+
+ browser_context->SetUserData(
+ kContentServiceDelegateKey,
+ std::make_unique<ContentServiceDelegateHolder>(browser_context));
+
+ {
+ service_manager::EmbeddedServiceInfo info;
+ info.task_runner = base::SequencedTaskRunnerHandle::Get();
+ info.factory = base::BindRepeating(
+ [](BrowserContext* context)
+ -> std::unique_ptr<service_manager::Service> {
+ auto* holder = static_cast<ContentServiceDelegateHolder*>(
+ context->GetUserData(kContentServiceDelegateKey));
+ auto* delegate = holder->delegate();
+ auto service = std::make_unique<content::Service>(delegate);
+ delegate->AddService(service.get());
+ return service;
+ },
+ browser_context);
+ connection->AddEmbeddedService(content::mojom::kServiceName, info);
+ }
ContentBrowserClient::StaticServiceMap services;
browser_context->RegisterInProcessServices(&services);
@@ -519,7 +592,7 @@ void BrowserContext::Initialize(
if (!browser_context->IsOffTheRecord()) {
WebRtcEventLogger* const logger = WebRtcEventLogger::Get();
if (logger) {
- logger->EnableForBrowserContext(browser_context);
+ logger->EnableForBrowserContext(browser_context, base::OnceClosure());
}
}
}
@@ -576,7 +649,7 @@ BrowserContext::~BrowserContext() {
WebRtcEventLogger* const logger = WebRtcEventLogger::Get();
if (logger) {
- logger->DisableForBrowserContext(this);
+ logger->DisableForBrowserContext(this, base::OnceClosure());
}
RemoveBrowserContextFromUserIdMap(this);
diff --git a/chromium/content/browser/browser_main.cc b/chromium/content/browser/browser_main.cc
index f06e59b43ff..65668ab3f5f 100644
--- a/chromium/content/browser/browser_main.cc
+++ b/chromium/content/browser/browser_main.cc
@@ -8,7 +8,6 @@
#include "base/trace_event/trace_event.h"
#include "content/browser/browser_main_runner_impl.h"
-#include "content/browser/browser_process_sub_thread.h"
#include "content/common/content_constants_internal.h"
namespace content {
@@ -31,9 +30,7 @@ class ScopedBrowserMainEvent {
} // namespace
// Main routine for running as the Browser process.
-int BrowserMain(
- const MainFunctionParams& parameters,
- std::unique_ptr<BrowserProcessSubThread> service_manager_thread) {
+int BrowserMain(const MainFunctionParams& parameters) {
ScopedBrowserMainEvent scoped_browser_main_event;
base::trace_event::TraceLog::GetInstance()->set_process_name("Browser");
@@ -43,8 +40,7 @@ int BrowserMain(
std::unique_ptr<BrowserMainRunnerImpl> main_runner(
BrowserMainRunnerImpl::Create());
- int exit_code =
- main_runner->Initialize(parameters, std::move(service_manager_thread));
+ int exit_code = main_runner->Initialize(parameters);
if (exit_code >= 0)
return exit_code;
diff --git a/chromium/content/browser/browser_main.h b/chromium/content/browser/browser_main.h
index 02f3af601fe..c4a5c719ff0 100644
--- a/chromium/content/browser/browser_main.h
+++ b/chromium/content/browser/browser_main.h
@@ -11,12 +11,9 @@
namespace content {
-class BrowserProcessSubThread;
struct MainFunctionParams;
-CONTENT_EXPORT int BrowserMain(
- const content::MainFunctionParams& parameters,
- std::unique_ptr<BrowserProcessSubThread> service_manager_thread);
+CONTENT_EXPORT int BrowserMain(const content::MainFunctionParams& parameters);
} // namespace content
diff --git a/chromium/content/browser/browser_main_loop.cc b/chromium/content/browser/browser_main_loop.cc
index 10de251accf..eb942391306 100644
--- a/chromium/content/browser/browser_main_loop.cc
+++ b/chromium/content/browser/browser_main_loop.cc
@@ -16,7 +16,6 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/debug/alias.h"
-#include "base/debug/stack_trace.h"
#include "base/deferred_sequenced_task_runner.h"
#include "base/feature_list.h"
#include "base/location.h"
@@ -28,6 +27,7 @@
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
+#include "base/path_service.h"
#include "base/pending_task.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_device_source.h"
@@ -47,6 +47,7 @@
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "cc/base/histograms.h"
#include "components/discardable_memory/service/discardable_shared_memory_manager.h"
#include "components/tracing/common/trace_startup_config.h"
#include "components/tracing/common/trace_to_console.h"
@@ -63,6 +64,7 @@
#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/dom_storage/storage_area_impl.h"
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/download/save_file_manager.h"
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
@@ -72,7 +74,6 @@
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/gpu/shader_cache_factory.h"
#include "content/browser/histogram_synchronizer.h"
-#include "content/browser/leveldb_wrapper_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader_delegate_impl.h"
#include "content/browser/media/capture/audio_mirroring_manager.h"
@@ -84,6 +85,7 @@
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/service_manager/service_manager_context.h"
#include "content/browser/speech/speech_recognition_manager_impl.h"
+#include "content/browser/startup_data_impl.h"
#include "content/browser/startup_task_runner.h"
#include "content/browser/tracing/background_tracing_manager_impl.h"
#include "content/browser/tracing/tracing_controller_impl.h"
@@ -108,6 +110,7 @@
#include "content/public/common/result_codes.h"
#include "content/public/common/service_names.mojom.h"
#include "device/gamepad/gamepad_service.h"
+#include "gpu/config/gpu_switches.h"
#include "media/audio/audio_manager.h"
#include "media/audio/audio_system.h"
#include "media/audio/audio_thread_impl.h"
@@ -116,8 +119,8 @@
#include "media/media_buildflags.h"
#include "media/midi/midi_service.h"
#include "media/mojo/buildflags.h"
-#include "mojo/edk/embedder/embedder.h"
-#include "mojo/edk/embedder/scoped_ipc_support.h"
+#include "mojo/core/embedder/embedder.h"
+#include "mojo/core/embedder/scoped_ipc_support.h"
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "net/base/network_change_notifier.h"
#include "net/socket/client_socket_factory.h"
@@ -136,6 +139,7 @@
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/display_switches.h"
+#include "ui/gfx/font_render_params.h"
#include "ui/gfx/switches.h"
#if defined(USE_AURA) || defined(OS_MACOSX)
@@ -201,10 +205,10 @@
#endif
#if defined(OS_FUCHSIA)
-#include <zircon/process.h>
-#include <zircon/syscalls.h>
+#include <lib/zx/job.h>
#include "base/fuchsia/default_job.h"
+#include "base/fuchsia/fuchsia_logging.h"
#endif // defined(OS_FUCHSIA)
#if defined(OS_POSIX) && !defined(OS_MACOSX)
@@ -230,8 +234,8 @@
#include "crypto/nss_util.h"
#endif
-#if BUILDFLAG(ENABLE_MUS)
-#include "services/ui/common/image_cursors_set.h"
+#if defined(ENABLE_IPC_FUZZER) && defined(OS_MACOSX)
+#include "base/mac/foundation_util.h"
#endif
// One of the linux specific headers defines this as a macro.
@@ -261,12 +265,6 @@ static void GLibLogHandler(const gchar* log_domain,
LOG(DFATAL) << log_domain << ": " << message;
} else if (log_level & (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL)) {
LOG(ERROR) << log_domain << ": " << message;
-#if defined(THREAD_SANITIZER)
- // TODO(thomasanderson): This is temporary debugging for
- // https://crbug.com/821704. Revert this CL once we have the stack trace:
- // https://chromium-review.googlesource.com/#/c/chromium/src/+/1069247
- base::debug::StackTrace().Print();
-#endif
} else if (log_level & (G_LOG_LEVEL_WARNING)) {
LOG(WARNING) << log_domain << ": " << message;
} else if (log_level &
@@ -397,14 +395,47 @@ constexpr base::TimeDelta kSwapMetricsInterval =
// Create and register the job which will contain all child processes
// of the browser process as well as their descendents.
void InitDefaultJob() {
- base::ScopedZxHandle handle;
- zx_status_t result = zx_job_create(zx_job_default(), 0, handle.receive());
- CHECK_EQ(ZX_OK, result) << "zx_job_create(job): "
- << zx_status_get_string(result);
- base::SetDefaultJob(std::move(handle));
+ zx::job job;
+ zx_status_t result = zx::job::create(*zx::job::default_job(), 0, &job);
+ ZX_CHECK(ZX_OK == result, result) << "zx_job_create";
+ base::SetDefaultJob(std::move(job));
}
#endif // defined(OS_FUCHSIA)
+#if defined(ENABLE_IPC_FUZZER)
+bool GetBuildDirectory(base::FilePath* result) {
+ if (!base::PathService::Get(base::DIR_EXE, result))
+ return false;
+
+#if defined(OS_MACOSX)
+ if (base::mac::AmIBundled()) {
+ // The bundled app executables (Chromium, TestShell, etc) live three
+ // levels down from the build directory, eg:
+ // Chromium.app/Contents/MacOS/Chromium
+ *result = result->DirName().DirName().DirName();
+ }
+#endif
+ return true;
+}
+
+void SetFileUrlPathAliasForIpcFuzzer() {
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kFileUrlPathAlias))
+ return;
+
+ base::FilePath build_directory;
+ if (!GetBuildDirectory(&build_directory)) {
+ LOG(ERROR) << "Failed to get build directory for /gen path alias.";
+ return;
+ }
+
+ const base::CommandLine::StringType alias_switch =
+ FILE_PATH_LITERAL("/gen=") + build_directory.AppendASCII("gen").value();
+ base::CommandLine::ForCurrentProcess()->AppendSwitchNative(
+ switches::kFileUrlPathAlias, alias_switch);
+}
+#endif
+
} // namespace
#if defined(USE_X11)
@@ -503,6 +534,11 @@ BrowserMainLoop* BrowserMainLoop::GetInstance() {
return g_current_browser_main_loop;
}
+// static
+media::AudioManager* BrowserMainLoop::GetAudioManager() {
+ return g_current_browser_main_loop->audio_manager();
+}
+
BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters)
: parameters_(parameters),
parsed_command_line_(parameters.command_line),
@@ -512,9 +548,7 @@ BrowserMainLoop::BrowserMainLoop(const MainFunctionParams& parameters)
g_current_browser_main_loop = this;
if (GetContentClient()->browser()->ShouldCreateTaskScheduler()) {
- // Use an empty string as TaskScheduler name to match the suffix of browser
- // process TaskScheduler histograms.
- base::TaskScheduler::Create("Browser");
+ DCHECK(base::TaskScheduler::GetInstance());
}
}
@@ -524,13 +558,20 @@ BrowserMainLoop::~BrowserMainLoop() {
g_current_browser_main_loop = nullptr;
}
-void BrowserMainLoop::Init(
- std::unique_ptr<BrowserProcessSubThread> service_manager_thread) {
+void BrowserMainLoop::Init() {
TRACE_EVENT0("startup", "BrowserMainLoop::Init");
- // This is always invoked before |io_thread_| is initialized (i.e. never
- // resets it).
- io_thread_ = std::move(service_manager_thread);
+ // |startup_data| is optional. If set, the thread owned by the data
+ // will be registered as BrowserThread::IO in CreateThreads() instead of
+ // creating a brand new thread.
+ if (parameters_.startup_data) {
+ StartupDataImpl* startup_data =
+ static_cast<StartupDataImpl*>(parameters_.startup_data);
+ // This is always invoked before |io_thread_| is initialized (i.e. never
+ // resets it).
+ io_thread_ = std::move(startup_data->thread);
+ }
+
parts_.reset(
GetContentClient()->browser()->CreateBrowserMainParts(parameters_));
}
@@ -597,6 +638,17 @@ int BrowserMainLoop::EarlyInitialization() {
command_line->GetSwitchValueASCII(switches::kDisableFeatures));
}
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+ // Up the priority of the UI thread unless it was already high (since recent
+ // versions of Android (O+) do this automatically).
+ if (base::PlatformThread::GetCurrentThreadPriority() <
+ base::ThreadPriority::DISPLAY ||
+ base::FeatureList::IsEnabled(features::kOverrideUIThreadPriority)) {
+ base::PlatformThread::SetCurrentThreadPriority(
+ base::ThreadPriority::DISPLAY);
+ }
+#endif // defined(OS_ANDROID) || defined(OS_CHROMEOS)
+
#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
defined(OS_ANDROID)
// We use quite a few file descriptors for our IPC as well as disk the disk
@@ -652,9 +704,8 @@ void BrowserMainLoop::MainMessageLoopStart() {
TRACE_EVENT0("startup", "BrowserMainLoop::MainMessageLoopStart");
- // Create a MessageLoop if one does not already exist for the current thread.
- if (!base::MessageLoopCurrent::Get())
- main_message_loop_.reset(new base::MessageLoopForUI);
+ if (!base::MessageLoopCurrentForUI::IsSet())
+ main_message_loop_ = std::make_unique<base::MessageLoopForUI>();
InitializeMainThread();
}
@@ -706,7 +757,7 @@ void BrowserMainLoop::PostMainMessageLoopStart() {
BrowserThread::GetTaskRunnerForThread(BrowserThread::UI));
}
- if (!base::FeatureList::IsEnabled(::features::kMash)) {
+ if (features::IsAshInBrowserProcess()) {
discardable_shared_memory_manager_ =
std::make_unique<discardable_memory::DiscardableSharedMemoryManager>();
// TODO(boliu): kSingleProcess check is a temporary workaround for
@@ -744,14 +795,18 @@ void BrowserMainLoop::PostMainMessageLoopStart() {
TRACE_EVENT0("startup",
"BrowserMainLoop::Subsystem:EnableAggressiveCommitDelay");
DOMStorageArea::EnableAggressiveCommitDelay();
- LevelDBWrapperImpl::EnableAggressiveCommitDelay();
+ StorageAreaImpl::EnableAggressiveCommitDelay();
}
// Enable memory-infra dump providers.
InitSkiaEventTracer();
- base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- viz::ServerSharedBitmapManager::current(),
- "viz::ServerSharedBitmapManager", nullptr);
+#if !defined(OS_ANDROID)
+ if (server_shared_bitmap_manager_) {
+ base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+ server_shared_bitmap_manager_.get(), "viz::ServerSharedBitmapManager",
+ base::ThreadTaskRunnerHandle::Get());
+ }
+#endif
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
@@ -836,10 +891,11 @@ void BrowserMainLoop::CreateStartupTasks() {
DCHECK(!startup_task_runner_);
#if defined(OS_ANDROID)
startup_task_runner_ = std::make_unique<StartupTaskRunner>(
- base::Bind(&BrowserStartupComplete), base::ThreadTaskRunnerHandle::Get());
+ base::BindOnce(&BrowserStartupComplete),
+ base::ThreadTaskRunnerHandle::Get());
#else
startup_task_runner_ = std::make_unique<StartupTaskRunner>(
- base::Callback<void(int)>(), base::ThreadTaskRunnerHandle::Get());
+ base::OnceCallback<void(int)>(), base::ThreadTaskRunnerHandle::Get());
#endif
StartupTask pre_create_threads =
base::Bind(&BrowserMainLoop::PreCreateThreads, base::Unretained(this));
@@ -916,7 +972,7 @@ int BrowserMainLoop::CreateThreads() {
task_scheduler_init_params->foreground_worker_pool_params =
base::SchedulerWorkerPoolParams(
std::max(GetMinThreadsInRendererTaskSchedulerForegroundPool(),
- current_foreground_worker_pool_params.max_threads()),
+ current_foreground_worker_pool_params.max_tasks()),
current_foreground_worker_pool_params.suggested_reclaim_time(),
current_foreground_worker_pool_params.backward_compatibility());
}
@@ -1005,12 +1061,6 @@ 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");
@@ -1054,6 +1104,7 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
host_frame_sink_manager_.reset();
frame_sink_manager_impl_.reset();
compositing_mode_reporter_impl_.reset();
+ server_shared_bitmap_manager_.reset();
#endif
// The device monitors are using |system_monitor_| as dependency, so delete
@@ -1138,17 +1189,15 @@ media::AudioManager* BrowserMainLoop::audio_manager() const {
return audio_manager_.get();
}
-base::SequencedTaskRunner* BrowserMainLoop::audio_service_runner() {
- DCHECK(audio_service_runner_) << "The audio service task runner is not "
- "instantiated - running the audio service "
- "out of process?";
- return audio_service_runner_.get();
-}
-
#if !defined(OS_ANDROID)
viz::FrameSinkManagerImpl* BrowserMainLoop::GetFrameSinkManager() const {
return frame_sink_manager_impl_.get();
}
+
+viz::ServerSharedBitmapManager* BrowserMainLoop::GetServerSharedBitmapManager()
+ const {
+ return server_shared_bitmap_manager_.get();
+}
#endif
void BrowserMainLoop::GetCompositingModeReporter(
@@ -1158,7 +1207,7 @@ void BrowserMainLoop::GetCompositingModeReporter(
// CompositingModeReporter.
return;
#else
- if (features::IsMashEnabled()) {
+ if (!features::IsAshInBrowserProcess()) {
// Mash == ChromeOS, which doesn't support software compositing, so no need
// to report compositing mode.
return;
@@ -1187,26 +1236,31 @@ void BrowserMainLoop::InitializeMainThread() {
int BrowserMainLoop::BrowserThreadsStarted() {
TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted");
- audio_service_runner_ =
- base::MakeRefCounted<base::DeferredSequencedTaskRunner>();
-
// Bring up Mojo IPC and the embedded Service Manager as early as possible.
// Initializaing mojo requires the IO thread to have been initialized first,
// so this cannot happen any earlier than now.
InitializeMojo();
#if BUILDFLAG(ENABLE_MUS)
- if (features::IsMashEnabled()) {
+ if (!features::IsAshInBrowserProcess()) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableSurfaceSynchronization);
}
#endif
HistogramSynchronizer::GetInstance();
-#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
- // Up the priority of the UI thread.
- base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::DISPLAY);
-#endif
+
+ // cc assumes a single client name for metrics in a process, which is
+ // is inconsistent with single process mode where both the renderer and
+ // browser compositor run in the same process. In this case, avoid
+ // initializing with a browser metric name to ensure we record metrics for the
+ // renderer compositor.
+ // Note that since single process mode is only used by webview in practice,
+ // which doesn't have a browser compositor, this is not required anyway.
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSingleProcess)) {
+ cc::SetClientNameForMetrics("Browser");
+ }
// Initialize the GPU shader cache. This needs to be initialized before
// BrowserGpuChannelHostFactory below, since that depends on an initialized
@@ -1214,8 +1268,16 @@ int BrowserMainLoop::BrowserThreadsStarted() {
InitShaderCacheFactorySingleton(
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ // Initialize the FontRenderParams on IO thread. This needs to be initialized
+ // before gpu process initialization below.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(
+ &GpuProcessHost::InitFontRenderParamsOnIO,
+ gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr)));
+
// If mus is not hosting viz, then the browser must.
- bool browser_is_viz_host = !base::FeatureList::IsEnabled(::features::kMash);
+ bool browser_is_viz_host = features::IsAshInBrowserProcess();
bool always_uses_gpu = true;
bool established_gpu_channel = false;
@@ -1246,17 +1308,20 @@ int BrowserMainLoop::BrowserThreadsStarted() {
transport_factory->ConnectHostFrameSinkManager();
ImageTransportFactory::SetFactory(std::move(transport_factory));
} else {
+ server_shared_bitmap_manager_ =
+ std::make_unique<viz::ServerSharedBitmapManager>();
frame_sink_manager_impl_ = std::make_unique<viz::FrameSinkManagerImpl>(
+ server_shared_bitmap_manager_.get(),
switches::GetDeadlineToSynchronizeSurfaces());
surface_utils::ConnectWithLocalFrameSinkManager(
host_frame_sink_manager_.get(), frame_sink_manager_impl_.get());
-
ImageTransportFactory::SetFactory(
std::make_unique<GpuProcessTransportFactory>(
BrowserGpuChannelHostFactory::instance(),
- compositing_mode_reporter_impl_.get(), GetResizeTaskRunner()));
+ compositing_mode_reporter_impl_.get(),
+ server_shared_bitmap_manager_.get(), GetResizeTaskRunner()));
}
}
@@ -1395,7 +1460,10 @@ int BrowserMainLoop::BrowserThreadsStarted() {
}
#if defined(OS_WIN)
- GpuDataManagerImpl::GetInstance()->RequestGpuSupportedRuntimeVersion();
+ if (!parsed_command_line_.HasSwitch(
+ switches::kDisableGpuProcessForDX12VulkanInfoCollection)) {
+ GpuDataManagerImpl::GetInstance()->RequestGpuSupportedRuntimeVersion();
+ }
#endif
#if defined(OS_MACOSX)
@@ -1407,6 +1475,9 @@ int BrowserMainLoop::BrowserThreadsStarted() {
media::SetMediaDrmBridgeClient(GetContentClient()->GetMediaDrmBridgeClient());
#endif
+#if defined(ENABLE_IPC_FUZZER)
+ SetFileUrlPathAliasForIpcFuzzer();
+#endif
return result_code_;
}
@@ -1477,16 +1548,11 @@ bool BrowserMainLoop::InitializeToolkit() {
// Env creates the compositor. Aura widgets need the compositor to be created
// before they can be initialized by the browser.
- env_ = aura::Env::CreateInstance(features::IsMashEnabled()
- ? aura::Env::Mode::MUS
- : aura::Env::Mode::LOCAL);
+ env_ = aura::Env::CreateInstance(features::IsAshInBrowserProcess()
+ ? aura::Env::Mode::LOCAL
+ : aura::Env::Mode::MUS);
#endif // defined(USE_AURA)
-#if BUILDFLAG(ENABLE_MUS)
- if (features::IsMashEnabled())
- image_cursors_set_ = std::make_unique<ui::ImageCursorsSet>();
-#endif
-
if (parts_)
parts_->ToolkitInitialized();
@@ -1505,6 +1571,7 @@ void BrowserMainLoop::MainMessageLoopRun() {
}
base::RunLoop run_loop;
+ parts_->PreDefaultMainMessageLoopRun(run_loop.QuitClosure());
run_loop.Run();
#endif
}
@@ -1517,13 +1584,15 @@ void BrowserMainLoop::InitializeMojo() {
mojo::SyncCallRestrictions::DisallowSyncCall();
}
- mojo_ipc_support_.reset(new mojo::edk::ScopedIPCSupport(
+ mojo_ipc_support_.reset(new mojo::core::ScopedIPCSupport(
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
- mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST));
+ mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST));
- service_manager_context_.reset(new ServiceManagerContext);
+ service_manager_context_.reset(
+ new ServiceManagerContext(io_thread_->task_runner()));
+ ServiceManagerContext::StartBrowserConnection();
#if defined(OS_MACOSX)
- mojo::edk::SetMachPortProvider(MachBroker::GetInstance());
+ mojo::core::SetMachPortProvider(MachBroker::GetInstance());
#endif // defined(OS_MACOSX)
GetContentClient()->OnServiceManagerConnected(
ServiceManagerConnection::GetForProcess());
@@ -1573,15 +1642,15 @@ void BrowserMainLoop::InitializeMojo() {
base::FilePath BrowserMainLoop::GetStartupTraceFileName() const {
base::FilePath trace_file;
-#if defined(OS_ANDROID)
- TracingControllerAndroid::GenerateTracingFilePath(&trace_file);
-#else
trace_file = tracing::TraceStartupConfig::GetInstance()->GetResultFile();
if (trace_file.empty()) {
+#if defined(OS_ANDROID)
+ TracingControllerAndroid::GenerateTracingFilePath(&trace_file);
+#else
// Default to saving the startup trace into the current dir.
trace_file = base::FilePath().AppendASCII("chrometrace.log");
- }
#endif
+ }
return trace_file;
}
@@ -1638,13 +1707,25 @@ void BrowserMainLoop::InitializeAudio() {
TRACE_EVENT_INSTANT0("startup", "Starting Audio service task runner",
TRACE_EVENT_SCOPE_THREAD);
- audio_service_runner_->StartWithTaskRunner(audio_manager_->GetTaskRunner());
+ ServiceManagerContext::GetAudioServiceRunner()->StartWithTaskRunner(
+ audio_manager_->GetTaskRunner());
}
if (base::FeatureList::IsEnabled(features::kAudioServiceLaunchOnStartup)) {
- content::ServiceManagerConnection::GetForProcess()
- ->GetConnector()
- ->StartService(audio::mojom::kServiceName);
+ // Schedule the audio service startup on the main thread.
+ BrowserThread::PostAfterStartupTask(
+ FROM_HERE, BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
+ base::BindOnce([]() {
+ TRACE_EVENT0("audio", "Starting audio service");
+ ServiceManagerConnection* connection =
+ content::ServiceManagerConnection::GetForProcess();
+ if (connection) {
+ // The browser is not shutting down: |connection| would be null
+ // otherwise.
+ connection->GetConnector()->StartService(
+ audio::mojom::kServiceName);
+ }
+ }));
}
audio_system_ = audio::CreateAudioSystem(
diff --git a/chromium/content/browser/browser_main_loop.h b/chromium/content/browser/browser_main_loop.h
index c8618c586f5..040f1b63136 100644
--- a/chromium/content/browser/browser_main_loop.h
+++ b/chromium/content/browser/browser_main_loop.h
@@ -32,7 +32,6 @@ class Env;
namespace base {
class CommandLine;
-class DeferredSequencedTaskRunner;
class FilePath;
class HighResolutionTimerManager;
class MemoryPressureMonitor;
@@ -72,25 +71,20 @@ class MidiService;
} // namespace midi
namespace mojo {
-namespace edk {
+namespace core {
class ScopedIPCSupport;
-} // namespace edk
+} // namespace core
} // namespace mojo
namespace net {
class NetworkChangeNotifier;
} // namespace net
-#if BUILDFLAG(ENABLE_MUS)
-namespace ui {
-class ImageCursorsSet;
-}
-#endif
-
namespace viz {
class CompositingModeReporterImpl;
class FrameSinkManagerImpl;
class HostFrameSinkManager;
+class ServerSharedBitmapManager;
}
namespace content {
@@ -126,13 +120,14 @@ class CONTENT_EXPORT BrowserMainLoop {
// that return objects which are owned by this class.
static BrowserMainLoop* GetInstance();
+ static media::AudioManager* GetAudioManager();
+
+ // The TaskScheduler instance must exist but not to be started when building
+ // BrowserMainLoop.
explicit BrowserMainLoop(const MainFunctionParams& parameters);
virtual ~BrowserMainLoop();
- // |service_manager_thread| is optional. If set, it will be registered as
- // BrowserThread::IO in CreateThreads() instead of creating a brand new
- // thread.
- void Init(std::unique_ptr<BrowserProcessSubThread> service_manager_thread);
+ void Init();
// Return value is exit status. Anything other than RESULT_CODE_NORMAL_EXIT
// is considered an error.
@@ -163,7 +158,6 @@ class CONTENT_EXPORT BrowserMainLoop {
int GetResultCode() const { return result_code_; }
media::AudioManager* audio_manager() const;
- base::SequencedTaskRunner* audio_service_runner();
bool AudioServiceOutOfProcess() const;
media::AudioSystem* audio_system() const { return audio_system_.get(); }
MediaStreamManager* media_stream_manager() const {
@@ -191,10 +185,6 @@ 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
@@ -217,6 +207,9 @@ class CONTENT_EXPORT BrowserMainLoop {
// TODO(crbug.com/657959): This will be removed once there are no users, as
// SurfaceManager is being moved out of process.
viz::FrameSinkManagerImpl* GetFrameSinkManager() const;
+
+ // This returns null when the display compositor is out of process.
+ viz::ServerSharedBitmapManager* GetServerSharedBitmapManager() const;
#endif
// Fulfills a mojo pointer to the singleton CompositingModeReporter.
@@ -307,9 +300,6 @@ 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
@@ -345,7 +335,7 @@ class CONTENT_EXPORT BrowserMainLoop {
// Members initialized in |BrowserThreadsStarted()| --------------------------
std::unique_ptr<ServiceManagerContext> service_manager_context_;
- std::unique_ptr<mojo::edk::ScopedIPCSupport> mojo_ipc_support_;
+ std::unique_ptr<mojo::core::ScopedIPCSupport> mojo_ipc_support_;
// |user_input_monitor_| has to outlive |audio_manager_|, so declared first.
std::unique_ptr<media::UserInputMonitor> user_input_monitor_;
@@ -354,9 +344,6 @@ class CONTENT_EXPORT BrowserMainLoop {
// process.
std::unique_ptr<media::AudioManager> audio_manager_;
- // Task runner for the audio service when it runs in the browser process.
- scoped_refptr<base::DeferredSequencedTaskRunner> audio_service_runner_;
-
std::unique_ptr<media::AudioSystem> audio_system_;
#if defined(OS_CHROMEOS)
@@ -384,6 +371,11 @@ class CONTENT_EXPORT BrowserMainLoop {
scoped_refptr<SaveFileManager> save_file_manager_;
std::unique_ptr<content::TracingControllerImpl> tracing_controller_;
#if !defined(OS_ANDROID)
+ // A SharedBitmapManager used to sharing and mapping IDs to shared memory
+ // between processes for software compositing. When the display compositor is
+ // in the browser process, then |server_shared_bitmap_manager_| is set, and
+ // when it is in the viz process, then it is null.
+ std::unique_ptr<viz::ServerSharedBitmapManager> server_shared_bitmap_manager_;
std::unique_ptr<viz::HostFrameSinkManager> host_frame_sink_manager_;
// This is owned here so that SurfaceManager will be accessible in process
// when display is in the same process. Other than using SurfaceManager,
diff --git a/chromium/content/browser/browser_main_loop_unittest.cc b/chromium/content/browser/browser_main_loop_unittest.cc
index 24e38ba8a61..46955a01c56 100644
--- a/chromium/content/browser/browser_main_loop_unittest.cc
+++ b/chromium/content/browser/browser_main_loop_unittest.cc
@@ -21,7 +21,7 @@ namespace content {
// the number of cores in its foreground pool.
TEST(BrowserMainLoopTest, CreateThreadsInSingleProcess) {
{
- base::MessageLoop message_loop;
+ base::TaskScheduler::Create("Browser");
base::test::ScopedCommandLine scoped_command_line;
scoped_command_line.GetProcessCommandLine()->AppendSwitch(
switches::kSingleProcess);
@@ -29,7 +29,7 @@ TEST(BrowserMainLoopTest, CreateThreadsInSingleProcess) {
*scoped_command_line.GetProcessCommandLine());
BrowserMainLoop browser_main_loop(main_function_params);
browser_main_loop.MainMessageLoopStart();
- browser_main_loop.Init(nullptr);
+ browser_main_loop.Init();
browser_main_loop.CreateThreads();
EXPECT_GE(base::TaskScheduler::GetInstance()
->GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated(
diff --git a/chromium/content/browser/browser_main_runner_impl.cc b/chromium/content/browser/browser_main_runner_impl.cc
index 6381234ca78..e0c7136869b 100644
--- a/chromium/content/browser/browser_main_runner_impl.cc
+++ b/chromium/content/browser/browser_main_runner_impl.cc
@@ -23,7 +23,6 @@
#include "components/tracing/common/trace_startup_config.h"
#include "components/tracing/common/tracing_switches.h"
#include "content/browser/browser_main_loop.h"
-#include "content/browser/browser_process_sub_thread.h"
#include "content/browser/browser_shutdown_profile_dumper.h"
#include "content/browser/notification_service_impl.h"
#include "content/common/content_switches_internal.h"
@@ -63,12 +62,6 @@ BrowserMainRunnerImpl::~BrowserMainRunnerImpl() {
}
int BrowserMainRunnerImpl::Initialize(const MainFunctionParams& parameters) {
- return Initialize(parameters, nullptr);
-}
-
-int BrowserMainRunnerImpl::Initialize(
- const MainFunctionParams& parameters,
- std::unique_ptr<BrowserProcessSubThread> service_manager_thread) {
SCOPED_UMA_HISTOGRAM_LONG_TIMER(
"Startup.BrowserMainRunnerImplInitializeLongTime");
TRACE_EVENT0("startup", "BrowserMainRunnerImpl::Initialize");
@@ -117,7 +110,7 @@ int BrowserMainRunnerImpl::Initialize(
main_loop_.reset(new BrowserMainLoop(parameters));
- main_loop_->Init(std::move(service_manager_thread));
+ main_loop_->Init();
if (parameters.created_main_parts_closure) {
parameters.created_main_parts_closure->Run(main_loop_->parts());
diff --git a/chromium/content/browser/browser_main_runner_impl.h b/chromium/content/browser/browser_main_runner_impl.h
index adb084fe27c..08e959ff7aa 100644
--- a/chromium/content/browser/browser_main_runner_impl.h
+++ b/chromium/content/browser/browser_main_runner_impl.h
@@ -19,7 +19,6 @@ class ScopedOleInitializer;
namespace content {
-class BrowserProcessSubThread;
class BrowserMainLoop;
class NotificationServiceImpl;
@@ -38,12 +37,6 @@ class BrowserMainRunnerImpl : public BrowserMainRunner {
int Run() override;
void Shutdown() override;
- // Initialize all necessary browser state with a |service_manager_thread|
- // on which ServiceManager is currently running.
- int Initialize(
- const MainFunctionParams& parameters,
- std::unique_ptr<BrowserProcessSubThread> service_manager_thread);
-
private:
// True if we have started to initialize the runner.
bool initialization_started_;
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc b/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
index c3e3bbd9b50..788d8399321 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
+++ b/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
@@ -196,18 +196,18 @@ BrowserPluginGuest* BrowserPluginEmbedder::GetFullPageGuest() {
}
// static
-bool BrowserPluginEmbedder::GuestRecentlyAudibleCallback(WebContents* guest) {
- return guest->WasRecentlyAudible();
+bool BrowserPluginEmbedder::GuestCurrentlyAudibleCallback(WebContents* guest) {
+ return guest->IsCurrentlyAudible();
}
-bool BrowserPluginEmbedder::WereAnyGuestsRecentlyAudible() {
+bool BrowserPluginEmbedder::AreAnyGuestsCurrentlyAudible() {
if (!GetBrowserPluginGuestManager())
return false;
return GetBrowserPluginGuestManager()->ForEachGuest(
web_contents(),
base::BindRepeating(
- &BrowserPluginEmbedder::GuestRecentlyAudibleCallback));
+ &BrowserPluginEmbedder::GuestCurrentlyAudibleCallback));
}
// static
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_embedder.h b/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
index e1007f040a7..326a9ac8fdd 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
@@ -80,8 +80,8 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
BrowserPluginGuest* GetFullPageGuest();
// Polls all guests for this web contents and returns true if any of them
- // were audible recently.
- bool WereAnyGuestsRecentlyAudible();
+ // are currently audible.
+ bool AreAnyGuestsCurrentlyAudible();
private:
explicit BrowserPluginEmbedder(WebContentsImpl* web_contents);
@@ -98,7 +98,7 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
static bool UnlockMouseIfNecessaryCallback(bool* mouse_unlocked,
WebContents* guest);
- static bool GuestRecentlyAudibleCallback(WebContents* guest);
+ static bool GuestCurrentlyAudibleCallback(WebContents* guest);
// Message handlers.
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
index a0bc9305e62..f56ce93c3d5 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -87,7 +87,6 @@ BrowserPluginGuest::BrowserPluginGuest(bool has_render_view,
: WebContentsObserver(web_contents),
owner_web_contents_(nullptr),
attached_(false),
- has_attached_since_surface_set_(false),
browser_plugin_instance_id_(browser_plugin::kInstanceIDNone),
focused_(false),
mouse_locked_(false),
@@ -407,12 +406,11 @@ void BrowserPluginGuest::PointerLockPermissionResponse(bool allow) {
browser_plugin_instance_id(), allow));
}
-void BrowserPluginGuest::SetChildFrameSurface(
+void BrowserPluginGuest::FirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) {
- has_attached_since_surface_set_ = false;
- if (!base::FeatureList::IsEnabled(::features::kMash)) {
+ if (features::IsAshInBrowserProcess()) {
SendMessageToEmbedder(
- std::make_unique<BrowserPluginMsg_SetChildFrameSurface>(
+ std::make_unique<BrowserPluginMsg_FirstSurfaceActivation>(
browser_plugin_instance_id(), surface_info));
}
}
@@ -663,7 +661,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() && !base::FeatureList::IsEnabled(::features::kMash)) {
+ if (attached() && features::IsAshInBrowserProcess()) {
RenderWidgetHostViewGuest* rwhv = static_cast<RenderWidgetHostViewGuest*>(
web_contents()->GetRenderWidgetHostView());
if (rwhv) {
@@ -796,7 +794,6 @@ void BrowserPluginGuest::OnWillAttachComplete(
InitInternal(params, embedder_web_contents);
attached_ = true;
- has_attached_since_surface_set_ = true;
SendQueuedMessages();
delegate_->DidAttach(GetGuestProxyRoutingID());
@@ -1038,8 +1035,8 @@ void BrowserPluginGuest::OnSynchronizeVisualProperties(
if (local_surface_id_ > local_surface_id ||
((frame_rect_.size() != visual_properties.screen_space_rect.size() ||
screen_info_ != visual_properties.screen_info ||
- capture_sequence_number_ !=
- visual_properties.capture_sequence_number) &&
+ capture_sequence_number_ != visual_properties.capture_sequence_number ||
+ zoom_level_ != visual_properties.zoom_level) &&
local_surface_id_ == local_surface_id)) {
SiteInstance* owner_site_instance = delegate_->GetOwnerSiteInstance();
bad_message::ReceivedBadMessage(
@@ -1050,6 +1047,8 @@ void BrowserPluginGuest::OnSynchronizeVisualProperties(
screen_info_ = visual_properties.screen_info;
frame_rect_ = visual_properties.screen_space_rect;
+ zoom_level_ = visual_properties.zoom_level;
+
GetWebContents()->SendScreenRects();
local_surface_id_ = local_surface_id;
bool capture_sequence_number_changed =
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.h b/chromium/content/browser/browser_plugin/browser_plugin_guest.h
index 964137dafc0..aab107192d0 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.h
@@ -215,12 +215,6 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
// Returns whether the guest is attached to an embedder.
bool attached() const { return attached_; }
- // Returns true when an attachment has taken place since the last time the
- // compositor surface was set.
- bool has_attached_since_surface_set() const {
- return has_attached_since_surface_set_;
- }
-
// Attaches this BrowserPluginGuest to the provided |embedder_web_contents|
// and initializes the guest with the provided |params|. Attaching a guest
// to an embedder implies that this guest's lifetime is no longer managed
@@ -250,7 +244,7 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
void PointerLockPermissionResponse(bool allow);
// The next function is virtual for test purposes.
- virtual void SetChildFrameSurface(const viz::SurfaceInfo& surface_info);
+ virtual void FirstSurfaceActivation(const viz::SurfaceInfo& surface_info);
void ResendEventToEmbedder(const blink::WebInputEvent& event);
@@ -271,11 +265,6 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
WebContentsImpl* web_contents,
BrowserPluginGuestDelegate* delegate);
- // Protected for testing.
- void set_has_attached_since_surface_set_for_test(bool has_attached) {
- has_attached_since_surface_set_ = has_attached;
- }
-
void set_attached_for_test(bool attached) {
attached_ = attached;
}
@@ -397,10 +386,6 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
// Indicates whether this guest has been attached to a container.
bool attached_;
- // Used to signal if a browser plugin has been attached since the last time
- // the compositing surface was set.
- bool has_attached_since_surface_set_;
-
// An identifier that uniquely identifies a browser plugin within an embedder.
int browser_plugin_instance_id_;
gfx::Rect frame_rect_;
@@ -455,6 +440,7 @@ class CONTENT_EXPORT BrowserPluginGuest : public GuestHost,
viz::LocalSurfaceId local_surface_id_;
ScreenInfo screen_info_;
+ double zoom_level_ = 0.0;
uint32_t capture_sequence_number_ = 0u;
// Weak pointer used to ask GeolocationPermissionContext about geolocation
diff --git a/chromium/content/browser/browser_process_sub_thread.cc b/chromium/content/browser/browser_process_sub_thread.cc
index 6f33cee4d65..876318dc799 100644
--- a/chromium/content/browser/browser_process_sub_thread.cc
+++ b/chromium/content/browser/browser_process_sub_thread.cc
@@ -197,14 +197,7 @@ void BrowserProcessSubThread::IOThreadCleanUp() {
static_cast<UtilityProcessHost*>(it.GetDelegate());
if (utility_process->sandbox_type() ==
service_manager::SANDBOX_TYPE_NETWORK) {
- // Even though the TerminateAll call above tries to kill all child
- // processes, that will fail sometimes (e.g. on Windows if there's pending
- // I/O). Once the network service is sandboxed this will be taken care of,
- // since the sandbox ensures child processes are terminated. Until then,
- // wait on the network process for a bit. This is done so that:
- // 1) when Chrome quits, we ensure that cookies & cache are flushed
- // 2) tests aren't killed by swarming because of child processes that
- // outlive the parent process.
+ // This ensures that cookies and cache are flushed to disk on shutdown.
// https://crbug.com/841001
const int kMaxSecondsToWaitForNetworkProcess = 10;
ChildProcessHostImpl* child_process =
diff --git a/chromium/content/browser/browser_side_navigation_browsertest.cc b/chromium/content/browser/browser_side_navigation_browsertest.cc
index bbc595fb84f..b4cf78fea84 100644
--- a/chromium/content/browser/browser_side_navigation_browsertest.cc
+++ b/chromium/content/browser/browser_side_navigation_browsertest.cc
@@ -5,6 +5,7 @@
#include <stdint.h>
#include "base/command_line.h"
+#include "base/files/scoped_temp_dir.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
@@ -15,7 +16,9 @@
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/download_manager_delegate.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
@@ -29,8 +32,10 @@
#include "content/public/test/navigation_handle_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/shell/browser/shell.h"
+#include "content/shell/browser/shell_download_manager_delegate.h"
#include "content/shell/browser/shell_network_delegate.h"
#include "content/test/content_browser_test_utils_internal.h"
+#include "content/test/did_commit_provisional_load_interceptor.h"
#include "ipc/ipc_security_test_util.h"
#include "net/base/filename_util.h"
#include "net/base/load_flags.h"
@@ -43,6 +48,96 @@
namespace content {
+namespace {
+
+class InterceptAndCancelDidCommitProvisionalLoad
+ : public DidCommitProvisionalLoadInterceptor {
+ public:
+ explicit InterceptAndCancelDidCommitProvisionalLoad(WebContents* web_contents)
+ : DidCommitProvisionalLoadInterceptor(web_contents) {}
+ ~InterceptAndCancelDidCommitProvisionalLoad() override {}
+
+ void Wait(size_t number_of_messages) {
+ while (intercepted_messages_.size() < number_of_messages) {
+ loop_.reset(new base::RunLoop);
+ loop_->Run();
+ }
+ }
+
+ const std::vector<::FrameHostMsg_DidCommitProvisionalLoad_Params>&
+ intercepted_messages() const {
+ return intercepted_messages_;
+ }
+
+ std::vector<::service_manager::mojom::InterfaceProviderRequest>&
+ intercepted_requests() {
+ return intercepted_requests_;
+ }
+
+ protected:
+ bool WillDispatchDidCommitProvisionalLoad(
+ RenderFrameHost* render_frame_host,
+ ::FrameHostMsg_DidCommitProvisionalLoad_Params* params,
+ service_manager::mojom::InterfaceProviderRequest*
+ interface_provider_request) override {
+ intercepted_messages_.push_back(*params);
+ intercepted_requests_.push_back(std::move(*interface_provider_request));
+ if (loop_)
+ loop_->Quit();
+ // Do not send the message to the RenderFrameHostImpl.
+ return false;
+ }
+
+ std::vector<::FrameHostMsg_DidCommitProvisionalLoad_Params>
+ intercepted_messages_;
+ std::vector<::service_manager::mojom::InterfaceProviderRequest>
+ intercepted_requests_;
+ std::unique_ptr<base::RunLoop> loop_;
+};
+
+// Record every WebContentsObserver's event related to navigation. The goal is
+// to check these events happen and happen in the expected right order.
+class NavigationRecorder : public WebContentsObserver {
+ public:
+ NavigationRecorder(WebContents* web_contents)
+ : WebContentsObserver(web_contents) {}
+
+ // WebContentsObserver implementation.
+ void DidStartNavigation(NavigationHandle* navigation_handle) override {
+ records_.push_back("start " + navigation_handle->GetURL().path());
+ WakeUp();
+ }
+ void ReadyToCommitNavigation(NavigationHandle* navigation_handle) override {
+ records_.push_back("ready-to-commit " + navigation_handle->GetURL().path());
+ WakeUp();
+ }
+ void DidFinishNavigation(NavigationHandle* navigation_handle) override {
+ records_.push_back("did-commit " + navigation_handle->GetURL().path());
+ WakeUp();
+ }
+
+ void WaitForEvents(size_t numbers_of_events) {
+ while (records_.size() < numbers_of_events) {
+ loop_.reset(new base::RunLoop);
+ loop_->Run();
+ loop_.reset();
+ }
+ }
+
+ const std::vector<std::string> records() { return records_; }
+
+ private:
+ void WakeUp() {
+ if (loop_)
+ loop_->Quit();
+ }
+
+ std::unique_ptr<base::RunLoop> loop_;
+ std::vector<std::string> records_;
+};
+
+} // namespace
+
// Test with BrowserSideNavigation enabled (aka PlzNavigate).
// If you don't need a custom embedded test server, please use the next class
// below (BrowserSideNavigationBrowserTest), it will automatically start the
@@ -458,8 +553,6 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserDisableWebSecurityTest,
data_url, Referrer(), ui::PAGE_TRANSITION_LINK,
FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT, true /* allow_download */,
false /* should_replace_current_entry */,
- base::TimeTicks() /* ui_timestamp */,
- FrameMsg_UILoadMetricsReportType::NO_REPORT,
file_url, /* base_url_for_data_url */
GURL() /* history_url_for_data_url */, PREVIEWS_UNSPECIFIED,
base::TimeTicks::Now() /* navigation_start */, "GET",
@@ -481,8 +574,18 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserDisableWebSecurityTest,
// Receiving the invalid IPC message should lead to renderer process
// termination.
RenderProcessHostKillWaiter process_kill_waiter(rfh->GetProcess());
- rfh->frame_host_binding_for_testing().impl()->BeginNavigation(
- common_params, std::move(begin_params), nullptr);
+
+ mojom::NavigationClientAssociatedPtr navigation_client;
+ if (IsPerNavigationMojoInterfaceEnabled()) {
+ auto navigation_client_request =
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&navigation_client);
+ rfh->frame_host_binding_for_testing().impl()->BeginNavigation(
+ common_params, std::move(begin_params), nullptr,
+ navigation_client.PassInterface());
+ } else {
+ rfh->frame_host_binding_for_testing().impl()->BeginNavigation(
+ common_params, std::move(begin_params), nullptr, nullptr);
+ }
EXPECT_EQ(bad_message::RFH_BASE_URL_FOR_DATA_URL_SPECIFIED,
process_kill_waiter.Wait());
@@ -704,4 +807,297 @@ IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
}
}
+// Regression test for https://crbug.com/260144
+// Back/Forward navigation in an iframe must not stop ongoing XHR.
+IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
+ IframeNavigationsDoNotStopXHR) {
+ // A response for the XHR request. It will be delayed until the end of all the
+ // navigations.
+ net::test_server::ControllableHttpResponse xhr_response(
+ embedded_test_server(), "/xhr");
+ EXPECT_TRUE(embedded_test_server()->Start());
+
+ GURL url(embedded_test_server()->GetURL("/title1.html"));
+ NavigateToURL(shell(), url);
+
+ DOMMessageQueue dom_message_queue(WebContents::FromRenderFrameHost(
+ shell()->web_contents()->GetMainFrame()));
+ std::string message;
+
+ // 1) Send an XHR.
+ ExecuteScriptAsync(
+ shell(),
+ "let xhr = new XMLHttpRequest();"
+ "xhr.open('GET', './xhr', true);"
+ "xhr.onabort = () => window.domAutomationController.send('xhr.onabort');"
+ "xhr.onerror = () => window.domAutomationController.send('xhr.onerror');"
+ "xhr.onload = () => window.domAutomationController.send('xhr.onload');"
+ "xhr.send();");
+
+ // 2) Create an iframe and wait for the initial load.
+ {
+ ExecuteScriptAsync(
+ shell(),
+ "var iframe = document.createElement('iframe');"
+ "iframe.src = './title1.html';"
+ "iframe.onload = function() {"
+ " window.domAutomationController.send('iframe.onload');"
+ "};"
+ "document.body.appendChild(iframe);");
+
+ EXPECT_TRUE(dom_message_queue.WaitForMessage(&message));
+ EXPECT_EQ("\"iframe.onload\"", message);
+ }
+
+ // 3) Navigate the iframe elsewhere.
+ {
+ ExecuteScriptAsync(shell(),
+ "var iframe = document.querySelector('iframe');"
+ "iframe.src = './title2.html';");
+
+ EXPECT_TRUE(dom_message_queue.WaitForMessage(&message));
+ EXPECT_EQ("\"iframe.onload\"", message);
+ }
+
+ // 4) history.back() in the iframe.
+ {
+ ExecuteScriptAsync(shell(),
+ "var iframe = document.querySelector('iframe');"
+ "iframe.contentWindow.history.back()");
+
+ EXPECT_TRUE(dom_message_queue.WaitForMessage(&message));
+ EXPECT_EQ("\"iframe.onload\"", message);
+ }
+
+ // 5) history.forward() in the iframe.
+ {
+ ExecuteScriptAsync(shell(),
+ "var iframe = document.querySelector('iframe');"
+ "iframe.contentWindow.history.forward()");
+
+ EXPECT_TRUE(dom_message_queue.WaitForMessage(&message));
+ EXPECT_EQ("\"iframe.onload\"", message);
+ }
+
+ // 6) Wait for the XHR.
+ {
+ xhr_response.WaitForRequest();
+ xhr_response.Send(
+ "HTTP/1.1 200 OK\r\n"
+ "Connection: close\r\n"
+ "Content-Length: 2\r\n"
+ "Content-Type: text/plain; charset=utf-8\r\n"
+ "\r\n"
+ "OK");
+ xhr_response.Done();
+ EXPECT_TRUE(dom_message_queue.WaitForMessage(&message));
+ EXPECT_EQ("\"xhr.onload\"", message);
+ }
+
+ EXPECT_FALSE(dom_message_queue.PopMessage(&message));
+}
+
+// Regression test for https://crbug.com/856396.
+IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBaseBrowserTest,
+ ReplacingDocumentLoaderFiresLoadEvent) {
+ net::test_server::ControllableHttpResponse main_document_response(
+ embedded_test_server(), "/main_document");
+ net::test_server::ControllableHttpResponse iframe_response(
+ embedded_test_server(), "/iframe");
+
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ // 1) Load the main document.
+ shell()->LoadURL(embedded_test_server()->GetURL("/main_document"));
+ main_document_response.WaitForRequest();
+ main_document_response.Send(
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "\r\n"
+ "<script>"
+ " var detach_iframe = function() {"
+ " var iframe = document.querySelector('iframe');"
+ " iframe.parentNode.removeChild(iframe);"
+ " }"
+ "</script>"
+ "<body onload='detach_iframe()'>"
+ " <iframe src='/iframe'></iframe>"
+ "</body>");
+ main_document_response.Done();
+
+ // 2) The iframe starts to load, but the server only have time to send the
+ // response's headers, not the response's body. A provisional DocumentLoader
+ // will be created in the renderer process, but it will never commit.
+ iframe_response.WaitForRequest();
+ iframe_response.Send(
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "\r\n");
+
+ // 3) In the meantime the iframe navigates elsewhere. It causes the previous
+ // provisional DocumentLoader to be replaced by the new one. Removing it may
+ // trigger the 'load' event and delete the iframe.
+ EXPECT_TRUE(ExecuteScript(
+ shell(), "document.querySelector('iframe').src = '/title1.html'"));
+
+ // Wait for the iframe to be deleted and check the renderer process is still
+ // alive.
+ int iframe_count = 1;
+ while (iframe_count != 0) {
+ ASSERT_TRUE(ExecuteScriptAndExtractInt(
+ shell(),
+ "var iframe_count = document.getElementsByTagName('iframe').length;"
+ "window.domAutomationController.send(iframe_count);",
+ &iframe_count));
+ }
+}
+
+class NavigationDownloadBrowserTest
+ : public BrowserSideNavigationBaseBrowserTest {
+ protected:
+ void SetUpOnMainThread() override {
+ BrowserSideNavigationBaseBrowserTest::SetUpOnMainThread();
+
+ // Set up a test download directory, in order to prevent prompting for
+ // handling downloads.
+ ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
+ ShellDownloadManagerDelegate* delegate =
+ static_cast<ShellDownloadManagerDelegate*>(
+ shell()
+ ->web_contents()
+ ->GetBrowserContext()
+ ->GetDownloadManagerDelegate());
+ delegate->SetDownloadBehaviorForTesting(downloads_directory_.GetPath());
+ }
+
+ private:
+ base::ScopedTempDir downloads_directory_;
+};
+
+// Regression test for https://crbug.com/855033
+// 1) A page contains many scripts and DOM elements. It forces the parser to
+// yield CPU to other tasks. That way the response body's data are not fully
+// read when URLLoaderClient::OnComplete(..) is received.
+// 2) A script makes the document navigates elsewhere while it is still loading.
+// It cancels the parser of the current document. Due to a bug, the document
+// loader was not marked to be 'loaded' at this step.
+// 3) The request for the new navigation starts and it turns out it is a
+// download. The navigation is dropped.
+// 4) There are no more possibilities for DidStopLoading() to be sent.
+IN_PROC_BROWSER_TEST_F(NavigationDownloadBrowserTest,
+ StopLoadingAfterDroppedNavigation) {
+ net::test_server::ControllableHttpResponse main_response(
+ embedded_test_server(), "/main");
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ GURL main_url(embedded_test_server()->GetURL("/main"));
+ GURL download_url(embedded_test_server()->GetURL("/download-test1.lib"));
+
+ shell()->LoadURL(main_url);
+ main_response.WaitForRequest();
+ std::string headers =
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "\r\n";
+
+ // Craft special HTML to make the blink::DocumentParser yield CPU to other
+ // tasks. The goal is to ensure the response body datapipe is not fully read
+ // when URLLoaderClient::OnComplete() is called.
+ // This relies on the HTMLParserScheduler::ShouldYield() heuristics.
+ std::string mix_of_script_and_div = "<script></script><div></div>";
+ for (size_t i = 0; i < 10; ++i) {
+ mix_of_script_and_div += mix_of_script_and_div; // Exponential growth.
+ }
+
+ std::string navigate_to_download =
+ "<script>location.href='" + download_url.spec() + "'</script>";
+
+ main_response.Send(headers + navigate_to_download + mix_of_script_and_div);
+ main_response.Done();
+
+ EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+}
+
+// This test reproduces the following race condition:
+// 1) A first navigation starts, the headers are received, the navigation
+// reaches ready-to-commit. It is sent to the renderer to be committed.
+// 2) In the meantime, a second navigation reaches ready-to-commit in the
+// browser.
+// 3) Before the renderer gets notified of the new navigation, the
+// first navigation is committed.
+// 4) The browser gets notified of the commit of the first navigation. This
+// should not destroy the NavigationRequest corresponding to the second
+// navigation.
+IN_PROC_BROWSER_TEST_F(BrowserSideNavigationBrowserTest,
+ RaceNewNavigationCommitWhileOldOneFinishesLoading) {
+ // Start the test with an initial document.
+ GURL main_url(embedded_test_server()->GetURL("/simple_page.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ RenderFrameHostImpl* render_frame_host = static_cast<RenderFrameHostImpl*>(
+ shell()->web_contents()->GetMainFrame());
+
+ NavigationRecorder recorder(shell()->web_contents());
+ // Note: These two pages contain an image that will never load. The goal is to
+ // prevent RenderFrameHostImpl::DidStopLoading() to be called since it will
+ // cancel any pending navigation.
+ GURL page_1(embedded_test_server()->GetURL("/infinite_load_1.html"));
+ GURL page_2(embedded_test_server()->GetURL("/infinite_load_2.html"));
+ // Intercept and cancel any FrameMsgHost_DidCommitProvisionalLoad events.
+ InterceptAndCancelDidCommitProvisionalLoad interceptor(
+ shell()->web_contents());
+
+ // 1) Navigate to page_1.
+ shell()->LoadURL(page_1);
+
+ // 2) The browser receives the response's headers. The navigation commits in
+ // the browser.
+ recorder.WaitForEvents(2);
+ EXPECT_EQ(2u, recorder.records().size());
+ EXPECT_STREQ("start /infinite_load_1.html", recorder.records()[0].c_str());
+ EXPECT_STREQ("ready-to-commit /infinite_load_1.html",
+ recorder.records()[1].c_str());
+
+ // 3) Wait for the renderer to receive the response's body, but do not notify
+ // the browser of it right now. It is delayed in 6).
+ interceptor.Wait(1);
+ EXPECT_EQ(1u, interceptor.intercepted_messages().size());
+
+ // 4) In the meantime, the browser starts a navigation to page_2.
+ shell()->LoadURL(page_2);
+
+ // 5) The response's headers are received, the navigation reaches
+ // ready-to-commit in the browser. This should not delete the ongoing
+ // NavigationRequest.
+ recorder.WaitForEvents(4);
+ EXPECT_EQ(4u, recorder.records().size());
+ EXPECT_STREQ("start /infinite_load_2.html", recorder.records()[2].c_str());
+ EXPECT_STREQ("ready-to-commit /infinite_load_2.html",
+ recorder.records()[3].c_str());
+
+ // 6) The browser receives the first DidCommitProvisionalLoad message. This
+ // should not delete the second navigation. This is the end of the first
+ // navigation.
+ render_frame_host->DidCommitProvisionalLoadForTesting(
+ std::make_unique<::FrameHostMsg_DidCommitProvisionalLoad_Params>(
+ interceptor.intercepted_messages()[0]),
+ std::move(interceptor.intercepted_requests()[0]));
+ recorder.WaitForEvents(5);
+ EXPECT_EQ(5u, recorder.records().size());
+ EXPECT_STREQ("did-commit /infinite_load_1.html",
+ recorder.records()[4].c_str());
+
+ // 7) Wait for the renderer to receive the second response's body. This is the
+ // end of the second navigation.
+ interceptor.Wait(2);
+ EXPECT_EQ(2u, interceptor.intercepted_messages().size());
+ render_frame_host->DidCommitProvisionalLoadForTesting(
+ std::make_unique<::FrameHostMsg_DidCommitProvisionalLoad_Params>(
+ interceptor.intercepted_messages()[1]),
+ std::move(interceptor.intercepted_requests()[1]));
+ recorder.WaitForEvents(6);
+ EXPECT_EQ(6u, recorder.records().size());
+ EXPECT_STREQ("did-commit /infinite_load_2.html",
+ recorder.records()[5].c_str());
+}
+
} // namespace content
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 4c478ad0079..3226847af60 100644
--- a/chromium/content/browser/browsing_data/browsing_data_remover_impl.cc
+++ b/chromium/content/browser/browsing_data/browsing_data_remover_impl.cc
@@ -16,6 +16,7 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
+#include "base/stl_util.h"
#include "content/browser/browsing_data/storage_partition_http_cache_data_remover.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -67,8 +68,7 @@ bool DoesOriginMatchMaskAndURLs(
const std::vector<std::string>& schemes = url::GetWebStorageSchemes();
bool is_web_scheme =
- (std::find(schemes.begin(), schemes.end(), origin.GetOrigin().scheme()) !=
- schemes.end());
+ base::ContainsValue(schemes, origin.GetOrigin().scheme());
// If a websafe origin is unprotected, it matches iff UNPROTECTED_WEB.
if ((!policy || !policy->IsStorageProtected(origin.GetOrigin())) &&
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 c7322c1f278..2f95096b273 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
@@ -342,7 +342,7 @@ class RemoveChannelIDTester : public net::SSLConfigService::Observer {
}
net::ChannelIDService* channel_id_service_;
- scoped_refptr<net::SSLConfigService> ssl_config_service_;
+ net::SSLConfigService* ssl_config_service_;
int ssl_config_changed_count_ = 0;
DISALLOW_COPY_AND_ASSIGN(RemoveChannelIDTester);
@@ -1492,7 +1492,8 @@ TEST_F(BrowsingDataRemoverImplTest, RemoveNetworkErrorLogging) {
GURL domain("https://google.com");
logging_service->OnHeader(url::Origin::Create(domain),
- "{\"report-to\":\"group\",\"max-age\":86400}");
+ net::IPAddress(192, 168, 0, 1),
+ "{\"report_to\":\"group\",\"max_age\":86400}");
ASSERT_EQ(1u, logging_service->GetPolicyOriginsForTesting().size());
@@ -1513,16 +1514,20 @@ TEST_F(BrowsingDataRemoverImplTest, RemoveNetworkErrorLogging_SpecificOrigins) {
GURL domain1("https://google.com");
logging_service->OnHeader(url::Origin::Create(domain1),
- "{\"report-to\":\"group\",\"max-age\":86400}");
+ net::IPAddress(192, 168, 0, 1),
+ "{\"report_to\":\"group\",\"max_age\":86400}");
GURL domain2("https://host2.com");
logging_service->OnHeader(url::Origin::Create(domain2),
- "{\"report-to\":\"group\",\"max-age\":86400}");
+ net::IPAddress(192, 168, 0, 1),
+ "{\"report_to\":\"group\",\"max_age\":86400}");
GURL domain3("https://host3.com");
logging_service->OnHeader(url::Origin::Create(domain3),
- "{\"report-to\":\"group\",\"max-age\":86400}");
+ net::IPAddress(192, 168, 0, 1),
+ "{\"report_to\":\"group\",\"max_age\":86400}");
GURL domain4("https://host4.com");
logging_service->OnHeader(url::Origin::Create(domain4),
- "{\"report-to\":\"group\",\"max-age\":86400}");
+ net::IPAddress(192, 168, 0, 1),
+ "{\"report_to\":\"group\",\"max_age\":86400}");
ASSERT_EQ(4u, logging_service->GetPolicyOriginsForTesting().size());
diff --git a/chromium/content/browser/cache_storage/README.md b/chromium/content/browser/cache_storage/README.md
index ea05b6c9d5e..77dfc1f4d07 100644
--- a/chromium/content/browser/cache_storage/README.md
+++ b/chromium/content/browser/cache_storage/README.md
@@ -3,12 +3,17 @@ This document describes the browser-process implementation of the [Cache
Storage specification](
https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html).
+As of June 2018, Chrome components can use the Cache Storage interface via
+`CacheStorageManager` to store Request/Response key-value pairs. The concept of
+`CacheStorageOwner` was added to distinguish and isolate the different
+components.
+
## Major Classes and Ownership
### Ownership
Where '=>' represents ownership, '->' is a reference, and '~>' is a weak
reference.
-##### `CacheStorageContextImpl`=>`CacheStorageManager`=>`CacheStorage`=>`CacheStorageCache`
+##### `CacheStorageContextImpl`->`CacheStorageManager`=>`CacheStorage`=>`CacheStorageCache`
* A `CacheStorageManager` can own multiple `CacheStorage` objects.
* A `CacheStorage` can own multiple `CacheStorageCache` objects.
@@ -44,12 +49,12 @@ reference.
mitigate rapid opening/closing/opening churn.
### CacheStorageManager
-1. Forwards calls to the appropriate `CacheStorage` for a given origin,
- loading `CacheStorage`s on demand.
+1. Forwards calls to the appropriate `CacheStorage` for a given origin-owner
+ pair, loading `CacheStorage`s on demand.
2. Handles `QuotaManager` and `BrowsingData` calls.
### CacheStorage
-1. Manages the caches for a single origin.
+1. Manages the caches for a single origin-owner pair.
2. Handles creation/deletion of caches and updates the index on disk
accordingly.
3. Manages operations that span multiple caches (e.g., `CacheStorage::Match`).
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 71a6e088876..103f821e3f8 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
@@ -144,7 +144,8 @@ class CacheStorageBlobToDiskCacheTest : public testing::Test {
std::unique_ptr<disk_cache::Entry*> entry(new disk_cache::Entry*());
disk_cache::Entry** entry_ptr = entry.get();
- rv = cache_backend_->CreateEntry(kEntryKey, entry_ptr, base::DoNothing());
+ rv = cache_backend_->CreateEntry(kEntryKey, net::HIGHEST, entry_ptr,
+ base::DoNothing());
EXPECT_EQ(net::OK, rv);
disk_cache_entry_.reset(*entry);
}
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache.cc b/chromium/content/browser/cache_storage/cache_storage_cache.cc
index d5459e40398..f853ed819ad 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_cache.cc
@@ -74,24 +74,6 @@ const uint64_t kPaddingRange = 14431 * 1024;
// 2: Uniform random 14,431K.
const int32_t kCachePaddingAlgorithmVersion = 2;
-// This class ensures that the cache and the entry have a lifetime as long as
-// the blob that is created to contain them.
-class CacheStorageCacheDataHandle
- : public storage::BlobDataBuilder::DataHandle {
- public:
- CacheStorageCacheDataHandle(CacheStorageCacheHandle cache_handle,
- disk_cache::ScopedEntryPtr entry)
- : cache_handle_(std::move(cache_handle)), entry_(std::move(entry)) {}
-
- private:
- ~CacheStorageCacheDataHandle() override {}
-
- CacheStorageCacheHandle cache_handle_;
- disk_cache::ScopedEntryPtr entry_;
-
- DISALLOW_COPY_AND_ASSIGN(CacheStorageCacheDataHandle);
-};
-
using MetadataCallback =
base::OnceCallback<void(std::unique_ptr<proto::CacheMetadata>)>;
@@ -343,6 +325,35 @@ int64_t CalculateResponsePaddingInternal(
} // namespace
+// This class ensures that the cache and the entry have a lifetime as long as
+// the blob that is created to contain them.
+class CacheStorageCache::BlobDataHandle
+ : public storage::BlobDataBuilder::DataHandle {
+ public:
+ BlobDataHandle(CacheStorageCacheHandle cache_handle,
+ disk_cache::ScopedEntryPtr entry)
+ : cache_handle_(std::move(cache_handle)), entry_(std::move(entry)) {}
+
+ bool IsValid() override { return bool{entry_}; }
+
+ void Invalidate() {
+ cache_handle_ = base::nullopt;
+ entry_ = nullptr;
+ }
+
+ private:
+ ~BlobDataHandle() override {
+ if (cache_handle_ && cache_handle_->value()) {
+ cache_handle_->value()->blob_data_handles_.erase(this);
+ }
+ }
+
+ base::Optional<CacheStorageCacheHandle> cache_handle_;
+ disk_cache::ScopedEntryPtr entry_;
+
+ DISALLOW_COPY_AND_ASSIGN(BlobDataHandle);
+};
+
// The state needed to pass between CacheStorageCache::Put callbacks.
struct CacheStorageCache::PutContext {
PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request,
@@ -511,10 +522,9 @@ void CacheStorageCache::WriteSideData(ErrorCallback callback,
quota_manager_proxy_->GetUsageAndQuota(
base::ThreadTaskRunnerHandle::Get().get(), origin_,
blink::mojom::StorageType::kTemporary,
- base::AdaptCallbackForRepeating(
- base::BindOnce(&CacheStorageCache::WriteSideDataDidGetQuota,
- weak_ptr_factory_.GetWeakPtr(), std::move(callback),
- url, expected_response_time, buffer, buf_len)));
+ base::BindOnce(&CacheStorageCache::WriteSideDataDidGetQuota,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback), url,
+ expected_response_time, buffer, buf_len));
}
void CacheStorageCache::BatchOperation(
@@ -557,11 +567,10 @@ void CacheStorageCache::BatchOperation(
quota_manager_proxy_->GetUsageAndQuota(
base::ThreadTaskRunnerHandle::Get().get(), origin_,
blink::mojom::StorageType::kTemporary,
- base::AdaptCallbackForRepeating(base::BindOnce(
- &CacheStorageCache::BatchDidGetUsageAndQuota,
- weak_ptr_factory_.GetWeakPtr(), std::move(operations),
- std::move(callback), std::move(bad_message_callback),
- space_required, side_data_size)));
+ base::BindOnce(&CacheStorageCache::BatchDidGetUsageAndQuota,
+ weak_ptr_factory_.GetWeakPtr(), std::move(operations),
+ std::move(callback), std::move(bad_message_callback),
+ space_required, side_data_size));
return;
}
@@ -804,8 +813,8 @@ void CacheStorageCache::QueryCache(
base::AdaptCallbackForRepeating(base::BindOnce(
&CacheStorageCache::QueryCacheDidOpenFastPath,
weak_ptr_factory_.GetWeakPtr(), std::move(query_cache_context)));
- int rv = backend_->OpenEntry(request_ptr->url.spec(), entry_ptr,
- open_entry_callback);
+ int rv = backend_->OpenEntry(request_ptr->url.spec(), net::HIGHEST,
+ entry_ptr, open_entry_callback);
if (rv != net::ERR_IO_PENDING)
std::move(open_entry_callback).Run(rv);
return;
@@ -1117,7 +1126,11 @@ void CacheStorageCache::WriteSideDataImpl(ErrorCallback callback,
expected_response_time, buffer, buf_len,
std::move(scoped_entry_ptr)));
- int rv = backend_->OpenEntry(url.spec(), entry_ptr, open_entry_callback);
+
+ // Use LOWEST priority here as writing side data is less important than
+ // loading resources on the page.
+ int rv = backend_->OpenEntry(url.spec(), net::LOWEST, entry_ptr,
+ open_entry_callback);
if (rv != net::ERR_IO_PENDING)
std::move(open_entry_callback).Run(rv);
}
@@ -1301,8 +1314,8 @@ void CacheStorageCache::PutDidDeleteEntry(
&CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(),
std::move(scoped_entry_ptr), std::move(put_context)));
- int rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr,
- create_entry_callback);
+ int rv = backend_ptr->CreateEntry(request_ptr->url.spec(), net::HIGHEST,
+ entry_ptr, create_entry_callback);
if (rv != net::ERR_IO_PENDING)
std::move(create_entry_callback).Run(rv);
@@ -1676,6 +1689,8 @@ void CacheStorageCache::SizeImpl(SizeCallback callback) {
void CacheStorageCache::GetSizeThenCloseDidGetSize(SizeCallback callback,
int64_t cache_size) {
+ for (auto* handle : blob_data_handles_)
+ handle->Invalidate();
CloseImpl(base::BindOnce(std::move(callback), cache_size));
}
@@ -1832,9 +1847,11 @@ void CacheStorageCache::PopulateResponseBody(disk_cache::ScopedEntryPtr entry,
std::make_unique<storage::BlobDataBuilder>(response->blob_uuid);
disk_cache::Entry* temp_entry = entry.get();
+ auto data_handle = base::MakeRefCounted<BlobDataHandle>(CreateCacheHandle(),
+ std::move(entry));
+ blob_data_handles_.insert(data_handle.get());
blob_data->AppendDiskCacheEntryWithSideData(
- new CacheStorageCacheDataHandle(CreateCacheHandle(), std::move(entry)),
- temp_entry, INDEX_RESPONSE_BODY, INDEX_SIDE_DATA);
+ std::move(data_handle), temp_entry, INDEX_RESPONSE_BODY, INDEX_SIDE_DATA);
auto blob_handle =
blob_storage_context_->AddFinishedBlob(std::move(blob_data));
diff --git a/chromium/content/browser/cache_storage/cache_storage_cache.h b/chromium/content/browser/cache_storage/cache_storage_cache.h
index f343ccbf97d..f065161eedb 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache.h
+++ b/chromium/content/browser/cache_storage/cache_storage_cache.h
@@ -476,6 +476,13 @@ class CONTENT_EXPORT CacheStorageCache {
// Owns the elements of the list
BlobToDiskCacheIDMap active_blob_to_disk_cache_writers_;
+ // This class ensures that the cache and the entry have a lifetime as long as
+ // the blob that is created to contain them. We keep track of these instances
+ // to allow us to invalidate them if the cache has to be deleted while there
+ // are still references to data in it.
+ class BlobDataHandle;
+ std::set<BlobDataHandle*> blob_data_handles_;
+
// Whether or not to store data in disk or memory.
bool memory_only_;
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 92d66a32d43..d20905a639a 100644
--- a/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_cache_unittest.cc
@@ -82,41 +82,46 @@ class DelayableBackend : public disk_cache::Backend {
}
int32_t GetEntryCount() const override { return backend_->GetEntryCount(); }
int OpenEntry(const std::string& key,
+ net::RequestPriority request_priority,
disk_cache::Entry** entry,
- const CompletionCallback& callback) override {
+ CompletionOnceCallback callback) override {
if (delay_open_entry_ && open_entry_callback_.is_null()) {
open_entry_callback_ = base::BindOnce(
&DelayableBackend::OpenEntryDelayedImpl, base::Unretained(this), key,
- base::Unretained(entry), callback);
+ base::Unretained(entry), std::move(callback));
return net::ERR_IO_PENDING;
}
- return backend_->OpenEntry(key, entry, callback);
+ return backend_->OpenEntry(key, request_priority, entry,
+ std::move(callback));
}
int CreateEntry(const std::string& key,
+ net::RequestPriority request_priority,
disk_cache::Entry** entry,
- const CompletionCallback& callback) override {
- return backend_->CreateEntry(key, entry, callback);
+ CompletionOnceCallback callback) override {
+ return backend_->CreateEntry(key, request_priority, entry,
+ std::move(callback));
}
int DoomEntry(const std::string& key,
- const CompletionCallback& callback) override {
- return backend_->DoomEntry(key, callback);
+ net::RequestPriority request_priority,
+ CompletionOnceCallback callback) override {
+ return backend_->DoomEntry(key, request_priority, std::move(callback));
}
- int DoomAllEntries(const CompletionCallback& callback) override {
- return backend_->DoomAllEntries(callback);
+ int DoomAllEntries(CompletionOnceCallback callback) override {
+ return backend_->DoomAllEntries(std::move(callback));
}
int DoomEntriesBetween(base::Time initial_time,
base::Time end_time,
- const CompletionCallback& callback) override {
- return backend_->DoomEntriesBetween(initial_time, end_time, callback);
+ CompletionOnceCallback callback) override {
+ return backend_->DoomEntriesBetween(initial_time, end_time,
+ std::move(callback));
}
int DoomEntriesSince(base::Time initial_time,
- const CompletionCallback& callback) override {
- return backend_->DoomEntriesSince(initial_time, callback);
+ CompletionOnceCallback callback) override {
+ return backend_->DoomEntriesSince(initial_time, std::move(callback));
}
- int CalculateSizeOfAllEntries(
- const CompletionCallback& callback) override {
- return backend_->CalculateSizeOfAllEntries(callback);
+ int CalculateSizeOfAllEntries(CompletionOnceCallback callback) override {
+ return backend_->CalculateSizeOfAllEntries(std::move(callback));
}
std::unique_ptr<Iterator> CreateIterator() override {
return backend_->CreateIterator();
@@ -148,10 +153,12 @@ class DelayableBackend : public disk_cache::Backend {
private:
void OpenEntryDelayedImpl(const std::string& key,
disk_cache::Entry** entry,
- const CompletionCallback& callback) {
- int rv = backend_->OpenEntry(key, entry, callback);
+ CompletionOnceCallback callback) {
+ auto copyable_callback =
+ base::AdaptCallbackForRepeating(std::move(callback));
+ int rv = backend_->OpenEntry(key, net::HIGHEST, entry, copyable_callback);
if (rv != net::ERR_IO_PENDING)
- callback.Run(rv);
+ copyable_callback.Run(rv);
}
std::unique_ptr<disk_cache::Backend> backend_;
@@ -746,6 +753,7 @@ class CacheStorageCacheTest : public testing::Test {
class CacheStorageCacheTestP : public CacheStorageCacheTest,
public testing::WithParamInterface<bool> {
+ public:
bool MemoryOnly() override { return !GetParam(); }
};
@@ -1824,10 +1832,19 @@ TEST_F(CacheStorageCacheTest, TestDoubleOpaquePut) {
}
TEST_P(CacheStorageCacheTestP, GetSizeThenClose) {
+ // Create the backend and put something in it.
EXPECT_TRUE(Put(body_request_, body_response_));
+ // Get a reference to the response in the cache.
+ EXPECT_TRUE(Match(body_request_));
+ blink::mojom::BlobPtr blob = callback_response_->blob->TakeBlobPtr();
+ callback_response_ = nullptr;
+
int64_t cache_size = Size();
EXPECT_EQ(cache_size, GetSizeThenClose());
VerifyAllOpsFail();
+
+ // Reading blob should fail.
+ EXPECT_TRUE(ResponseBodiesEqual("", blob.get()));
}
TEST_P(CacheStorageCacheTestP, OpsFailOnClosedBackend) {
@@ -1837,6 +1854,30 @@ TEST_P(CacheStorageCacheTestP, OpsFailOnClosedBackend) {
VerifyAllOpsFail();
}
+TEST_P(CacheStorageCacheTestP, BlobReferenceDelaysClose) {
+ // Create the backend and put something in it.
+ EXPECT_TRUE(Put(body_request_, body_response_));
+ // Get a reference to the response in the cache.
+ EXPECT_TRUE(Match(body_request_));
+ blink::mojom::BlobPtr blob = callback_response_->blob->TakeBlobPtr();
+ callback_response_ = nullptr;
+
+ base::RunLoop loop;
+ cache_->Close(base::BindOnce(&CacheStorageCacheTest::CloseCallback,
+ base::Unretained(this),
+ base::Unretained(&loop)));
+ browser_thread_bundle_.RunUntilIdle();
+ // If MemoryOnly closing does succeed right away.
+ EXPECT_EQ(MemoryOnly(), callback_closed_);
+
+ // Reading blob should succeed.
+ EXPECT_TRUE(ResponseBodiesEqual(expected_blob_data_, blob.get()));
+ blob.reset();
+
+ loop.Run();
+ EXPECT_TRUE(callback_closed_);
+}
+
TEST_P(CacheStorageCacheTestP, VerifySerialScheduling) {
// Start two operations, the first one is delayed but the second isn't. The
// second should wait for the first.
diff --git a/chromium/content/browser/cache_storage/cache_storage_context_impl.cc b/chromium/content/browser/cache_storage/cache_storage_context_impl.cc
index 17157f81340..87c836e3f98 100644
--- a/chromium/content/browser/cache_storage/cache_storage_context_impl.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_context_impl.cc
@@ -129,7 +129,12 @@ void CacheStorageContextImpl::CreateCacheStorageManager(
void CacheStorageContextImpl::ShutdownOnIO() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- cache_manager_.reset();
+ // Release |cache_manager_|. New clients will get a nullptr if they request
+ // an instance of CacheStorageManager after this. Any other client that
+ // ref-wrapped |cache_manager_| will be able to continue using it, and the
+ // CacheStorageManager will be destroyed when all the references are
+ // destroyed.
+ cache_manager_ = nullptr;
}
} // namespace content
diff --git a/chromium/content/browser/cache_storage/cache_storage_context_impl.h b/chromium/content/browser/cache_storage/cache_storage_context_impl.h
index 47c28f06ce8..cedfd960e13 100644
--- a/chromium/content/browser/cache_storage/cache_storage_context_impl.h
+++ b/chromium/content/browser/cache_storage/cache_storage_context_impl.h
@@ -9,6 +9,7 @@
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "content/common/content_export.h"
#include "content/public/browser/cache_storage_context.h"
#include "content/public/browser/cache_storage_usage_info.h"
@@ -98,7 +99,7 @@ class CONTENT_EXPORT CacheStorageContextImpl : public CacheStorageContext {
bool is_incognito_ = false;
// Only accessed on the IO thread.
- std::unique_ptr<CacheStorageManager> cache_manager_;
+ scoped_refptr<CacheStorageManager> cache_manager_;
};
} // namespace content
diff --git a/chromium/content/browser/cache_storage/cache_storage_manager.cc b/chromium/content/browser/cache_storage/cache_storage_manager.cc
index eb0fbd228dd..be479cf1d69 100644
--- a/chromium/content/browser/cache_storage/cache_storage_manager.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_manager.cc
@@ -28,7 +28,6 @@
#include "content/browser/cache_storage/cache_storage.pb.h"
#include "content/browser/cache_storage/cache_storage_quota_client.h"
#include "content/browser/service_worker/service_worker_context_core.h"
-#include "content/public/browser/browser_thread.h"
#include "net/base/url_util.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/common/database/database_identifier.h"
@@ -153,7 +152,7 @@ void OneOriginSizeReported(base::OnceClosure callback,
} // namespace
// static
-std::unique_ptr<CacheStorageManager> CacheStorageManager::Create(
+scoped_refptr<CacheStorageManager> CacheStorageManager::Create(
const base::FilePath& path,
scoped_refptr<base::SequencedTaskRunner> cache_task_runner,
scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy) {
@@ -163,14 +162,14 @@ std::unique_ptr<CacheStorageManager> CacheStorageManager::Create(
.AppendASCII("CacheStorage");
}
- return base::WrapUnique(new CacheStorageManager(
+ return base::WrapRefCounted(new CacheStorageManager(
root_path, std::move(cache_task_runner), std::move(quota_manager_proxy)));
}
// static
-std::unique_ptr<CacheStorageManager> CacheStorageManager::Create(
+scoped_refptr<CacheStorageManager> CacheStorageManager::Create(
CacheStorageManager* old_manager) {
- std::unique_ptr<CacheStorageManager> manager(new CacheStorageManager(
+ scoped_refptr<CacheStorageManager> manager(new CacheStorageManager(
old_manager->root_path(), old_manager->cache_task_runner(),
old_manager->quota_manager_proxy_.get()));
// These values may be NULL, in which case this will be called again later by
diff --git a/chromium/content/browser/cache_storage/cache_storage_manager.h b/chromium/content/browser/cache_storage/cache_storage_manager.h
index e94dfa631b4..e7460ce34f8 100644
--- a/chromium/content/browser/cache_storage/cache_storage_manager.h
+++ b/chromium/content/browser/cache_storage/cache_storage_manager.h
@@ -13,9 +13,11 @@
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
#include "content/browser/cache_storage/cache_storage.h"
#include "content/browser/cache_storage/cache_storage_context_impl.h"
#include "content/common/content_export.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/cache_storage_context.h"
#include "content/public/browser/cache_storage_usage_info.h"
#include "net/url_request/url_request_context_getter.h"
@@ -55,14 +57,16 @@ enum class CacheStorageOwner {
// CacheStorageManager per ServiceWorkerContextCore.
// TODO(jkarlin): Remove CacheStorage from memory once they're no
// longer in active use.
-class CONTENT_EXPORT CacheStorageManager {
+class CONTENT_EXPORT CacheStorageManager
+ : public base::RefCountedThreadSafe<CacheStorageManager,
+ BrowserThread::DeleteOnIOThread> {
public:
- static std::unique_ptr<CacheStorageManager> Create(
+ static scoped_refptr<CacheStorageManager> Create(
const base::FilePath& path,
scoped_refptr<base::SequencedTaskRunner> cache_task_runner,
scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy);
- static std::unique_ptr<CacheStorageManager> Create(
+ static scoped_refptr<CacheStorageManager> Create(
CacheStorageManager* old_manager);
// Map a database identifier (computed from an origin) to the path.
@@ -70,8 +74,6 @@ class CONTENT_EXPORT CacheStorageManager {
const url::Origin& origin,
CacheStorageOwner owner);
- virtual ~CacheStorageManager();
-
// Methods to support the CacheStorage spec. These methods call the
// corresponding CacheStorage method on the appropriate thread.
void OpenCache(const url::Origin& origin,
@@ -131,9 +133,12 @@ class CONTENT_EXPORT CacheStorageManager {
base::FilePath root_path() const { return root_path_; }
private:
- friend class CacheStorageContextImpl;
+ friend class base::DeleteHelper<CacheStorageManager>;
+ friend class base::RefCountedThreadSafe<CacheStorageManager>;
friend class cache_storage_manager_unittest::CacheStorageManagerTest;
+ friend class CacheStorageContextImpl;
friend class CacheStorageQuotaClient;
+ friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
typedef std::map<std::pair<url::Origin, CacheStorageOwner>,
std::unique_ptr<CacheStorage>>
@@ -144,6 +149,8 @@ class CONTENT_EXPORT CacheStorageManager {
scoped_refptr<base::SequencedTaskRunner> cache_task_runner,
scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy);
+ virtual ~CacheStorageManager();
+
// The returned CacheStorage* is owned by this manager.
CacheStorage* FindOrCreateCacheStorage(const url::Origin& origin,
CacheStorageOwner owner);
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 e779d23257c..d62569b7672 100644
--- a/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_manager_unittest.cc
@@ -636,7 +636,7 @@ class CacheStorageManagerTest : public testing::Test {
scoped_refptr<MockSpecialStoragePolicy> quota_policy_;
scoped_refptr<MockQuotaManager> mock_quota_manager_;
scoped_refptr<MockCacheStorageQuotaManagerProxy> quota_manager_proxy_;
- std::unique_ptr<CacheStorageManager> cache_manager_;
+ scoped_refptr<CacheStorageManager> cache_manager_;
CacheStorageCacheHandle callback_cache_handle_;
int callback_bool_;
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 b1bd4a25961..5f9597f21cc 100644
--- a/chromium/content/browser/cache_storage/cache_storage_operation_unittest.cc
+++ b/chromium/content/browser/cache_storage/cache_storage_operation_unittest.cc
@@ -8,7 +8,7 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/test_mock_time_task_runner.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/content/browser/child_process_launcher.cc b/chromium/content/browser/child_process_launcher.cc
index b1869a2723c..f071c1d5c05 100644
--- a/chromium/content/browser/child_process_launcher.cc
+++ b/chromium/content/browser/child_process_launcher.cc
@@ -26,9 +26,8 @@ ChildProcessLauncher::ChildProcessLauncher(
std::unique_ptr<base::CommandLine> command_line,
int child_process_id,
Client* client,
- std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation>
- broker_client_invitation,
- const mojo::edk::ProcessErrorCallback& process_error_callback,
+ mojo::OutgoingInvitation mojo_invitation,
+ const mojo::ProcessErrorCallback& process_error_callback,
bool terminate_on_shutdown)
: client_(client),
starting_(true),
@@ -47,7 +46,7 @@ ChildProcessLauncher::ChildProcessLauncher(
helper_ = new ChildProcessLauncherHelper(
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);
+ std::move(mojo_invitation), process_error_callback);
helper_->StartLaunchOnClientThread();
}
@@ -169,7 +168,13 @@ ChildProcessLauncher::Client* ChildProcessLauncher::ReplaceClientForTest(
bool ChildProcessLauncherPriority::operator==(
const ChildProcessLauncherPriority& other) const {
- return background == other.background && frame_depth == other.frame_depth &&
+ // |should_boost_for_pending_views| is temporary and constant for all
+ // ChildProcessLauncherPriority throughout a session (experiment driven).
+ DCHECK_EQ(should_boost_for_pending_views,
+ other.should_boost_for_pending_views);
+ return visible == other.visible &&
+ has_media_stream == other.has_media_stream &&
+ frame_depth == other.frame_depth &&
boost_for_pending_views == other.boost_for_pending_views
#if defined(OS_ANDROID)
&& importance == other.importance
diff --git a/chromium/content/browser/child_process_launcher.h b/chromium/content/browser/child_process_launcher.h
index 04787554d23..190ee370186 100644
--- a/chromium/content/browser/child_process_launcher.h
+++ b/chromium/content/browser/child_process_launcher.h
@@ -22,8 +22,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_termination_info.h"
#include "content/public/common/result_codes.h"
-#include "mojo/edk/embedder/outgoing_broker_client_invitation.h"
-#include "mojo/edk/embedder/scoped_platform_handle.h"
+#include "mojo/public/cpp/system/invitation.h"
#if defined(OS_ANDROID)
#include "content/public/browser/android/child_process_importance.h"
@@ -57,17 +56,75 @@ static_assert(static_cast<int>(LAUNCH_RESULT_START) >
#endif
struct ChildProcessLauncherPriority {
- bool background;
- unsigned int frame_depth;
- bool boost_for_pending_views;
+ ChildProcessLauncherPriority(bool visible,
+ bool has_media_stream,
+ unsigned int frame_depth,
+ bool boost_for_pending_views,
+ bool should_boost_for_pending_views
#if defined(OS_ANDROID)
- ChildProcessImportance importance;
+ ,
+ ChildProcessImportance importance
+#endif
+ )
+ : visible(visible),
+ has_media_stream(has_media_stream),
+ frame_depth(frame_depth),
+ boost_for_pending_views(boost_for_pending_views),
+ should_boost_for_pending_views(should_boost_for_pending_views)
+#if defined(OS_ANDROID)
+ ,
+ importance(importance)
#endif
+ {
+ }
+
+ // Returns true if the child process is backgrounded.
+ bool is_background() const {
+ return !visible && !has_media_stream &&
+ !(should_boost_for_pending_views && boost_for_pending_views);
+ }
bool operator==(const ChildProcessLauncherPriority& other) const;
bool operator!=(const ChildProcessLauncherPriority& other) const {
return !(*this == other);
}
+
+ // Prefer |is_background()| to inspecting these fields individually (to ensure
+ // all logic uses the same notion of "backgrounded").
+
+ // |visible| is true if the process is responsible for one or more widget(s)
+ // in foreground tabs. The notion of "visible" is determined by the embedder
+ // but is ideally a widget in a non-minimized, non-background, non-occluded
+ // tab (i.e. with pixels visible on the screen).
+ bool visible;
+
+ // |has_media_stream| is true when the process is responsible for "hearable"
+ // content.
+ bool has_media_stream;
+
+ // |frame_depth| is the depth of the shallowest frame this process is
+ // responsible for which has |visible| visibility. It only makes sense to
+ // compare this property for two ChildProcessLauncherPriority instances with
+ // matching |visible| properties.
+ unsigned int frame_depth;
+
+ // |boost_for_pending_views| is true if this process is responsible for a
+ // pending view (this is used to boost priority of a process responsible for
+ // foreground content which hasn't yet been added as a visible widget -- i.e.
+ // during navigation).
+ bool boost_for_pending_views;
+
+ // True iff |boost_for_pending_views| should be considered in
+ // |is_background()|. This needs to be a separate parameter as opposed to
+ // having the experiment set |boost_for_pending_views == false| when
+ // |!should_boost_for_pending_views| as that would result in different
+ // |is_background()| logic than before and defeat the purpose of the
+ // experiment. TODO(gab): Remove this field when the
+ // BoostRendererPriorityForPendingViews desktop experiment is over.
+ bool should_boost_for_pending_views;
+#if defined(OS_ANDROID)
+ ChildProcessImportance importance;
+#endif
};
// Launches a process asynchronously and notifies the client of the process
@@ -101,9 +158,8 @@ class CONTENT_EXPORT ChildProcessLauncher {
std::unique_ptr<base::CommandLine> cmd_line,
int child_process_id,
Client* client,
- std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation>
- broker_client_invitation,
- const mojo::edk::ProcessErrorCallback& process_error_callback,
+ mojo::OutgoingInvitation mojo_invitation,
+ const mojo::ProcessErrorCallback& process_error_callback,
bool terminate_on_shutdown = true);
~ChildProcessLauncher();
diff --git a/chromium/content/browser/child_process_launcher_helper.cc b/chromium/content/browser/child_process_launcher_helper.cc
index b9ad8d7ed5e..d4272efe0e4 100644
--- a/chromium/content/browser/child_process_launcher_helper.cc
+++ b/chromium/content/browser/child_process_launcher_helper.cc
@@ -16,7 +16,7 @@
#include "content/public/browser/child_process_launcher_utils.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
-#include "mojo/edk/embedder/platform_channel_pair.h"
+#include "mojo/public/cpp/platform/platform_channel.h"
#if defined(OS_ANDROID)
#include "content/browser/android/launcher_thread.h"
@@ -69,32 +69,27 @@ ChildProcessLauncherHelper::ChildProcessLauncherHelper(
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
const base::WeakPtr<ChildProcessLauncher>& child_process_launcher,
bool terminate_on_shutdown,
- std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation>
- broker_client_invitation,
- const mojo::edk::ProcessErrorCallback& process_error_callback)
+ mojo::OutgoingInvitation mojo_invitation,
+ const mojo::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),
- broker_client_invitation_(std::move(broker_client_invitation)),
+ mojo_invitation_(std::move(mojo_invitation)),
process_error_callback_(process_error_callback) {}
-ChildProcessLauncherHelper::~ChildProcessLauncherHelper() {
-}
+ChildProcessLauncherHelper::~ChildProcessLauncherHelper() = default;
void ChildProcessLauncherHelper::StartLaunchOnClientThread() {
DCHECK_CURRENTLY_ON(client_thread_id_);
BeforeLaunchOnClientThread();
- mojo_server_handle_ = PrepareMojoPipeHandlesOnClientThread();
- if (!mojo_server_handle_.is_valid()) {
- mojo::edk::PlatformChannelPair channel_pair;
- mojo_server_handle_ = channel_pair.PassServerHandle();
- mojo_client_handle_ = channel_pair.PassClientHandle();
- }
+ mojo_named_channel_ = CreateNamedPlatformChannelOnClientThread();
+ if (!mojo_named_channel_)
+ mojo_channel_.emplace();
GetProcessLauncherTaskRunner()->PostTask(
FROM_HERE,
@@ -130,10 +125,8 @@ void ChildProcessLauncherHelper::LaunchOnLauncherThread() {
void ChildProcessLauncherHelper::PostLaunchOnLauncherThread(
ChildProcessLauncherHelper::Process process,
int launch_result) {
- // Release the client handle now that the process has been started (the pipe
- // may not signal when the process dies otherwise and we would not detect the
- // child process died).
- mojo_client_handle_.reset();
+ if (mojo_channel_)
+ mojo_channel_->RemoteProcessLaunchAttempted();
if (process.process.IsValid()) {
RecordHistogramsOnLauncherThread(base::TimeTicks::Now() -
@@ -142,16 +135,20 @@ void ChildProcessLauncherHelper::PostLaunchOnLauncherThread(
// 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_);
+ mojo::OutgoingInvitation invitation = std::move(mojo_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_);
+ if (mojo_channel_) {
+ DCHECK(mojo_channel_->local_endpoint().is_valid());
+ mojo::OutgoingInvitation::Send(
+ std::move(invitation), process.process.Handle(),
+ mojo_channel_->TakeLocalEndpoint(), process_error_callback_);
+ } else {
+ DCHECK(mojo_named_channel_);
+ mojo::OutgoingInvitation::Send(
+ std::move(invitation), process.process.Handle(),
+ mojo_named_channel_->TakeServerEndpoint(), process_error_callback_);
+ }
}
BrowserThread::PostTask(
diff --git a/chromium/content/browser/child_process_launcher_helper.h b/chromium/content/browser/child_process_launcher_helper.h
index 51d54bb4ab6..da64a5c3df0 100644
--- a/chromium/content/browser/child_process_launcher_helper.h
+++ b/chromium/content/browser/child_process_launcher_helper.h
@@ -9,14 +9,15 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/optional.h"
#include "base/process/kill.h"
#include "base/process/process.h"
#include "build/build_config.h"
#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 "mojo/public/cpp/platform/named_platform_channel.h"
+#include "mojo/public/cpp/platform/platform_channel.h"
+#include "mojo/public/cpp/system/invitation.h"
#include "services/catalog/public/cpp/manifest_parsing_util.h"
#include "services/service_manager/zygote/common/zygote_buildflags.h"
@@ -34,6 +35,10 @@
#include "sandbox/mac/seatbelt_exec.h"
#endif
+#if defined(OS_FUCHSIA)
+#include "content/common/sandbox_policy_fuchsia.h"
+#endif
+
#if BUILDFLAG(USE_ZYGOTE_HANDLE)
#include "services/service_manager/zygote/common/zygote_handle.h" // nogncheck
#endif
@@ -90,9 +95,8 @@ class ChildProcessLauncherHelper :
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
const base::WeakPtr<ChildProcessLauncher>& child_process_launcher,
bool terminate_on_shutdown,
- std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation>
- broker_client_invitation,
- const mojo::edk::ProcessErrorCallback& process_error_callback);
+ mojo::OutgoingInvitation mojo_invitation,
+ const mojo::ProcessErrorCallback& process_error_callback);
// The methods below are defined in the order they are called.
@@ -102,10 +106,11 @@ class ChildProcessLauncherHelper :
// Platform specific.
void BeforeLaunchOnClientThread();
- // Called in to give implementors a chance at creating a server pipe.
- // Platform specific.
- mojo::edk::ScopedInternalPlatformHandle
- PrepareMojoPipeHandlesOnClientThread();
+ // Called to give implementors a chance at creating a server pipe. Platform-
+ // specific. Returns |base::nullopt| if the helper should initialize
+ // a regular PlatformChannel for communication instead.
+ base::Optional<mojo::NamedPlatformChannel>
+ CreateNamedPlatformChannelOnClientThread();
// Returns the list of files that should be mapped in the child process.
// Platform specific.
@@ -189,9 +194,6 @@ class ChildProcessLauncherHelper :
void LaunchOnLauncherThread();
- const mojo::edk::InternalPlatformHandle& mojo_client_handle() const {
- return mojo_client_handle_.get();
- }
base::CommandLine* command_line() { return command_line_.get(); }
int child_process_id() const { return child_process_id_; }
@@ -212,12 +214,21 @@ class ChildProcessLauncherHelper :
std::unique_ptr<base::CommandLine> command_line_;
std::unique_ptr<SandboxedProcessLauncherDelegate> delegate_;
base::WeakPtr<ChildProcessLauncher> child_process_launcher_;
- mojo::edk::ScopedInternalPlatformHandle mojo_client_handle_;
- mojo::edk::ScopedInternalPlatformHandle mojo_server_handle_;
+
+ // The PlatformChannel that will be used to transmit an invitation to the
+ // child process in most cases. Only used if the platform's helper
+ // implementation doesn't return a server endpoint from
+ // |CreateNamedPlatformChannelOnClientThread()|.
+ base::Optional<mojo::PlatformChannel> mojo_channel_;
+
+ // May be used in exclusion to the above if the platform helper implementation
+ // returns a valid server endpoint from
+ // |CreateNamedPlatformChannelOnClientThread()|.
+ base::Optional<mojo::NamedPlatformChannel> mojo_named_channel_;
+
bool terminate_on_shutdown_;
- std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation>
- broker_client_invitation_;
- const mojo::edk::ProcessErrorCallback process_error_callback_;
+ mojo::OutgoingInvitation mojo_invitation_;
+ const mojo::ProcessErrorCallback process_error_callback_;
#if defined(OS_MACOSX)
std::unique_ptr<sandbox::SeatbeltExecClient> seatbelt_exec_client_;
@@ -227,6 +238,10 @@ class ChildProcessLauncherHelper :
base::android::ScopedJavaGlobalRef<jobject> java_peer_;
bool java_peer_avaiable_on_client_thread_ = false;
#endif
+
+#if defined(OS_FUCHSIA)
+ SandboxPolicyFuchsia sandbox_policy_;
+#endif
};
} // namespace internal
diff --git a/chromium/content/browser/child_process_launcher_helper_android.cc b/chromium/content/browser/child_process_launcher_helper_android.cc
index 07c1a74cec2..2115d7f830c 100644
--- a/chromium/content/browser/child_process_launcher_helper_android.cc
+++ b/chromium/content/browser/child_process_launcher_helper_android.cc
@@ -5,6 +5,7 @@
#include <memory>
#include "base/android/apk_assets.h"
+#include "base/android/application_status_listener.h"
#include "base/android/jni_array.h"
#include "base/i18n/icu_util.h"
#include "base/logging.h"
@@ -19,7 +20,7 @@
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_descriptors.h"
#include "content/public/common/content_switches.h"
-#include "jni/ChildProcessLauncherHelper_jni.h"
+#include "jni/ChildProcessLauncherHelperImpl_jni.h"
#include "services/service_manager/sandbox/switches.h"
using base::android::AttachCurrentThread;
@@ -37,7 +38,7 @@ void StopChildProcess(base::ProcessHandle handle) {
DCHECK(CurrentlyOnProcessLauncherTaskRunner());
JNIEnv* env = AttachCurrentThread();
DCHECK(env);
- Java_ChildProcessLauncherHelper_stop(env, static_cast<jint>(handle));
+ Java_ChildProcessLauncherHelperImpl_stop(env, static_cast<jint>(handle));
}
} // namespace
@@ -48,9 +49,6 @@ void ChildProcessLauncherHelper::BeforeLaunchOnClientThread() {
command_line()->GetSwitchValueASCII(switches::kProcessType);
CHECK(process_type == switches::kGpuProcess ||
process_type == switches::kRendererProcess ||
-#if BUILDFLAG(ENABLE_PLUGINS)
- process_type == switches::kPpapiPluginProcess ||
-#endif
process_type == switches::kUtilityProcess)
<< "Unsupported process type: " << process_type;
@@ -59,9 +57,9 @@ void ChildProcessLauncherHelper::BeforeLaunchOnClientThread() {
!command_line()->HasSwitch(service_manager::switches::kNoSandbox));
}
-mojo::edk::ScopedInternalPlatformHandle
-ChildProcessLauncherHelper::PrepareMojoPipeHandlesOnClientThread() {
- return mojo::edk::ScopedInternalPlatformHandle();
+base::Optional<mojo::NamedPlatformChannel>
+ChildProcessLauncherHelper::CreateNamedPlatformChannelOnClientThread() {
+ return base::nullopt;
}
std::unique_ptr<PosixFileDescriptorInfo>
@@ -73,7 +71,8 @@ ChildProcessLauncherHelper::GetFilesToMap() {
CHECK(!command_line()->HasSwitch(switches::kSingleProcess));
std::unique_ptr<PosixFileDescriptorInfo> files_to_register =
- CreateDefaultPosixFilesToMap(child_process_id(), mojo_client_handle(),
+ CreateDefaultPosixFilesToMap(child_process_id(),
+ mojo_channel_->remote_endpoint(),
true /* include_service_required_files */,
GetProcessType(), command_line());
@@ -123,8 +122,8 @@ ChildProcessLauncherHelper::LaunchProcessOnLauncherThread(
const auto& region = files_to_register->GetRegionAt(i);
bool auto_close = files_to_register->OwnsFD(fd);
ScopedJavaLocalRef<jobject> j_file_info =
- Java_ChildProcessLauncherHelper_makeFdInfo(env, id, fd, auto_close,
- region.offset, region.size);
+ Java_ChildProcessLauncherHelperImpl_makeFdInfo(
+ env, id, fd, auto_close, region.offset, region.size);
PCHECK(j_file_info.obj());
env->SetObjectArrayElement(j_file_infos.obj(), i, j_file_info.obj());
if (auto_close) {
@@ -132,7 +131,7 @@ ChildProcessLauncherHelper::LaunchProcessOnLauncherThread(
}
}
- java_peer_.Reset(Java_ChildProcessLauncherHelper_createAndStart(
+ java_peer_.Reset(Java_ChildProcessLauncherHelperImpl_createAndStart(
env, reinterpret_cast<intptr_t>(this), j_argv, j_file_infos));
AddRef(); // Balanced by OnChildProcessStarted.
BrowserThread::PostTask(
@@ -153,19 +152,21 @@ ChildProcessTerminationInfo ChildProcessLauncherHelper::GetTerminationInfo(
const ChildProcessLauncherHelper::Process& process,
bool known_dead) {
ChildProcessTerminationInfo info;
- info.has_oom_protection_bindings =
- java_peer_avaiable_on_client_thread_ &&
- Java_ChildProcessLauncherHelper_hasOomProtectionBindings(
- AttachCurrentThread(), java_peer_);
- info.was_killed_intentionally_by_browser =
- java_peer_avaiable_on_client_thread_ &&
- Java_ChildProcessLauncherHelper_isKilledByUs(AttachCurrentThread(),
- java_peer_);
+ if (!java_peer_avaiable_on_client_thread_)
+ return info;
+
+ Java_ChildProcessLauncherHelperImpl_getTerminationInfo(
+ AttachCurrentThread(), java_peer_, reinterpret_cast<intptr_t>(&info));
+
+ base::android::ApplicationState app_state =
+ base::android::ApplicationStatusListener::GetState();
bool app_foreground =
- java_peer_avaiable_on_client_thread_ &&
- Java_ChildProcessLauncherHelper_isApplicationInForeground(
- AttachCurrentThread(), java_peer_);
- if (app_foreground && info.has_oom_protection_bindings) {
+ app_state == base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES ||
+ app_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
+
+ if (app_foreground &&
+ (info.binding_state == base::android::ChildBindingState::MODERATE ||
+ info.binding_state == base::android::ChildBindingState::STRONG)) {
info.status = base::TERMINATION_STATUS_OOM_PROTECTED;
} else {
// Note waitpid does not work on Android since these are not actually child
@@ -175,6 +176,28 @@ ChildProcessTerminationInfo ChildProcessLauncherHelper::GetTerminationInfo(
return info;
}
+static void JNI_ChildProcessLauncherHelperImpl_SetTerminationInfo(
+ JNIEnv* env,
+ const JavaParamRef<jclass>&,
+ jlong termination_info_ptr,
+ jint binding_state,
+ jboolean killed_by_us,
+ jint remaining_process_with_strong_binding,
+ jint remaining_process_with_moderate_binding,
+ jint remaining_process_with_waived_binding) {
+ ChildProcessTerminationInfo* info =
+ reinterpret_cast<ChildProcessTerminationInfo*>(termination_info_ptr);
+ info->binding_state =
+ static_cast<base::android::ChildBindingState>(binding_state);
+ info->was_killed_intentionally_by_browser = killed_by_us;
+ info->remaining_process_with_strong_binding =
+ remaining_process_with_strong_binding;
+ info->remaining_process_with_moderate_binding =
+ remaining_process_with_moderate_binding;
+ info->remaining_process_with_waived_binding =
+ remaining_process_with_waived_binding;
+}
+
// static
bool ChildProcessLauncherHelper::TerminateProcess(const base::Process& process,
int exit_code) {
@@ -197,10 +220,10 @@ void ChildProcessLauncherHelper::SetProcessPriorityOnLauncherThread(
const ChildProcessLauncherPriority& priority) {
JNIEnv* env = AttachCurrentThread();
DCHECK(env);
- return Java_ChildProcessLauncherHelper_setPriority(
- env, java_peer_, process.Handle(), !priority.background,
- priority.frame_depth, priority.boost_for_pending_views,
- static_cast<jint>(priority.importance));
+ return Java_ChildProcessLauncherHelperImpl_setPriority(
+ env, java_peer_, process.Handle(), priority.visible,
+ priority.has_media_stream, priority.frame_depth,
+ priority.boost_for_pending_views, static_cast<jint>(priority.importance));
}
// static
diff --git a/chromium/content/browser/child_process_launcher_helper_fuchsia.cc b/chromium/content/browser/child_process_launcher_helper_fuchsia.cc
index cd3095ce794..c834ebd29b4 100644
--- a/chromium/content/browser/child_process_launcher_helper_fuchsia.cc
+++ b/chromium/content/browser/child_process_launcher_helper_fuchsia.cc
@@ -10,7 +10,6 @@
#include "content/common/sandbox_policy_fuchsia.h"
#include "content/public/browser/child_process_launcher_utils.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
-#include "mojo/edk/embedder/platform_channel_pair.h"
#include "services/service_manager/embedder/result_codes.h"
namespace content {
@@ -55,15 +54,14 @@ void ChildProcessLauncherHelper::ResetRegisteredFilesForTesting() {
void ChildProcessLauncherHelper::BeforeLaunchOnClientThread() {
DCHECK_CURRENTLY_ON(client_thread_id_);
+
+ sandbox_policy_.Initialize(delegate_->GetSandboxType());
}
-mojo::edk::ScopedInternalPlatformHandle
-ChildProcessLauncherHelper::PrepareMojoPipeHandlesOnClientThread() {
+base::Optional<mojo::NamedPlatformChannel>
+ChildProcessLauncherHelper::CreateNamedPlatformChannelOnClientThread() {
DCHECK_CURRENTLY_ON(client_thread_id_);
-
- // By doing nothing here, StartLaunchOnClientThread() will construct a channel
- // pair instead.
- return mojo::edk::ScopedInternalPlatformHandle();
+ return base::nullopt;
}
std::unique_ptr<FileMappedForLaunch>
@@ -77,10 +75,9 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
base::LaunchOptions* options) {
DCHECK(CurrentlyOnProcessLauncherTaskRunner());
- mojo::edk::PlatformChannelPair::PrepareToPassHandleToChildProcess(
- mojo_client_handle(), command_line(), &options->handles_to_transfer);
-
- UpdateLaunchOptionsForSandbox(delegate_->GetSandboxType(), options);
+ mojo_channel_->PrepareToPassRemoteEndpoint(&options->handles_to_transfer,
+ command_line());
+ sandbox_policy_.UpdateLaunchOptionsForSandbox(options);
return true;
}
@@ -92,7 +89,8 @@ ChildProcessLauncherHelper::LaunchProcessOnLauncherThread(
bool* is_synchronous_launch,
int* launch_result) {
DCHECK(CurrentlyOnProcessLauncherTaskRunner());
- DCHECK(mojo_client_handle().is_valid());
+ DCHECK(mojo_channel_);
+ DCHECK(mojo_channel_->remote_endpoint().is_valid());
// TODO(750938): Implement sandboxed/isolated subprocess launching.
Process child_process;
@@ -103,14 +101,6 @@ ChildProcessLauncherHelper::LaunchProcessOnLauncherThread(
void ChildProcessLauncherHelper::AfterLaunchOnLauncherThread(
const ChildProcessLauncherHelper::Process& process,
const base::LaunchOptions& options) {
- DCHECK(CurrentlyOnProcessLauncherTaskRunner());
-
- if (process.process.IsValid()) {
- // |mojo_client_handle_| has already been transferred to the child process
- // by this point. Remove it from the scoped container so that we don't
- // erroneously delete it.
- ignore_result(mojo_client_handle_.release());
- }
}
// static
diff --git a/chromium/content/browser/child_process_launcher_helper_linux.cc b/chromium/content/browser/child_process_launcher_helper_linux.cc
index 5db82c367aa..c981f7fc90f 100644
--- a/chromium/content/browser/child_process_launcher_helper_linux.cc
+++ b/chromium/content/browser/child_process_launcher_helper_linux.cc
@@ -15,7 +15,6 @@
#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"
#include "services/service_manager/zygote/common/common_sandbox_support_linux.h"
#include "services/service_manager/zygote/common/zygote_handle.h"
@@ -25,10 +24,10 @@
namespace content {
namespace internal {
-mojo::edk::ScopedInternalPlatformHandle
-ChildProcessLauncherHelper::PrepareMojoPipeHandlesOnClientThread() {
+base::Optional<mojo::NamedPlatformChannel>
+ChildProcessLauncherHelper::CreateNamedPlatformChannelOnClientThread() {
DCHECK_CURRENTLY_ON(client_thread_id_);
- return mojo::edk::ScopedInternalPlatformHandle();
+ return base::nullopt;
}
void ChildProcessLauncherHelper::BeforeLaunchOnClientThread() {
@@ -38,7 +37,8 @@ void ChildProcessLauncherHelper::BeforeLaunchOnClientThread() {
std::unique_ptr<FileMappedForLaunch>
ChildProcessLauncherHelper::GetFilesToMap() {
DCHECK(CurrentlyOnProcessLauncherTaskRunner());
- return CreateDefaultPosixFilesToMap(child_process_id(), mojo_client_handle(),
+ return CreateDefaultPosixFilesToMap(child_process_id(),
+ mojo_channel_->remote_endpoint(),
true /* include_service_required_files */,
GetProcessType(), command_line());
}
@@ -50,10 +50,7 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
options->fds_to_remap = files_to_register.GetMappingWithIDAdjustment(
base::GlobalDescriptors::kBaseDescriptor);
- if (GetProcessType() == switches::kRendererProcess ||
- (GetProcessType() == switches::kGpuProcess &&
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableOOPRasterization))) {
+ if (GetProcessType() == switches::kRendererProcess) {
const int sandbox_fd = SandboxHostLinux::GetInstance()->GetChildSocket();
options->fds_to_remap.push_back(
std::make_pair(sandbox_fd, service_manager::GetSandboxFD()));
@@ -161,7 +158,7 @@ void ChildProcessLauncherHelper::SetProcessPriorityOnLauncherThread(
const ChildProcessLauncherPriority& priority) {
DCHECK(CurrentlyOnProcessLauncherTaskRunner());
if (process.CanBackgroundProcesses())
- process.SetProcessBackgrounded(priority.background);
+ process.SetProcessBackgrounded(priority.is_background());
}
// static
diff --git a/chromium/content/browser/child_process_launcher_helper_mac.cc b/chromium/content/browser/child_process_launcher_helper_mac.cc
index 902177996e1..3fd28bf7589 100644
--- a/chromium/content/browser/child_process_launcher_helper_mac.cc
+++ b/chromium/content/browser/child_process_launcher_helper_mac.cc
@@ -6,6 +6,7 @@
#include "base/feature_list.h"
#include "base/path_service.h"
#include "base/posix/global_descriptors.h"
+#include "base/strings/stringprintf.h"
#include "content/browser/child_process_launcher.h"
#include "content/browser/child_process_launcher_helper.h"
#include "content/browser/child_process_launcher_helper_posix.h"
@@ -19,7 +20,6 @@
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
-#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "sandbox/mac/seatbelt_exec.h"
#include "services/service_manager/embedder/result_codes.h"
#include "services/service_manager/sandbox/mac/cdm.sb.h"
@@ -37,10 +37,10 @@
namespace content {
namespace internal {
-mojo::edk::ScopedInternalPlatformHandle
-ChildProcessLauncherHelper::PrepareMojoPipeHandlesOnClientThread() {
+base::Optional<mojo::NamedPlatformChannel>
+ChildProcessLauncherHelper::CreateNamedPlatformChannelOnClientThread() {
DCHECK_CURRENTLY_ON(client_thread_id_);
- return mojo::edk::ScopedInternalPlatformHandle();
+ return base::nullopt;
}
void ChildProcessLauncherHelper::BeforeLaunchOnClientThread() {
@@ -51,7 +51,7 @@ std::unique_ptr<PosixFileDescriptorInfo>
ChildProcessLauncherHelper::GetFilesToMap() {
DCHECK(CurrentlyOnProcessLauncherTaskRunner());
return CreateDefaultPosixFilesToMap(
- child_process_id(), mojo_client_handle(),
+ child_process_id(), mojo_channel_->remote_endpoint(),
false /* include_service_required_files */, GetProcessType(),
command_line());
}
@@ -171,8 +171,8 @@ bool ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread(
// Update the command line to enable the V2 sandbox and pass the
// communication FD to the helper executable.
- command_line_->AppendSwitch(switches::kEnableV2Sandbox);
- command_line_->AppendArg("--fd_mapping=" + std::to_string(pipe));
+ command_line_->AppendArg(
+ base::StringPrintf("%s%d", sandbox::switches::kSeatbeltClient, pipe));
}
// Hold the MachBroker lock for the duration of LaunchProcess. The child will
@@ -259,7 +259,7 @@ void ChildProcessLauncherHelper::SetProcessPriorityOnLauncherThread(
const ChildProcessLauncherPriority& priority) {
if (process.CanBackgroundProcesses()) {
process.SetProcessBackgrounded(MachBroker::GetInstance(),
- priority.background);
+ priority.is_background());
}
}
diff --git a/chromium/content/browser/child_process_launcher_helper_posix.cc b/chromium/content/browser/child_process_launcher_helper_posix.cc
index 60aedf2a364..bdd38c9cc61 100644
--- a/chromium/content/browser/child_process_launcher_helper_posix.cc
+++ b/chromium/content/browser/child_process_launcher_helper_posix.cc
@@ -14,7 +14,7 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_descriptors.h"
#include "content/public/common/content_switches.h"
-#include "mojo/edk/embedder/platform_handle.h"
+#include "mojo/public/cpp/platform/platform_channel_endpoint.h"
#include "services/catalog/public/cpp/manifest_parsing_util.h"
#include "services/service_manager/embedder/shared_file_util.h"
#include "services/service_manager/embedder/switches.h"
@@ -73,7 +73,7 @@ base::PlatformFile OpenFileIfNecessary(const base::FilePath& path,
std::unique_ptr<PosixFileDescriptorInfo> CreateDefaultPosixFilesToMap(
int child_process_id,
- const mojo::edk::InternalPlatformHandle& mojo_client_handle,
+ const mojo::PlatformChannelEndpoint& mojo_channel_remote_endpoint,
bool include_service_required_files,
const std::string& process_type,
base::CommandLine* command_line) {
@@ -87,9 +87,10 @@ std::unique_ptr<PosixFileDescriptorInfo> CreateDefaultPosixFilesToMap(
base::SharedMemory::GetFdFromSharedMemoryHandle(shm));
}
- DCHECK(mojo_client_handle.is_valid());
- files_to_register->Share(service_manager::kMojoIPCChannel,
- mojo_client_handle.handle);
+ DCHECK(mojo_channel_remote_endpoint.is_valid());
+ files_to_register->Share(
+ service_manager::kMojoIPCChannel,
+ mojo_channel_remote_endpoint.platform_handle().GetFD().get());
// TODO(jcivelli): remove this "if defined" by making
// GetAdditionalMappedFilesForChildProcess a no op on Mac.
diff --git a/chromium/content/browser/child_process_launcher_helper_posix.h b/chromium/content/browser/child_process_launcher_helper_posix.h
index df353a54a11..956c6d3a5a9 100644
--- a/chromium/content/browser/child_process_launcher_helper_posix.h
+++ b/chromium/content/browser/child_process_launcher_helper_posix.h
@@ -17,10 +17,8 @@ class FilePath;
} // namespace base
namespace mojo {
-namespace edk {
-struct InternalPlatformHandle;
+class PlatformChannelEndpoint;
} // namespace mojo
-} // namespace edk
// Contains the common functionalities between the various POSIX child process
// launcher implementations.
@@ -33,7 +31,7 @@ namespace internal {
std::unique_ptr<PosixFileDescriptorInfo> CreateDefaultPosixFilesToMap(
int child_process_id,
- const mojo::edk::InternalPlatformHandle& mojo_client_handle,
+ const mojo::PlatformChannelEndpoint& mojo_channel_remote_endpoint,
bool include_service_required_files,
const std::string& process_type,
base::CommandLine* command_line);
diff --git a/chromium/content/browser/child_process_launcher_helper_win.cc b/chromium/content/browser/child_process_launcher_helper_win.cc
index 46c2dbea83d..4deb9438f18 100644
--- a/chromium/content/browser/child_process_launcher_helper_win.cc
+++ b/chromium/content/browser/child_process_launcher_helper_win.cc
@@ -14,9 +14,8 @@
#include "content/public/common/result_codes.h"
#include "content/public/common/sandbox_init.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
-#include "mojo/edk/embedder/named_platform_channel_pair.h"
-#include "mojo/edk/embedder/platform_channel_pair.h"
-#include "mojo/edk/embedder/scoped_platform_handle.h"
+#include "mojo/public/cpp/platform/named_platform_channel.h"
+#include "mojo/public/cpp/platform/platform_channel.h"
#include "sandbox/win/src/sandbox_types.h"
#include "services/service_manager/embedder/result_codes.h"
#include "services/service_manager/sandbox/win/sandbox_win.h"
@@ -28,16 +27,17 @@ void ChildProcessLauncherHelper::BeforeLaunchOnClientThread() {
DCHECK_CURRENTLY_ON(client_thread_id_);
}
-mojo::edk::ScopedInternalPlatformHandle
-ChildProcessLauncherHelper::PrepareMojoPipeHandlesOnClientThread() {
+base::Optional<mojo::NamedPlatformChannel>
+ChildProcessLauncherHelper::CreateNamedPlatformChannelOnClientThread() {
DCHECK_CURRENTLY_ON(client_thread_id_);
if (!delegate_->ShouldLaunchElevated())
- return mojo::edk::ScopedInternalPlatformHandle();
+ return base::nullopt;
- mojo::edk::NamedPlatformChannelPair named_pair;
- named_pair.PrepareToPassClientHandleToChildProcess(command_line());
- return named_pair.PassServerHandle();
+ mojo::NamedPlatformChannel::Options options;
+ mojo::NamedPlatformChannel named_channel(options);
+ named_channel.PassServerNameOnCommandLine(command_line());
+ return named_channel;
}
std::unique_ptr<FileMappedForLaunch>
@@ -70,11 +70,8 @@ ChildProcessLauncherHelper::LaunchProcessOnLauncherThread(
return process;
}
base::HandlesToInheritVector handles;
- handles.push_back(mojo_client_handle().handle);
+ mojo_channel_->PrepareToPassRemoteEndpoint(&handles, command_line());
base::FieldTrialList::AppendFieldTrialHandleIfNeeded(&handles);
- command_line()->AppendSwitchASCII(
- mojo::edk::PlatformChannelPair::kMojoPlatformChannelHandleSwitch,
- base::UintToString(base::win::HandleToUint32(handles[0])));
ChildProcessLauncherHelper::Process process;
*launch_result = StartSandboxedProcess(
delegate_.get(),
@@ -118,7 +115,7 @@ void ChildProcessLauncherHelper::SetProcessPriorityOnLauncherThread(
const ChildProcessLauncherPriority& priority) {
DCHECK(CurrentlyOnProcessLauncherTaskRunner());
if (process.CanBackgroundProcesses())
- process.SetProcessBackgrounded(priority.background);
+ process.SetProcessBackgrounded(priority.is_background());
}
// static
diff --git a/chromium/content/browser/child_process_security_policy_impl.cc b/chromium/content/browser/child_process_security_policy_impl.cc
index 4bf51fd3352..1272be30040 100644
--- a/chromium/content/browser/child_process_security_policy_impl.cc
+++ b/chromium/content/browser/child_process_security_policy_impl.cc
@@ -117,13 +117,30 @@ class ChildProcessSecurityPolicyImpl::SecurityState {
file_permissions_.size());
}
- // Grant permission to request URLs with the specified origin.
- void GrantOrigin(const url::Origin& origin) {
- origin_set_.insert(origin);
+ // Grant permission to request and commit URLs with the specified origin.
+ void GrantCommitOrigin(const url::Origin& origin) {
+ if (origin.unique())
+ return;
+ origin_map_[origin] = CommitRequestPolicy::kCommitAndRequest;
+ }
+
+ void GrantRequestOrigin(const url::Origin& origin) {
+ if (origin.unique())
+ return;
+ // Anything already in |origin_map_| must have at least request permission
+ // already. In that case, the emplace() below will be a no-op.
+ origin_map_.emplace(origin, CommitRequestPolicy::kRequestOnly);
+ }
+
+ void GrantCommitScheme(const std::string& scheme) {
+ scheme_map_[scheme] = CommitRequestPolicy::kCommitAndRequest;
}
- // Grant permission to request URLs with the specified scheme.
- void GrantScheme(const std::string& scheme) { scheme_policy_.insert(scheme); }
+ void GrantRequestScheme(const std::string& scheme) {
+ // Anything already in |scheme_map_| must have at least request permission
+ // already. In that case, the emplace() below will be a no-op.
+ scheme_map_.emplace(scheme, CommitRequestPolicy::kRequestOnly);
+ }
// Grant certain permissions to a file.
void GrantPermissionsForFile(const base::FilePath& file, int permissions) {
@@ -194,26 +211,25 @@ class ChildProcessSecurityPolicyImpl::SecurityState {
can_send_midi_sysex_ = true;
}
- bool CanCommitOrigin(const url::Origin& origin) {
- return base::ContainsKey(origin_set_, origin);
- }
-
// Determine whether permission has been granted to commit |url|.
bool CanCommitURL(const GURL& url) {
DCHECK(!url.SchemeIsBlob() && !url.SchemeIsFileSystem())
<< "inner_url extraction should be done already.";
// Having permission to a scheme implies permission to all of its URLs.
- SchemeSet::const_iterator scheme_judgment(
- scheme_policy_.find(url.scheme()));
- if (scheme_judgment != scheme_policy_.end())
+ auto scheme_judgment = scheme_map_.find(url.scheme());
+ if (scheme_judgment != scheme_map_.end() &&
+ scheme_judgment->second == CommitRequestPolicy::kCommitAndRequest) {
return true;
+ }
- // Otherwise, check for permission for specific origin.
+ // Check for permission for specific origin.
if (CanCommitOrigin(url::Origin::Create(url)))
return true;
- // file:// URLs are more granular. The child may have been given
- // permission to a specific file but not the file:// scheme in general.
+ // file:// URLs may sometimes be more granular, e.g. dragging and dropping a
+ // file from the local filesystem. The child itself may not have been
+ // granted access to the entire file:// scheme, but it should still be
+ // allowed to request the dragged and dropped file.
if (url.SchemeIs(url::kFileScheme)) {
base::FilePath path;
if (net::FileURLToFilePath(url, &path))
@@ -223,6 +239,22 @@ class ChildProcessSecurityPolicyImpl::SecurityState {
return false; // Unmentioned schemes are disallowed.
}
+ bool CanRequestURL(const GURL& url) {
+ DCHECK(!url.SchemeIsBlob() && !url.SchemeIsFileSystem())
+ << "inner_url extraction should be done already.";
+ // Having permission to a scheme implies permission to all of its URLs.
+ auto scheme_judgment = scheme_map_.find(url.scheme());
+ if (scheme_judgment != scheme_map_.end())
+ return true;
+
+ if (CanRequestOrigin(url::Origin::Create(url)))
+ return true;
+
+ // Otherwise, delegate to CanCommitURL. Unmentioned schemes are disallowed.
+ // TODO(dcheng): It would be nice to avoid constructing the origin twice.
+ return CanCommitURL(url);
+ }
+
// Determine if the certain permissions have been granted to a file.
bool HasPermissionsForFile(const base::FilePath& file, int permissions) {
#if defined(OS_ANDROID)
@@ -280,7 +312,7 @@ class ChildProcessSecurityPolicyImpl::SecurityState {
}
bool has_web_ui_bindings() const {
- return enabled_bindings_ & BINDINGS_POLICY_WEB_UI;
+ return enabled_bindings_ & kWebUIBindingsPolicyMask;
}
bool can_read_raw_cookies() const {
@@ -292,22 +324,39 @@ class ChildProcessSecurityPolicyImpl::SecurityState {
}
private:
- typedef std::set<std::string> SchemeSet;
- typedef std::set<url::Origin> OriginSet;
+ enum class CommitRequestPolicy {
+ kRequestOnly,
+ kCommitAndRequest,
+ };
+
+ bool CanCommitOrigin(const url::Origin& origin) {
+ auto it = origin_map_.find(origin);
+ if (it == origin_map_.end())
+ return false;
+ return it->second == CommitRequestPolicy::kCommitAndRequest;
+ }
+
+ bool CanRequestOrigin(const url::Origin& origin) {
+ // Anything already in |origin_map_| must have at least request permissions
+ // already.
+ return origin_map_.find(origin) != origin_map_.end();
+ }
+
+ typedef std::map<std::string, CommitRequestPolicy> SchemeMap;
+ typedef std::map<url::Origin, CommitRequestPolicy> OriginMap;
typedef int FilePermissionFlags; // bit-set of base::File::Flags
typedef std::map<base::FilePath, FilePermissionFlags> FileMap;
typedef std::map<std::string, FilePermissionFlags> FileSystemMap;
typedef std::set<base::FilePath> FileSet;
- // Maps URL schemes to whether permission has been granted, containment means
- // that the scheme has been granted, otherwise, it has never been granted.
- // There is no provision for revoking.
- SchemeSet scheme_policy_;
+ // Maps URL schemes to commit/request policies the child process has been
+ // granted. There is no provision for revoking.
+ SchemeMap scheme_map_;
- // The set of URL origins to which the child process has been granted
- // permission.
- OriginSet origin_set_;
+ // The map of URL origins to commit/request policies the child process has
+ // been granted. There is no provision for revoking.
+ OriginMap origin_map_;
// The set of files the child process is permited to upload to the web.
FileMap file_permissions_;
@@ -431,34 +480,57 @@ bool ChildProcessSecurityPolicyImpl::IsPseudoScheme(
return base::ContainsKey(pseudo_schemes_, scheme);
}
-void ChildProcessSecurityPolicyImpl::GrantRequestURL(
- int child_id, const GURL& url) {
-
+void ChildProcessSecurityPolicyImpl::GrantCommitURL(int child_id,
+ const GURL& url) {
+ // Can't grant the capability to commit invalid URLs.
if (!url.is_valid())
- return; // Can't grant the capability to request invalid URLs.
-
- const std::string& scheme = url.scheme();
+ return;
- if (IsWebSafeScheme(scheme))
- return; // The scheme has already been whitelisted for every child process.
+ // Can't grant the capability to commit pseudo schemes.
+ if (IsPseudoScheme(url.scheme()))
+ return;
- if (IsPseudoScheme(scheme)) {
- return; // Can't grant the capability to request pseudo schemes.
- }
+ url::Origin origin = url::Origin::Create(url);
+ // Blob and filesystem URLs require special treatment; grant access to the
+ // inner origin they embed instead.
+ // TODO(dcheng): Can this logic be simplified to just derive an origin up
+ // front and use that? That probably requires fixing GURL canonicalization of
+ // blob URLs though. For now, be consistent with how CanRequestURL and
+ // CanCommitURL normalize.
if (url.SchemeIsBlob() || url.SchemeIsFileSystem()) {
- return; // Don't grant blanket access to blob: or filesystem: schemes.
+ if (IsMalformedBlobUrl(url))
+ return;
+
+ GrantCommitURL(child_id, GURL(origin.Serialize()));
}
- {
- base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
- if (state == security_state_.end())
- return;
+ // TODO(dcheng): In the future, URLs with opaque origins would ideally carry
+ // around an origin with them, so we wouldn't need to grant commit access to
+ // the entire scheme.
+ if (!origin.unique())
+ GrantCommitOrigin(child_id, origin);
+
+ // The scheme has already been whitelisted for every child process, so no need
+ // to do anything else.
+ if (IsWebSafeScheme(url.scheme()))
+ return;
+
+ base::AutoLock lock(lock_);
- // When the child process has been commanded to request this scheme,
- // we grant it the capability to request all URLs of that scheme.
- state->second->GrantScheme(scheme);
+ auto state = security_state_.find(child_id);
+ if (state == security_state_.end())
+ return;
+
+ if (origin.unique()) {
+ // If it's impossible to grant commit rights to just the origin (among other
+ // things, URLs with non-standard schemes will be treated as opaque
+ // origins), then grant access to commit all URLs of that scheme.
+ state->second->GrantCommitScheme(url.scheme());
+ } else {
+ // When the child process has been commanded to request this scheme, grant
+ // it the capability to request all URLs of that scheme.
+ state->second->GrantRequestScheme(url.scheme());
}
}
@@ -565,42 +637,61 @@ void ChildProcessSecurityPolicyImpl::GrantSendMidiSysExMessage(int child_id) {
state->second->GrantPermissionForMidiSysEx();
}
-void ChildProcessSecurityPolicyImpl::GrantOrigin(int child_id,
- const url::Origin& origin) {
+void ChildProcessSecurityPolicyImpl::GrantCommitOrigin(
+ int child_id,
+ const url::Origin& origin) {
base::AutoLock lock(lock_);
SecurityStateMap::iterator state = security_state_.find(child_id);
if (state == security_state_.end())
return;
- state->second->GrantOrigin(origin);
+ state->second->GrantCommitOrigin(origin);
}
-void ChildProcessSecurityPolicyImpl::GrantScheme(int child_id,
- const std::string& scheme) {
+void ChildProcessSecurityPolicyImpl::GrantRequestOrigin(
+ int child_id,
+ const url::Origin& origin) {
base::AutoLock lock(lock_);
SecurityStateMap::iterator state = security_state_.find(child_id);
if (state == security_state_.end())
return;
- state->second->GrantScheme(scheme);
+ state->second->GrantRequestOrigin(origin);
+}
+
+void ChildProcessSecurityPolicyImpl::GrantRequestScheme(
+ int child_id,
+ const std::string& scheme) {
+ base::AutoLock lock(lock_);
+
+ auto state = security_state_.find(child_id);
+ if (state == security_state_.end())
+ return;
+
+ state->second->GrantRequestScheme(scheme);
}
-void ChildProcessSecurityPolicyImpl::GrantWebUIBindings(int child_id) {
+void ChildProcessSecurityPolicyImpl::GrantWebUIBindings(int child_id,
+ int bindings) {
+ // Only WebUI bindings should come through here.
+ CHECK(bindings & kWebUIBindingsPolicyMask);
+ CHECK_EQ(0, bindings & ~kWebUIBindingsPolicyMask);
+
base::AutoLock lock(lock_);
SecurityStateMap::iterator state = security_state_.find(child_id);
if (state == security_state_.end())
return;
- state->second->GrantBindings(BINDINGS_POLICY_WEB_UI);
+ state->second->GrantBindings(bindings);
// Web UI bindings need the ability to request chrome: URLs.
- state->second->GrantScheme(kChromeUIScheme);
+ state->second->GrantRequestScheme(kChromeUIScheme);
// Web UI pages can contain links to file:// URLs.
- state->second->GrantScheme(url::kFileScheme);
+ state->second->GrantRequestScheme(url::kFileScheme);
}
void ChildProcessSecurityPolicyImpl::GrantReadRawCookies(int child_id) {
@@ -630,35 +721,43 @@ bool ChildProcessSecurityPolicyImpl::CanRequestURL(
const std::string& scheme = url.scheme();
- if (IsPseudoScheme(scheme)) {
- // Every child process can request <about:blank>, <about:blank?foo>,
- // <about:blank/#foo> and <about:srcdoc>.
- if (url.IsAboutBlank() || url == kAboutSrcDocURL)
- return true;
- // URLs like <about:version>, <about:crash>, <view-source:...> shouldn't be
- // requestable by any child process. Also, this case covers
- // <javascript:...>, which should be handled internally by the process and
- // not kicked up to the browser.
- return false;
- }
+ // Every child process can request <about:blank>, <about:blank?foo>,
+ // <about:blank/#foo> and <about:srcdoc>.
+ //
+ // URLs like <about:version>, <about:crash>, <view-source:...> shouldn't be
+ // requestable by any child process. Also, this case covers
+ // <javascript:...>, which should be handled internally by the process and
+ // not kicked up to the browser.
+ // TODO(dcheng): Figure out why this check is different from CanCommitURL,
+ // which checks for direct equality with kAboutBlankURL.
+ if (IsPseudoScheme(scheme))
+ return url.IsAboutBlank() || url == kAboutSrcDocURL;
- // Blob and filesystem URLs require special treatment, since they embed an
- // inner origin.
+ // Blob and filesystem URLs require special treatment; validate the inner
+ // origin they embed.
if (url.SchemeIsBlob() || url.SchemeIsFileSystem()) {
if (IsMalformedBlobUrl(url))
return false;
url::Origin origin = url::Origin::Create(url);
- return origin.unique() || IsWebSafeScheme(origin.scheme()) ||
- CanCommitURL(child_id, GURL(origin.Serialize()));
+ return origin.unique() || CanRequestURL(child_id, GURL(origin.Serialize()));
}
if (IsWebSafeScheme(scheme))
return true;
- // If the process can commit the URL, it can request it.
- if (CanCommitURL(child_id, url))
- return true;
+ {
+ base::AutoLock lock(lock_);
+
+ SecurityStateMap::iterator state = security_state_.find(child_id);
+ if (state == security_state_.end())
+ return false;
+
+ // Otherwise, we consult the child process's security state to see if it is
+ // allowed to request the URL.
+ if (state->second->CanRequestURL(url))
+ return true;
+ }
// Also allow URLs destined for ShellExecute and not the browser itself.
return !GetContentClient()->browser()->IsHandledURL(url) &&
@@ -1047,18 +1146,12 @@ bool ChildProcessSecurityPolicyImpl::CanAccessDataForOrigin(int child_id,
return can_access;
}
-bool ChildProcessSecurityPolicyImpl::HasSpecificPermissionForOrigin(
- int child_id,
- const url::Origin& origin) {
- base::AutoLock lock(lock_);
- SecurityStateMap::iterator state = security_state_.find(child_id);
- if (state == security_state_.end())
- return false;
- return state->second->CanCommitOrigin(origin);
-}
-
void ChildProcessSecurityPolicyImpl::LockToOrigin(int child_id,
const GURL& gurl) {
+ // LockToOrigin should only be called on the UI thread (OTOH, it is okay to
+ // call GetOriginLock or CheckOriginLock from any thread).
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
// "gurl" can be currently empty in some cases, such as file://blah.
DCHECK(SiteInstanceImpl::GetSiteForURL(nullptr, gurl) == gurl);
base::AutoLock lock(lock_);
diff --git a/chromium/content/browser/child_process_security_policy_impl.h b/chromium/content/browser/child_process_security_policy_impl.h
index 47eb3321976..a82411ecdce 100644
--- a/chromium/content/browser/child_process_security_policy_impl.h
+++ b/chromium/content/browser/child_process_security_policy_impl.h
@@ -75,8 +75,9 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
const std::string& filesystem_id) override;
void GrantDeleteFromFileSystem(int child_id,
const std::string& filesystem_id) override;
- void GrantOrigin(int child_id, const url::Origin& origin) override;
- void GrantScheme(int child_id, const std::string& scheme) override;
+ void GrantCommitOrigin(int child_id, const url::Origin& origin) override;
+ void GrantRequestOrigin(int child_id, const url::Origin& origin) override;
+ void GrantRequestScheme(int child_id, const std::string& scheme) override;
bool CanRequestURL(int child_id, const GURL& url) override;
bool CanCommitURL(int child_id, const GURL& url) override;
bool CanReadFile(int child_id, const base::FilePath& file) override;
@@ -93,8 +94,6 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
bool HasWebUIBindings(int child_id) override;
void GrantSendMidiSysExMessage(int child_id) override;
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;
@@ -137,11 +136,11 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
// this method exactly once.
void Remove(int child_id);
- // Whenever the browser processes commands the child process to request a URL,
+ // Whenever the browser processes commands the child process to commit a URL,
// it should call this method to grant the child process the capability to
- // request the URL, along with permission to request all URLs of the same
- // scheme.
- void GrantRequestURL(int child_id, const GURL& url);
+ // commit anything from the URL's origin, along with permission to request all
+ // URLs of the same scheme.
+ void GrantCommitURL(int child_id, const GURL& url);
// Whenever the browser process drops a file icon on a tab, it should call
// this method to grant the child process the capability to request this one
@@ -151,8 +150,9 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
// Revokes all permissions granted to the given file.
void RevokeAllPermissionsForFile(int child_id, const base::FilePath& file);
- // Grant the child process the ability to use Web UI Bindings.
- void GrantWebUIBindings(int child_id);
+ // Grant the child process the ability to use Web UI Bindings where |bindings|
+ // is either BINDINGS_POLICY_WEB_UI or BINDINGS_POLICY_MOJO_WEB_UI or both.
+ void GrantWebUIBindings(int child_id, int bindings);
// Grant the child process the ability to read raw cookies.
void GrantReadRawCookies(int child_id);
@@ -183,8 +183,9 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
bool CanReadRawCookies(int child_id);
// Sets the process as only permitted to use and see the cookies for the
- // given origin.
- void LockToOrigin(int child_id, const GURL& gurl);
+ // given origin. Most callers should use RenderProcessHostImpl::LockToOrigin
+ // instead of calling this directly.
+ void LockToOrigin(int child_id, const GURL& lock_url);
// Used to indicate the result of comparing a process's origin lock to
// another value:
diff --git a/chromium/content/browser/child_process_security_policy_unittest.cc b/chromium/content/browser/child_process_security_policy_unittest.cc
index 499cf3ac9eb..57bc04c9d8c 100644
--- a/chromium/content/browser/child_process_security_policy_unittest.cc
+++ b/chromium/content/browser/child_process_security_policy_unittest.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/test/mock_log.h"
#include "content/browser/child_process_security_policy_impl.h"
+#include "content/public/common/bindings_policy.h"
#include "content/public/common/url_constants.h"
#include "content/test/test_content_browser_client.h"
#include "storage/browser/fileapi/file_permission_policy.h"
@@ -342,20 +343,12 @@ TEST_F(ChildProcessSecurityPolicyTest, AboutTest) {
EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, GURL("aBoUt:version")));
// Requests for about: pages should be denied.
- p->GrantRequestURL(kRendererID, GURL("about:crash"));
+ p->GrantCommitURL(kRendererID, GURL("about:crash"));
EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:crash")));
EXPECT_FALSE(p->CanRedirectToURL(GURL("about:crash")));
EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("about:crash")));
EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, GURL("about:crash")));
- // These requests for chrome:// pages should be granted.
- GURL chrome_url("chrome://foo");
- p->GrantRequestURL(kRendererID, chrome_url);
- EXPECT_TRUE(p->CanRequestURL(kRendererID, chrome_url));
- EXPECT_TRUE(p->CanRedirectToURL(GURL(chrome_url)));
- EXPECT_TRUE(p->CanCommitURL(kRendererID, chrome_url));
- EXPECT_TRUE(p->CanSetAsOriginHeader(kRendererID, chrome_url));
-
p->Remove(kRendererID);
}
@@ -370,7 +363,7 @@ TEST_F(ChildProcessSecurityPolicyTest, JavaScriptTest) {
EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("javascript:alert('xss')")));
EXPECT_FALSE(
p->CanSetAsOriginHeader(kRendererID, GURL("javascript:alert('xss')")));
- p->GrantRequestURL(kRendererID, GURL("javascript:alert('xss')"));
+ p->GrantCommitURL(kRendererID, GURL("javascript:alert('xss')"));
EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')")));
EXPECT_FALSE(p->CanRedirectToURL(GURL("javascript:alert('xss')")));
EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("javascript:alert('xss')")));
@@ -422,7 +415,7 @@ TEST_F(ChildProcessSecurityPolicyTest, CanServiceCommandsTest) {
EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("file:///etc/passwd")));
EXPECT_FALSE(
p->CanSetAsOriginHeader(kRendererID, GURL("file:///etc/passwd")));
- p->GrantRequestURL(kRendererID, GURL("file:///etc/passwd"));
+ p->GrantCommitURL(kRendererID, GURL("file:///etc/passwd"));
EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
EXPECT_TRUE(p->CanRedirectToURL(GURL("file:///etc/passwd")));
EXPECT_TRUE(p->CanCommitURL(kRendererID, GURL("file:///etc/passwd")));
@@ -481,7 +474,7 @@ TEST_F(ChildProcessSecurityPolicyTest, ViewSource) {
EXPECT_FALSE(p->CanSetAsOriginHeader(
kRendererID, GURL("view-source:view-source:http://www.google.com/")));
- p->GrantRequestURL(kRendererID, GURL("view-source:file:///etc/passwd"));
+ p->GrantCommitURL(kRendererID, GURL("view-source:file:///etc/passwd"));
EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
EXPECT_TRUE(p->CanRedirectToURL(GURL("file:///etc/passwd")));
EXPECT_FALSE(p->CanCommitURL(kRendererID, GURL("file:///etc/passwd")));
@@ -497,6 +490,44 @@ TEST_F(ChildProcessSecurityPolicyTest, ViewSource) {
p->Remove(kRendererID);
}
+TEST_F(ChildProcessSecurityPolicyTest, GrantCommitURLToNonStandardScheme) {
+ ChildProcessSecurityPolicyImpl* p =
+ ChildProcessSecurityPolicyImpl::GetInstance();
+
+ const GURL url("httpxml://awesome");
+ const GURL url2("httpxml://also-awesome");
+
+ ASSERT_TRUE(url::Origin::Create(url).unique());
+ ASSERT_TRUE(url::Origin::Create(url2).unique());
+ RegisterTestScheme("httpxml");
+
+ p->Add(kRendererID);
+
+ EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
+ EXPECT_FALSE(p->CanRequestURL(kRendererID, url2));
+ EXPECT_TRUE(p->CanRedirectToURL(url));
+ EXPECT_TRUE(p->CanRedirectToURL(url2));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url2));
+ EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, url));
+ EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, url2));
+
+ // GrantCommitURL with a non-standard scheme should grant commit access to the
+ // entire scheme.
+ p->GrantCommitURL(kRendererID, url);
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, url2));
+ EXPECT_TRUE(p->CanRedirectToURL(url));
+ EXPECT_TRUE(p->CanRedirectToURL(url2));
+ EXPECT_TRUE(p->CanCommitURL(kRendererID, url));
+ EXPECT_TRUE(p->CanCommitURL(kRendererID, url2));
+ EXPECT_TRUE(p->CanSetAsOriginHeader(kRendererID, url));
+ EXPECT_TRUE(p->CanSetAsOriginHeader(kRendererID, url2));
+
+ p->Remove(kRendererID);
+}
+
TEST_F(ChildProcessSecurityPolicyTest, SpecificFile) {
ChildProcessSecurityPolicyImpl* p =
ChildProcessSecurityPolicyImpl::GetInstance();
@@ -524,7 +555,7 @@ TEST_F(ChildProcessSecurityPolicyTest, SpecificFile) {
EXPECT_TRUE(p->CanSetAsOriginHeader(kRendererID, icon_url));
EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, sensitive_url));
- p->GrantRequestURL(kRendererID, icon_url);
+ p->GrantCommitURL(kRendererID, icon_url);
EXPECT_TRUE(p->CanRequestURL(kRendererID, icon_url));
EXPECT_TRUE(p->CanRequestURL(kRendererID, sensitive_url));
EXPECT_TRUE(p->CanRedirectToURL(icon_url));
@@ -833,19 +864,121 @@ TEST_F(ChildProcessSecurityPolicyTest, CanServiceWebUIBindings) {
ChildProcessSecurityPolicyImpl* p =
ChildProcessSecurityPolicyImpl::GetInstance();
- GURL url("chrome://thumb/http://www.google.com/");
+ const GURL url("chrome://thumb/http://www.google.com/");
+ const GURL other_url("chrome://not-thumb/");
+ const url::Origin origin = url::Origin::Create(url);
+ {
+ p->Add(kRendererID);
- p->Add(kRendererID);
+ EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
- EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
- EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
- EXPECT_TRUE(p->CanRedirectToURL(url));
- p->GrantWebUIBindings(kRendererID);
- EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
- EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
- EXPECT_TRUE(p->CanRedirectToURL(url));
+ EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
+ EXPECT_TRUE(p->CanRedirectToURL(url));
- p->Remove(kRendererID);
+ EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
+ EXPECT_TRUE(p->CanRedirectToURL(other_url));
+
+ p->GrantWebUIBindings(kRendererID, BINDINGS_POLICY_WEB_UI);
+
+ EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
+ EXPECT_TRUE(p->CanRedirectToURL(url));
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, other_url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
+ EXPECT_TRUE(p->CanRedirectToURL(other_url));
+
+ p->GrantCommitOrigin(kRendererID, origin);
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
+ EXPECT_TRUE(p->CanCommitURL(kRendererID, url));
+ EXPECT_TRUE(p->CanRedirectToURL(url));
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, other_url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
+ EXPECT_TRUE(p->CanRedirectToURL(other_url));
+
+ p->Remove(kRendererID);
+ }
+ {
+ p->Add(kRendererID);
+
+ EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
+
+ EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
+ EXPECT_TRUE(p->CanRedirectToURL(url));
+
+ EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
+ EXPECT_TRUE(p->CanRedirectToURL(other_url));
+
+ p->GrantWebUIBindings(kRendererID, BINDINGS_POLICY_MOJO_WEB_UI);
+
+ EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
+ EXPECT_TRUE(p->CanRedirectToURL(url));
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, other_url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
+ EXPECT_TRUE(p->CanRedirectToURL(other_url));
+
+ p->GrantCommitOrigin(kRendererID, origin);
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
+ EXPECT_TRUE(p->CanCommitURL(kRendererID, url));
+ EXPECT_TRUE(p->CanRedirectToURL(url));
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, other_url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
+ EXPECT_TRUE(p->CanRedirectToURL(other_url));
+
+ p->Remove(kRendererID);
+ }
+ {
+ p->Add(kRendererID);
+
+ EXPECT_FALSE(p->HasWebUIBindings(kRendererID));
+
+ EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
+ EXPECT_TRUE(p->CanRedirectToURL(url));
+
+ EXPECT_FALSE(p->CanRequestURL(kRendererID, other_url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
+ EXPECT_TRUE(p->CanRedirectToURL(other_url));
+
+ p->GrantWebUIBindings(kRendererID,
+ BINDINGS_POLICY_WEB_UI | BINDINGS_POLICY_MOJO_WEB_UI);
+
+ EXPECT_TRUE(p->HasWebUIBindings(kRendererID));
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url));
+ EXPECT_TRUE(p->CanRedirectToURL(url));
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, other_url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
+ EXPECT_TRUE(p->CanRedirectToURL(other_url));
+
+ p->GrantCommitOrigin(kRendererID, origin);
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
+ EXPECT_TRUE(p->CanCommitURL(kRendererID, url));
+ EXPECT_TRUE(p->CanRedirectToURL(url));
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, other_url));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, other_url));
+ EXPECT_TRUE(p->CanRedirectToURL(other_url));
+
+ p->Remove(kRendererID);
+ }
}
TEST_F(ChildProcessSecurityPolicyTest, RemoveRace) {
@@ -857,9 +990,10 @@ TEST_F(ChildProcessSecurityPolicyTest, RemoveRace) {
p->Add(kRendererID);
- p->GrantRequestURL(kRendererID, url);
+ p->GrantCommitURL(kRendererID, url);
p->GrantReadFile(kRendererID, file);
- p->GrantWebUIBindings(kRendererID);
+ p->GrantWebUIBindings(kRendererID,
+ BINDINGS_POLICY_WEB_UI | BINDINGS_POLICY_MOJO_WEB_UI);
EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
EXPECT_TRUE(p->CanRedirectToURL(url));
@@ -904,7 +1038,22 @@ TEST_F(ChildProcessSecurityPolicyTest, OriginGranting) {
EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, url_foo2));
EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, url_bar));
- p->GrantOrigin(kRendererID, url::Origin::Create(url_foo1));
+ p->GrantRequestOrigin(kRendererID, url::Origin::Create(url_foo1));
+
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo1));
+ EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo2));
+ EXPECT_FALSE(p->CanRequestURL(kRendererID, url_bar));
+ EXPECT_TRUE(p->CanRedirectToURL(url_foo1));
+ EXPECT_TRUE(p->CanRedirectToURL(url_foo2));
+ EXPECT_TRUE(p->CanRedirectToURL(url_bar));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url_foo1));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url_foo2));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url_bar));
+ EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, url_foo1));
+ EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, url_foo2));
+ EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, url_bar));
+
+ p->GrantCommitOrigin(kRendererID, url::Origin::Create(url_foo1));
EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo1));
EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo2));
@@ -919,20 +1068,21 @@ TEST_F(ChildProcessSecurityPolicyTest, OriginGranting) {
EXPECT_TRUE(p->CanSetAsOriginHeader(kRendererID, url_foo2));
EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, url_bar));
- p->GrantScheme(kRendererID, kChromeUIScheme);
+ // Make sure this doesn't overwrite the earlier commit grants.
+ p->GrantRequestOrigin(kRendererID, url::Origin::Create(url_foo1));
EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo1));
EXPECT_TRUE(p->CanRequestURL(kRendererID, url_foo2));
- EXPECT_TRUE(p->CanRequestURL(kRendererID, url_bar));
+ EXPECT_FALSE(p->CanRequestURL(kRendererID, url_bar));
EXPECT_TRUE(p->CanRedirectToURL(url_foo1));
EXPECT_TRUE(p->CanRedirectToURL(url_foo2));
EXPECT_TRUE(p->CanRedirectToURL(url_bar));
EXPECT_TRUE(p->CanCommitURL(kRendererID, url_foo1));
EXPECT_TRUE(p->CanCommitURL(kRendererID, url_foo2));
- EXPECT_TRUE(p->CanCommitURL(kRendererID, url_bar));
+ EXPECT_FALSE(p->CanCommitURL(kRendererID, url_bar));
EXPECT_TRUE(p->CanSetAsOriginHeader(kRendererID, url_foo1));
EXPECT_TRUE(p->CanSetAsOriginHeader(kRendererID, url_foo2));
- EXPECT_TRUE(p->CanSetAsOriginHeader(kRendererID, url_bar));
+ EXPECT_FALSE(p->CanSetAsOriginHeader(kRendererID, url_bar));
p->Remove(kRendererID);
}
diff --git a/chromium/content/browser/code_cache/generated_code_cache.cc b/chromium/content/browser/code_cache/generated_code_cache.cc
new file mode 100644
index 00000000000..c74c9a32d40
--- /dev/null
+++ b/chromium/content/browser/code_cache/generated_code_cache.cc
@@ -0,0 +1,383 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/code_cache/generated_code_cache.h"
+#include "base/memory/ptr_util.h"
+#include "net/base/completion_callback.h"
+#include "net/base/completion_once_callback.h"
+#include "net/http/http_util.h"
+
+namespace content {
+
+namespace {
+// Checks if |requesting_origin| is allowed to cache code for |resource_url|.
+// |resource_url| is the url corresponding to the requested resource.
+// If this url is invalid we don't cache the code.
+// |requesting_origin| is the origin that has requested the resource.
+// If this is a unique origin, then we don't cache the code.
+// For example, if http://script.com/script1.js is requested by
+// http://example.com, then http://script.com/script.js is the resource_url
+// and example.com is the requesting_origin.
+bool IsAllowedToCache(const GURL& resource_url,
+ const url::Origin& requesting_origin) {
+ // Don't cache the code corresponding to unique origins. The same-origin
+ // checks should always fail for unique origins but the serialized value of
+ // unique origins does not ensure this.
+ if (requesting_origin.unique())
+ return false;
+
+ // If the resource url or requesting url is invalid don't cache the code.
+ if (!resource_url.is_valid())
+ return false;
+
+ return true;
+}
+
+// Generates the cache key for the given |resource_url| and the
+// |requesting_origin|. This returns the key by concatenating the
+// serialized url and origin with a separator in between.
+std::string GetCacheKey(const GURL& resource_url,
+ const url::Origin& requesting_origin) {
+ DCHECK(!requesting_origin.unique());
+ DCHECK(resource_url.is_valid());
+ // Add a prefix _ so it can't be parsed as a valid URL.
+ std::string key = "_key";
+ // Remove reference, username and password sections of the URL.
+ key.append(net::HttpUtil::SpecForRequest(resource_url));
+ // Add a separator between URL and origin to avoid any possibility of
+ // attacks by crafting the URL. URLs do not contain any control ASCII
+ // characters, and also space is encoded. So use ' \n' as a seperator.
+ key.append(" \n");
+ key.append(requesting_origin.Serialize());
+ return key;
+}
+} // namespace
+
+// Stores the information about a pending request while disk backend is
+// being initialized.
+class GeneratedCodeCache::PendingOperation {
+ public:
+ PendingOperation(Operation op,
+ std::string key,
+ scoped_refptr<net::IOBufferWithSize>);
+ PendingOperation(Operation op, std::string key, const ReadDataCallback&);
+ PendingOperation(Operation op, std::string key);
+
+ ~PendingOperation();
+
+ Operation operation() const { return op_; }
+ const std::string& key() const { return key_; }
+ const scoped_refptr<net::IOBufferWithSize> data() const { return data_; }
+ const ReadDataCallback& callback() const { return callback_; }
+
+ private:
+ const Operation op_;
+ const std::string key_;
+ const scoped_refptr<net::IOBufferWithSize> data_;
+ const ReadDataCallback callback_;
+};
+
+GeneratedCodeCache::PendingOperation::PendingOperation(
+ Operation op,
+ std::string key,
+ scoped_refptr<net::IOBufferWithSize> buffer)
+ : op_(op),
+ key_(std::move(key)),
+ data_(buffer),
+ callback_(ReadDataCallback()) {}
+
+GeneratedCodeCache::PendingOperation::PendingOperation(
+ Operation op,
+ std::string key,
+ const ReadDataCallback& callback)
+ : op_(op),
+ key_(std::move(key)),
+ data_(scoped_refptr<net::IOBufferWithSize>()),
+ callback_(callback) {}
+
+GeneratedCodeCache::PendingOperation::PendingOperation(Operation op,
+ std::string key)
+ : op_(op),
+ key_(std::move(key)),
+ data_(scoped_refptr<net::IOBufferWithSize>()),
+ callback_(ReadDataCallback()) {}
+
+GeneratedCodeCache::PendingOperation::~PendingOperation() = default;
+
+// Static factory method.
+std::unique_ptr<GeneratedCodeCache> GeneratedCodeCache::Create(
+ const base::FilePath& path,
+ int max_size_bytes) {
+ return base::WrapUnique(new GeneratedCodeCache(path, max_size_bytes));
+}
+
+GeneratedCodeCache::~GeneratedCodeCache() = default;
+
+void GeneratedCodeCache::WriteData(
+ const GURL& url,
+ const url::Origin& origin,
+ scoped_refptr<net::IOBufferWithSize> buffer) {
+ // Silently ignore the requests.
+ if (backend_state_ == kFailed)
+ return;
+
+ // If the url is invalid or if it is from a unique origin, we should not
+ // cache the code.
+ if (!IsAllowedToCache(url, origin))
+ return;
+
+ std::string key = GetCacheKey(url, origin);
+ if (backend_state_ != kInitialized) {
+ // Insert it into the list of pending operations while the backend is
+ // still being opened.
+ pending_ops_.push_back(std::make_unique<PendingOperation>(
+ Operation::kWrite, std::move(key), buffer));
+ return;
+ }
+
+ WriteDataImpl(key, buffer);
+}
+
+void GeneratedCodeCache::FetchEntry(const GURL& url,
+ const url::Origin& origin,
+ ReadDataCallback read_data_callback) {
+ if (backend_state_ == kFailed) {
+ // Silently ignore the requests.
+ std::move(read_data_callback).Run(scoped_refptr<net::IOBufferWithSize>());
+ return;
+ }
+
+ // If the url is invalid or if it is from a unique origin, we should not
+ // cache the code.
+ if (!IsAllowedToCache(url, origin)) {
+ std::move(read_data_callback).Run(scoped_refptr<net::IOBufferWithSize>());
+ return;
+ }
+
+ std::string key = GetCacheKey(url, origin);
+ if (backend_state_ != kInitialized) {
+ // Insert it into the list of pending operations while the backend is
+ // still being opened.
+ pending_ops_.push_back(std::make_unique<PendingOperation>(
+ Operation::kFetch, std::move(key), read_data_callback));
+ return;
+ }
+
+ FetchEntryImpl(key, read_data_callback);
+}
+
+void GeneratedCodeCache::DeleteEntry(const GURL& url,
+ const url::Origin& origin) {
+ // Silently ignore the requests.
+ if (backend_state_ == kFailed)
+ return;
+
+ // If the url is invalid or if it is from a unique origin, we should not
+ // cache the code.
+ if (!IsAllowedToCache(url, origin))
+ return;
+
+ std::string key = GetCacheKey(url, origin);
+ if (backend_state_ != kInitialized) {
+ // Insert it into the list of pending operations while the backend is
+ // still being opened.
+ pending_ops_.push_back(
+ std::make_unique<PendingOperation>(Operation::kDelete, std::move(key)));
+ return;
+ }
+
+ DeleteEntryImpl(key);
+}
+
+GeneratedCodeCache::GeneratedCodeCache(const base::FilePath& path,
+ int max_size_bytes)
+ : backend_state_(kUnInitialized),
+ path_(path),
+ max_size_bytes_(max_size_bytes),
+ weak_ptr_factory_(this) {
+ CreateBackend();
+}
+
+void GeneratedCodeCache::CreateBackend() {
+ // Create a new Backend pointer that cleans itself if the GeneratedCodeCache
+ // instance is not live when the CreateCacheBackend finishes.
+ scoped_refptr<base::RefCountedData<ScopedBackendPtr>> shared_backend_ptr =
+ new base::RefCountedData<ScopedBackendPtr>();
+
+ net::CompletionOnceCallback create_backend_complete =
+ base::BindOnce(&GeneratedCodeCache::DidCreateBackend,
+ weak_ptr_factory_.GetWeakPtr(), shared_backend_ptr);
+
+ // If the initialization of the existing cache fails, this call would delete
+ // all the contents and recreates a new one.
+ int rv = disk_cache::CreateCacheBackend(
+ net::GENERATED_CODE_CACHE, net::CACHE_BACKEND_SIMPLE, path_,
+ max_size_bytes_, true, nullptr, &shared_backend_ptr->data,
+ std::move(create_backend_complete));
+ if (rv != net::ERR_IO_PENDING) {
+ DidCreateBackend(shared_backend_ptr, rv);
+ }
+}
+
+void GeneratedCodeCache::DidCreateBackend(
+ scoped_refptr<base::RefCountedData<ScopedBackendPtr>> backend_ptr,
+ int rv) {
+ if (rv != net::OK) {
+ backend_state_ = kFailed;
+ // Process pending operations to process any required callbacks.
+ IssuePendingOperations();
+ return;
+ }
+
+ backend_ = std::move(backend_ptr->data);
+ backend_state_ = kInitialized;
+ IssuePendingOperations();
+}
+
+void GeneratedCodeCache::IssuePendingOperations() {
+ DCHECK_EQ(backend_state_, kInitialized);
+ // Issue all the pending operations that were received when creating
+ // the backend.
+ for (auto const& op : pending_ops_) {
+ switch (op->operation()) {
+ case kFetch:
+ FetchEntryImpl(op->key(), op->callback());
+ break;
+ case kWrite:
+ WriteDataImpl(op->key(), op->data());
+ break;
+ case kDelete:
+ DeleteEntryImpl(op->key());
+ break;
+ }
+ }
+ pending_ops_.clear();
+}
+
+void GeneratedCodeCache::WriteDataImpl(
+ const std::string& key,
+ scoped_refptr<net::IOBufferWithSize> buffer) {
+ if (backend_state_ != kInitialized)
+ return;
+
+ scoped_refptr<base::RefCountedData<disk_cache::Entry*>> entry_ptr =
+ new base::RefCountedData<disk_cache::Entry*>();
+ net::CompletionOnceCallback callback =
+ base::BindOnce(&GeneratedCodeCache::OpenCompleteForWriteData,
+ weak_ptr_factory_.GetWeakPtr(), buffer, key, entry_ptr);
+
+ int result =
+ backend_->OpenEntry(key, net::LOW, &entry_ptr->data, std::move(callback));
+ if (result != net::ERR_IO_PENDING) {
+ OpenCompleteForWriteData(buffer, key, entry_ptr, result);
+ }
+}
+
+void GeneratedCodeCache::OpenCompleteForWriteData(
+ scoped_refptr<net::IOBufferWithSize> buffer,
+ const std::string& key,
+ scoped_refptr<base::RefCountedData<disk_cache::Entry*>> entry,
+ int rv) {
+ if (rv != net::OK) {
+ net::CompletionOnceCallback callback =
+ base::BindOnce(&GeneratedCodeCache::CreateCompleteForWriteData,
+ weak_ptr_factory_.GetWeakPtr(), buffer, entry);
+
+ int result =
+ backend_->CreateEntry(key, net::LOW, &entry->data, std::move(callback));
+ if (result != net::ERR_IO_PENDING) {
+ CreateCompleteForWriteData(buffer, entry, result);
+ }
+ return;
+ }
+
+ DCHECK(entry->data);
+ disk_cache::ScopedEntryPtr disk_entry(entry->data);
+
+ // This call will truncate the data. This is safe to do since we read the
+ // entire data at the same time currently. If we want to read in parts we have
+ // to doom the entry first.
+ disk_entry->WriteData(kDataIndex, 0, buffer.get(), buffer->size(),
+ net::CompletionOnceCallback(), true);
+}
+
+void GeneratedCodeCache::CreateCompleteForWriteData(
+ scoped_refptr<net::IOBufferWithSize> buffer,
+ scoped_refptr<base::RefCountedData<disk_cache::Entry*>> entry,
+ int rv) {
+ if (rv != net::OK)
+ return;
+
+ DCHECK(entry->data);
+ disk_cache::ScopedEntryPtr disk_entry(entry->data);
+ disk_entry->WriteData(kDataIndex, 0, buffer.get(), buffer->size(),
+ net::CompletionOnceCallback(), true);
+}
+
+void GeneratedCodeCache::FetchEntryImpl(const std::string& key,
+ ReadDataCallback read_data_callback) {
+ if (backend_state_ != kInitialized) {
+ std::move(read_data_callback).Run(scoped_refptr<net::IOBufferWithSize>());
+ return;
+ }
+
+ scoped_refptr<base::RefCountedData<disk_cache::Entry*>> entry_ptr =
+ new base::RefCountedData<disk_cache::Entry*>();
+
+ net::CompletionOnceCallback callback = base::BindOnce(
+ &GeneratedCodeCache::OpenCompleteForReadData,
+ weak_ptr_factory_.GetWeakPtr(), read_data_callback, entry_ptr);
+
+ // This is a part of loading cycle and hence should run with a high priority.
+ int result = backend_->OpenEntry(key, net::HIGHEST, &entry_ptr->data,
+ std::move(callback));
+ if (result != net::ERR_IO_PENDING) {
+ OpenCompleteForReadData(read_data_callback, entry_ptr, result);
+ }
+}
+
+void GeneratedCodeCache::OpenCompleteForReadData(
+ ReadDataCallback read_data_callback,
+ scoped_refptr<base::RefCountedData<disk_cache::Entry*>> entry,
+ int rv) {
+ if (rv != net::OK) {
+ std::move(read_data_callback).Run(scoped_refptr<net::IOBufferWithSize>());
+ return;
+ }
+
+ // There should be a valid entry if the open was successful.
+ DCHECK(entry->data);
+
+ disk_cache::ScopedEntryPtr disk_entry(entry->data);
+ int size = disk_entry->GetDataSize(kDataIndex);
+ scoped_refptr<net::IOBufferWithSize> buffer(new net::IOBufferWithSize(size));
+ net::CompletionOnceCallback callback = base::BindOnce(
+ &GeneratedCodeCache::ReadDataComplete, weak_ptr_factory_.GetWeakPtr(),
+ read_data_callback, buffer);
+ int result = disk_entry->ReadData(kDataIndex, 0, buffer.get(), size,
+ std::move(callback));
+ if (result != net::ERR_IO_PENDING) {
+ ReadDataComplete(read_data_callback, buffer, result);
+ }
+}
+
+void GeneratedCodeCache::ReadDataComplete(
+ ReadDataCallback callback,
+ scoped_refptr<net::IOBufferWithSize> buffer,
+ int rv) {
+ if (rv != buffer->size()) {
+ std::move(callback).Run(scoped_refptr<net::IOBufferWithSize>());
+ } else {
+ std::move(callback).Run(buffer);
+ }
+}
+
+void GeneratedCodeCache::DeleteEntryImpl(const std::string& key) {
+ if (backend_state_ != kInitialized)
+ return;
+
+ backend_->DoomEntry(key, net::LOWEST, net::CompletionOnceCallback());
+}
+
+} // namespace content
diff --git a/chromium/content/browser/code_cache/generated_code_cache.h b/chromium/content/browser/code_cache/generated_code_cache.h
new file mode 100644
index 00000000000..57e92b76946
--- /dev/null
+++ b/chromium/content/browser/code_cache/generated_code_cache.h
@@ -0,0 +1,125 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_CODE_CACHE_GENERATED_CODE_CACHE_H_
+#define CONTENT_BROWSER_CODE_CACHE_GENERATED_CODE_CACHE_H_
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+#include "net/base/io_buffer.h"
+#include "net/disk_cache/disk_cache.h"
+#include "url/origin.h"
+
+namespace content {
+
+// Cache for storing generated code from the renderer on the disk.
+// This cache is keyed on two keys: |resource_url| and |requesting_origin|.
+// The |resource_url| is the url of the resource that was requested and the
+// |requesting_origin| is the origin that requested this resource. This origin
+// is used to enforce site isolation policy on stored code. We don't cache the
+// code corresponding to unique origins or invalid URLs.
+//
+// This uses a simple disk_cache backend. It just stores one data stream and
+// stores response_time + generated code as one data blob.
+// TODO(mythria): Update this comment if the design changes.
+//
+// There exists one cache per storage partition and is owned by the storage
+// partition. This cache is created, accessed and destroyed on the I/O thread.
+class CONTENT_EXPORT GeneratedCodeCache {
+ public:
+ using ReadDataCallback =
+ base::RepeatingCallback<void(scoped_refptr<net::IOBufferWithSize>)>;
+
+ // Creates a GeneratedCodeCache with the specified path and the maximum size.
+ static std::unique_ptr<GeneratedCodeCache> Create(const base::FilePath& path,
+ int max_size);
+
+ ~GeneratedCodeCache();
+
+ // Writes data to the cache. If there is an entry corresponding to
+ // <|url|, |origin|> this overwrites the existing data. If there is no entry
+ // it creates a new one.
+ void WriteData(const GURL& url,
+ const url::Origin& origin,
+ scoped_refptr<net::IOBufferWithSize>);
+
+ // Fetch entry corresponding to <url, origin> from the cache and pass
+ // it using the ReadDataCallback.
+ void FetchEntry(const GURL& url, const url::Origin& origin, ReadDataCallback);
+
+ // Delete the entry corresponding to <url, origin>
+ void DeleteEntry(const GURL& url, const url::Origin& origin);
+
+ const base::FilePath& path() const { return path_; }
+
+ private:
+ class PendingOperation;
+ using ScopedBackendPtr = std::unique_ptr<disk_cache::Backend>;
+
+ // State of the backend.
+ enum BackendState { kUnInitialized, kInitializing, kInitialized, kFailed };
+
+ // The operation requested.
+ enum Operation { kFetch, kWrite, kDelete };
+
+ // Data streams corresponding to each entry.
+ enum { kDataIndex = 1 };
+
+ GeneratedCodeCache(const base::FilePath& path, int max_size_bytes);
+
+ // Creates a simple_disk_cache backend.
+ void CreateBackend();
+ void DidCreateBackend(
+ scoped_refptr<base::RefCountedData<ScopedBackendPtr>> backend_ptr,
+ int rv);
+
+ // The requests that are received while tha backend is being initialized
+ // are recorded in pending operations list. This function issues all pending
+ // operations.
+ void IssuePendingOperations();
+
+ // Write entry to cache
+ void WriteDataImpl(const std::string& key,
+ scoped_refptr<net::IOBufferWithSize> buffer);
+ void OpenCompleteForWriteData(
+ scoped_refptr<net::IOBufferWithSize> buffer,
+ const std::string& key,
+ scoped_refptr<base::RefCountedData<disk_cache::Entry*>> entry,
+ int rv);
+ void CreateCompleteForWriteData(
+ scoped_refptr<net::IOBufferWithSize> buffer,
+ scoped_refptr<base::RefCountedData<disk_cache::Entry*>> entry,
+ int rv);
+
+ // Fetch entry from cache
+ void FetchEntryImpl(const std::string& key, ReadDataCallback);
+ void OpenCompleteForReadData(
+ ReadDataCallback callback,
+ scoped_refptr<base::RefCountedData<disk_cache::Entry*>> entry,
+ int rv);
+ void ReadDataComplete(ReadDataCallback callback,
+ scoped_refptr<net::IOBufferWithSize> buffer,
+ int rv);
+
+ // Delete entry from cache
+ void DeleteEntryImpl(const std::string& key);
+
+ std::unique_ptr<disk_cache::Backend> backend_;
+ BackendState backend_state_;
+
+ std::vector<std::unique_ptr<PendingOperation>> pending_ops_;
+
+ base::FilePath path_;
+ int max_size_bytes_;
+
+ base::WeakPtrFactory<GeneratedCodeCache> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(GeneratedCodeCache);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_CODE_CACHE_GENERATED_CODE_CACHE_H_
diff --git a/chromium/content/browser/code_cache/generated_code_cache_unittest.cc b/chromium/content/browser/code_cache/generated_code_cache_unittest.cc
new file mode 100644
index 00000000000..45ea2246f85
--- /dev/null
+++ b/chromium/content/browser/code_cache/generated_code_cache_unittest.cc
@@ -0,0 +1,293 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/code_cache/generated_code_cache.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/test/scoped_task_environment.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace content {
+
+class GeneratedCodeCacheTest : public testing::Test {
+ public:
+ static const int kMaxSizeInBytes = 1024 * 1024;
+ static constexpr char kInitialUrl[] = "http://example.com/script.js";
+ static constexpr char kInitialOrigin[] = "http://example.com";
+ static constexpr char kInitialData[] = "InitialData";
+
+ GeneratedCodeCacheTest() = default;
+
+ void SetUp() override {
+ ASSERT_TRUE(cache_dir_.CreateUniqueTempDir());
+ cache_path_ = cache_dir_.GetPath();
+ generated_code_cache_ =
+ GeneratedCodeCache::Create(cache_path_, kMaxSizeInBytes);
+ }
+
+ void TearDown() override {
+ disk_cache::FlushCacheThreadForTesting();
+ scoped_task_environment_.RunUntilIdle();
+ }
+
+ // This function initializes the cache and waits till the transaction is
+ // finished. When this function returns, the backend is already initialized.
+ void InitializeCache() {
+ GURL url(kInitialUrl);
+ url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+ WriteToCache(url, origin, kInitialData);
+ scoped_task_environment_.RunUntilIdle();
+ }
+
+ // This function initializes the cache and reopens it. When this function
+ // returns, the backend initialization is not complete yet. This is used
+ // to test the pending operaions path.
+ void InitializeCacheAndReOpen() {
+ InitializeCache();
+ generated_code_cache_.reset();
+ generated_code_cache_ =
+ GeneratedCodeCache::Create(cache_path_, kMaxSizeInBytes);
+ }
+
+ void WriteToCache(const GURL& url,
+ const url::Origin& origin,
+ const std::string& data) {
+ scoped_refptr<net::IOBufferWithSize> buffer(
+ new net::IOBufferWithSize(data.length()));
+ memcpy(buffer->data(), data.c_str(), data.length());
+ generated_code_cache_->WriteData(url, origin, buffer);
+ }
+
+ void DeleteFromCache(const GURL& url, const url::Origin& origin) {
+ generated_code_cache_->DeleteEntry(url, origin);
+ }
+
+ void FetchFromCache(const GURL& url, const url::Origin& origin) {
+ received_ = false;
+ GeneratedCodeCache::ReadDataCallback callback = base::BindRepeating(
+ &GeneratedCodeCacheTest::FetchEntryCallback, base::Unretained(this));
+ generated_code_cache_->FetchEntry(url, origin, callback);
+ }
+
+ void FetchEntryCallback(scoped_refptr<net::IOBufferWithSize> buffer) {
+ if (!buffer || !buffer->data()) {
+ received_ = true;
+ received_null_ = true;
+ return;
+ }
+ std::string str(buffer->data(), buffer->size());
+ received_ = true;
+ received_null_ = false;
+ received_data_ = str;
+ }
+
+ protected:
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ std::unique_ptr<GeneratedCodeCache> generated_code_cache_;
+ base::ScopedTempDir cache_dir_;
+ std::string received_data_;
+ bool received_;
+ bool received_null_;
+ base::FilePath cache_path_;
+};
+
+constexpr char GeneratedCodeCacheTest::kInitialUrl[];
+constexpr char GeneratedCodeCacheTest::kInitialOrigin[];
+constexpr char GeneratedCodeCacheTest::kInitialData[];
+
+TEST_F(GeneratedCodeCacheTest, FetchEntry) {
+ GURL url(kInitialUrl);
+ url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+
+ InitializeCache();
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+
+ ASSERT_TRUE(received_);
+ EXPECT_EQ(kInitialData, received_data_);
+}
+
+TEST_F(GeneratedCodeCacheTest, WriteEntry) {
+ GURL new_url("http://example1.com/script.js");
+ url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+
+ InitializeCache();
+ std::string data = "SerializedCodeForScript";
+ WriteToCache(new_url, origin, data);
+ FetchFromCache(new_url, origin);
+ scoped_task_environment_.RunUntilIdle();
+
+ ASSERT_TRUE(received_);
+ EXPECT_EQ(data, received_data_);
+}
+
+TEST_F(GeneratedCodeCacheTest, DeleteEntry) {
+ GURL url(kInitialUrl);
+ url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+
+ InitializeCache();
+ DeleteFromCache(url, origin);
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+
+ ASSERT_TRUE(received_);
+ ASSERT_TRUE(received_null_);
+}
+
+TEST_F(GeneratedCodeCacheTest, FetchEntryPendingOp) {
+ GURL url(kInitialUrl);
+ url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+
+ InitializeCacheAndReOpen();
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+
+ ASSERT_TRUE(received_);
+ EXPECT_EQ(kInitialData, received_data_);
+}
+
+TEST_F(GeneratedCodeCacheTest, WriteEntryPendingOp) {
+ GURL new_url("http://example1.com/script1.js");
+ url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+
+ InitializeCache();
+ std::string data = "SerializedCodeForScript";
+ WriteToCache(new_url, origin, data);
+ scoped_task_environment_.RunUntilIdle();
+ FetchFromCache(new_url, origin);
+ scoped_task_environment_.RunUntilIdle();
+
+ ASSERT_TRUE(received_);
+ EXPECT_EQ(data, received_data_);
+}
+
+TEST_F(GeneratedCodeCacheTest, DeleteEntryPendingOp) {
+ GURL url(kInitialUrl);
+ url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+
+ InitializeCacheAndReOpen();
+ DeleteFromCache(url, origin);
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+
+ ASSERT_TRUE(received_);
+ ASSERT_TRUE(received_null_);
+}
+
+TEST_F(GeneratedCodeCacheTest, UpdateDataOfExistingEntry) {
+ GURL url(kInitialUrl);
+ url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+
+ InitializeCache();
+ std::string new_data = "SerializedCodeForScriptOverwrite";
+ WriteToCache(url, origin, new_data);
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+
+ ASSERT_TRUE(received_);
+ EXPECT_EQ(new_data, received_data_);
+}
+
+TEST_F(GeneratedCodeCacheTest, FetchFailsForNonexistingOrigin) {
+ InitializeCache();
+ url::Origin new_origin = url::Origin::Create(GURL("http://not-example.com"));
+ FetchFromCache(GURL(kInitialUrl), new_origin);
+ scoped_task_environment_.RunUntilIdle();
+
+ ASSERT_TRUE(received_);
+ ASSERT_TRUE(received_null_);
+}
+
+TEST_F(GeneratedCodeCacheTest, FetchEntriesFromSameOrigin) {
+ GURL url("http://example.com/script.js");
+ GURL second_url("http://script.com/one.js");
+ url::Origin origin = url::Origin::Create(GURL(kInitialOrigin));
+
+ std::string data_first_resource = "SerializedCodeForFirstResource";
+ WriteToCache(url, origin, data_first_resource);
+
+ std::string data_second_resource = "SerializedCodeForSecondResource";
+ WriteToCache(second_url, origin, data_second_resource);
+ scoped_task_environment_.RunUntilIdle();
+
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+ ASSERT_TRUE(received_);
+ EXPECT_EQ(data_first_resource, received_data_);
+
+ FetchFromCache(second_url, origin);
+ scoped_task_environment_.RunUntilIdle();
+ ASSERT_TRUE(received_);
+ EXPECT_EQ(data_second_resource, received_data_);
+}
+
+TEST_F(GeneratedCodeCacheTest, FetchSucceedsFromDifferentOrigins) {
+ GURL url("http://example.com/script.js");
+ url::Origin origin = url::Origin::Create(GURL("http://example.com"));
+ url::Origin origin1 = url::Origin::Create(GURL("http://example1.com"));
+
+ std::string data_origin = "SerializedCodeForFirstOrigin";
+ WriteToCache(url, origin, data_origin);
+
+ std::string data_origin1 = "SerializedCodeForSecondOrigin";
+ WriteToCache(url, origin1, data_origin1);
+ scoped_task_environment_.RunUntilIdle();
+
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+ ASSERT_TRUE(received_);
+ EXPECT_EQ(data_origin, received_data_);
+
+ FetchFromCache(url, origin1);
+ scoped_task_environment_.RunUntilIdle();
+ ASSERT_TRUE(received_);
+ EXPECT_EQ(data_origin1, received_data_);
+}
+
+TEST_F(GeneratedCodeCacheTest, FetchFailsForUniqueOrigin) {
+ GURL url("http://example.com/script.js");
+ url::Origin origin =
+ url::Origin::Create(GURL("data:text/html,<script></script>"));
+
+ std::string data = "SerializedCodeForUniqueOrigin";
+ WriteToCache(url, origin, data);
+ scoped_task_environment_.RunUntilIdle();
+
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+ ASSERT_TRUE(received_);
+ ASSERT_TRUE(received_null_);
+}
+
+TEST_F(GeneratedCodeCacheTest, FetchFailsForInvalidOrigin) {
+ GURL url("http://example.com/script.js");
+ url::Origin origin = url::Origin::Create(GURL("invalidURL"));
+
+ std::string data = "SerializedCodeForInvalidOrigin";
+ WriteToCache(url, origin, data);
+ scoped_task_environment_.RunUntilIdle();
+
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+ ASSERT_TRUE(received_);
+ ASSERT_TRUE(received_null_);
+}
+
+TEST_F(GeneratedCodeCacheTest, FetchFailsForInvalidURL) {
+ GURL url("InvalidURL");
+ url::Origin origin = url::Origin::Create(GURL("http://example.com"));
+
+ std::string data = "SerializedCodeForInvalidURL";
+ WriteToCache(url, origin, data);
+ scoped_task_environment_.RunUntilIdle();
+
+ FetchFromCache(url, origin);
+ scoped_task_environment_.RunUntilIdle();
+ ASSERT_TRUE(received_);
+ ASSERT_TRUE(received_null_);
+}
+} // namespace content
diff --git a/chromium/content/browser/compositor/external_begin_frame_controller_client_impl.cc b/chromium/content/browser/compositor/external_begin_frame_controller_client_impl.cc
deleted file mode 100644
index 13583a06d26..00000000000
--- a/chromium/content/browser/compositor/external_begin_frame_controller_client_impl.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/compositor/external_begin_frame_controller_client_impl.h"
-
-#include "ui/compositor/compositor.h"
-
-namespace content {
-
-ExternalBeginFrameControllerClientImpl::ExternalBeginFrameControllerClientImpl(
- ui::Compositor* compositor)
- : compositor_(compositor), binding_(this) {}
-
-ExternalBeginFrameControllerClientImpl::
- ~ExternalBeginFrameControllerClientImpl() = default;
-
-viz::mojom::ExternalBeginFrameControllerClientPtr
-ExternalBeginFrameControllerClientImpl::GetBoundPtr() {
- viz::mojom::ExternalBeginFrameControllerClientPtr ptr;
- binding_.Bind(mojo::MakeRequest(&ptr));
- return ptr;
-}
-
-viz::mojom::ExternalBeginFrameControllerAssociatedRequest
-ExternalBeginFrameControllerClientImpl::GetControllerRequest() {
- return mojo::MakeRequest(&controller_);
-}
-
-viz::mojom::ExternalBeginFrameControllerAssociatedPtr&
-ExternalBeginFrameControllerClientImpl::GetController() {
- return controller_;
-}
-
-void ExternalBeginFrameControllerClientImpl::OnNeedsBeginFrames(
- bool needs_begin_frames) {
- compositor_->OnNeedsExternalBeginFrames(needs_begin_frames);
-}
-
-void ExternalBeginFrameControllerClientImpl::OnDisplayDidFinishFrame(
- const viz::BeginFrameAck& ack) {
- compositor_->OnDisplayDidFinishFrame(ack);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/compositor/external_begin_frame_controller_client_impl.h b/chromium/content/browser/compositor/external_begin_frame_controller_client_impl.h
deleted file mode 100644
index 9ecd0ae4882..00000000000
--- a/chromium/content/browser/compositor/external_begin_frame_controller_client_impl.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_COMPOSITOR_EXTERNAL_BEGIN_FRAME_CONTROLLER_CLIENT_IMPL_H_
-#define CONTENT_BROWSER_COMPOSITOR_EXTERNAL_BEGIN_FRAME_CONTROLLER_CLIENT_IMPL_H_
-
-#include "mojo/public/cpp/bindings/binding.h"
-#include "services/viz/privileged/interfaces/compositing/external_begin_frame_controller.mojom.h"
-
-namespace ui {
-class Compositor;
-} // namespace ui
-
-namespace content {
-
-// ExternalBeginFrameControllerClient implementation that notifies a
-// ui::Compositor about BeginFrame events.
-class ExternalBeginFrameControllerClientImpl
- : public viz::mojom::ExternalBeginFrameControllerClient {
- public:
- explicit ExternalBeginFrameControllerClientImpl(ui::Compositor* compositor);
- ~ExternalBeginFrameControllerClientImpl() override;
-
- viz::mojom::ExternalBeginFrameControllerClientPtr GetBoundPtr();
-
- viz::mojom::ExternalBeginFrameControllerAssociatedRequest
- GetControllerRequest();
-
- viz::mojom::ExternalBeginFrameControllerAssociatedPtr& GetController();
-
- private:
- // viz::ExternalBeginFrameControllerClient implementation.
- void OnNeedsBeginFrames(bool needs_begin_frames) override;
- void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) override;
-
- ui::Compositor* compositor_;
-
- mojo::Binding<viz::mojom::ExternalBeginFrameControllerClient> binding_;
- viz::mojom::ExternalBeginFrameControllerAssociatedPtr controller_;
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_COMPOSITOR_GPU_PROCESS_TRANSPORT_FACTORY_H_
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 34fbb3a9521..15226b0f4d7 100644
--- a/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.cc
@@ -38,19 +38,16 @@ GpuBrowserCompositorOutputSurface::GpuBrowserCompositorOutputSurface(
}
capabilities_.supports_stencil =
context_provider()->ContextCapabilities().num_stencil_bits > 0;
+ // Since one of the buffers is used by the surface for presentation, there can
+ // be at most |num_surface_buffers - 1| pending buffers that the compositor
+ // can use.
+ capabilities_.max_frames_pending =
+ context_provider()->ContextCapabilities().num_surface_buffers - 1;
}
GpuBrowserCompositorOutputSurface::~GpuBrowserCompositorOutputSurface() =
default;
-void GpuBrowserCompositorOutputSurface::SetNeedsVSync(bool needs_vsync) {
-#if defined(OS_WIN)
- GetCommandBufferProxy()->SetNeedsVSync(needs_vsync);
-#else
- NOTREACHED();
-#endif // defined(OS_WIN)
-}
-
void GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
std::vector<ui::LatencyInfo> latency_info,
const gpu::SwapBuffersCompleteParams& params) {
@@ -60,7 +57,6 @@ void GpuBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted(
client_->DidReceiveTextureInUseResponses(params.texture_in_use_responses);
client_->DidReceiveSwapBuffersAck();
UpdateLatencyInfoOnSwap(params.swap_response, &latency_info);
- RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(latency_info);
latency_tracker_.OnGpuSwapBuffersCompleted(latency_info);
}
@@ -110,9 +106,6 @@ void GpuBrowserCompositorOutputSurface::Reshape(
void GpuBrowserCompositorOutputSurface::SwapBuffers(
viz::OutputSurfaceFrame frame) {
- if (LatencyInfoHasSnapshotRequest(frame.latency_info))
- GetCommandBufferProxy()->SetSnapshotRequested();
-
gfx::Size surface_size = frame.size;
if (reflector_) {
if (frame.sub_buffer_rect && reflector_texture_defined_) {
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 1ec2b3e3fdf..67ef5d40f1c 100644
--- a/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h
+++ b/chromium/content/browser/compositor/gpu_browser_compositor_output_surface.h
@@ -10,7 +10,6 @@
#include "base/macros.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"
#include "gpu/vulkan/buildflags.h"
#include "ui/gfx/swap_result.h"
#include "ui/latency/latency_tracker.h"
@@ -38,8 +37,8 @@ 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:
GpuBrowserCompositorOutputSurface(
scoped_refptr<ui::ContextProviderCommandBuffer> context,
@@ -76,8 +75,6 @@ class GpuBrowserCompositorOutputSurface : public BrowserCompositorOutputSurface,
void SetDrawRectangle(const gfx::Rect& rect) override;
- // GpuVSyncControl implementation.
- void SetNeedsVSync(bool needs_vsync) override;
#if BUILDFLAG(ENABLE_VULKAN)
gpu::VulkanSurface* GetVulkanSurface() override;
#endif
diff --git a/chromium/content/browser/compositor/gpu_process_transport_factory.cc b/chromium/content/browser/compositor/gpu_process_transport_factory.cc
index e679dbb02a8..511d805187b 100644
--- a/chromium/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/chromium/content/browser/compositor/gpu_process_transport_factory.cc
@@ -16,6 +16,7 @@
#include "base/single_thread_task_runner.h"
#include "base/threading/simple_thread.h"
#include "base/threading/thread.h"
+#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "cc/base/histograms.h"
@@ -27,22 +28,21 @@
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
#include "components/viz/common/gl_helper.h"
#include "components/viz/common/switches.h"
+#include "components/viz/host/host_display_client.h"
#include "components/viz/host/host_frame_sink_manager.h"
#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_embedder/compositing_mode_reporter_impl.h"
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator.h"
-#include "components/viz/service/display_embedder/external_begin_frame_controller_impl.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h"
+#include "components/viz/service/frame_sinks/external_begin_frame_source_mojo.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/compositor/browser_compositor_output_surface.h"
-#include "content/browser/compositor/external_begin_frame_controller_client_impl.h"
#include "content/browser/compositor/gpu_browser_compositor_output_surface.h"
#include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h"
-#include "content/browser/compositor/in_process_display_client.h"
#include "content/browser/compositor/offscreen_browser_compositor_output_surface.h"
#include "content/browser/compositor/reflector_impl.h"
#include "content/browser/compositor/software_browser_compositor_output_surface.h"
@@ -69,6 +69,7 @@
#include "ui/base/ui_base_switches_util.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_switches.h"
+#include "ui/compositor/host/external_begin_frame_controller_client_impl.h"
#include "ui/compositor/layer.h"
#include "ui/display/display_switches.h"
#include "ui/display/types/display_snapshot.h"
@@ -115,7 +116,7 @@
#if BUILDFLAG(ENABLE_VULKAN)
#include "components/viz/common/gpu/vulkan_in_process_context_provider.h"
#include "content/browser/compositor/vulkan_browser_compositor_output_surface.h"
-#include "gpu/vulkan/init/vulkan_factory.cc"
+#include "gpu/vulkan/init/vulkan_factory.h"
#endif
using viz::ContextProvider;
@@ -127,17 +128,6 @@ namespace {
// from RenderWidgetHostImpl.
constexpr uint32_t kDefaultClientId = 0u;
-bool IsGpuVSyncSignalSupported() {
-#if defined(OS_WIN)
- // TODO(stanisc): http://crbug.com/467617 Limit to Windows 8.1+ for now
- // because of locking issue caused by waiting for VSync on Win7 and Win 8.0.
- return base::win::GetVersion() >= base::win::VERSION_WIN8_1 &&
- base::FeatureList::IsEnabled(features::kD3DVsync);
-#else
- return false;
-#endif // defined(OS_WIN)
-}
-
#if defined(OS_MACOSX)
bool IsCALayersDisabledFromCommandLine() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
@@ -160,14 +150,12 @@ namespace content {
struct GpuProcessTransportFactory::PerCompositorData {
gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
BrowserCompositorOutputSurface* display_output_surface = nullptr;
- // Exactly one of |synthetic_begin_frame_source|,
- // |gpu_vsync_begin_frame_source|, and |external_begin_frame_source| is valid
- // at the same time.
+ // Exactly one of |synthetic_begin_frame_source| and
+ // |external_begin_frame_source| is valid at the same time.
std::unique_ptr<viz::SyntheticBeginFrameSource> synthetic_begin_frame_source;
- std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
- std::unique_ptr<viz::ExternalBeginFrameControllerImpl>
- external_begin_frame_controller;
- std::unique_ptr<ExternalBeginFrameControllerClientImpl>
+ std::unique_ptr<viz::ExternalBeginFrameSourceMojo>
+ external_begin_frame_source_mojo;
+ std::unique_ptr<ui::ExternalBeginFrameControllerClientImpl>
external_begin_frame_controller_client;
ReflectorImpl* reflector = nullptr;
std::unique_ptr<viz::Display> display;
@@ -178,6 +166,7 @@ struct GpuProcessTransportFactory::PerCompositorData {
GpuProcessTransportFactory::GpuProcessTransportFactory(
gpu::GpuChannelEstablishFactory* gpu_channel_factory,
viz::CompositingModeReporterImpl* compositing_mode_reporter,
+ viz::ServerSharedBitmapManager* server_shared_bitmap_manager,
scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner)
: frame_sink_id_allocator_(kDefaultClientId),
renderer_settings_(viz::CreateRendererSettings()),
@@ -185,9 +174,9 @@ GpuProcessTransportFactory::GpuProcessTransportFactory(
task_graph_runner_(new cc::SingleThreadTaskGraphRunner),
gpu_channel_factory_(gpu_channel_factory),
compositing_mode_reporter_(compositing_mode_reporter),
+ server_shared_bitmap_manager_(server_shared_bitmap_manager),
callback_factory_(this) {
DCHECK(gpu_channel_factory_);
- cc::SetClientNameForMetrics("Browser");
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kDisableFrameRateLimit))
@@ -229,7 +218,7 @@ GpuProcessTransportFactory::CreateSoftwareOutputDevice(
return base::WrapUnique(new viz::SoftwareOutputDevice);
#if defined(USE_AURA)
- if (base::FeatureList::IsEnabled(features::kMash)) {
+ if (!features::IsAshInBrowserProcess()) {
NOTREACHED();
return nullptr;
}
@@ -412,7 +401,7 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
gpu_channel_host, gpu::kNullSurfaceHandle, need_alpha_channel,
false /* support_stencil */, support_locking, support_gles2_interface,
support_raster_interface, support_grcontext,
- ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT);
+ ui::command_buffer_metrics::ContextType::BROWSER_WORKER);
auto result = shared_worker_context_provider_->BindToCurrentThread();
if (result != gpu::ContextResult::kSuccess) {
shared_worker_context_provider_ = nullptr;
@@ -439,7 +428,7 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
std::move(gpu_channel_host), surface_handle, need_alpha_channel,
support_stencil, support_locking, support_gles2_interface,
support_raster_interface, support_grcontext,
- ui::command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT);
+ ui::command_buffer_metrics::ContextType::BROWSER_COMPOSITOR);
// On Mac, GpuCommandBufferMsg_SwapBuffersCompleted must be handled in
// a nested run loop during resize.
context_provider->SetDefaultTaskRunner(resize_task_runner_);
@@ -479,8 +468,6 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
BrowserCompositorOutputSurface::UpdateVSyncParametersCallback vsync_callback =
base::Bind(&ui::Compositor::SetDisplayVSyncParameters, compositor);
- GpuVSyncControl* gpu_vsync_control = nullptr;
-
std::unique_ptr<BrowserCompositorOutputSurface> display_output_surface;
#if BUILDFLAG(ENABLE_VULKAN)
std::unique_ptr<VulkanBrowserCompositorOutputSurface> vulkan_surface;
@@ -540,7 +527,6 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
GL_TEXTURE_2D, GL_BGRA_EXT,
display::DisplaySnapshot::PrimaryFormat(),
GetGpuMemoryBufferManager());
- gpu_vsync_control = gpu_output_surface.get();
display_output_surface = std::move(gpu_output_surface);
#endif
} else {
@@ -556,7 +542,6 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
std::make_unique<GpuBrowserCompositorOutputSurface>(
context_provider, std::move(vsync_callback),
std::move(validator));
- gpu_vsync_control = gpu_output_surface.get();
display_output_surface = std::move(gpu_output_surface);
}
}
@@ -567,26 +552,25 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
data->reflector->OnSourceSurfaceReady(data->display_output_surface);
std::unique_ptr<viz::SyntheticBeginFrameSource> synthetic_begin_frame_source;
- std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
- std::unique_ptr<viz::ExternalBeginFrameControllerImpl>
- external_begin_frame_controller;
- std::unique_ptr<ExternalBeginFrameControllerClientImpl>
+ std::unique_ptr<viz::ExternalBeginFrameSourceMojo>
+ external_begin_frame_source_mojo;
+ std::unique_ptr<ui::ExternalBeginFrameControllerClientImpl>
external_begin_frame_controller_client;
viz::BeginFrameSource* begin_frame_source = nullptr;
if (compositor->external_begin_frames_enabled()) {
external_begin_frame_controller_client =
- std::make_unique<ExternalBeginFrameControllerClientImpl>(
+ std::make_unique<ui::ExternalBeginFrameControllerClientImpl>(
compositor.get());
// We don't bind the controller mojo interface, since we only use the
- // ExternalBeginFrameControllerImpl directly and not via mojo (plus, as it
+ // ExternalBeginFrameSourceMojo directly and not via mojo (plus, as it
// is an associated interface, binding it would require a separate pipe).
viz::mojom::ExternalBeginFrameControllerAssociatedRequest request = nullptr;
- external_begin_frame_controller =
- std::make_unique<viz::ExternalBeginFrameControllerImpl>(
+ external_begin_frame_source_mojo =
+ std::make_unique<viz::ExternalBeginFrameSourceMojo>(
std::move(request),
external_begin_frame_controller_client->GetBoundPtr());
- begin_frame_source = external_begin_frame_controller->begin_frame_source();
+ begin_frame_source = external_begin_frame_source_mojo.get();
} else if (disable_frame_rate_limit_) {
synthetic_begin_frame_source =
std::make_unique<viz::BackToBackBeginFrameSource>(
@@ -594,18 +578,12 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
compositor->task_runner().get()));
begin_frame_source = synthetic_begin_frame_source.get();
} else {
- if (gpu_vsync_control && IsGpuVSyncSignalSupported()) {
- gpu_vsync_begin_frame_source =
- std::make_unique<GpuVSyncBeginFrameSource>(gpu_vsync_control);
- begin_frame_source = gpu_vsync_begin_frame_source.get();
- } else {
synthetic_begin_frame_source =
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();
- }
}
#if defined(OS_WIN)
@@ -615,13 +593,10 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
if (data->synthetic_begin_frame_source) {
GetFrameSinkManager()->UnregisterBeginFrameSource(
data->synthetic_begin_frame_source.get());
- } else if (data->gpu_vsync_begin_frame_source) {
- GetFrameSinkManager()->UnregisterBeginFrameSource(
- data->gpu_vsync_begin_frame_source.get());
- } else if (data->external_begin_frame_controller) {
+ } else if (data->external_begin_frame_source_mojo) {
GetFrameSinkManager()->UnregisterBeginFrameSource(
- data->external_begin_frame_controller->begin_frame_source());
- data->external_begin_frame_controller->SetDisplay(nullptr);
+ data->external_begin_frame_source_mojo.get());
+ data->external_begin_frame_source_mojo->SetDisplay(nullptr);
}
auto scheduler = std::make_unique<viz::DisplayScheduler>(
@@ -631,23 +606,22 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
// The Display owns and uses the |display_output_surface| created above.
data->display = std::make_unique<viz::Display>(
- viz::ServerSharedBitmapManager::current(), renderer_settings_,
+ server_shared_bitmap_manager_, renderer_settings_,
compositor->frame_sink_id(), std::move(display_output_surface),
std::move(scheduler), compositor->task_runner());
data->display_client =
- std::make_unique<InProcessDisplayClient>(compositor->widget());
+ std::make_unique<viz::HostDisplayClient>(compositor->widget());
GetFrameSinkManager()->RegisterBeginFrameSource(begin_frame_source,
compositor->frame_sink_id());
// Note that we are careful not to destroy prior BeginFrameSource objects
// until we have reset |data->display|.
data->synthetic_begin_frame_source = std::move(synthetic_begin_frame_source);
- data->gpu_vsync_begin_frame_source = std::move(gpu_vsync_begin_frame_source);
- data->external_begin_frame_controller =
- std::move(external_begin_frame_controller);
+ data->external_begin_frame_source_mojo =
+ std::move(external_begin_frame_source_mojo);
data->external_begin_frame_controller_client =
std::move(external_begin_frame_controller_client);
- if (data->external_begin_frame_controller)
- data->external_begin_frame_controller->SetDisplay(data->display.get());
+ if (data->external_begin_frame_source_mojo)
+ data->external_begin_frame_source_mojo->SetDisplay(data->display.get());
// The |delegated_output_surface| is given back to the compositor, it
// delegates to the Display as its root surface. Importantly, it shares the
@@ -750,13 +724,10 @@ void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
if (data->synthetic_begin_frame_source) {
GetFrameSinkManager()->UnregisterBeginFrameSource(
data->synthetic_begin_frame_source.get());
- } else if (data->gpu_vsync_begin_frame_source) {
- GetFrameSinkManager()->UnregisterBeginFrameSource(
- data->gpu_vsync_begin_frame_source.get());
- } else if (data->external_begin_frame_controller) {
+ } else if (data->external_begin_frame_source_mojo) {
GetFrameSinkManager()->UnregisterBeginFrameSource(
- data->external_begin_frame_controller->begin_frame_source());
- data->external_begin_frame_controller->SetDisplay(nullptr);
+ data->external_begin_frame_source_mojo.get());
+ data->external_begin_frame_source_mojo->SetDisplay(nullptr);
}
per_compositor_data_.erase(it);
if (per_compositor_data_.empty()) {
@@ -770,7 +741,7 @@ void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
// If there are any observer left at this point, make sure they clean up
// before we destroy the GLHelper.
for (auto& observer : observer_list_)
- observer.OnLostResources();
+ observer.OnLostSharedContext();
helper.reset();
DCHECK(!gl_helper_) << "Destroying the GLHelper should not cause a new "
@@ -795,6 +766,11 @@ cc::TaskGraphRunner* GpuProcessTransportFactory::GetTaskGraphRunner() {
return task_graph_runner_.get();
}
+void GpuProcessTransportFactory::DisableGpuCompositing() {
+ if (!is_gpu_compositing_disabled_)
+ DisableGpuCompositing(nullptr);
+}
+
bool GpuProcessTransportFactory::IsGpuCompositingDisabled() {
return is_gpu_compositing_disabled_;
}
@@ -841,6 +817,17 @@ void GpuProcessTransportFactory::ResizeDisplay(ui::Compositor* compositor,
data->display->Resize(size);
}
+void GpuProcessTransportFactory::DisableSwapUntilResize(
+ ui::Compositor* compositor) {
+ PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ if (it == per_compositor_data_.end())
+ return;
+ PerCompositorData* data = it->second.get();
+ DCHECK(data);
+ if (data->display)
+ data->display->Resize(gfx::Size());
+}
+
void GpuProcessTransportFactory::SetDisplayColorMatrix(
ui::Compositor* compositor,
const SkMatrix44& matrix) {
@@ -893,8 +880,6 @@ void GpuProcessTransportFactory::SetDisplayVSyncParameters(
if (data->synthetic_begin_frame_source) {
data->synthetic_begin_frame_source->OnUpdateVSyncParameters(timebase,
interval);
- } else if (data->gpu_vsync_begin_frame_source) {
- data->gpu_vsync_begin_frame_source->OnVSync(timebase, interval);
}
}
@@ -906,8 +891,8 @@ void GpuProcessTransportFactory::IssueExternalBeginFrame(
return;
PerCompositorData* data = it->second.get();
DCHECK(data);
- DCHECK(data->external_begin_frame_controller);
- data->external_begin_frame_controller->IssueExternalBeginFrame(args);
+ DCHECK(data->external_begin_frame_source_mojo);
+ data->external_begin_frame_source_mojo->IssueExternalBeginFrame(args);
}
void GpuProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor,
@@ -932,6 +917,12 @@ void GpuProcessTransportFactory::RemoveObserver(
observer_list_.RemoveObserver(observer);
}
+bool GpuProcessTransportFactory::SyncTokensRequiredForDisplayCompositor() {
+ // Display and DirectLayerTreeFrameSink share a GL context, so sync
+ // points aren't needed when passing resources between them.
+ return false;
+}
+
viz::FrameSinkManagerImpl* GpuProcessTransportFactory::GetFrameSinkManager() {
return BrowserMainLoop::GetInstance()->GetFrameSinkManager();
}
@@ -977,7 +968,7 @@ GpuProcessTransportFactory::SharedMainThreadContextProvider() {
std::move(gpu_channel_host), gpu::kNullSurfaceHandle, need_alpha_channel,
false, support_locking, support_gles2_interface, support_raster_interface,
support_grcontext,
- ui::command_buffer_metrics::BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT);
+ ui::command_buffer_metrics::ContextType::BROWSER_MAIN_THREAD);
shared_main_thread_contexts_->AddObserver(this);
auto result = shared_main_thread_contexts_->BindToCurrentThread();
if (result != gpu::ContextResult::kSuccess) {
@@ -1028,7 +1019,7 @@ void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
std::unique_ptr<viz::GLHelper> lost_gl_helper = std::move(gl_helper_);
for (auto& observer : observer_list_)
- observer.OnLostResources();
+ observer.OnLostSharedContext();
// Kill things that use the shared context before killing the shared context.
lost_gl_helper.reset();
@@ -1041,6 +1032,7 @@ GpuProcessTransportFactory::SharedVulkanContextProvider() {
if (!shared_vulkan_context_provider_initialized_) {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableVulkan)) {
+ base::ScopedAllowBlocking allow_blocking;
vulkan_implementation_ = gpu::CreateVulkanImplementation();
if (vulkan_implementation_ &&
vulkan_implementation_->InitializeVulkanInstance()) {
diff --git a/chromium/content/browser/compositor/gpu_process_transport_factory.h b/chromium/content/browser/compositor/gpu_process_transport_factory.h
index 02c1ec0d59b..6704fa4bb4c 100644
--- a/chromium/content/browser/compositor/gpu_process_transport_factory.h
+++ b/chromium/content/browser/compositor/gpu_process_transport_factory.h
@@ -47,6 +47,7 @@ class ContextProviderCommandBuffer;
namespace viz {
class CompositingModeReporterImpl;
class OutputDeviceBacking;
+class ServerSharedBitmapManager;
class SoftwareOutputDevice;
class VulkanInProcessContextProvider;
class RasterContextProvider;
@@ -62,6 +63,7 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
GpuProcessTransportFactory(
gpu::GpuChannelEstablishFactory* gpu_channel_factory,
viz::CompositingModeReporterImpl* compositing_mode_reporter,
+ viz::ServerSharedBitmapManager* server_shared_bitmap_manager,
scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner);
~GpuProcessTransportFactory() override;
@@ -76,6 +78,7 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
cc::TaskGraphRunner* GetTaskGraphRunner() override;
void AddObserver(ui::ContextFactoryObserver* observer) override;
void RemoveObserver(ui::ContextFactoryObserver* observer) override;
+ bool SyncTokensRequiredForDisplayCompositor() override;
// ui::ContextFactoryPrivate implementation.
std::unique_ptr<ui::Reflector> CreateReflector(ui::Compositor* source,
@@ -87,6 +90,7 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
void SetDisplayVisible(ui::Compositor* compositor, bool visible) override;
void ResizeDisplay(ui::Compositor* compositor,
const gfx::Size& size) override;
+ void DisableSwapUntilResize(ui::Compositor* compositor) override;
void SetDisplayColorMatrix(ui::Compositor* compositor,
const SkMatrix44& matrix) override;
void SetDisplayColorSpace(ui::Compositor* compositor,
@@ -102,6 +106,7 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
void SetOutputIsSecure(ui::Compositor* compositor, bool secure) override;
// ImageTransportFactory implementation.
+ void DisableGpuCompositing() override;
bool IsGpuCompositingDisabled() override;
ui::ContextFactory* GetContextFactory() override;
ui::ContextFactoryPrivate* GetContextFactoryPrivate() override;
@@ -180,6 +185,8 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
// Service-side impl that controls the compositing mode based on what mode the
// display compositors are using.
viz::CompositingModeReporterImpl* const compositing_mode_reporter_;
+ // Manages a mapping of SharedBitmapId to shared memory objects.
+ viz::ServerSharedBitmapManager* const server_shared_bitmap_manager_;
base::WeakPtrFactory<GpuProcessTransportFactory> callback_factory_;
diff --git a/chromium/content/browser/compositor/gpu_vsync_begin_frame_source.cc b/chromium/content/browser/compositor/gpu_vsync_begin_frame_source.cc
deleted file mode 100644
index d46b8337f35..00000000000
--- a/chromium/content/browser/compositor/gpu_vsync_begin_frame_source.cc
+++ /dev/null
@@ -1,87 +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/compositor/gpu_vsync_begin_frame_source.h"
-
-namespace content {
-
-GpuVSyncBeginFrameSource::GpuVSyncBeginFrameSource(
- GpuVSyncControl* vsync_control)
- : viz::ExternalBeginFrameSource(this),
- vsync_control_(vsync_control),
- needs_begin_frames_(false),
- next_sequence_number_(viz::BeginFrameArgs::kStartingFrameNumber) {
- DCHECK(vsync_control);
-}
-
-GpuVSyncBeginFrameSource::~GpuVSyncBeginFrameSource() = default;
-
-void GpuVSyncBeginFrameSource::OnVSync(base::TimeTicks timestamp,
- base::TimeDelta interval) {
- if (!needs_begin_frames_)
- return;
-
- base::TimeTicks now = Now();
- base::TimeTicks deadline = now.SnappedToNextTick(timestamp, interval);
-
- TRACE_EVENT1("cc", "GpuVSyncBeginFrameSource::OnVSync", "latency",
- (now - timestamp).ToInternalValue());
-
- // Fast forward timestamp to avoid generating BeginFrame with a timestamp
- // that is too far behind. Most of the time it would remain the same.
- timestamp = deadline - interval;
-
- next_sequence_number_++;
-
- // OnBeginFrame can still skip this notification if it is behind
- // last_begin_frame_args_.
- OnBeginFrame(viz::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, source_id(), next_sequence_number_, timestamp,
- deadline, interval, viz::BeginFrameArgs::NORMAL));
-}
-
-void GpuVSyncBeginFrameSource::OnNeedsBeginFrames(bool needs_begin_frames) {
- needs_begin_frames_ = needs_begin_frames;
- vsync_control_->SetNeedsVSync(needs_begin_frames);
-}
-
-base::TimeTicks GpuVSyncBeginFrameSource::Now() const {
- return base::TimeTicks::Now();
-}
-
-viz::BeginFrameArgs GpuVSyncBeginFrameSource::GetMissedBeginFrameArgs(
- viz::BeginFrameObserver* obs) {
- if (!last_begin_frame_args_.IsValid())
- return viz::BeginFrameArgs();
-
- base::TimeTicks now = Now();
- base::TimeTicks estimated_next_timestamp = now.SnappedToNextTick(
- last_begin_frame_args_.frame_time, last_begin_frame_args_.interval);
- base::TimeTicks missed_timestamp =
- estimated_next_timestamp - last_begin_frame_args_.interval;
-
- if (missed_timestamp > last_begin_frame_args_.frame_time) {
- // The projected missed timestamp is newer than the last known timestamp.
- // In this case create BeginFrameArgs with a new sequence number.
- next_sequence_number_++;
- last_begin_frame_args_ = viz::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, source_id(), next_sequence_number_,
- missed_timestamp, estimated_next_timestamp,
- last_begin_frame_args_.interval, viz::BeginFrameArgs::NORMAL);
- }
-
- // The last known args object is up-to-date. Skip sending notification
- // if the observer has already seen it.
- const viz::BeginFrameArgs& last_observer_args = obs->LastUsedBeginFrameArgs();
- if (last_observer_args.IsValid() &&
- last_begin_frame_args_.frame_time <= last_observer_args.frame_time) {
- return viz::BeginFrameArgs();
- }
-
- viz::BeginFrameArgs missed_args = last_begin_frame_args_;
- missed_args.type = viz::BeginFrameArgs::MISSED;
- return missed_args;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/compositor/gpu_vsync_begin_frame_source.h b/chromium/content/browser/compositor/gpu_vsync_begin_frame_source.h
deleted file mode 100644
index 251b69263a6..00000000000
--- a/chromium/content/browser/compositor/gpu_vsync_begin_frame_source.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_COMPOSITOR_GPU_VSYNC_BEGIN_FRAME_SOURCE_H_
-#define CONTENT_BROWSER_COMPOSITOR_GPU_VSYNC_BEGIN_FRAME_SOURCE_H_
-
-#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
-#include "components/viz/common/frame_sinks/begin_frame_source.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-// This class is used to control VSync production on GPU side.
-class CONTENT_EXPORT GpuVSyncControl {
- public:
- virtual void SetNeedsVSync(bool needs_vsync) = 0;
-};
-
-// This is a type of ExternalBeginFrameSource where VSync signals are
-// generated externally on GPU side.
-class CONTENT_EXPORT GpuVSyncBeginFrameSource
- : public viz::ExternalBeginFrameSource,
- public viz::ExternalBeginFrameSourceClient {
- public:
- explicit GpuVSyncBeginFrameSource(GpuVSyncControl* vsync_control);
- ~GpuVSyncBeginFrameSource() override;
-
- // viz::ExternalBeginFrameSourceClient implementation.
- void OnNeedsBeginFrames(bool needs_begin_frames) override;
-
- void OnVSync(base::TimeTicks timestamp, base::TimeDelta interval);
-
- protected:
- // Virtual for testing.
- virtual base::TimeTicks Now() const;
-
- private:
- viz::BeginFrameArgs GetMissedBeginFrameArgs(
- viz::BeginFrameObserver* obs) override;
-
- GpuVSyncControl* const vsync_control_;
- bool needs_begin_frames_;
- uint64_t next_sequence_number_;
-
- DISALLOW_COPY_AND_ASSIGN(GpuVSyncBeginFrameSource);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_COMPOSITOR_GPU_VSYNC_BEGIN_FRAME_SOURCE_H_
diff --git a/chromium/content/browser/compositor/gpu_vsync_begin_frame_source_unittest.cc b/chromium/content/browser/compositor/gpu_vsync_begin_frame_source_unittest.cc
deleted file mode 100644
index 7b091fe0b98..00000000000
--- a/chromium/content/browser/compositor/gpu_vsync_begin_frame_source_unittest.cc
+++ /dev/null
@@ -1,190 +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/gpu_vsync_begin_frame_source.h"
-
-#include "base/macros.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-namespace {
-
-class TestBeginFrameObserver : public viz::BeginFrameObserverBase {
- public:
- TestBeginFrameObserver() = default;
-
- int begin_frame_count() { return begin_frame_count_; }
-
- private:
- bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args) override {
- begin_frame_count_++;
- return true;
- }
-
- void OnBeginFrameSourcePausedChanged(bool paused) override {}
-
- int begin_frame_count_ = 0;
-
- DISALLOW_COPY_AND_ASSIGN(TestBeginFrameObserver);
-};
-
-class TestGpuVSyncBeginFrameSource : public GpuVSyncBeginFrameSource {
- public:
- explicit TestGpuVSyncBeginFrameSource(GpuVSyncControl* vsync_control)
- : GpuVSyncBeginFrameSource(vsync_control) {}
-
- void SetNow(base::TimeTicks now) { now_ = now; }
-
- private:
- base::TimeTicks Now() const override { return now_; }
-
- base::TimeTicks now_;
-
- DISALLOW_COPY_AND_ASSIGN(TestGpuVSyncBeginFrameSource);
-};
-
-class GpuVSyncBeginFrameSourceTest : public testing::Test,
- public GpuVSyncControl {
- public:
- GpuVSyncBeginFrameSourceTest() = default;
- ~GpuVSyncBeginFrameSourceTest() override = default;
-
- protected:
- void SetNeedsVSync(bool needs_vsync) override { needs_vsync_ = needs_vsync; }
-
- bool needs_vsync_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(GpuVSyncBeginFrameSourceTest);
-};
-
-// Test that an observer can be added to BFS and that it receives OnBeginFrame
-// notification.
-TEST_F(GpuVSyncBeginFrameSourceTest, BasicTest) {
- TestBeginFrameObserver observer;
- TestGpuVSyncBeginFrameSource begin_frame_source(this);
-
- base::TimeTicks now = base::TimeTicks() + base::TimeDelta::FromHours(2);
- begin_frame_source.SetNow(now);
-
- EXPECT_FALSE(needs_vsync_);
-
- begin_frame_source.AddObserver(&observer);
-
- EXPECT_TRUE(needs_vsync_);
- EXPECT_FALSE(observer.LastUsedBeginFrameArgs().IsValid());
-
- base::TimeTicks timestamp = now - base::TimeDelta::FromSeconds(1);
- base::TimeDelta interval = base::TimeDelta::FromSeconds(2);
-
- begin_frame_source.OnVSync(timestamp, interval);
-
- EXPECT_EQ(1, observer.begin_frame_count());
-
- viz::BeginFrameArgs args = observer.LastUsedBeginFrameArgs();
- EXPECT_TRUE(args.IsValid());
- EXPECT_EQ(timestamp, args.frame_time);
- EXPECT_EQ(interval, args.interval);
- EXPECT_EQ(timestamp + interval, args.deadline);
- EXPECT_EQ(viz::BeginFrameArgs::kStartingFrameNumber + 1,
- args.sequence_number);
- EXPECT_EQ(viz::BeginFrameArgs::NORMAL, args.type);
- EXPECT_EQ(begin_frame_source.source_id(), args.source_id);
-
- // Make sure that the deadline time is correctly advanced forward to be after
- // 'now' when frame time is way behind.
- now += base::TimeDelta::FromSeconds(10);
- begin_frame_source.SetNow(now);
- // v-sync timestamp is 5 seconds behind but frame time should be projected
- // forward to be 1 second before 'now' and the the deadline should be 1 second
- // after 'now' considering the 2 second interval.
- timestamp = now - base::TimeDelta::FromSeconds(5);
-
- begin_frame_source.OnVSync(timestamp, interval);
-
- EXPECT_EQ(2, observer.begin_frame_count());
-
- args = observer.LastUsedBeginFrameArgs();
- EXPECT_TRUE(args.IsValid());
- EXPECT_EQ(now - base::TimeDelta::FromSeconds(1), args.frame_time);
- EXPECT_EQ(interval, args.interval);
- EXPECT_EQ(now + base::TimeDelta::FromSeconds(1), args.deadline);
- EXPECT_EQ(viz::BeginFrameArgs::kStartingFrameNumber + 2,
- args.sequence_number);
- EXPECT_EQ(viz::BeginFrameArgs::NORMAL, args.type);
- EXPECT_EQ(begin_frame_source.source_id(), args.source_id);
-
- begin_frame_source.RemoveObserver(&observer);
-
- EXPECT_EQ(2, observer.begin_frame_count());
- EXPECT_FALSE(needs_vsync_);
-}
-
-// Test that MISSED OnBeginFrame is produced as expected.
-TEST_F(GpuVSyncBeginFrameSourceTest, MissedBeginFrameArgs) {
- TestBeginFrameObserver observer1;
- TestBeginFrameObserver observer2;
- TestGpuVSyncBeginFrameSource begin_frame_source(this);
-
- base::TimeTicks now = base::TimeTicks() + base::TimeDelta::FromHours(2);
- begin_frame_source.SetNow(now);
-
- begin_frame_source.AddObserver(&observer1);
-
- // The observer shouldn't be getting any BeginFrame at this point.
- EXPECT_EQ(0, observer1.begin_frame_count());
-
- base::TimeDelta interval = base::TimeDelta::FromSeconds(2);
-
- // Trigger first OnBeginFrame.
- begin_frame_source.OnVSync(now, interval);
-
- // The observer should get a NORMAL BeginFrame notification which is covered
- // by BasicTest above.
- EXPECT_EQ(1, observer1.begin_frame_count());
- EXPECT_EQ(viz::BeginFrameArgs::NORMAL,
- observer1.LastUsedBeginFrameArgs().type);
-
- // Remove the first observer and add it back after advancing the 'now' time.
- // It should get a more recent missed notification calculated from the
- // projection of the previous notification.
- begin_frame_source.RemoveObserver(&observer1);
- now = now + base::TimeDelta::FromSeconds(5);
- begin_frame_source.SetNow(now);
- begin_frame_source.AddObserver(&observer1);
-
- EXPECT_EQ(2, observer1.begin_frame_count());
-
- // The projected MISSED frame_time should be 1 second behind 'now'.
- base::TimeTicks timestamp1 = now - base::TimeDelta::FromSeconds(1);
- viz::BeginFrameArgs args1 = observer1.LastUsedBeginFrameArgs();
- EXPECT_TRUE(args1.IsValid());
- EXPECT_EQ(timestamp1, args1.frame_time);
- EXPECT_EQ(timestamp1 + interval, args1.deadline);
- EXPECT_EQ(viz::BeginFrameArgs::kStartingFrameNumber + 2,
- args1.sequence_number);
- EXPECT_EQ(viz::BeginFrameArgs::MISSED, args1.type);
-
- // Add second observer which should receive the same notification.
- begin_frame_source.AddObserver(&observer2);
-
- EXPECT_EQ(1, observer2.begin_frame_count());
-
- viz::BeginFrameArgs args2 = observer2.LastUsedBeginFrameArgs();
- EXPECT_TRUE(args2.IsValid());
- EXPECT_EQ(timestamp1, args2.frame_time);
- EXPECT_EQ(timestamp1 + interval, args2.deadline);
- EXPECT_EQ(viz::BeginFrameArgs::kStartingFrameNumber + 2,
- args2.sequence_number);
- EXPECT_EQ(viz::BeginFrameArgs::MISSED, args2.type);
-
- // Adding and removing the second observer shouldn't produce any
- // new notifications.
- begin_frame_source.RemoveObserver(&observer2);
- begin_frame_source.AddObserver(&observer2);
-
- EXPECT_EQ(1, observer2.begin_frame_count());
-}
-
-} // namespace
-} // namespace content
diff --git a/chromium/content/browser/compositor/image_transport_factory.h b/chromium/content/browser/compositor/image_transport_factory.h
index 0ccaf358643..9dba97fe029 100644
--- a/chromium/content/browser/compositor/image_transport_factory.h
+++ b/chromium/content/browser/compositor/image_transport_factory.h
@@ -38,6 +38,10 @@ class CONTENT_EXPORT ImageTransportFactory {
// Gets the factory instance.
static ImageTransportFactory* GetInstance();
+ // Disable GPU compositing. Will do nothing if GPU compositing is already
+ // disabled.
+ virtual void DisableGpuCompositing() = 0;
+
// Whether gpu compositing is being used or is disabled for software
// compositing. Clients of the compositor should give resources that match
// the appropriate mode.
diff --git a/chromium/content/browser/compositor/image_transport_factory_browsertest.cc b/chromium/content/browser/compositor/image_transport_factory_browsertest.cc
index 8a918a746a9..659533c687d 100644
--- a/chromium/content/browser/compositor/image_transport_factory_browsertest.cc
+++ b/chromium/content/browser/compositor/image_transport_factory_browsertest.cc
@@ -6,58 +6,50 @@
#include "base/run_loop.h"
#include "build/build_config.h"
+#include "components/viz/common/features.h"
#include "components/viz/common/gpu/context_provider.h"
#include "content/browser/compositor/owned_mailbox.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"
namespace content {
namespace {
-typedef ContentBrowserTest ImageTransportFactoryBrowserTest;
+using ImageTransportFactoryBrowserTest = ContentBrowserTest;
class MockContextFactoryObserver : public ui::ContextFactoryObserver {
public:
- MOCK_METHOD0(OnLostResources, void());
+ MOCK_METHOD0(OnLostSharedContext, void());
+ MOCK_METHOD0(OnLostVizProcess, void());
};
-// This crashes on Mac ASAN: http://crbug.com/335083
// Flaky on ChromeOS: crbug.com/394083
-#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS)
#define MAYBE_TestLostContext DISABLED_TestLostContext
#else
#define MAYBE_TestLostContext TestLostContext
#endif
-// Checks that upon context loss, the observer is called and the created
-// resources are reset.
+// Checks that upon context loss the observer is notified.
IN_PROC_BROWSER_TEST_F(ImageTransportFactoryBrowserTest,
MAYBE_TestLostContext) {
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
// This test doesn't make sense in software compositing mode.
- scoped_refptr<viz::ContextProvider> context_provider =
- factory->GetContextFactory()->SharedMainThreadContextProvider();
- if (context_provider->GetGpuFeatureInfo()
- .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] !=
- gpu::kGpuFeatureStatusEnabled) {
+ if (factory->IsGpuCompositingDisabled())
return;
- }
-
- scoped_refptr<OwnedMailbox> mailbox =
- new OwnedMailbox(factory->GetGLHelper());
- EXPECT_FALSE(mailbox->mailbox().IsZero());
MockContextFactoryObserver observer;
factory->GetContextFactory()->AddObserver(&observer);
base::RunLoop run_loop;
- EXPECT_CALL(observer, OnLostResources())
- .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
+ EXPECT_CALL(observer, OnLostSharedContext())
+ .WillOnce(testing::Invoke(&run_loop, &base::RunLoop::Quit));
+ scoped_refptr<viz::ContextProvider> context_provider =
+ factory->GetContextFactory()->SharedMainThreadContextProvider();
gpu::gles2::GLES2Interface* gl = context_provider->ContextGL();
gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
GL_INNOCENT_CONTEXT_RESET_ARB);
@@ -67,16 +59,14 @@ IN_PROC_BROWSER_TEST_F(ImageTransportFactoryBrowserTest,
gl->Flush();
run_loop.Run();
- EXPECT_TRUE(mailbox->mailbox().IsZero());
factory->GetContextFactory()->RemoveObserver(&observer);
}
class ImageTransportFactoryTearDownBrowserTest : public ContentBrowserTest {
public:
- ImageTransportFactoryTearDownBrowserTest() {}
-
void TearDown() override {
+ // Mailbox is null if the test exited early.
if (mailbox_.get())
EXPECT_TRUE(mailbox_->mailbox().IsZero());
ContentBrowserTest::TearDown();
@@ -86,34 +76,27 @@ class ImageTransportFactoryTearDownBrowserTest : public ContentBrowserTest {
scoped_refptr<OwnedMailbox> mailbox_;
};
-// This crashes on Mac. ImageTransportFactory is NULL unless
-// --enable-delegated-renderer is passed, and after that, we'd need to spawn a
-// renderer and get a frame before we create a browser compositor, necessary for
-// the GLHelper to not be NULL.
-// http://crbug.com/335083
-#if defined(OS_MACOSX)
-#define MAYBE_LoseOnTearDown DISABLED_LoseOnTearDown
-#else
-#define MAYBE_LoseOnTearDown LoseOnTearDown
-#endif
// Checks that upon destruction of the ImageTransportFactory, the observer is
// called and the created resources are reset.
IN_PROC_BROWSER_TEST_F(ImageTransportFactoryTearDownBrowserTest,
- MAYBE_LoseOnTearDown) {
+ LoseOnTearDown) {
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+
+ // TODO(crbug.com/844469): Delete after OOP-D is launched because GLHelper
+ // and OwnedMailbox aren't used.
+ if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor))
+ return;
+
// This test doesn't make sense in software compositing mode.
- scoped_refptr<viz::ContextProvider> context_provider =
- factory->GetContextFactory()->SharedMainThreadContextProvider();
- if (context_provider->GetGpuFeatureInfo()
- .status_values[gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING] !=
- gpu::kGpuFeatureStatusEnabled) {
+ if (factory->IsGpuCompositingDisabled())
return;
- }
viz::GLHelper* helper = factory->GetGLHelper();
ASSERT_TRUE(helper);
- mailbox_ = new OwnedMailbox(helper);
+ mailbox_ = base::MakeRefCounted<OwnedMailbox>(helper);
EXPECT_FALSE(mailbox_->mailbox().IsZero());
+
+ // See TearDown() for the test expectation that |mailbox_| has been reset.
}
} // anonymous namespace
diff --git a/chromium/content/browser/compositor/in_process_display_client.cc b/chromium/content/browser/compositor/in_process_display_client.cc
deleted file mode 100644
index 3190c0d90ff..00000000000
--- a/chromium/content/browser/compositor/in_process_display_client.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/compositor/in_process_display_client.h"
-
-#include "content/browser/renderer_host/render_widget_host_impl.h"
-
-#if defined(OS_MACOSX)
-#include "ui/accelerated_widget_mac/ca_layer_frame_sink.h"
-#endif
-
-#if defined(OS_WIN)
-#include <windows.h>
-
-#include "components/viz/common/display/use_layered_window.h"
-#include "components/viz/host/layered_window_updater_impl.h"
-#include "ui/base/win/internal_constants.h"
-#endif
-
-namespace content {
-
-InProcessDisplayClient::InProcessDisplayClient(gfx::AcceleratedWidget widget)
- : binding_(this) {
-#if defined(OS_MACOSX) || defined(OS_WIN)
- widget_ = widget;
-#endif
-}
-
-InProcessDisplayClient::~InProcessDisplayClient() {}
-
-viz::mojom::DisplayClientPtr InProcessDisplayClient::GetBoundPtr(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- viz::mojom::DisplayClientPtr ptr;
- binding_.Bind(mojo::MakeRequest(&ptr), task_runner);
- return ptr;
-}
-
-void InProcessDisplayClient::OnDisplayReceivedCALayerParams(
- const gfx::CALayerParams& ca_layer_params) {
-#if defined(OS_MACOSX)
- ui::CALayerFrameSink* ca_layer_frame_sink =
- ui::CALayerFrameSink::FromAcceleratedWidget(widget_);
- if (ca_layer_frame_sink)
- ca_layer_frame_sink->UpdateCALayerTree(ca_layer_params);
- else
- DLOG(WARNING) << "Received frame for non-existent widget.";
-#else
- DLOG(ERROR) << "Should not receive CALayer params on non-macOS platforms.";
-#endif
-}
-
-void InProcessDisplayClient::DidSwapAfterSnapshotRequestReceived(
- const std::vector<ui::LatencyInfo>& latency_info) {
- RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(latency_info);
-}
-
-void InProcessDisplayClient::CreateLayeredWindowUpdater(
- viz::mojom::LayeredWindowUpdaterRequest request) {
-#if defined(OS_WIN)
- if (!viz::NeedsToUseLayerWindow(widget_)) {
- DLOG(ERROR) << "HWND shouldn't be using a layered window";
- return;
- }
-
- layered_window_updater_ = std::make_unique<viz::LayeredWindowUpdaterImpl>(
- widget_, std::move(request));
-#else
-// This should never happen on non-Windows platforms.
-#endif
-}
-
-} // namespace content
diff --git a/chromium/content/browser/compositor/in_process_display_client.h b/chromium/content/browser/compositor/in_process_display_client.h
deleted file mode 100644
index baa83594ed5..00000000000
--- a/chromium/content/browser/compositor/in_process_display_client.h
+++ /dev/null
@@ -1,54 +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_COMPOSITOR_IN_PROCESS_DISPLAY_CLIENT_H_
-#define CONTENT_BROWSER_COMPOSITOR_IN_PROCESS_DISPLAY_CLIENT_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/single_thread_task_runner.h"
-#include "build/build_config.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "services/viz/privileged/interfaces/compositing/display_private.mojom.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace viz {
-class LayeredWindowUpdaterImpl;
-}
-
-namespace content {
-
-// A DisplayClient that can be used to display received
-// gfx::CALayerParams in a CALayer tree in this process.
-class InProcessDisplayClient : public viz::mojom::DisplayClient {
- public:
- explicit InProcessDisplayClient(gfx::AcceleratedWidget widget);
- ~InProcessDisplayClient() override;
-
- viz::mojom::DisplayClientPtr GetBoundPtr(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-
- private:
- // viz::mojom::DisplayClient implementation:
- void OnDisplayReceivedCALayerParams(
- const gfx::CALayerParams& ca_layer_params) override;
- void DidSwapAfterSnapshotRequestReceived(
- const std::vector<ui::LatencyInfo>& latency_info) override;
- void CreateLayeredWindowUpdater(
- viz::mojom::LayeredWindowUpdaterRequest request) override;
-
- mojo::Binding<viz::mojom::DisplayClient> binding_;
-#if defined(OS_MACOSX) || defined(OS_WIN)
- gfx::AcceleratedWidget widget_;
-#endif
-
-#if defined(OS_WIN)
- std::unique_ptr<viz::LayeredWindowUpdaterImpl> layered_window_updater_;
-#endif
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_COMPOSITOR_IN_PROCESS_DISPLAY_CLIENT_H_
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 2792d4646f5..3b3dc6943a6 100644
--- a/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
@@ -193,7 +193,6 @@ void OffscreenBrowserCompositorOutputSurface::OnReflectorChanged() {
void OffscreenBrowserCompositorOutputSurface::OnSwapBuffersComplete(
const std::vector<ui::LatencyInfo>& latency_info,
bool need_presentation_feedback) {
- RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(latency_info);
latency_tracker_.OnGpuSwapBuffersCompleted(latency_info);
client_->DidReceiveSwapBuffersAck();
if (need_presentation_feedback)
diff --git a/chromium/content/browser/compositor/owned_mailbox.cc b/chromium/content/browser/compositor/owned_mailbox.cc
index 69e1687c9d0..f1eddad0fbc 100644
--- a/chromium/content/browser/compositor/owned_mailbox.cc
+++ b/chromium/content/browser/compositor/owned_mailbox.cc
@@ -41,9 +41,11 @@ void OwnedMailbox::Destroy() {
gl_helper_ = nullptr;
}
-void OwnedMailbox::OnLostResources() {
+void OwnedMailbox::OnLostSharedContext() {
if (gl_helper_)
Destroy();
}
+void OwnedMailbox::OnLostVizProcess() {}
+
} // namespace content
diff --git a/chromium/content/browser/compositor/owned_mailbox.h b/chromium/content/browser/compositor/owned_mailbox.h
index d703dfa5b99..9880759f4c6 100644
--- a/chromium/content/browser/compositor/owned_mailbox.h
+++ b/chromium/content/browser/compositor/owned_mailbox.h
@@ -41,7 +41,8 @@ class CONTENT_EXPORT OwnedMailbox : public base::RefCounted<OwnedMailbox>,
~OwnedMailbox() override;
// ImageTransportFactoryObserver implementation.
- void OnLostResources() override;
+ void OnLostSharedContext() override;
+ void OnLostVizProcess() override;
private:
friend class base::RefCounted<OwnedMailbox>;
diff --git a/chromium/content/browser/compositor/reflector_impl_unittest.cc b/chromium/content/browser/compositor/reflector_impl_unittest.cc
index feb02e87cfb..fd673e054bd 100644
--- a/chromium/content/browser/compositor/reflector_impl_unittest.cc
+++ b/chromium/content/browser/compositor/reflector_impl_unittest.cc
@@ -14,7 +14,6 @@
#include "components/viz/service/display/output_surface_frame.h"
#include "components/viz/service/display_embedder/compositor_overlay_candidate_validator.h"
#include "components/viz/test/test_context_provider.h"
-#include "components/viz/test/test_web_graphics_context_3d.h"
#include "content/browser/compositor/browser_compositor_output_surface.h"
#include "content/browser/compositor/reflector_texture.h"
#include "content/browser/compositor/test/test_image_transport_factory.h"
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 b5b49363709..ff4f125cdd1 100644
--- a/chromium/content/browser/compositor/software_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/software_browser_compositor_output_surface.cc
@@ -71,10 +71,9 @@ void SoftwareBrowserCompositorOutputSurface::SwapBuffers(
base::TimeTicks swap_time = base::TimeTicks::Now();
for (auto& latency : frame.latency_info) {
latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, swap_time, 1);
+ ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, swap_time, 1);
latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, swap_time,
- 1);
+ ui::INPUT_EVENT_LATENCY_FRAME_SWAP_COMPONENT, swap_time, 1);
}
gfx::VSyncProvider* vsync_provider = software_device()->GetVSyncProvider();
@@ -93,7 +92,6 @@ void SoftwareBrowserCompositorOutputSurface::SwapBuffers(
void SoftwareBrowserCompositorOutputSurface::SwapBuffersCallback(
const std::vector<ui::LatencyInfo>& latency_info,
bool need_presentation_feedback) {
- RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(latency_info);
latency_tracker_.OnGpuSwapBuffersCompleted(latency_info);
client_->DidReceiveSwapBuffersAck();
if (need_presentation_feedback) {
diff --git a/chromium/content/browser/compositor/viz_process_transport_factory.cc b/chromium/content/browser/compositor/viz_process_transport_factory.cc
index 7f02b82c3a4..af692aeb080 100644
--- a/chromium/content/browser/compositor/viz_process_transport_factory.cc
+++ b/chromium/content/browser/compositor/viz_process_transport_factory.cc
@@ -10,18 +10,17 @@
#include "base/command_line.h"
#include "base/debug/dump_without_crashing.h"
#include "base/single_thread_task_runner.h"
+#include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
#include "cc/raster/single_thread_task_graph_runner.h"
-#include "components/viz/client/client_layer_tree_frame_sink.h"
#include "components/viz/client/hit_test_data_provider_draw_quad.h"
#include "components/viz/client/local_surface_id_provider.h"
#include "components/viz/common/gpu/context_provider.h"
#include "components/viz/common/gpu/raster_context_provider.h"
+#include "components/viz/common/switches.h"
#include "components/viz/host/host_frame_sink_manager.h"
-#include "components/viz/host/renderer_settings_creation.h"
#include "components/viz/service/display_embedder/compositing_mode_reporter_impl.h"
#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "content/browser/browser_main_loop.h"
-#include "content/browser/compositor/external_begin_frame_controller_client_impl.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
@@ -110,12 +109,13 @@ VizProcessTransportFactory::VizProcessTransportFactory(
gpu::GpuChannelEstablishFactory* gpu_channel_establish_factory,
scoped_refptr<base::SingleThreadTaskRunner> resize_task_runner,
viz::CompositingModeReporterImpl* compositing_mode_reporter)
- : gpu_channel_establish_factory_(gpu_channel_establish_factory),
- resize_task_runner_(std::move(resize_task_runner)),
+ : ui::HostContextFactoryPrivate(
+ kBrowserClientId,
+ BrowserMainLoop::GetInstance()->host_frame_sink_manager(),
+ resize_task_runner),
+ gpu_channel_establish_factory_(gpu_channel_establish_factory),
compositing_mode_reporter_(compositing_mode_reporter),
- frame_sink_id_allocator_(kBrowserClientId),
task_graph_runner_(std::make_unique<cc::SingleThreadTaskGraphRunner>()),
- renderer_settings_(viz::CreateRendererSettings()),
weak_ptr_factory_(this) {
DCHECK(gpu_channel_establish_factory_);
task_graph_runner_->Start("CompositorTileWorker1",
@@ -150,28 +150,50 @@ void VizProcessTransportFactory::ConnectHostFrameSinkManager() {
// Setup HostFrameSinkManager with interface endpoints.
GetHostFrameSinkManager()->BindAndSetManager(
- std::move(frame_sink_manager_client_request), resize_task_runner_,
+ std::move(frame_sink_manager_client_request), resize_task_runner(),
std::move(frame_sink_manager));
- // 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) {
- // There should always be a GpuProcessHost instance, and GPU process,
- // for running the compositor thread. The exception is during shutdown
- // the GPU process won't be restarted and GpuProcessHost::Get() can
- // return null.
- auto* gpu_process_host = GpuProcessHost::Get();
- if (gpu_process_host) {
- gpu_process_host->ConnectFrameSinkManager(std::move(request),
- std::move(client));
- }
- };
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(connect_on_io_thread,
- std::move(frame_sink_manager_request),
- frame_sink_manager_client.PassInterface()));
+ if (GpuDataManagerImpl::GetInstance()->GpuProcessStartAllowed()) {
+ // 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) {
+ // There should always be a GpuProcessHost instance, and GPU process,
+ // for running the compositor thread. The exception is during shutdown
+ // the GPU process won't be restarted and GpuProcessHost::Get() can
+ // return null.
+ auto* gpu_process_host = GpuProcessHost::Get();
+ if (gpu_process_host) {
+ gpu_process_host->ConnectFrameSinkManager(std::move(request),
+ std::move(client));
+ }
+ };
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(connect_on_io_thread,
+ std::move(frame_sink_manager_request),
+ frame_sink_manager_client.PassInterface()));
+ } else {
+ DCHECK(!viz_compositor_thread_);
+
+ // GPU process access is disabled. Start a new thread to run the display
+ // compositor in-process and connect HostFrameSinkManager to it.
+ viz_compositor_thread_ = std::make_unique<viz::VizCompositorThreadRunner>();
+
+ viz::mojom::FrameSinkManagerParamsPtr params =
+ viz::mojom::FrameSinkManagerParams::New();
+ params->restart_id = viz::BeginFrameSource::kNotRestartableId;
+ base::Optional<uint32_t> activation_deadline_in_frames =
+ switches::GetDeadlineToSynchronizeSurfaces();
+ params->use_activation_deadline = activation_deadline_in_frames.has_value();
+ params->activation_deadline_in_frames =
+ activation_deadline_in_frames.value_or(0u);
+ params->frame_sink_manager = std::move(frame_sink_manager_request);
+ params->frame_sink_manager_client =
+ frame_sink_manager_client.PassInterface();
+ viz_compositor_thread_->CreateFrameSinkManager(std::move(params));
+ }
}
void VizProcessTransportFactory::CreateLayerTreeFrameSink(
@@ -181,7 +203,8 @@ void VizProcessTransportFactory::CreateLayerTreeFrameSink(
compositor->widget());
#endif
- if (is_gpu_compositing_disabled_ || compositor->force_software_compositor()) {
+ if (is_gpu_compositing_disabled() ||
+ compositor->force_software_compositor()) {
OnEstablishedGpuChannel(compositor, nullptr);
return;
}
@@ -192,7 +215,7 @@ void VizProcessTransportFactory::CreateLayerTreeFrameSink(
scoped_refptr<viz::ContextProvider>
VizProcessTransportFactory::SharedMainThreadContextProvider() {
- if (is_gpu_compositing_disabled_)
+ if (is_gpu_compositing_disabled())
return nullptr;
if (!main_context_provider_) {
@@ -211,14 +234,7 @@ VizProcessTransportFactory::SharedMainThreadContextProvider() {
}
void VizProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
-#if defined(OS_WIN)
- // TODO(crbug.com/791660): Make sure that GpuProcessHost::SetChildSurface()
- // doesn't crash the GPU process after parent is unregistered.
- gfx::RenderingWindowManager::GetInstance()->UnregisterParent(
- compositor->widget());
-#endif
-
- compositor_data_map_.erase(compositor);
+ UnconfigureCompositor(compositor);
}
double VizProcessTransportFactory::GetRefreshRate() const {
@@ -245,112 +261,19 @@ void VizProcessTransportFactory::RemoveObserver(
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::SetDisplayColorMatrix(
- ui::Compositor* compositor,
- const SkMatrix44& matrix) {
- auto iter = compositor_data_map_.find(compositor);
- if (iter == compositor_data_map_.end() || !iter->second.display_private)
- return;
- iter->second.display_private->SetDisplayColorMatrix(gfx::Transform(matrix));
-}
-
-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) {
- auto iter = compositor_data_map_.find(compositor);
- if (iter == compositor_data_map_.end() || !iter->second.display_private)
- return;
- iter->second.display_private->SetDisplayVSyncParameters(timebase, interval);
-}
-
-void VizProcessTransportFactory::IssueExternalBeginFrame(
- ui::Compositor* compositor,
- const viz::BeginFrameArgs& args) {
- auto iter = compositor_data_map_.find(compositor);
- if (iter == compositor_data_map_.end() || !iter->second.display_private)
- return;
-
- DCHECK(iter->second.external_begin_frame_controller_client);
- iter->second.external_begin_frame_controller_client->GetController()
- ->IssueExternalBeginFrame(args);
-}
-
-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);
+bool VizProcessTransportFactory::SyncTokensRequiredForDisplayCompositor() {
+ // The display compositor is out-of-process, so must be using a different
+ // context from the UI compositor, and requires synchronization between them.
+ return true;
}
-viz::FrameSinkManagerImpl* VizProcessTransportFactory::GetFrameSinkManager() {
- // When running with viz there is no FrameSinkManagerImpl in the browser
- // process. FrameSinkManagerImpl runs in the GPU process instead. Anything in
- // the browser process that relies FrameSinkManagerImpl or SurfaceManager
- // internal state needs to change. See https://crbug.com/787097 and
- // https://crbug.com/760181 for more context.
- NOTREACHED();
- return nullptr;
+void VizProcessTransportFactory::DisableGpuCompositing() {
+ if (!is_gpu_compositing_disabled())
+ DisableGpuCompositing(nullptr);
}
bool VizProcessTransportFactory::IsGpuCompositingDisabled() {
- return is_gpu_compositing_disabled_;
+ return is_gpu_compositing_disabled();
}
ui::ContextFactory* VizProcessTransportFactory::GetContextFactory() {
@@ -379,7 +302,7 @@ void VizProcessTransportFactory::DisableGpuCompositing(
DLOG(ERROR) << "Switching to software compositing.";
// Change the result of IsGpuCompositingDisabled() before notifying anything.
- is_gpu_compositing_disabled_ = true;
+ set_is_gpu_compositing_disabled(true);
compositing_mode_reporter_->SetUsingSoftwareCompositing();
@@ -396,27 +319,18 @@ void VizProcessTransportFactory::DisableGpuCompositing(
main_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;
+ // Reemove the FrameSink from every compositor that needs to fall back to
+ // software compositing.
+ for (ui::Compositor* compositor : GetAllCompositors()) {
// The |guilty_compositor| is in the process of setting up its FrameSink
// so removing it from |compositor_data_map_| 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) {
+ if (compositor == guilty_compositor ||
+ compositor->force_software_compositor())
+ continue;
+
// Compositor expects to be not visible when releasing its FrameSink.
bool visible = compositor->IsVisible();
compositor->SetVisible(false);
@@ -432,6 +346,9 @@ void VizProcessTransportFactory::DisableGpuCompositing(
void VizProcessTransportFactory::OnGpuProcessLost() {
// Reconnect HostFrameSinkManager to new GPU process.
ConnectHostFrameSinkManager();
+
+ for (auto& observer : observer_list_)
+ observer.OnLostVizProcess();
}
void VizProcessTransportFactory::OnEstablishedGpuChannel(
@@ -441,8 +358,8 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel(
if (!compositor)
return;
- bool gpu_compositing =
- !is_gpu_compositing_disabled_ && !compositor->force_software_compositor();
+ bool gpu_compositing = !is_gpu_compositing_disabled() &&
+ !compositor->force_software_compositor();
if (gpu_compositing) {
auto context_result =
@@ -459,72 +376,6 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel(
}
}
-#if defined(OS_WIN)
- gfx::RenderingWindowManager::GetInstance()->RegisterParent(
- compositor->widget());
-#endif
-
- auto& compositor_data = compositor_data_map_[compositor];
-
- auto root_params = viz::mojom::RootCompositorFrameSinkParams::New();
-
- // Create interfaces for a root CompositorFrameSink.
- viz::mojom::CompositorFrameSinkAssociatedPtrInfo sink_info;
- root_params->compositor_frame_sink = mojo::MakeRequest(&sink_info);
- viz::mojom::CompositorFrameSinkClientRequest client_request =
- mojo::MakeRequest(&root_params->compositor_frame_sink_client);
- root_params->display_private =
- mojo::MakeRequest(&compositor_data.display_private);
- compositor_data.display_client =
- std::make_unique<InProcessDisplayClient>(compositor->widget());
- root_params->display_client =
- compositor_data.display_client->GetBoundPtr(resize_task_runner_)
- .PassInterface();
-
-#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
-
- // Initialize ExternalBeginFrameController client if enabled.
- compositor_data.external_begin_frame_controller_client.reset();
- if (compositor->external_begin_frames_enabled()) {
- compositor_data.external_begin_frame_controller_client =
- std::make_unique<ExternalBeginFrameControllerClientImpl>(compositor);
- root_params->external_begin_frame_controller =
- compositor_data.external_begin_frame_controller_client
- ->GetControllerRequest();
- root_params->external_begin_frame_controller_client =
- compositor_data.external_begin_frame_controller_client->GetBoundPtr()
- .PassInterface();
- }
-
- root_params->frame_sink_id = compositor->frame_sink_id();
- root_params->widget = surface_handle;
- root_params->gpu_compositing = gpu_compositing;
- root_params->renderer_settings = renderer_settings_;
-
- // Connects the viz process end of CompositorFrameSink message pipes. The
- // browser compositor may request a new CompositorFrameSink on context loss,
- // which will destroy the existing CompositorFrameSink.
- GetHostFrameSinkManager()->CreateRootCompositorFrameSink(
- std::move(root_params));
-
- // Create LayerTreeFrameSink with the browser end of CompositorFrameSink.
- viz::ClientLayerTreeFrameSink::InitParams params;
- params.compositor_task_runner = compositor->task_runner();
- 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 = true;
- params.hit_test_data_provider =
- std::make_unique<viz::HitTestDataProviderDrawQuad>(
- /*should_ask_for_child_region=*/false);
-
scoped_refptr<viz::ContextProvider> compositor_context;
scoped_refptr<viz::RasterContextProvider> worker_context;
if (gpu_compositing) {
@@ -532,20 +383,14 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel(
compositor_context = main_context_provider_;
worker_context = worker_context_provider_;
}
- compositor->SetLayerTreeFrameSink(
- std::make_unique<viz::ClientLayerTreeFrameSink>(
- std::move(compositor_context), std::move(worker_context), &params));
-
-#if defined(OS_WIN)
- gfx::RenderingWindowManager::GetInstance()->DoSetParentOnChild(
- compositor->widget());
-#endif
+ ConfigureCompositor(compositor_weak_ptr, std::move(compositor_context),
+ std::move(worker_context));
}
gpu::ContextResult
VizProcessTransportFactory::TryCreateContextsForGpuCompositing(
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
- DCHECK(!is_gpu_compositing_disabled_);
+ DCHECK(!is_gpu_compositing_disabled());
// Fallback to software compositing if there is no IPC channel.
if (!gpu_channel_host)
@@ -575,7 +420,7 @@ VizProcessTransportFactory::TryCreateContextsForGpuCompositing(
kSharedWorkerContextSupportsLocking, kSharedWorkerContextSupportsGLES2,
kSharedWorkerContextSupportsRaster,
kSharedWorkerContextSupportsGrContext,
- ui::command_buffer_metrics::BROWSER_WORKER_CONTEXT);
+ ui::command_buffer_metrics::ContextType::BROWSER_WORKER);
// Don't observer context loss on |worker_context_provider_| here, that is
// already observered by LayerTreeFrameSink. The lost context will be caught
@@ -602,8 +447,8 @@ VizProcessTransportFactory::TryCreateContextsForGpuCompositing(
std::move(gpu_channel_host), GetGpuMemoryBufferManager(),
kCompositorContextSupportsLocking, kCompositorContextSupportsGLES2,
kCompositorContextSupportsRaster, kCompositorContextSupportsGrContext,
- ui::command_buffer_metrics::UI_COMPOSITOR_CONTEXT);
- main_context_provider_->SetDefaultTaskRunner(resize_task_runner_);
+ ui::command_buffer_metrics::ContextType::BROWSER_MAIN_THREAD);
+ main_context_provider_->SetDefaultTaskRunner(resize_task_runner());
auto context_result = main_context_provider_->BindToCurrentThread();
if (context_result != gpu::ContextResult::kSuccess) {
@@ -627,15 +472,7 @@ void VizProcessTransportFactory::OnLostMainThreadSharedContext() {
}
for (auto& observer : observer_list_)
- observer.OnLostResources();
+ observer.OnLostSharedContext();
}
-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
index 229b760eb08..731a309d53a 100644
--- a/chromium/content/browser/compositor/viz_process_transport_factory.h
+++ b/chromium/content/browser/compositor/viz_process_transport_factory.h
@@ -7,19 +7,17 @@
#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/gpu/context_lost_observer.h"
-#include "components/viz/common/surfaces/frame_sink_id_allocator.h"
+#include "components/viz/service/main/viz_compositor_thread_runner.h"
#include "content/browser/compositor/image_transport_factory.h"
-#include "content/browser/compositor/in_process_display_client.h"
#include "gpu/command_buffer/common/context_result.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/compositor_frame_sink.mojom.h"
#include "ui/compositor/compositor.h"
+#include "ui/compositor/host/host_context_factory_private.h"
namespace base {
class SingleThreadTaskRunner;
@@ -44,14 +42,12 @@ class RasterContextProvider;
namespace content {
-class ExternalBeginFrameControllerClientImpl;
-
// 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 ui::HostContextFactoryPrivate,
public ImageTransportFactory,
public viz::ContextLostObserver {
public:
@@ -75,32 +71,10 @@ class VizProcessTransportFactory : public ui::ContextFactory,
cc::TaskGraphRunner* GetTaskGraphRunner() 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 SetDisplayColorMatrix(ui::Compositor* compositor,
- const SkMatrix44& matrix) 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;
+ bool SyncTokensRequiredForDisplayCompositor() override;
// ImageTransportFactory implementation.
+ void DisableGpuCompositing() override;
bool IsGpuCompositingDisabled() override;
ui::ContextFactory* GetContextFactory() override;
ui::ContextFactoryPrivate* GetContextFactoryPrivate() override;
@@ -110,26 +84,6 @@ class VizProcessTransportFactory : public ui::ContextFactory,
void OnContextLost() 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;
- std::unique_ptr<InProcessDisplayClient> display_client;
-
- // Controls external BeginFrames for the display. Only set if external
- // BeginFrames are enabled for the compositor.
- std::unique_ptr<ExternalBeginFrameControllerClientImpl>
- external_begin_frame_controller_client;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CompositorData);
- };
-
// Disables GPU compositing. This notifies UI and renderer compositors to drop
// LayerTreeFrameSinks and request new ones. If fallback happens while
// creating a new LayerTreeFrameSink for UI compositor it should be passed in
@@ -159,15 +113,11 @@ class VizProcessTransportFactory : public ui::ContextFactory,
void OnLostMainThreadSharedContext();
gpu::GpuChannelEstablishFactory* const gpu_channel_establish_factory_;
- scoped_refptr<base::SingleThreadTaskRunner> const resize_task_runner_;
// Controls the compositing mode based on what mode the display compositors
// are using.
viz::CompositingModeReporterImpl* const compositing_mode_reporter_;
- base::flat_map<ui::Compositor*, CompositorData> compositor_data_map_;
- bool is_gpu_compositing_disabled_ = false;
-
base::ObserverList<ui::ContextFactoryObserver> observer_list_;
// ContextProvider used on worker threads for rasterization.
@@ -177,9 +127,11 @@ class VizProcessTransportFactory : public ui::ContextFactory,
// returned from GetSharedMainThreadContextProvider().
scoped_refptr<ui::ContextProviderCommandBuffer> main_context_provider_;
- viz::FrameSinkIdAllocator frame_sink_id_allocator_;
std::unique_ptr<cc::SingleThreadTaskGraphRunner> task_graph_runner_;
- const viz::RendererSettings renderer_settings_;
+
+ // Will start and run the VizCompositorThread for using an in-process display
+ // compositor.
+ std::unique_ptr<viz::VizCompositorThreadRunner> viz_compositor_thread_;
base::WeakPtrFactory<VizProcessTransportFactory> weak_ptr_factory_;
diff --git a/chromium/content/browser/compositor/vulkan_browser_compositor_output_surface.cc b/chromium/content/browser/compositor/vulkan_browser_compositor_output_surface.cc
index 50ea53d2cec..8637358c8e2 100644
--- a/chromium/content/browser/compositor/vulkan_browser_compositor_output_surface.cc
+++ b/chromium/content/browser/compositor/vulkan_browser_compositor_output_surface.cc
@@ -94,6 +94,10 @@ void VulkanBrowserCompositorOutputSurface::SetDrawRectangle(
NOTREACHED();
}
+unsigned VulkanBrowserCompositorOutputSurface::UpdateGpuFence() {
+ return 0;
+}
+
uint32_t
VulkanBrowserCompositorOutputSurface::GetFramebufferCopyTextureFormat() {
NOTIMPLEMENTED();
diff --git a/chromium/content/browser/compositor/vulkan_browser_compositor_output_surface.h b/chromium/content/browser/compositor/vulkan_browser_compositor_output_surface.h
index 7de13ae0e6a..870afb75ceb 100644
--- a/chromium/content/browser/compositor/vulkan_browser_compositor_output_surface.h
+++ b/chromium/content/browser/compositor/vulkan_browser_compositor_output_surface.h
@@ -47,6 +47,7 @@ class VulkanBrowserCompositorOutputSurface
uint32_t GetFramebufferCopyTextureFormat() override;
void SwapBuffers(viz::OutputSurfaceFrame frame) override;
void SetDrawRectangle(const gfx::Rect& rect) override;
+ unsigned UpdateGpuFence() override;
gpu::VulkanSurface* GetVulkanSurface() override;
diff --git a/chromium/content/browser/content_service_browsertest.cc b/chromium/content/browser/content_service_browsertest.cc
new file mode 100644
index 00000000000..633ff83f863
--- /dev/null
+++ b/chromium/content/browser/content_service_browsertest.cc
@@ -0,0 +1,59 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/path_service.h"
+#include "base/run_loop.h"
+#include "base/test/bind_test_util.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_paths.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/shell/browser/shell.h"
+#include "services/content/public/cpp/navigable_contents.h"
+#include "services/content/public/mojom/constants.mojom.h"
+#include "services/content/public/mojom/navigable_contents_factory.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+
+namespace content {
+namespace {
+
+class ContentServiceBrowserTest : public ContentBrowserTest {
+ public:
+ ContentServiceBrowserTest() = default;
+ ~ContentServiceBrowserTest() override = default;
+
+ void SetUpOnMainThread() override {
+ ContentBrowserTest::SetUpOnMainThread();
+
+ base::FilePath test_data_path;
+ CHECK(base::PathService::Get(DIR_TEST_DATA, &test_data_path));
+ embedded_test_server()->ServeFilesFromDirectory(test_data_path);
+ CHECK(embedded_test_server()->Start());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ContentServiceBrowserTest);
+};
+
+// Verifies that the embedded Content Service is reachable. Does a basic
+// end-to-end sanity check to also verify that a NavigableContents is backed by
+// a WebContents instance in the browser.
+IN_PROC_BROWSER_TEST_F(ContentServiceBrowserTest, EmbeddedContentService) {
+ auto* browser_context = shell()->web_contents()->GetBrowserContext();
+ auto* connector = BrowserContext::GetConnectorFor(browser_context);
+
+ content::mojom::NavigableContentsFactoryPtr factory;
+ connector->BindInterface(content::mojom::kServiceName, &factory);
+ auto contents = std::make_unique<content::NavigableContents>(factory.get());
+
+ base::RunLoop loop;
+ contents->set_did_stop_loading_callback_for_testing(loop.QuitClosure());
+ contents->Navigate(embedded_test_server()->GetURL("/hello.html"));
+ loop.Run();
+}
+
+} // namespace
+} // namespace content
diff --git a/chromium/content/browser/content_service_delegate_impl.cc b/chromium/content/browser/content_service_delegate_impl.cc
new file mode 100644
index 00000000000..40eb806f117
--- /dev/null
+++ b/chromium/content/browser/content_service_delegate_impl.cc
@@ -0,0 +1,90 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/content_service_delegate_impl.h"
+
+#include "base/macros.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "services/content/navigable_contents_delegate.h"
+#include "services/content/service.h"
+
+namespace content {
+
+namespace {
+
+// Bridge between Content Service navigable contents delegation API and a
+// WebContentsImpl.
+class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
+ public WebContentsObserver {
+ public:
+ explicit NavigableContentsDelegateImpl(BrowserContext* browser_context,
+ mojom::NavigableContentsClient* client)
+ : client_(client) {
+ WebContents::CreateParams params(browser_context);
+ web_contents_ = WebContents::Create(params);
+ WebContentsObserver::Observe(web_contents_.get());
+ }
+
+ ~NavigableContentsDelegateImpl() override {
+ WebContentsObserver::Observe(nullptr);
+ }
+
+ private:
+ // content::NavigableContentsDelegate:
+ gfx::NativeView GetNativeView() override {
+ return web_contents_->GetNativeView();
+ }
+
+ void Navigate(const GURL& url) override {
+ NavigationController::LoadURLParams params(url);
+ params.transition_type = ui::PAGE_TRANSITION_AUTO_TOPLEVEL;
+ web_contents_->GetController().LoadURLWithParams(params);
+ }
+
+ // WebContentsObserver:
+ void DidStopLoading() override { client_->DidStopLoading(); }
+
+ std::unique_ptr<WebContents> web_contents_;
+ mojom::NavigableContentsClient* const client_;
+
+ DISALLOW_COPY_AND_ASSIGN(NavigableContentsDelegateImpl);
+};
+
+} // namespace
+
+ContentServiceDelegateImpl::ContentServiceDelegateImpl(
+ BrowserContext* browser_context)
+ : browser_context_(browser_context) {}
+
+ContentServiceDelegateImpl::~ContentServiceDelegateImpl() {
+ // This delegate is destroyed immediately before |browser_context_| is
+ // destroyed. We force-kill any Content Service instances which depend on
+ // |this|, since they will no longer be functional anyway.
+ std::set<content::Service*> instances;
+ std::swap(instances, service_instances_);
+ for (content::Service* service : instances) {
+ // Eventually destroys |service|. Ensures that no more calls into |this|
+ // will occur.
+ service->ForceQuit();
+ }
+}
+
+void ContentServiceDelegateImpl::AddService(content::Service* service) {
+ service_instances_.insert(service);
+}
+
+void ContentServiceDelegateImpl::WillDestroyServiceInstance(
+ content::Service* service) {
+ service_instances_.erase(service);
+}
+
+std::unique_ptr<content::NavigableContentsDelegate>
+ContentServiceDelegateImpl::CreateNavigableContentsDelegate(
+ mojom::NavigableContentsClient* client) {
+ return std::make_unique<NavigableContentsDelegateImpl>(browser_context_,
+ client);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/content_service_delegate_impl.h b/chromium/content/browser/content_service_delegate_impl.h
new file mode 100644
index 00000000000..70b2295f950
--- /dev/null
+++ b/chromium/content/browser/content_service_delegate_impl.h
@@ -0,0 +1,56 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_CONTENT_SERVICE_DELEGATE_IMPL_H_
+#define CONTENT_BROWSER_CONTENT_SERVICE_DELEGATE_IMPL_H_
+
+#include <memory>
+#include <set>
+
+#include "base/macros.h"
+#include "services/content/service_delegate.h"
+
+namespace content {
+
+class BrowserContext;
+
+// Implementation of the main delegate interface for the Content Service. This
+// is used to support the Content Service implementation with content/browser
+// details, without the Content Service having any build dependencies on
+// src/content. There is one instance of this delegate per BrowserContext,
+// shared by any ContentService instance instantiated on behalf of that
+// BrowserContext.
+class ContentServiceDelegateImpl : public content::ServiceDelegate {
+ public:
+ // Constructs a new ContentServiceDelegateImpl for |browser_context|.
+ // |browser_context| must outlive |this|.
+ explicit ContentServiceDelegateImpl(BrowserContext* browser_context);
+ ~ContentServiceDelegateImpl() override;
+
+ // Registers |service| with this delegate. Must be called for any |service|
+ // using |this| as its ContentServiceDelegate. Automatically balanced by
+ // |WillDestroyServiceInstance()|.
+ void AddService(content::Service* service);
+
+ private:
+ // content::ContentServiceDelegate:
+ void WillDestroyServiceInstance(content::Service* service) override;
+ std::unique_ptr<NavigableContentsDelegate> CreateNavigableContentsDelegate(
+ mojom::NavigableContentsClient* client) override;
+
+ BrowserContext* const browser_context_;
+
+ // Tracks ContentService instances currently using this delegate. Necessary
+ // because the lifetime of |this| is tied to the lifetime of
+ // |browser_context_|; on destruction of |this|, we need to force all of these
+ // ContentService instances to terminate, since they cannot operate without
+ // their delegate.
+ std::set<content::Service*> service_instances_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentServiceDelegateImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_CONTENT_SERVICE_DELEGATE_IMPL_H_
diff --git a/chromium/content/browser/cookie_store/cookie_store_manager.cc b/chromium/content/browser/cookie_store/cookie_store_manager.cc
index 8e08a32ed55..717c5d04a3c 100644
--- a/chromium/content/browser/cookie_store/cookie_store_manager.cc
+++ b/chromium/content/browser/cookie_store/cookie_store_manager.cc
@@ -13,9 +13,9 @@
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_version.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/public/browser/browser_context.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "url/gurl.h"
@@ -27,13 +27,14 @@ namespace {
const char kSubscriptionsUserKey[] = "cookie_store_subscriptions";
// Handles the result of ServiceWorkerContextWrapper::StoreRegistrationUserData.
-void HandleStoreRegistrationUserDataStatus(ServiceWorkerStatusCode status) {
+void HandleStoreRegistrationUserDataStatus(
+ blink::ServiceWorkerStatusCode status) {
// The current implementation does not have a good way to handle errors in
// StoreRegistrationUserData. Cookie change subscriptions have been added to
// the registration during the install event, so it's too late to surface the
// error to the renderer. The registration has already been persisted, and the
// Service Worker is likely active by now.
- DLOG_IF(ERROR, status != SERVICE_WORKER_OK)
+ DLOG_IF(ERROR, status != blink::ServiceWorkerStatusCode::kOk)
<< "StoreRegistrationUserData failed";
}
@@ -94,13 +95,13 @@ void CookieStoreManager::ListenToCookieChanges(
void CookieStoreManager::ProcessOnDiskSubscriptions(
base::OnceCallback<void(bool)> load_callback,
const std::vector<std::pair<int64_t, std::string>>& user_data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!done_loading_subscriptions_) << __func__ << " already called";
done_loading_subscriptions_ = true;
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
DidLoadAllSubscriptions(false, std::move(load_callback));
return;
}
@@ -480,9 +481,9 @@ void CookieStoreManager::OnCookieChange(
[](base::WeakPtr<CookieStoreManager> manager,
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
- ServiceWorkerStatusCode find_status,
+ blink::ServiceWorkerStatusCode find_status,
scoped_refptr<ServiceWorkerRegistration> registration) {
- if (find_status != SERVICE_WORKER_OK)
+ if (find_status != blink::ServiceWorkerStatusCode::kOk)
return;
DCHECK(registration);
@@ -513,7 +514,7 @@ void CookieStoreManager::DispatchChangeEvent(
int request_id = active_version->StartRequest(
ServiceWorkerMetrics::EventType::COOKIE_CHANGE, base::DoNothing());
- active_version->event_dispatcher()->DispatchCookieChangeEvent(
+ active_version->endpoint()->DispatchCookieChangeEvent(
cookie, cause, active_version->CreateSimpleEventCallback(request_id));
}
@@ -521,8 +522,8 @@ void CookieStoreManager::DidStartWorkerForChangeEvent(
scoped_refptr<ServiceWorkerRegistration> registration,
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
- ServiceWorkerStatusCode start_worker_status) {
- if (start_worker_status != SERVICE_WORKER_OK)
+ blink::ServiceWorkerStatusCode start_worker_status) {
+ if (start_worker_status != blink::ServiceWorkerStatusCode::kOk)
return;
DispatchChangeEvent(std::move(registration), cookie, cause);
}
diff --git a/chromium/content/browser/cookie_store/cookie_store_manager.h b/chromium/content/browser/cookie_store/cookie_store_manager.h
index 19ccf7333b1..ce506e744f9 100644
--- a/chromium/content/browser/cookie_store/cookie_store_manager.h
+++ b/chromium/content/browser/cookie_store/cookie_store_manager.h
@@ -105,7 +105,7 @@ class CookieStoreManager : public ServiceWorkerContextCoreObserver,
void ProcessOnDiskSubscriptions(
base::OnceCallback<void(bool)> load_callback,
const std::vector<std::pair<int64_t, std::string>>& user_data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// Runs all the callbacks waiting for on-disk subscription data.
//
@@ -145,7 +145,7 @@ class CookieStoreManager : public ServiceWorkerContextCoreObserver,
scoped_refptr<ServiceWorkerRegistration> registration,
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
- ServiceWorkerStatusCode start_worker_status);
+ blink::ServiceWorkerStatusCode start_worker_status);
// Used to efficiently implement OnRegistrationDeleted().
//
diff --git a/chromium/content/browser/cookie_store/cookie_store_manager_unittest.cc b/chromium/content/browser/cookie_store/cookie_store_manager_unittest.cc
index 68c926cab07..b74748e9a2a 100644
--- a/chromium/content/browser/cookie_store/cookie_store_manager_unittest.cc
+++ b/chromium/content/browser/cookie_store/cookie_store_manager_unittest.cc
@@ -13,7 +13,7 @@
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/storage_partition_impl.h"
-#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker.mojom.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -116,7 +116,7 @@ class CookieStoreWorkerTestHelper : public EmbeddedWorkerTestHelper {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
@@ -129,15 +129,14 @@ class CookieStoreWorkerTestHelper : public EmbeddedWorkerTestHelper {
EmbeddedWorkerTestHelper::OnStartWorker(
embedded_worker_id, service_worker_version_id, scope, script_url,
- pause_after_download, std::move(dispatcher_request),
+ pause_after_download, std::move(service_worker_request),
std::move(controller_request), std::move(instance_host),
std::move(provider_info), std::move(installed_scripts_info));
}
// Cookie change subscriptions can only be created in this event handler.
void OnInstallEvent(
- mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
- callback) override {
+ mojom::ServiceWorker::DispatchInstallEventCallback callback) override {
for (auto& subscriptions : install_subscription_batches_) {
cookie_store_service_->AppendSubscriptions(
service_worker_registration_id_, std::move(subscriptions),
@@ -152,8 +151,7 @@ class CookieStoreWorkerTestHelper : public EmbeddedWorkerTestHelper {
// Used to implement WaitForActivateEvent().
void OnActivateEvent(
- mojom::ServiceWorkerEventDispatcher::DispatchActivateEventCallback
- callback) override {
+ mojom::ServiceWorker::DispatchActivateEventCallback callback) override {
if (quit_on_activate_) {
quit_on_activate_->Quit();
quit_on_activate_ = nullptr;
@@ -165,8 +163,8 @@ class CookieStoreWorkerTestHelper : public EmbeddedWorkerTestHelper {
void OnCookieChangeEvent(
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
- mojom::ServiceWorkerEventDispatcher::DispatchCookieChangeEventCallback
- callback) override {
+ mojom::ServiceWorker::DispatchCookieChangeEventCallback callback)
+ override {
changes_.emplace_back(cookie, cause);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
@@ -270,13 +268,13 @@ class CookieStoreManagerTest
GURL(script_url), options,
base::BindOnce(
[](base::RunLoop* run_loop, bool* success, int64_t* registration_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t service_worker_registration_id) {
- *success = (status == SERVICE_WORKER_OK);
+ *success = (status == blink::ServiceWorkerStatusCode::kOk);
*registration_id = service_worker_registration_id;
- EXPECT_EQ(SERVICE_WORKER_OK, status)
- << ServiceWorkerStatusToString(status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
+ << blink::ServiceWorkerStatusToString(status);
run_loop->Quit();
},
&run_loop, &success, &registration_id));
@@ -288,19 +286,8 @@ class CookieStoreManagerTest
return registration_id;
}
- // Simplified helper for SetCanonicalCookie.
- //
- // Creates a CanonicalCookie that is not secure, not http-only,
- // and not restricted to first parties. Returns false if creation fails.
- bool SetSessionCookie(const char* name,
- const char* value,
- const char* domain,
- const char* path) {
- net::CanonicalCookie cookie(
- name, value, domain, path, base::Time(), base::Time(), base::Time(),
- /* secure = */ false,
- /* httponly = */ false, net::CookieSameSite::NO_RESTRICTION,
- net::COOKIE_PRIORITY_DEFAULT);
+ // Synchronous helper for CookieManager::SetCanonicalCookie.
+ bool SetCanonicalCookie(const net::CanonicalCookie& cookie) {
base::RunLoop run_loop;
bool success = false;
cookie_manager_->SetCanonicalCookie(
@@ -315,6 +302,21 @@ class CookieStoreManagerTest
return success;
}
+ // Simplified helper for SetCanonicalCookie.
+ //
+ // Creates a CanonicalCookie that is not secure, not http-only,
+ // and not restricted to first parties. Returns false if creation fails.
+ bool SetSessionCookie(const char* name,
+ const char* value,
+ const char* domain,
+ const char* path) {
+ return 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));
+ }
+
bool reset_context_during_test() const { return GetParam(); }
static constexpr const int64_t kInvalidRegistrationId = -1;
@@ -824,6 +826,58 @@ TEST_P(CookieStoreManagerTest, CookieChangeUrl) {
worker_test_helper_->changes()[0].second);
}
+TEST_P(CookieStoreManagerTest, HttpOnlyCookieChange) {
+ std::vector<CookieStoreSync::Subscriptions> batches;
+ batches.emplace_back();
+
+ CookieStoreSync::Subscriptions& subscriptions = batches.back();
+ subscriptions.emplace_back(blink::mojom::CookieChangeSubscription::New());
+ subscriptions.back()->name = "";
+ subscriptions.back()->match_type =
+ ::network::mojom::CookieMatchType::STARTS_WITH;
+ subscriptions.back()->url = GURL(kExampleScope);
+
+ worker_test_helper_->SetOnInstallSubscriptions(std::move(batches),
+ example_service_ptr_.get());
+ int64_t registration_id =
+ RegisterServiceWorker(kExampleScope, kExampleWorkerScript);
+ ASSERT_NE(registration_id, kInvalidRegistrationId);
+
+ base::Optional<CookieStoreSync::Subscriptions> all_subscriptions_opt =
+ example_service_->GetSubscriptions(registration_id);
+ ASSERT_TRUE(all_subscriptions_opt.has_value());
+ ASSERT_EQ(1u, all_subscriptions_opt.value().size());
+
+ if (reset_context_during_test())
+ ResetServiceWorkerContext();
+
+ ASSERT_TRUE(SetCanonicalCookie(net::CanonicalCookie(
+ "cookie-name-1", "cookie-value-1", "example.com", "/", base::Time(),
+ base::Time(), base::Time(),
+ /* secure = */ false,
+ /* httponly = */ true, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_DEFAULT)));
+ thread_bundle_.RunUntilIdle();
+ EXPECT_EQ(0u, worker_test_helper_->changes().size());
+
+ worker_test_helper_->changes().clear();
+ ASSERT_TRUE(SetCanonicalCookie(net::CanonicalCookie(
+ "cookie-name-2", "cookie-value-2", "example.com", "/", base::Time(),
+ base::Time(), base::Time(),
+ /* secure = */ false,
+ /* httponly = */ false, net::CookieSameSite::NO_RESTRICTION,
+ net::COOKIE_PRIORITY_DEFAULT)));
+ thread_bundle_.RunUntilIdle();
+
+ ASSERT_EQ(1u, worker_test_helper_->changes().size());
+ EXPECT_EQ("cookie-name-2", worker_test_helper_->changes()[0].first.Name());
+ EXPECT_EQ("cookie-value-2", worker_test_helper_->changes()[0].first.Value());
+ EXPECT_EQ("example.com", worker_test_helper_->changes()[0].first.Domain());
+ EXPECT_EQ("/", worker_test_helper_->changes()[0].first.Path());
+ EXPECT_EQ(::network::mojom::CookieChangeCause::INSERTED,
+ worker_test_helper_->changes()[0].second);
+}
+
TEST_P(CookieStoreManagerTest, GetSubscriptionsFromWrongOrigin) {
std::vector<CookieStoreSync::Subscriptions> batches;
batches.emplace_back();
diff --git a/chromium/content/browser/dedicated_worker/dedicated_worker_host.cc b/chromium/content/browser/dedicated_worker/dedicated_worker_host.cc
index 86b2b534245..7eccbe6db70 100644
--- a/chromium/content/browser/dedicated_worker/dedicated_worker_host.cc
+++ b/chromium/content/browser/dedicated_worker/dedicated_worker_host.cc
@@ -11,6 +11,7 @@
#include "content/browser/interface_provider_filtering.h"
#include "content/browser/renderer_interface_binders.h"
#include "content/browser/websockets/websocket_manager.h"
+#include "content/public/browser/render_frame_host.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"
@@ -27,10 +28,10 @@ namespace {
class DedicatedWorkerHost : public service_manager::mojom::InterfaceProvider {
public:
DedicatedWorkerHost(int process_id,
- int parent_render_frame_id,
+ int ancestor_render_frame_id,
const url::Origin& origin)
: process_id_(process_id),
- parent_render_frame_id_(parent_render_frame_id),
+ ancestor_render_frame_id_(ancestor_render_frame_id),
origin_(origin) {
RegisterMojoInterfaces();
}
@@ -53,22 +54,52 @@ class DedicatedWorkerHost : public service_manager::mojom::InterfaceProvider {
private:
void RegisterMojoInterfaces() {
- registry_.AddInterface(
- base::BindRepeating(&WebSocketManager::CreateWebSocket, process_id_,
- parent_render_frame_id_, origin_));
+ registry_.AddInterface(base::BindRepeating(
+ &DedicatedWorkerHost::CreateWebSocket, base::Unretained(this)));
registry_.AddInterface(base::BindRepeating(
&DedicatedWorkerHost::CreateUsbDeviceManager, base::Unretained(this)));
+ registry_.AddInterface(base::BindRepeating(
+ &DedicatedWorkerHost::CreateDedicatedWorker, base::Unretained(this)));
}
void CreateUsbDeviceManager(device::mojom::UsbDeviceManagerRequest request) {
auto* host =
- RenderFrameHostImpl::FromID(process_id_, parent_render_frame_id_);
+ RenderFrameHostImpl::FromID(process_id_, ancestor_render_frame_id_);
GetContentClient()->browser()->CreateUsbDeviceManager(host,
std::move(request));
}
+ void CreateWebSocket(network::mojom::WebSocketRequest request) {
+ network::mojom::AuthenticationHandlerPtr auth_handler;
+ auto* frame =
+ RenderFrameHost::FromID(process_id_, ancestor_render_frame_id_);
+ if (!frame) {
+ // In some cases |frame| can be null. In such cases the worker will
+ // soon be terminated too, so let's abort the connection.
+ request.ResetWithReason(network::mojom::WebSocket::kInsufficientResources,
+ "The parent frame has already been gone.");
+ return;
+ }
+
+ GetContentClient()->browser()->WillCreateWebSocket(frame, &request,
+ &auth_handler);
+
+ WebSocketManager::CreateWebSocket(process_id_, ancestor_render_frame_id_,
+ origin_, std::move(auth_handler),
+ std::move(request));
+ }
+
+ void CreateDedicatedWorker(
+ blink::mojom::DedicatedWorkerFactoryRequest request) {
+ CreateDedicatedWorkerHostFactory(process_id_, ancestor_render_frame_id_,
+ origin_, std::move(request));
+ }
+
const int process_id_;
- const int parent_render_frame_id_;
+ // ancestor_render_frame_id_ is the id of the frame that owns this worker,
+ // either directly, or (in the case of nested workers) indirectly via a tree
+ // of dedicated workers.
+ const int ancestor_render_frame_id_;
const url::Origin origin_;
service_manager::BinderRegistry registry_;
@@ -81,10 +112,10 @@ class DedicatedWorkerHost : public service_manager::mojom::InterfaceProvider {
class DedicatedWorkerFactoryImpl : public blink::mojom::DedicatedWorkerFactory {
public:
DedicatedWorkerFactoryImpl(int process_id,
- int parent_render_frame_id,
+ int ancestor_render_frame_id,
const url::Origin& parent_context_origin)
: process_id_(process_id),
- parent_render_frame_id_(parent_render_frame_id),
+ ancestor_render_frame_id_(ancestor_render_frame_id),
parent_context_origin_(parent_context_origin) {}
// blink::mojom::DedicatedWorkerFactory:
@@ -95,7 +126,7 @@ class DedicatedWorkerFactoryImpl : public blink::mojom::DedicatedWorkerFactory {
// 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_, parent_render_frame_id_, origin),
+ process_id_, ancestor_render_frame_id_, origin),
FilterRendererExposedInterfaces(
blink::mojom::kNavigation_DedicatedWorkerSpec,
process_id_, std::move(request)));
@@ -103,7 +134,7 @@ class DedicatedWorkerFactoryImpl : public blink::mojom::DedicatedWorkerFactory {
private:
const int process_id_;
- const int parent_render_frame_id_;
+ const int ancestor_render_frame_id_;
const url::Origin parent_context_origin_;
DISALLOW_COPY_AND_ASSIGN(DedicatedWorkerFactoryImpl);
@@ -113,11 +144,11 @@ class DedicatedWorkerFactoryImpl : public blink::mojom::DedicatedWorkerFactory {
void CreateDedicatedWorkerHostFactory(
int process_id,
- int parent_render_frame_id,
+ int ancestor_render_frame_id,
const url::Origin& origin,
blink::mojom::DedicatedWorkerFactoryRequest request) {
mojo::MakeStrongBinding(std::make_unique<DedicatedWorkerFactoryImpl>(
- process_id, parent_render_frame_id, origin),
+ process_id, ancestor_render_frame_id, origin),
std::move(request));
}
diff --git a/chromium/content/browser/device_sensors/device_sensor_browsertest.cc b/chromium/content/browser/device_sensors/device_sensor_browsertest.cc
index 494c1c7acc1..2829fe11923 100644
--- a/chromium/content/browser/device_sensors/device_sensor_browsertest.cc
+++ b/chromium/content/browser/device_sensors/device_sensor_browsertest.cc
@@ -9,7 +9,6 @@
#include "base/command_line.h"
#include "base/macros.h"
#include "base/run_loop.h"
-#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"
@@ -44,10 +43,20 @@ using device::FakeSensorProvider;
class DeviceSensorBrowserTest : public ContentBrowserTest {
public:
- DeviceSensorBrowserTest()
- : io_loop_finished_event_(
- base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED) {}
+ DeviceSensorBrowserTest() {
+ // Because Device Service also runs in this process (browser process), here
+ // we can directly set our binder to intercept interface requests against
+ // it.
+ service_manager::ServiceContext::SetGlobalBinderForTesting(
+ device::mojom::kServiceName, device::mojom::SensorProvider::Name_,
+ base::BindRepeating(&DeviceSensorBrowserTest::Bind,
+ base::Unretained(this)));
+ }
+
+ ~DeviceSensorBrowserTest() override {
+ service_manager::ServiceContext::ClearGlobalBindersForTesting(
+ device::mojom::kServiceName);
+ }
void SetUpOnMainThread() override {
https_embedded_test_server_.reset(
@@ -66,11 +75,6 @@ class DeviceSensorBrowserTest : public ContentBrowserTest {
sensor_provider_->SetGyroscopeData(7, 8, 9);
sensor_provider_->SetRelativeOrientationSensorData(1, 2, 3);
sensor_provider_->SetAbsoluteOrientationSensorData(4, 5, 6);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&DeviceSensorBrowserTest::SetUpOnIOThread,
- base::Unretained(this)));
- io_loop_finished_event_.Wait();
}
void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -79,17 +83,6 @@ class DeviceSensorBrowserTest : public ContentBrowserTest {
command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
}
- void SetUpOnIOThread() {
- // Because Device Service also runs in this process(browser process), here
- // we can directly set our binder to intercept interface requests against
- // it.
- service_manager::ServiceContext::SetGlobalBinderForTesting(
- device::mojom::kServiceName, device::mojom::SensorProvider::Name_,
- base::Bind(&DeviceSensorBrowserTest::Bind, base::Unretained(this)));
-
- io_loop_finished_event_.Signal();
- }
-
void DelayAndQuit(base::TimeDelta delay) {
base::PlatformThread::Sleep(delay);
base::RunLoop::QuitCurrentWhenIdleDeprecated();
@@ -117,8 +110,6 @@ class DeviceSensorBrowserTest : public ContentBrowserTest {
sensor_provider_->Bind(
device::mojom::SensorProviderRequest(std::move(handle)));
}
-
- base::WaitableEvent io_loop_finished_event_;
};
IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest, OrientationTest) {
@@ -364,7 +355,7 @@ IN_PROC_BROWSER_TEST_F(DeviceSensorBrowserTest,
"The deviceorientationabsolute events are blocked by "
"feature policy. See "
"https://github.com/WICG/feature-policy/blob/"
- "gh-pages/features.md#sensor-features";
+ "master/features.md#sensor-features";
auto console_delegate = std::make_unique<ConsoleObserverDelegate>(
shell()->web_contents(), kWarningMessage);
diff --git a/chromium/content/browser/devtools/README.md b/chromium/content/browser/devtools/README.md
new file mode 100644
index 00000000000..e0315182b14
--- /dev/null
+++ b/chromium/content/browser/devtools/README.md
@@ -0,0 +1,3 @@
+# Chrome DevTools Protocol
+
+Contributing to Chrome DevTools Protocol: [docs.google.com](https://docs.google.com/document/d/1c-COD2kaK__5iMM5SEx-PzNA7HFmgttcYfOHHX0HaOM/edit?usp=sharing).
diff --git a/chromium/content/browser/devtools/browser_devtools_agent_host.cc b/chromium/content/browser/devtools/browser_devtools_agent_host.cc
index bd0c4705380..5bdec4f820f 100644
--- a/chromium/content/browser/devtools/browser_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/browser_devtools_agent_host.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "base/guid.h"
+#include "base/json/json_reader.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "content/browser/devtools/devtools_session.h"
@@ -18,6 +19,7 @@
#include "content/browser/devtools/protocol/target_handler.h"
#include "content/browser/devtools/protocol/tethering_handler.h"
#include "content/browser/devtools/protocol/tracing_handler.h"
+#include "content/browser/devtools/target_registry.h"
#include "content/browser/frame_host/frame_tree_node.h"
namespace content {
@@ -48,30 +50,40 @@ BrowserDevToolsAgentHost::BrowserDevToolsAgentHost(
BrowserDevToolsAgentHost::~BrowserDevToolsAgentHost() {
}
-bool BrowserDevToolsAgentHost::AttachSession(DevToolsSession* session) {
+bool BrowserDevToolsAgentHost::AttachSession(DevToolsSession* session,
+ TargetRegistry* parent_registry) {
if (session->restricted())
return false;
+ TargetRegistry* registry = parent_registry;
+ if (!registry) {
+ auto new_registry = std::make_unique<TargetRegistry>(session);
+ registry = new_registry.get();
+ target_registries_[session->client()] = std::move(new_registry);
+ }
session->SetBrowserOnly(true);
- session->AddHandler(
- base::WrapUnique(new protocol::TargetHandler(true /* browser_only */)));
+ session->AddHandler(std::make_unique<protocol::TargetHandler>(
+ true /* browser_only */, GetId(), registry));
if (only_discovery_)
return true;
- session->AddHandler(base::WrapUnique(new protocol::BrowserHandler()));
- session->AddHandler(base::WrapUnique(new protocol::IOHandler(
- GetIOContext())));
- session->AddHandler(base::WrapUnique(new protocol::MemoryHandler()));
- session->AddHandler(base::WrapUnique(new protocol::SecurityHandler()));
- session->AddHandler(base::WrapUnique(new protocol::SystemInfoHandler()));
- session->AddHandler(base::WrapUnique(new protocol::TetheringHandler(
- socket_callback_, tethering_task_runner_)));
+ session->AddHandler(std::make_unique<protocol::BrowserHandler>());
+ session->AddHandler(std::make_unique<protocol::IOHandler>(GetIOContext()));
+ session->AddHandler(std::make_unique<protocol::MemoryHandler>());
+ session->AddHandler(std::make_unique<protocol::SecurityHandler>());
+ session->AddHandler(std::make_unique<protocol::SystemInfoHandler>());
+ if (tethering_task_runner_) {
+ session->AddHandler(std::make_unique<protocol::TetheringHandler>(
+ socket_callback_, tethering_task_runner_));
+ }
session->AddHandler(
- base::WrapUnique(new protocol::TracingHandler(nullptr, GetIOContext())));
+ std::make_unique<protocol::TracingHandler>(nullptr, GetIOContext()));
return true;
}
-void BrowserDevToolsAgentHost::DetachSession(DevToolsSession* session) {}
+void BrowserDevToolsAgentHost::DetachSession(DevToolsSession* session) {
+ target_registries_.erase(session->client());
+}
std::string BrowserDevToolsAgentHost::GetType() {
return kTypeBrowser;
@@ -96,10 +108,17 @@ bool BrowserDevToolsAgentHost::Close() {
void BrowserDevToolsAgentHost::Reload() {
}
-void BrowserDevToolsAgentHost::DispatchProtocolMessage(
- DevToolsSession* session,
- const std::string& message) {
- session->DispatchProtocolMessage(message);
+bool BrowserDevToolsAgentHost::DispatchProtocolMessage(
+ DevToolsAgentHostClient* client,
+ const std::string& message,
+ base::DictionaryValue* parsed_message) {
+ auto it = target_registries_.find(client);
+ if (it != target_registries_.end() &&
+ it->second->DispatchMessageOnAgentHost(message, parsed_message)) {
+ return true;
+ }
+ return DevToolsAgentHostImpl::DispatchProtocolMessage(client, message,
+ parsed_message);
}
} // content
diff --git a/chromium/content/browser/devtools/browser_devtools_agent_host.h b/chromium/content/browser/devtools/browser_devtools_agent_host.h
index 7022e2d167c..29963484035 100644
--- a/chromium/content/browser/devtools/browser_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/browser_devtools_agent_host.h
@@ -5,10 +5,13 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_BROWSER_DEVTOOLS_AGENT_HOST_H_
#define CONTENT_BROWSER_DEVTOOLS_BROWSER_DEVTOOLS_AGENT_HOST_H_
+#include "base/containers/flat_map.h"
#include "content/browser/devtools/devtools_agent_host_impl.h"
namespace content {
+class TargetRegistry;
+
class BrowserDevToolsAgentHost : public DevToolsAgentHostImpl {
private:
friend class DevToolsAgentHost;
@@ -18,11 +21,13 @@ class BrowserDevToolsAgentHost : public DevToolsAgentHostImpl {
bool only_discovery);
~BrowserDevToolsAgentHost() override;
- // DevToolsAgentHostImpl implementation.
- bool AttachSession(DevToolsSession* session) override;
+ // DevToolsAgentHostImpl overrides.
+ bool AttachSession(DevToolsSession* session,
+ TargetRegistry* registry) override;
void DetachSession(DevToolsSession* session) override;
- void DispatchProtocolMessage(DevToolsSession* session,
- const std::string& message) override;
+ bool DispatchProtocolMessage(DevToolsAgentHostClient* client,
+ const std::string& message,
+ base::DictionaryValue* parsed_message) override;
// DevToolsAgentHost implementation.
std::string GetType() override;
@@ -35,6 +40,8 @@ class BrowserDevToolsAgentHost : public DevToolsAgentHostImpl {
scoped_refptr<base::SingleThreadTaskRunner> tethering_task_runner_;
CreateServerSocketCallback socket_callback_;
bool only_discovery_;
+ base::flat_map<DevToolsAgentHostClient*, std::unique_ptr<TargetRegistry>>
+ target_registries_;
};
} // 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 a67148429f1..273ca40034c 100644
--- a/chromium/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/chromium/content/browser/devtools/devtools_agent_host_impl.cc
@@ -8,6 +8,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/lazy_instance.h"
#include "base/observer_list.h"
@@ -176,12 +177,13 @@ DevToolsSession* DevToolsAgentHostImpl::SessionByClient(
}
bool DevToolsAgentHostImpl::InnerAttachClient(DevToolsAgentHostClient* client,
+ TargetRegistry* registry,
bool restricted) {
scoped_refptr<DevToolsAgentHostImpl> protect(this);
DevToolsSession* session = new DevToolsSession(this, client, restricted);
sessions_.insert(session);
session_by_client_[client].reset(session);
- if (!AttachSession(session)) {
+ if (!AttachSession(session, registry)) {
sessions_.erase(session);
session_by_client_.erase(client);
return false;
@@ -198,14 +200,22 @@ bool DevToolsAgentHostImpl::InnerAttachClient(DevToolsAgentHostClient* client,
void DevToolsAgentHostImpl::AttachClient(DevToolsAgentHostClient* client) {
if (SessionByClient(client))
return;
- InnerAttachClient(client, false /* restricted */);
+ InnerAttachClient(client, nullptr, false /* restricted */);
+}
+
+void DevToolsAgentHostImpl::AttachSubtargetClient(
+ DevToolsAgentHostClient* client,
+ TargetRegistry* registry) {
+ if (SessionByClient(client))
+ return;
+ InnerAttachClient(client, registry, false /* restricted */);
}
bool DevToolsAgentHostImpl::AttachRestrictedClient(
DevToolsAgentHostClient* client) {
if (SessionByClient(client))
return false;
- return InnerAttachClient(client, true /* restricted */);
+ return InnerAttachClient(client, nullptr, true /* restricted */);
}
bool DevToolsAgentHostImpl::DetachClient(DevToolsAgentHostClient* client) {
@@ -220,16 +230,29 @@ bool DevToolsAgentHostImpl::DetachClient(DevToolsAgentHostClient* client) {
bool DevToolsAgentHostImpl::DispatchProtocolMessage(
DevToolsAgentHostClient* client,
const std::string& message) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(message);
+ if (value && !value->is_dict())
+ value.reset();
+ return DispatchProtocolMessage(
+ client, message, static_cast<base::DictionaryValue*>(value.get()));
+}
+
+bool DevToolsAgentHostImpl::DispatchProtocolMessage(
+ DevToolsAgentHostClient* client,
+ const std::string& message,
+ base::DictionaryValue* parsed_message) {
DevToolsSession* session = SessionByClient(client);
if (!session)
return false;
- DispatchProtocolMessage(session, message);
+ session->DispatchProtocolMessage(message, parsed_message);
return true;
}
void DevToolsAgentHostImpl::InnerDetachClient(DevToolsAgentHostClient* client) {
std::unique_ptr<DevToolsSession> session =
std::move(session_by_client_[client]);
+ // Make sure we dispose session prior to reporting it to the host.
+ session->Dispose();
sessions_.erase(session.get());
session_by_client_.erase(client);
DetachSession(session.get());
@@ -310,32 +333,24 @@ void DevToolsAgentHostImpl::ForceDetachAllSessions() {
}
}
-void DevToolsAgentHostImpl::ForceDetachRestrictedSessions() {
- if (sessions_.empty())
- return;
+void DevToolsAgentHostImpl::ForceDetachRestrictedSessions(
+ const std::vector<DevToolsSession*>& restricted_sessions) {
scoped_refptr<DevToolsAgentHostImpl> protect(this);
- std::vector<DevToolsSession*> restricted;
- for (DevToolsSession* session : sessions_) {
- if (session->restricted())
- restricted.push_back(session);
- }
- for (DevToolsSession* session : restricted) {
+
+ for (DevToolsSession* session : restricted_sessions) {
DevToolsAgentHostClient* client = session->client();
DetachClient(client);
client->AgentHostClosed(this);
}
}
-bool DevToolsAgentHostImpl::AttachSession(DevToolsSession* session) {
+bool DevToolsAgentHostImpl::AttachSession(DevToolsSession* session,
+ TargetRegistry* registry) {
return false;
}
void DevToolsAgentHostImpl::DetachSession(DevToolsSession* session) {}
-void DevToolsAgentHostImpl::DispatchProtocolMessage(
- DevToolsSession* session,
- const std::string& message) {}
-
// static
void DevToolsAgentHost::DetachAllClients() {
if (!g_devtools_instances.IsCreated())
@@ -343,11 +358,14 @@ void DevToolsAgentHost::DetachAllClients() {
// Make a copy, since detaching may lead to agent destruction, which
// removes it from the instances.
- DevToolsMap copy = g_devtools_instances.Get();
- for (DevToolsMap::iterator it(copy.begin()); it != copy.end(); ++it) {
- DevToolsAgentHostImpl* agent_host = it->second;
- agent_host->ForceDetachAllSessions();
- }
+ std::vector<scoped_refptr<DevToolsAgentHostImpl>> copy;
+ for (DevToolsMap::iterator it(g_devtools_instances.Get().begin());
+ it != g_devtools_instances.Get().end(); ++it)
+ copy.push_back(it->second);
+ for (std::vector<scoped_refptr<DevToolsAgentHostImpl>>::iterator it(
+ copy.begin());
+ it != copy.end(); ++it)
+ it->get()->ForceDetachAllSessions();
}
// static
@@ -400,6 +418,11 @@ void DevToolsAgentHostImpl::NotifyDetached() {
observer.DevToolsAgentHostDetached(this);
}
+void DevToolsAgentHostImpl::NotifyCrashed(base::TerminationStatus status) {
+ for (auto& observer : g_devtools_observers.Get())
+ observer.DevToolsAgentHostCrashed(this, status);
+}
+
void DevToolsAgentHostImpl::NotifyDestroyed() {
DCHECK(g_devtools_instances.Get().find(id_) !=
g_devtools_instances.Get().end());
diff --git a/chromium/content/browser/devtools/devtools_agent_host_impl.h b/chromium/content/browser/devtools/devtools_agent_host_impl.h
index 6831704222e..b258f840c9b 100644
--- a/chromium/content/browser/devtools/devtools_agent_host_impl.h
+++ b/chromium/content/browser/devtools/devtools_agent_host_impl.h
@@ -12,6 +12,7 @@
#include "base/compiler_specific.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
+#include "base/process/kill.h"
#include "content/browser/devtools/devtools_io_context.h"
#include "content/common/content_export.h"
#include "content/public/browser/certificate_request_result_type.h"
@@ -22,6 +23,7 @@ namespace content {
class BrowserContext;
class DevToolsSession;
+class TargetRegistry;
// Describes interface for managing devtools agents from the browser process.
class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
@@ -64,29 +66,42 @@ class CONTENT_EXPORT DevToolsAgentHostImpl : public DevToolsAgentHost {
static bool ShouldForceCreation();
// Returning |false| will block the attach.
- virtual bool AttachSession(DevToolsSession* session);
+ virtual bool AttachSession(DevToolsSession* session,
+ TargetRegistry* registry);
virtual void DetachSession(DevToolsSession* session);
- virtual void DispatchProtocolMessage(DevToolsSession* session,
- const std::string& message);
+
+ virtual bool DispatchProtocolMessage(DevToolsAgentHostClient* client,
+ const std::string& message,
+ base::DictionaryValue* parsed_message);
void NotifyCreated();
void NotifyNavigated();
+ void NotifyCrashed(base::TerminationStatus status);
void ForceDetachAllSessions();
- void ForceDetachRestrictedSessions();
+ void ForceDetachRestrictedSessions(
+ const std::vector<DevToolsSession*>& restricted_sessions);
DevToolsIOContext* GetIOContext() { return &io_context_; }
base::flat_set<DevToolsSession*>& sessions() { return sessions_; }
private:
- friend class DevToolsAgentHost; // for static methods
+ friend class DevToolsAgentHost; // for static methods
friend class DevToolsSession;
- bool InnerAttachClient(DevToolsAgentHostClient* client, bool restricted);
+ friend class TargetRegistry; // for subtarget management
+
+ bool InnerAttachClient(DevToolsAgentHostClient* client,
+ TargetRegistry* registry,
+ bool restricted);
void InnerDetachClient(DevToolsAgentHostClient* client);
void NotifyAttached();
void NotifyDetached();
void NotifyDestroyed();
DevToolsSession* SessionByClient(DevToolsAgentHostClient* client);
+ // TargetRegistry API for subtarget management.
+ void AttachSubtargetClient(DevToolsAgentHostClient* client,
+ TargetRegistry* registry);
+
const std::string id_;
base::flat_set<DevToolsSession*> sessions_;
base::flat_map<DevToolsAgentHostClient*, std::unique_ptr<DevToolsSession>>
diff --git a/chromium/content/browser/devtools/devtools_http_handler.cc b/chromium/content/browser/devtools/devtools_http_handler.cc
index c9187e77495..eaf44246e9e 100644
--- a/chromium/content/browser/devtools/devtools_http_handler.cc
+++ b/chromium/content/browser/devtools/devtools_http_handler.cc
@@ -289,7 +289,10 @@ void StartServerOnHandlerThread(
}
}
} else {
- LOG(ERROR) << "Cannot start http server for devtools. Stop devtools.";
+#if !defined(OS_ANDROID)
+ // Android uses UNIX domain sockets which don't have an IP address.
+ LOG(ERROR) << "Cannot start http server for devtools.";
+#endif
}
BrowserThread::PostTask(
diff --git a/chromium/content/browser/devtools/devtools_manager_unittest.cc b/chromium/content/browser/devtools/devtools_manager_unittest.cc
index b945b03f214..affaef82158 100644
--- a/chromium/content/browser/devtools/devtools_manager_unittest.cc
+++ b/chromium/content/browser/devtools/devtools_manager_unittest.cc
@@ -4,7 +4,10 @@
#include "content/browser/devtools/devtools_manager.h"
+#include <map>
#include <memory>
+#include <string>
+#include <utility>
#include "base/guid.h"
#include "base/location.h"
@@ -84,8 +87,10 @@ class TestWebContentsDelegate : public WebContentsDelegate {
TestWebContentsDelegate() : renderer_unresponsive_received_(false) {}
// Notification that the contents is hung.
- void RendererUnresponsive(WebContents* source,
- RenderWidgetHost* render_widget_host) override {
+ void RendererUnresponsive(
+ WebContents* source,
+ RenderWidgetHost* render_widget_host,
+ base::RepeatingClosure hang_monitor_restarter) override {
renderer_unresponsive_received_ = true;
}
@@ -141,25 +146,32 @@ TEST_F(DevToolsManagerTest, NoUnresponsiveDialogInInspectedContents) {
client_host.InspectAgentHost(agent_host.get());
// Start with a short timeout.
- inspected_rvh->GetWidget()->StartHangMonitorTimeout(
+ inspected_rvh->GetWidget()->StartInputEventAckTimeout(
TimeDelta::FromMilliseconds(10));
- // Wait long enough for first timeout and see if it fired.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMilliseconds(10));
- base::RunLoop().Run();
+ {
+ base::RunLoop run_loop;
+ // Wait long enough for first timeout and see if it fired. We use quit-when-
+ // idle so that all tasks due after the timeout get a chance to run.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitWhenIdleClosure(),
+ TimeDelta::FromMilliseconds(10));
+ run_loop.Run();
+ }
EXPECT_FALSE(delegate.renderer_unresponsive_received());
// Now close devtools and check that the notification is delivered.
client_host.Close();
// Start with a short timeout.
- inspected_rvh->GetWidget()->StartHangMonitorTimeout(
- TimeDelta::FromMilliseconds(10));
- // Wait long enough for first timeout and see if it fired.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
+ inspected_rvh->GetWidget()->StartInputEventAckTimeout(
TimeDelta::FromMilliseconds(10));
- base::RunLoop().Run();
+ {
+ base::RunLoop run_loop;
+ // Wait long enough for first timeout and see if it fired.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitWhenIdleClosure(),
+ TimeDelta::FromMilliseconds(10));
+ run_loop.Run();
+ }
EXPECT_TRUE(delegate.renderer_unresponsive_received());
contents()->SetDelegate(nullptr);
@@ -178,7 +190,7 @@ class TestExternalAgentDelegate: public DevToolsExternalAgentProxyDelegate {
}
private:
- std::map<std::string,int> event_counter_;
+ std::map<std::string, int> event_counter_;
void recordEvent(const std::string& name) {
if (event_counter_.find(name) == event_counter_.end())
@@ -213,7 +225,6 @@ class TestExternalAgentDelegate: public DevToolsExternalAgentProxyDelegate {
const std::string& message) override {
recordEvent(std::string("SendMessageToBackend.") + message);
};
-
};
TEST_F(DevToolsManagerTest, TestExternalProxy) {
diff --git a/chromium/content/browser/devtools/devtools_pipe_handler.cc b/chromium/content/browser/devtools/devtools_pipe_handler.cc
index 4fbea246102..dcdce1fe0ef 100644
--- a/chromium/content/browser/devtools/devtools_pipe_handler.cc
+++ b/chromium/content/browser/devtools/devtools_pipe_handler.cc
@@ -66,9 +66,9 @@ void WriteIntoPipe(int write_fd, const std::string& message) {
}
#if defined(OS_WIN)
DWORD result = 0;
- WriteFile(handle, "\n", 1, &result, nullptr);
+ WriteFile(handle, "\0", 1, &result, nullptr);
#else
- int result = write(write_fd, "\n", 1);
+ int result = write(write_fd, "\0", 1);
#endif
if (!result) {
LOG(ERROR) << "Could not write into pipe";
@@ -145,11 +145,11 @@ bool PipeReader::HandleReadResult(int result) {
read_buffer_->DidRead(result);
- // Go over the last read chunk, look for \n, extract messages.
+ // Go over the last read chunk, look for \0, extract messages.
int offset = 0;
for (int i = read_buffer_->GetSize() - result; i < read_buffer_->GetSize();
++i) {
- if (read_buffer_->StartOfBuffer()[i] == '\n') {
+ if (read_buffer_->StartOfBuffer()[i] == '\0') {
std::string str(read_buffer_->StartOfBuffer() + offset, i - offset);
BrowserThread::PostTask(
@@ -190,7 +190,8 @@ DevToolsPipeHandler::DevToolsPipeHandler()
return;
}
- browser_target_ = DevToolsAgentHost::CreateForDiscovery();
+ browser_target_ = DevToolsAgentHost::CreateForBrowser(
+ nullptr, DevToolsAgentHost::CreateServerSocketCallback());
browser_target_->AttachClient(this);
pipe_reader_.reset(new PipeReader(weak_factory_.GetWeakPtr(), read_fd_));
diff --git a/chromium/content/browser/devtools/devtools_session.cc b/chromium/content/browser/devtools/devtools_session.cc
index 10a84a5ef0a..a82213afc24 100644
--- a/chromium/content/browser/devtools/devtools_session.cc
+++ b/chromium/content/browser/devtools/devtools_session.cc
@@ -46,6 +46,13 @@ DevToolsSession::DevToolsSession(DevToolsAgentHostImpl* agent_host,
}
DevToolsSession::~DevToolsSession() {
+ // It is Ok for session to be deleted without the dispose -
+ // it can be kicked out by an extension connect / disconnect.
+ if (dispatcher_)
+ Dispose();
+}
+
+void DevToolsSession::Dispose() {
dispatcher_.reset();
for (auto& pair : handlers_)
pair.second->Disable();
@@ -116,22 +123,19 @@ void DevToolsSession::MojoConnectionDestroyed() {
io_session_ptr_.reset();
}
-void DevToolsSession::DispatchProtocolMessage(const std::string& message) {
- std::unique_ptr<base::Value> value = base::JSONReader::Read(message);
-
+void DevToolsSession::DispatchProtocolMessage(
+ const std::string& message,
+ base::DictionaryValue* parsed_message) {
DevToolsManagerDelegate* delegate =
DevToolsManager::GetInstance()->delegate();
- if (value && value->is_dict() && delegate) {
- base::DictionaryValue* dict_value =
- static_cast<base::DictionaryValue*>(value.get());
-
- if (delegate->HandleCommand(agent_host_, client_, dict_value))
- return;
+ if (delegate && parsed_message &&
+ delegate->HandleCommand(agent_host_, client_, parsed_message)) {
+ return;
}
int call_id;
std::string method;
- if (dispatcher_->dispatch(protocol::toProtocolValue(value.get(), 1000),
+ if (dispatcher_->dispatch(protocol::toProtocolValue(parsed_message, 1000),
&call_id,
&method) != protocol::Response::kFallThrough) {
return;
diff --git a/chromium/content/browser/devtools/devtools_session.h b/chromium/content/browser/devtools/devtools_session.h
index 9ae28ad0097..2b2bccf785b 100644
--- a/chromium/content/browser/devtools/devtools_session.h
+++ b/chromium/content/browser/devtools/devtools_session.h
@@ -28,8 +28,10 @@ class DevToolsSession : public protocol::FrontendChannel,
DevToolsAgentHostClient* client,
bool restricted);
~DevToolsSession() override;
+ void Dispose();
bool restricted() { return restricted_; }
+ DevToolsAgentHost* agent_host() { return agent_host_; };
DevToolsAgentHostClient* client() { return client_; };
// Browser-only sessions do not talk to mojom::DevToolsAgent, but instead
@@ -41,7 +43,8 @@ class DevToolsSession : public protocol::FrontendChannel,
void SetRenderer(int process_host_id, RenderFrameHostImpl* frame_host);
void AttachToAgent(const blink::mojom::DevToolsAgentAssociatedPtr& agent);
- void DispatchProtocolMessage(const std::string& message);
+ void DispatchProtocolMessage(const std::string& message,
+ base::DictionaryValue* parsed_message);
void SuspendSendingMessagesToAgent();
void ResumeSendingMessagesToAgent();
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 abfa5795a0c..65329798837 100644
--- a/chromium/content/browser/devtools/devtools_url_interceptor_request_job.cc
+++ b/chromium/content/browser/devtools/devtools_url_interceptor_request_job.cc
@@ -9,7 +9,7 @@
#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/navigation_loader_util.h"
+#include "content/browser/loader/download_utils_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "ipc/ipc_channel.h"
#include "net/base/completion_once_callback.h"
@@ -18,12 +18,13 @@
#include "net/base/upload_bytes_element_reader.h"
#include "net/base/upload_element_reader.h"
#include "net/cert/cert_status_flags.h"
+#include "net/cookies/cookie_options.h"
+#include "net/cookies/cookie_store.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request_context.h"
#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
-
namespace {
static const int kInitialBufferSize = 4096;
static const int kMaxBufferSize = IPC::Channel::kMaximumMessageSize / 4;
@@ -105,8 +106,8 @@ DevToolsURLInterceptorRequestJob::SubRequest::SubRequest(
"This feature cannot be disabled in settings, however it happens "
"only when user is debugging a page."
chrome_policy {
- DeveloperToolsDisabled {
- DeveloperToolsDisabled: true
+ DeveloperToolsAvailability {
+ DeveloperToolsAvailability: 2
}
}
})");
@@ -551,8 +552,8 @@ bool IsDownload(net::URLRequest* orig_request, net::URLRequest* subrequest) {
std::string mime_type;
subrequest->GetMimeType(&mime_type);
return req_info->allow_download() &&
- navigation_loader_util::IsDownload(
- orig_request->url(), subrequest->response_headers(), mime_type);
+ download_utils::IsDownload(orig_request->url(),
+ subrequest->response_headers(), mime_type);
}
} // namespace
@@ -605,6 +606,30 @@ void DevToolsURLInterceptorRequestJob::SetExtraRequestHeaders(
void DevToolsURLInterceptorRequestJob::Start() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ auto* store = request_details_.url_request_context->cookie_store();
+ if (!store || (request()->load_flags() & net::LOAD_DO_NOT_SEND_COOKIES)) {
+ StartWithCookies(net::CookieList());
+ return;
+ }
+
+ net::CookieOptions options;
+ options.set_include_httponly();
+ if (request()->attach_same_site_cookies()) {
+ options.set_same_site_cookie_mode(
+ net::CookieOptions::SameSiteCookieMode::INCLUDE_STRICT_AND_LAX);
+ }
+ store->GetCookieListWithOptionsAsync(
+ request_details_.url, options,
+ base::BindOnce(&DevToolsURLInterceptorRequestJob::StartWithCookies,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void DevToolsURLInterceptorRequestJob::StartWithCookies(
+ const net::CookieList& cookie_list) {
+ request_details_.cookie_line =
+ net::CanonicalCookie::BuildCookieLine(cookie_list);
+
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (stage_to_intercept_ == InterceptionStage::DONT_INTERCEPT) {
sub_request_.reset(new SubRequest(request_details_, this, interceptor_));
return;
@@ -1057,7 +1082,8 @@ DevToolsURLInterceptorRequestJob::BuildRequestInfo() {
auto result = std::make_unique<InterceptedRequestInfo>();
result->interception_id = interception_id_;
result->network_request =
- protocol::NetworkHandler::CreateRequestFromURLRequest(request());
+ protocol::NetworkHandler::CreateRequestFromURLRequest(
+ request(), request_details_.cookie_line);
result->frame_id = devtools_token_;
result->resource_type = resource_type_;
result->is_navigation =
@@ -1086,7 +1112,7 @@ void DevToolsURLInterceptorRequestJob::ProcessInterceptionResponse(
// far, to minimize risk of breaking other usages.
ResourceRequestInfoImpl* resource_request_info =
ResourceRequestInfoImpl::ForRequest(request());
- resource_request_info->set_resource_request_blocked_reason(
+ resource_request_info->SetResourceRequestBlockedReason(
blink::ResourceRequestBlockedReason::kInspector);
}
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
@@ -1103,6 +1129,33 @@ void DevToolsURLInterceptorRequestJob::ProcessInterceptionResponse(
interceptor_->ExpectRequestAfterRedirect(request(), interception_id_);
}
+ // Set cookies in the network stack.
+ net::CookieOptions options;
+ options.set_include_httponly();
+ base::Time response_date;
+ if (!mock_response_details_->response_headers()->GetDateValue(
+ &response_date)) {
+ response_date = base::Time();
+ }
+ options.set_server_time(response_date);
+
+ const base::StringPiece name("Set-Cookie");
+ std::string cookie_line;
+ size_t iter = 0;
+ while (mock_response_details_->response_headers()->EnumerateHeader(
+ &iter, name, &cookie_line)) {
+ std::unique_ptr<net::CanonicalCookie> cookie =
+ net::CanonicalCookie::Create(request_details_.url, cookie_line,
+ base::Time::Now(), options);
+ if (!cookie)
+ continue;
+
+ auto* store = request_details_.url_request_context->cookie_store();
+ store->SetCanonicalCookieAsync(
+ std::move(cookie), request_details_.url.SchemeIsCryptographic(),
+ !options.exclude_httponly(), net::CookieStore::SetCookiesCallback());
+ }
+
if (sub_request_) {
sub_request_->Cancel();
sub_request_.reset();
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 48e7a7bde39..e7531a1d79d 100644
--- a/chromium/content/browser/devtools/devtools_url_interceptor_request_job.h
+++ b/chromium/content/browser/devtools/devtools_url_interceptor_request_job.h
@@ -12,6 +12,7 @@
#include "content/browser/devtools/protocol/network.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/resource_type.h"
+#include "net/cookies/canonical_cookie.h"
#include "net/http/http_raw_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
@@ -104,6 +105,7 @@ class DevToolsURLInterceptorRequestJob : public net::URLRequestJob {
GURL url;
std::string method;
std::unique_ptr<net::UploadDataStream> post_data;
+ std::string cookie_line;
net::HttpRequestHeaders extra_request_headers;
std::string referrer;
net::URLRequest::ReferrerPolicy referrer_policy;
@@ -111,6 +113,8 @@ class DevToolsURLInterceptorRequestJob : public net::URLRequestJob {
const net::URLRequestContext* url_request_context;
};
+ void StartWithCookies(const net::CookieList& cookies);
+
// Callbacks from SubRequest.
void OnSubRequestAuthRequired(net::AuthChallengeInfo* auth_info);
void OnSubRequestRedirectReceived(const net::URLRequest& request,
diff --git a/chromium/content/browser/devtools/devtools_url_loader_interceptor.cc b/chromium/content/browser/devtools/devtools_url_loader_interceptor.cc
index bc91e2d6d59..6d4201baf6d 100644
--- a/chromium/content/browser/devtools/devtools_url_loader_interceptor.cc
+++ b/chromium/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -10,7 +10,7 @@
#include "base/unguessable_token.h"
#include "content/browser/devtools/protocol/network_handler.h"
#include "content/browser/frame_host/frame_tree_node.h"
-#include "content/browser/loader/navigation_loader_util.h"
+#include "content/browser/loader/download_utils_impl.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/system/data_pipe_drainer.h"
@@ -151,7 +151,6 @@ struct ResponseMetadata {
network::ResourceResponseHead head;
std::unique_ptr<net::RedirectInfo> redirect_info;
- network::mojom::DownloadedTempFilePtr downloaded_file;
std::vector<uint8_t> cached_metadata;
size_t encoded_length = 0;
size_t transfer_size = 0;
@@ -229,7 +228,9 @@ class InterceptionJob : public network::mojom::URLLoaderClient,
}
// network::mojom::URLLoader methods
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
@@ -238,12 +239,9 @@ class InterceptionJob : public network::mojom::URLLoaderClient,
void ResumeReadingBodyFromNet() override;
// network::mojom::URLLoaderClient methods
- void OnReceiveResponse(
- const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override;
+ void OnReceiveResponse(const network::ResourceResponseHead& head) override;
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
const network::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;
@@ -336,7 +334,9 @@ class DevToolsURLLoaderInterceptor::Impl
InterceptionStage GetInterceptionStage(const GURL& url,
ResourceType resource_type) const {
InterceptionStage stage = InterceptionStage::DONT_INTERCEPT;
- std::string url_str = protocol::NetworkHandler::ClearUrlRef(url).spec();
+ std::string unused;
+ std::string url_str =
+ protocol::NetworkHandler::ExtractFragment(url, &unused);
for (const auto& pattern : patterns_) {
if (pattern.Matches(url_str, resource_type))
stage |= pattern.interception_stage;
@@ -818,8 +818,7 @@ Response InterceptionJob::InnerContinueRequest(
// TODO(caseq): report error if other modifications are present.
DCHECK_EQ(State::kResponseReceived, state_);
DCHECK(!body_reader_);
- client_->OnReceiveResponse(response_metadata_->head,
- std::move(response_metadata_->downloaded_file));
+ client_->OnReceiveResponse(response_metadata_->head);
response_metadata_.reset();
loader_->ResumeReadingBodyFromNet();
client_binding_.ResumeIncomingMethodCallProcessing();
@@ -962,7 +961,7 @@ Response InterceptionJob::ProcessRedirectByClient(const std::string& location) {
first_party_url_policy, request.referrer_policy,
request.referrer.spec(), &headers, headers.response_code(),
redirect_url, false /* token_binding_negotiated */,
- false /* copy_fragment */));
+ false /* insecure_scheme_was_upgraded */, false /* copy_fragment */));
client_->OnReceiveRedirect(*response_metadata_->redirect_info,
response_metadata_->head);
@@ -970,8 +969,7 @@ Response InterceptionJob::ProcessRedirectByClient(const std::string& location) {
}
void InterceptionJob::SendResponse(const base::StringPiece& body) {
- client_->OnReceiveResponse(response_metadata_->head,
- std::move(response_metadata_->downloaded_file));
+ client_->OnReceiveResponse(response_metadata_->head);
// We shouldn't be able to transfer a string that big over the protocol,
// but just in case...
@@ -1086,6 +1084,8 @@ void InterceptionJob::Shutdown() {
// URLLoader methods
void InterceptionJob::FollowRedirect(
+ const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
DCHECK(!modified_request_headers.has_value()) << "Redirect with modified "
"headers was not supported "
@@ -1106,7 +1106,7 @@ void InterceptionJob::FollowRedirect(
}
if (state_ == State::kRedirectReceived) {
state_ = State::kRequestSent;
- loader_->FollowRedirect(base::nullopt);
+ loader_->FollowRedirect(base::nullopt, base::nullopt);
return;
}
@@ -1138,25 +1138,23 @@ void InterceptionJob::ResumeReadingBodyFromNet() {
// URLLoaderClient methods
void InterceptionJob::OnReceiveResponse(
- const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file) {
+ const network::ResourceResponseHead& head) {
state_ = State::kResponseReceived;
DCHECK(!response_metadata_);
if (!(stage_ & InterceptionStage::RESPONSE)) {
- client_->OnReceiveResponse(head, std::move(downloaded_file));
+ client_->OnReceiveResponse(head);
return;
}
loader_->PauseReadingBodyFromNet();
client_binding_.PauseIncomingMethodCallProcessing();
response_metadata_ = std::make_unique<ResponseMetadata>(head);
- response_metadata_->downloaded_file = std::move(downloaded_file);
auto request_info = BuildRequestInfo(&head);
const network::ResourceRequest& request = create_loader_params_->request;
request_info->is_download =
request_info->is_navigation && request.allow_download &&
- (is_download_ || navigation_loader_util::IsDownload(
+ (is_download_ || download_utils::IsDownload(
request.url, head.headers.get(), head.mime_type));
NotifyClient(std::move(request_info));
}
@@ -1182,12 +1180,6 @@ void InterceptionJob::OnReceiveRedirect(
NotifyClient(std::move(request_info));
}
-void InterceptionJob::OnDataDownloaded(int64_t data_length,
- int64_t encoded_length) {
- if (ShouldBypassForResponse())
- client_->OnDataDownloaded(data_length, encoded_length);
-}
-
void InterceptionJob::OnUploadProgress(int64_t current_position,
int64_t total_size,
OnUploadProgressCallback callback) {
diff --git a/chromium/content/browser/devtools/devtools_url_request_interceptor.cc b/chromium/content/browser/devtools/devtools_url_request_interceptor.cc
index 260a5206a1f..0a02236d4dc 100644
--- a/chromium/content/browser/devtools/devtools_url_request_interceptor.cc
+++ b/chromium/content/browser/devtools/devtools_url_request_interceptor.cc
@@ -219,7 +219,9 @@ DevToolsURLRequestInterceptor::FilterEntryForRequest(
return nullptr;
const std::vector<std::unique_ptr<FilterEntry>>& entries = it->second;
- const std::string url_str = protocol::NetworkHandler::ClearUrlRef(url).spec();
+ std::string unused;
+ const std::string url_str =
+ protocol::NetworkHandler::ExtractFragment(url, &unused);
for (const auto& entry : entries) {
for (const Pattern& pattern : entry->patterns) {
if (!pattern.resource_types.empty() &&
diff --git a/chromium/content/browser/devtools/devtools_video_consumer.cc b/chromium/content/browser/devtools/devtools_video_consumer.cc
index fb91996670c..2b185d09f79 100644
--- a/chromium/content/browser/devtools/devtools_video_consumer.cc
+++ b/chromium/content/browser/devtools/devtools_video_consumer.cc
@@ -4,6 +4,8 @@
#include "content/browser/devtools/devtools_video_consumer.h"
+#include <utility>
+
#include "cc/paint/skia_paint_canvas.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "components/viz/service/frame_sinks/video_capture/frame_sink_video_capturer_impl.h"
@@ -25,6 +27,11 @@ constexpr base::TimeDelta kDefaultMinPeriod = base::TimeDelta();
// Allow variable aspect ratio.
const bool kDefaultUseFixedAspectRatio = false;
+// Creates a ClientFrameSinkVideoCapturer via HostFrameSinkManager.
+std::unique_ptr<viz::ClientFrameSinkVideoCapturer> CreateCapturer() {
+ return GetHostFrameSinkManager()->CreateVideoCapturer();
+}
+
} // namespace
// static
@@ -37,8 +44,7 @@ DevToolsVideoConsumer::DevToolsVideoConsumer(OnFrameCapturedCallback callback)
: callback_(std::move(callback)),
min_capture_period_(kDefaultMinCapturePeriod),
min_frame_size_(kDefaultMinFrameSize),
- max_frame_size_(kDefaultMaxFrameSize),
- binding_(this) {}
+ max_frame_size_(kDefaultMaxFrameSize) {}
DevToolsVideoConsumer::~DevToolsVideoConsumer() = default;
@@ -63,16 +69,18 @@ void DevToolsVideoConsumer::StartCapture() {
void DevToolsVideoConsumer::StopCapture() {
if (!capturer_)
return;
- binding_.Close();
- capturer_->Stop();
capturer_.reset();
}
void DevToolsVideoConsumer::SetFrameSinkId(
const viz::FrameSinkId& frame_sink_id) {
frame_sink_id_ = frame_sink_id;
- if (capturer_)
- capturer_->ChangeTarget(frame_sink_id_);
+ if (capturer_) {
+ if (frame_sink_id_.is_valid())
+ capturer_->ChangeTarget(frame_sink_id_);
+ else
+ capturer_->ChangeTarget(base::nullopt);
+ }
}
void DevToolsVideoConsumer::SetMinCapturePeriod(
@@ -93,28 +101,19 @@ void DevToolsVideoConsumer::SetMinAndMaxFrameSize(gfx::Size min_frame_size,
}
}
-viz::mojom::FrameSinkVideoCapturerPtrInfo
-DevToolsVideoConsumer::CreateCapturer() {
- viz::HostFrameSinkManager* const manager = GetHostFrameSinkManager();
- viz::mojom::FrameSinkVideoCapturerPtr capturer;
- manager->CreateVideoCapturer(mojo::MakeRequest(&capturer));
- return capturer.PassInterface();
-}
-
void DevToolsVideoConsumer::InnerStartCapture(
- viz::mojom::FrameSinkVideoCapturerPtrInfo capturer_info) {
- capturer_.Bind(std::move(capturer_info));
+ std::unique_ptr<viz::ClientFrameSinkVideoCapturer> capturer) {
+ capturer_ = std::move(capturer);
// Give |capturer_| the capture parameters.
capturer_->SetMinCapturePeriod(min_capture_period_);
capturer_->SetMinSizeChangePeriod(kDefaultMinPeriod);
capturer_->SetResolutionConstraints(min_frame_size_, max_frame_size_,
kDefaultUseFixedAspectRatio);
- capturer_->ChangeTarget(frame_sink_id_);
+ if (frame_sink_id_.is_valid())
+ capturer_->ChangeTarget(frame_sink_id_);
- viz::mojom::FrameSinkVideoConsumerPtr consumer;
- binding_.Bind(mojo::MakeRequest(&consumer));
- capturer_->Start(std::move(consumer));
+ capturer_->Start(this);
}
bool DevToolsVideoConsumer::IsValidMinAndMaxFrameSize(
@@ -160,9 +159,6 @@ void DevToolsVideoConsumer::OnFrameCaptured(
callback_.Run(std::move(frame));
}
-void DevToolsVideoConsumer::OnTargetLost(
- const viz::FrameSinkId& frame_sink_id) {}
-
void DevToolsVideoConsumer::OnStopped() {}
} // namespace content
diff --git a/chromium/content/browser/devtools/devtools_video_consumer.h b/chromium/content/browser/devtools/devtools_video_consumer.h
index fc9bbdba359..dd17f36abdd 100644
--- a/chromium/content/browser/devtools/devtools_video_consumer.h
+++ b/chromium/content/browser/devtools/devtools_video_consumer.h
@@ -5,10 +5,12 @@
#ifndef CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_VIDEO_CONSUMER_H_
#define CONTENT_BROWSER_DEVTOOLS_DEVTOOLS_VIDEO_CONSUMER_H_
+#include <memory>
+
#include "base/time/time.h"
+#include "components/viz/host/client_frame_sink_video_capturer.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/binding.h"
-#include "services/viz/privileged/interfaces/compositing/frame_sink_video_capture.mojom.h"
#include "ui/gfx/geometry/size.h"
class SkBitmap;
@@ -18,8 +20,8 @@ namespace content {
// This class is the video consumer to FrameSinkVideoCapturerImpl. This class,
// in turn sends video frames to its host via the OnFrameCapturedCallback. Used
// when the VizDisplayCompositor feature is enabled.
-// TODO(https://crbug.com/813929): Use this class everywhere even if viz is not
-// enabled.
+// TODO(crbug.com/846811): This class can probably be merged into
+// viz::ClientFrameSinkVideoCapturer.
class CONTENT_EXPORT DevToolsVideoConsumer
: public viz::mojom::FrameSinkVideoConsumer {
public:
@@ -35,7 +37,7 @@ class CONTENT_EXPORT DevToolsVideoConsumer
// If not currently capturing, this creates the capturer and starts capturing.
void StartCapture();
- // Closes |binding_|. Stops capturing and resets |capturer_|.
+ // Stops capturing and resets |capturer_|.
void StopCapture();
// These functions cache the values passed to them and if we're currently
@@ -49,15 +51,11 @@ class CONTENT_EXPORT DevToolsVideoConsumer
private:
friend class DevToolsVideoConsumerTest;
- // Sets up a mojo message pipe and requests the HostFrameSinkManager create a
- // new capturer instance bound to it. Returns the client-side interface.
- viz::mojom::FrameSinkVideoCapturerPtrInfo CreateCapturer();
- // Binds |capturer_info| to the |capturer_|, sets capture parameters, and
- // starts capture. Normally, CreateCapturer produces the |capturer_info|, but
- // unittests can provide a mock.
+ // Sets |capturer_|, sends capture parameters, and starts capture. Normally,
+ // CreateCapturer produces the |capturer|, but unittests can provide a mock.
void InnerStartCapture(
- viz::mojom::FrameSinkVideoCapturerPtrInfo capturer_info);
+ std::unique_ptr<viz::ClientFrameSinkVideoCapturer> capturer);
// Checks that |min_frame_size| and |max_frame_size| are in the expected
// range. Limits are specified in media::limits.
@@ -72,7 +70,6 @@ class CONTENT_EXPORT DevToolsVideoConsumer
const gfx::Rect& update_rect,
const gfx::Rect& content_rect,
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) override;
- void OnTargetLost(const viz::FrameSinkId& frame_sink_id) override;
void OnStopped() override;
// Default min frame size is 1x1, as otherwise, nothing would be captured.
@@ -90,11 +87,8 @@ class CONTENT_EXPORT DevToolsVideoConsumer
gfx::Size max_frame_size_;
viz::FrameSinkId frame_sink_id_;
- // Mojo pointer to the viz::FrameSinkVideoCapturer instance. If |capturer_|
- // is alive, then we are currently capturing.
- viz::mojom::FrameSinkVideoCapturerPtr capturer_;
-
- mojo::Binding<viz::mojom::FrameSinkVideoConsumer> binding_;
+ // If |capturer_| is alive, then we are currently capturing.
+ std::unique_ptr<viz::ClientFrameSinkVideoCapturer> capturer_;
DISALLOW_COPY_AND_ASSIGN(DevToolsVideoConsumer);
};
diff --git a/chromium/content/browser/devtools/devtools_video_consumer_unittest.cc b/chromium/content/browser/devtools/devtools_video_consumer_unittest.cc
index 20f9b2fdb62..826ab906e49 100644
--- a/chromium/content/browser/devtools/devtools_video_consumer_unittest.cc
+++ b/chromium/content/browser/devtools/devtools_video_consumer_unittest.cc
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <memory>
+#include <utility>
+#include <vector>
#include "base/message_loop/message_loop.h"
#include "content/browser/devtools/devtools_video_consumer.h"
@@ -38,6 +39,11 @@ class MockFrameSinkVideoCapturer : public viz::mojom::FrameSinkVideoCapturer {
binding_.Bind(std::move(request));
}
+ void Reset() {
+ binding_.Close();
+ consumer_.reset();
+ }
+
// This is never called.
MOCK_METHOD2(SetFormat,
void(media::VideoPixelFormat format,
@@ -66,8 +72,9 @@ class MockFrameSinkVideoCapturer : public viz::mojom::FrameSinkVideoCapturer {
bool use_fixed_aspect_ratio));
// This is never called.
MOCK_METHOD1(SetAutoThrottlingEnabled, void(bool));
- void ChangeTarget(const viz::FrameSinkId& frame_sink_id) final {
- frame_sink_id_ = frame_sink_id;
+ void ChangeTarget(
+ const base::Optional<viz::FrameSinkId>& frame_sink_id) final {
+ frame_sink_id_ = frame_sink_id ? *frame_sink_id : viz::FrameSinkId();
MockChangeTarget(frame_sink_id_);
}
MOCK_METHOD1(MockChangeTarget, void(const viz::FrameSinkId& frame_sink_id));
@@ -177,7 +184,7 @@ class DevToolsVideoConsumerTest : public testing::Test {
}
void StartCaptureWithMockCapturer() {
- consumer_->InnerStartCapture(BindMockCapturer());
+ consumer_->InnerStartCapture(CreateMockCapturer());
}
bool IsValidMinAndMaxFrameSize(gfx::Size min_frame_size,
@@ -208,10 +215,14 @@ class DevToolsVideoConsumerTest : public testing::Test {
std::unique_ptr<DevToolsVideoConsumer> consumer_;
private:
- viz::mojom::FrameSinkVideoCapturerPtrInfo BindMockCapturer() {
- viz::mojom::FrameSinkVideoCapturerPtr capturer_ptr;
- capturer_.Bind(mojo::MakeRequest(&capturer_ptr));
- return capturer_ptr.PassInterface();
+ std::unique_ptr<viz::ClientFrameSinkVideoCapturer> CreateMockCapturer() {
+ return std::make_unique<viz::ClientFrameSinkVideoCapturer>(
+ base::BindRepeating(
+ [](base::WeakPtr<DevToolsVideoConsumerTest> self,
+ viz::mojom::FrameSinkVideoCapturerRequest request) {
+ self->capturer_.Bind(std::move(request));
+ },
+ weak_factory_.GetWeakPtr()));
}
base::MessageLoop message_loop_;
@@ -281,9 +292,10 @@ TEST_F(DevToolsVideoConsumerTest, StartCaptureCallsSetFunctions) {
base::RunLoop().RunUntilIdle();
// Stop capturing.
- EXPECT_CALL(capturer_, MockStop());
consumer_->StopCapture();
- base::RunLoop().RunUntilIdle();
+
+ // Reset the mock to allow the next consumer to connect.
+ capturer_.Reset();
// Start capturing again, and expect that these |capturer_| functions are
// called once. This will re-bind the |capturer_| and ensures that destroyed
diff --git a/chromium/content/browser/devtools/protocol/browser_handler.cc b/chromium/content/browser/devtools/protocol/browser_handler.cc
index 7e03482fde2..618ca845bad 100644
--- a/chromium/content/browser/devtools/protocol/browser_handler.cc
+++ b/chromium/content/browser/devtools/protocol/browser_handler.cc
@@ -47,10 +47,14 @@ Response BrowserHandler::GetVersion(std::string* protocol_version,
namespace {
// Converts an histogram.
-std::unique_ptr<Browser::Histogram> Convert(
- const base::HistogramBase& in_histogram) {
- const std::unique_ptr<const base::HistogramSamples> in_buckets =
- in_histogram.SnapshotSamples();
+std::unique_ptr<Browser::Histogram> Convert(base::HistogramBase& in_histogram,
+ bool in_delta) {
+ std::unique_ptr<const base::HistogramSamples> in_buckets;
+ if (!in_delta) {
+ in_buckets = in_histogram.SnapshotSamples();
+ } else {
+ in_buckets = in_histogram.SnapshotDelta();
+ }
DCHECK(in_buckets);
auto out_buckets = std::make_unique<Array<Browser::Bucket>>();
@@ -81,16 +85,17 @@ std::unique_ptr<Browser::Histogram> Convert(
Response BrowserHandler::GetHistograms(
const Maybe<std::string> in_query,
+ const Maybe<bool> in_delta,
std::unique_ptr<Array<Browser::Histogram>>* const out_histograms) {
// Convert histograms.
DCHECK(out_histograms);
*out_histograms = std::make_unique<Array<Browser::Histogram>>();
- for (const base::HistogramBase* const h :
+ for (base::HistogramBase* const h :
base::StatisticsRecorder::Sort(base::StatisticsRecorder::WithName(
base::StatisticsRecorder::GetHistograms(),
in_query.fromMaybe("")))) {
DCHECK(h);
- (*out_histograms)->addItem(Convert(*h));
+ (*out_histograms)->addItem(Convert(*h, in_delta.fromMaybe(false)));
}
return Response::OK();
@@ -98,16 +103,17 @@ Response BrowserHandler::GetHistograms(
Response BrowserHandler::GetHistogram(
const std::string& in_name,
+ const Maybe<bool> in_delta,
std::unique_ptr<Browser::Histogram>* const out_histogram) {
// Get histogram by name.
- const base::HistogramBase* const in_histogram =
+ base::HistogramBase* const in_histogram =
base::StatisticsRecorder::FindHistogram(in_name);
if (!in_histogram)
return Response::InvalidParams("Cannot find histogram: " + in_name);
// Convert histogram.
DCHECK(out_histogram);
- *out_histogram = Convert(*in_histogram);
+ *out_histogram = Convert(*in_histogram, in_delta.fromMaybe(false));
return Response::OK();
}
diff --git a/chromium/content/browser/devtools/protocol/browser_handler.h b/chromium/content/browser/devtools/protocol/browser_handler.h
index b4f3e05eccc..9ced0243186 100644
--- a/chromium/content/browser/devtools/protocol/browser_handler.h
+++ b/chromium/content/browser/devtools/protocol/browser_handler.h
@@ -28,10 +28,12 @@ class BrowserHandler : public DevToolsDomainHandler, public Browser::Backend {
Response GetHistograms(
Maybe<std::string> in_query,
+ Maybe<bool> in_delta,
std::unique_ptr<Array<Browser::Histogram>>* histograms) override;
Response GetHistogram(
const std::string& in_name,
+ Maybe<bool> in_delta,
std::unique_ptr<Browser::Histogram>* out_histogram) override;
Response GetBrowserCommandLine(
diff --git a/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
index e63b7fc855d..aa29868d07d 100644
--- a/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/chromium/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -546,9 +546,9 @@ IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, KeyEventSynthesizeKey) {
NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
Attach();
ASSERT_TRUE(content::ExecuteScript(
- shell()->web_contents()->GetRenderViewHost(),
+ shell()->web_contents(),
"function handleKeyEvent(event) {"
- "domAutomationController.send(event.key);"
+ "domAutomationController.send(event.key);"
"}"
"document.body.addEventListener('keydown', handleKeyEvent);"
"document.body.addEventListener('keyup', handleKeyEvent);"));
@@ -579,7 +579,7 @@ IN_PROC_BROWSER_TEST_F(SyntheticKeyEventTest, KeyboardEventAck) {
NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
Attach();
ASSERT_TRUE(content::ExecuteScript(
- shell()->web_contents()->GetRenderViewHost(),
+ shell()->web_contents(),
"document.body.addEventListener('keydown', () => {debugger;});"));
auto filter = std::make_unique<InputMsgWatcher>(
@@ -605,7 +605,7 @@ IN_PROC_BROWSER_TEST_F(SyntheticMouseEventTest, MouseEventAck) {
NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
Attach();
ASSERT_TRUE(content::ExecuteScript(
- shell()->web_contents()->GetRenderViewHost(),
+ shell()->web_contents(),
"document.body.addEventListener('mousedown', () => {debugger;});"));
auto filter = std::make_unique<InputMsgWatcher>(
@@ -781,7 +781,7 @@ class CaptureScreenshotTest : public DevToolsProtocolTest {
// Draw a blue box of provided size in the horizontal center of the page.
EXPECT_TRUE(content::ExecuteScript(
- shell()->web_contents()->GetRenderViewHost(),
+ shell()->web_contents(),
base::StringPrintf(
"var style = document.body.style; "
"style.overflow = 'hidden'; "
@@ -2605,9 +2605,15 @@ IN_PROC_BROWSER_TEST_F(DevToolsDownloadContentTest, ResetDownloadState) {
ASSERT_EQ(download::DownloadItem::COMPLETE, download->GetState());
}
+// Flakly on ChromeOS https://crbug.com/860312
+#if defined(OS_CHROMEOS)
+#define MAYBE_MultiDownload DISABLED_MultiDownload
+#else
+#define MAYBE_MultiDownload MultiDownload
+#endif
// Check that downloading multiple (in this case, 2) files does not result in
// corrupted files.
-IN_PROC_BROWSER_TEST_F(DevToolsDownloadContentTest, MultiDownload) {
+IN_PROC_BROWSER_TEST_F(DevToolsDownloadContentTest, MAYBE_MultiDownload) {
base::ThreadRestrictions::SetIOAllowed(true);
SetupEnsureNoPendingDownloads();
NavigateToURLBlockUntilNavigationsComplete(shell(), GURL("about:blank"), 1);
diff --git a/chromium/content/browser/devtools/protocol/emulation_handler.cc b/chromium/content/browser/devtools/protocol/emulation_handler.cc
index ca11b87a749..af6d9a2b197 100644
--- a/chromium/content/browser/devtools/protocol/emulation_handler.cc
+++ b/chromium/content/browser/devtools/protocol/emulation_handler.cc
@@ -8,13 +8,15 @@
#include "base/strings/string_number_conversions.h"
#include "build/build_config.h"
+#include "content/browser/devtools/devtools_session.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/input/touch_emulator.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/view_messages.h"
#include "content/public/common/url_constants.h"
-#include "device/geolocation/public/cpp/geoposition.h"
+#include "net/http/http_util.h"
+#include "services/device/public/cpp/geolocation/geoposition.h"
#include "services/device/public/mojom/geolocation_context.mojom.h"
#include "services/device/public/mojom/geoposition.mojom.h"
#include "ui/events/gesture_detection/gesture_provider_config_helper.h"
@@ -64,6 +66,13 @@ EmulationHandler::EmulationHandler()
EmulationHandler::~EmulationHandler() {
}
+// static
+std::vector<EmulationHandler*> EmulationHandler::ForAgentHost(
+ DevToolsAgentHostImpl* host) {
+ return DevToolsSession::HandlersForAgentHost<EmulationHandler>(
+ host, Emulation::Metainfo::domainName);
+}
+
void EmulationHandler::SetRenderer(int process_host_id,
RenderFrameHostImpl* frame_host) {
if (host_ == frame_host)
@@ -84,6 +93,7 @@ Response EmulationHandler::Disable() {
touch_emulation_enabled_ = false;
UpdateTouchEventEmulationState();
}
+ user_agent_ = std::string();
device_emulation_enabled_ = false;
UpdateDeviceEmulationState();
return Response::OK();
@@ -304,6 +314,23 @@ Response EmulationHandler::SetVisibleSize(int width, int height) {
return Response::OK();
}
+Response EmulationHandler::SetUserAgentOverride(
+ const std::string& user_agent,
+ Maybe<std::string> accept_language,
+ Maybe<std::string> platform) {
+ if (!user_agent.empty() && !net::HttpUtil::IsValidHeaderValue(user_agent))
+ return Response::InvalidParams("Invalid characters found in userAgent");
+ std::string accept_lang = accept_language.fromMaybe(std::string());
+ if (!accept_lang.empty() && !net::HttpUtil::IsValidHeaderValue(accept_lang)) {
+ return Response::InvalidParams(
+ "Invalid characters found in acceptLanguage");
+ }
+
+ user_agent_ = user_agent;
+ accept_language_ = accept_lang;
+ return Response::FallThrough();
+}
+
blink::WebDeviceEmulationParams EmulationHandler::GetDeviceEmulationParams() {
return device_emulation_params_;
}
@@ -372,5 +399,15 @@ void EmulationHandler::UpdateDeviceEmulationState() {
}
}
+void EmulationHandler::ApplyOverrides(net::HttpRequestHeaders* headers) {
+ if (!user_agent_.empty())
+ headers->SetHeader(net::HttpRequestHeaders::kUserAgent, user_agent_);
+ if (!accept_language_.empty()) {
+ headers->SetHeader(
+ net::HttpRequestHeaders::kAcceptLanguage,
+ net::HttpUtil::GenerateAcceptLanguageHeader(accept_language_));
+ }
+}
+
} // namespace protocol
} // namespace content
diff --git a/chromium/content/browser/devtools/protocol/emulation_handler.h b/chromium/content/browser/devtools/protocol/emulation_handler.h
index 1503b2e70da..5890b6797b6 100644
--- a/chromium/content/browser/devtools/protocol/emulation_handler.h
+++ b/chromium/content/browser/devtools/protocol/emulation_handler.h
@@ -10,8 +10,13 @@
#include "content/browser/devtools/protocol/emulation.h"
#include "third_party/blink/public/web/web_device_emulation_params.h"
+namespace net {
+class HttpRequestHeaders;
+} // namespace net
+
namespace content {
+class DevToolsAgentHostImpl;
class RenderFrameHostImpl;
class WebContentsImpl;
@@ -23,6 +28,9 @@ class EmulationHandler : public DevToolsDomainHandler,
EmulationHandler();
~EmulationHandler() override;
+ static std::vector<EmulationHandler*> ForAgentHost(
+ DevToolsAgentHostImpl* host);
+
void Wire(UberDispatcher* dispatcher) override;
void SetRenderer(int process_host_id,
RenderFrameHostImpl* frame_host) override;
@@ -38,6 +46,10 @@ class EmulationHandler : public DevToolsDomainHandler,
bool enabled,
Maybe<std::string> configuration) override;
+ Response SetUserAgentOverride(const std::string& user_agent,
+ Maybe<std::string> accept_language,
+ Maybe<std::string> platform) override;
+
Response CanEmulate(bool* result) override;
Response SetDeviceMetricsOverride(
int width,
@@ -61,6 +73,8 @@ class EmulationHandler : public DevToolsDomainHandler,
bool device_emulation_enabled() { return device_emulation_enabled_; }
+ void ApplyOverrides(net::HttpRequestHeaders* headers);
+
private:
WebContentsImpl* GetWebContents();
void UpdateTouchEventEmulationState();
@@ -71,6 +85,8 @@ class EmulationHandler : public DevToolsDomainHandler,
bool device_emulation_enabled_;
blink::WebDeviceEmulationParams device_emulation_params_;
+ std::string user_agent_;
+ std::string accept_language_;
RenderFrameHostImpl* host_;
diff --git a/chromium/content/browser/devtools/protocol/input_handler.cc b/chromium/content/browser/devtools/protocol/input_handler.cc
index 4440a13e4c4..e6b74e54193 100644
--- a/chromium/content/browser/devtools/protocol/input_handler.cc
+++ b/chromium/content/browser/devtools/protocol/input_handler.cc
@@ -19,7 +19,6 @@
#include "content/common/input/synthetic_pinch_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/content_features.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/web_input_event_traits.h"
#include "ui/events/gesture_detection/gesture_provider_config_helper.h"
@@ -285,15 +284,12 @@ class InputHandler::InputInjector
return;
}
- 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;
- widget_host_->ForwardWheelEvent(*wheel_event);
- }
+ // 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;
+ widget_host_->ForwardWheelEvent(*wheel_event);
}
void InjectMouseEvent(const blink::WebMouseEvent& mouse_event,
@@ -585,11 +581,8 @@ void InputHandler::DispatchMouseEvent(
}
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;
- wheel_event->dispatch_type = blink::WebInputEvent::kBlocking;
- }
+ wheel_event->phase = blink::WebMouseWheelEvent::kPhaseBegan;
+ wheel_event->dispatch_type = blink::WebInputEvent::kBlocking;
} else {
mouse_event.reset(new blink::WebMouseEvent(type, modifiers, timestamp));
}
@@ -802,10 +795,7 @@ Response InputHandler::EmulateTouchFromMouseEvent(const std::string& type,
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;
- }
+ wheel_event->phase = blink::WebMouseWheelEvent::kPhaseBegan;
} else {
mouse_event = new blink::WebMouseEvent(
event_type,
@@ -828,15 +818,12 @@ Response InputHandler::EmulateTouchFromMouseEvent(const std::string& type,
if (wheel_event) {
host_->GetRenderWidgetHost()->ForwardWheelEvent(*wheel_event);
- 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);
- }
+ // 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);
}
diff --git a/chromium/content/browser/devtools/protocol/network_handler.cc b/chromium/content/browser/devtools/protocol/network_handler.cc
index b8ea9fc9205..905fe910beb 100644
--- a/chromium/content/browser/devtools/protocol/network_handler.cc
+++ b/chromium/content/browser/devtools/protocol/network_handler.cc
@@ -31,7 +31,8 @@
#include "content/browser/frame_host/navigation_request.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/storage_partition_impl.h"
-#include "content/browser/web_package/signed_exchange_header.h"
+#include "content/browser/web_package/signed_exchange_envelope.h"
+#include "content/browser/web_package/signed_exchange_error.h"
#include "content/common/navigation_params.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -53,6 +54,8 @@
#include "net/base/upload_bytes_element_reader.h"
#include "net/cert/ct_policy_status.h"
#include "net/cert/ct_sct_to_string.h"
+#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_store.h"
#include "net/http/http_response_headers.h"
@@ -85,9 +88,6 @@ using DeleteCookiesCallback = Network::Backend::DeleteCookiesCallback;
using ClearBrowserCookiesCallback =
Network::Backend::ClearBrowserCookiesCallback;
-const char kDevToolsEmulateNetworkConditionsClientId[] =
- "X-DevTools-Emulate-Network-Conditions-Client-Id";
-
Network::CertificateTransparencyCompliance SerializeCTPolicyCompliance(
net::ct::CTPolicyCompliance ct_compliance) {
switch (ct_compliance) {
@@ -379,8 +379,6 @@ void DeleteFilteredCookies(network::mojom::CookieManager* cookie_manager,
const std::string& path,
std::unique_ptr<DeleteCookiesCallback> callback,
const std::vector<net::CanonicalCookie>& cookies) {
- base::Time yesterday(base::Time::Now() - base::TimeDelta::FromDays(1));
-
std::vector<net::CanonicalCookie> filtered_list =
FilterCookies(cookies, name, normalized_domain, path);
@@ -389,17 +387,10 @@ void DeleteFilteredCookies(network::mojom::CookieManager* cookie_manager,
base::BindOnce(&DeleteCookiesCallback::sendSuccess, std::move(callback)));
for (auto& cookie : filtered_list) {
- // Delete a single cookie by setting its expiration time into the past.
- cookie_manager->SetCanonicalCookie(
- net::CanonicalCookie(cookie.Name(), cookie.Value(), cookie.Domain(),
- cookie.Path(), cookie.CreationDate(), yesterday,
- cookie.LastAccessDate(), cookie.IsSecure(),
- cookie.IsHttpOnly(), cookie.SameSite(),
- cookie.Priority()),
- true /* secure_source */, true /* modify_http_only */,
- base::BindOnce(
- [](base::RepeatingClosure callback, bool) { callback.Run(); },
- barrier_closure));
+ cookie_manager->DeleteCanonicalCookie(
+ cookie, base::BindOnce([](base::RepeatingClosure callback,
+ bool) { callback.Run(); },
+ barrier_closure));
}
}
@@ -705,15 +696,21 @@ bool AddInterceptedResourceType(
intercepted_resource_types->insert(RESOURCE_TYPE_PREFETCH);
return true;
}
+ if (resource_type == protocol::Page::ResourceTypeEnum::CSPViolationReport) {
+ intercepted_resource_types->insert(RESOURCE_TYPE_CSP_REPORT);
+ return true;
+ }
+ if (resource_type == protocol::Page::ResourceTypeEnum::Ping) {
+ intercepted_resource_types->insert(RESOURCE_TYPE_PING);
+ return true;
+ }
if (resource_type == protocol::Page::ResourceTypeEnum::Other) {
intercepted_resource_types->insert(RESOURCE_TYPE_SUB_RESOURCE);
intercepted_resource_types->insert(RESOURCE_TYPE_OBJECT);
intercepted_resource_types->insert(RESOURCE_TYPE_WORKER);
intercepted_resource_types->insert(RESOURCE_TYPE_SHARED_WORKER);
intercepted_resource_types->insert(RESOURCE_TYPE_FAVICON);
- intercepted_resource_types->insert(RESOURCE_TYPE_PING);
intercepted_resource_types->insert(RESOURCE_TYPE_SERVICE_WORKER);
- intercepted_resource_types->insert(RESOURCE_TYPE_CSP_REPORT);
intercepted_resource_types->insert(RESOURCE_TYPE_PLUGIN_RESOURCE);
return true;
}
@@ -820,12 +817,6 @@ class NetworkNavigationThrottle : public content::NavigationThrottle {
DISALLOW_COPY_AND_ASSIGN(NetworkNavigationThrottle);
};
-void ConfigureServiceWorkerContextOnIO() {
- std::set<std::string> headers;
- headers.insert(kDevToolsEmulateNetworkConditionsClientId);
- content::ServiceWorkerContext::AddExcludedHeadersForFetchEvent(headers);
-}
-
bool GetPostData(const net::URLRequest* request, std::string* post_data) {
if (!request->has_upload())
return false;
@@ -868,10 +859,44 @@ bool GetPostData(const network::ResourceRequestBody& request_body,
return true;
}
-std::string StripFragment(const GURL& url) {
- url::Replacements<char> replacements;
- replacements.ClearRef();
- return url.ReplaceComponents(replacements).spec();
+String SignedExchangeErrorErrorFieldToString(SignedExchangeError::Field field) {
+ switch (field) {
+ case SignedExchangeError::Field::kSignatureSig:
+ return Network::SignedExchangeErrorFieldEnum::SignatureSig;
+ case SignedExchangeError::Field::kSignatureIintegrity:
+ return Network::SignedExchangeErrorFieldEnum::SignatureIntegrity;
+ case SignedExchangeError::Field::kSignatureCertUrl:
+ return Network::SignedExchangeErrorFieldEnum::SignatureCertUrl;
+ case SignedExchangeError::Field::kSignatureCertSha256:
+ return Network::SignedExchangeErrorFieldEnum::SignatureCertSha256;
+ case SignedExchangeError::Field::kSignatureValidityUrl:
+ return Network::SignedExchangeErrorFieldEnum::SignatureValidityUrl;
+ case SignedExchangeError::Field::kSignatureTimestamps:
+ return Network::SignedExchangeErrorFieldEnum::SignatureTimestamps;
+ }
+ NOTREACHED();
+ return "";
+}
+
+std::unique_ptr<Network::SignedExchangeError> BuildSignedExchangeError(
+ const SignedExchangeError& error) {
+ std::unique_ptr<Network::SignedExchangeError> signed_exchange_error =
+ Network::SignedExchangeError::Create().SetMessage(error.message).Build();
+ if (error.field) {
+ signed_exchange_error->SetSignatureIndex(error.field->first);
+ signed_exchange_error->SetErrorField(
+ SignedExchangeErrorErrorFieldToString(error.field->second));
+ }
+ return signed_exchange_error;
+}
+
+std::unique_ptr<Array<Network::SignedExchangeError>> BuildSignedExchangeErrors(
+ const std::vector<SignedExchangeError>& errors) {
+ std::unique_ptr<Array<Network::SignedExchangeError>> signed_exchange_errors =
+ Array<Network::SignedExchangeError>::create();
+ for (const auto& error : errors)
+ signed_exchange_errors->addItem(BuildSignedExchangeError(error));
+ return signed_exchange_errors;
}
} // namespace
@@ -933,9 +958,11 @@ class BackgroundSyncRestorer {
};
NetworkHandler::NetworkHandler(const std::string& host_id,
+ const base::UnguessableToken& devtools_token,
DevToolsIOContext* io_context)
: DevToolsDomainHandler(Network::Metainfo::domainName),
host_id_(host_id),
+ devtools_token_(devtools_token),
io_context_(io_context),
browser_context_(nullptr),
storage_partition_(nullptr),
@@ -949,8 +976,6 @@ NetworkHandler::NetworkHandler(const std::string& host_id,
if (have_configured_service_worker_context)
return;
have_configured_service_worker_context = true;
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&ConfigureServiceWorkerContextOnIO));
}
NetworkHandler::~NetworkHandler() {
@@ -993,7 +1018,6 @@ Response NetworkHandler::Enable(Maybe<int> max_total_size,
Response NetworkHandler::Disable() {
enabled_ = false;
- user_agent_ = std::string();
interception_handle_.reset();
url_loader_interceptor_.reset();
SetNetworkConditions(nullptr);
@@ -1264,16 +1288,6 @@ void NetworkHandler::DeleteCookies(
normalized_domain, path.fromMaybe(""), std::move(callback)));
}
-Response NetworkHandler::SetUserAgentOverride(const std::string& user_agent) {
- if (user_agent.find('\n') != std::string::npos ||
- user_agent.find('\r') != std::string::npos ||
- user_agent.find('\0') != std::string::npos) {
- return Response::InvalidParams("Invalid characters found in userAgent");
- }
- user_agent_ = 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;
@@ -1442,9 +1456,10 @@ std::unique_ptr<Network::Response> BuildResponse(
status_text = "OK";
}
+ std::string url_fragment;
auto response =
Network::Response::Create()
- .SetUrl(StripFragment(url))
+ .SetUrl(NetworkHandler::ExtractFragment(url, &url_fragment))
.SetStatus(status)
.SetStatusText(status_text)
.SetHeaders(Object::fromValue(headers_dict.get(), nullptr))
@@ -1502,6 +1517,8 @@ String blockedReason(blink::ResourceRequestBlockedReason reason) {
return protocol::Network::BlockedReasonEnum::ContentType;
case blink::ResourceRequestBlockedReason::kOther:
return protocol::Network::BlockedReasonEnum::Other;
+ case blink::ResourceRequestBlockedReason::kCollapsedByClient:
+ return protocol::Network::BlockedReasonEnum::CollapsedByClient;
}
NOTREACHED();
return protocol::Network::BlockedReasonEnum::Other;
@@ -1540,14 +1557,19 @@ void NetworkHandler::NavigationRequestWillBeSent(
redirect_response = BuildResponse(request_params.redirects.back(),
request_params.redirect_response.back());
}
+ std::string url_fragment;
+ std::string url_without_fragment =
+ ExtractFragment(common_params.url, &url_fragment);
auto request =
Network::Request::Create()
- .SetUrl(StripFragment(common_params.url))
+ .SetUrl(url_without_fragment)
.SetMethod(common_params.method)
.SetHeaders(Object::fromValue(headers_dict.get(), nullptr))
.SetInitialPriority(resourcePriority(net::HIGHEST))
.SetReferrerPolicy(referrerPolicy(common_params.referrer.policy))
.Build();
+ if (!url_fragment.empty())
+ request->SetUrlFragment(url_fragment);
std::string post_data;
if (common_params.post_data &&
@@ -1578,9 +1600,8 @@ void NetworkHandler::NavigationRequestWillBeSent(
std::string frame_token =
nav_request.frame_tree_node()->devtools_frame_token().ToString();
frontend_->RequestWillBeSent(
- id, id, StripFragment(common_params.url), std::move(request),
- current_ticks, current_wall_time, std::move(initiator),
- std::move(redirect_response),
+ id, id, url_without_fragment, std::move(request), current_ticks,
+ current_wall_time, std::move(initiator), std::move(redirect_response),
std::string(Page::ResourceTypeEnum::Document), std::move(frame_token),
common_params.has_user_gesture);
}
@@ -1599,15 +1620,21 @@ void NetworkHandler::RequestSent(const std::string& request_id,
Network::Initiator::Create().SetType(initiator_type).Build();
if (initiator_url)
initiator->SetUrl(initiator_url->spec());
- frontend_->RequestWillBeSent(
- request_id, loader_id, StripFragment(request.url),
+ std::string url_fragment;
+ std::string url_without_fragment =
+ ExtractFragment(request.url, &url_fragment);
+ auto request_object =
Network::Request::Create()
- .SetUrl(StripFragment(request.url))
+ .SetUrl(url_without_fragment)
.SetMethod(request.method)
.SetHeaders(Object::fromValue(headers_dict.get(), nullptr))
.SetInitialPriority(resourcePriority(request.priority))
.SetReferrerPolicy(referrerPolicy(request.referrer_policy))
- .Build(),
+ .Build();
+ if (!url_fragment.empty())
+ request_object->SetUrlFragment(url_fragment);
+ frontend_->RequestWillBeSent(
+ request_id, loader_id, url_without_fragment, std::move(request_object),
base::TimeTicks::Now().ToInternalValue() /
static_cast<double>(base::Time::kMicrosecondsPerSecond),
base::Time::Now().ToDoubleT(), std::move(initiator),
@@ -1660,9 +1687,10 @@ void NetworkHandler::OnSignedExchangeReceived(
base::Optional<const base::UnguessableToken> devtools_navigation_token,
const GURL& outer_request_url,
const network::ResourceResponseHead& outer_response,
- const base::Optional<SignedExchangeHeader>& header,
+ const base::Optional<SignedExchangeEnvelope>& envelope,
+ const scoped_refptr<net::X509Certificate>& certificate,
const base::Optional<net::SSLInfo>& ssl_info,
- const std::vector<std::string>& error_messages) {
+ const std::vector<SignedExchangeError>& errors) {
if (!enabled_)
return;
std::unique_ptr<Network::SignedExchangeInfo> signed_exchange_info =
@@ -1670,40 +1698,59 @@ void NetworkHandler::OnSignedExchangeReceived(
.SetOuterResponse(BuildResponse(outer_request_url, outer_response))
.Build();
- if (header) {
+ if (envelope) {
std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create());
- for (const auto it : header->response_headers())
+ for (const auto it : envelope->response_headers())
headers_dict->setString(it.first, it.second);
- const SignedExchangeHeaderParser::Signature& sig = header->signature();
+ const SignedExchangeSignatureHeaderField::Signature& sig =
+ envelope->signature();
std::unique_ptr<Array<Network::SignedExchangeSignature>> signatures =
Array<Network::SignedExchangeSignature>::create();
- signatures->addItem(Network::SignedExchangeSignature::Create()
- .SetLabel(sig.label)
- .SetIntegrity(sig.integrity)
- .SetCertUrl(sig.cert_url.spec())
- .SetValidityUrl(sig.validity_url.spec())
- .SetDate(sig.date)
- .SetExpires(sig.expires)
- .Build());
+ std::unique_ptr<Network::SignedExchangeSignature> signature =
+ Network::SignedExchangeSignature::Create()
+ .SetLabel(sig.label)
+ .SetSignature(base::HexEncode(sig.sig.data(), sig.sig.size()))
+ .SetIntegrity(sig.integrity)
+ .SetCertUrl(sig.cert_url.spec())
+ .SetValidityUrl(sig.validity_url.spec())
+ .SetDate(sig.date)
+ .SetExpires(sig.expires)
+ .Build();
+ if (sig.cert_sha256) {
+ signature->SetCertSha256(base::HexEncode(sig.cert_sha256->data,
+ sizeof(sig.cert_sha256->data)));
+ }
+ if (certificate) {
+ std::unique_ptr<Array<String>> encoded_certificates =
+ Array<String>::create();
+ std::string encoded;
+ base::Base64Encode(
+ net::x509_util::CryptoBufferAsStringPiece(certificate->cert_buffer()),
+ &encoded);
+ encoded_certificates->addItem(std::move(encoded));
+ for (const auto& cert : certificate->intermediate_buffers()) {
+ base::Base64Encode(
+ net::x509_util::CryptoBufferAsStringPiece(cert.get()), &encoded);
+ encoded_certificates->addItem(std::move(encoded));
+ }
+ signature->SetCertificates(std::move(encoded_certificates));
+ }
+ signatures->addItem(std::move(signature));
signed_exchange_info->SetHeader(
Network::SignedExchangeHeader::Create()
- .SetRequestUrl(header->request_url().spec())
- .SetRequestMethod(header->request_method())
- .SetResponseCode(header->response_code())
+ .SetRequestUrl(envelope->request_url().spec())
+ .SetRequestMethod(envelope->request_method())
+ .SetResponseCode(envelope->response_code())
.SetResponseHeaders(Object::fromValue(headers_dict.get(), nullptr))
.SetSignatures(std::move(signatures))
.Build());
}
if (ssl_info)
signed_exchange_info->SetSecurityDetails(BuildSecurityDetails(*ssl_info));
- if (error_messages.size()) {
- std::unique_ptr<Array<String>> errors = Array<String>::create();
- for (const auto& message : error_messages)
- errors->addItem(message);
- signed_exchange_info->SetErrors(std::move(errors));
- }
+ if (errors.size())
+ signed_exchange_info->SetErrors(BuildSignedExchangeErrors(errors));
frontend_->SignedExchangeReceived(
devtools_navigation_token ? devtools_navigation_token->ToString() : "",
@@ -1877,12 +1924,16 @@ void NetworkHandler::OnResponseBodyPipeTaken(
}
// static
-GURL NetworkHandler::ClearUrlRef(const GURL& url) {
- if (!url.has_ref())
- return url;
+std::string NetworkHandler::ExtractFragment(const GURL& url,
+ std::string* fragment) {
+ if (!url.has_ref()) {
+ *fragment = std::string();
+ return url.spec();
+ }
+ *fragment = "#" + url.ref();
GURL::Replacements replacements;
replacements.ClearRef();
- return url.ReplaceComponents(replacements);
+ return url.ReplaceComponents(replacements).spec();
}
// static
@@ -1896,14 +1947,17 @@ NetworkHandler::CreateRequestFromResourceRequest(
headers_dict->setString(net::HttpRequestHeaders::kReferer,
request.referrer.spec());
}
+ std::string url_fragment;
std::unique_ptr<protocol::Network::Request> request_object =
Network::Request::Create()
- .SetUrl(ClearUrlRef(request.url).spec())
+ .SetUrl(ExtractFragment(request.url, &url_fragment))
.SetMethod(request.method)
.SetHeaders(Object::fromValue(headers_dict.get(), nullptr))
.SetInitialPriority(resourcePriority(request.priority))
.SetReferrerPolicy(referrerPolicy(request.referrer_policy))
.Build();
+ if (!url_fragment.empty())
+ request_object->SetUrlFragment(url_fragment);
std::string post_data;
if (request.request_body && GetPostData(*request.request_body, &post_data))
request_object->SetPostData(std::move(post_data));
@@ -1912,24 +1966,30 @@ NetworkHandler::CreateRequestFromResourceRequest(
// static
std::unique_ptr<Network::Request> NetworkHandler::CreateRequestFromURLRequest(
- const net::URLRequest* request) {
+ const net::URLRequest* request,
+ const std::string& cookie) {
std::unique_ptr<DictionaryValue> headers_dict(DictionaryValue::create());
for (net::HttpRequestHeaders::Iterator it(request->extra_request_headers());
it.GetNext();) {
headers_dict->setString(it.name(), it.value());
}
+ if (!cookie.empty())
+ headers_dict->setString(net::HttpRequestHeaders::kCookie, cookie);
if (!request->referrer().empty()) {
headers_dict->setString(net::HttpRequestHeaders::kReferer,
request->referrer());
}
+ std::string url_fragment;
std::unique_ptr<protocol::Network::Request> request_object =
Network::Request::Create()
- .SetUrl(ClearUrlRef(request->url()).spec())
+ .SetUrl(ExtractFragment(request->url(), &url_fragment))
.SetMethod(request->method())
.SetHeaders(Object::fromValue(headers_dict.get(), nullptr))
.SetInitialPriority(resourcePriority(request->priority()))
.SetReferrerPolicy(referrerPolicy(request->referrer_policy()))
.Build();
+ if (!url_fragment.empty())
+ request_object->SetUrlFragment(url_fragment);
std::string post_data;
if (GetPostData(request, &post_data))
request_object->SetPostData(std::move(post_data));
@@ -1969,9 +2029,6 @@ bool NetworkHandler::MaybeCreateProxyForInterception(
void NetworkHandler::ApplyOverrides(net::HttpRequestHeaders* headers,
bool* skip_service_worker,
bool* disable_cache) {
- 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);
*skip_service_worker |= bypass_service_worker_;
@@ -2011,11 +2068,11 @@ const char* ResourceTypeToString(ResourceType resource_type) {
case RESOURCE_TYPE_XHR:
return protocol::Page::ResourceTypeEnum::XHR;
case RESOURCE_TYPE_PING:
- return protocol::Page::ResourceTypeEnum::Other;
+ return protocol::Page::ResourceTypeEnum::Ping;
case RESOURCE_TYPE_SERVICE_WORKER:
return protocol::Page::ResourceTypeEnum::Other;
case RESOURCE_TYPE_CSP_REPORT:
- return protocol::Page::ResourceTypeEnum::Other;
+ return protocol::Page::ResourceTypeEnum::CSPViolationReport;
case RESOURCE_TYPE_PLUGIN_RESOURCE:
return protocol::Page::ResourceTypeEnum::Other;
default:
@@ -2046,7 +2103,9 @@ void NetworkHandler::SetNetworkConditions(
network::mojom::NetworkContext* context =
storage_partition_->GetNetworkContext();
bool offline = conditions ? conditions->offline : false;
- context->SetNetworkConditions(host_id_, std::move(conditions));
+
+ if (!devtools_token_.is_empty())
+ context->SetNetworkConditions(devtools_token_, std::move(conditions));
if (offline == !!background_sync_restorer_)
return;
diff --git a/chromium/content/browser/devtools/protocol/network_handler.h b/chromium/content/browser/devtools/protocol/network_handler.h
index 121d24f0bf5..e83b50cad5b 100644
--- a/chromium/content/browser/devtools/protocol/network_handler.h
+++ b/chromium/content/browser/devtools/protocol/network_handler.h
@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
+#include "base/unguessable_token.h"
#include "content/browser/devtools/devtools_url_loader_interceptor.h"
#include "content/browser/devtools/protocol/devtools_domain_handler.h"
#include "content/browser/devtools/protocol/network.h"
@@ -21,14 +22,11 @@
#include "net/cookies/canonical_cookie.h"
#include "services/network/public/mojom/network_service.mojom.h"
-namespace base {
-class UnguessableToken;
-};
-
namespace net {
class HttpRequestHeaders;
class URLRequest;
class SSLInfo;
+class X509Certificate;
} // namespace net
namespace network {
@@ -46,10 +44,11 @@ class InterceptionHandle;
class NavigationHandle;
class NavigationRequest;
class NavigationThrottle;
-class SignedExchangeHeader;
+class SignedExchangeEnvelope;
class StoragePartition;
struct GlobalRequestID;
struct InterceptedRequestInfo;
+struct SignedExchangeError;
namespace protocol {
class BackgroundSyncRestorer;
@@ -57,7 +56,9 @@ class BackgroundSyncRestorer;
class NetworkHandler : public DevToolsDomainHandler,
public Network::Backend {
public:
- NetworkHandler(const std::string& host_id, DevToolsIOContext* io_context);
+ NetworkHandler(const std::string& host_id,
+ const base::UnguessableToken& devtools_token,
+ DevToolsIOContext* io_context);
~NetworkHandler() override;
static std::vector<NetworkHandler*> ForAgentHost(DevToolsAgentHostImpl* host);
@@ -101,7 +102,6 @@ class NetworkHandler : public DevToolsDomainHandler,
std::unique_ptr<protocol::Array<Network::CookieParam>> cookies,
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;
@@ -166,19 +166,21 @@ class NetworkHandler : public DevToolsDomainHandler,
base::Optional<const base::UnguessableToken> devtools_navigation_token,
const GURL& outer_request_url,
const network::ResourceResponseHead& outer_response,
- const base::Optional<SignedExchangeHeader>& header,
+ const base::Optional<SignedExchangeEnvelope>& header,
+ const scoped_refptr<net::X509Certificate>& certificate,
const base::Optional<net::SSLInfo>& ssl_info,
- const std::vector<std::string>& error_messages);
+ const std::vector<SignedExchangeError>& errors);
bool enabled() const { return enabled_; }
Network::Frontend* frontend() const { return frontend_.get(); }
- static GURL ClearUrlRef(const GURL& url);
+ static std::string ExtractFragment(const GURL& url, std::string* fragment);
static std::unique_ptr<Network::Request> CreateRequestFromResourceRequest(
const network::ResourceRequest& request);
static std::unique_ptr<Network::Request> CreateRequestFromURLRequest(
- const net::URLRequest* request);
+ const net::URLRequest* request,
+ const std::string& cookie);
std::unique_ptr<NavigationThrottle> CreateThrottleForNavigation(
NavigationHandle* navigation_handle);
@@ -197,7 +199,10 @@ class NetworkHandler : public DevToolsDomainHandler,
mojo::ScopedDataPipeConsumerHandle pipe,
const std::string& mime_type);
+ // TODO(dgozman): Remove this.
const std::string host_id_;
+
+ const base::UnguessableToken devtools_token_;
DevToolsIOContext* const io_context_;
std::unique_ptr<Network::Frontend> frontend_;
@@ -205,7 +210,6 @@ class NetworkHandler : public DevToolsDomainHandler,
StoragePartition* storage_partition_;
RenderFrameHostImpl* host_;
bool enabled_;
- std::string user_agent_;
std::vector<std::pair<std::string, std::string>> extra_headers_;
std::unique_ptr<InterceptionHandle> interception_handle_;
std::unique_ptr<DevToolsURLLoaderInterceptor> url_loader_interceptor_;
diff --git a/chromium/content/browser/devtools/protocol/page_handler.cc b/chromium/content/browser/devtools/protocol/page_handler.cc
index 7e497a0402b..a55920d878a 100644
--- a/chromium/content/browser/devtools/protocol/page_handler.cc
+++ b/chromium/content/browser/devtools/protocol/page_handler.cc
@@ -153,11 +153,12 @@ gfx::Size DetermineSnapshotSize(const gfx::Size& surface_size,
return gfx::ToRoundedSize(gfx::ScaleSize(gfx::SizeF(surface_size), scale));
}
-#if !defined(OS_ANDROID)
void GetMetadataFromFrame(const media::VideoFrame& frame,
double* device_scale_factor,
double* page_scale_factor,
- gfx::Vector2dF* root_scroll_offset) {
+ gfx::Vector2dF* root_scroll_offset,
+ double* top_controls_height,
+ double* top_controls_shown_ratio) {
// Get metadata from |frame| and ensure that no metadata is missing.
bool success = true;
double root_scroll_offset_x, root_scroll_offset_y;
@@ -169,12 +170,16 @@ void GetMetadataFromFrame(const media::VideoFrame& frame,
media::VideoFrameMetadata::ROOT_SCROLL_OFFSET_X, &root_scroll_offset_x);
success &= frame.metadata()->GetDouble(
media::VideoFrameMetadata::ROOT_SCROLL_OFFSET_Y, &root_scroll_offset_y);
+ success &= frame.metadata()->GetDouble(
+ media::VideoFrameMetadata::TOP_CONTROLS_HEIGHT, top_controls_height);
+ success &= frame.metadata()->GetDouble(
+ media::VideoFrameMetadata::TOP_CONTROLS_SHOWN_RATIO,
+ top_controls_shown_ratio);
DCHECK(success);
root_scroll_offset->set_x(root_scroll_offset_x);
root_scroll_offset->set_y(root_scroll_offset_y);
}
-#endif // !defined(OS_ANDROID)
} // namespace
@@ -191,15 +196,12 @@ PageHandler::PageHandler(EmulationHandler* emulation_handler)
session_id_(0),
frame_counter_(0),
frames_in_flight_(0),
-#if !defined(OS_ANDROID)
video_consumer_(nullptr),
last_surface_size_(gfx::Size()),
-#endif // !defined(OS_ANDROID)
host_(nullptr),
emulation_handler_(emulation_handler),
observer_(this),
weak_factory_(this) {
-#if !defined(OS_ANDROID)
if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
base::FeatureList::IsEnabled(
features::kUseVideoCaptureApiForDevToolsSnapshots)) {
@@ -207,7 +209,6 @@ PageHandler::PageHandler(EmulationHandler* emulation_handler)
base::BindRepeating(&PageHandler::OnFrameFromVideoConsumer,
weak_factory_.GetWeakPtr()));
}
-#endif // !defined(OS_ANDROID)
DCHECK(emulation_handler_);
}
@@ -252,12 +253,10 @@ void PageHandler::SetRenderer(int process_host_id,
if (widget_host)
observer_.Add(widget_host);
-#if !defined(OS_ANDROID)
if (video_consumer_ && frame_host) {
video_consumer_->SetFrameSinkId(
frame_host->GetRenderWidgetHost()->GetFrameSinkId());
}
-#endif // !defined(OS_ANDROID)
}
void PageHandler::Wire(UberDispatcher* dispatcher) {
@@ -267,6 +266,9 @@ void PageHandler::Wire(UberDispatcher* dispatcher) {
void PageHandler::OnSwapCompositorFrame(
viz::CompositorFrameMetadata frame_metadata) {
+ if (video_consumer_)
+ return;
+
last_compositor_frame_metadata_ = std::move(frame_metadata);
has_compositor_frame_metadata_ = true;
@@ -365,10 +367,8 @@ Response PageHandler::Disable() {
enabled_ = false;
screencast_enabled_ = false;
-#if !defined(OS_ANDROID)
if (video_consumer_)
video_consumer_->StopCapture();
-#endif // !defined(OS_ANDROID)
if (!pending_dialog_.is_null()) {
WebContentsImpl* web_contents = GetWebContents();
@@ -768,7 +768,6 @@ Response PageHandler::StartScreencast(Maybe<std::string> format,
bool visible = !widget_host->is_hidden();
NotifyScreencastVisibility(visible);
-#if !defined(OS_ANDROID)
if (video_consumer_) {
gfx::Size surface_size = gfx::Size();
RenderWidgetHostViewBase* const view =
@@ -786,7 +785,6 @@ Response PageHandler::StartScreencast(Maybe<std::string> format,
video_consumer_->StartCapture();
return Response::FallThrough();
}
-#endif // !defined(OS_ANDROID)
if (!visible)
return Response::FallThrough();
@@ -794,18 +792,15 @@ Response PageHandler::StartScreencast(Maybe<std::string> format,
if (has_compositor_frame_metadata_) {
InnerSwapCompositorFrame();
} else {
- widget_host->Send(new ViewMsg_ForceRedraw(widget_host->GetRoutingID(),
- ui::LatencyInfo()));
+ widget_host->Send(new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), 0));
}
return Response::FallThrough();
}
Response PageHandler::StopScreencast() {
screencast_enabled_ = false;
-#if !defined(OS_ANDROID)
if (video_consumer_)
video_consumer_->StopCapture();
-#endif // !defined(OS_ANDROID)
return Response::FallThrough();
}
@@ -969,7 +964,6 @@ void PageHandler::InnerSwapCompositorFrame() {
frames_in_flight_++;
}
-#if !defined(OS_ANDROID)
void PageHandler::OnFrameFromVideoConsumer(
scoped_refptr<media::VideoFrame> frame) {
if (!host_)
@@ -995,24 +989,21 @@ void PageHandler::OnFrameFromVideoConsumer(
}
double device_scale_factor, page_scale_factor;
+ double top_controls_height, top_controls_shown_ratio;
gfx::Vector2dF root_scroll_offset;
GetMetadataFromFrame(*frame, &device_scale_factor, &page_scale_factor,
- &root_scroll_offset);
- // Top controls are only present on Android. Hence use default values of 0.f.
- // TODO(dgozman): fix this when viz capture is available on Android.
- const float kTopControlsHeight = 0.f;
- const float kTopControlsShownRatio = 0.f;
+ &root_scroll_offset, &top_controls_height,
+ &top_controls_shown_ratio);
std::unique_ptr<Page::ScreencastFrameMetadata> page_metadata =
- BuildScreencastFrameMetadata(surface_size, device_scale_factor,
- page_scale_factor, root_scroll_offset,
- kTopControlsHeight, kTopControlsShownRatio);
+ BuildScreencastFrameMetadata(
+ surface_size, device_scale_factor, page_scale_factor,
+ root_scroll_offset, top_controls_height, top_controls_shown_ratio);
if (!page_metadata)
return;
ScreencastFrameCaptured(std::move(page_metadata),
DevToolsVideoConsumer::GetSkBitmapFromFrame(frame));
}
-#endif // !defined(OS_ANDROID)
void PageHandler::ScreencastFrameCaptured(
std::unique_ptr<Page::ScreencastFrameMetadata> page_metadata,
@@ -1121,13 +1112,11 @@ Response PageHandler::SetWebLifecycleState(const std::string& state) {
// TODO(fmeawad): Instead of forcing a visibility change, only allow
// freezing a page if it was already hidden.
web_contents->WasHidden();
- web_contents->FreezePage();
+ web_contents->SetPageFrozen(true);
return Response::OK();
}
if (state == Page::SetWebLifecycleState::StateEnum::Active) {
- // Making the page visible should make it active as visible pages cannot be
- // frozen.
- web_contents->WasShown();
+ web_contents->SetPageFrozen(false);
return Response::OK();
}
return Response::Error("Unidentified lifecycle state");
diff --git a/chromium/content/browser/devtools/protocol/page_handler.h b/chromium/content/browser/devtools/protocol/page_handler.h
index c9c0b1f1ed4..eb6a09acea3 100644
--- a/chromium/content/browser/devtools/protocol/page_handler.h
+++ b/chromium/content/browser/devtools/protocol/page_handler.h
@@ -19,6 +19,7 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/viz/common/quads/compositor_frame_metadata.h"
+#include "content/browser/devtools/devtools_video_consumer.h"
#include "content/browser/devtools/protocol/devtools_domain_handler.h"
#include "content/browser/devtools/protocol/devtools_download_manager_delegate.h"
#include "content/browser/devtools/protocol/page.h"
@@ -28,10 +29,6 @@
#include "third_party/blink/public/mojom/manifest/manifest_manager.mojom.h"
#include "url/gurl.h"
-#if !defined(OS_ANDROID)
-#include "content/browser/devtools/devtools_video_consumer.h"
-#endif // !defined(OS_ANDROID)
-
class SkBitmap;
namespace base {
@@ -162,9 +159,7 @@ class PageHandler : public DevToolsDomainHandler,
WebContentsImpl* GetWebContents();
void NotifyScreencastVisibility(bool visible);
void InnerSwapCompositorFrame();
-#if !defined(OS_ANDROID)
void OnFrameFromVideoConsumer(scoped_refptr<media::VideoFrame> frame);
-#endif // !defined(OS_ANDROID)
void ScreencastFrameCaptured(
std::unique_ptr<Page::ScreencastFrameMetadata> metadata,
const SkBitmap& bitmap);
@@ -206,7 +201,6 @@ class PageHandler : public DevToolsDomainHandler,
int frame_counter_;
int frames_in_flight_;
-#if !defined(OS_ANDROID)
// |video_consumer_| consumes video frames from FrameSinkVideoCapturerImpl,
// and provides PageHandler with these frames via OnFrameFromVideoConsumer.
// This is only used if Viz is enabled and if OS is not Android.
@@ -215,7 +209,6 @@ class PageHandler : public DevToolsDomainHandler,
// The last surface size used to determine if frames with new sizes need
// to be requested. This changes due to window resizing.
gfx::Size last_surface_size_;
-#endif // !defined(OS_ANDROID)
RenderFrameHostImpl* host_;
EmulationHandler* emulation_handler_;
diff --git a/chromium/content/browser/devtools/protocol/service_worker_handler.cc b/chromium/content/browser/devtools/protocol/service_worker_handler.cc
index 5449b409717..77d1cc9fda7 100644
--- a/chromium/content/browser/devtools/protocol/service_worker_handler.cc
+++ b/chromium/content/browser/devtools/protocol/service_worker_handler.cc
@@ -114,9 +114,10 @@ void DidFindRegistrationForDispatchSyncEventOnIO(
scoped_refptr<BackgroundSyncContext> sync_context,
const std::string& tag,
bool last_chance,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<content::ServiceWorkerRegistration> registration) {
- if (status != SERVICE_WORKER_OK || !registration->active_version())
+ if (status != blink::ServiceWorkerStatusCode::kOk ||
+ !registration->active_version())
return;
BackgroundSyncManager* background_sync_manager =
sync_context->background_sync_manager();
@@ -127,7 +128,7 @@ void DidFindRegistrationForDispatchSyncEventOnIO(
tag, std::move(version), last_chance,
base::BindOnce(base::DoNothing::Once<
scoped_refptr<content::ServiceWorkerRegistration>,
- ServiceWorkerStatusCode>(),
+ blink::ServiceWorkerStatusCode>(),
std::move(registration)));
}
diff --git a/chromium/content/browser/devtools/protocol/system_info_handler.cc b/chromium/content/browser/devtools/protocol/system_info_handler.cc
index 618ad4a9f24..c6673d3451c 100644
--- a/chromium/content/browser/devtools/protocol/system_info_handler.cc
+++ b/chromium/content/browser/devtools/protocol/system_info_handler.cc
@@ -83,6 +83,10 @@ class AuxGPUInfoEnumerator : public gpu::GPUInfo::Enumerator {
void EndVideoEncodeAcceleratorSupportedProfile() override {}
+ void BeginOverlayCapability() override {}
+
+ void EndOverlayCapability() override {}
+
void BeginAuxAttributes() override {
in_aux_attributes_ = true;
}
diff --git a/chromium/content/browser/devtools/protocol/target_handler.cc b/chromium/content/browser/devtools/protocol/target_handler.cc
index 1ebf94ff0ef..1d467539ccc 100644
--- a/chromium/content/browser/devtools/protocol/target_handler.cc
+++ b/chromium/content/browser/devtools/protocol/target_handler.cc
@@ -4,15 +4,23 @@
#include "content/browser/devtools/protocol/target_handler.h"
+#include "base/base64.h"
+#include "base/containers/flat_map.h"
#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
#include "base/strings/stringprintf.h"
+#include "base/unguessable_token.h"
#include "base/values.h"
+#include "build/build_config.h"
+#include "content/browser/devtools/browser_devtools_agent_host.h"
#include "content/browser/devtools/devtools_manager.h"
#include "content/browser/devtools/devtools_session.h"
+#include "content/browser/devtools/target_registry.h"
#include "content/browser/frame_host/navigation_handle_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/devtools_agent_host_client.h"
#include "content/public/browser/navigation_throttle.h"
+#include "content/public/browser/web_contents.h"
namespace content {
namespace protocol {
@@ -21,6 +29,19 @@ namespace {
static const char kMethod[] = "method";
static const char kResumeMethod[] = "Runtime.runIfWaitingForDebugger";
+static const char kInitializerScript[] = R"(
+ (function() {
+ const bindingName = "%s";
+ const binding = window[bindingName];
+ delete window[bindingName];
+ if (window.self === window.top) {
+ window[bindingName] = {
+ onmessage: () => {},
+ send: binding
+ };
+ }
+ })();
+)";
std::unique_ptr<Target::TargetInfo> CreateInfo(DevToolsAgentHost* host) {
std::unique_ptr<Target::TargetInfo> target_info =
@@ -38,6 +59,152 @@ std::unique_ptr<Target::TargetInfo> CreateInfo(DevToolsAgentHost* host) {
return target_info;
}
+static std::string TerminationStatusToString(base::TerminationStatus status) {
+ switch (status) {
+ case base::TERMINATION_STATUS_NORMAL_TERMINATION:
+ return "normal";
+ case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
+ return "abnormal";
+ case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
+ return "killed";
+ case base::TERMINATION_STATUS_PROCESS_CRASHED:
+ return "crashed";
+ case base::TERMINATION_STATUS_STILL_RUNNING:
+ return "still running";
+#if defined(OS_CHROMEOS)
+ // Used for the case when oom-killer kills a process on ChromeOS.
+ case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
+ return "oom killed";
+#endif
+#if defined(OS_ANDROID)
+ // On Android processes are spawned from the system Zygote and we do not get
+ // the termination status. We can't know if the termination was a crash or
+ // an oom kill for sure: but we can use status of the strong process
+ // bindings as a hint.
+ case base::TERMINATION_STATUS_OOM_PROTECTED:
+ return "oom protected";
+#endif
+ case base::TERMINATION_STATUS_LAUNCH_FAILED:
+ return "failed to launch";
+ case base::TERMINATION_STATUS_OOM:
+ return "oom";
+ case base::TERMINATION_STATUS_MAX_ENUM:
+ break;
+ }
+ NOTREACHED() << "Unknown Termination Status.";
+ return "unknown";
+}
+
+class BrowserToPageConnector;
+
+base::LazyInstance<base::flat_map<DevToolsAgentHost*,
+ std::unique_ptr<BrowserToPageConnector>>>::
+ Leaky g_browser_to_page_connectors;
+
+class BrowserToPageConnector : public DevToolsAgentHostClient {
+ public:
+ BrowserToPageConnector(const std::string& binding_name,
+ DevToolsAgentHost* page_host)
+ : binding_name_(binding_name), page_host_(page_host) {
+ browser_host_ = BrowserDevToolsAgentHost::CreateForDiscovery();
+ browser_host_->AttachClient(this);
+ page_host_->AttachClient(this);
+
+ SendProtocolMessageToPage("Page.enable", std::make_unique<base::Value>());
+ SendProtocolMessageToPage("Runtime.enable",
+ std::make_unique<base::Value>());
+
+ std::unique_ptr<base::DictionaryValue> add_binding_params =
+ std::make_unique<base::DictionaryValue>();
+ add_binding_params->SetString("name", binding_name);
+ SendProtocolMessageToPage("Runtime.addBinding",
+ std::move(add_binding_params));
+
+ std::string initializer_script =
+ base::StringPrintf(kInitializerScript, binding_name.c_str());
+
+ std::unique_ptr<base::DictionaryValue> params =
+ std::make_unique<base::DictionaryValue>();
+ params->SetString("scriptSource", initializer_script);
+ SendProtocolMessageToPage("Page.addScriptToEvaluateOnLoad",
+ std::move(params));
+
+ std::unique_ptr<base::DictionaryValue> evaluate_params =
+ std::make_unique<base::DictionaryValue>();
+ evaluate_params->SetString("expression", initializer_script);
+ SendProtocolMessageToPage("Runtime.evaluate", std::move(evaluate_params));
+ g_browser_to_page_connectors.Get()[page_host_.get()].reset(this);
+ }
+
+ private:
+ void SendProtocolMessageToPage(const char* method,
+ std::unique_ptr<base::Value> params) {
+ base::DictionaryValue message;
+ message.SetInteger("id", page_message_id_++);
+ message.SetString("method", method);
+ message.Set("params", std::move(params));
+ std::string json_message;
+ base::JSONWriter::Write(message, &json_message);
+ page_host_->DispatchProtocolMessage(this, json_message);
+ }
+
+ void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
+ const std::string& message) override {
+ if (agent_host == page_host_.get()) {
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(message);
+ if (!value || !value->is_dict())
+ return;
+ // Make sure this is a binding call.
+ base::Value* method = value->FindKey("method");
+ if (!method || !method->is_string() ||
+ method->GetString() != "Runtime.bindingCalled")
+ return;
+ base::Value* params = value->FindKey("params");
+ if (!params || !params->is_dict())
+ return;
+ base::Value* name = params->FindKey("name");
+ if (!name || !name->is_string() || name->GetString() != binding_name_)
+ return;
+ base::Value* payload = params->FindKey("payload");
+ if (!payload || !payload->is_string())
+ return;
+ browser_host_->DispatchProtocolMessage(this, payload->GetString());
+ return;
+ }
+ DCHECK(agent_host == browser_host_.get());
+
+ std::string encoded;
+ base::Base64Encode(message, &encoded);
+ std::string eval_code = "window." + binding_name_ + ".onmessage(atob(\"";
+ std::string eval_suffix = "\"))";
+ eval_code.reserve(eval_code.size() + encoded.size() + eval_suffix.size());
+ eval_code.append(encoded);
+ eval_code.append(eval_suffix);
+
+ std::unique_ptr<base::DictionaryValue> params =
+ std::make_unique<base::DictionaryValue>();
+ params->SetString("expression", eval_code);
+ SendProtocolMessageToPage("Runtime.evaluate", std::move(params));
+ }
+
+ void AgentHostClosed(DevToolsAgentHost* agent_host) override {
+ if (agent_host == browser_host_.get()) {
+ page_host_->DetachClient(this);
+ } else {
+ DCHECK(agent_host == page_host_.get());
+ browser_host_->DetachClient(this);
+ }
+ g_browser_to_page_connectors.Get().erase(page_host_.get());
+ }
+
+ std::string binding_name_;
+ scoped_refptr<DevToolsAgentHost> browser_host_;
+ scoped_refptr<DevToolsAgentHost> page_host_;
+ int page_message_id_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserToPageConnector);
+};
+
} // namespace
// Throttle is owned externally by the navigation subsystem.
@@ -49,9 +216,11 @@ class TargetHandler::Throttle : public content::NavigationThrottle {
void Clear();
// content::NavigationThrottle implementation:
NavigationThrottle::ThrottleCheckResult WillProcessResponse() override;
+ NavigationThrottle::ThrottleCheckResult WillFailRequest() override;
const char* GetNameForLogging() override;
private:
+ NavigationThrottle::ThrottleCheckResult MaybeAttach();
void CleanupPointers();
base::WeakPtr<protocol::TargetHandler> target_handler_;
@@ -64,28 +233,41 @@ class TargetHandler::Session : public DevToolsAgentHostClient {
public:
static std::string Attach(TargetHandler* handler,
DevToolsAgentHost* agent_host,
- bool waiting_for_debugger) {
- std::string id = base::StringPrintf("%s:%d", agent_host->GetId().c_str(),
- ++handler->last_session_id_);
- Session* session = new Session(handler, agent_host, id);
+ bool waiting_for_debugger,
+ bool flatten_protocol) {
+ std::string id = base::UnguessableToken::Create().ToString();
+ Session* session = new Session(handler, agent_host, id, flatten_protocol);
handler->attached_sessions_[id].reset(session);
- agent_host->AttachClient(session);
+ DevToolsAgentHostImpl* agent_host_impl =
+ static_cast<DevToolsAgentHostImpl*>(agent_host);
+ if (flatten_protocol) {
+ handler->target_registry_->AttachSubtargetSession(id, agent_host_impl,
+ session);
+ } else {
+ agent_host_impl->AttachClient(session);
+ }
handler->frontend_->AttachedToTarget(id, CreateInfo(agent_host),
waiting_for_debugger);
return id;
}
~Session() override {
- if (agent_host_)
- agent_host_->DetachClient(this);
+ if (!agent_host_)
+ return;
+ if (handler_->target_registry_)
+ handler_->target_registry_->DetachSubtargetSession(id_);
+ agent_host_->DetachClient(this);
}
void Detach(bool host_closed) {
handler_->frontend_->DetachedFromTarget(id_, agent_host_->GetId());
if (host_closed)
handler_->auto_attacher_.AgentHostClosed(agent_host_.get());
- else
+ else {
+ if (handler_->target_registry_)
+ handler_->target_registry_->DetachSubtargetSession(id_);
agent_host_->DetachClient(this);
+ }
handler_->auto_attached_sessions_.erase(agent_host_.get());
agent_host_ = nullptr;
handler_->attached_sessions_.erase(id_);
@@ -114,15 +296,26 @@ class TargetHandler::Session : public DevToolsAgentHostClient {
}
private:
+ friend class TargetHandler;
+
Session(TargetHandler* handler,
DevToolsAgentHost* agent_host,
- const std::string& id)
- : handler_(handler), agent_host_(agent_host), id_(id) {}
+ const std::string& id,
+ bool flatten_protocol)
+ : handler_(handler),
+ agent_host_(agent_host),
+ id_(id),
+ flatten_protocol_(flatten_protocol) {}
// DevToolsAgentHostClient implementation.
void DispatchProtocolMessage(DevToolsAgentHost* agent_host,
const std::string& message) override {
DCHECK(agent_host == agent_host_.get());
+ if (flatten_protocol_) {
+ handler_->target_registry_->SendMessageToClient(id_, message);
+ return;
+ }
+
handler_->frontend_->ReceivedMessageFromTarget(id_, message,
agent_host_->GetId());
}
@@ -135,6 +328,7 @@ class TargetHandler::Session : public DevToolsAgentHostClient {
TargetHandler* handler_;
scoped_refptr<DevToolsAgentHost> agent_host_;
std::string id_;
+ bool flatten_protocol_;
Throttle* throttle_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(Session);
@@ -166,6 +360,15 @@ void TargetHandler::Throttle::CleanupPointers() {
NavigationThrottle::ThrottleCheckResult
TargetHandler::Throttle::WillProcessResponse() {
+ return MaybeAttach();
+}
+
+NavigationThrottle::ThrottleCheckResult
+TargetHandler::Throttle::WillFailRequest() {
+ return MaybeAttach();
+}
+
+NavigationThrottle::ThrottleCheckResult TargetHandler::Throttle::MaybeAttach() {
if (!target_handler_)
return PROCEED;
agent_host_ = target_handler_->auto_attacher_.AutoAttachToFrame(
@@ -189,13 +392,17 @@ void TargetHandler::Throttle::Clear() {
}
}
-TargetHandler::TargetHandler(bool browser_only)
+TargetHandler::TargetHandler(bool browser_only,
+ const std::string& owner_target_id,
+ TargetRegistry* target_registry)
: DevToolsDomainHandler(Target::Metainfo::domainName),
auto_attacher_(
base::Bind(&TargetHandler::AutoAttach, base::Unretained(this)),
base::Bind(&TargetHandler::AutoDetach, base::Unretained(this))),
discover_(false),
browser_only_(browser_only),
+ owner_target_id_(owner_target_id),
+ target_registry_(target_registry),
weak_factory_(this) {}
TargetHandler::~TargetHandler() {
@@ -247,7 +454,8 @@ void TargetHandler::ClearThrottles() {
void TargetHandler::AutoAttach(DevToolsAgentHost* host,
bool waiting_for_debugger) {
- std::string session_id = Session::Attach(this, host, waiting_for_debugger);
+ std::string session_id =
+ Session::Attach(this, host, waiting_for_debugger, false);
auto_attached_sessions_[host] = attached_sessions_[session_id].get();
}
@@ -323,13 +531,27 @@ Response TargetHandler::SetRemoteLocations(
}
Response TargetHandler::AttachToTarget(const std::string& target_id,
+ Maybe<bool> flatten,
std::string* out_session_id) {
// TODO(dgozman): only allow reported hosts.
scoped_refptr<DevToolsAgentHost> agent_host =
DevToolsAgentHost::GetForId(target_id);
if (!agent_host)
return Response::InvalidParams("No target with given id found");
- *out_session_id = Session::Attach(this, agent_host.get(), false);
+ if (flatten.fromMaybe(false) && !target_registry_) {
+ return Response::InvalidParams(
+ "Will only provide flatten access for browser endpoint");
+ }
+ *out_session_id =
+ Session::Attach(this, agent_host.get(), false, flatten.fromMaybe(false));
+ return Response::OK();
+}
+
+Response TargetHandler::AttachToBrowserTarget(std::string* out_session_id) {
+ scoped_refptr<DevToolsAgentHost> agent_host =
+ DevToolsAgentHost::CreateForBrowser(
+ nullptr, DevToolsAgentHost::CreateServerSocketCallback());
+ *out_session_id = Session::Attach(this, agent_host.get(), false, true);
return Response::OK();
}
@@ -352,13 +574,20 @@ Response TargetHandler::SendMessageToTarget(const std::string& message,
FindSession(std::move(session_id), std::move(target_id), &session, true);
if (!response.isSuccess())
return response;
+ if (session->flatten_protocol_) {
+ return Response::Error(
+ "When using flat protocol, messages are routed to the target "
+ "via the sessionId attribute.");
+ }
session->SendMessageToAgentHost(message);
return Response::OK();
}
Response TargetHandler::GetTargetInfo(
- const std::string& target_id,
+ Maybe<std::string> maybe_target_id,
std::unique_ptr<Target::TargetInfo>* target_info) {
+ const std::string& target_id =
+ maybe_target_id.isJust() ? maybe_target_id.fromJust() : owner_target_id_;
// TODO(dgozman): only allow reported hosts.
scoped_refptr<DevToolsAgentHost> agent_host(
DevToolsAgentHost::GetForId(target_id));
@@ -388,6 +617,32 @@ Response TargetHandler::CloseTarget(const std::string& target_id,
return Response::OK();
}
+Response TargetHandler::ExposeDevToolsProtocol(
+ const std::string& target_id,
+ Maybe<std::string> binding_name) {
+ if (!browser_only_) {
+ return Response::InvalidParams(
+ "Cannot grant remote debugging capability from non-browser session.");
+ }
+ scoped_refptr<DevToolsAgentHost> agent_host =
+ DevToolsAgentHost::GetForId(target_id);
+ if (!agent_host)
+ return Response::InvalidParams("No target with given id found");
+
+ if (g_browser_to_page_connectors.Get()[agent_host.get()]) {
+ return Response::Error(base::StringPrintf(
+ "Target with id %s is already granted remote debugging bindings.",
+ target_id.c_str()));
+ }
+ if (!agent_host->GetWebContents()) {
+ return Response::Error(
+ "RemoteDebuggingBinding can be granted only to page targets");
+ }
+
+ new BrowserToPageConnector(binding_name.fromMaybe("cdp"), agent_host.get());
+ return Response::OK();
+}
+
Response TargetHandler::CreateBrowserContext(std::string* out_context_id) {
return Response::Error("Not supported");
}
@@ -467,5 +722,15 @@ void TargetHandler::DevToolsAgentHostDetached(DevToolsAgentHost* host) {
frontend_->TargetInfoChanged(CreateInfo(host));
}
+void TargetHandler::DevToolsAgentHostCrashed(DevToolsAgentHost* host,
+ base::TerminationStatus status) {
+ if (reported_hosts_.find(host) == reported_hosts_.end())
+ return;
+ frontend_->TargetCrashed(host->GetId(), TerminationStatusToString(status),
+ host->GetWebContents()
+ ? host->GetWebContents()->GetCrashedErrorCode()
+ : 0);
+}
+
} // namespace protocol
} // namespace content
diff --git a/chromium/content/browser/devtools/protocol/target_handler.h b/chromium/content/browser/devtools/protocol/target_handler.h
index 7d75e62ad4c..ba5702adbd0 100644
--- a/chromium/content/browser/devtools/protocol/target_handler.h
+++ b/chromium/content/browser/devtools/protocol/target_handler.h
@@ -21,6 +21,7 @@ class DevToolsAgentHostImpl;
class NavigationHandle;
class NavigationThrottle;
class RenderFrameHostImpl;
+class TargetRegistry;
namespace protocol {
@@ -28,7 +29,9 @@ class TargetHandler : public DevToolsDomainHandler,
public Target::Backend,
public DevToolsAgentHostObserver {
public:
- explicit TargetHandler(bool browser_only);
+ TargetHandler(bool browser_only,
+ const std::string& owner_target_id,
+ TargetRegistry* target_registry);
~TargetHandler() override;
static std::vector<TargetHandler*> ForAgentHost(DevToolsAgentHostImpl* host);
@@ -50,18 +53,22 @@ class TargetHandler : public DevToolsDomainHandler,
Response SetRemoteLocations(
std::unique_ptr<protocol::Array<Target::RemoteLocation>>) override;
Response AttachToTarget(const std::string& target_id,
+ Maybe<bool> flatten,
std::string* out_session_id) override;
+ Response AttachToBrowserTarget(std::string* out_session_id) override;
Response DetachFromTarget(Maybe<std::string> session_id,
Maybe<std::string> target_id) override;
Response SendMessageToTarget(const std::string& message,
Maybe<std::string> session_id,
Maybe<std::string> target_id) override;
Response GetTargetInfo(
- const std::string& target_id,
+ Maybe<std::string> target_id,
std::unique_ptr<Target::TargetInfo>* target_info) override;
Response ActivateTarget(const std::string& target_id) override;
Response CloseTarget(const std::string& target_id,
bool* out_success) override;
+ Response ExposeDevToolsProtocol(const std::string& target_id,
+ Maybe<std::string> binding_name) override;
Response CreateBrowserContext(std::string* out_context_id) override;
Response DisposeBrowserContext(const std::string& context_id) override;
Response GetBrowserContexts(
@@ -95,6 +102,8 @@ class TargetHandler : public DevToolsDomainHandler,
void DevToolsAgentHostDestroyed(DevToolsAgentHost* agent_host) override;
void DevToolsAgentHostAttached(DevToolsAgentHost* agent_host) override;
void DevToolsAgentHostDetached(DevToolsAgentHost* agent_host) override;
+ void DevToolsAgentHostCrashed(DevToolsAgentHost* agent_host,
+ base::TerminationStatus status) override;
std::unique_ptr<Target::Frontend> frontend_;
TargetAutoAttacher auto_attacher_;
@@ -102,8 +111,9 @@ class TargetHandler : public DevToolsDomainHandler,
std::map<std::string, std::unique_ptr<Session>> attached_sessions_;
std::map<DevToolsAgentHost*, Session*> auto_attached_sessions_;
std::set<DevToolsAgentHost*> reported_hosts_;
- int last_session_id_ = 0;
bool browser_only_;
+ std::string owner_target_id_;
+ TargetRegistry* target_registry_;
base::flat_set<Throttle*> throttles_;
base::WeakPtrFactory<TargetHandler> weak_factory_;
diff --git a/chromium/content/browser/devtools/protocol/tracing_handler.cc b/chromium/content/browser/devtools/protocol/tracing_handler.cc
index 3435d90b298..9546e5dd5a3 100644
--- a/chromium/content/browser/devtools/protocol/tracing_handler.cc
+++ b/chromium/content/browser/devtools/protocol/tracing_handler.cc
@@ -42,6 +42,10 @@
#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
#include "services/tracing/public/mojom/constants.mojom.h"
+#ifdef OS_ANDROID
+#include "content/browser/renderer_host/compositor_impl_android.h"
+#endif
+
namespace content {
namespace protocol {
@@ -190,15 +194,15 @@ void FillFrameData(base::trace_event::TracedValue* data,
node->parent()->devtools_frame_token().ToString());
if (frame_host) {
RenderProcessHost* process_host = frame_host->GetProcess();
- base::ProcessId process_id = process_host->GetProcess().Pid();
- if (process_id == base::kNullProcessId) {
+ const base::Process& process_handle = process_host->GetProcess();
+ if (!process_handle.IsValid()) {
data->SetString("processPseudoId", GetProcessHostHex(process_host));
frame_host->GetProcess()->PostTaskWhenProcessIsReady(
base::BindOnce(&SendProcessReadyInBrowserEvent,
node->devtools_frame_token(), process_host));
} else {
// Cast process id to int to be compatible with tracing.
- data->SetInteger("processId", static_cast<int>(process_id));
+ data->SetInteger("processId", static_cast<int>(process_handle.Pid()));
}
}
}
@@ -214,17 +218,23 @@ TracingHandler::TracingHandler(FrameTreeNode* frame_tree_node_,
return_as_stream_(false),
gzip_compression_(false),
weak_factory_(this) {
- if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
+ bool use_video_capture_api =
+ base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
base::FeatureList::IsEnabled(
- features::kUseVideoCaptureApiForDevToolsSnapshots)) {
+ features::kUseVideoCaptureApiForDevToolsSnapshots);
+#ifdef OS_ANDROID
+ // Video capture API cannot be used on Android WebView.
+ if (!CompositorImpl::IsInitialized())
+ use_video_capture_api = false;
+#endif
+ if (use_video_capture_api) {
video_consumer_ =
std::make_unique<DevToolsVideoConsumer>(base::BindRepeating(
&TracingHandler::OnFrameFromVideoConsumer, base::Unretained(this)));
}
}
-TracingHandler::~TracingHandler() {
-}
+TracingHandler::~TracingHandler() = default;
// static
std::vector<TracingHandler*> TracingHandler::ForAgentHost(
@@ -386,17 +396,17 @@ void TracingHandler::Start(Maybe<std::string> categories,
if (buffer_usage_reporting_interval.isJust())
SetupTimer(buffer_usage_reporting_interval.fromJust());
- base::trace_event::TraceConfig trace_config;
+ trace_config_ = base::trace_event::TraceConfig();
if (config.isJust()) {
std::unique_ptr<base::Value> value =
protocol::toBaseValue(config.fromJust()->toValue().get(), 1000);
if (value && value->is_dict()) {
- trace_config = GetTraceConfigFromDevToolsConfig(
+ trace_config_ = GetTraceConfigFromDevToolsConfig(
*static_cast<base::DictionaryValue*>(value.get()));
}
} else if (categories.isJust() || options.isJust()) {
- trace_config = base::trace_event::TraceConfig(
- categories.fromMaybe(""), options.fromMaybe(""));
+ trace_config_ = base::trace_event::TraceConfig(categories.fromMaybe(""),
+ options.fromMaybe(""));
}
// If inspected target is a render process Tracing.start will be handled by
@@ -404,11 +414,57 @@ void TracingHandler::Start(Maybe<std::string> categories,
if (frame_tree_node_)
callback->fallThrough();
+ SetupProcessFilter(nullptr);
+
TracingController::GetInstance()->StartTracing(
- trace_config,
- base::Bind(&TracingHandler::OnRecordingEnabled,
- weak_factory_.GetWeakPtr(),
- base::Passed(std::move(callback))));
+ trace_config_, base::BindRepeating(&TracingHandler::OnRecordingEnabled,
+ weak_factory_.GetWeakPtr(),
+ base::Passed(std::move(callback))));
+}
+
+void TracingHandler::SetupProcessFilter(
+ RenderFrameHost* new_render_frame_host) {
+ if (!frame_tree_node_)
+ return;
+
+ base::ProcessId browser_pid = base::Process::Current().Pid();
+ std::unordered_set<base::ProcessId> included_process_ids({browser_pid});
+ if (new_render_frame_host)
+ AppendProcessId(new_render_frame_host, &included_process_ids);
+ for (FrameTreeNode* node :
+ frame_tree_node_->frame_tree()->SubtreeNodes(frame_tree_node_)) {
+ RenderFrameHost* frame_host = node->current_frame_host();
+ if (frame_host)
+ AppendProcessId(frame_host, &included_process_ids);
+ }
+ trace_config_.SetProcessFilterConfig(
+ base::trace_event::TraceConfig::ProcessFilterConfig(
+ included_process_ids));
+}
+
+void TracingHandler::AppendProcessId(
+ RenderFrameHost* render_frame_host,
+ std::unordered_set<base::ProcessId>* process_set) {
+ RenderProcessHost* process_host = render_frame_host->GetProcess();
+ if (process_host->GetProcess().IsValid()) {
+ process_set->insert(process_host->GetProcess().Pid());
+ } else {
+ process_host->PostTaskWhenProcessIsReady(
+ base::BindOnce(&TracingHandler::OnProcessReady,
+ weak_factory_.GetWeakPtr(), process_host));
+ }
+}
+
+void TracingHandler::OnProcessReady(RenderProcessHost* process_host) {
+ if (!did_initiate_recording_)
+ return;
+ std::unordered_set<base::ProcessId> included_process_ids(
+ {process_host->GetProcess().Pid()});
+ trace_config_.SetProcessFilterConfig(
+ base::trace_event::TraceConfig::ProcessFilterConfig(
+ included_process_ids));
+ TracingController::GetInstance()->StartTracing(
+ trace_config_, base::RepeatingCallback<void()>());
}
void TracingHandler::End(std::unique_ptr<EndCallback> callback) {
@@ -474,6 +530,8 @@ void TracingHandler::OnRecordingEnabled(
void TracingHandler::OnBufferUsage(float percent_full,
size_t approximate_event_count) {
+ if (!did_initiate_recording_)
+ return;
// TODO(crbug426117): remove set_value once all clients have switched to
// the new interface of the event.
frontend_->BufferUsage(percent_full, approximate_event_count, percent_full);
@@ -549,14 +607,13 @@ void TracingHandler::SetupTimer(double usage_reporting_interval) {
base::TimeDelta interval = base::TimeDelta::FromMilliseconds(
std::ceil(usage_reporting_interval));
- buffer_usage_poll_timer_.reset(new base::Timer(
+ buffer_usage_poll_timer_.reset(new base::RepeatingTimer());
+ buffer_usage_poll_timer_->Start(
FROM_HERE, interval,
base::Bind(base::IgnoreResult(&TracingController::GetTraceBufferUsage),
base::Unretained(TracingController::GetInstance()),
base::Bind(&TracingHandler::OnBufferUsage,
- weak_factory_.GetWeakPtr())),
- true));
- buffer_usage_poll_timer_->Reset();
+ weak_factory_.GetWeakPtr())));
}
void TracingHandler::StopTracing(
@@ -605,6 +662,10 @@ void TracingHandler::ReadyToCommitNavigation(
TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
"FrameCommittedInBrowser", TRACE_EVENT_SCOPE_THREAD,
"data", std::move(data));
+
+ SetupProcessFilter(navigation_handle->GetRenderFrameHost());
+ TracingController::GetInstance()->StartTracing(
+ trace_config_, base::RepeatingCallback<void()>());
}
void TracingHandler::FrameDeleted(RenderFrameHostImpl* frame_host) {
diff --git a/chromium/content/browser/devtools/protocol/tracing_handler.h b/chromium/content/browser/devtools/protocol/tracing_handler.h
index 7f21754cc10..82f11ef2a25 100644
--- a/chromium/content/browser/devtools/protocol/tracing_handler.h
+++ b/chromium/content/browser/devtools/protocol/tracing_handler.h
@@ -11,6 +11,7 @@
#include <memory>
#include <set>
#include <string>
+#include <unordered_set>
#include <vector>
#include "base/gtest_prod_util.h"
@@ -23,7 +24,7 @@
#include "content/public/browser/tracing_controller.h"
namespace base {
-class Timer;
+class RepeatingTimer;
}
namespace media {
@@ -37,6 +38,8 @@ class DevToolsVideoConsumer;
class DevToolsIOContext;
class FrameTreeNode;
class NavigationHandleImpl;
+class RenderFrameHost;
+class RenderProcessHost;
namespace protocol {
@@ -113,8 +116,12 @@ class TracingHandler : public DevToolsDomainHandler, public Tracing::Backend {
CONTENT_EXPORT static base::trace_event::TraceConfig
GetTraceConfigFromDevToolsConfig(
const base::DictionaryValue& devtools_config);
+ void SetupProcessFilter(RenderFrameHost*);
+ void AppendProcessId(RenderFrameHost*,
+ std::unordered_set<base::ProcessId>* process_set);
+ void OnProcessReady(RenderProcessHost*);
- std::unique_ptr<base::Timer> buffer_usage_poll_timer_;
+ std::unique_ptr<base::RepeatingTimer> buffer_usage_poll_timer_;
std::unique_ptr<Tracing::Frontend> frontend_;
DevToolsIOContext* io_context_;
@@ -125,6 +132,7 @@ class TracingHandler : public DevToolsDomainHandler, public Tracing::Backend {
TraceDataBufferState trace_data_buffer_state_;
std::unique_ptr<DevToolsVideoConsumer> video_consumer_;
int number_of_screenshots_from_video_consumer_ = 0;
+ base::trace_event::TraceConfig trace_config_;
base::WeakPtrFactory<TracingHandler> weak_factory_;
FRIEND_TEST_ALL_PREFIXES(TracingHandlerTest,
diff --git a/chromium/content/browser/devtools/protocol_config.json b/chromium/content/browser/devtools/protocol_config.json
index 90c595d05dc..0919b220303 100644
--- a/chromium/content/browser/devtools/protocol_config.json
+++ b/chromium/content/browser/devtools/protocol_config.json
@@ -20,7 +20,7 @@
},
{
"domain": "Emulation",
- "include": ["setGeolocationOverride", "clearGeolocationOverride", "setEmitTouchEventsForMouse", "canEmulate", "setDeviceMetricsOverride", "clearDeviceMetricsOverride", "setVisibleSize"]
+ "include": ["setGeolocationOverride", "clearGeolocationOverride", "setEmitTouchEventsForMouse", "canEmulate", "setDeviceMetricsOverride", "clearDeviceMetricsOverride", "setVisibleSize", "setUserAgentOverride"]
},
{
"domain": "Input",
@@ -41,7 +41,7 @@
},
{
"domain": "Network",
- "include": ["enable", "disable", "clearBrowserCache", "clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookies", "setCookie", "setCookies", "setUserAgentOverride", "setExtraHTTPHeaders", "canEmulateNetworkConditions", "emulateNetworkConditions", "setBypassServiceWorker", "setRequestInterception", "continueInterceptedRequest", "getResponseBodyForInterception", "setCacheDisabled", "takeResponseBodyForInterceptionAsStream"],
+ "include": ["enable", "disable", "clearBrowserCache", "clearBrowserCookies", "getCookies", "getAllCookies", "deleteCookies", "setCookie", "setCookies", "setExtraHTTPHeaders", "canEmulateNetworkConditions", "emulateNetworkConditions", "setBypassServiceWorker", "setRequestInterception", "continueInterceptedRequest", "getResponseBodyForInterception", "setCacheDisabled", "takeResponseBodyForInterceptionAsStream"],
"include_events": ["requestWillBeSent", "responseReceived", "loadingFinished", "loadingFailed", "requestIntercepted", "signedExchangeReceived"],
"async": ["clearBrowserCookies", "clearBrowserCache", "getCookies", "getAllCookies", "deleteCookies", "setCookie", "setCookies", "continueInterceptedRequest", "getResponseBodyForInterception", "takeResponseBodyForInterceptionAsStream"]
},
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 8c663d94e92..9493103481a 100644
--- a/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -41,7 +41,7 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/browser/web_package/signed_exchange_header.h"
+#include "content/browser/web_package/signed_exchange_envelope.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -60,6 +60,7 @@
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#if defined(OS_ANDROID)
+#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/public/browser/render_widget_host_view.h"
#include "services/device/public/mojom/wake_lock_context.mojom.h"
#endif
@@ -230,13 +231,14 @@ void RenderFrameDevToolsAgentHost::OnSignedExchangeReceived(
base::Optional<const base::UnguessableToken> devtools_navigation_token,
const GURL& outer_request_url,
const network::ResourceResponseHead& outer_response,
- const base::Optional<SignedExchangeHeader>& header,
+ const base::Optional<SignedExchangeEnvelope>& envelope,
+ const scoped_refptr<net::X509Certificate>& certificate,
const base::Optional<net::SSLInfo>& ssl_info,
- const std::vector<std::string>& error_messages) {
+ const std::vector<SignedExchangeError>& errors) {
DispatchToAgents(frame_tree_node,
&protocol::NetworkHandler::OnSignedExchangeReceived,
devtools_navigation_token, outer_request_url, outer_response,
- header, ssl_info, error_messages);
+ envelope, certificate, ssl_info, errors);
}
// static
@@ -334,6 +336,10 @@ void RenderFrameDevToolsAgentHost::ApplyOverrides(
network->ApplyOverrides(&headers, &begin_params->skip_service_worker,
&disable_cache);
}
+
+ for (auto* emulation : protocol::EmulationHandler::ForAgentHost(agent_host))
+ emulation->ApplyOverrides(&headers);
+
if (disable_cache) {
begin_params->load_flags &=
~(net::LOAD_VALIDATE_CACHE | net::LOAD_SKIP_CACHE_VALIDATION |
@@ -421,9 +427,18 @@ WebContents* RenderFrameDevToolsAgentHost::GetWebContents() {
return web_contents();
}
-bool RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session) {
- if (session->restricted() && !IsFrameHostAllowedForRestrictedSessions())
+bool RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session,
+ TargetRegistry* registry) {
+ DevToolsManager* manager = DevToolsManager::GetInstance();
+ if (manager->delegate() && web_contents()) {
+ if (!manager->delegate()->AllowInspectingWebContents(web_contents()))
+ return false;
+ }
+ const bool is_webui =
+ frame_host_ && (frame_host_->web_ui() || frame_host_->pending_web_ui());
+ if (!session->client()->MayAttachToRenderer(frame_host_, is_webui))
return false;
+
session->SetRenderer(frame_host_ ? frame_host_->GetProcess()->GetID()
: ChildProcessHost::kInvalidUniqueID,
frame_host_);
@@ -438,14 +453,17 @@ bool RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session) {
session->AddHandler(base::WrapUnique(new protocol::IOHandler(
GetIOContext())));
session->AddHandler(base::WrapUnique(new protocol::MemoryHandler()));
- session->AddHandler(
- base::WrapUnique(new protocol::NetworkHandler(GetId(), GetIOContext())));
+ session->AddHandler(base::WrapUnique(new protocol::NetworkHandler(
+ GetId(),
+ frame_tree_node_ ? frame_tree_node_->devtools_frame_token()
+ : base::UnguessableToken(),
+ GetIOContext())));
session->AddHandler(base::WrapUnique(new protocol::SchemaHandler()));
session->AddHandler(base::WrapUnique(new protocol::ServiceWorkerHandler()));
session->AddHandler(base::WrapUnique(new protocol::StorageHandler()));
if (!session->restricted()) {
- session->AddHandler(base::WrapUnique(
- new protocol::TargetHandler(false /* browser_only */)));
+ session->AddHandler(base::WrapUnique(new protocol::TargetHandler(
+ false /* browser_only */, GetId(), registry)));
}
session->AddHandler(
base::WrapUnique(new protocol::PageHandler(emulation_handler)));
@@ -459,12 +477,19 @@ bool RenderFrameDevToolsAgentHost::AttachSession(DevToolsSession* session) {
session->AttachToAgent(agent_ptr_);
if (sessions().size() == 1) {
- // Taking screenshots using the video capture API is done in TracingHandler.
- if (!base::FeatureList::IsEnabled(features::kVizDisplayCompositor) &&
- !base::FeatureList::IsEnabled(
- features::kUseVideoCaptureApiForDevToolsSnapshots)) {
+ bool use_video_capture_api =
+ base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
+ base::FeatureList::IsEnabled(
+ features::kUseVideoCaptureApiForDevToolsSnapshots);
+#ifdef OS_ANDROID
+ // Video capture API cannot be used on Android WebView.
+ if (!CompositorImpl::IsInitialized())
+ use_video_capture_api = false;
+#endif
+ // When video capture API is used, don't instantiate
+ // DevToolsFrameTraceRecorder. Taking snapshots happens in TracingHandler.
+ if (!use_video_capture_api)
frame_trace_recorder_.reset(new DevToolsFrameTraceRecorder());
- }
GrantPolicy();
#if defined(OS_ANDROID)
GetWakeLock()->RequestWakeLock();
@@ -484,12 +509,6 @@ void RenderFrameDevToolsAgentHost::DetachSession(DevToolsSession* session) {
}
}
-void RenderFrameDevToolsAgentHost::DispatchProtocolMessage(
- DevToolsSession* session,
- const std::string& message) {
- session->DispatchProtocolMessage(message);
-}
-
void RenderFrameDevToolsAgentHost::InspectElement(RenderFrameHost* frame_host,
int x,
int y) {
@@ -584,8 +603,17 @@ void RenderFrameDevToolsAgentHost::UpdateFrameHost(
frame_host_ = frame_host;
agent_ptr_.reset();
- if (!IsFrameHostAllowedForRestrictedSessions())
- ForceDetachRestrictedSessions();
+ std::vector<DevToolsSession*> restricted_sessions;
+ const bool is_webui =
+ frame_host && (frame_host->web_ui() || frame_host->pending_web_ui());
+
+ for (DevToolsSession* session : sessions()) {
+ if (!session->client()->MayAttachToRenderer(frame_host, is_webui))
+ restricted_sessions.push_back(session);
+ }
+
+ if (!restricted_sessions.empty())
+ ForceDetachRestrictedSessions(restricted_sessions);
if (!render_frame_alive_) {
render_frame_alive_ = true;
@@ -729,6 +757,7 @@ void RenderFrameDevToolsAgentHost::RenderProcessGone(
case base::TERMINATION_STATUS_LAUNCH_FAILED:
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
inspector->TargetCrashed();
+ NotifyCrashed(status);
break;
default:
for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
@@ -952,9 +981,4 @@ bool RenderFrameDevToolsAgentHost::IsChildFrame() {
return frame_tree_node_ && frame_tree_node_->parent();
}
-bool RenderFrameDevToolsAgentHost::IsFrameHostAllowedForRestrictedSessions() {
- return !frame_host_ ||
- (!frame_host_->web_ui() && !frame_host_->pending_web_ui());
-}
-
} // namespace content
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 d4c77584e64..b4184bb250d 100644
--- a/chromium/content/browser/devtools/render_frame_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -42,6 +42,7 @@ class CompositorFrameMetadata;
namespace net {
class SSLInfo;
+class X509Certificate;
}
namespace content {
@@ -53,7 +54,8 @@ class NavigationHandleImpl;
class NavigationRequest;
class NavigationThrottle;
class RenderFrameHostImpl;
-class SignedExchangeHeader;
+class SignedExchangeEnvelope;
+struct SignedExchangeError;
class CONTENT_EXPORT RenderFrameDevToolsAgentHost
: public DevToolsAgentHostImpl,
@@ -101,9 +103,10 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
base::Optional<const base::UnguessableToken> devtools_navigation_token,
const GURL& outer_request_url,
const network::ResourceResponseHead& outer_response,
- const base::Optional<SignedExchangeHeader>& header,
+ const base::Optional<SignedExchangeEnvelope>& header,
+ const scoped_refptr<net::X509Certificate>& certificate,
const base::Optional<net::SSLInfo>& ssl_info,
- const std::vector<std::string>& error_messages);
+ const std::vector<SignedExchangeError>& errors);
static void OnSignedExchangeCertificateRequestSent(
FrameTreeNode* frame_tree_node,
const base::UnguessableToken& request_id,
@@ -158,11 +161,10 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
~RenderFrameDevToolsAgentHost() override;
// DevToolsAgentHostImpl overrides.
- bool AttachSession(DevToolsSession* session) override;
+ bool AttachSession(DevToolsSession* session,
+ TargetRegistry* registry) override;
void DetachSession(DevToolsSession* session) override;
void InspectElement(RenderFrameHost* frame_host, int x, int y) override;
- void DispatchProtocolMessage(DevToolsSession* session,
- const std::string& message) override;
// WebContentsObserver overrides.
void DidStartNavigation(NavigationHandle* navigation_handle) override;
@@ -180,7 +182,6 @@ class CONTENT_EXPORT RenderFrameDevToolsAgentHost
void OnPageScaleFactorChanged(float page_scale_factor) override;
bool IsChildFrame();
- bool IsFrameHostAllowedForRestrictedSessions();
void OnSwapCompositorFrame(const IPC::Message& message);
void DestroyOnRenderFrameGone();
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 64801cf7cda..32f191e75cc 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/service_worker_devtools_agent_host.cc
@@ -115,7 +115,8 @@ ServiceWorkerDevToolsAgentHost::~ServiceWorkerDevToolsAgentHost() {
ServiceWorkerDevToolsManager::GetInstance()->AgentHostDestroyed(this);
}
-bool ServiceWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session) {
+bool ServiceWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session,
+ TargetRegistry* registry) {
if (state_ == WORKER_READY) {
if (sessions().size() == 1) {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
@@ -126,8 +127,8 @@ bool ServiceWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session) {
session->AttachToAgent(agent_ptr_);
}
session->AddHandler(base::WrapUnique(new protocol::InspectorHandler()));
- session->AddHandler(
- base::WrapUnique(new protocol::NetworkHandler(GetId(), GetIOContext())));
+ session->AddHandler(base::WrapUnique(new protocol::NetworkHandler(
+ GetId(), devtools_worker_token_, GetIOContext())));
session->AddHandler(base::WrapUnique(new protocol::SchemaHandler()));
return true;
}
@@ -141,12 +142,6 @@ void ServiceWorkerDevToolsAgentHost::DetachSession(DevToolsSession* session) {
}
}
-void ServiceWorkerDevToolsAgentHost::DispatchProtocolMessage(
- DevToolsSession* session,
- const std::string& message) {
- session->DispatchProtocolMessage(message);
-}
-
void ServiceWorkerDevToolsAgentHost::WorkerReadyForInspection(
blink::mojom::DevToolsAgentAssociatedPtrInfo devtools_agent_ptr_info) {
DCHECK_EQ(WORKER_NOT_READY, state_);
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 453f52c6da9..b2612093058 100644
--- a/chromium/content/browser/devtools/service_worker_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/service_worker_devtools_agent_host.h
@@ -47,10 +47,9 @@ class ServiceWorkerDevToolsAgentHost : public DevToolsAgentHostImpl {
bool Close() override;
// DevToolsAgentHostImpl overrides.
- bool AttachSession(DevToolsSession* session) override;
+ bool AttachSession(DevToolsSession* session,
+ TargetRegistry* registry) override;
void DetachSession(DevToolsSession* session) override;
- void DispatchProtocolMessage(DevToolsSession* session,
- const std::string& message) override;
void WorkerRestarted(int worker_process_id, int worker_route_id);
void WorkerReadyForInspection(
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 fd40420eed3..c09e04a0717 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_agent_host.cc
+++ b/chromium/content/browser/devtools/shared_worker_devtools_agent_host.cc
@@ -66,10 +66,11 @@ bool SharedWorkerDevToolsAgentHost::Close() {
return true;
}
-bool SharedWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session) {
+bool SharedWorkerDevToolsAgentHost::AttachSession(DevToolsSession* session,
+ TargetRegistry* registry) {
session->AddHandler(std::make_unique<protocol::InspectorHandler>());
- session->AddHandler(
- std::make_unique<protocol::NetworkHandler>(GetId(), GetIOContext()));
+ session->AddHandler(std::make_unique<protocol::NetworkHandler>(
+ GetId(), devtools_worker_token_, GetIOContext()));
session->AddHandler(std::make_unique<protocol::SchemaHandler>());
session->SetRenderer(worker_host_ ? worker_host_->process_id() : -1, nullptr);
if (state_ == WORKER_READY)
@@ -81,12 +82,6 @@ void SharedWorkerDevToolsAgentHost::DetachSession(DevToolsSession* session) {
// Destroying session automatically detaches in renderer.
}
-void SharedWorkerDevToolsAgentHost::DispatchProtocolMessage(
- DevToolsSession* session,
- const std::string& message) {
- session->DispatchProtocolMessage(message);
-}
-
bool SharedWorkerDevToolsAgentHost::Matches(SharedWorkerHost* worker_host) {
return instance_->Matches(*worker_host->instance());
}
diff --git a/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h b/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h
index 6a1d800795b..c0a867de030 100644
--- a/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h
+++ b/chromium/content/browser/devtools/shared_worker_devtools_agent_host.h
@@ -33,10 +33,9 @@ class SharedWorkerDevToolsAgentHost : public DevToolsAgentHostImpl {
bool Close() override;
// DevToolsAgentHostImpl overrides.
- bool AttachSession(DevToolsSession* session) override;
+ bool AttachSession(DevToolsSession* session,
+ TargetRegistry* registry) override;
void DetachSession(DevToolsSession* session) override;
- void DispatchProtocolMessage(DevToolsSession* session,
- const std::string& message) override;
bool Matches(SharedWorkerHost* worker_host);
void WorkerReadyForInspection();
diff --git a/chromium/content/browser/devtools/target_registry.cc b/chromium/content/browser/devtools/target_registry.cc
new file mode 100644
index 00000000000..07d168aa79b
--- /dev/null
+++ b/chromium/content/browser/devtools/target_registry.cc
@@ -0,0 +1,56 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/devtools/target_registry.h"
+
+#include "base/strings/stringprintf.h"
+#include "content/browser/devtools/devtools_session.h"
+
+namespace content {
+
+TargetRegistry::TargetRegistry(DevToolsSession* root_session)
+ : root_session_(root_session) {}
+
+TargetRegistry::~TargetRegistry() {}
+
+void TargetRegistry::AttachSubtargetSession(const std::string& session_id,
+ DevToolsAgentHostImpl* agent_host,
+ DevToolsAgentHostClient* client) {
+ sessions_[session_id] = std::make_pair(agent_host, client);
+ agent_host->AttachSubtargetClient(client, this);
+}
+void TargetRegistry::DetachSubtargetSession(const std::string& session_id) {
+ sessions_.erase(session_id);
+}
+
+bool TargetRegistry::DispatchMessageOnAgentHost(
+ const std::string& message,
+ base::DictionaryValue* parsed_message) {
+ std::string session_id;
+ if (!parsed_message->GetString("sessionId", &session_id))
+ return false;
+ auto it = sessions_.find(session_id);
+ if (it == sessions_.end()) {
+ LOG(ERROR) << "Unknown session " << session_id;
+ return true;
+ }
+ scoped_refptr<DevToolsAgentHostImpl> agent_host = it->second.first;
+ DevToolsAgentHostClient* client = it->second.second;
+ return agent_host->DispatchProtocolMessage(client, message, parsed_message);
+}
+
+void TargetRegistry::SendMessageToClient(const std::string& session_id,
+ const std::string& message) {
+ DCHECK(message[message.length() - 1] == '}');
+ std::string suffix =
+ base::StringPrintf(", \"sessionId\": \"%s\"}", session_id.c_str());
+ std::string patched;
+ patched.reserve(message.length() + suffix.length() - 1);
+ patched.append(message.data(), message.length() - 1);
+ patched.append(suffix);
+ root_session_->client()->DispatchProtocolMessage(root_session_->agent_host(),
+ patched);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/devtools/target_registry.h b/chromium/content/browser/devtools/target_registry.h
new file mode 100644
index 00000000000..d915e1f1368
--- /dev/null
+++ b/chromium/content/browser/devtools/target_registry.h
@@ -0,0 +1,44 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DEVTOOLS_TARGET_REGISTRY_H_
+#define CONTENT_BROWSER_DEVTOOLS_TARGET_REGISTRY_H_
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/containers/flat_map.h"
+#include "base/values.h"
+#include "content/browser/devtools/devtools_agent_host_impl.h"
+
+namespace content {
+
+class DevToolsSession;
+
+class TargetRegistry {
+ public:
+ explicit TargetRegistry(DevToolsSession* root_session);
+ ~TargetRegistry();
+
+ void AttachSubtargetSession(const std::string& session_id,
+ DevToolsAgentHostImpl* agent_host,
+ DevToolsAgentHostClient* client);
+ void DetachSubtargetSession(const std::string& session_id);
+ bool DispatchMessageOnAgentHost(const std::string& message,
+ base::DictionaryValue* parsed_message);
+ void SendMessageToClient(const std::string& session_id,
+ const std::string& message);
+
+ private:
+ DevToolsSession* root_session_;
+ base::flat_map<
+ std::string,
+ std::pair<scoped_refptr<DevToolsAgentHostImpl>, DevToolsAgentHostClient*>>
+ sessions_;
+ DISALLOW_COPY_AND_ASSIGN(TargetRegistry);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DEVTOOLS_TARGET_REGISTRY_H_
diff --git a/chromium/content/browser/display_cutout/OWNERS b/chromium/content/browser/display_cutout/OWNERS
new file mode 100644
index 00000000000..3b7954a88fd
--- /dev/null
+++ b/chromium/content/browser/display_cutout/OWNERS
@@ -0,0 +1,3 @@
+file://chrome/android/java/src/org/chromium/chrome/browser/display_cutout/OWNERS
+
+# COMPONENT: Blink>Layout
diff --git a/chromium/content/browser/display_cutout/display_cutout_browsertest.cc b/chromium/content/browser/display_cutout/display_cutout_browsertest.cc
new file mode 100644
index 00000000000..f254afeff13
--- /dev/null
+++ b/chromium/content/browser/display_cutout/display_cutout_browsertest.cc
@@ -0,0 +1,468 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/run_loop.h"
+#include "build/build_config.h"
+#include "components/ukm/test_ukm_recorder.h"
+#include "content/browser/display_cutout/display_cutout_constants.h"
+#include "content/browser/frame_host/frame_tree_node.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/web_contents_delegate.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_frame_navigation_observer.h"
+#include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test_utils_internal.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/mojom/page/display_cutout.mojom.h"
+
+namespace content {
+
+namespace {
+
+#if defined(OS_ANDROID)
+
+// These inset and flags simulate when we are not extending into the cutout.
+const gfx::Insets kNoCutoutInsets = gfx::Insets();
+const int kNoCutoutInsetsExpectedFlags = DisplayCutoutSafeArea::kEmpty;
+
+// These inset and flags simulate when the we are extending into the cutout.
+const gfx::Insets kCutoutInsets = gfx::Insets(1, 0, 1, 0);
+const int kCutoutInsetsExpectedFlags =
+ DisplayCutoutSafeArea::kTop | DisplayCutoutSafeArea::kBottom;
+
+// These inset and flags simulate when we are extending into the cutout and have
+// rotated the device so that the cutout is on the other sides.
+const gfx::Insets kRotatedCutoutInsets = gfx::Insets(0, 1, 0, 1);
+const int kRotatedCutoutInsetsExpectedFlags =
+ DisplayCutoutSafeArea::kLeft | DisplayCutoutSafeArea::kRight;
+
+#endif
+
+class TestWebContentsObserver : public WebContentsObserver {
+ public:
+ explicit TestWebContentsObserver(content::WebContents* web_contents)
+ : WebContentsObserver(web_contents) {}
+
+ // WebContentsObserver override.
+ void ViewportFitChanged(blink::mojom::ViewportFit value) override {
+ value_ = value;
+
+ if (value_ == wanted_value_)
+ run_loop_.Quit();
+ }
+
+ bool has_value() const { return value_.has_value(); }
+
+ void WaitForWantedValue(blink::mojom::ViewportFit wanted_value) {
+ if (value_.has_value()) {
+ EXPECT_EQ(wanted_value, value_);
+ return;
+ }
+
+ wanted_value_ = wanted_value;
+ run_loop_.Run();
+ }
+
+ private:
+ base::RunLoop run_loop_;
+ base::Optional<blink::mojom::ViewportFit> value_;
+ blink::mojom::ViewportFit wanted_value_ = blink::mojom::ViewportFit::kAuto;
+
+ DISALLOW_COPY_AND_ASSIGN(TestWebContentsObserver);
+};
+
+// Used for forcing a specific |blink::WebDisplayMode| during a test.
+class DisplayCutoutWebContentsDelegate : public WebContentsDelegate {
+ public:
+ blink::WebDisplayMode GetDisplayMode(
+ const WebContents* web_contents) const override {
+ return display_mode_;
+ }
+
+ void SetDisplayMode(blink::WebDisplayMode display_mode) {
+ display_mode_ = display_mode;
+ }
+
+ private:
+ blink::WebDisplayMode display_mode_ =
+ blink::WebDisplayMode::kWebDisplayModeBrowser;
+};
+
+const char kTestHTML[] =
+ "<!DOCTYPE html>"
+ "<style>"
+ " #target {"
+ " margin-top: env(safe-area-inset-top);"
+ " margin-left: env(safe-area-inset-left);"
+ " margin-bottom: env(safe-area-inset-bottom);"
+ " margin-right: env(safe-area-inset-right);"
+ " }"
+ "</style>"
+ "<div id=target></div>";
+
+} // namespace
+
+class DisplayCutoutBrowserTest : public ContentBrowserTest {
+ public:
+ DisplayCutoutBrowserTest() = default;
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitchASCII("enable-blink-features",
+ "DisplayCutoutAPI");
+ }
+
+ void LoadTestPageWithViewportFitFromMeta(const std::string& value) {
+ LoadTestPageWithData(
+ "<!DOCTYPE html>"
+ "<meta name='viewport' content='viewport-fit=" +
+ value + "'><iframe></iframe>");
+ }
+
+ void LoadSubFrameWithViewportFitMetaValue(const std::string& value) {
+ const std::string data =
+ "data:text/html;charset=utf-8,<!DOCTYPE html>"
+ "<meta name='viewport' content='viewport-fit=" +
+ value + "'>";
+
+ FrameTreeNode* root = web_contents_impl()->GetFrameTree()->root();
+ FrameTreeNode* child = root->child_at(0);
+
+ TestFrameNavigationObserver observer(child);
+ NavigationController::LoadURLParams params(GURL::EmptyGURL());
+ params.url = GURL(data);
+ params.frame_tree_node_id = child->frame_tree_node_id();
+ params.load_type = NavigationController::LOAD_TYPE_DATA;
+ web_contents_impl()->GetController().LoadURLWithParams(params);
+ web_contents_impl()->Focus();
+ observer.Wait();
+ }
+
+ bool ClearViewportFitTag() {
+ return ExecuteScript(
+ web_contents_impl(),
+ "document.getElementsByTagName('meta')[0].content = ''");
+ }
+
+ void SendSafeAreaToFrame(int top, int left, int bottom, int right) {
+ blink::mojom::DisplayCutoutClientAssociatedPtr client;
+ MainFrame()->GetRemoteAssociatedInterfaces()->GetInterface(&client);
+ client->SetSafeArea(
+ blink::mojom::DisplayCutoutSafeArea::New(top, left, bottom, right));
+ }
+
+ std::string GetCurrentSafeAreaValue(const std::string& name) {
+ std::string value;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ MainFrame(),
+ "(() => {"
+ "const e = document.getElementById('target');"
+ "const style = window.getComputedStyle(e, null);"
+ "window.domAutomationController.send("
+ " style.getPropertyValue('margin-" +
+ name +
+ "'));"
+ "})();",
+ &value));
+ return value;
+ }
+
+ void LoadTestPageWithData(const std::string& data) {
+ GURL url("https://www.example.com");
+ ResetUKM();
+
+ TestNavigationObserver same_tab_observer(shell()->web_contents(), 1);
+#if defined(OS_ANDROID)
+ shell()->LoadDataAsStringWithBaseURL(url, data, url);
+#else
+ shell()->LoadDataWithBaseURL(url, data, url);
+#endif
+ same_tab_observer.Wait();
+ }
+
+ void SimulateFullscreenStateChanged(RenderFrameHost* frame,
+ bool is_fullscreen) {
+ web_contents_impl()->FullscreenStateChanged(frame, is_fullscreen);
+ }
+
+ void SimulateFullscreenExit() {
+ web_contents_impl()->ExitFullscreenMode(true);
+ }
+
+ RenderFrameHost* MainFrame() { return web_contents_impl()->GetMainFrame(); }
+
+ RenderFrameHost* ChildFrame() {
+ FrameTreeNode* root = web_contents_impl()->GetFrameTree()->root();
+ return root->child_at(0)->current_frame_host();
+ }
+
+ WebContentsImpl* web_contents_impl() {
+ return static_cast<WebContentsImpl*>(shell()->web_contents());
+ }
+
+ unsigned GetUKMEntryCount() const {
+ using Entry = ukm::builders::Layout_DisplayCutout_StateChanged;
+ auto ukm_entries = test_ukm_recorder_->GetEntriesByName(Entry::kEntryName);
+ return ukm_entries.size();
+ }
+
+ void ExpectUKMEntry(int index,
+ ukm::SourceId source_id,
+ bool is_main_frame,
+ blink::mojom::ViewportFit applied_value,
+ blink::mojom::ViewportFit supplied_value,
+ int ignored_reason,
+ int safe_areas_present) {
+ using Entry = ukm::builders::Layout_DisplayCutout_StateChanged;
+ auto ukm_entries = test_ukm_recorder_->GetEntriesByName(Entry::kEntryName);
+
+ EXPECT_EQ(source_id, ukm_entries[index]->source_id);
+ EXPECT_EQ(is_main_frame, *test_ukm_recorder_->GetEntryMetric(
+ ukm_entries[index], Entry::kIsMainFrameName));
+ EXPECT_EQ(static_cast<int>(applied_value),
+ *test_ukm_recorder_->GetEntryMetric(
+ ukm_entries[index], Entry::kViewportFit_AppliedName));
+ EXPECT_EQ(static_cast<int>(supplied_value),
+ *test_ukm_recorder_->GetEntryMetric(
+ ukm_entries[index], Entry::kViewportFit_SuppliedName));
+ EXPECT_EQ(ignored_reason,
+ *test_ukm_recorder_->GetEntryMetric(
+ ukm_entries[index], Entry::kViewportFit_IgnoredReasonName));
+ EXPECT_EQ(safe_areas_present,
+ *test_ukm_recorder_->GetEntryMetric(
+ ukm_entries[index], Entry::kSafeAreasPresentName));
+ }
+
+ private:
+ void ResetUKM() {
+ test_ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
+ }
+
+ std::unique_ptr<ukm::TestUkmRecorder> test_ukm_recorder_;
+
+ DISALLOW_COPY_AND_ASSIGN(DisplayCutoutBrowserTest);
+};
+
+// The viewport meta tag is only enabled on Android.
+#if defined(OS_ANDROID)
+
+IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, ViewportFit_Fullscreen) {
+ LoadTestPageWithViewportFitFromMeta("cover");
+ LoadSubFrameWithViewportFitMetaValue("contain");
+
+ {
+ TestWebContentsObserver observer(web_contents_impl());
+ SimulateFullscreenStateChanged(MainFrame(), true);
+ observer.WaitForWantedValue(blink::mojom::ViewportFit::kCover);
+ web_contents_impl()->SetDisplayCutoutSafeArea(kCutoutInsets);
+ }
+
+ {
+ TestWebContentsObserver observer(web_contents_impl());
+ SimulateFullscreenStateChanged(ChildFrame(), true);
+ observer.WaitForWantedValue(blink::mojom::ViewportFit::kContain);
+ web_contents_impl()->SetDisplayCutoutSafeArea(kNoCutoutInsets);
+ }
+
+ {
+ TestWebContentsObserver observer(web_contents_impl());
+ SimulateFullscreenStateChanged(ChildFrame(), false);
+ observer.WaitForWantedValue(blink::mojom::ViewportFit::kCover);
+
+ // This simulates the user rotating the device.
+ web_contents_impl()->SetDisplayCutoutSafeArea(kCutoutInsets);
+ web_contents_impl()->SetDisplayCutoutSafeArea(kRotatedCutoutInsets);
+ }
+
+ {
+ TestWebContentsObserver observer(web_contents_impl());
+ SimulateFullscreenStateChanged(MainFrame(), false);
+ SimulateFullscreenExit();
+ observer.WaitForWantedValue(blink::mojom::ViewportFit::kAuto);
+ web_contents_impl()->SetDisplayCutoutSafeArea(kNoCutoutInsets);
+ }
+
+ // Get the source id for the page and close the |shell|. This will flush any
+ // unrecorded UKM metrics.
+ ukm::SourceId source_id =
+ web_contents_impl()->GetUkmSourceIdForLastCommittedSource();
+ shell()->Close();
+
+ // Check UKM metrics are recorded. The first two entries are from loading the
+ // frame and the subframe with a viewport fit attribute.
+ EXPECT_EQ(5u, GetUKMEntryCount());
+ ExpectUKMEntry(0, source_id, true, blink::mojom::ViewportFit::kAuto,
+ blink::mojom::ViewportFit::kCover,
+ DisplayCutoutIgnoredReason::kWebContentsNotFullscreen,
+ kNoCutoutInsetsExpectedFlags);
+ ExpectUKMEntry(1, source_id, false, blink::mojom::ViewportFit::kAuto,
+ blink::mojom::ViewportFit::kContain,
+ DisplayCutoutIgnoredReason::kWebContentsNotFullscreen,
+ kNoCutoutInsetsExpectedFlags);
+
+ // This is when we take the main frame fullscreen.
+ ExpectUKMEntry(2, source_id, true, blink::mojom::ViewportFit::kCover,
+ blink::mojom::ViewportFit::kCover,
+ DisplayCutoutIgnoredReason::kAllowed,
+ kCutoutInsetsExpectedFlags);
+
+ // This is when we take the subframe fullscreen.
+ ExpectUKMEntry(3, source_id, false, blink::mojom::ViewportFit::kContain,
+ blink::mojom::ViewportFit::kContain,
+ DisplayCutoutIgnoredReason::kAllowed,
+ kNoCutoutInsetsExpectedFlags);
+
+ // These is when the subframe exits fullscreen.
+ ExpectUKMEntry(4, source_id, true, blink::mojom::ViewportFit::kCover,
+ blink::mojom::ViewportFit::kCover,
+ DisplayCutoutIgnoredReason::kAllowed,
+ kRotatedCutoutInsetsExpectedFlags);
+}
+
+IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest,
+ ViewportFit_Fullscreen_Update) {
+ LoadTestPageWithViewportFitFromMeta("cover");
+
+ {
+ TestWebContentsObserver observer(web_contents_impl());
+ SimulateFullscreenStateChanged(MainFrame(), true);
+ observer.WaitForWantedValue(blink::mojom::ViewportFit::kCover);
+ web_contents_impl()->SetDisplayCutoutSafeArea(kNoCutoutInsets);
+ }
+
+ {
+ TestWebContentsObserver observer(web_contents_impl());
+ EXPECT_TRUE(ClearViewportFitTag());
+ observer.WaitForWantedValue(blink::mojom::ViewportFit::kAuto);
+ web_contents_impl()->SetDisplayCutoutSafeArea(kNoCutoutInsets);
+ }
+
+ // Get the source id for the page and close the |shell|. This will flush any
+ // unrecorded UKM metrics.
+ ukm::SourceId source_id =
+ web_contents_impl()->GetUkmSourceIdForLastCommittedSource();
+ shell()->Close();
+
+ // Check UKM metrics are recorded.
+ EXPECT_EQ(2u, GetUKMEntryCount());
+ ExpectUKMEntry(0, source_id, true, blink::mojom::ViewportFit::kAuto,
+ blink::mojom::ViewportFit::kCover,
+ DisplayCutoutIgnoredReason::kWebContentsNotFullscreen,
+ kNoCutoutInsetsExpectedFlags);
+ ExpectUKMEntry(1, source_id, true, blink::mojom::ViewportFit::kCover,
+ blink::mojom::ViewportFit::kCover,
+ DisplayCutoutIgnoredReason::kAllowed,
+ kNoCutoutInsetsExpectedFlags);
+}
+
+IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, ViewportFit_Noop_Navigate) {
+ {
+ TestWebContentsObserver observer(web_contents_impl());
+ LoadTestPageWithViewportFitFromMeta("cover");
+ EXPECT_FALSE(observer.has_value());
+ }
+
+ ukm::SourceId source_id =
+ web_contents_impl()->GetUkmSourceIdForLastCommittedSource();
+ LoadTestPageWithData("");
+
+ // Check UKM metrics are recorded.
+ EXPECT_EQ(1u, GetUKMEntryCount());
+ ExpectUKMEntry(0, source_id, true, blink::mojom::ViewportFit::kAuto,
+ blink::mojom::ViewportFit::kCover,
+ DisplayCutoutIgnoredReason::kWebContentsNotFullscreen,
+ kNoCutoutInsetsExpectedFlags);
+}
+
+IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest,
+ ViewportFit_Noop_WebContentsDestroyed) {
+ {
+ TestWebContentsObserver observer(web_contents_impl());
+ LoadTestPageWithViewportFitFromMeta("cover");
+ EXPECT_FALSE(observer.has_value());
+ }
+
+ ukm::SourceId source_id =
+ web_contents_impl()->GetUkmSourceIdForLastCommittedSource();
+ shell()->Close();
+
+ // Check UKM metrics are recorded.
+ EXPECT_EQ(1u, GetUKMEntryCount());
+ ExpectUKMEntry(0, source_id, true, blink::mojom::ViewportFit::kAuto,
+ blink::mojom::ViewportFit::kCover,
+ DisplayCutoutIgnoredReason::kWebContentsNotFullscreen,
+ kNoCutoutInsetsExpectedFlags);
+}
+
+IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, WebDisplayMode) {
+ // Inject the custom delegate used for this test.
+ std::unique_ptr<DisplayCutoutWebContentsDelegate> delegate(
+ new DisplayCutoutWebContentsDelegate());
+ web_contents_impl()->SetDelegate(delegate.get());
+ EXPECT_EQ(delegate.get(), web_contents_impl()->GetDelegate());
+
+ {
+ TestWebContentsObserver observer(web_contents_impl());
+ LoadTestPageWithViewportFitFromMeta("cover");
+ EXPECT_FALSE(observer.has_value());
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, WebDisplayMode_Fullscreen) {
+ // Inject the custom delegate used for this test.
+ std::unique_ptr<DisplayCutoutWebContentsDelegate> delegate(
+ new DisplayCutoutWebContentsDelegate());
+ delegate->SetDisplayMode(blink::WebDisplayMode::kWebDisplayModeFullscreen);
+ web_contents_impl()->SetDelegate(delegate.get());
+ EXPECT_EQ(delegate.get(), web_contents_impl()->GetDelegate());
+
+ {
+ TestWebContentsObserver observer(web_contents_impl());
+ LoadTestPageWithViewportFitFromMeta("cover");
+ observer.WaitForWantedValue(blink::mojom::ViewportFit::kCover);
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, WebDisplayMode_Standalone) {
+ // Inject the custom delegate used for this test.
+ std::unique_ptr<DisplayCutoutWebContentsDelegate> delegate(
+ new DisplayCutoutWebContentsDelegate());
+ delegate->SetDisplayMode(blink::WebDisplayMode::kWebDisplayModeStandalone);
+ web_contents_impl()->SetDelegate(delegate.get());
+ EXPECT_EQ(delegate.get(), web_contents_impl()->GetDelegate());
+
+ {
+ TestWebContentsObserver observer(web_contents_impl());
+ LoadTestPageWithViewportFitFromMeta("cover");
+ EXPECT_FALSE(observer.has_value());
+ }
+}
+
+#endif
+
+IN_PROC_BROWSER_TEST_F(DisplayCutoutBrowserTest, PublishSafeAreaVariables) {
+ LoadTestPageWithData(kTestHTML);
+
+ // Make sure all the safe areas are currently zero.
+ EXPECT_EQ("0px", GetCurrentSafeAreaValue("top"));
+ EXPECT_EQ("0px", GetCurrentSafeAreaValue("left"));
+ EXPECT_EQ("0px", GetCurrentSafeAreaValue("bottom"));
+ EXPECT_EQ("0px", GetCurrentSafeAreaValue("right"));
+
+ SendSafeAreaToFrame(1, 2, 3, 4);
+
+ // Make sure all the safe ares are correctly set.
+ EXPECT_EQ("1px", GetCurrentSafeAreaValue("top"));
+ EXPECT_EQ("2px", GetCurrentSafeAreaValue("left"));
+ EXPECT_EQ("3px", GetCurrentSafeAreaValue("bottom"));
+ EXPECT_EQ("4px", GetCurrentSafeAreaValue("right"));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/display_cutout/display_cutout_constants.h b/chromium/content/browser/display_cutout/display_cutout_constants.h
new file mode 100644
index 00000000000..fe070209868
--- /dev/null
+++ b/chromium/content/browser/display_cutout/display_cutout_constants.h
@@ -0,0 +1,37 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DISPLAY_CUTOUT_DISPLAY_CUTOUT_CONSTANTS_H_
+#define CONTENT_BROWSER_DISPLAY_CUTOUT_DISPLAY_CUTOUT_CONSTANTS_H_
+
+namespace content {
+
+// Contains the reasons why a |RenderFrameHost| does not have control over a
+// the Display Cutout. This enum is used in metrics so the order should not
+// be changed.
+enum DisplayCutoutIgnoredReason {
+ // The frame was not ignored.
+ kAllowed = 0,
+
+ // The frame was ignored because it was not the current active fullscreen
+ // frame.
+ kFrameNotCurrentFullscreen,
+
+ // The frame was ignored because the WebContents was not fullscreen.
+ kWebContentsNotFullscreen,
+};
+
+// Contains flags as to which safe areas are present and greater than zero. This
+// enum is used in metrics so the order should not be changed.
+enum DisplayCutoutSafeArea {
+ kEmpty = 0,
+ kTop = 1 << 0,
+ kLeft = 1 << 1,
+ kBottom = 1 << 2,
+ kRight = 1 << 3,
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DISPLAY_CUTOUT_DISPLAY_CUTOUT_CONSTANTS_H_
diff --git a/chromium/content/browser/display_cutout/display_cutout_host_impl.cc b/chromium/content/browser/display_cutout/display_cutout_host_impl.cc
new file mode 100644
index 00000000000..4785df22f40
--- /dev/null
+++ b/chromium/content/browser/display_cutout/display_cutout_host_impl.cc
@@ -0,0 +1,230 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/display_cutout/display_cutout_host_impl.h"
+
+#include "content/browser/display_cutout/display_cutout_constants.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/navigation_handle.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+
+namespace content {
+
+DisplayCutoutHostImpl::DisplayCutoutHostImpl(
+ WebContentsImpl* web_contents,
+ ViewportFitChangedCallback callback)
+ : WebContentsObserver(web_contents),
+ viewport_fit_changed_callback_(callback),
+ bindings_(web_contents, this) {}
+
+DisplayCutoutHostImpl::~DisplayCutoutHostImpl() = default;
+
+void DisplayCutoutHostImpl::NotifyViewportFitChanged(
+ blink::mojom::ViewportFit value) {
+ ViewportFitChangedForFrame(bindings_.GetCurrentTargetFrame(), value);
+}
+
+void DisplayCutoutHostImpl::ViewportFitChangedForFrame(
+ RenderFrameHost* rfh,
+ blink::mojom::ViewportFit value) {
+ if (GetValueOrDefault(rfh) == value)
+ return;
+
+ values_[rfh] = value;
+
+ // If we are the current |RenderFrameHost| frame then notify
+ // WebContentsObservers about the new value.
+ if (current_rfh_ == rfh)
+ viewport_fit_changed_callback_.Run(value);
+
+ MaybeQueueUKMEvent(rfh);
+}
+
+void DisplayCutoutHostImpl::DidAcquireFullscreen(RenderFrameHost* rfh) {
+ SetCurrentRenderFrameHost(rfh);
+}
+
+void DisplayCutoutHostImpl::DidToggleFullscreenModeForTab(
+ bool entered_fullscreen,
+ bool will_cause_resize) {
+ if (!entered_fullscreen)
+ SetCurrentRenderFrameHost(nullptr);
+}
+
+void DisplayCutoutHostImpl::DidStartNavigation(
+ NavigationHandle* navigation_handle) {
+ // If the navigation is not in the main frame or if we are a same document
+ // navigation then we should stop now.
+ if (!navigation_handle->IsInMainFrame() ||
+ navigation_handle->IsSameDocument()) {
+ return;
+ }
+
+ RecordPendingUKMEvents();
+}
+
+void DisplayCutoutHostImpl::DidFinishNavigation(
+ NavigationHandle* navigation_handle) {
+ // If the navigation is not in the main frame or if we are a same document
+ // navigation then we should stop now.
+ if (!navigation_handle->IsInMainFrame() ||
+ navigation_handle->IsSameDocument()) {
+ return;
+ }
+
+ // If we finish a main frame navigation and the |WebDisplayMode| is
+ // fullscreen then we should make the main frame the current
+ // |RenderFrameHost|.
+ RenderWidgetHostImpl* rwh =
+ web_contents_impl()->GetRenderViewHost()->GetWidget();
+ blink::WebDisplayMode mode = web_contents_impl()->GetDisplayMode(rwh);
+ if (mode == blink::WebDisplayMode::kWebDisplayModeFullscreen) {
+ SetCurrentRenderFrameHost(web_contents_impl()->GetMainFrame());
+ }
+}
+
+void DisplayCutoutHostImpl::RenderFrameDeleted(RenderFrameHost* rfh) {
+ values_.erase(rfh);
+
+ // If we were the current |RenderFrameHost| then we should clear that.
+ if (current_rfh_ == rfh)
+ SetCurrentRenderFrameHost(nullptr);
+}
+
+void DisplayCutoutHostImpl::RenderFrameCreated(RenderFrameHost* rfh) {
+ ViewportFitChangedForFrame(rfh, blink::mojom::ViewportFit::kAuto);
+}
+
+void DisplayCutoutHostImpl::WebContentsDestroyed() {
+ // Record any pending UKM events that we are waiting to record.
+ RecordPendingUKMEvents();
+}
+
+void DisplayCutoutHostImpl::SetDisplayCutoutSafeArea(gfx::Insets insets) {
+ insets_ = insets;
+
+ if (current_rfh_)
+ SendSafeAreaToFrame(current_rfh_, insets);
+
+ // If we have a pending UKM event on the top of the stack that is |kAllowed|
+ // and we have a |current_rfh_| then we should update that UKM event as it
+ // was recorded before we received the safe area.
+ if (!pending_ukm_events_.empty() && current_rfh_) {
+ PendingUKMEvent& last_entry = pending_ukm_events_.back();
+ if (last_entry.ignored_reason == DisplayCutoutIgnoredReason::kAllowed)
+ last_entry.safe_areas_present = GetSafeAreasPresentUKMValue();
+ }
+}
+
+void DisplayCutoutHostImpl::SetCurrentRenderFrameHost(RenderFrameHost* rfh) {
+ if (current_rfh_ == rfh)
+ return;
+
+ // If we had a previous frame then we should clear the insets on that frame.
+ if (current_rfh_)
+ SendSafeAreaToFrame(current_rfh_, gfx::Insets());
+
+ // Update the |current_rfh_| with the new frame.
+ current_rfh_ = rfh;
+
+ // If the new RenderFrameHost is nullptr we should stop here and notify
+ // observers that the new viewport fit is kAuto (the default).
+ if (!rfh) {
+ viewport_fit_changed_callback_.Run(blink::mojom::ViewportFit::kAuto);
+ return;
+ }
+
+ // Record a UKM event for the new frame.
+ MaybeQueueUKMEvent(current_rfh_);
+
+ // Send the current safe area to the new frame.
+ SendSafeAreaToFrame(rfh, insets_);
+
+ // Notify the WebContentsObservers that the viewport fit value has changed.
+ viewport_fit_changed_callback_.Run(GetValueOrDefault(rfh));
+}
+
+void DisplayCutoutHostImpl::SendSafeAreaToFrame(RenderFrameHost* rfh,
+ gfx::Insets insets) {
+ blink::AssociatedInterfaceProvider* provider =
+ rfh->GetRemoteAssociatedInterfaces();
+ if (!provider)
+ return;
+
+ blink::mojom::DisplayCutoutClientAssociatedPtr client;
+ provider->GetInterface(&client);
+ client->SetSafeArea(blink::mojom::DisplayCutoutSafeArea::New(
+ insets.top(), insets.left(), insets.bottom(), insets.right()));
+}
+
+blink::mojom::ViewportFit DisplayCutoutHostImpl::GetValueOrDefault(
+ RenderFrameHost* rfh) const {
+ auto value = values_.find(rfh);
+ if (value != values_.end())
+ return value->second;
+ return blink::mojom::ViewportFit::kAuto;
+}
+
+WebContentsImpl* DisplayCutoutHostImpl::web_contents_impl() {
+ return static_cast<WebContentsImpl*>(web_contents());
+}
+
+void DisplayCutoutHostImpl::MaybeQueueUKMEvent(RenderFrameHost* frame) {
+ if (!frame)
+ return;
+
+ // Get the current applied ViewportFit and the ViewportFit value supplied by
+ // |frame|. If the |supplied_value| is kAuto then we will not record the
+ // event since it is the default.
+ blink::mojom::ViewportFit supplied_value = GetValueOrDefault(frame);
+ if (supplied_value == blink::mojom::ViewportFit::kAuto)
+ return;
+ blink::mojom::ViewportFit applied_value = GetValueOrDefault(current_rfh_);
+
+ // Set the reason why this frame is not the current frame.
+ int ignored_reason = DisplayCutoutIgnoredReason::kAllowed;
+ if (current_rfh_ != frame) {
+ ignored_reason =
+ current_rfh_ == nullptr
+ ? DisplayCutoutIgnoredReason::kWebContentsNotFullscreen
+ : DisplayCutoutIgnoredReason::kFrameNotCurrentFullscreen;
+ }
+
+ // Adds the UKM event to the list of pending events.
+ PendingUKMEvent pending_event;
+ pending_event.is_main_frame = !frame->GetParent();
+ pending_event.applied_value = applied_value;
+ pending_event.supplied_value = supplied_value;
+ pending_event.ignored_reason = ignored_reason;
+ if (ignored_reason == DisplayCutoutIgnoredReason::kAllowed)
+ pending_event.safe_areas_present = GetSafeAreasPresentUKMValue();
+ pending_ukm_events_.push_back(pending_event);
+}
+
+void DisplayCutoutHostImpl::RecordPendingUKMEvents() {
+ for (const auto& event : pending_ukm_events_) {
+ ukm::builders::Layout_DisplayCutout_StateChanged builder(
+ web_contents_impl()->GetUkmSourceIdForLastCommittedSource());
+ builder.SetIsMainFrame(event.is_main_frame);
+ builder.SetViewportFit_Applied(static_cast<int>(event.applied_value));
+ builder.SetViewportFit_Supplied(static_cast<int>(event.supplied_value));
+ builder.SetViewportFit_IgnoredReason(event.ignored_reason);
+ builder.SetSafeAreasPresent(event.safe_areas_present);
+ builder.Record(ukm::UkmRecorder::Get());
+ }
+
+ pending_ukm_events_.clear();
+}
+
+int DisplayCutoutHostImpl::GetSafeAreasPresentUKMValue() const {
+ int flags = 0;
+ flags |= insets_.top() ? DisplayCutoutSafeArea::kTop : 0;
+ flags |= insets_.left() ? DisplayCutoutSafeArea::kLeft : 0;
+ flags |= insets_.bottom() ? DisplayCutoutSafeArea::kBottom : 0;
+ flags |= insets_.right() ? DisplayCutoutSafeArea::kRight : 0;
+ return flags;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/display_cutout/display_cutout_host_impl.h b/chromium/content/browser/display_cutout/display_cutout_host_impl.h
new file mode 100644
index 00000000000..eba70e23dac
--- /dev/null
+++ b/chromium/content/browser/display_cutout/display_cutout_host_impl.h
@@ -0,0 +1,100 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DISPLAY_CUTOUT_DISPLAY_CUTOUT_HOST_IMPL_H_
+#define CONTENT_BROWSER_DISPLAY_CUTOUT_DISPLAY_CUTOUT_HOST_IMPL_H_
+
+#include "content/public/browser/web_contents_binding_set.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "third_party/blink/public/mojom/page/display_cutout.mojom.h"
+
+namespace content {
+
+class DisplayCutoutHostImpl : public blink::mojom::DisplayCutoutHost,
+ public WebContentsObserver {
+ public:
+ // Called when the effective viewport fit value has changed.
+ using ViewportFitChangedCallback =
+ base::RepeatingCallback<void(blink::mojom::ViewportFit)>;
+
+ DisplayCutoutHostImpl(WebContentsImpl*, ViewportFitChangedCallback);
+ ~DisplayCutoutHostImpl() override;
+
+ // blink::mojom::DisplayCutoutHost
+ void NotifyViewportFitChanged(blink::mojom::ViewportFit value) override;
+
+ // Stores the updated viewport fit value for a |frame| and notifies observers
+ // if it has changed.
+ void ViewportFitChangedForFrame(RenderFrameHost* rfh,
+ blink::mojom::ViewportFit value);
+
+ // WebContentsObserver override.
+ void DidAcquireFullscreen(RenderFrameHost* rfh) override;
+ void DidToggleFullscreenModeForTab(bool entered_fullscreen,
+ bool will_cause_resize) override;
+ void DidStartNavigation(NavigationHandle* navigation_handle) override;
+ void DidFinishNavigation(NavigationHandle* navigation_handle) override;
+ void RenderFrameDeleted(RenderFrameHost* rfh) override;
+ void RenderFrameCreated(RenderFrameHost* rfh) override;
+ void WebContentsDestroyed() override;
+
+ // Updates the safe area insets on the current frame.
+ void SetDisplayCutoutSafeArea(gfx::Insets insets);
+
+ private:
+ // Stores the data for a pending UKM event.
+ struct PendingUKMEvent {
+ bool is_main_frame;
+ blink::mojom::ViewportFit applied_value;
+ blink::mojom::ViewportFit supplied_value;
+ int ignored_reason;
+ int safe_areas_present = 0;
+ };
+
+ // Set the current |RenderFrameHost| that should have control over the
+ // viewport fit value and we should set safe area insets on.
+ void SetCurrentRenderFrameHost(RenderFrameHost* rfh);
+
+ // Send the safe area insets to a |RenderFrameHost|.
+ void SendSafeAreaToFrame(RenderFrameHost* rfh, gfx::Insets insets);
+
+ // Get the stored viewport fit value for a frame or kAuto if there is no
+ // stored value.
+ blink::mojom::ViewportFit GetValueOrDefault(RenderFrameHost* rfh) const;
+
+ WebContentsImpl* web_contents_impl();
+
+ // Builds and records a Layout.DisplayCutout.StateChanged UKM event for the
+ // provided |frame|. The event will be added to the list of pending events.
+ void MaybeQueueUKMEvent(RenderFrameHost* frame);
+
+ // Records any UKM events that we have not recorded yet.
+ void RecordPendingUKMEvents();
+
+ // Gets the integer value of the current safe areas for recording to UKM.
+ int GetSafeAreasPresentUKMValue() const;
+
+ // Stores pending UKM events.
+ std::list<PendingUKMEvent> pending_ukm_events_;
+
+ // Stores the current safe area insets.
+ gfx::Insets insets_;
+
+ // Stores the current |RenderFrameHost| that has the applied safe area insets
+ // and is controlling the viewport fit value.
+ RenderFrameHost* current_rfh_ = nullptr;
+
+ // Stores a map of RenderFrameHosts and their current viewport fit values.
+ std::map<RenderFrameHost*, blink::mojom::ViewportFit> values_;
+
+ // Stores the callback for when the effective viewport fit value has changed.
+ ViewportFitChangedCallback viewport_fit_changed_callback_;
+
+ // Holds WebContents associated mojo bindings.
+ WebContentsFrameBindingSet<blink::mojom::DisplayCutoutHost> bindings_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DISPLAY_CUTOUT_DISPLAY_CUTOUT_HOST_IMPL_H_
diff --git a/chromium/content/browser/do_not_track_browsertest.cc b/chromium/content/browser/do_not_track_browsertest.cc
index c09c64f7a5b..83c39160e4c 100644
--- a/chromium/content/browser/do_not_track_browsertest.cc
+++ b/chromium/content/browser/do_not_track_browsertest.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/strings/utf_string_conversions.h"
+#include "build/build_config.h"
+#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/test/browser_test_utils.h"
@@ -9,18 +12,52 @@
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.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"
+
+#if defined(OS_ANDROID)
+#include "base/sys_info.h"
+#endif
namespace content {
namespace {
+class MockContentBrowserClient final : public ContentBrowserClient {
+ public:
+ void UpdateRendererPreferencesForWorker(BrowserContext*,
+ RendererPreferences* prefs) override {
+ prefs->enable_do_not_track = true;
+ prefs->enable_referrers = true;
+ }
+};
+
class DoNotTrackTest : public ContentBrowserTest {
protected:
- void EnableDoNotTrack() {
+ void TearDownOnMainThread() override {
+ if (original_client_)
+ SetBrowserClientForTesting(original_client_);
+ }
+
+ // Returns false if we cannot enable do not track. It happens only when
+ // Android Kitkat or older systems.
+ // TODO(crbug.com/864403): It seems that we call unsupported Android APIs on
+ // KitKat when we set a ContentBrowserClient. Don't call such APIs and make
+ // this test available on KitKat.
+ bool EnableDoNotTrack() {
+#if defined(OS_ANDROID)
+ int32_t major_version = 0, minor_version = 0, bugfix_version = 0;
+ base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version,
+ &bugfix_version);
+ if (major_version < 5)
+ return false;
+#endif
+ original_client_ = SetBrowserClientForTesting(&client_);
RendererPreferences* prefs =
shell()->web_contents()->GetMutableRendererPrefs();
EXPECT_FALSE(prefs->enable_do_not_track);
prefs->enable_do_not_track = true;
+ return true;
}
void ExpectPageTextEq(const std::string& expected_content) {
@@ -41,8 +78,26 @@ class DoNotTrackTest : public ContentBrowserTest {
&value));
return value;
}
+
+ private:
+ ContentBrowserClient* original_client_ = nullptr;
+ MockContentBrowserClient client_;
};
+std::unique_ptr<net::test_server::HttpResponse> CaptureHeaderHandler(
+ const std::string& path,
+ net::test_server::HttpRequest::HeaderMap* header_map,
+ base::OnceClosure done_callback,
+ const net::test_server::HttpRequest& request) {
+ GURL request_url = request.GetURL();
+ if (request_url.path() != path)
+ return nullptr;
+
+ *header_map = request.headers;
+ std::move(done_callback).Run();
+ return std::make_unique<net::test_server::BasicHttpResponse>();
+}
+
// Checks that the DNT header is not sent by default.
IN_PROC_BROWSER_TEST_F(DoNotTrackTest, NotEnabled) {
ASSERT_TRUE(embedded_test_server()->Start());
@@ -56,7 +111,8 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest, NotEnabled) {
// Checks that the DNT header is sent when the corresponding preference is set.
IN_PROC_BROWSER_TEST_F(DoNotTrackTest, Simple) {
ASSERT_TRUE(embedded_test_server()->Start());
- EnableDoNotTrack();
+ if (!EnableDoNotTrack())
+ return;
GURL url = embedded_test_server()->GetURL("/echoheader?DNT");
EXPECT_TRUE(NavigateToURL(shell(), url));
ExpectPageTextEq("1");
@@ -68,7 +124,8 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest, Redirect) {
GURL final_url = embedded_test_server()->GetURL("/echoheader?DNT");
GURL url = embedded_test_server()->GetURL(std::string("/server-redirect?") +
final_url.spec());
- EnableDoNotTrack();
+ if (!EnableDoNotTrack())
+ return;
// We don't check the result NavigateToURL as it returns true only if the
// final URL is equal to the passed URL.
NavigateToURL(shell(), url);
@@ -79,11 +136,137 @@ IN_PROC_BROWSER_TEST_F(DoNotTrackTest, Redirect) {
IN_PROC_BROWSER_TEST_F(DoNotTrackTest, DOMProperty) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL url = embedded_test_server()->GetURL("/echo");
- EnableDoNotTrack();
+ if (!EnableDoNotTrack())
+ return;
EXPECT_TRUE(NavigateToURL(shell(), url));
EXPECT_EQ("1", GetDOMDoNotTrackProperty());
}
+// Checks that the DNT header is sent in a request for a dedicated worker
+// script.
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, Worker) {
+ net::test_server::HttpRequest::HeaderMap header_map;
+ base::RunLoop loop;
+ embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
+ &CaptureHeaderHandler, "/capture", &header_map, loop.QuitClosure()));
+ ASSERT_TRUE(embedded_test_server()->Start());
+ if (!EnableDoNotTrack())
+ return;
+ const GURL url = embedded_test_server()->GetURL(
+ std::string("/workers/create_worker.html?worker_url=/capture"));
+ NavigateToURL(shell(), url);
+ loop.Run();
+
+ EXPECT_TRUE(header_map.find("DNT") != header_map.end());
+ EXPECT_EQ("1", header_map["DNT"]);
+}
+
+// Checks that the DNT header is sent in a request for shared worker script.
+// Disabled on Android since a shared worker is not available on Android:
+// crbug.com/869745.
+#if defined(OS_ANDROID)
+#define MAYBE_SharedWorker DISABLED_SharedWorker
+#else
+#define MAYBE_SharedWorker SharedWorker
+#endif
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, MAYBE_SharedWorker) {
+ net::test_server::HttpRequest::HeaderMap header_map;
+ base::RunLoop loop;
+ embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
+ &CaptureHeaderHandler, "/capture", &header_map, loop.QuitClosure()));
+ ASSERT_TRUE(embedded_test_server()->Start());
+ if (!EnableDoNotTrack())
+ return;
+ const GURL url = embedded_test_server()->GetURL(
+ std::string("/workers/create_shared_worker.html?worker_url=/capture"));
+ NavigateToURL(shell(), url);
+ loop.Run();
+
+ EXPECT_TRUE(header_map.find("DNT") != header_map.end());
+ EXPECT_EQ("1", header_map["DNT"]);
+}
+
+// Checks that the DNT header is sent in a request for a service worker
+// script.
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, ServiceWorker) {
+ net::test_server::HttpRequest::HeaderMap header_map;
+ base::RunLoop loop;
+ embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
+ &CaptureHeaderHandler, "/capture", &header_map, loop.QuitClosure()));
+ ASSERT_TRUE(embedded_test_server()->Start());
+ if (!EnableDoNotTrack())
+ return;
+ const GURL url = embedded_test_server()->GetURL(std::string(
+ "/service_worker/create_service_worker.html?worker_url=/capture"));
+ NavigateToURL(shell(), url);
+ loop.Run();
+
+ EXPECT_TRUE(header_map.find("DNT") != header_map.end());
+ EXPECT_EQ("1", header_map["DNT"]);
+}
+
+// Checks that the DNT header is preserved when fetching from a dedicated
+// worker.
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, FetchFromWorker) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ if (!EnableDoNotTrack())
+ return;
+ const GURL fetch_url = embedded_test_server()->GetURL("/echoheader?DNT");
+ const GURL url = embedded_test_server()->GetURL(
+ std::string("/workers/fetch_from_worker.html?url=") + fetch_url.spec());
+ NavigateToURL(shell(), url);
+
+ const base::string16 title = base::ASCIIToUTF16("DONE");
+ TitleWatcher watcher(shell()->web_contents(), title);
+ EXPECT_EQ(title, watcher.WaitAndGetTitle());
+
+ ExpectPageTextEq("1");
+}
+
+// Checks that the DNT header is preserved when fetching from a shared worker.
+//
+// Disabled on Android since a shared worker is not available on Android:
+// crbug.com/869745.
+#if defined(OS_ANDROID)
+#define MAYBE_FetchFromSharedWorker DISABLED_FetchFromSharedWorker
+#else
+#define MAYBE_FetchFromSharedWorker FetchFromSharedWorker
+#endif
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, MAYBE_FetchFromSharedWorker) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ if (!EnableDoNotTrack())
+ return;
+ const GURL fetch_url = embedded_test_server()->GetURL("/echoheader?DNT");
+ const GURL url = embedded_test_server()->GetURL(
+ std::string("/workers/fetch_from_shared_worker.html?url=") +
+ fetch_url.spec());
+ NavigateToURL(shell(), url);
+
+ const base::string16 title = base::ASCIIToUTF16("DONE");
+ TitleWatcher watcher(shell()->web_contents(), title);
+ EXPECT_EQ(title, watcher.WaitAndGetTitle());
+
+ ExpectPageTextEq("1");
+}
+
+// Checks that the DNT header is preserved when fetching from a service worker.
+IN_PROC_BROWSER_TEST_F(DoNotTrackTest, FetchFromServiceWorker) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ if (!EnableDoNotTrack())
+ return;
+ const GURL fetch_url = embedded_test_server()->GetURL("/echoheader?DNT");
+ const GURL url = embedded_test_server()->GetURL(
+ std::string("/service_worker/fetch_from_service_worker.html?url=") +
+ fetch_url.spec());
+ NavigateToURL(shell(), url);
+
+ const base::string16 title = base::ASCIIToUTF16("DONE");
+ TitleWatcher watcher(shell()->web_contents(), title);
+ EXPECT_EQ(title, watcher.WaitAndGetTitle());
+
+ ExpectPageTextEq("1");
+}
+
} // namespace
-} // namespace content \ No newline at end of file
+} // namespace content
diff --git a/chromium/content/browser/dom_storage/dom_storage_area.cc b/chromium/content/browser/dom_storage/dom_storage_area.cc
index 593fa6d693b..590de955c5f 100644
--- a/chromium/content/browser/dom_storage/dom_storage_area.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_area.cc
@@ -24,7 +24,6 @@
#include "content/browser/dom_storage/dom_storage_task_runner.h"
#include "content/browser/dom_storage/session_storage_database.h"
#include "content/browser/dom_storage/session_storage_database_adapter.h"
-#include "content/browser/leveldb_wrapper_impl.h"
#include "content/common/dom_storage/dom_storage_map.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/public/browser/browser_thread.h"
@@ -106,7 +105,6 @@ url::Origin DOMStorageArea::OriginFromDatabaseFileName(
void DOMStorageArea::EnableAggressiveCommitDelay() {
s_aggressive_flushing_enabled_ = true;
- LevelDBWrapperImpl::EnableAggressiveCommitDelay();
}
DOMStorageArea::DOMStorageArea(const std::string& namespace_id,
diff --git a/chromium/content/browser/dom_storage/dom_storage_browsertest.cc b/chromium/content/browser/dom_storage/dom_storage_browsertest.cc
index 61f3ebdb64a..e2e095605e5 100644
--- a/chromium/content/browser/dom_storage/dom_storage_browsertest.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_browsertest.cc
@@ -5,18 +5,25 @@
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
+#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
+#include "components/services/leveldb/public/cpp/util.h"
+#include "components/services/leveldb/public/interfaces/leveldb.mojom.h"
#include "content/browser/dom_storage/dom_storage_area.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/dom_storage_database.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/browser/web_contents/web_contents_impl.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/local_storage_usage_info.h"
#include "content/public/browser/storage_partition.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
@@ -24,10 +31,15 @@
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_launcher.h"
#include "content/shell/browser/shell.h"
+#include "content/shell/browser/shell_browser_context.h"
+#include "content/shell/browser/shell_content_browser_client.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace content {
+constexpr const char kTestSessionStorageId[] =
+ "574d2d70-24ca-4d8c-ae23-c7e1e39d07be";
+
// This browser test is aimed towards exercising the DOMStorage system
// from end-to-end.
class DOMStorageBrowserTest : public ContentBrowserTest {
@@ -74,12 +86,21 @@ class DOMStorageBrowserTest : public ContentBrowserTest {
loop.Run();
}
- LocalStorageContextMojo* context() {
+ DOMStorageContextWrapper* context_wrapper() {
return static_cast<DOMStorageContextWrapper*>(
- BrowserContext::GetDefaultStoragePartition(
- shell()->web_contents()->GetBrowserContext())
- ->GetDOMStorageContext())
- ->mojo_state_;
+ BrowserContext::GetDefaultStoragePartition(
+ shell()->web_contents()->GetBrowserContext())
+ ->GetDOMStorageContext());
+ }
+
+ base::SequencedTaskRunner* mojo_task_runner() {
+ return context_wrapper()->mojo_task_runner();
+ }
+
+ LocalStorageContextMojo* context() { return context_wrapper()->mojo_state_; }
+
+ SessionStorageContextMojo* session_storage_context() {
+ return context_wrapper()->mojo_session_state_;
}
base::FilePath legacy_localstorage_path() {
@@ -88,14 +109,19 @@ class DOMStorageBrowserTest : public ContentBrowserTest {
void EnsureConnected() {
base::RunLoop run_loop;
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(
- &LocalStorageContextMojo::RunWhenConnected,
- base::Unretained(context()),
- base::BindOnce(base::IgnoreResult(&base::TaskRunner::PostTask),
- base::ThreadTaskRunnerHandle::Get(), FROM_HERE,
- run_loop.QuitClosure())));
+ mojo_task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&LocalStorageContextMojo::RunWhenConnected,
+ base::Unretained(context()), run_loop.QuitClosure()));
+ run_loop.Run();
+ }
+
+ void EnsureSessionStorageConnected() {
+ base::RunLoop run_loop;
+ mojo_task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(&SessionStorageContextMojo::RunWhenConnected,
+ base::Unretained(session_storage_context()),
+ run_loop.QuitClosure()));
run_loop.Run();
}
};
@@ -194,4 +220,78 @@ IN_PROC_BROWSER_TEST_F(DOMStorageBrowserTest, DataMigrates) {
}
}
+class DOMStorageMigrationBrowserTest : public DOMStorageBrowserTest {
+ public:
+ DOMStorageMigrationBrowserTest() : DOMStorageBrowserTest() {
+ if (IsPreTest())
+ feature_list_.InitAndDisableFeature(features::kMojoSessionStorage);
+ else
+ feature_list_.InitAndEnableFeature(features::kMojoSessionStorage);
+ }
+
+ void SessionStorageTest(const GURL& test_url) {
+ // The test page will perform tests then navigate to either
+ // a #pass or #fail ref.
+ context_wrapper()->SetSaveSessionStorageOnDisk();
+ scoped_refptr<SessionStorageNamespaceImpl> ss_namespace =
+ SessionStorageNamespaceImpl::Create(context_wrapper(),
+ kTestSessionStorageId);
+ ss_namespace->SetShouldPersist(true);
+ Shell* the_browser = Shell::CreateNewWindowWithSessionStorageNamespace(
+ ShellContentBrowserClient::Get()->browser_context(),
+ GURL(url::kAboutBlankURL), nullptr, gfx::Size(),
+ std::move(ss_namespace));
+ NavigateToURLBlockUntilNavigationsComplete(the_browser, test_url, 2);
+ context_wrapper()->Flush();
+ std::string result =
+ the_browser->web_contents()->GetLastCommittedURL().ref();
+ if (result != "pass") {
+ std::string js_result;
+ ASSERT_TRUE(ExecuteScriptAndExtractString(
+ the_browser, "window.domAutomationController.send(getLog())",
+ &js_result));
+ FAIL() << "Failed: " << js_result;
+ }
+ }
+
+ private:
+ base::test::ScopedFeatureList feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(DOMStorageMigrationBrowserTest, PRE_DataMigrates) {
+ SessionStorageTest(
+ GetTestUrl("dom_storage", "store_session_storage_data.html"));
+}
+
+// http://crbug.com/654704 PRE_ tests aren't supported on Android.
+#if defined(OS_ANDROID)
+#define MAYBE_DataMigrates DISABLED_DataMigrates
+#else
+#define MAYBE_DataMigrates DataMigrates
+#endif
+IN_PROC_BROWSER_TEST_F(DOMStorageMigrationBrowserTest, MAYBE_DataMigrates) {
+ EXPECT_TRUE(session_storage_context());
+ EnsureSessionStorageConnected();
+ SessionStorageTest(
+ GetTestUrl("dom_storage", "verify_session_storage_data.html"));
+
+ // Check that we migrated from v0 (no version) to v1.
+ base::RunLoop loop;
+ leveldb::mojom::LevelDBDatabase* database =
+ session_storage_context()->DatabaseForTesting();
+ mojo_task_runner()->PostTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ database->Get(
+ leveldb::StringPieceToUint8Vector("version"),
+ base::BindLambdaForTesting([&](leveldb::mojom::DatabaseError error,
+ const std::vector<uint8_t>& value) {
+ EXPECT_EQ(leveldb::mojom::DatabaseError::OK, error);
+ EXPECT_EQ(base::StringPiece("1"),
+ leveldb::Uint8VectorToStringPiece(value));
+ loop.Quit();
+ }));
+ }));
+ loop.Run();
+}
+
} // namespace content
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 efa6d8dc10f..3d71c01f1ec 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_wrapper.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_context_wrapper.cc
@@ -21,6 +21,7 @@
#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/dom_storage/dom_storage_area.h"
#include "content/browser/dom_storage/dom_storage_context_impl.h"
#include "content/browser/dom_storage/dom_storage_task_runner.h"
@@ -153,8 +154,19 @@ DOMStorageContextWrapper::DOMStorageContextWrapper(
if (base::FeatureList::IsEnabled(features::kMojoSessionStorage)) {
mojo_session_state_ = new SessionStorageContextMojo(
- mojo_task_runner_, connector, local_partition_path,
- std::string(kSessionStorageDirectory));
+ mojo_task_runner_, connector,
+
+#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.
+ SessionStorageContextMojo::BackingMode::kClearDiskStateOnOpen,
+#else
+ profile_path.empty()
+ ? SessionStorageContextMojo::BackingMode::kNoDisk
+ : SessionStorageContextMojo::BackingMode::kRestoreDiskState,
+#endif
+ local_partition_path, std::string(kSessionStorageDirectory));
}
if (base::FeatureList::IsEnabled(features::kMemoryCoordinator)) {
@@ -368,7 +380,7 @@ void DOMStorageContextWrapper::Flush() {
void DOMStorageContextWrapper::OpenLocalStorage(
const url::Origin& origin,
- mojom::LevelDBWrapperRequest request) {
+ blink::mojom::StorageAreaRequest request) {
DCHECK(mojo_state_);
// base::Unretained is safe here, because the mojo_state_ won't be deleted
// until a ShutdownAndDelete task has been ran on the mojo_task_runner_, and
@@ -383,7 +395,7 @@ void DOMStorageContextWrapper::OpenLocalStorage(
void DOMStorageContextWrapper::OpenSessionStorage(
int process_id,
const std::string& namespace_id,
- mojom::SessionStorageNamespaceRequest request) {
+ blink::mojom::SessionStorageNamespaceRequest request) {
if (!mojo_session_state_)
return;
// base::Unretained is safe here, because the mojo_state_ won't be deleted
diff --git a/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h b/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h
index 0f2e85e9224..9ab2eed323a 100644
--- a/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h
+++ b/chromium/content/browser/dom_storage/dom_storage_context_wrapper.h
@@ -14,10 +14,12 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
+#include "components/services/leveldb/public/interfaces/leveldb.mojom.h"
#include "content/browser/dom_storage/dom_storage_context_impl.h"
#include "content/common/content_export.h"
-#include "content/common/storage_partition_service.mojom.h"
#include "content/public/browser/dom_storage_context.h"
+#include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_area.mojom.h"
#include "url/origin.h"
namespace base {
@@ -78,10 +80,10 @@ class CONTENT_EXPORT DOMStorageContextWrapper
// See mojom::StoragePartitionService interface.
void OpenLocalStorage(const url::Origin& origin,
- mojom::LevelDBWrapperRequest request);
+ blink::mojom::StorageAreaRequest request);
void OpenSessionStorage(int process_id,
const std::string& namespace_id,
- mojom::SessionStorageNamespaceRequest request);
+ blink::mojom::SessionStorageNamespaceRequest request);
void SetLocalStorageDatabaseForTesting(
leveldb::mojom::LevelDBDatabaseAssociatedPtr database);
diff --git a/chromium/content/browser/dom_storage/dom_storage_database_unittest.cc b/chromium/content/browser/dom_storage/dom_storage_database_unittest.cc
index 5226a1a7a26..d3b199a0e86 100644
--- a/chromium/content/browser/dom_storage/dom_storage_database_unittest.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_database_unittest.cc
@@ -354,11 +354,6 @@ TEST(DOMStorageDatabaseTest, TestCanOpenFileThatIsNotADatabase) {
{
sql::test::ScopedErrorExpecter expecter;
-
- // Old SQLite versions returned a different error code.
- ASSERT_GE(expecter.SQLiteLibVersionNumber(), 3014000)
- << "Chrome ships with SQLite 3.22.0+. The system SQLite version is "
- << "only supported on iOS 10+, which ships with SQLite 3.14.0+";
expecter.ExpectError(SQLITE_NOTADB);
// Try and open the file. As it's not a database, we should end up deleting
diff --git a/chromium/content/browser/dom_storage/dom_storage_namespace.cc b/chromium/content/browser/dom_storage/dom_storage_namespace.cc
index e83a735a3ba..d78f30fb98e 100644
--- a/chromium/content/browser/dom_storage/dom_storage_namespace.cc
+++ b/chromium/content/browser/dom_storage/dom_storage_namespace.cc
@@ -64,11 +64,11 @@ DOMStorageArea* DOMStorageNamespace::GetOpenStorageArea(
return nullptr;
}
-DOMStorageNamespace* DOMStorageNamespace::Clone(
+scoped_refptr<DOMStorageNamespace> DOMStorageNamespace::Clone(
const std::string& clone_namespace_id) {
DCHECK(!namespace_id_.empty());
DCHECK(!clone_namespace_id.empty());
- DOMStorageNamespace* clone = new DOMStorageNamespace(
+ auto clone = base::MakeRefCounted<DOMStorageNamespace>(
clone_namespace_id, session_storage_database_.get(), task_runner_.get());
AreaMap::const_iterator it = areas_.begin();
// Clone the in-memory structures.
diff --git a/chromium/content/browser/dom_storage/dom_storage_namespace.h b/chromium/content/browser/dom_storage/dom_storage_namespace.h
index 60c1a83bc41..fc2a5c68161 100644
--- a/chromium/content/browser/dom_storage/dom_storage_namespace.h
+++ b/chromium/content/browser/dom_storage/dom_storage_namespace.h
@@ -63,7 +63,8 @@ class CONTENT_EXPORT DOMStorageNamespace
// Creates a clone of |this| namespace including
// shallow copies of all contained areas.
// Should only be called for session storage namespaces.
- DOMStorageNamespace* Clone(const std::string& clone_namespace_id);
+ scoped_refptr<DOMStorageNamespace> Clone(
+ const std::string& clone_namespace_id);
void DeleteSessionStorageOrigin(const url::Origin& origin);
void PurgeMemory(bool aggressively);
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 369046443da..3d90057ed86 100644
--- a/chromium/content/browser/dom_storage/local_storage_context_mojo.cc
+++ b/chromium/content/browser/dom_storage/local_storage_context_mojo.cc
@@ -27,7 +27,7 @@
#include "content/browser/dom_storage/dom_storage_database.h"
#include "content/browser/dom_storage/dom_storage_task_runner.h"
#include "content/browser/dom_storage/local_storage_database.pb.h"
-#include "content/browser/leveldb_wrapper_impl.h"
+#include "content/browser/dom_storage/storage_area_impl.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/public/browser/local_storage_usage_info.h"
#include "services/file/public/mojom/constants.mojom.h"
@@ -98,12 +98,11 @@ void DatabaseErrorResponse(base::OnceClosure callback,
void MigrateStorageHelper(
base::FilePath db_path,
const scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner,
- base::Callback<void(std::unique_ptr<LevelDBWrapperImpl::ValueMap>)>
- callback) {
+ base::Callback<void(std::unique_ptr<StorageAreaImpl::ValueMap>)> callback) {
DOMStorageDatabase db(db_path);
DOMStorageValuesMap map;
db.ReadAllValues(&map);
- auto values = std::make_unique<LevelDBWrapperImpl::ValueMap>();
+ auto values = std::make_unique<StorageAreaImpl::ValueMap>();
for (const auto& it : map) {
(*values)[LocalStorageContextMojo::MigrateString(it.first)] =
LocalStorageContextMojo::MigrateString(it.second.string());
@@ -113,8 +112,8 @@ void MigrateStorageHelper(
}
// Helper to convert from OnceCallback to Callback.
-void CallMigrationCalback(LevelDBWrapperImpl::ValueMapCallback callback,
- std::unique_ptr<LevelDBWrapperImpl::ValueMap> data) {
+void CallMigrationCalback(StorageAreaImpl::ValueMapCallback callback,
+ std::unique_ptr<StorageAreaImpl::ValueMap> data) {
std::move(callback).Run(std::move(data));
}
@@ -175,11 +174,10 @@ void RecordCachePurgedHistogram(CachePurgeReason reason,
} // namespace
-class LocalStorageContextMojo::LevelDBWrapperHolder final
- : public LevelDBWrapperImpl::Delegate {
+class LocalStorageContextMojo::StorageAreaHolder final
+ : public StorageAreaImpl::Delegate {
public:
- LevelDBWrapperHolder(LocalStorageContextMojo* context,
- const url::Origin& origin)
+ StorageAreaHolder(LocalStorageContextMojo* context, const url::Origin& origin)
: context_(context), origin_(origin) {
// Delay for a moment after a value is set in anticipation
// of other values being set, so changes are batched.
@@ -191,34 +189,33 @@ class LocalStorageContextMojo::LevelDBWrapperHolder final
static constexpr int kMaxBytesPerHour = kPerStorageAreaQuota;
static constexpr int kMaxCommitsPerHour = 60;
- LevelDBWrapperImpl::Options options;
+ StorageAreaImpl::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;
+ options.cache_mode = StorageAreaImpl::CacheMode::KEYS_ONLY_WHEN_POSSIBLE;
#else
- options.cache_mode = LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES;
+ options.cache_mode = StorageAreaImpl::CacheMode::KEYS_AND_VALUES;
if (base::SysInfo::IsLowEndDevice()) {
- options.cache_mode =
- LevelDBWrapperImpl::CacheMode::KEYS_ONLY_WHEN_POSSIBLE;
+ options.cache_mode = StorageAreaImpl::CacheMode::KEYS_ONLY_WHEN_POSSIBLE;
}
#endif
- level_db_wrapper_ = std::make_unique<LevelDBWrapperImpl>(
+ area_ = std::make_unique<StorageAreaImpl>(
context_->database_.get(),
kDataPrefix + origin_.Serialize() + kOriginSeparator, this, options);
- level_db_wrapper_ptr_ = level_db_wrapper_.get();
+ area_ptr_ = area_.get();
}
- LevelDBWrapperImpl* level_db_wrapper() { return level_db_wrapper_ptr_; }
+ StorageAreaImpl* storage_area() { return area_ptr_; }
void OnNoBindings() override {
has_bindings_ = false;
// Don't delete ourselves, but do schedule an immediate commit. Possible
// deletion will happen under memory pressure or when another localstorage
// area is opened.
- level_db_wrapper()->ScheduleImmediateCommit();
+ storage_area()->ScheduleImmediateCommit();
}
std::vector<leveldb::mojom::BatchedOperationPtr> PrepareToCommit() override {
@@ -240,13 +237,13 @@ class LocalStorageContextMojo::LevelDBWrapperHolder final
leveldb::mojom::BatchedOperation::New();
item->type = leveldb::mojom::BatchOperationType::PUT_KEY;
item->key = CreateMetaDataKey(origin_);
- if (level_db_wrapper()->empty()) {
+ if (storage_area()->empty()) {
item->type = leveldb::mojom::BatchOperationType::DELETE_KEY;
} else {
item->type = leveldb::mojom::BatchOperationType::PUT_KEY;
LocalStorageOriginMetaData data;
data.set_last_modified(base::Time::Now().ToInternalValue());
- data.set_size_bytes(level_db_wrapper()->storage_used());
+ data.set_size_bytes(storage_area()->storage_used());
item->value = leveldb::StdStringToUint8Vector(data.SerializeAsString());
}
operations.push_back(std::move(item));
@@ -274,7 +271,7 @@ class LocalStorageContextMojo::LevelDBWrapperHolder final
context_->OnCommitResult(error);
}
- void MigrateData(LevelDBWrapperImpl::ValueMapCallback callback) override {
+ void MigrateData(StorageAreaImpl::ValueMapCallback callback) override {
if (context_->task_runner_ && !context_->old_localstorage_path_.empty()) {
context_->task_runner_->PostShutdownBlockingTask(
FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE,
@@ -287,9 +284,9 @@ class LocalStorageContextMojo::LevelDBWrapperHolder final
std::move(callback).Run(nullptr);
}
- std::vector<LevelDBWrapperImpl::Change> FixUpData(
- const LevelDBWrapperImpl::ValueMap& data) override {
- std::vector<LevelDBWrapperImpl::Change> changes;
+ std::vector<StorageAreaImpl::Change> FixUpData(
+ const StorageAreaImpl::ValueMap& data) override {
+ std::vector<StorageAreaImpl::Change> changes;
// Chrome M61/M62 had a bug where keys that should have been encoded as
// Latin1 were instead encoded as UTF16. Fix this by finding any 8-bit only
// keys, and re-encode those. If two encodings of the key exist, the Latin1
@@ -346,9 +343,9 @@ class LocalStorageContextMojo::LevelDBWrapperHolder final
leveldb_env::LEVELDB_STATUS_MAX);
}
- void Bind(mojom::LevelDBWrapperRequest request) {
+ void Bind(blink::mojom::StorageAreaRequest request) {
has_bindings_ = true;
- level_db_wrapper()->Bind(std::move(request));
+ storage_area()->Bind(std::move(request));
}
bool has_bindings() const { return has_bindings_; }
@@ -363,12 +360,12 @@ class LocalStorageContextMojo::LevelDBWrapperHolder final
LocalStorageContextMojo* context_;
url::Origin origin_;
- std::unique_ptr<LevelDBWrapperImpl> level_db_wrapper_;
- // Holds the same value as |level_db_wrapper_|. The reason for this is that
- // during destruction of the LevelDBWrapperImpl instance we might still get
- // called and need access to the LevelDBWrapperImpl instance. The unique_ptr
+ std::unique_ptr<StorageAreaImpl> area_;
+ // Holds the same value as |area_|. The reason for this is that
+ // during destruction of the StorageAreaImpl instance we might still get
+ // called and need access to the StorageAreaImpl instance. The unique_ptr
// could already be null, but this field should still be valid.
- LevelDBWrapperImpl* level_db_wrapper_ptr_;
+ StorageAreaImpl* area_ptr_;
bool deleted_old_data_ = false;
bool has_bindings_ = false;
};
@@ -396,7 +393,7 @@ LocalStorageContextMojo::LocalStorageContextMojo(
void LocalStorageContextMojo::OpenLocalStorage(
const url::Origin& origin,
- mojom::LevelDBWrapperRequest request) {
+ blink::mojom::StorageAreaRequest request) {
RunWhenConnected(base::BindOnce(&LocalStorageContextMojo::BindLocalStorage,
weak_ptr_factory_.GetWeakPtr(), origin,
std::move(request)));
@@ -418,13 +415,13 @@ void LocalStorageContextMojo::DeleteStorage(const url::Origin& origin,
return;
}
- auto found = level_db_wrappers_.find(origin);
- if (found != level_db_wrappers_.end()) {
+ auto found = areas_.find(origin);
+ if (found != areas_.end()) {
// Renderer process expects |source| to always be two newline separated
// strings.
- found->second->level_db_wrapper()->DeleteAll(
+ found->second->storage_area()->DeleteAll(
"\n", base::BindOnce(&SuccessResponse, std::move(callback)));
- found->second->level_db_wrapper()->ScheduleImmediateCommit();
+ found->second->storage_area()->ScheduleImmediateCommit();
} else if (database_) {
std::vector<leveldb::mojom::BatchedOperationPtr> operations;
AddDeleteOriginOperations(&operations, origin);
@@ -442,17 +439,17 @@ void LocalStorageContextMojo::Flush() {
weak_ptr_factory_.GetWeakPtr()));
return;
}
- for (const auto& it : level_db_wrappers_)
- it.second->level_db_wrapper()->ScheduleImmediateCommit();
+ for (const auto& it : areas_)
+ it.second->storage_area()->ScheduleImmediateCommit();
}
void LocalStorageContextMojo::FlushOriginForTesting(const url::Origin& origin) {
if (connection_state_ != CONNECTION_FINISHED)
return;
- const auto& it = level_db_wrappers_.find(origin);
- if (it == level_db_wrappers_.end())
+ const auto& it = areas_.find(origin);
+ if (it == areas_.end())
return;
- it->second->level_db_wrapper()->ScheduleImmediateCommit();
+ it->second->storage_area()->ScheduleImmediateCommit();
}
void LocalStorageContextMojo::ShutdownAndDelete() {
@@ -468,15 +465,15 @@ void LocalStorageContextMojo::ShutdownAndDelete() {
connection_state_ = CONNECTION_SHUTDOWN;
// Flush any uncommitted data.
- for (const auto& it : level_db_wrappers_) {
- auto* wrapper = it.second->level_db_wrapper();
+ for (const auto& it : areas_) {
+ auto* area = it.second->storage_area();
LOCAL_HISTOGRAM_BOOLEAN(
"LocalStorageContext.ShutdownAndDelete.MaybeDroppedChanges",
- wrapper->has_pending_load_tasks());
- wrapper->ScheduleImmediateCommit();
+ area->has_pending_load_tasks());
+ area->ScheduleImmediateCommit();
// TODO(dmurph): Monitor the above histogram, and if dropping changes is
// common then handle that here.
- wrapper->CancelAllPendingRequests();
+ area->CancelAllPendingRequests();
}
// Respect the content policy settings about what to
@@ -500,39 +497,39 @@ void LocalStorageContextMojo::ShutdownAndDelete() {
}
void LocalStorageContextMojo::PurgeMemory() {
- size_t total_cache_size, unused_wrapper_count;
- GetStatistics(&total_cache_size, &unused_wrapper_count);
+ size_t total_cache_size, unused_area_count;
+ GetStatistics(&total_cache_size, &unused_area_count);
- for (auto it = level_db_wrappers_.begin(); it != level_db_wrappers_.end();) {
+ for (auto it = areas_.begin(); it != areas_.end();) {
if (it->second->has_bindings()) {
- it->second->level_db_wrapper()->PurgeMemory();
+ it->second->storage_area()->PurgeMemory();
++it;
} else {
- it = level_db_wrappers_.erase(it);
+ it = areas_.erase(it);
}
}
// Track the size of cache purged.
size_t final_total_cache_size;
- GetStatistics(&final_total_cache_size, &unused_wrapper_count);
+ GetStatistics(&final_total_cache_size, &unused_area_count);
size_t purged_size_kib = (total_cache_size - final_total_cache_size) / 1024;
RecordCachePurgedHistogram(CachePurgeReason::AggressivePurgeTriggered,
purged_size_kib);
}
-void LocalStorageContextMojo::PurgeUnusedWrappersIfNeeded() {
- size_t total_cache_size, unused_wrapper_count;
- GetStatistics(&total_cache_size, &unused_wrapper_count);
+void LocalStorageContextMojo::PurgeUnusedAreasIfNeeded() {
+ size_t total_cache_size, unused_area_count;
+ GetStatistics(&total_cache_size, &unused_area_count);
// Nothing to purge.
- if (!unused_wrapper_count)
+ if (!unused_area_count)
return;
CachePurgeReason purge_reason = CachePurgeReason::NotNeeded;
if (total_cache_size > kMaxLocalStorageCacheSize)
purge_reason = CachePurgeReason::SizeLimitExceeded;
- else if (level_db_wrappers_.size() > kMaxLocalStorageAreaCount)
+ else if (areas_.size() > kMaxLocalStorageAreaCount)
purge_reason = CachePurgeReason::AreaCountLimitExceeded;
else if (is_low_end_device_)
purge_reason = CachePurgeReason::InactiveOnLowEndDevice;
@@ -540,16 +537,16 @@ void LocalStorageContextMojo::PurgeUnusedWrappersIfNeeded() {
if (purge_reason == CachePurgeReason::NotNeeded)
return;
- for (auto it = level_db_wrappers_.begin(); it != level_db_wrappers_.end();) {
+ for (auto it = areas_.begin(); it != areas_.end();) {
if (it->second->has_bindings())
++it;
else
- it = level_db_wrappers_.erase(it);
+ it = areas_.erase(it);
}
// Track the size of cache purged.
size_t final_total_cache_size;
- GetStatistics(&final_total_cache_size, &unused_wrapper_count);
+ GetStatistics(&final_total_cache_size, &unused_area_count);
size_t purged_size_kib = (total_cache_size - final_total_cache_size) / 1024;
RecordCachePurgedHistogram(purge_reason, purged_size_kib);
}
@@ -582,28 +579,28 @@ bool LocalStorageContextMojo::OnMemoryDump(
if (args.level_of_detail ==
base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND) {
- size_t total_cache_size, unused_wrapper_count;
- GetStatistics(&total_cache_size, &unused_wrapper_count);
+ size_t total_cache_size, unused_area_count;
+ GetStatistics(&total_cache_size, &unused_area_count);
auto* mad = pmd->CreateAllocatorDump(context_name + "/cache_size");
mad->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
total_cache_size);
mad->AddScalar("total_areas",
base::trace_event::MemoryAllocatorDump::kUnitsObjects,
- level_db_wrappers_.size());
+ areas_.size());
return true;
}
- for (const auto& it : level_db_wrappers_) {
+ for (const auto& it : areas_) {
// Limit the url length to 50 and strip special characters.
std::string url = it.first.Serialize().substr(0, 50);
for (size_t index = 0; index < url.size(); ++index) {
if (!std::isalnum(url[index]))
url[index] = '_';
}
- std::string wrapper_dump_name = base::StringPrintf(
+ std::string area_dump_name = base::StringPrintf(
"%s/%s/0x%" PRIXPTR, context_name.c_str(), url.c_str(),
- reinterpret_cast<uintptr_t>(it.second->level_db_wrapper()));
- it.second->level_db_wrapper()->OnMemoryDump(wrapper_dump_name, pmd);
+ reinterpret_cast<uintptr_t>(it.second->storage_area()));
+ it.second->storage_area()->OnMemoryDump(area_dump_name, pmd);
}
return true;
}
@@ -688,7 +685,7 @@ void LocalStorageContextMojo::InitiateConnection(bool in_memory_only) {
void LocalStorageContextMojo::OnDirectoryOpened(base::File::Error err) {
if (err != base::File::Error::FILE_OK) {
// We failed to open the directory; continue with startup so that we create
- // the |level_db_wrappers_|.
+ // the |areas_|.
UMA_HISTOGRAM_ENUMERATION("LocalStorageContext.DirectoryOpenError", -err,
-base::File::FILE_ERROR_MAX);
LogDatabaseOpenResult(OpenResult::DIRECTORY_OPEN_FAILED);
@@ -813,14 +810,14 @@ void LocalStorageContextMojo::OnConnectionFinished() {
void LocalStorageContextMojo::DeleteAndRecreateDatabase(
const char* histogram_name) {
- // We're about to set database_ to null, so delete the LevelDBWrappers
+ // We're about to set database_ to null, so delete the StorageAreaImpls
// 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();
+ for (const auto& it : areas_)
+ it.second->storage_area()->CancelAllPendingRequests();
+ areas_.clear();
// Reset state to be in process of connecting. This will cause requests for
- // LevelDBWrappers to be queued until the connection is complete.
+ // StorageAreas to be queued until the connection is complete.
connection_state_ = CONNECTION_IN_PROGRESS;
commit_error_count_ = 0;
database_ = nullptr;
@@ -875,30 +872,30 @@ void LocalStorageContextMojo::OnDBDestroyed(
// directly from that function, or through |on_database_open_callbacks_|.
void LocalStorageContextMojo::BindLocalStorage(
const url::Origin& origin,
- mojom::LevelDBWrapperRequest request) {
- GetOrCreateDBWrapper(origin)->Bind(std::move(request));
+ blink::mojom::StorageAreaRequest request) {
+ GetOrCreateStorageArea(origin)->Bind(std::move(request));
}
-LocalStorageContextMojo::LevelDBWrapperHolder*
-LocalStorageContextMojo::GetOrCreateDBWrapper(const url::Origin& origin) {
+LocalStorageContextMojo::StorageAreaHolder*
+LocalStorageContextMojo::GetOrCreateStorageArea(const url::Origin& origin) {
DCHECK_EQ(connection_state_, CONNECTION_FINISHED);
- auto found = level_db_wrappers_.find(origin);
- if (found != level_db_wrappers_.end()) {
+ auto found = areas_.find(origin);
+ if (found != areas_.end()) {
return found->second.get();
}
- size_t total_cache_size, unused_wrapper_count;
- GetStatistics(&total_cache_size, &unused_wrapper_count);
+ size_t total_cache_size, unused_area_count;
+ GetStatistics(&total_cache_size, &unused_area_count);
// Track the total localStorage cache size.
UMA_HISTOGRAM_COUNTS_100000("LocalStorageContext.CacheSizeInKB",
total_cache_size / 1024);
- PurgeUnusedWrappersIfNeeded();
+ PurgeUnusedAreasIfNeeded();
- auto holder = std::make_unique<LevelDBWrapperHolder>(this, origin);
- LevelDBWrapperHolder* holder_ptr = holder.get();
- level_db_wrappers_[origin] = std::move(holder);
+ auto holder = std::make_unique<StorageAreaHolder>(this, origin);
+ StorageAreaHolder* holder_ptr = holder.get();
+ areas_[origin] = std::move(holder);
return holder_ptr;
}
@@ -906,10 +903,10 @@ void LocalStorageContextMojo::RetrieveStorageUsage(
GetStorageUsageCallback callback) {
if (!database_) {
// If for whatever reason no leveldb database is available, no storage is
- // used, so return an array only containing the current leveldb wrappers.
+ // used, so return an array only containing the current areas.
std::vector<LocalStorageUsageInfo> result;
base::Time now = base::Time::Now();
- for (const auto& it : level_db_wrappers_) {
+ for (const auto& it : areas_) {
LocalStorageUsageInfo info;
info.origin = it.first.GetURL();
info.last_modified = now;
@@ -952,15 +949,15 @@ void LocalStorageContextMojo::OnGotMetaData(
base::Time::FromInternalValue(row_data.last_modified());
result.push_back(std::move(info));
}
- // Add any origins for which LevelDBWrappers exist, but which haven't
+ // Add any origins for which StorageAreas exist, but which haven't
// committed any data to disk yet.
base::Time now = base::Time::Now();
- for (const auto& it : level_db_wrappers_) {
+ for (const auto& it : areas_) {
if (origins.find(it.first) != origins.end())
continue;
// Skip any origins that definitely don't have any data.
- if (!it.second->level_db_wrapper()->has_pending_load_tasks() &&
- it.second->level_db_wrapper()->empty()) {
+ if (!it.second->storage_area()->has_pending_load_tasks() &&
+ it.second->storage_area()->empty()) {
continue;
}
LocalStorageUsageInfo info;
@@ -999,13 +996,13 @@ void LocalStorageContextMojo::OnShutdownComplete(
}
void LocalStorageContextMojo::GetStatistics(size_t* total_cache_size,
- size_t* unused_wrapper_count) {
+ size_t* unused_area_count) {
*total_cache_size = 0;
- *unused_wrapper_count = 0;
- for (const auto& it : level_db_wrappers_) {
- *total_cache_size += it.second->level_db_wrapper()->memory_used();
+ *unused_area_count = 0;
+ for (const auto& it : areas_) {
+ *total_cache_size += it.second->storage_area()->memory_used();
if (!it.second->has_bindings())
- (*unused_wrapper_count)++;
+ (*unused_area_count)++;
}
}
@@ -1030,8 +1027,8 @@ void LocalStorageContextMojo::OnCommitResult(
}
tried_to_recover_from_commit_errors_ = true;
- // Deleting LevelDBWrappers in here could cause more commits (and commit
- // errors), but those commits won't reach OnCommitResult because the wrapper
+ // Deleting StorageAreas in here could cause more commits (and commit
+ // errors), but those commits won't reach OnCommitResult because the area
// will have been deleted before the commit finishes.
DeleteAndRecreateDatabase(
"LocalStorageContext.OpenResultAfterCommitErrors");
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 3670af2a646..5f7d21c98a7 100644
--- a/chromium/content/browser/dom_storage/local_storage_context_mojo.h
+++ b/chromium/content/browser/dom_storage/local_storage_context_mojo.h
@@ -16,10 +16,11 @@
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
#include "base/trace_event/memory_dump_provider.h"
+#include "components/services/leveldb/public/interfaces/leveldb.mojom.h"
#include "content/common/content_export.h"
-#include "content/common/leveldb_wrapper.mojom.h"
#include "content/public/browser/browser_thread.h"
#include "services/file/public/mojom/file_system.mojom.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_area.mojom.h"
#include "url/origin.h"
namespace service_manager {
@@ -56,7 +57,7 @@ class CONTENT_EXPORT LocalStorageContextMojo
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy);
void OpenLocalStorage(const url::Origin& origin,
- mojom::LevelDBWrapperRequest request);
+ blink::mojom::StorageAreaRequest request);
void GetStorageUsage(GetStorageUsageCallback callback);
// |callback| is called when the deletion is sent to the database and
// GetStorageUsage() will not return entries for |origin| anymore.
@@ -80,8 +81,8 @@ class CONTENT_EXPORT LocalStorageContextMojo
// storage for a particular origin will reload the data from the database.
void PurgeMemory();
- // Clears unused leveldb wrappers, when thresholds are reached.
- void PurgeUnusedWrappersIfNeeded();
+ // Clears unused storage areas, when thresholds are reached.
+ void PurgeUnusedAreasIfNeeded();
void SetDatabaseForTesting(
leveldb::mojom::LevelDBDatabaseAssociatedPtr database);
@@ -96,7 +97,7 @@ class CONTENT_EXPORT LocalStorageContextMojo
private:
friend class DOMStorageBrowserTest;
- class LevelDBWrapperHolder;
+ class StorageAreaHolder;
~LocalStorageContextMojo() override;
@@ -119,8 +120,8 @@ class CONTENT_EXPORT LocalStorageContextMojo
// The (possibly delayed) implementation of OpenLocalStorage(). Can be called
// directly from that function, or through |on_database_open_callbacks_|.
void BindLocalStorage(const url::Origin& origin,
- mojom::LevelDBWrapperRequest request);
- LevelDBWrapperHolder* GetOrCreateDBWrapper(const url::Origin& origin);
+ blink::mojom::StorageAreaRequest request);
+ StorageAreaHolder* GetOrCreateStorageArea(const url::Origin& origin);
// The (possibly delayed) implementation of GetStorageUsage(). Can be called
// directly from that function, or through |on_database_open_callbacks_|.
@@ -132,7 +133,7 @@ class CONTENT_EXPORT LocalStorageContextMojo
void OnGotStorageUsageForShutdown(std::vector<LocalStorageUsageInfo> usage);
void OnShutdownComplete(leveldb::mojom::DatabaseError error);
- void GetStatistics(size_t* total_cache_size, size_t* unused_wrapper_count);
+ void GetStatistics(size_t* total_cache_size, size_t* unused_area_count);
void OnCommitResult(leveldb::mojom::DatabaseError error);
// These values are written to logs. New enum values can be added, but
@@ -174,8 +175,7 @@ class CONTENT_EXPORT LocalStorageContextMojo
std::vector<base::OnceClosure> on_database_opened_callbacks_;
// Maps between an origin and its prefixed LevelDB view.
- std::map<url::Origin, std::unique_ptr<LevelDBWrapperHolder>>
- level_db_wrappers_;
+ std::map<url::Origin, std::unique_ptr<StorageAreaHolder>> areas_;
// Used to access old data for migration.
scoped_refptr<DOMStorageTaskRunner> task_runner_;
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 b758d40ec16..a01c79873af 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,13 +22,13 @@
#include "content/browser/dom_storage/test/fake_leveldb_database_error_on_write.h"
#include "content/browser/dom_storage/test/fake_leveldb_service.h"
#include "content/browser/dom_storage/test/mojo_test_with_file_service.h"
+#include "content/browser/dom_storage/test/storage_area_test_util.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/public/browser/browser_thread.h"
#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/fake_leveldb_database.h"
-#include "content/test/leveldb_wrapper_test_util.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
@@ -63,7 +63,7 @@ void GetStorageUsageCallback(const base::RepeatingClosure& callback,
callback.Run();
}
-class TestLevelDBObserver : public mojom::LevelDBObserver {
+class TestLevelDBObserver : public blink::mojom::StorageAreaObserver {
public:
struct Observation {
enum { kAdd, kChange, kDelete, kDeleteAll } type;
@@ -75,8 +75,8 @@ class TestLevelDBObserver : public mojom::LevelDBObserver {
TestLevelDBObserver() : binding_(this) {}
- mojom::LevelDBObserverAssociatedPtrInfo Bind() {
- mojom::LevelDBObserverAssociatedPtrInfo ptr_info;
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo Bind() {
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo ptr_info;
binding_.Bind(mojo::MakeRequest(&ptr_info));
return ptr_info;
}
@@ -110,7 +110,7 @@ class TestLevelDBObserver : public mojom::LevelDBObserver {
void ShouldSendOldValueOnMutations(bool value) override {}
std::vector<Observation> observations_;
- mojo::AssociatedBinding<mojom::LevelDBObserver> binding_;
+ mojo::AssociatedBinding<blink::mojom::StorageAreaObserver> binding_;
};
} // namespace
@@ -186,12 +186,12 @@ class LocalStorageContextMojoTest : public testing::Test {
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));
+ blink::mojom::StorageAreaPtr area;
+ blink::mojom::StorageAreaPtr dummy_area; // To make sure values are cached.
+ context()->OpenLocalStorage(kOrigin, MakeRequest(&area));
+ context()->OpenLocalStorage(kOrigin, MakeRequest(&dummy_area));
std::vector<uint8_t> result;
- bool success = test::GetSync(wrapper.get(), key, &result);
+ bool success = test::GetSync(area.get(), key, &result);
return success ? base::Optional<std::vector<uint8_t>>(result)
: base::nullopt;
}
@@ -219,11 +219,11 @@ TEST_F(LocalStorageContextMojoTest, Basic) {
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
- mojom::LevelDBWrapperPtr wrapper;
+ blink::mojom::StorageAreaPtr area;
context()->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
base::RunLoop().RunUntilIdle();
@@ -239,14 +239,14 @@ TEST_F(LocalStorageContextMojoTest, OriginsAreIndependent) {
auto key2 = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
- mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->Put(key1, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ blink::mojom::StorageAreaPtr area;
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->Put(key1, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
- context()->OpenLocalStorage(origin2, MakeRequest(&wrapper));
- wrapper->Put(key2, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ context()->OpenLocalStorage(origin2, MakeRequest(&area));
+ area->Put(key2, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
base::RunLoop().RunUntilIdle();
ASSERT_EQ(5u, mock_data().size());
@@ -257,22 +257,22 @@ TEST_F(LocalStorageContextMojoTest, WrapperOutlivesMojoConnection) {
auto value = StdStringToUint8Vector("value");
// Write some data to the DB.
- mojom::LevelDBWrapperPtr wrapper;
- mojom::LevelDBWrapperPtr dummy_wrapper; // To make sure values are cached.
+ blink::mojom::StorageAreaPtr area;
+ blink::mojom::StorageAreaPtr dummy_area; // 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::DoNothing());
- wrapper.reset();
- dummy_wrapper.reset();
+ context()->OpenLocalStorage(kOrigin, MakeRequest(&area));
+ context()->OpenLocalStorage(kOrigin, MakeRequest(&dummy_area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
+ dummy_area.reset();
base::RunLoop().RunUntilIdle();
// Clear all the data from the backing database.
EXPECT_FALSE(mock_data().empty());
clear_mock_data();
- // Data should still be readable, because despite closing the wrapper
- // connection above, the actual wrapper instance should have been kept alive.
+ // Data should still be readable, because despite closing the area
+ // connection above, the actual area instance should have been kept alive.
EXPECT_EQ(value, DoTestGet(key));
// Now purge memory.
@@ -287,23 +287,23 @@ TEST_F(LocalStorageContextMojoTest, OpeningWrappersPurgesInactiveWrappers) {
auto value = StdStringToUint8Vector("value");
// Write some data to the DB.
- mojom::LevelDBWrapperPtr wrapper;
+ blink::mojom::StorageAreaPtr area;
context()->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
base::RunLoop().RunUntilIdle();
// Clear all the data from the backing database.
EXPECT_FALSE(mock_data().empty());
clear_mock_data();
- // Now open many new wrappers (for different origins) to trigger clean up.
+ // Now open many new areas (for different origins) to trigger clean up.
for (int i = 1; i <= 100; ++i) {
context()->OpenLocalStorage(url::Origin::Create(GURL(base::StringPrintf(
"http://example.com:%d", i))),
- MakeRequest(&wrapper));
- wrapper.reset();
+ MakeRequest(&area));
+ area.reset();
}
// And make sure caches were actually cleared.
@@ -346,15 +346,15 @@ TEST_F(LocalStorageContextMojoTest, GetStorageUsage_Data) {
base::Time before_write = base::Time::Now();
- mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->Put(key1, value, base::nullopt, "source", base::DoNothing());
- wrapper->Put(key2, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ blink::mojom::StorageAreaPtr area;
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->Put(key1, value, base::nullopt, "source", base::DoNothing());
+ area->Put(key2, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
- context()->OpenLocalStorage(origin2, MakeRequest(&wrapper));
- wrapper->Put(key2, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ context()->OpenLocalStorage(origin2, MakeRequest(&area));
+ area->Put(key2, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
// GetStorageUsage only includes committed data, but still returns all origins
// that used localstorage with zero size.
@@ -393,16 +393,16 @@ TEST_F(LocalStorageContextMojoTest, MetaDataClearedOnDelete) {
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
- mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
- context()->OpenLocalStorage(origin2, MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->Delete(key, value, "source", base::DoNothing());
- wrapper.reset();
+ blink::mojom::StorageAreaPtr area;
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
+ context()->OpenLocalStorage(origin2, MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->Delete(key, value, "source", base::DoNothing());
+ area.reset();
// Make sure all data gets committed to disk.
base::RunLoop().RunUntilIdle();
@@ -426,17 +426,17 @@ TEST_F(LocalStorageContextMojoTest, MetaDataClearedOnDeleteAll) {
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
- mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
- context()->OpenLocalStorage(origin2, MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ blink::mojom::StorageAreaPtr area;
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
+ context()->OpenLocalStorage(origin2, MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->DeleteAll("source", base::DoNothing());
- wrapper.reset();
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->DeleteAll("source", base::DoNothing());
+ area.reset();
// Make sure all data gets committed to disk.
base::RunLoop().RunUntilIdle();
@@ -471,14 +471,14 @@ TEST_F(LocalStorageContextMojoTest, DeleteStorageWithoutConnection) {
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
- mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ blink::mojom::StorageAreaPtr area;
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
- context()->OpenLocalStorage(origin2, MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ context()->OpenLocalStorage(origin2, MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
// Make sure all data gets committed to disk.
base::RunLoop().RunUntilIdle();
@@ -506,22 +506,22 @@ TEST_F(LocalStorageContextMojoTest, DeleteStorageNotifiesWrapper) {
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
- mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ blink::mojom::StorageAreaPtr area;
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
- context()->OpenLocalStorage(origin2, MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ context()->OpenLocalStorage(origin2, MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
// Make sure all data gets committed to disk.
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(mock_data().empty());
TestLevelDBObserver observer;
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->AddObserver(observer.Bind());
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->AddObserver(observer.Bind());
base::RunLoop().RunUntilIdle();
context()->DeleteStorage(origin1, base::DoNothing());
@@ -550,24 +550,24 @@ TEST_F(LocalStorageContextMojoTest, DeleteStorageWithPendingWrites) {
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
- mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ blink::mojom::StorageAreaPtr area;
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
- context()->OpenLocalStorage(origin2, MakeRequest(&wrapper));
- wrapper->Put(key, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ context()->OpenLocalStorage(origin2, MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
// Make sure all data gets committed to disk.
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(mock_data().empty());
TestLevelDBObserver observer;
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->AddObserver(observer.Bind());
- wrapper->Put(StdStringToUint8Vector("key2"), value, base::nullopt, "source",
- base::DoNothing());
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->AddObserver(observer.Bind());
+ area->Put(StdStringToUint8Vector("key2"), value, base::nullopt, "source",
+ base::DoNothing());
base::RunLoop().RunUntilIdle();
context()->DeleteStorage(origin1, base::DoNothing());
@@ -613,27 +613,27 @@ TEST_F(LocalStorageContextMojoTest, Migration) {
EXPECT_TRUE(base::PathExists(old_db_path));
// 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::DoNothing());
- wrapper.reset();
- dummy_wrapper.reset();
+ blink::mojom::StorageAreaPtr area;
+ context()->OpenLocalStorage(origin2, MakeRequest(&area));
+ blink::mojom::StorageAreaPtr dummy_area; // To make sure values are cached.
+ context()->OpenLocalStorage(origin2, MakeRequest(&dummy_area));
+ area->Get(std::vector<uint8_t>(), base::DoNothing());
+ area.reset();
+ dummy_area.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::DoNothing());
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ context()->OpenLocalStorage(origin1, MakeRequest(&dummy_area));
+ area->Get(std::vector<uint8_t>(), base::DoNothing());
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(mock_data().empty());
{
std::vector<uint8_t> result;
bool success = test::GetSync(
- wrapper.get(), LocalStorageContextMojo::MigrateString(key), &result);
+ area.get(), LocalStorageContextMojo::MigrateString(key), &result);
EXPECT_TRUE(success);
EXPECT_EQ(LocalStorageContextMojo::MigrateString(value), result);
}
@@ -641,7 +641,7 @@ TEST_F(LocalStorageContextMojoTest, Migration) {
{
std::vector<uint8_t> result;
bool success = test::GetSync(
- wrapper.get(), LocalStorageContextMojo::MigrateString(key2), &result);
+ area.get(), LocalStorageContextMojo::MigrateString(key2), &result);
EXPECT_TRUE(success);
EXPECT_EQ(LocalStorageContextMojo::MigrateString(value), result);
}
@@ -677,23 +677,23 @@ TEST_F(LocalStorageContextMojoTest, FixUp) {
EncodeKeyAsUTF16("http://foobar.com", base::ASCIIToUTF16("foo")),
"value3");
- mojom::LevelDBWrapperPtr wrapper;
- mojom::LevelDBWrapperPtr dummy_wrapper; // To make sure values are cached.
+ blink::mojom::StorageAreaPtr area;
+ blink::mojom::StorageAreaPtr dummy_area; // To make sure values are cached.
context()->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
+ MakeRequest(&area));
context()->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
- MakeRequest(&dummy_wrapper));
+ MakeRequest(&dummy_area));
{
std::vector<uint8_t> result;
bool success = test::GetSync(
- wrapper.get(), leveldb::StdStringToUint8Vector("\x01key"), &result);
+ area.get(), leveldb::StdStringToUint8Vector("\x01key"), &result);
EXPECT_TRUE(success);
EXPECT_EQ(leveldb::StdStringToUint8Vector("value1"), result);
}
{
std::vector<uint8_t> result;
- bool success = test::GetSync(wrapper.get(),
+ bool success = test::GetSync(area.get(),
leveldb::StdStringToUint8Vector("\x01"
"foo"),
&result);
@@ -717,15 +717,15 @@ TEST_F(LocalStorageContextMojoTest, ShutdownClearsData) {
auto key2 = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
- mojom::LevelDBWrapperPtr wrapper;
- context()->OpenLocalStorage(origin1, MakeRequest(&wrapper));
- wrapper->Put(key1, value, base::nullopt, "source", base::DoNothing());
- wrapper->Put(key2, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ blink::mojom::StorageAreaPtr area;
+ context()->OpenLocalStorage(origin1, MakeRequest(&area));
+ area->Put(key1, value, base::nullopt, "source", base::DoNothing());
+ area->Put(key2, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
- context()->OpenLocalStorage(origin2, MakeRequest(&wrapper));
- wrapper->Put(key2, value, base::nullopt, "source", base::DoNothing());
- wrapper.reset();
+ context()->OpenLocalStorage(origin2, MakeRequest(&area));
+ area->Put(key2, value, base::nullopt, "source", base::DoNothing());
+ area.reset();
// Make sure all data gets committed to the DB.
base::RunLoop().RunUntilIdle();
@@ -756,36 +756,36 @@ class LocalStorageContextMojoTestWithService
void DoTestPut(LocalStorageContextMojo* context,
const std::vector<uint8_t>& key,
const std::vector<uint8_t>& value) {
- mojom::LevelDBWrapperPtr wrapper;
+ blink::mojom::StorageAreaPtr area;
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",
- test::MakeSuccessCallback(run_loop.QuitClosure(), &success));
+ MakeRequest(&area));
+ area->Put(key, value, base::nullopt, "source",
+ test::MakeSuccessCallback(run_loop.QuitClosure(), &success));
run_loop.Run();
EXPECT_TRUE(success);
- wrapper.reset();
- base::RunLoop().RunUntilIdle();
+ area.reset();
+ RunUntilIdle();
}
bool DoTestGet(LocalStorageContextMojo* context,
const std::vector<uint8_t>& key,
std::vector<uint8_t>* result) {
- mojom::LevelDBWrapperPtr wrapper;
+ blink::mojom::StorageAreaPtr area;
context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
+ MakeRequest(&area));
base::RunLoop run_loop;
- std::vector<content::mojom::KeyValuePtr> data;
- leveldb::mojom::DatabaseError status;
+ std::vector<blink::mojom::KeyValuePtr> data;
+ bool success = false;
bool done = false;
- wrapper->GetAll(
+ area->GetAll(
test::GetAllCallback::CreateAndBind(&done, run_loop.QuitClosure()),
- test::MakeGetAllCallback(&status, &data));
+ test::MakeGetAllCallback(&success, &data));
run_loop.Run();
EXPECT_TRUE(done);
- EXPECT_EQ(status, leveldb::mojom::DatabaseError::OK);
+ EXPECT_TRUE(success);
for (auto& entry : data) {
if (key == entry->key) {
@@ -805,6 +805,15 @@ class LocalStorageContextMojoTestWithService
}
private:
+ // testing::Test:
+ void TearDown() override {
+ // Some of these tests close message pipes which serve as master interfaces
+ // to other associated interfaces; this in turn schedules tasks to invoke
+ // the associated interfaces' error handlers, and local storage code relies
+ // on those handlers running in order to avoid memory leaks at shutdown.
+ RunUntilIdle();
+ }
+
DISALLOW_COPY_AND_ASSIGN(LocalStorageContextMojoTestWithService);
};
@@ -815,9 +824,9 @@ TEST_F(LocalStorageContextMojoTestWithService, InMemory) {
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
- mojom::LevelDBWrapperPtr wrapper;
+ blink::mojom::StorageAreaPtr area;
context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
+ MakeRequest(&area));
DoTestPut(context, key, value);
std::vector<uint8_t> result;
EXPECT_TRUE(DoTestGet(context, key, &result));
@@ -825,7 +834,7 @@ TEST_F(LocalStorageContextMojoTestWithService, InMemory) {
context->ShutdownAndDelete();
context = nullptr;
- base::RunLoop().RunUntilIdle();
+ RunUntilIdle();
// Should not have created any files.
EXPECT_TRUE(FirstEntryInDir().empty());
@@ -845,9 +854,9 @@ TEST_F(LocalStorageContextMojoTestWithService, InMemoryInvalidPath) {
auto key = StdStringToUint8Vector("key");
auto value = StdStringToUint8Vector("value");
- mojom::LevelDBWrapperPtr wrapper;
+ blink::mojom::StorageAreaPtr area;
context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
+ MakeRequest(&area));
DoTestPut(context, key, value);
std::vector<uint8_t> result;
@@ -856,7 +865,7 @@ TEST_F(LocalStorageContextMojoTestWithService, InMemoryInvalidPath) {
context->ShutdownAndDelete();
context = nullptr;
- base::RunLoop().RunUntilIdle();
+ RunUntilIdle();
// Should not have created any files.
EXPECT_TRUE(FirstEntryInDir().empty());
@@ -877,7 +886,7 @@ TEST_F(LocalStorageContextMojoTestWithService, OnDisk) {
context->ShutdownAndDelete();
context = nullptr;
- base::RunLoop().RunUntilIdle();
+ RunUntilIdle();
// Should have created files.
EXPECT_EQ(test_path, FirstEntryInDir().BaseName());
@@ -908,7 +917,7 @@ TEST_F(LocalStorageContextMojoTestWithService, InvalidVersionOnDisk) {
context->ShutdownAndDelete();
context = nullptr;
- base::RunLoop().RunUntilIdle();
+ RunUntilIdle();
{
// Mess up version number in database.
@@ -933,7 +942,7 @@ TEST_F(LocalStorageContextMojoTestWithService, InvalidVersionOnDisk) {
context->ShutdownAndDelete();
context = nullptr;
- base::RunLoop().RunUntilIdle();
+ RunUntilIdle();
// Data should have been preserved now.
context = new LocalStorageContextMojo(base::ThreadTaskRunnerHandle::Get(),
@@ -961,9 +970,7 @@ TEST_F(LocalStorageContextMojoTestWithService, CorruptionOnDisk) {
context->ShutdownAndDelete();
context = nullptr;
- base::RunLoop().RunUntilIdle();
- // Also flush Task Scheduler tasks to make sure the leveldb is fully closed.
- content::RunAllTasksUntilIdle();
+ RunUntilIdle();
// Delete manifest files to mess up opening DB.
base::FilePath db_path =
@@ -986,7 +993,7 @@ TEST_F(LocalStorageContextMojoTestWithService, CorruptionOnDisk) {
context->ShutdownAndDelete();
context = nullptr;
- base::RunLoop().RunUntilIdle();
+ RunUntilIdle();
// Data should have been preserved now.
context = new LocalStorageContextMojo(base::ThreadTaskRunnerHandle::Get(),
@@ -1019,26 +1026,26 @@ TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
// Open three connections to the database. Two to the same origin, and a third
// to a different origin.
- mojom::LevelDBWrapperPtr wrapper1;
- mojom::LevelDBWrapperPtr wrapper2;
- mojom::LevelDBWrapperPtr wrapper3;
+ blink::mojom::StorageAreaPtr area1;
+ blink::mojom::StorageAreaPtr area2;
+ blink::mojom::StorageAreaPtr area3;
{
base::RunLoop loop;
mock_leveldb_service.SetOnOpenCallback(loop.QuitClosure());
context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
- MakeRequest(&wrapper1));
+ MakeRequest(&area1));
context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
- MakeRequest(&wrapper2));
+ MakeRequest(&area2));
context->OpenLocalStorage(url::Origin::Create(GURL("http://example.com")),
- MakeRequest(&wrapper3));
+ MakeRequest(&area3));
loop.Run();
}
// Add observers to the first two connections.
TestLevelDBObserver observer1;
- wrapper1->AddObserver(observer1.Bind());
+ area1->AddObserver(observer1.Bind());
TestLevelDBObserver observer2;
- wrapper2->AddObserver(observer2.Bind());
+ area2->AddObserver(observer2.Bind());
// Verify one attempt was made to open the database, and connect that request
// with a database implementation that always fails on write.
@@ -1060,22 +1067,22 @@ TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
// a lot of data on the first origin. This put operation should result in a
// pending commit that will get cancelled when the database connection is
// closed.
- wrapper3->Put(key, value, base::nullopt, "source",
- base::BindOnce([](bool success) { EXPECT_TRUE(success); }));
+ area3->Put(key, value, base::nullopt, "source",
+ base::BindOnce([](bool success) { EXPECT_TRUE(success); }));
// Repeatedly write data to the database, to trigger enough commit errors.
size_t values_written = 0;
- while (!wrapper1.encountered_error()) {
+ while (!area1.encountered_error()) {
base::RunLoop put_loop;
// Every write needs to be different to make sure there actually is a
// change to commit.
value[0]++;
- wrapper1.set_connection_error_handler(put_loop.QuitClosure());
- wrapper1->Put(key, value, base::nullopt, "source",
- base::BindLambdaForTesting([&](bool success) {
- EXPECT_TRUE(success);
- put_loop.Quit();
- }));
+ area1.set_connection_error_handler(put_loop.QuitClosure());
+ area1->Put(key, value, base::nullopt, "source",
+ base::BindLambdaForTesting([&](bool success) {
+ EXPECT_TRUE(success);
+ put_loop.Quit();
+ }));
put_loop.RunUntilIdle();
values_written++;
// And we need to flush after every change. Otherwise changes get batched up
@@ -1092,24 +1099,24 @@ TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
// connection to the database to have been severed.
EXPECT_FALSE(mock_db);
- // The connection to the second wrapper should have closed as well.
- EXPECT_TRUE(wrapper2.encountered_error());
+ // The connection to the second area should have closed as well.
+ EXPECT_TRUE(area2.encountered_error());
// And the old database should have been destroyed.
EXPECT_EQ(1u, mock_leveldb_service.destroy_requests().size());
- // Reconnect wrapper1 to the database, and try to read a value.
+ // Reconnect area1 to the database, and try to read a value.
context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
- MakeRequest(&wrapper1));
+ MakeRequest(&area1));
base::RunLoop delete_loop;
bool success = true;
TestLevelDBObserver observer3;
- wrapper1->AddObserver(observer3.Bind());
- wrapper1->Delete(key, base::nullopt, "source",
- base::BindLambdaForTesting([&](bool success_in) {
- success = success_in;
- delete_loop.Quit();
- }));
+ area1->AddObserver(observer3.Bind());
+ area1->Delete(key, base::nullopt, "source",
+ base::BindLambdaForTesting([&](bool success_in) {
+ success = success_in;
+ delete_loop.Quit();
+ }));
// Wait for LocalStorageContextMojo to try to reconnect to the database, and
// connect that new request to a properly functioning database.
@@ -1122,11 +1129,11 @@ TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
std::move(reopen_request.callback).Run(leveldb::mojom::DatabaseError::OK);
mock_leveldb_service.open_requests().clear();
- // And deleting the value from the new wrapper should have failed (as the
+ // And deleting the value from the new area should have failed (as the
// database is empty).
delete_loop.Run();
EXPECT_EQ(0u, observer3.observations().size());
- wrapper1 = nullptr;
+ area1 = nullptr;
{
// Committing data should now work.
@@ -1168,12 +1175,12 @@ TEST_F(LocalStorageContextMojoTestWithService,
auto value = StdStringToUint8Vector("value");
// Open a connection to the database.
- mojom::LevelDBWrapperPtr wrapper;
+ blink::mojom::StorageAreaPtr area;
{
base::RunLoop loop;
mock_leveldb_service.SetOnOpenCallback(loop.QuitClosure());
context->OpenLocalStorage(url::Origin::Create(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
+ MakeRequest(&area));
loop.Run();
}
@@ -1195,17 +1202,17 @@ TEST_F(LocalStorageContextMojoTestWithService,
// Repeatedly write data to the database, to trigger enough commit errors.
base::Optional<std::vector<uint8_t>> old_value;
- while (!wrapper.encountered_error()) {
+ while (!area.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, old_value, "source",
- base::BindLambdaForTesting([&](bool success) {
- EXPECT_TRUE(success);
- put_loop.Quit();
- }));
+ area.set_connection_error_handler(put_loop.QuitClosure());
+ area->Put(key, value, old_value, "source",
+ base::BindLambdaForTesting([&](bool success) {
+ EXPECT_TRUE(success);
+ put_loop.Quit();
+ }));
old_value = std::vector<uint8_t>(value);
put_loop.RunUntilIdle();
// And we need to flush after every change. Otherwise changes get batched up
@@ -1237,23 +1244,23 @@ TEST_F(LocalStorageContextMojoTestWithService,
// The old database should also have been destroyed.
EXPECT_EQ(1u, mock_leveldb_service.destroy_requests().size());
- // Reconnect a wrapper to the database, and repeatedly write data to it again.
+ // Reconnect a area 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::Create(GURL("http://foobar.com")),
- MakeRequest(&wrapper));
+ MakeRequest(&area));
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, old_value, "source",
- base::BindLambdaForTesting([&](bool success) {
- EXPECT_TRUE(success);
- put_loop.Quit();
- }));
+ area.set_connection_error_handler(put_loop.QuitClosure());
+ area->Put(key, value, old_value, "source",
+ base::BindLambdaForTesting([&](bool success) {
+ EXPECT_TRUE(success);
+ put_loop.Quit();
+ }));
put_loop.RunUntilIdle();
old_value = value;
// And we need to flush after every change. Otherwise changes get batched up
@@ -1267,7 +1274,7 @@ TEST_F(LocalStorageContextMojoTestWithService,
if (mock_db)
mock_db->FlushForTesting();
EXPECT_TRUE(mock_db);
- EXPECT_FALSE(wrapper.encountered_error());
+ EXPECT_FALSE(area.encountered_error());
}
} // namespace content
diff --git a/chromium/content/browser/dom_storage/session_storage_leveldb_wrapper.cc b/chromium/content/browser/dom_storage/session_storage_area_impl.cc
index 2e20a45d2c3..0ba8ed4b9a6 100644
--- a/chromium/content/browser/dom_storage/session_storage_leveldb_wrapper.cc
+++ b/chromium/content/browser/dom_storage/session_storage_area_impl.cc
@@ -2,9 +2,11 @@
// 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_leveldb_wrapper.h"
+#include "content/browser/dom_storage/session_storage_area_impl.h"
#include "base/bind.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "content/browser/dom_storage/session_storage_data_map.h"
#include "content/common/dom_storage/dom_storage_types.h"
@@ -12,7 +14,7 @@
namespace content {
-SessionStorageLevelDBWrapper::SessionStorageLevelDBWrapper(
+SessionStorageAreaImpl::SessionStorageAreaImpl(
SessionStorageMetadata::NamespaceEntry namespace_entry,
url::Origin origin,
scoped_refptr<SessionStorageDataMap> data_map,
@@ -23,41 +25,47 @@ SessionStorageLevelDBWrapper::SessionStorageLevelDBWrapper(
register_new_map_callback_(std::move(register_new_map_callback)),
binding_(this) {}
-SessionStorageLevelDBWrapper::~SessionStorageLevelDBWrapper() {
+SessionStorageAreaImpl::~SessionStorageAreaImpl() {
if (binding_.is_bound())
shared_data_map_->RemoveBindingReference();
}
-void SessionStorageLevelDBWrapper::Bind(
- mojom::LevelDBWrapperAssociatedRequest request) {
- DCHECK(!IsBound());
- shared_data_map_->AddBindingReference();
+void SessionStorageAreaImpl::Bind(
+ blink::mojom::StorageAreaAssociatedRequest request) {
+ if (IsBound()) {
+ binding_.Unbind();
+ } else {
+ shared_data_map_->AddBindingReference();
+ }
binding_.Bind(std::move(request));
- binding_.set_connection_error_handler(
- base::BindOnce(&SessionStorageLevelDBWrapper::OnConnectionError,
- base::Unretained(this)));
+ binding_.set_connection_error_handler(base::BindOnce(
+ &SessionStorageAreaImpl::OnConnectionError, base::Unretained(this)));
}
-std::unique_ptr<SessionStorageLevelDBWrapper>
-SessionStorageLevelDBWrapper::Clone(
+std::unique_ptr<SessionStorageAreaImpl> SessionStorageAreaImpl::Clone(
SessionStorageMetadata::NamespaceEntry namespace_entry) {
DCHECK(namespace_entry_ != namespace_entry);
- return base::WrapUnique(new SessionStorageLevelDBWrapper(
+ return base::WrapUnique(new SessionStorageAreaImpl(
namespace_entry, origin_, shared_data_map_, register_new_map_callback_));
}
-// LevelDBWrapper:
-void SessionStorageLevelDBWrapper::AddObserver(
- mojom::LevelDBObserverAssociatedPtrInfo observer) {
- mojom::LevelDBObserverAssociatedPtr observer_ptr;
+void SessionStorageAreaImpl::NotifyObserversAllDeleted() {
+ observers_.ForAllPtrs([](blink::mojom::StorageAreaObserver* observer) {
+ // Renderer process expects |source| to always be two newline separated
+ // strings.
+ observer->AllDeleted("\n");
+ });
+}
+
+// blink::mojom::StorageArea:
+void SessionStorageAreaImpl::AddObserver(
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo observer) {
+ blink::mojom::StorageAreaObserverAssociatedPtr observer_ptr;
observer_ptr.Bind(std::move(observer));
- mojo::InterfacePtrSetElementId ptr_id =
- shared_data_map_->level_db_wrapper()->AddObserver(
- std::move(observer_ptr));
- observer_ptrs_.push_back(ptr_id);
+ observers_.AddPtr(std::move(observer_ptr));
}
-void SessionStorageLevelDBWrapper::Put(
+void SessionStorageAreaImpl::Put(
const std::vector<uint8_t>& key,
const std::vector<uint8_t>& value,
const base::Optional<std::vector<uint8_t>>& client_old_value,
@@ -67,11 +75,11 @@ void SessionStorageLevelDBWrapper::Put(
DCHECK_NE(0, shared_data_map_->map_data()->ReferenceCount());
if (shared_data_map_->map_data()->ReferenceCount() > 1)
CreateNewMap(NewMapType::FORKED, base::nullopt);
- shared_data_map_->level_db_wrapper()->Put(key, value, client_old_value,
- source, std::move(callback));
+ shared_data_map_->storage_area()->Put(key, value, client_old_value, source,
+ std::move(callback));
}
-void SessionStorageLevelDBWrapper::Delete(
+void SessionStorageAreaImpl::Delete(
const std::vector<uint8_t>& key,
const base::Optional<std::vector<uint8_t>>& client_old_value,
const std::string& source,
@@ -80,40 +88,40 @@ void SessionStorageLevelDBWrapper::Delete(
DCHECK_NE(0, shared_data_map_->map_data()->ReferenceCount());
if (shared_data_map_->map_data()->ReferenceCount() > 1)
CreateNewMap(NewMapType::FORKED, base::nullopt);
- shared_data_map_->level_db_wrapper()->Delete(key, client_old_value, source,
- std::move(callback));
+ shared_data_map_->storage_area()->Delete(key, client_old_value, source,
+ std::move(callback));
}
-void SessionStorageLevelDBWrapper::DeleteAll(const std::string& source,
- DeleteAllCallback callback) {
- DCHECK(IsBound());
- DCHECK_NE(0, shared_data_map_->map_data()->ReferenceCount());
+void SessionStorageAreaImpl::DeleteAll(const std::string& source,
+ DeleteAllCallback callback) {
+ // Note: This can be called by the Clear Browsing Data flow, and thus doesn't
+ // have to be bound.
if (shared_data_map_->map_data()->ReferenceCount() > 1) {
CreateNewMap(NewMapType::EMPTY_FROM_DELETE_ALL, source);
std::move(callback).Run(true);
return;
}
- shared_data_map_->level_db_wrapper()->DeleteAll(source, std::move(callback));
+ shared_data_map_->storage_area()->DeleteAll(source, std::move(callback));
}
-void SessionStorageLevelDBWrapper::Get(const std::vector<uint8_t>& key,
- GetCallback callback) {
+void SessionStorageAreaImpl::Get(const std::vector<uint8_t>& key,
+ GetCallback callback) {
DCHECK(IsBound());
DCHECK_NE(0, shared_data_map_->map_data()->ReferenceCount());
- shared_data_map_->level_db_wrapper()->Get(key, std::move(callback));
+ shared_data_map_->storage_area()->Get(key, std::move(callback));
}
-void SessionStorageLevelDBWrapper::GetAll(
- mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo complete_callback,
+void SessionStorageAreaImpl::GetAll(
+ blink::mojom::StorageAreaGetAllCallbackAssociatedPtrInfo complete_callback,
GetAllCallback callback) {
DCHECK(IsBound());
DCHECK_NE(0, shared_data_map_->map_data()->ReferenceCount());
- shared_data_map_->level_db_wrapper()->GetAll(std::move(complete_callback),
- std::move(callback));
+ shared_data_map_->storage_area()->GetAll(std::move(complete_callback),
+ std::move(callback));
}
// Note: this can be called after invalidation of the |namespace_entry_|.
-void SessionStorageLevelDBWrapper::OnConnectionError() {
+void SessionStorageAreaImpl::OnConnectionError() {
shared_data_map_->RemoveBindingReference();
// Make sure we totally unbind the binding - this doesn't seem to happen
// automatically on connection error. The bound status is used in the
@@ -122,23 +130,16 @@ void SessionStorageLevelDBWrapper::OnConnectionError() {
binding_.Unbind();
}
-void SessionStorageLevelDBWrapper::CreateNewMap(
+void SessionStorageAreaImpl::CreateNewMap(
NewMapType map_type,
const base::Optional<std::string>& delete_all_source) {
- std::vector<mojom::LevelDBObserverAssociatedPtr> ptrs_to_move;
- for (const mojo::InterfacePtrSetElementId& ptr_id : observer_ptrs_) {
- DCHECK(shared_data_map_->level_db_wrapper()->HasObserver(ptr_id));
- ptrs_to_move.push_back(
- shared_data_map_->level_db_wrapper()->RemoveObserver(ptr_id));
- }
- observer_ptrs_.clear();
shared_data_map_->RemoveBindingReference();
switch (map_type) {
case NewMapType::FORKED:
shared_data_map_ = SessionStorageDataMap::CreateClone(
shared_data_map_->listener(),
register_new_map_callback_.Run(namespace_entry_, origin_),
- shared_data_map_->level_db_wrapper());
+ shared_data_map_->storage_area());
break;
case NewMapType::EMPTY_FROM_DELETE_ALL: {
// The code optimizes the 'delete all' for shared maps by just creating
@@ -147,19 +148,11 @@ void SessionStorageLevelDBWrapper::CreateNewMap(
shared_data_map_ = SessionStorageDataMap::Create(
shared_data_map_->listener(),
register_new_map_callback_.Run(namespace_entry_, origin_),
- shared_data_map_->level_db_wrapper()->database());
- for (auto& ptr : ptrs_to_move) {
- ptr->AllDeleted(delete_all_source.value_or("\n"));
- }
+ shared_data_map_->storage_area()->database());
break;
}
}
shared_data_map_->AddBindingReference();
-
- for (auto& observer_ptr : ptrs_to_move) {
- observer_ptrs_.push_back(shared_data_map_->level_db_wrapper()->AddObserver(
- std::move(observer_ptr)));
- }
}
} // namespace content
diff --git a/chromium/content/browser/dom_storage/session_storage_leveldb_wrapper.h b/chromium/content/browser/dom_storage/session_storage_area_impl.h
index 0a856c8b05a..0cd28db8403 100644
--- a/chromium/content/browser/dom_storage/session_storage_leveldb_wrapper.h
+++ b/chromium/content/browser/dom_storage/session_storage_area_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_BROWSER_DOM_STORAGE_SESSION_STORAGE_LEVELDB_WRAPPER_H_
-#define CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_LEVELDB_WRAPPER_H_
+#ifndef CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_AREA_IMPL_H_
+#define CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_AREA_IMPL_H_
#include <vector>
@@ -11,9 +11,8 @@
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "content/browser/dom_storage/session_storage_metadata.h"
-#include "content/browser/leveldb_wrapper_impl.h"
+#include "content/browser/dom_storage/storage_area_impl.h"
#include "content/common/content_export.h"
-#include "content/common/leveldb_wrapper.mojom.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h"
#include "url/origin.h"
@@ -22,7 +21,7 @@ namespace content {
class SessionStorageDataMap;
// This class provides session storage access to the renderer by binding to the
-// LevelDBWrapper mojom interface. It represents the data stored for a
+// StorageArea mojom interface. It represents the data stored for a
// namespace-origin area.
//
// This class delegates calls to SessionStorageDataMap objects, and can share
@@ -30,42 +29,48 @@ class SessionStorageDataMap;
// cloning (copy-on-write). This should be done through the |Clone()| method and
// not manually.
//
+// Unlike regular observers, adding an observer to this class only notifies when
+// the whole area is deleted manually (not by using DeleteAll on this binding).
+// This can happen when clearing browser data.
+//
// During forking, this class is responsible for dealing with moving its
-// observers from the SessionStorageDataMap's LevelDBWrapper to the new forked
-// SessionStorageDataMap's LevelDBWrapper.
-class CONTENT_EXPORT SessionStorageLevelDBWrapper
- : public mojom::LevelDBWrapper {
+// observers from the SessionStorageDataMap's StorageArea to the new forked
+// SessionStorageDataMap's StorageArea.
+class CONTENT_EXPORT SessionStorageAreaImpl : public blink::mojom::StorageArea {
public:
using RegisterNewAreaMap =
base::RepeatingCallback<scoped_refptr<SessionStorageMetadata::MapData>(
SessionStorageMetadata::NamespaceEntry namespace_entry,
const url::Origin& origin)>;
- // Creates a wrapper for the given |namespace_entry|-|origin| data area. All
- // LevelDBWrapper calls are delegated to the |data_map|. The
+ // Creates a area for the given |namespace_entry|-|origin| data area. All
+ // StorageArea calls are delegated to the |data_map|. The
// |register_new_map_callback| is called when a shared |data_map| needs to be
// forked for the copy-on-write behavior and a new map needs to be registered.
- SessionStorageLevelDBWrapper(
- SessionStorageMetadata::NamespaceEntry namespace_entry,
- url::Origin origin,
- scoped_refptr<SessionStorageDataMap> data_map,
- RegisterNewAreaMap register_new_map_callback);
- ~SessionStorageLevelDBWrapper() override;
+ SessionStorageAreaImpl(SessionStorageMetadata::NamespaceEntry namespace_entry,
+ url::Origin origin,
+ scoped_refptr<SessionStorageDataMap> data_map,
+ RegisterNewAreaMap register_new_map_callback);
+ ~SessionStorageAreaImpl() override;
// Creates a shallow copy clone for the new namespace entry.
// This doesn't change the refcount of the underlying map - that operation
// must be done using SessionStorageMetadata::RegisterShallowClonedNamespace.
- std::unique_ptr<SessionStorageLevelDBWrapper> Clone(
+ std::unique_ptr<SessionStorageAreaImpl> Clone(
SessionStorageMetadata::NamespaceEntry namespace_entry);
- void Bind(mojom::LevelDBWrapperAssociatedRequest request);
+ void Bind(blink::mojom::StorageAreaAssociatedRequest request);
bool IsBound() const { return binding_.is_bound(); }
SessionStorageDataMap* data_map() { return shared_data_map_.get(); }
- // LevelDBWrapper:
- void AddObserver(mojom::LevelDBObserverAssociatedPtrInfo observer) override;
+ // Notifies all observers that this area was deleted.
+ void NotifyObserversAllDeleted();
+
+ // blink::mojom::StorageArea:
+ void AddObserver(
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo 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,
@@ -78,9 +83,9 @@ class CONTENT_EXPORT SessionStorageLevelDBWrapper
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;
+ void GetAll(blink::mojom::StorageAreaGetAllCallbackAssociatedPtrInfo
+ complete_callback,
+ GetAllCallback callback) override;
private:
void OnConnectionError();
@@ -95,12 +100,12 @@ class CONTENT_EXPORT SessionStorageLevelDBWrapper
scoped_refptr<SessionStorageDataMap> shared_data_map_;
RegisterNewAreaMap register_new_map_callback_;
- std::vector<mojo::InterfacePtrSetElementId> observer_ptrs_;
- mojo::AssociatedBinding<mojom::LevelDBWrapper> binding_;
+ mojo::AssociatedInterfacePtrSet<blink::mojom::StorageAreaObserver> observers_;
+ mojo::AssociatedBinding<blink::mojom::StorageArea> binding_;
- DISALLOW_COPY_AND_ASSIGN(SessionStorageLevelDBWrapper);
+ DISALLOW_COPY_AND_ASSIGN(SessionStorageAreaImpl);
};
} // namespace content
-#endif // CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_LEVELDB_WRAPPER_H_
+#endif // CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_AREA_IMPL_H_
diff --git a/chromium/content/browser/dom_storage/session_storage_leveldb_wrapper_unittest.cc b/chromium/content/browser/dom_storage/session_storage_area_impl_unittest.cc
index 6f768e0a050..7fdc77561d6 100644
--- a/chromium/content/browser/dom_storage/session_storage_leveldb_wrapper_unittest.cc
+++ b/chromium/content/browser/dom_storage/session_storage_area_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/dom_storage/session_storage_leveldb_wrapper.h"
+#include "content/browser/dom_storage/session_storage_area_impl.h"
#include "base/barrier_closure.h"
#include "base/bind.h"
@@ -21,10 +21,10 @@
#include "components/services/leveldb/public/interfaces/leveldb.mojom.h"
#include "content/browser/dom_storage/session_storage_data_map.h"
#include "content/browser/dom_storage/session_storage_metadata.h"
+#include "content/browser/dom_storage/test/storage_area_test_util.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/fake_leveldb_database.h"
#include "content/test/gmock_util.h"
-#include "content/test/leveldb_wrapper_test_util.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/bindings/strong_binding_set.h"
@@ -61,9 +61,9 @@ class MockListener : public SessionStorageDataMap::Listener {
MOCK_METHOD1(OnCommitResult, void(DatabaseError error));
};
-class SessionStorageLevelDBWrapperTest : public testing::Test {
+class SessionStorageAreaImplTest : public testing::Test {
public:
- SessionStorageLevelDBWrapperTest()
+ SessionStorageAreaImplTest()
: test_namespace_id1_(base::GenerateGUID()),
test_namespace_id2_(base::GenerateGUID()),
test_origin1_(url::Origin::Create(GURL("https://host1.com:1/"))),
@@ -75,7 +75,7 @@ class SessionStorageLevelDBWrapperTest : public testing::Test {
std::make_unique<leveldb::LevelDBServiceImpl>(std::move(file_runner)));
leveldb_service_->OpenInMemory(
- base::nullopt, "SessionStorageLevelDBWrapperTestDatabase",
+ base::nullopt, "SessionStorageAreaImplTestDatabase",
mojo::MakeRequest(&leveldb_database_), base::DoNothing());
leveldb_database_->Put(StdStringToUint8Vector("map-0-key1"),
@@ -89,7 +89,7 @@ class SessionStorageLevelDBWrapperTest : public testing::Test {
DCHECK(map_id->KeyPrefix() == StdStringToUint8Vector("map-0-"));
leveldb_database_->Write(std::move(save_operations), base::DoNothing());
}
- ~SessionStorageLevelDBWrapperTest() override = default;
+ ~SessionStorageAreaImplTest() override = default;
scoped_refptr<SessionStorageMetadata::MapData> RegisterNewAreaMap(
SessionStorageMetadata::NamespaceEntry namespace_entry,
@@ -101,11 +101,9 @@ class SessionStorageLevelDBWrapperTest : public testing::Test {
return map_data;
}
- SessionStorageLevelDBWrapper::RegisterNewAreaMap
- GetRegisterNewAreaMapCallback() {
- return base::BindRepeating(
- &SessionStorageLevelDBWrapperTest::RegisterNewAreaMap,
- base::Unretained(this));
+ SessionStorageAreaImpl::RegisterNewAreaMap GetRegisterNewAreaMapCallback() {
+ return base::BindRepeating(&SessionStorageAreaImplTest::RegisterNewAreaMap,
+ base::Unretained(this));
}
protected:
@@ -122,12 +120,12 @@ class SessionStorageLevelDBWrapperTest : public testing::Test {
};
} // namespace
-TEST_F(SessionStorageLevelDBWrapperTest, BasicUsage) {
+TEST_F(SessionStorageAreaImplTest, BasicUsage) {
EXPECT_CALL(listener_,
OnDataMapCreation(StdStringToUint8Vector("0"), testing::_))
.Times(1);
- auto ss_leveldb_impl = std::make_unique<SessionStorageLevelDBWrapper>(
+ auto ss_leveldb_impl = std::make_unique<SessionStorageAreaImpl>(
metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_), test_origin1_,
SessionStorageDataMap::Create(
&listener_,
@@ -136,28 +134,61 @@ TEST_F(SessionStorageLevelDBWrapperTest, BasicUsage) {
leveldb_database_.get()),
GetRegisterNewAreaMapCallback());
- mojom::LevelDBWrapperAssociatedPtr ss_leveldb;
+ blink::mojom::StorageAreaAssociatedPtr ss_leveldb;
ss_leveldb_impl->Bind(
mojo::MakeRequestAssociatedWithDedicatedPipe(&ss_leveldb));
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(ss_leveldb.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(ss_leveldb.get(), &data));
ASSERT_EQ(1ul, data.size());
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(StdStringToUint8Vector("key1"),
- StdStringToUint8Vector("data1"))));
+ data, blink::mojom::KeyValue::New(StdStringToUint8Vector("key1"),
+ StdStringToUint8Vector("data1"))));
EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
.Times(1);
}
-TEST_F(SessionStorageLevelDBWrapperTest, Cloning) {
+TEST_F(SessionStorageAreaImplTest, DoubleBind) {
EXPECT_CALL(listener_,
OnDataMapCreation(StdStringToUint8Vector("0"), testing::_))
.Times(1);
- auto ss_leveldb_impl1 = std::make_unique<SessionStorageLevelDBWrapper>(
+ auto ss_leveldb_impl = std::make_unique<SessionStorageAreaImpl>(
+ metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_), test_origin1_,
+ SessionStorageDataMap::Create(
+ &listener_,
+ metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_)
+ ->second[test_origin1_],
+ leveldb_database_.get()),
+ GetRegisterNewAreaMapCallback());
+
+ blink::mojom::StorageAreaAssociatedPtr ss_leveldb1;
+ base::RunLoop loop;
+ ss_leveldb_impl->Bind(
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&ss_leveldb1));
+ ss_leveldb1.set_connection_error_handler(loop.QuitClosure());
+ // Check that we can bind twice and get data from the second binding.
+ blink::mojom::StorageAreaAssociatedPtr ss_leveldb2;
+ ss_leveldb_impl->Bind(
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&ss_leveldb2));
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(ss_leveldb2.get(), &data));
+ ASSERT_EQ(1ul, data.size());
+
+ // Make sure the first binding was closed.
+ loop.Run();
+
+ EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
+ .Times(1);
+}
+
+TEST_F(SessionStorageAreaImplTest, Cloning) {
+ EXPECT_CALL(listener_,
+ OnDataMapCreation(StdStringToUint8Vector("0"), testing::_))
+ .Times(1);
+
+ auto ss_leveldb_impl1 = std::make_unique<SessionStorageAreaImpl>(
metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_), test_origin1_,
SessionStorageDataMap::Create(
&listener_,
@@ -176,10 +207,10 @@ TEST_F(SessionStorageLevelDBWrapperTest, Cloning) {
auto ss_leveldb_impl2 = ss_leveldb_impl1->Clone(
metadata_.GetOrCreateNamespaceEntry(test_namespace_id2_));
- mojom::LevelDBWrapperAssociatedPtr ss_leveldb1;
+ blink::mojom::StorageAreaAssociatedPtr ss_leveldb1;
ss_leveldb_impl1->Bind(
mojo::MakeRequestAssociatedWithDedicatedPipe(&ss_leveldb1));
- mojom::LevelDBWrapperAssociatedPtr ss_leveldb2;
+ blink::mojom::StorageAreaAssociatedPtr ss_leveldb2;
ss_leveldb_impl2->Bind(
mojo::MakeRequestAssociatedWithDedicatedPipe(&ss_leveldb2));
@@ -200,25 +231,23 @@ TEST_F(SessionStorageLevelDBWrapperTest, Cloning) {
EXPECT_NE(ss_leveldb_impl1->data_map(), ss_leveldb_impl2->data_map());
// Check map 1 data.
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(ss_leveldb1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(ss_leveldb1.get(), &data));
ASSERT_EQ(1ul, data.size());
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(StdStringToUint8Vector("key1"),
- StdStringToUint8Vector("data1"))));
+ data, blink::mojom::KeyValue::New(StdStringToUint8Vector("key1"),
+ StdStringToUint8Vector("data1"))));
// Check map 2 data.
data.clear();
- status = test::GetAllSync(ss_leveldb2.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ EXPECT_TRUE(test::GetAllSync(ss_leveldb2.get(), &data));
ASSERT_EQ(2ul, data.size());
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(StdStringToUint8Vector("key1"),
- StdStringToUint8Vector("data1"))));
+ data, blink::mojom::KeyValue::New(StdStringToUint8Vector("key1"),
+ StdStringToUint8Vector("data1"))));
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(StdStringToUint8Vector("key2"),
- StdStringToUint8Vector("data2"))));
+ data, blink::mojom::KeyValue::New(StdStringToUint8Vector("key2"),
+ StdStringToUint8Vector("data2"))));
EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
.Times(1);
@@ -229,12 +258,12 @@ TEST_F(SessionStorageLevelDBWrapperTest, Cloning) {
ss_leveldb_impl2 = nullptr;
}
-TEST_F(SessionStorageLevelDBWrapperTest, ObserverTransfer) {
+TEST_F(SessionStorageAreaImplTest, NotifyAllDeleted) {
EXPECT_CALL(listener_,
OnDataMapCreation(StdStringToUint8Vector("0"), testing::_))
.Times(1);
- auto ss_leveldb_impl1 = std::make_unique<SessionStorageLevelDBWrapper>(
+ auto ss_leveldb_impl1 = std::make_unique<SessionStorageAreaImpl>(
metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_), test_origin1_,
SessionStorageDataMap::Create(
&listener_,
@@ -243,77 +272,34 @@ TEST_F(SessionStorageLevelDBWrapperTest, ObserverTransfer) {
leveldb_database_.get()),
GetRegisterNewAreaMapCallback());
- // Create the mojo binding.
- mojom::LevelDBWrapperAssociatedPtr ss_leveldb1;
+ blink::mojom::StorageAreaAssociatedPtr ss_leveldb1;
ss_leveldb_impl1->Bind(
mojo::MakeRequestAssociatedWithDedicatedPipe(&ss_leveldb1));
- // Create the observer, and attach it to the mojo bound implementation.
testing::StrictMock<test::MockLevelDBObserver> mock_observer;
- mojo::AssociatedBinding<mojom::LevelDBObserver> observer_binding(
+ mojo::AssociatedBinding<blink::mojom::StorageAreaObserver> observer_binding(
&mock_observer);
- mojom::LevelDBObserverAssociatedPtrInfo observer_ptr_info;
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo observer_ptr_info;
observer_binding.Bind(mojo::MakeRequest(&observer_ptr_info));
ss_leveldb1->AddObserver(std::move(observer_ptr_info));
+ ss_leveldb1.FlushForTesting();
- // Perform a shallow clone.
- std::vector<leveldb::mojom::BatchedOperationPtr> save_operations;
- metadata_.RegisterShallowClonedNamespace(
- metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_),
- metadata_.GetOrCreateNamespaceEntry(test_namespace_id2_),
- &save_operations);
- leveldb_database_->Write(std::move(save_operations), base::DoNothing());
- auto ss_leveldb_impl2 = ss_leveldb_impl1->Clone(
- metadata_.GetOrCreateNamespaceEntry(test_namespace_id2_));
- mojom::LevelDBWrapperAssociatedPtr ss_leveldb2;
- ss_leveldb_impl2->Bind(
- mojo::MakeRequestAssociatedWithDedicatedPipe(&ss_leveldb2));
-
- // Wait for our future commits to finish.
- base::RunLoop commit_waiters;
- auto barrier = base::BarrierClosure(3, commit_waiters.QuitClosure());
- EXPECT_CALL(listener_, OnCommitResult(DatabaseError::OK))
- .Times(3)
- .WillRepeatedly(base::test::RunClosure(barrier));
-
- // Do a change on the new interface. There should be no observation.
- EXPECT_CALL(listener_,
- OnDataMapCreation(StdStringToUint8Vector("1"), testing::_))
- .Times(1);
- EXPECT_TRUE(test::PutSync(ss_leveldb2.get(), StdStringToUint8Vector("key2"),
- StdStringToUint8Vector("data2"), base::nullopt,
- ""));
- ss_leveldb_impl2->data_map()->level_db_wrapper()->ScheduleImmediateCommit();
-
- // Do a change on the old interface.
- EXPECT_CALL(mock_observer,
- KeyChanged(StdStringToUint8Vector("key1"),
- StdStringToUint8Vector("data2"),
- StdStringToUint8Vector("data1"), "ss_leveldb1"))
- .Times(1);
- EXPECT_TRUE(test::PutSync(ss_leveldb1.get(), StdStringToUint8Vector("key1"),
- StdStringToUint8Vector("data2"),
- StdStringToUint8Vector("data1"), "ss_leveldb1"));
- ss_leveldb_impl1->data_map()->level_db_wrapper()->ScheduleImmediateCommit();
-
- // Wait for the commits.
- commit_waiters.Run();
+ base::RunLoop loop;
+ EXPECT_CALL(mock_observer, AllDeleted("\n"))
+ .WillOnce(base::test::RunClosure(loop.QuitClosure()));
+ ss_leveldb_impl1->NotifyObserversAllDeleted();
+ loop.Run();
EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
.Times(1);
- EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("1")))
- .Times(1);
-
- ss_leveldb_impl1 = nullptr;
- ss_leveldb_impl2 = nullptr;
}
-TEST_F(SessionStorageLevelDBWrapperTest, DeleteAllOnShared) {
+TEST_F(SessionStorageAreaImplTest, DeleteAllOnShared) {
EXPECT_CALL(listener_,
OnDataMapCreation(StdStringToUint8Vector("0"), testing::_))
.Times(1);
- auto ss_leveldb_impl1 = std::make_unique<SessionStorageLevelDBWrapper>(
+ auto ss_leveldb_impl1 = std::make_unique<SessionStorageAreaImpl>(
metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_), test_origin1_,
SessionStorageDataMap::Create(
&listener_,
@@ -332,21 +318,23 @@ TEST_F(SessionStorageLevelDBWrapperTest, DeleteAllOnShared) {
auto ss_leveldb_impl2 = ss_leveldb_impl1->Clone(
metadata_.GetOrCreateNamespaceEntry(test_namespace_id2_));
- mojom::LevelDBWrapperAssociatedPtr ss_leveldb1;
+ blink::mojom::StorageAreaAssociatedPtr ss_leveldb1;
ss_leveldb_impl1->Bind(
mojo::MakeRequestAssociatedWithDedicatedPipe(&ss_leveldb1));
- mojom::LevelDBWrapperAssociatedPtr ss_leveldb2;
+ blink::mojom::StorageAreaAssociatedPtr ss_leveldb2;
ss_leveldb_impl2->Bind(
mojo::MakeRequestAssociatedWithDedicatedPipe(&ss_leveldb2));
// Same maps are used.
EXPECT_EQ(ss_leveldb_impl1->data_map(), ss_leveldb_impl2->data_map());
- // Create the observer, attach to the first namespace.
+ // Create the observer, attach to the first namespace, and verify we don't see
+ // any changes (see SessionStorageAreaImpl class comment about when observers
+ // are called).
testing::StrictMock<test::MockLevelDBObserver> mock_observer;
- mojo::AssociatedBinding<mojom::LevelDBObserver> observer_binding(
+ mojo::AssociatedBinding<blink::mojom::StorageAreaObserver> observer_binding(
&mock_observer);
- mojom::LevelDBObserverAssociatedPtrInfo observer_ptr_info;
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo observer_ptr_info;
observer_binding.Bind(mojo::MakeRequest(&observer_ptr_info));
ss_leveldb1->AddObserver(std::move(observer_ptr_info));
@@ -358,7 +346,6 @@ TEST_F(SessionStorageLevelDBWrapperTest, DeleteAllOnShared) {
// There should be no commits, as we don't actually have to change any data.
// |ss_leveldb_impl1| should just switch to a new, empty map.
EXPECT_CALL(listener_, OnCommitResult(DatabaseError::OK)).Times(0);
- EXPECT_CALL(mock_observer, AllDeleted("source")).Times(1);
EXPECT_TRUE(test::DeleteAllSync(ss_leveldb1.get(), "source"));
// The maps were forked on the above call.
@@ -373,4 +360,31 @@ TEST_F(SessionStorageLevelDBWrapperTest, DeleteAllOnShared) {
ss_leveldb_impl2 = nullptr;
}
+TEST_F(SessionStorageAreaImplTest, DeleteAllWithoutBinding) {
+ EXPECT_CALL(listener_,
+ OnDataMapCreation(StdStringToUint8Vector("0"), testing::_))
+ .Times(1);
+
+ auto ss_leveldb_impl1 = std::make_unique<SessionStorageAreaImpl>(
+ metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_), test_origin1_,
+ SessionStorageDataMap::Create(
+ &listener_,
+ metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_)
+ ->second[test_origin1_],
+ leveldb_database_.get()),
+ GetRegisterNewAreaMapCallback());
+
+ base::RunLoop loop;
+ EXPECT_CALL(listener_, OnCommitResult(DatabaseError::OK))
+ .WillOnce(base::test::RunClosure(loop.QuitClosure()));
+ EXPECT_TRUE(test::DeleteAllSync(ss_leveldb_impl1.get(), "source"));
+ ss_leveldb_impl1->data_map()->storage_area()->ScheduleImmediateCommit();
+ loop.Run();
+
+ EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
+ .Times(1);
+
+ ss_leveldb_impl1 = nullptr;
+}
+
} // namespace content
diff --git a/chromium/content/browser/dom_storage/session_storage_context_mojo.cc b/chromium/content/browser/dom_storage/session_storage_context_mojo.cc
index 0f4bf4aed6c..a3998a49115 100644
--- a/chromium/content/browser/dom_storage/session_storage_context_mojo.cc
+++ b/chromium/content/browser/dom_storage/session_storage_context_mojo.cc
@@ -22,9 +22,9 @@
#include "build/build_config.h"
#include "components/services/leveldb/public/cpp/util.h"
#include "components/services/leveldb/public/interfaces/leveldb.mojom.h"
-#include "content/browser/dom_storage/session_storage_leveldb_wrapper.h"
+#include "content/browser/dom_storage/session_storage_area_impl.h"
#include "content/browser/dom_storage/session_storage_namespace_impl_mojo.h"
-#include "content/browser/leveldb_wrapper_impl.h"
+#include "content/browser/dom_storage/storage_area_impl.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/public/browser/session_storage_usage_info.h"
#include "content/public/common/content_features.h"
@@ -94,9 +94,11 @@ void RecordSessionStorageCachePurgedHistogram(
SessionStorageContextMojo::SessionStorageContextMojo(
scoped_refptr<base::SequencedTaskRunner> memory_dump_task_runner,
service_manager::Connector* connector,
- base::Optional<base::FilePath> local_partition_directory,
+ BackingMode backing_mode,
+ base::FilePath local_partition_directory,
std::string leveldb_name)
: connector_(connector ? connector->Clone() : nullptr),
+ backing_mode_(backing_mode),
partition_directory_path_(std::move(local_partition_directory)),
leveldb_name_(std::move(leveldb_name)),
memory_dump_id_(base::StringPrintf("SessionStorage/0x%" PRIXPTR,
@@ -119,7 +121,7 @@ SessionStorageContextMojo::~SessionStorageContextMojo() {
void SessionStorageContextMojo::OpenSessionStorage(
int process_id,
const std::string& namespace_id,
- mojom::SessionStorageNamespaceRequest request) {
+ blink::mojom::SessionStorageNamespaceRequest request) {
if (connection_state_ != CONNECTION_FINISHED) {
RunWhenConnected(
base::BindOnce(&SessionStorageContextMojo::OpenSessionStorage,
@@ -128,7 +130,10 @@ void SessionStorageContextMojo::OpenSessionStorage(
return;
}
auto found = namespaces_.find(namespace_id);
- DCHECK(found != namespaces_.end()) << namespace_id;
+ if (found == namespaces_.end()) {
+ mojo::ReportBadMessage("Namespace not found: " + namespace_id);
+ return;
+ }
if (!found->second->IsPopulated() &&
!found->second->waiting_on_clone_population()) {
@@ -137,11 +142,11 @@ void SessionStorageContextMojo::OpenSessionStorage(
data_maps_);
}
- PurgeUnusedWrappersIfNeeded();
+ PurgeUnusedAreasIfNeeded();
found->second->Bind(std::move(request), process_id);
- size_t total_cache_size, unused_wrapper_count;
- GetStatistics(&total_cache_size, &unused_wrapper_count);
+ size_t total_cache_size, unused_area_count;
+ GetStatistics(&total_cache_size, &unused_area_count);
// Track the total sessionStorage cache size.
UMA_HISTOGRAM_COUNTS_100000("SessionStorageContext.CacheSizeInKB",
total_cache_size / 1024);
@@ -158,15 +163,42 @@ void SessionStorageContextMojo::CreateSessionNamespace(
void SessionStorageContextMojo::CloneSessionNamespace(
const std::string& namespace_id_to_clone,
- const std::string& clone_namespace_id) {
- if (namespaces_.find(clone_namespace_id) != namespaces_.end())
+ const std::string& clone_namespace_id,
+ CloneType clone_type) {
+ if (namespaces_.find(clone_namespace_id) != namespaces_.end()) {
+ // Non-immediate commits expect to be paired with a |Clone| from the mojo
+ // namespace object. If that clone has already happened, then we don't need
+ // to do anything here.
+ // However, immediate commits happen without a |Clone| from the mojo
+ // namespace object, so there should never be a namespace already populated
+ // for an immediate clone.
+ DCHECK_NE(clone_type, CloneType::kImmediate);
return;
+ }
std::unique_ptr<SessionStorageNamespaceImplMojo> namespace_impl =
CreateSessionStorageNamespaceImplMojo(clone_namespace_id);
- namespace_impl->SetWaitingForClonePopulation();
- namespaces_.emplace(
- std::make_pair(clone_namespace_id, std::move(namespace_impl)));
+ switch (clone_type) {
+ case CloneType::kImmediate: {
+ auto clone_from_ns = namespaces_.find(namespace_id_to_clone);
+ // If the namespace doesn't exist or it's not populated yet, just create
+ // an empty session storage.
+ if (clone_from_ns == namespaces_.end() ||
+ !clone_from_ns->second->IsPopulated()) {
+ break;
+ }
+ clone_from_ns->second->Clone(clone_namespace_id);
+ return;
+ }
+ case CloneType::kWaitForCloneOnNamespace:
+ namespace_impl->SetWaitingForClonePopulation();
+ break;
+ default:
+ NOTREACHED();
+ }
+ namespaces_.emplace(std::piecewise_construct,
+ std::forward_as_tuple(clone_namespace_id),
+ std::forward_as_tuple(std::move(namespace_impl)));
}
void SessionStorageContextMojo::DeleteSessionNamespace(
@@ -193,7 +225,7 @@ void SessionStorageContextMojo::Flush() {
return;
}
for (const auto& it : data_maps_)
- it.second->level_db_wrapper()->ScheduleImmediateCommit();
+ it.second->storage_area()->ScheduleImmediateCommit();
}
void SessionStorageContextMojo::GetStorageUsage(
@@ -229,7 +261,9 @@ void SessionStorageContextMojo::DeleteStorage(const url::Origin& origin,
return;
}
auto found = namespaces_.find(namespace_id);
- if (found != namespaces_.end()) {
+ if (found != namespaces_.end() &&
+ (found->second->IsPopulated() ||
+ found->second->waiting_on_clone_population())) {
found->second->RemoveOriginData(origin);
} else {
// If we don't have the namespace loaded, then we can delete it all
@@ -255,47 +289,47 @@ void SessionStorageContextMojo::ShutdownAndDelete() {
// Flush any uncommitted data.
for (const auto& it : data_maps_) {
- auto* wrapper = it.second->level_db_wrapper();
+ auto* area = it.second->storage_area();
LOCAL_HISTOGRAM_BOOLEAN(
"SessionStorageContext.ShutdownAndDelete.MaybeDroppedChanges",
- wrapper->has_pending_load_tasks());
- wrapper->ScheduleImmediateCommit();
+ area->has_pending_load_tasks());
+ area->ScheduleImmediateCommit();
// TODO(dmurph): Monitor the above histogram, and if dropping changes is
// common then handle that here.
- wrapper->CancelAllPendingRequests();
+ area->CancelAllPendingRequests();
}
OnShutdownComplete(leveldb::mojom::DatabaseError::OK);
}
void SessionStorageContextMojo::PurgeMemory() {
- size_t total_cache_size, unused_wrapper_count;
- GetStatistics(&total_cache_size, &unused_wrapper_count);
+ size_t total_cache_size, unused_area_count;
+ GetStatistics(&total_cache_size, &unused_area_count);
- // Purge all wrappers that don't have bindings.
- for (auto it = namespaces_.begin(); it != namespaces_.end();) {
- if (!it->second->IsBound()) {
- it = namespaces_.erase(it);
- continue;
- }
- it->second->PurgeUnboundWrappers();
+ // Purge all areas that don't have bindings.
+ for (const auto& namespace_pair : namespaces_) {
+ namespace_pair.second->PurgeUnboundAreas();
+ }
+ // Purge memory from bound maps.
+ for (const auto& data_map_pair : data_maps_) {
+ data_map_pair.second->storage_area()->PurgeMemory();
}
// Track the size of cache purged.
size_t final_total_cache_size;
- GetStatistics(&final_total_cache_size, &unused_wrapper_count);
+ GetStatistics(&final_total_cache_size, &unused_area_count);
size_t purged_size_kib = (total_cache_size - final_total_cache_size) / 1024;
RecordSessionStorageCachePurgedHistogram(
SessionStorageCachePurgeReason::kAggressivePurgeTriggered,
purged_size_kib);
}
-void SessionStorageContextMojo::PurgeUnusedWrappersIfNeeded() {
- size_t total_cache_size, unused_wrapper_count;
- GetStatistics(&total_cache_size, &unused_wrapper_count);
+void SessionStorageContextMojo::PurgeUnusedAreasIfNeeded() {
+ size_t total_cache_size, unused_area_count;
+ GetStatistics(&total_cache_size, &unused_area_count);
// Nothing to purge.
- if (!unused_wrapper_count)
+ if (!unused_area_count)
return;
SessionStorageCachePurgeReason purge_reason =
@@ -311,18 +345,15 @@ void SessionStorageContextMojo::PurgeUnusedWrappersIfNeeded() {
if (purge_reason == SessionStorageCachePurgeReason::kNotNeeded)
return;
- // Purge all wrappers that don't have bindings.
- for (auto it = namespaces_.begin(); it != namespaces_.end();) {
- if (!it->second->IsBound())
- it = namespaces_.erase(it);
+ // Purge all areas that don't have bindings.
+ for (const auto& namespace_pair : namespaces_) {
+ namespace_pair.second->PurgeUnboundAreas();
}
size_t final_total_cache_size;
- GetStatistics(&final_total_cache_size, &unused_wrapper_count);
+ GetStatistics(&final_total_cache_size, &unused_area_count);
size_t purged_size_kib = (total_cache_size - final_total_cache_size) / 1024;
- RecordSessionStorageCachePurgedHistogram(
- SessionStorageCachePurgeReason::kAggressivePurgeTriggered,
- purged_size_kib);
+ RecordSessionStorageCachePurgedHistogram(purge_reason, purged_size_kib);
}
void SessionStorageContextMojo::ScavengeUnusedNamespaces(
@@ -381,8 +412,8 @@ bool SessionStorageContextMojo::OnMemoryDump(
if (args.level_of_detail ==
base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND) {
- size_t total_cache_size, unused_wrapper_count;
- GetStatistics(&total_cache_size, &unused_wrapper_count);
+ size_t total_cache_size, unused_area_count;
+ GetStatistics(&total_cache_size, &unused_area_count);
auto* mad = pmd->CreateAllocatorDump(context_name + "/cache_size");
mad->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
base::trace_event::MemoryAllocatorDump::kUnitsBytes,
@@ -400,10 +431,10 @@ bool SessionStorageContextMojo::OnMemoryDump(
if (!std::isalnum(url[index]))
url[index] = '_';
}
- std::string wrapper_dump_name = base::StringPrintf(
+ std::string area_dump_name = base::StringPrintf(
"%s/%s/0x%" PRIXPTR, context_name.c_str(), url.c_str(),
- reinterpret_cast<uintptr_t>(it.second->level_db_wrapper()));
- it.second->level_db_wrapper()->OnMemoryDump(wrapper_dump_name, pmd);
+ reinterpret_cast<uintptr_t>(it.second->storage_area()));
+ it.second->storage_area()->OnMemoryDump(area_dump_name, pmd);
}
return true;
}
@@ -442,8 +473,8 @@ void SessionStorageContextMojo::OnCommitResult(
}
tried_to_recover_from_commit_errors_ = true;
- // Deleting LevelDBWrappers in here could cause more commits (and commit
- // errors), but those commits won't reach OnCommitResult because the wrapper
+ // Deleting StorageAreas in here could cause more commits (and commit
+ // errors), but those commits won't reach OnCommitResult because the area
// will have been deleted before the commit finishes.
DeleteAndRecreateDatabase(
"SessionStorageContext.OpenResultAfterCommitErrors");
@@ -488,6 +519,17 @@ void SessionStorageContextMojo::RegisterShallowClonedNamespace(
const std::string& new_namespace_id,
const SessionStorageNamespaceImplMojo::OriginAreas& clone_from_areas) {
std::vector<leveldb::mojom::BatchedOperationPtr> save_operations;
+
+ bool found = false;
+ auto it = namespaces_.find(new_namespace_id);
+ if (it != namespaces_.end()) {
+ found = true;
+ if (it->second->IsPopulated()) {
+ mojo::ReportBadMessage("Cannot clone to already populated namespace");
+ return;
+ }
+ }
+
SessionStorageMetadata::NamespaceEntry namespace_entry =
metadata_.GetOrCreateNamespaceEntry(new_namespace_id);
metadata_.RegisterShallowClonedNamespace(source_namespace_entry,
@@ -496,8 +538,7 @@ void SessionStorageContextMojo::RegisterShallowClonedNamespace(
base::BindOnce(&SessionStorageContextMojo::OnCommitResult,
base::Unretained(this)));
- auto it = namespaces_.find(new_namespace_id);
- if (it != namespaces_.end()) {
+ if (found) {
it->second->PopulateAsClone(database_.get(), namespace_entry,
clone_from_areas);
return;
@@ -506,8 +547,9 @@ void SessionStorageContextMojo::RegisterShallowClonedNamespace(
auto namespace_impl = CreateSessionStorageNamespaceImplMojo(new_namespace_id);
namespace_impl->PopulateAsClone(database_.get(), namespace_entry,
clone_from_areas);
- namespaces_.emplace(
- std::make_pair(new_namespace_id, std::move(namespace_impl)));
+ namespaces_.emplace(std::piecewise_construct,
+ std::forward_as_tuple(new_namespace_id),
+ std::forward_as_tuple(std::move(namespace_impl)));
}
std::unique_ptr<SessionStorageNamespaceImplMojo>
@@ -517,7 +559,7 @@ SessionStorageContextMojo::CreateSessionStorageNamespaceImplMojo(
add_namespace_callback = base::BindRepeating(
&SessionStorageContextMojo::RegisterShallowClonedNamespace,
base::Unretained(this));
- SessionStorageLevelDBWrapper::RegisterNewAreaMap map_id_callback =
+ SessionStorageAreaImpl::RegisterNewAreaMap map_id_callback =
base::BindRepeating(&SessionStorageContextMojo::RegisterNewAreaMap,
base::Unretained(this));
@@ -537,21 +579,25 @@ void SessionStorageContextMojo::DoDatabaseDelete(
}
void SessionStorageContextMojo::RunWhenConnected(base::OnceClosure callback) {
- DCHECK_NE(connection_state_, CONNECTION_SHUTDOWN);
-
- // If we don't have a filesystem_connection_, we'll need to establish one.
- if (connection_state_ == NO_CONNECTION) {
- connection_state_ = CONNECTION_IN_PROGRESS;
- InitiateConnection();
- }
-
- if (connection_state_ == CONNECTION_IN_PROGRESS) {
- // Queue this OpenSessionStorage call for when we have a level db pointer.
- on_database_opened_callbacks_.push_back(std::move(callback));
- return;
+ switch (connection_state_) {
+ case NO_CONNECTION:
+ // If we don't have a filesystem_connection_, we'll need to establish one.
+ connection_state_ = CONNECTION_IN_PROGRESS;
+ on_database_opened_callbacks_.push_back(std::move(callback));
+ InitiateConnection();
+ return;
+ case CONNECTION_IN_PROGRESS:
+ // Queue this OpenSessionStorage call for when we have a level db pointer.
+ on_database_opened_callbacks_.push_back(std::move(callback));
+ return;
+ case CONNECTION_SHUTDOWN:
+ NOTREACHED();
+ return;
+ case CONNECTION_FINISHED:
+ std::move(callback).Run();
+ return;
}
-
- std::move(callback).Run();
+ NOTREACHED();
}
void SessionStorageContextMojo::InitiateConnection(bool in_memory_only) {
@@ -563,12 +609,12 @@ void SessionStorageContextMojo::InitiateConnection(bool in_memory_only) {
return;
}
- if (partition_directory_path_ && !in_memory_only) {
+ if (backing_mode_ != BackingMode::kNoDisk && !in_memory_only) {
// We were given a subdirectory to write to. Get it and use a disk backed
// database.
connector_->BindInterface(file::mojom::kServiceName, &file_system_);
file_system_->GetSubDirectory(
- partition_directory_path_.value().AsUTF8Unsafe(),
+ partition_directory_path_.AsUTF8Unsafe(),
MakeRequest(&partition_directory_),
base::BindOnce(&SessionStorageContextMojo::OnDirectoryOpened,
weak_ptr_factory_.GetWeakPtr()));
@@ -585,7 +631,7 @@ void SessionStorageContextMojo::InitiateConnection(bool in_memory_only) {
void SessionStorageContextMojo::OnDirectoryOpened(base::File::Error err) {
if (err != base::File::FILE_OK) {
// We failed to open the directory; continue with startup so that we create
- // the |level_db_wrappers_|.
+ // the data maps.
UMA_HISTOGRAM_ENUMERATION("SessionStorageContext.DirectoryOpenError", -err,
-base::File::FILE_ERROR_MAX);
LogDatabaseOpenResult(OpenResult::kDirectoryOpenFailed);
@@ -601,6 +647,14 @@ void SessionStorageContextMojo::OnDirectoryOpened(base::File::Error err) {
filesystem::mojom::DirectoryPtr partition_directory_clone;
partition_directory_->Clone(MakeRequest(&partition_directory_clone));
+ if (backing_mode_ == BackingMode::kClearDiskStateOnOpen) {
+ filesystem::mojom::DirectoryPtr partition_directory_clone_for_deletion;
+ partition_directory_->Clone(
+ MakeRequest(&partition_directory_clone_for_deletion));
+ leveldb_service_->Destroy(std::move(partition_directory_clone_for_deletion),
+ leveldb_name_, base::DoNothing());
+ }
+
leveldb_env::Options options;
options.create_if_missing = true;
options.max_open_files = 0; // use minimum
@@ -679,7 +733,6 @@ void SessionStorageContextMojo::OnGotDatabaseVersion(
"SessionStorageContext.OpenResultAfterReadVersionError");
return;
}
- connection_state_ = FETCHING_METADATA;
base::RepeatingClosure barrier = base::BarrierClosure(
2, base::BindOnce(&SessionStorageContextMojo::OnConnectionFinished,
@@ -706,7 +759,7 @@ void SessionStorageContextMojo::OnGotNamespaces(
std::vector<leveldb::mojom::BatchedOperationPtr> migration_operations,
leveldb::mojom::DatabaseError status,
std::vector<leveldb::mojom::KeyValuePtr> values) {
- DCHECK(connection_state_ == FETCHING_METADATA);
+ DCHECK_EQ(connection_state_, CONNECTION_IN_PROGRESS);
bool parsing_failure =
status == leveldb::mojom::DatabaseError::OK &&
!metadata_.ParseNamespaces(std::move(values), &migration_operations);
@@ -733,7 +786,7 @@ void SessionStorageContextMojo::OnGotNextMapId(
base::OnceClosure done,
leveldb::mojom::DatabaseError status,
const std::vector<uint8_t>& map_id) {
- DCHECK(connection_state_ == FETCHING_METADATA);
+ DCHECK_EQ(connection_state_, CONNECTION_IN_PROGRESS);
if (status == leveldb::mojom::DatabaseError::NOT_FOUND) {
std::move(done).Run();
return;
@@ -754,7 +807,7 @@ void SessionStorageContextMojo::OnGotNextMapId(
}
void SessionStorageContextMojo::OnConnectionFinished() {
- DCHECK(!database_ || connection_state_ == FETCHING_METADATA);
+ DCHECK(!database_ || connection_state_ == CONNECTION_IN_PROGRESS);
if (!database_) {
partition_directory_.reset();
file_system_.reset();
@@ -779,10 +832,10 @@ void SessionStorageContextMojo::OnConnectionFinished() {
void SessionStorageContextMojo::DeleteAndRecreateDatabase(
const char* histogram_name) {
- // We're about to set database_ to null, so delete the LevelDBWrappers
+ // We're about to set database_ to null, so delete the StorageAreas
// that might still be using the old database.
for (const auto& it : data_maps_)
- it.second->level_db_wrapper()->CancelAllPendingRequests();
+ it.second->storage_area()->CancelAllPendingRequests();
for (const auto& namespace_pair : namespaces_) {
namespace_pair.second->Reset();
@@ -790,7 +843,7 @@ void SessionStorageContextMojo::DeleteAndRecreateDatabase(
DCHECK(data_maps_.empty());
// Reset state to be in process of connecting. This will cause requests for
- // LevelDBWrappers to be queued until the connection is complete.
+ // StorageAreas to be queued until the connection is complete.
connection_state_ = CONNECTION_IN_PROGRESS;
commit_error_count_ = 0;
database_ = nullptr;
@@ -800,7 +853,7 @@ void SessionStorageContextMojo::DeleteAndRecreateDatabase(
// If tried to recreate database on disk already, try again but this time
// in memory.
- if (tried_to_recreate_during_open_ && !!partition_directory_path_) {
+ if (tried_to_recreate_during_open_ && backing_mode_ != BackingMode::kNoDisk) {
recreate_in_memory = true;
} else if (tried_to_recreate_during_open_) {
// Give up completely, run without any database.
@@ -849,13 +902,13 @@ void SessionStorageContextMojo::OnShutdownComplete(
}
void SessionStorageContextMojo::GetStatistics(size_t* total_cache_size,
- size_t* unused_wrapper_count) {
+ size_t* unused_area_count) {
*total_cache_size = 0;
- *unused_wrapper_count = 0;
+ *unused_area_count = 0;
for (const auto& it : data_maps_) {
- *total_cache_size += it.second->level_db_wrapper()->memory_used();
+ *total_cache_size += it.second->storage_area()->memory_used();
if (it.second->binding_count() == 0)
- (*unused_wrapper_count)++;
+ (*unused_area_count)++;
}
}
diff --git a/chromium/content/browser/dom_storage/session_storage_context_mojo.h b/chromium/content/browser/dom_storage/session_storage_context_mojo.h
index 6361d3a2bfd..9a4c3aa3d20 100644
--- a/chromium/content/browser/dom_storage/session_storage_context_mojo.h
+++ b/chromium/content/browser/dom_storage/session_storage_context_mojo.h
@@ -13,6 +13,7 @@
#include "base/callback_forward.h"
#include "base/files/file_path.h"
+#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
@@ -21,10 +22,9 @@
#include "content/browser/dom_storage/session_storage_metadata.h"
#include "content/browser/dom_storage/session_storage_namespace_impl_mojo.h"
#include "content/common/content_export.h"
-#include "content/common/leveldb_wrapper.mojom.h"
-#include "content/common/storage_partition_service.mojom.h"
#include "content/public/browser/session_storage_usage_info.h"
#include "services/file/public/mojom/file_system.mojom.h"
+#include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom.h"
#include "url/origin.h"
namespace base {
@@ -50,19 +50,44 @@ class CONTENT_EXPORT SessionStorageContextMojo
using GetStorageUsageCallback =
base::OnceCallback<void(std::vector<SessionStorageUsageInfo>)>;
+ enum class CloneType {
+ // Expect a clone to come from the SessionStorageNamespace mojo object. This
+ // guarantees ordering with any writes from that namespace.
+ kWaitForCloneOnNamespace,
+ // There will not be a clone coming from the SessionStorageNamespace mojo
+ // object, so clone immediately.
+ kImmediate
+ };
+
+ enum class BackingMode {
+ // Use an in-memory leveldb database to store our state.
+ kNoDisk,
+ // Use disk for the leveldb database, but clear its contents before we open
+ // it. This is used for platforms like Android where the session restore
+ // code is never used, ScavengeUnusedNamespace is never called, and old
+ // session storage data will never be reused.
+ kClearDiskStateOnOpen,
+ // Use disk for the leveldb database, restore all saved namespaces from
+ // disk. This assumes that ScavengeUnusedNamespace will eventually be called
+ // to clean up unused namespaces on disk.
+ kRestoreDiskState
+ };
+
SessionStorageContextMojo(
scoped_refptr<base::SequencedTaskRunner> task_runner,
service_manager::Connector* connector,
- base::Optional<base::FilePath> local_partition_directory,
+ BackingMode backing_option,
+ base::FilePath local_partition_directory,
std::string leveldb_name);
void OpenSessionStorage(int process_id,
const std::string& namespace_id,
- mojom::SessionStorageNamespaceRequest request);
+ blink::mojom::SessionStorageNamespaceRequest request);
void CreateSessionNamespace(const std::string& namespace_id);
void CloneSessionNamespace(const std::string& namespace_id_to_clone,
- const std::string& clone_namespace_id);
+ const std::string& clone_namespace_id,
+ CloneType clone_type);
void DeleteSessionNamespace(const std::string& namespace_id,
bool should_persist);
@@ -84,8 +109,8 @@ class CONTENT_EXPORT SessionStorageContextMojo
// storage for a particular origin will reload the data from the database.
void PurgeMemory();
- // Clears unused leveldb wrappers, when thresholds are reached.
- void PurgeUnusedWrappersIfNeeded();
+ // Clears unused storage areas, when thresholds are reached.
+ void PurgeUnusedAreasIfNeeded();
// Any namespaces that have been loaded from disk and have not had a
// corresponding CreateSessionNamespace() call will be deleted. Called after
@@ -98,7 +123,7 @@ class CONTENT_EXPORT SessionStorageContextMojo
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
- // SessionStorageLevelDBWrapper::Listener implementation:
+ // SessionStorageAreaImpl::Listener implementation:
void OnDataMapCreation(const std::vector<uint8_t>& map_prefix,
SessionStorageDataMap* map) override;
void OnDataMapDestruction(const std::vector<uint8_t>& map_prefix) override;
@@ -116,6 +141,10 @@ class CONTENT_EXPORT SessionStorageContextMojo
const url::Origin& origin);
private:
+ friend class DOMStorageBrowserTest;
+ FRIEND_TEST_ALL_PREFIXES(SessionStorageContextMojoTest,
+ PurgeMemoryDoesNotCrashOrHang);
+
// Object deletion is done through |ShutdownAndDelete()|.
~SessionStorageContextMojo() override;
@@ -163,7 +192,7 @@ class CONTENT_EXPORT SessionStorageContextMojo
void OnShutdownComplete(leveldb::mojom::DatabaseError error);
- void GetStatistics(size_t* total_cache_size, size_t* unused_wrapper_count);
+ void GetStatistics(size_t* total_cache_size, size_t* unused_areas_count);
// These values are written to logs. New enum values can be added, but
// existing enums must never be renumbered or deleted and reused.
@@ -184,12 +213,12 @@ class CONTENT_EXPORT SessionStorageContextMojo
SessionStorageMetadata metadata_;
std::unique_ptr<service_manager::Connector> connector_;
- const base::Optional<base::FilePath> partition_directory_path_;
+ BackingMode backing_mode_;
+ base::FilePath partition_directory_path_;
std::string leveldb_name_;
enum ConnectionState {
NO_CONNECTION,
- FETCHING_METADATA,
CONNECTION_IN_PROGRESS,
CONNECTION_FINISHED,
CONNECTION_SHUTDOWN
diff --git a/chromium/content/browser/dom_storage/session_storage_context_mojo_unittest.cc b/chromium/content/browser/dom_storage/session_storage_context_mojo_unittest.cc
index 1b9ee547d47..f09686f30e9 100644
--- a/chromium/content/browser/dom_storage/session_storage_context_mojo_unittest.cc
+++ b/chromium/content/browser/dom_storage/session_storage_context_mojo_unittest.cc
@@ -21,11 +21,12 @@
#include "content/browser/dom_storage/test/fake_leveldb_database_error_on_write.h"
#include "content/browser/dom_storage/test/fake_leveldb_service.h"
#include "content/browser/dom_storage/test/mojo_test_with_file_service.h"
+#include "content/browser/dom_storage/test/storage_area_test_util.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "content/public/browser/session_storage_usage_info.h"
#include "content/public/common/content_features.h"
#include "content/public/test/test_utils.h"
-#include "content/test/leveldb_wrapper_test_util.h"
+#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "services/file/file_service.h"
#include "services/file/public/mojom/constants.mojom.h"
@@ -62,13 +63,27 @@ class SessionStorageContextMojoTest : public test::MojoTestWithFileService {
void SetUp() override {
features_.InitAndEnableFeature(features::kMojoSessionStorage);
+ mojo::core::SetDefaultProcessErrorCallback(base::BindRepeating(
+ &SessionStorageContextMojoTest::OnBadMessage, base::Unretained(this)));
+ }
+
+ void TearDown() override {
+ mojo::core::SetDefaultProcessErrorCallback(
+ mojo::core::ProcessErrorCallback());
+ }
+
+ void OnBadMessage(const std::string& reason) { bad_message_called_ = true; }
+
+ void SetBackingMode(SessionStorageContextMojo::BackingMode backing_mode) {
+ DCHECK(!context_);
+ backing_mode_ = backing_mode;
}
SessionStorageContextMojo* context() {
if (!context_) {
context_ = new SessionStorageContextMojo(
- base::SequencedTaskRunnerHandle::Get(), connector(), base::FilePath(),
- kSessionStorageDirectory);
+ base::SequencedTaskRunnerHandle::Get(), connector(), backing_mode_,
+ base::FilePath(), kSessionStorageDirectory);
}
return context_;
}
@@ -94,10 +109,10 @@ class SessionStorageContextMojoTest : public test::MojoTestWithFileService {
base::StringPiece value,
const std::string& source) {
context()->CreateSessionNamespace(namespace_id);
- mojom::SessionStorageNamespacePtr ss_namespace;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace;
context()->OpenSessionStorage(kTestProcessId, namespace_id,
mojo::MakeRequest(&ss_namespace));
- mojom::LevelDBWrapperAssociatedPtr leveldb;
+ blink::mojom::StorageAreaAssociatedPtr leveldb;
ss_namespace->OpenArea(origin, mojo::MakeRequest(&leveldb));
EXPECT_TRUE(test::PutSync(
leveldb.get(), leveldb::StringPieceToUint8Vector(key),
@@ -110,16 +125,15 @@ class SessionStorageContextMojoTest : public test::MojoTestWithFileService {
const url::Origin& origin,
base::StringPiece key) {
context()->CreateSessionNamespace(namespace_id);
- mojom::SessionStorageNamespacePtr ss_namespace;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace;
context()->OpenSessionStorage(kTestProcessId, namespace_id,
mojo::MakeRequest(&ss_namespace));
- mojom::LevelDBWrapperAssociatedPtr leveldb;
+ blink::mojom::StorageAreaAssociatedPtr leveldb;
ss_namespace->OpenArea(origin, mojo::MakeRequest(&leveldb));
// Use the GetAll interface because Gets are being removed.
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(leveldb.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb.get(), &data));
context()->DeleteSessionNamespace(namespace_id, true);
std::vector<uint8_t> key_as_bytes = leveldb::StringPieceToUint8Vector(key);
@@ -131,7 +145,12 @@ class SessionStorageContextMojoTest : public test::MojoTestWithFileService {
return base::nullopt;
}
+ protected:
+ bool bad_message_called_ = false;
+
private:
+ SessionStorageContextMojo::BackingMode backing_mode_ =
+ SessionStorageContextMojo::BackingMode::kRestoreDiskState;
base::test::ScopedFeatureList features_;
SessionStorageContextMojo* context_ = nullptr;
@@ -167,30 +186,31 @@ TEST_F(SessionStorageContextMojoTest, MigrationV0ToV1) {
context()->CreateSessionNamespace(namespace_id1);
context()->CreateSessionNamespace(namespace_id2);
- mojom::SessionStorageNamespacePtr ss_namespace1;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
context()->OpenSessionStorage(kTestProcessId, namespace_id1,
mojo::MakeRequest(&ss_namespace1));
- mojom::SessionStorageNamespacePtr ss_namespace2;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace2;
context()->OpenSessionStorage(kTestProcessId, namespace_id2,
mojo::MakeRequest(&ss_namespace2));
- mojom::LevelDBWrapperAssociatedPtr leveldb_n2_o1;
- mojom::LevelDBWrapperAssociatedPtr leveldb_n2_o2;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n2_o1;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n2_o2;
ss_namespace2->OpenArea(origin1, mojo::MakeRequest(&leveldb_n2_o1));
ss_namespace2->OpenArea(origin2, mojo::MakeRequest(&leveldb_n2_o2));
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(leveldb_n2_o1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_n2_o1.get(), &data));
// There should have been a migration to get rid of the "map-0-" refcount
// field.
EXPECT_EQ(2ul, data.size());
std::vector<uint8_t> key_as_vector =
StdStringToUint8Vector(base::UTF16ToUTF8(key));
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(key_as_vector, String16ToUint8Vector(value))));
+ data, blink::mojom::KeyValue::New(key_as_vector,
+ String16ToUint8Vector(value))));
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(key_as_vector, String16ToUint8Vector(value))));
+ data, blink::mojom::KeyValue::New(key_as_vector,
+ String16ToUint8Vector(value))));
}
TEST_F(SessionStorageContextMojoTest, StartupShutdownSave) {
@@ -198,17 +218,16 @@ TEST_F(SessionStorageContextMojoTest, StartupShutdownSave) {
url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
context()->CreateSessionNamespace(namespace_id1);
- mojom::SessionStorageNamespacePtr ss_namespace1;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
context()->OpenSessionStorage(kTestProcessId, namespace_id1,
mojo::MakeRequest(&ss_namespace1));
- mojom::LevelDBWrapperAssociatedPtr leveldb_n1_o1;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n1_o1;
ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
// Verify no data.
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(leveldb_n1_o1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
EXPECT_EQ(0ul, data.size());
// Put some data.
@@ -217,8 +236,7 @@ TEST_F(SessionStorageContextMojoTest, StartupShutdownSave) {
leveldb::StringPieceToUint8Vector("value1"), base::nullopt, "source1"));
// Verify data is there.
- status = test::GetAllSync(leveldb_n1_o1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ EXPECT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
EXPECT_EQ(1ul, data.size());
// Delete the namespace and shutdown the context, BUT persist the namespace so
@@ -233,8 +251,7 @@ TEST_F(SessionStorageContextMojoTest, StartupShutdownSave) {
ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
// The data from before should be here.
- status = test::GetAllSync(leveldb_n1_o1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ EXPECT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
EXPECT_EQ(1ul, data.size());
// Delete the namespace and shutdown the context and do not persist the data.
@@ -247,26 +264,64 @@ TEST_F(SessionStorageContextMojoTest, StartupShutdownSave) {
mojo::MakeRequest(&ss_namespace1));
ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
- // The data from before should be here.
- status = test::GetAllSync(leveldb_n1_o1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ // The data from before should not be here.
+ EXPECT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
EXPECT_EQ(0ul, data.size());
}
+TEST_F(SessionStorageContextMojoTest, CloneBeforeBrowserClone) {
+ std::string namespace_id1 = base::GenerateGUID();
+ std::string namespace_id2 = base::GenerateGUID();
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ context()->CreateSessionNamespace(namespace_id1);
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id1,
+ mojo::MakeRequest(&ss_namespace1));
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n1_o1;
+ ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
+
+ // Put some data.
+ EXPECT_TRUE(test::PutSync(
+ leveldb_n1_o1.get(), leveldb::StringPieceToUint8Vector("key1"),
+ leveldb::StringPieceToUint8Vector("value1"), base::nullopt, "source1"));
+
+ ss_namespace1->Clone(namespace_id2);
+ leveldb_n1_o1.FlushForTesting();
+
+ // Do the browser-side clone afterwards.
+ context()->CloneSessionNamespace(
+ namespace_id1, namespace_id2,
+ SessionStorageContextMojo::CloneType::kWaitForCloneOnNamespace);
+
+ // Open the second namespace.
+ blink::mojom::SessionStorageNamespacePtr ss_namespace2;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id2,
+ mojo::MakeRequest(&ss_namespace2));
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n2_o1;
+ ss_namespace2->OpenArea(origin1, mojo::MakeRequest(&leveldb_n2_o1));
+
+ // The data should be in namespace 2.
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_n2_o1.get(), &data));
+ EXPECT_EQ(1ul, data.size());
+}
+
TEST_F(SessionStorageContextMojoTest, Cloning) {
std::string namespace_id1 = base::GenerateGUID();
std::string namespace_id2 = base::GenerateGUID();
url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
context()->CreateSessionNamespace(namespace_id1);
- mojom::SessionStorageNamespacePtr ss_namespace1;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
context()->OpenSessionStorage(kTestProcessId, namespace_id1,
mojo::MakeRequest(&ss_namespace1));
- mojom::LevelDBWrapperAssociatedPtr leveldb_n1_o1;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n1_o1;
ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
// Context-triggered clone before the put. The clone doesn't actually count
// until a clone comes from the namespace.
- context()->CloneSessionNamespace(namespace_id1, namespace_id2);
+ context()->CloneSessionNamespace(
+ namespace_id1, namespace_id2,
+ SessionStorageContextMojo::CloneType::kWaitForCloneOnNamespace);
// Put some data.
EXPECT_TRUE(test::PutSync(
@@ -277,10 +332,10 @@ TEST_F(SessionStorageContextMojoTest, Cloning) {
leveldb_n1_o1.FlushForTesting();
// Open the second namespace.
- mojom::SessionStorageNamespacePtr ss_namespace2;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace2;
context()->OpenSessionStorage(kTestProcessId, namespace_id2,
mojo::MakeRequest(&ss_namespace2));
- mojom::LevelDBWrapperAssociatedPtr leveldb_n2_o1;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n2_o1;
ss_namespace2->OpenArea(origin1, mojo::MakeRequest(&leveldb_n2_o1));
// Delete the namespace and shutdown the context, BUT persist the namespace so
@@ -289,17 +344,15 @@ TEST_F(SessionStorageContextMojoTest, Cloning) {
context()->DeleteSessionNamespace(namespace_id1, true);
// The data from before should be in namespace 2.
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(leveldb_n2_o1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_n2_o1.get(), &data));
EXPECT_EQ(1ul, data.size());
// Put some data in namespace 2.
EXPECT_TRUE(test::PutSync(
leveldb_n2_o1.get(), leveldb::StringPieceToUint8Vector("key2"),
leveldb::StringPieceToUint8Vector("value2"), base::nullopt, "source1"));
- status = test::GetAllSync(leveldb_n2_o1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ EXPECT_TRUE(test::GetAllSync(leveldb_n2_o1.get(), &data));
EXPECT_EQ(2ul, data.size());
// Re-open namespace 1, check that we don't have the extra data.
@@ -309,11 +362,77 @@ TEST_F(SessionStorageContextMojoTest, Cloning) {
ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
// We should only have the first value.
- status = test::GetAllSync(leveldb_n1_o1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ EXPECT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
EXPECT_EQ(1ul, data.size());
}
+TEST_F(SessionStorageContextMojoTest, ImmediateCloning) {
+ std::string namespace_id1 = base::GenerateGUID();
+ std::string namespace_id2 = base::GenerateGUID();
+ std::string namespace_id3 = base::GenerateGUID();
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ context()->CreateSessionNamespace(namespace_id1);
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id1,
+ mojo::MakeRequest(&ss_namespace1));
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n1_o1;
+ ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
+
+ // Immediate clone.
+ context()->CloneSessionNamespace(
+ namespace_id1, namespace_id2,
+ SessionStorageContextMojo::CloneType::kImmediate);
+
+ // Open the second namespace, ensure empty.
+ {
+ blink::mojom::SessionStorageNamespacePtr ss_namespace2;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id2,
+ mojo::MakeRequest(&ss_namespace2));
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n2_o1;
+ ss_namespace2->OpenArea(origin1, mojo::MakeRequest(&leveldb_n2_o1));
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_n2_o1.get(), &data));
+ EXPECT_EQ(0ul, data.size());
+ }
+
+ // Delete that namespace, copy again after a put.
+ context()->DeleteSessionNamespace(namespace_id2, false);
+
+ // Put some data.
+ EXPECT_TRUE(test::PutSync(
+ leveldb_n1_o1.get(), leveldb::StringPieceToUint8Vector("key1"),
+ leveldb::StringPieceToUint8Vector("value2"), base::nullopt, "source1"));
+
+ context()->CloneSessionNamespace(
+ namespace_id1, namespace_id2,
+ SessionStorageContextMojo::CloneType::kImmediate);
+
+ // Open the second namespace, ensure populated
+ {
+ blink::mojom::SessionStorageNamespacePtr ss_namespace2;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id2,
+ mojo::MakeRequest(&ss_namespace2));
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n2_o1;
+ ss_namespace2->OpenArea(origin1, mojo::MakeRequest(&leveldb_n2_o1));
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_n2_o1.get(), &data));
+ EXPECT_EQ(1ul, data.size());
+ }
+
+ context()->DeleteSessionNamespace(namespace_id2, false);
+
+ // Verify that cloning from the namespace object will result in a bad message.
+ context()->CloneSessionNamespace(
+ namespace_id1, namespace_id2,
+ SessionStorageContextMojo::CloneType::kImmediate);
+
+ // This should cause a bad message.
+ ss_namespace1->Clone(namespace_id2);
+ leveldb_n1_o1.FlushForTesting();
+
+ EXPECT_TRUE(bad_message_called_);
+}
+
TEST_F(SessionStorageContextMojoTest, Scavenging) {
// Create our namespace, destroy our context and leave that namespace on disk,
// and verify that it is scavenged if we re-create the context without calling
@@ -327,6 +446,8 @@ TEST_F(SessionStorageContextMojoTest, Scavenging) {
// This scavenge call should NOT delete the namespace, as we just created it.
{
base::RunLoop loop;
+ // Cause the connection to start loading, so we start scavenging mid-load.
+ context()->Flush();
context()->ScavengeUnusedNamespaces(loop.QuitClosure());
loop.Run();
}
@@ -334,10 +455,10 @@ TEST_F(SessionStorageContextMojoTest, Scavenging) {
ShutdownContext();
context()->CreateSessionNamespace(namespace_id1);
- mojom::SessionStorageNamespacePtr ss_namespace1;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
context()->OpenSessionStorage(kTestProcessId, namespace_id1,
mojo::MakeRequest(&ss_namespace1));
- mojom::LevelDBWrapperAssociatedPtr leveldb_n1_o1;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n1_o1;
ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
EXPECT_TRUE(test::PutSync(
leveldb_n1_o1.get(), leveldb::StringPieceToUint8Vector("key1"),
@@ -371,9 +492,8 @@ TEST_F(SessionStorageContextMojoTest, Scavenging) {
context()->OpenSessionStorage(kTestProcessId, namespace_id1,
mojo::MakeRequest(&ss_namespace1));
ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(leveldb_n1_o1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
EXPECT_EQ(1ul, data.size());
// Shutting down the context without an explicit DeleteSessionNamespace should
@@ -391,8 +511,7 @@ TEST_F(SessionStorageContextMojoTest, Scavenging) {
context()->OpenSessionStorage(kTestProcessId, namespace_id1,
mojo::MakeRequest(&ss_namespace1));
ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
- status = test::GetAllSync(leveldb_n1_o1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ EXPECT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
EXPECT_EQ(0ul, data.size());
}
@@ -488,29 +607,22 @@ TEST_F(SessionStorageContextMojoTest, RecreateOnCommitFailure) {
base::Unretained(&fake_leveldb_service))));
// Open three connections to the database.
- mojom::LevelDBWrapperAssociatedPtr wrapper1;
- mojom::LevelDBWrapperAssociatedPtr wrapper2;
- mojom::LevelDBWrapperAssociatedPtr wrapper3;
- mojom::SessionStorageNamespacePtr ss_namespace;
+ blink::mojom::StorageAreaAssociatedPtr area1;
+ blink::mojom::StorageAreaAssociatedPtr area2;
+ blink::mojom::StorageAreaAssociatedPtr area3;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace;
context()->CreateSessionNamespace(namespace_id);
{
base::RunLoop loop;
fake_leveldb_service.SetOnOpenCallback(loop.QuitClosure());
context()->OpenSessionStorage(kTestProcessId, namespace_id,
mojo::MakeRequest(&ss_namespace));
- ss_namespace->OpenArea(origin1, mojo::MakeRequest(&wrapper1));
- ss_namespace->OpenArea(origin2, mojo::MakeRequest(&wrapper2));
- ss_namespace->OpenArea(origin3, mojo::MakeRequest(&wrapper3));
+ ss_namespace->OpenArea(origin1, mojo::MakeRequest(&area1));
+ ss_namespace->OpenArea(origin2, mojo::MakeRequest(&area2));
+ ss_namespace->OpenArea(origin3, mojo::MakeRequest(&area3));
loop.Run();
}
- // Add observers to the first two connections.
- testing::StrictMock<test::MockLevelDBObserver> observer1;
- wrapper1->AddObserver(observer1.Bind());
- EXPECT_FALSE(wrapper1.encountered_error());
- testing::StrictMock<test::MockLevelDBObserver> observer3;
- wrapper3->AddObserver(observer3.Bind());
-
// Verify one attempt was made to open the database, and connect that request
// with a database implementation that always fails on write.
ASSERT_EQ(1u, fake_leveldb_service.open_requests().size());
@@ -533,42 +645,27 @@ TEST_F(SessionStorageContextMojoTest, RecreateOnCommitFailure) {
// pending commit that will get cancelled when the database connection is
// closed.
auto value = leveldb::StringPieceToUint8Vector("avalue");
- EXPECT_CALL(observer3, KeyAdded(leveldb::StringPieceToUint8Vector("w3key"),
- value, "source"))
- .Times(1);
- wrapper3->Put(leveldb::StringPieceToUint8Vector("w3key"), value,
- base::nullopt, "source",
- base::BindOnce([](bool success) { EXPECT_TRUE(success); }));
+ area3->Put(leveldb::StringPieceToUint8Vector("w3key"), value, base::nullopt,
+ "source",
+ base::BindOnce([](bool success) { EXPECT_TRUE(success); }));
// Repeatedly write data to the database, to trigger enough commit errors.
int i = 0;
- while (!wrapper1.encountered_error()) {
+ while (!area1.encountered_error()) {
++i;
base::RunLoop put_loop;
// Every write needs to be different to make sure there actually is a
// change to commit.
std::vector<uint8_t> old_value = value;
value[0]++;
- wrapper1.set_connection_error_handler(put_loop.QuitClosure());
-
- if (i == 1) {
- EXPECT_CALL(observer1, ShouldSendOldValueOnMutations(false)).Times(1);
- EXPECT_CALL(observer1, KeyAdded(leveldb::StringPieceToUint8Vector("key"),
- value, "source"))
- .Times(1);
- } else {
- EXPECT_CALL(observer1,
- KeyChanged(leveldb::StringPieceToUint8Vector("key"), value,
- old_value, "source"))
- .Times(1);
- }
- wrapper1->Put(leveldb::StringPieceToUint8Vector("key"), value,
- base::nullopt, "source",
- base::BindLambdaForTesting([&](bool success) {
- EXPECT_TRUE(success);
- put_loop.Quit();
- }));
- wrapper1.FlushForTesting();
+ area1.set_connection_error_handler(put_loop.QuitClosure());
+
+ area1->Put(leveldb::StringPieceToUint8Vector("key"), value, base::nullopt,
+ "source", base::BindLambdaForTesting([&](bool success) {
+ EXPECT_TRUE(success);
+ put_loop.Quit();
+ }));
+ area1.FlushForTesting();
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.
@@ -583,27 +680,27 @@ TEST_F(SessionStorageContextMojoTest, RecreateOnCommitFailure) {
// connection to the database to have been severed.
EXPECT_FALSE(mock_db);
- // The connection to the second wrapper should have closed as well.
- EXPECT_TRUE(wrapper2.encountered_error());
+ // The connection to the second area should have closed as well.
+ EXPECT_TRUE(area2.encountered_error());
EXPECT_TRUE(ss_namespace.encountered_error());
// And the old database should have been destroyed.
EXPECT_EQ(1u, fake_leveldb_service.destroy_requests().size());
- // Reconnect wrapper1 to the database, and try to read a value.
+ // Reconnect area1 to the database, and try to read a value.
context()->OpenSessionStorage(kTestProcessId, namespace_id,
mojo::MakeRequest(&ss_namespace));
- ss_namespace->OpenArea(origin1, mojo::MakeRequest(&wrapper1));
+ ss_namespace->OpenArea(origin1, mojo::MakeRequest(&area1));
base::RunLoop delete_loop;
bool success = true;
test::MockLevelDBObserver observer4;
- wrapper1->AddObserver(observer4.Bind());
- wrapper1->Delete(leveldb::StringPieceToUint8Vector("key"), base::nullopt,
- "source", base::BindLambdaForTesting([&](bool success_in) {
- success = success_in;
- delete_loop.Quit();
- }));
+ area1->AddObserver(observer4.Bind());
+ area1->Delete(leveldb::StringPieceToUint8Vector("key"), base::nullopt,
+ "source", base::BindLambdaForTesting([&](bool success_in) {
+ success = success_in;
+ delete_loop.Quit();
+ }));
// Wait for LocalStorageContextMojo to try to reconnect to the database, and
// connect that new request to a properly functioning database.
@@ -616,10 +713,10 @@ TEST_F(SessionStorageContextMojoTest, RecreateOnCommitFailure) {
std::move(reopen_request.callback).Run(leveldb::mojom::DatabaseError::OK);
fake_leveldb_service.open_requests().clear();
- // And deleting the value from the new wrapper should have failed (as the
+ // And deleting the value from the new area should have failed (as the
// database is empty).
delete_loop.Run();
- wrapper1 = nullptr;
+ area1 = nullptr;
ss_namespace.reset();
context()->DeleteSessionNamespace(namespace_id, true);
@@ -647,15 +744,15 @@ TEST_F(SessionStorageContextMojoTest, DontRecreateOnRepeatedCommitFailure) {
std::map<std::vector<uint8_t>, std::vector<uint8_t>> test_data;
// Open three connections to the database.
- mojom::LevelDBWrapperAssociatedPtr wrapper;
- mojom::SessionStorageNamespacePtr ss_namespace;
+ blink::mojom::StorageAreaAssociatedPtr area;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace;
context()->CreateSessionNamespace(namespace_id);
{
base::RunLoop loop;
fake_leveldb_service.SetOnOpenCallback(loop.QuitClosure());
context()->OpenSessionStorage(kTestProcessId, namespace_id,
mojo::MakeRequest(&ss_namespace));
- ss_namespace->OpenArea(origin1, mojo::MakeRequest(&wrapper));
+ ss_namespace->OpenArea(origin1, mojo::MakeRequest(&area));
loop.Run();
}
@@ -678,17 +775,17 @@ TEST_F(SessionStorageContextMojoTest, DontRecreateOnRepeatedCommitFailure) {
// Repeatedly write data to the database, to trigger enough commit errors.
auto value = leveldb::StringPieceToUint8Vector("avalue");
base::Optional<std::vector<uint8_t>> old_value = base::nullopt;
- while (!wrapper.encountered_error()) {
+ while (!area.encountered_error()) {
base::RunLoop put_loop;
// Every write needs to be different to make sure there actually is a
// change to commit.
- wrapper.set_connection_error_handler(put_loop.QuitClosure());
- wrapper->Put(leveldb::StringPieceToUint8Vector("key"), value, old_value,
- "source", base::BindLambdaForTesting([&](bool success) {
- EXPECT_TRUE(success);
- put_loop.Quit();
- }));
- wrapper.FlushForTesting();
+ area.set_connection_error_handler(put_loop.QuitClosure());
+ area->Put(leveldb::StringPieceToUint8Vector("key"), value, old_value,
+ "source", base::BindLambdaForTesting([&](bool success) {
+ EXPECT_TRUE(success);
+ put_loop.Quit();
+ }));
+ area.FlushForTesting();
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.
@@ -721,24 +818,24 @@ TEST_F(SessionStorageContextMojoTest, DontRecreateOnRepeatedCommitFailure) {
// The old database should also have been destroyed.
EXPECT_EQ(1u, fake_leveldb_service.destroy_requests().size());
- // Reconnect a wrapper to the database, and repeatedly write data to it again.
+ // Reconnect a area 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()->OpenSessionStorage(kTestProcessId, namespace_id,
mojo::MakeRequest(&ss_namespace));
- ss_namespace->OpenArea(origin1, mojo::MakeRequest(&wrapper));
+ ss_namespace->OpenArea(origin1, mojo::MakeRequest(&area));
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.
- wrapper.set_connection_error_handler(put_loop.QuitClosure());
- wrapper->Put(leveldb::StringPieceToUint8Vector("key"), value, old_value,
- "source", base::BindLambdaForTesting([&](bool success) {
- EXPECT_TRUE(success);
- put_loop.Quit();
- }));
- wrapper.FlushForTesting();
+ area.set_connection_error_handler(put_loop.QuitClosure());
+ area->Put(leveldb::StringPieceToUint8Vector("key"), value, old_value,
+ "source", base::BindLambdaForTesting([&](bool success) {
+ EXPECT_TRUE(success);
+ put_loop.Quit();
+ }));
+ area.FlushForTesting();
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.
@@ -753,10 +850,233 @@ TEST_F(SessionStorageContextMojoTest, DontRecreateOnRepeatedCommitFailure) {
if (mock_db)
mock_db->FlushForTesting();
EXPECT_TRUE(mock_db);
- EXPECT_FALSE(wrapper.encountered_error());
+ EXPECT_FALSE(area.encountered_error());
context()->DeleteSessionNamespace(namespace_id, false);
}
+TEST_F(SessionStorageContextMojoTest, GetUsage) {
+ std::string namespace_id1 = base::GenerateGUID();
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ context()->CreateSessionNamespace(namespace_id1);
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id1,
+ mojo::MakeRequest(&ss_namespace1));
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n1_o1;
+ ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
+
+ // Put some data.
+ EXPECT_TRUE(test::PutSync(
+ leveldb_n1_o1.get(), leveldb::StringPieceToUint8Vector("key1"),
+ leveldb::StringPieceToUint8Vector("value1"), base::nullopt, "source1"));
+
+ base::RunLoop loop;
+ context()->GetStorageUsage(base::BindLambdaForTesting(
+ [&](std::vector<SessionStorageUsageInfo> usage) {
+ loop.Quit();
+ ASSERT_EQ(1u, usage.size());
+ EXPECT_EQ(origin1.GetURL(), usage[0].origin);
+ EXPECT_EQ(namespace_id1, usage[0].namespace_id);
+ }));
+ loop.Run();
+}
+
+TEST_F(SessionStorageContextMojoTest, DeleteStorage) {
+ std::string namespace_id1 = base::GenerateGUID();
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+
+ // First, test deleting data for a namespace that is open.
+ context()->CreateSessionNamespace(namespace_id1);
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id1,
+ mojo::MakeRequest(&ss_namespace1));
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n1_o1;
+ ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
+
+ // Put some data.
+ EXPECT_TRUE(test::PutSync(
+ leveldb_n1_o1.get(), leveldb::StringPieceToUint8Vector("key1"),
+ leveldb::StringPieceToUint8Vector("value1"), base::nullopt, "source1"));
+
+ context()->DeleteStorage(origin1, namespace_id1);
+
+ std::vector<blink::mojom::KeyValuePtr> data;
+ ASSERT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
+ EXPECT_EQ(0ul, data.size());
+
+ // Next, test that it deletes the data even if there isn't a namespace open.
+ // Put some data.
+ EXPECT_TRUE(test::PutSync(
+ leveldb_n1_o1.get(), leveldb::StringPieceToUint8Vector("key1"),
+ leveldb::StringPieceToUint8Vector("value1"), base::nullopt, "source1"));
+ // Delete the namespace and shutdown the context, BUT persist the namespace so
+ // it can be loaded again.
+ context()->DeleteSessionNamespace(namespace_id1, true);
+ ShutdownContext();
+
+ // This restarts the context, then deletes the storage.
+ context()->DeleteStorage(origin1, namespace_id1);
+
+ context()->CreateSessionNamespace(namespace_id1);
+ context()->OpenSessionStorage(kTestProcessId, namespace_id1,
+ mojo::MakeRequest(&ss_namespace1));
+ ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
+ data.clear();
+ EXPECT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
+ EXPECT_EQ(0ul, data.size());
+}
+
+TEST_F(SessionStorageContextMojoTest, PurgeInactiveWrappers) {
+ std::string namespace_id1 = base::GenerateGUID();
+ std::string namespace_id2 = base::GenerateGUID();
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+
+ context()->CreateSessionNamespace(namespace_id1);
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id1,
+ mojo::MakeRequest(&ss_namespace1));
+ blink::mojom::StorageAreaAssociatedPtr leveldb;
+ ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb));
+
+ // Put some data in both.
+ EXPECT_TRUE(test::PutSync(
+ leveldb.get(), leveldb::StringPieceToUint8Vector("key1"),
+ leveldb::StringPieceToUint8Vector("value1"), base::nullopt, "source1"));
+ context()->FlushAreaForTesting(namespace_id1, origin1);
+
+ ss_namespace1.reset();
+ leveldb.reset();
+
+ // Clear all the data from the backing database.
+ base::RunLoop loop;
+ context()->DatabaseForTesting()->DeletePrefixed(
+ leveldb::StringPieceToUint8Vector("map"),
+ base::BindLambdaForTesting([&](DatabaseError status) {
+ loop.Quit();
+ EXPECT_EQ(DatabaseError::OK, status);
+ }));
+ loop.Run();
+
+ // Now open many new wrappers (for different origins) to trigger clean up.
+ for (int i = 1; i <= 100; ++i) {
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id1,
+ mojo::MakeRequest(&ss_namespace1));
+ blink::mojom::StorageAreaAssociatedPtr leveldb;
+ ss_namespace1->OpenArea(url::Origin::Create(GURL(base::StringPrintf(
+ "http://example.com:%d", i))),
+ mojo::MakeRequest(&leveldb));
+ base::RunLoop().RunUntilIdle();
+ ss_namespace1.reset();
+ leveldb.reset();
+ }
+
+ // And make sure caches were actually cleared.
+ context()->OpenSessionStorage(kTestProcessId, namespace_id1,
+ mojo::MakeRequest(&ss_namespace1));
+ ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb));
+ std::vector<blink::mojom::KeyValuePtr> data;
+ ASSERT_TRUE(test::GetAllSync(leveldb.get(), &data));
+ EXPECT_EQ(0ul, data.size());
+}
+
+TEST_F(SessionStorageContextMojoTest, ClearDiskState) {
+ SetBackingMode(SessionStorageContextMojo::BackingMode::kClearDiskStateOnOpen);
+ std::string namespace_id1 = base::GenerateGUID();
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+ context()->CreateSessionNamespace(namespace_id1);
+
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id1,
+ mojo::MakeRequest(&ss_namespace1));
+
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n1_o1;
+ ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
+
+ // Verify no data.
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
+ EXPECT_EQ(0ul, data.size());
+
+ // Put some data.
+ EXPECT_TRUE(test::PutSync(
+ leveldb_n1_o1.get(), leveldb::StringPieceToUint8Vector("key1"),
+ leveldb::StringPieceToUint8Vector("value1"), base::nullopt, "source1"));
+
+ // Delete the namespace and shutdown the context, BUT persist the namespace on
+ // disk.
+ context()->DeleteSessionNamespace(namespace_id1, true);
+ ShutdownContext();
+
+ // This will re-open the context, and load the persisted namespace, but it
+ // should have been deleted due to our backing mode.
+ context()->CreateSessionNamespace(namespace_id1);
+ context()->OpenSessionStorage(kTestProcessId, namespace_id1,
+ mojo::MakeRequest(&ss_namespace1));
+ ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
+
+ // The data from before should not be here, because the context clears disk
+ // space on open.
+ EXPECT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
+ EXPECT_EQ(0ul, data.size());
+}
+
} // namespace
+
+TEST_F(SessionStorageContextMojoTest, PurgeMemoryDoesNotCrashOrHang) {
+ std::string namespace_id1 = base::GenerateGUID();
+ std::string namespace_id2 = base::GenerateGUID();
+ url::Origin origin1 = url::Origin::Create(GURL("http://foobar.com"));
+
+ context()->CreateSessionNamespace(namespace_id1);
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id1,
+ mojo::MakeRequest(&ss_namespace1));
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n1_o1;
+ ss_namespace1->OpenArea(origin1, mojo::MakeRequest(&leveldb_n1_o1));
+
+ context()->CreateSessionNamespace(namespace_id2);
+ blink::mojom::SessionStorageNamespacePtr ss_namespace2;
+ context()->OpenSessionStorage(kTestProcessId, namespace_id2,
+ mojo::MakeRequest(&ss_namespace2));
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n2_o1;
+ ss_namespace2->OpenArea(origin1, mojo::MakeRequest(&leveldb_n2_o1));
+
+ // Put some data in both.
+ EXPECT_TRUE(test::PutSync(
+ leveldb_n1_o1.get(), leveldb::StringPieceToUint8Vector("key1"),
+ leveldb::StringPieceToUint8Vector("value1"), base::nullopt, "source1"));
+ EXPECT_TRUE(test::PutSync(
+ leveldb_n2_o1.get(), leveldb::StringPieceToUint8Vector("key1"),
+ leveldb::StringPieceToUint8Vector("value2"), base::nullopt, "source1"));
+
+ context()->FlushAreaForTesting(namespace_id1, origin1);
+
+ leveldb_n2_o1.reset();
+ ss_namespace2.reset();
+
+ base::RunLoop().RunUntilIdle();
+
+ // Verify this doesn't crash or hang.
+ context()->PurgeMemory();
+
+ size_t memory_used = context()
+ ->namespaces_[namespace_id1]
+ ->origin_areas_[origin1]
+ ->data_map()
+ ->storage_area()
+ ->memory_used();
+ EXPECT_EQ(0ul, memory_used);
+
+ // Test the values is still there.
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_n1_o1.get(), &data));
+ EXPECT_EQ(1ul, data.size());
+
+ base::Optional<std::vector<uint8_t>> opt_value2 =
+ DoTestGet(namespace_id2, origin1, "key1");
+ ASSERT_TRUE(opt_value2);
+ EXPECT_EQ(leveldb::StringPieceToUint8Vector("value2"), opt_value2.value());
+}
+
} // namespace content
diff --git a/chromium/content/browser/dom_storage/session_storage_data_map.cc b/chromium/content/browser/dom_storage/session_storage_data_map.cc
index 4580e195381..a2f0507de42 100644
--- a/chromium/content/browser/dom_storage/session_storage_data_map.cc
+++ b/chromium/content/browser/dom_storage/session_storage_data_map.cc
@@ -24,7 +24,7 @@ scoped_refptr<SessionStorageDataMap> SessionStorageDataMap::Create(
scoped_refptr<SessionStorageDataMap> SessionStorageDataMap::CreateClone(
Listener* listener,
scoped_refptr<SessionStorageMetadata::MapData> map_data,
- LevelDBWrapperImpl* clone_from) {
+ StorageAreaImpl* clone_from) {
return base::WrapRefCounted(
new SessionStorageDataMap(listener, std::move(map_data), clone_from));
}
@@ -44,11 +44,12 @@ SessionStorageDataMap::SessionStorageDataMap(
leveldb::mojom::LevelDBDatabase* database)
: listener_(listener),
map_data_(std::move(map_data)),
- wrapper_impl_(std::make_unique<LevelDBWrapperImpl>(database,
- map_data_->KeyPrefix(),
- this,
- GetOptions())),
- level_db_wrapper_ptr_(wrapper_impl_.get()) {
+ storage_area_impl_(
+ std::make_unique<StorageAreaImpl>(database,
+ map_data_->KeyPrefix(),
+ this,
+ GetOptions())),
+ storage_area_ptr_(storage_area_impl_.get()) {
DCHECK(listener_);
DCHECK(map_data_);
listener_->OnDataMapCreation(map_data_->MapNumberAsBytes(), this);
@@ -57,13 +58,13 @@ SessionStorageDataMap::SessionStorageDataMap(
SessionStorageDataMap::SessionStorageDataMap(
Listener* listener,
scoped_refptr<SessionStorageMetadata::MapData> map_data,
- LevelDBWrapperImpl* forking_from)
+ StorageAreaImpl* forking_from)
: listener_(listener),
map_data_(std::move(map_data)),
- wrapper_impl_(forking_from->ForkToNewPrefix(map_data_->KeyPrefix(),
- this,
- GetOptions())),
- level_db_wrapper_ptr_(wrapper_impl_.get()) {
+ storage_area_impl_(forking_from->ForkToNewPrefix(map_data_->KeyPrefix(),
+ this,
+ GetOptions())),
+ storage_area_ptr_(storage_area_impl_.get()) {
DCHECK(listener_);
DCHECK(map_data_);
listener_->OnDataMapCreation(map_data_->MapNumberAsBytes(), this);
@@ -81,11 +82,11 @@ void SessionStorageDataMap::RemoveBindingReference() {
// Don't delete ourselves, but do schedule an immediate commit. Possible
// deletion will happen under memory pressure or when another sessionstorage
// area is opened.
- level_db_wrapper()->ScheduleImmediateCommit();
+ storage_area()->ScheduleImmediateCommit();
}
// static
-LevelDBWrapperImpl::Options SessionStorageDataMap::GetOptions() {
+StorageAreaImpl::Options SessionStorageDataMap::GetOptions() {
// Delay for a moment after a value is set in anticipation
// of other values being set, so changes are batched.
constexpr const base::TimeDelta kCommitDefaultDelaySecs =
@@ -93,12 +94,12 @@ LevelDBWrapperImpl::Options SessionStorageDataMap::GetOptions() {
// To avoid excessive IO we apply limits to the amount of data being
// written and the frequency of writes.
- LevelDBWrapperImpl::Options options;
+ StorageAreaImpl::Options options;
options.max_size = kPerStorageAreaQuota + kPerStorageAreaOverQuotaAllowance;
options.default_commit_delay = kCommitDefaultDelaySecs;
options.max_bytes_per_hour = kPerStorageAreaQuota;
options.max_commits_per_hour = 60;
- options.cache_mode = LevelDBWrapperImpl::CacheMode::KEYS_ONLY_WHEN_POSSIBLE;
+ options.cache_mode = StorageAreaImpl::CacheMode::KEYS_ONLY_WHEN_POSSIBLE;
return options;
}
diff --git a/chromium/content/browser/dom_storage/session_storage_data_map.h b/chromium/content/browser/dom_storage/session_storage_data_map.h
index b4f60811a9a..038652ffc96 100644
--- a/chromium/content/browser/dom_storage/session_storage_data_map.h
+++ b/chromium/content/browser/dom_storage/session_storage_data_map.h
@@ -12,25 +12,24 @@
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "content/browser/dom_storage/session_storage_metadata.h"
-#include "content/browser/leveldb_wrapper_impl.h"
+#include "content/browser/dom_storage/storage_area_impl.h"
#include "content/common/content_export.h"
-#include "content/common/leveldb_wrapper.mojom.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
namespace content {
-// Holds the LevelDBWrapper for a session storage data map. Every
+// Holds the StorageArea for a session storage data map. Every
// namespace-origin area has a data map. To support shallow copying of the data
// (copy-on-write), a single data map can be shared between multiple namespaces.
// Thus this class is refcounted. This class has a one-to-one relationship with
// the SessionStorageMetadata::MapData object, accessible from |map_data()|.
//
-// Neither this data map nor the inner LevelDBWrapper is bound to, as it needs
+// Neither this data map nor the inner StorageArea is bound to, as it needs
// to be shared between multiple connections if it is shallow-copied. However,
// it does allow it's user to keep track of the number of binding using
// |binding_count()|, |AddBindingReference()|, and |RemoveBindingReference()|.
class CONTENT_EXPORT SessionStorageDataMap final
- : public LevelDBWrapperImpl::Delegate,
+ : public StorageAreaImpl::Delegate,
public base::RefCounted<SessionStorageDataMap> {
public:
class CONTENT_EXPORT Listener {
@@ -50,11 +49,11 @@ class CONTENT_EXPORT SessionStorageDataMap final
static scoped_refptr<SessionStorageDataMap> CreateClone(
Listener* listener,
scoped_refptr<SessionStorageMetadata::MapData> map_data,
- LevelDBWrapperImpl* clone_from);
+ StorageAreaImpl* clone_from);
Listener* listener() const { return listener_; }
- LevelDBWrapperImpl* level_db_wrapper() { return level_db_wrapper_ptr_; }
+ StorageAreaImpl* storage_area() { return storage_area_ptr_; }
scoped_refptr<SessionStorageMetadata::MapData> map_data() {
return map_data_.get();
@@ -63,10 +62,10 @@ class CONTENT_EXPORT SessionStorageDataMap final
int binding_count() { return binding_count_; }
void AddBindingReference() { ++binding_count_; }
// When the binding count reaches 0, we schedule an immediate commit on our
- // wrapper, but we don't close the connection.
+ // area, but we don't close the connection.
void RemoveBindingReference();
- // Note: this is irrelevant, as the parent wrapper is handling binding.
+ // Note: this is irrelevant, as the parent area is handling binding.
void OnNoBindings() override {}
std::vector<leveldb::mojom::BatchedOperationPtr> PrepareToCommit() override;
@@ -83,21 +82,21 @@ class CONTENT_EXPORT SessionStorageDataMap final
SessionStorageDataMap(
Listener* listener,
scoped_refptr<SessionStorageMetadata::MapData> map_entry,
- LevelDBWrapperImpl* forking_from);
+ StorageAreaImpl* forking_from);
~SessionStorageDataMap() override;
- static LevelDBWrapperImpl::Options GetOptions();
+ static StorageAreaImpl::Options GetOptions();
Listener* listener_;
int binding_count_ = 0;
scoped_refptr<SessionStorageMetadata::MapData> map_data_;
- std::unique_ptr<LevelDBWrapperImpl> wrapper_impl_;
- // Holds the same value as |wrapper_impl_|. The reason for this is that
- // during destruction of the LevelDBWrapperImpl instance we might still get
- // called and need access to the LevelDBWrapperImpl instance. The
+ std::unique_ptr<StorageAreaImpl> storage_area_impl_;
+ // Holds the same value as |storage_area_impl_|. The reason for this is that
+ // during destruction of the StorageAreaImpl instance we might still get
+ // called and need access to the StorageAreaImpl instance. The
// unique_ptr could already be null, but this field should still be valid.
// TODO(dmurph): Change delegate ownership so this doesn't have to be done.
- LevelDBWrapperImpl* level_db_wrapper_ptr_;
+ StorageAreaImpl* storage_area_ptr_;
DISALLOW_COPY_AND_ASSIGN(SessionStorageDataMap);
};
diff --git a/chromium/content/browser/dom_storage/session_storage_data_map_unittest.cc b/chromium/content/browser/dom_storage/session_storage_data_map_unittest.cc
index 97af433c270..8797e0c9db1 100644
--- a/chromium/content/browser/dom_storage/session_storage_data_map_unittest.cc
+++ b/chromium/content/browser/dom_storage/session_storage_data_map_unittest.cc
@@ -33,27 +33,27 @@ class MockListener : public SessionStorageDataMap::Listener {
MOCK_METHOD1(OnCommitResult, void(leveldb::mojom::DatabaseError error));
};
-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;
+void GetAllDataCallback(bool* success_out,
+ std::vector<blink::mojom::KeyValuePtr>* data_out,
+ bool success,
+ std::vector<blink::mojom::KeyValuePtr> data) {
+ *success_out = success;
*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);
+base::OnceCallback<void(bool success,
+ std::vector<blink::mojom::KeyValuePtr> data)>
+MakeGetAllCallback(bool* sucess_out,
+ std::vector<blink::mojom::KeyValuePtr>* data_out) {
+ return base::BindOnce(&GetAllDataCallback, sucess_out, data_out);
}
-class GetAllCallback : public mojom::LevelDBWrapperGetAllCallback {
+class GetAllCallback : public blink::mojom::StorageAreaGetAllCallback {
public:
- static mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo CreateAndBind(
+ static blink::mojom::StorageAreaGetAllCallbackAssociatedPtrInfo CreateAndBind(
bool* result,
base::OnceClosure callback) {
- mojom::LevelDBWrapperGetAllCallbackAssociatedPtr ptr;
+ blink::mojom::StorageAreaGetAllCallbackAssociatedPtr ptr;
auto request = mojo::MakeRequestAssociatedWithDedicatedPipe(&ptr);
mojo::MakeStrongAssociatedBinding(
base::WrapUnique(new GetAllCallback(result, std::move(callback))),
@@ -108,13 +108,13 @@ TEST_F(SessionStorageDataMapTest, BasicEmptyCreation) {
base::MakeRefCounted<SessionStorageMetadata::MapData>(1, test_origin_),
&database_);
- leveldb::mojom::DatabaseError status;
- std::vector<mojom::KeyValuePtr> data;
+ bool success;
+ std::vector<blink::mojom::KeyValuePtr> data;
bool done = false;
base::RunLoop loop;
- map->level_db_wrapper()->GetAll(
+ map->storage_area()->GetAll(
GetAllCallback::CreateAndBind(&done, loop.QuitClosure()),
- MakeGetAllCallback(&status, &data));
+ MakeGetAllCallback(&success, &data));
loop.Run();
EXPECT_TRUE(done);
@@ -152,15 +152,15 @@ TEST_F(SessionStorageDataMapTest, Clone) {
&listener_,
base::MakeRefCounted<SessionStorageMetadata::MapData>(2,
test_origin_),
- map1->level_db_wrapper());
+ map1->storage_area());
- leveldb::mojom::DatabaseError status;
- std::vector<mojom::KeyValuePtr> data;
+ bool success;
+ std::vector<blink::mojom::KeyValuePtr> data;
bool done = false;
base::RunLoop loop;
- map2->level_db_wrapper()->GetAll(
+ map2->storage_area()->GetAll(
GetAllCallback::CreateAndBind(&done, loop.QuitClosure()),
- MakeGetAllCallback(&status, &data));
+ MakeGetAllCallback(&success, &data));
loop.Run();
EXPECT_TRUE(done);
diff --git a/chromium/content/browser/dom_storage/session_storage_database.cc b/chromium/content/browser/dom_storage/session_storage_database.cc
index 8af5497c82c..cc9e839424a 100644
--- a/chromium/content/browser/dom_storage/session_storage_database.cc
+++ b/chromium/content/browser/dom_storage/session_storage_database.cc
@@ -19,6 +19,7 @@
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/process_memory_dump.h"
#include "build/build_config.h"
+#include "content/browser/dom_storage/session_storage_metadata.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/leveldb_chrome.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
@@ -492,7 +493,24 @@ leveldb::Status SessionStorageDatabase::TryToOpen(
// delete the old database here before we open it.
leveldb::DestroyDB(db_name, options);
#endif
- return leveldb_env::OpenDB(options, db_name, db);
+ leveldb::Status s = leveldb_env::OpenDB(options, db_name, db);
+ if (!s.ok())
+ return s;
+
+ // If there is a version entry from the new implementation, treat the database
+ // as corrupt.
+ leveldb::Slice version_key =
+ leveldb::Slice(reinterpret_cast<const char*>(
+ SessionStorageMetadata::kDatabaseVersionBytes),
+ sizeof(SessionStorageMetadata::kDatabaseVersionBytes));
+ std::string dummy;
+ s = (*db)->Get(leveldb::ReadOptions(), version_key, &dummy);
+ if (s.IsNotFound())
+ return leveldb::Status::OK();
+
+ db->reset();
+ return leveldb::Status::Corruption(
+ "Cannot read a database that is a higher schema version.", dummy);
}
bool SessionStorageDatabase::IsOpen() const {
diff --git a/chromium/content/browser/dom_storage/session_storage_database_unittest.cc b/chromium/content/browser/dom_storage/session_storage_database_unittest.cc
index ad590cad0df..af7de589318 100644
--- a/chromium/content/browser/dom_storage/session_storage_database_unittest.cc
+++ b/chromium/content/browser/dom_storage/session_storage_database_unittest.cc
@@ -21,6 +21,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "content/browser/dom_storage/session_storage_metadata.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
@@ -825,5 +826,24 @@ TEST_F(SessionStorageDatabaseTest, DeleteAllOrigins) {
CheckDatabaseConsistency();
}
+TEST_F(SessionStorageDatabaseTest, WipeDBOnNewVersion) {
+ // Write data for a namespace.
+ DOMStorageValuesMap data;
+ data[kKey1] = kValue1;
+ ASSERT_TRUE(db_->CommitAreaChanges(kNamespace1, kOrigin1, false, data));
+ CheckDatabaseConsistency();
+
+ leveldb::Slice version_key =
+ leveldb::Slice(reinterpret_cast<const char*>(
+ SessionStorageMetadata::kDatabaseVersionBytes),
+ sizeof(SessionStorageMetadata::kDatabaseVersionBytes));
+ db_->db()->Put(leveldb::WriteOptions(), version_key, "something");
+ ResetDatabase();
+
+ CheckDatabaseConsistency();
+ CheckEmptyDatabase();
+ data.clear();
+ CheckAreaData(kNamespace1, kOrigin1, data);
+}
} // namespace content
diff --git a/chromium/content/browser/dom_storage/session_storage_metadata.cc b/chromium/content/browser/dom_storage/session_storage_metadata.cc
index d129f92e127..515bbac0b12 100644
--- a/chromium/content/browser/dom_storage/session_storage_metadata.cc
+++ b/chromium/content/browser/dom_storage/session_storage_metadata.cc
@@ -300,7 +300,8 @@ void SessionStorageMetadata::RegisterShallowClonedNamespace(
source_namespace->second;
std::map<url::Origin, scoped_refptr<MapData>>& destination_origins =
destination_namespace->second;
- DCHECK_EQ(0ul, destination_origins.size());
+ DCHECK_EQ(0ul, destination_origins.size())
+ << "The destination already has data.";
save_operations->reserve(save_operations->size() + source_origins.size());
for (const auto& origin_map_pair : source_origins) {
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 484118b1826..81c1d91c755 100644
--- a/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc
+++ b/chromium/content/browser/dom_storage/session_storage_namespace_impl.cc
@@ -60,7 +60,8 @@ scoped_refptr<SessionStorageNamespaceImpl>
SessionStorageNamespaceImpl::CloneFrom(
scoped_refptr<DOMStorageContextWrapper> context,
std::string namespace_id,
- const std::string& namespace_id_to_clone) {
+ const std::string& namespace_id_to_clone,
+ bool immediately) {
if (context->mojo_session_state()) {
DCHECK(base::FeatureList::IsEnabled(features::kMojoSessionStorage));
auto result = base::WrapRefCounted(
@@ -69,7 +70,11 @@ SessionStorageNamespaceImpl::CloneFrom(
FROM_HERE,
base::BindOnce(&SessionStorageContextMojo::CloneSessionNamespace,
base::Unretained(context->mojo_session_state()),
- namespace_id_to_clone, result->namespace_id_));
+ namespace_id_to_clone, result->namespace_id_,
+ immediately
+ ? SessionStorageContextMojo::CloneType::kImmediate
+ : SessionStorageContextMojo::CloneType::
+ kWaitForCloneOnNamespace));
return result;
}
scoped_refptr<DOMStorageContextImpl> context_impl = context->context();
@@ -96,7 +101,7 @@ bool SessionStorageNamespaceImpl::should_persist() const {
scoped_refptr<SessionStorageNamespaceImpl>
SessionStorageNamespaceImpl::Clone() {
return CloneFrom(context_wrapper_, AllocateSessionStorageNamespaceId(),
- namespace_id_);
+ namespace_id_, true);
}
bool SessionStorageNamespaceImpl::IsFromContext(
diff --git a/chromium/content/browser/dom_storage/session_storage_namespace_impl.h b/chromium/content/browser/dom_storage/session_storage_namespace_impl.h
index 8278286e086..7f3de289774 100644
--- a/chromium/content/browser/dom_storage/session_storage_namespace_impl.h
+++ b/chromium/content/browser/dom_storage/session_storage_namespace_impl.h
@@ -34,16 +34,20 @@ class SessionStorageNamespaceImpl : public SessionStorageNamespace {
// If there is an existing SessionStorageNamespaceImpl with the given id in
// the DOMStorageContextWrapper, this will return that object. Otherwise this
// constructs a SessionStorageNamespaceImpl and assigns |namespace_id| to it.
- static scoped_refptr<SessionStorageNamespaceImpl> Create(
+ CONTENT_EXPORT static scoped_refptr<SessionStorageNamespaceImpl> Create(
scoped_refptr<DOMStorageContextWrapper> context,
std::string namespace_id);
// Constructs a |SessionStorageNamespaceImpl| with id |namespace_id| by
// cloning |namespace_to_clone|. Allocates it a new ID.
+ // Only set |immediately| to true to cause the clone to immediately happen,
+ // where there definitely will not be a |Clone| call from the
+ // SessionStorageNamespace mojo object.
static scoped_refptr<SessionStorageNamespaceImpl> CloneFrom(
scoped_refptr<DOMStorageContextWrapper> context,
std::string namespace_id,
- const std::string& namespace_id_to_clone);
+ const std::string& namespace_id_to_clone,
+ bool immediately = false);
DOMStorageContextWrapper* context() const { return context_wrapper_.get(); }
diff --git a/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo.cc b/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo.cc
index d02473e3d23..6bc8e13b918 100644
--- a/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo.cc
+++ b/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo.cc
@@ -17,7 +17,7 @@ SessionStorageNamespaceImplMojo::SessionStorageNamespaceImplMojo(
std::string namespace_id,
SessionStorageDataMap::Listener* data_map_listener,
RegisterShallowClonedNamespace add_namespace_callback,
- SessionStorageLevelDBWrapper::RegisterNewAreaMap register_new_map_callback)
+ SessionStorageAreaImpl::RegisterNewAreaMap register_new_map_callback)
: namespace_id_(std::move(namespace_id)),
data_map_listener_(data_map_listener),
add_namespace_callback_(std::move(add_namespace_callback)),
@@ -49,7 +49,7 @@ void SessionStorageNamespaceImplMojo::PopulateFromMetadata(
} else {
data_map = base::WrapRefCounted(map_it->second);
}
- origin_areas_[pair.first] = std::make_unique<SessionStorageLevelDBWrapper>(
+ origin_areas_[pair.first] = std::make_unique<SessionStorageAreaImpl>(
namespace_entry_, pair.first, std::move(data_map),
register_new_map_callback_);
}
@@ -79,7 +79,6 @@ void SessionStorageNamespaceImplMojo::PopulateAsClone(
void SessionStorageNamespaceImplMojo::Reset() {
namespace_entry_ = SessionStorageMetadata::NamespaceEntry();
- process_id_ = ChildProcessHost::kInvalidUniqueID;
database_ = nullptr;
waiting_on_clone_population_ = false;
bind_waiting_on_clone_population_ = false;
@@ -90,7 +89,7 @@ void SessionStorageNamespaceImplMojo::Reset() {
}
void SessionStorageNamespaceImplMojo::Bind(
- mojom::SessionStorageNamespaceRequest request,
+ blink::mojom::SessionStorageNamespaceRequest request,
int process_id) {
if (waiting_on_clone_population_) {
bind_waiting_on_clone_population_ = true;
@@ -100,16 +99,17 @@ void SessionStorageNamespaceImplMojo::Bind(
return;
}
DCHECK(IsPopulated());
- process_id_ = process_id;
- bindings_.AddBinding(this, std::move(request));
+ bindings_.AddBinding(this, std::move(request), process_id);
bind_waiting_on_clone_population_ = false;
}
-void SessionStorageNamespaceImplMojo::PurgeUnboundWrappers() {
+void SessionStorageNamespaceImplMojo::PurgeUnboundAreas() {
auto it = origin_areas_.begin();
while (it != origin_areas_.end()) {
if (!it->second->IsBound())
it = origin_areas_.erase(it);
+ else
+ ++it;
}
}
@@ -128,32 +128,40 @@ void SessionStorageNamespaceImplMojo::RemoveOriginData(
// Renderer process expects |source| to always be two newline separated
// strings.
it->second->DeleteAll("\n", base::DoNothing());
- it->second->data_map()->level_db_wrapper()->ScheduleImmediateCommit();
+ it->second->NotifyObserversAllDeleted();
+ it->second->data_map()->storage_area()->ScheduleImmediateCommit();
}
void SessionStorageNamespaceImplMojo::OpenArea(
const url::Origin& origin,
- mojom::LevelDBWrapperAssociatedRequest database) {
+ blink::mojom::StorageAreaAssociatedRequest database) {
DCHECK(IsPopulated());
DCHECK(!bindings_.empty());
- DCHECK_NE(process_id_, ChildProcessHost::kInvalidUniqueID);
+ int process_id = bindings_.dispatch_context();
if (!ChildProcessSecurityPolicy::GetInstance()->CanAccessDataForOrigin(
- process_id_, origin.GetURL())) {
+ process_id, origin.GetURL())) {
bindings_.ReportBadMessage("Access denied for sessionStorage request");
return;
}
auto it = origin_areas_.find(origin);
if (it == origin_areas_.end()) {
+ scoped_refptr<SessionStorageMetadata::MapData> map_data;
+ // The area may have been purged due to lack of bindings, so check the
+ // metadata for the map.
+ auto map_it = namespace_entry_->second.find(origin);
+ if (map_it != namespace_entry_->second.end()) {
+ map_data = map_it->second;
+ } else {
+ map_data = register_new_map_callback_.Run(namespace_entry_, origin);
+ }
it = origin_areas_
.emplace(std::make_pair(
- origin, std::make_unique<SessionStorageLevelDBWrapper>(
- namespace_entry_, origin,
- SessionStorageDataMap::Create(
- data_map_listener_,
- register_new_map_callback_.Run(
- namespace_entry_, origin),
- database_),
- register_new_map_callback_)))
+ origin,
+ std::make_unique<SessionStorageAreaImpl>(
+ namespace_entry_, origin,
+ SessionStorageDataMap::Create(
+ data_map_listener_, std::move(map_data), database_),
+ register_new_map_callback_)))
.first;
}
it->second->Bind(std::move(database));
@@ -172,7 +180,7 @@ void SessionStorageNamespaceImplMojo::FlushOriginForTesting(
auto it = origin_areas_.find(origin);
if (it == origin_areas_.end())
return;
- it->second->data_map()->level_db_wrapper()->ScheduleImmediateCommit();
+ it->second->data_map()->storage_area()->ScheduleImmediateCommit();
}
} // namespace content
diff --git a/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo.h b/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo.h
index 5936c469fc7..eb70ad8dde2 100644
--- a/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo.h
+++ b/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo.h
@@ -8,22 +8,21 @@
#include "base/callback.h"
#include "base/containers/flat_map.h"
+#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
+#include "content/browser/dom_storage/session_storage_area_impl.h"
#include "content/browser/dom_storage/session_storage_data_map.h"
-#include "content/browser/dom_storage/session_storage_leveldb_wrapper.h"
#include "content/browser/dom_storage/session_storage_metadata.h"
-#include "content/common/leveldb_wrapper.mojom.h"
-#include "content/common/storage_partition_service.mojom.h"
-#include "content/public/common/child_process_host.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h"
+#include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom.h"
#include "url/origin.h"
namespace content {
// Implements the mojo interface SessionStorageNamespace. Stores data maps per
-// origin, which are accessible using the LevelDBWrapper interface with the
+// origin, which are accessible using the StorageArea interface with the
// |OpenArea| call. Supports cloning (shallow cloning with copy-on-write
// behavior) from another SessionStorageNamespaceImplMojo.
//
@@ -46,10 +45,10 @@ namespace content {
// create the cloned namespace and expect to manage it's lifetime that way, and
// this can happen before the first case, as they are on different task runners.
class CONTENT_EXPORT SessionStorageNamespaceImplMojo final
- : public mojom::SessionStorageNamespace {
+ : public blink::mojom::SessionStorageNamespace {
public:
using OriginAreas =
- std::map<url::Origin, std::unique_ptr<SessionStorageLevelDBWrapper>>;
+ std::map<url::Origin, std::unique_ptr<SessionStorageAreaImpl>>;
using RegisterShallowClonedNamespace = base::RepeatingCallback<void(
SessionStorageMetadata::NamespaceEntry source_namespace,
const std::string& destination_namespace,
@@ -60,14 +59,13 @@ class CONTENT_EXPORT SessionStorageNamespaceImplMojo final
// |data_map_listener| are given to any data maps constructed for this
// namespace. The |add_namespace_callback| is called when the |Clone| method
// is called by mojo. The |register_new_map_callback| is given to the the
- // SessionStorageLevelDBWrapper's, used per-origin, that are bound to in
+ // SessionStorageAreaImpl's, used per-origin, that are bound to in
// OpenArea.
SessionStorageNamespaceImplMojo(
std::string namespace_id,
SessionStorageDataMap::Listener* data_map_listener,
RegisterShallowClonedNamespace add_namespace_callback,
- SessionStorageLevelDBWrapper::RegisterNewAreaMap
- register_new_map_callback);
+ SessionStorageAreaImpl::RegisterNewAreaMap register_new_map_callback);
~SessionStorageNamespaceImplMojo() override;
@@ -108,17 +106,19 @@ class CONTENT_EXPORT SessionStorageNamespaceImplMojo final
// |SetWaitingForClonePopulation|. For the later case, |PopulateAsClone| must
// eventually be called before the SessionStorageNamespaceRequest can be
// bound.
- void Bind(mojom::SessionStorageNamespaceRequest request, int process_id);
+ void Bind(blink::mojom::SessionStorageNamespaceRequest request,
+ int process_id);
bool IsBound() const {
return !bindings_.empty() || bind_waiting_on_clone_population_;
}
- // Removes any LevelDBWrappers bound in |OpenArea| that are no longer bound.
- void PurgeUnboundWrappers();
+ // Removes any StorageAreas bound in |OpenArea| that are no longer bound.
+ void PurgeUnboundAreas();
// Removes data for the given origin from this namespace. If there is no data
- // map for that given origin, this does nothing.
+ // map for that given origin, this does nothing. Expects that this namespace
+ // is either populated or waiting for clone population.
void RemoveOriginData(const url::Origin& origin);
// SessionStorageNamespace:
@@ -126,7 +126,7 @@ class CONTENT_EXPORT SessionStorageNamespaceImplMojo final
// origin. Before connection, it checks to make sure the |process_id| given to
// the |Bind| method can access the given origin.
void OpenArea(const url::Origin& origin,
- mojom::LevelDBWrapperAssociatedRequest database) override;
+ blink::mojom::StorageAreaAssociatedRequest database) override;
// Simply calls the |add_namespace_callback_| callback with this namespace's
// data.
@@ -135,14 +135,16 @@ class CONTENT_EXPORT SessionStorageNamespaceImplMojo final
void FlushOriginForTesting(const url::Origin& origin);
private:
+ FRIEND_TEST_ALL_PREFIXES(SessionStorageContextMojoTest,
+ PurgeMemoryDoesNotCrashOrHang);
+
const std::string namespace_id_;
SessionStorageMetadata::NamespaceEntry namespace_entry_;
- int process_id_ = ChildProcessHost::kInvalidUniqueID;
leveldb::mojom::LevelDBDatabase* database_;
SessionStorageDataMap::Listener* data_map_listener_;
RegisterShallowClonedNamespace add_namespace_callback_;
- SessionStorageLevelDBWrapper::RegisterNewAreaMap register_new_map_callback_;
+ SessionStorageAreaImpl::RegisterNewAreaMap register_new_map_callback_;
bool waiting_on_clone_population_ = false;
bool bind_waiting_on_clone_population_ = false;
@@ -150,7 +152,8 @@ class CONTENT_EXPORT SessionStorageNamespaceImplMojo final
bool populated_ = false;
OriginAreas origin_areas_;
- mojo::BindingSet<mojom::SessionStorageNamespace> bindings_;
+ // The context is the process id.
+ mojo::BindingSet<blink::mojom::SessionStorageNamespace, int> bindings_;
};
} // namespace content
diff --git a/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo_unittest.cc b/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo_unittest.cc
index 7ee00233e60..b813634fcf5 100644
--- a/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo_unittest.cc
+++ b/chromium/content/browser/dom_storage/session_storage_namespace_impl_mojo_unittest.cc
@@ -7,14 +7,15 @@
#include "base/guid.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
-#include "base/test/scoped_task_environment.h"
#include "components/services/leveldb/public/cpp/util.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/dom_storage/session_storage_data_map.h"
#include "content/browser/dom_storage/session_storage_metadata.h"
+#include "content/browser/dom_storage/test/storage_area_test_util.h"
+#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/fake_leveldb_database.h"
-#include "content/test/leveldb_wrapper_test_util.h"
-#include "mojo/edk/embedder/embedder.h"
+#include "content/test/gmock_util.h"
+#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -77,7 +78,7 @@ class SessionStorageNamespaceImplMojoTest : public testing::Test {
security_policy->LockToOrigin(kTestProcessIdOrigin3,
test_origin3_.GetURL());
- mojo::edk::SetDefaultProcessErrorCallback(
+ mojo::core::SetDefaultProcessErrorCallback(
base::BindRepeating(&SessionStorageNamespaceImplMojoTest::OnBadMessage,
base::Unretained(this)));
}
@@ -90,8 +91,8 @@ class SessionStorageNamespaceImplMojoTest : public testing::Test {
security_policy->Remove(kTestProcessIdAllOrigins);
security_policy->Remove(kTestProcessIdOrigin3);
- mojo::edk::SetDefaultProcessErrorCallback(
- mojo::edk::ProcessErrorCallback());
+ mojo::core::SetDefaultProcessErrorCallback(
+ mojo::core::ProcessErrorCallback());
}
// Creates a SessionStorageNamespaceImplMojo, saves it in the namespaces_ map,
@@ -104,7 +105,7 @@ class SessionStorageNamespaceImplMojoTest : public testing::Test {
base::BindRepeating(&SessionStorageNamespaceImplMojoTest::
RegisterShallowClonedNamespace,
base::Unretained(this));
- SessionStorageLevelDBWrapper::RegisterNewAreaMap map_id_callback =
+ SessionStorageAreaImpl::RegisterNewAreaMap map_id_callback =
base::BindRepeating(
&SessionStorageNamespaceImplMojoTest::RegisterNewAreaMap,
base::Unretained(this));
@@ -150,7 +151,7 @@ class SessionStorageNamespaceImplMojoTest : public testing::Test {
}
protected:
- base::test::ScopedTaskEnvironment task_environment_;
+ TestBrowserThreadBundle test_browser_thread_bundle_;
const std::string test_namespace_id1_;
const std::string test_namespace_id2_;
const url::Origin test_origin1_;
@@ -180,19 +181,18 @@ TEST_F(SessionStorageNamespaceImplMojoTest, MetadataLoad) {
&database_, metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_),
std::map<std::vector<uint8_t>, SessionStorageDataMap*>());
- mojom::SessionStorageNamespacePtr ss_namespace;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace;
namespace_impl->Bind(mojo::MakeRequest(&ss_namespace), kTestProcessIdOrigin1);
- mojom::LevelDBWrapperAssociatedPtr leveldb_1;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_1;
ss_namespace->OpenArea(test_origin1_, mojo::MakeRequest(&leveldb_1));
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(leveldb_1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_1.get(), &data));
EXPECT_EQ(1ul, data.size());
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(StdStringToUint8Vector("key1"),
- StdStringToUint8Vector("data1"))));
+ data, blink::mojom::KeyValue::New(StdStringToUint8Vector("key1"),
+ StdStringToUint8Vector("data1"))));
EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
.Times(1);
@@ -213,26 +213,25 @@ TEST_F(SessionStorageNamespaceImplMojoTest, MetadataLoadWithMapOperations) {
&database_, metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_),
std::map<std::vector<uint8_t>, SessionStorageDataMap*>());
- mojom::SessionStorageNamespacePtr ss_namespace;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace;
namespace_impl->Bind(mojo::MakeRequest(&ss_namespace), kTestProcessIdOrigin1);
- mojom::LevelDBWrapperAssociatedPtr leveldb_1;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_1;
ss_namespace->OpenArea(test_origin1_, mojo::MakeRequest(&leveldb_1));
EXPECT_CALL(listener_, OnCommitResult(DatabaseError::OK)).Times(1);
test::PutSync(leveldb_1.get(), StdStringToUint8Vector("key2"),
StdStringToUint8Vector("data2"), base::nullopt, "");
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(leveldb_1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_1.get(), &data));
EXPECT_EQ(2ul, data.size());
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(StdStringToUint8Vector("key1"),
- StdStringToUint8Vector("data1"))));
+ data, blink::mojom::KeyValue::New(StdStringToUint8Vector("key1"),
+ StdStringToUint8Vector("data1"))));
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(StdStringToUint8Vector("key2"),
- StdStringToUint8Vector("data2"))));
+ data, blink::mojom::KeyValue::New(StdStringToUint8Vector("key2"),
+ StdStringToUint8Vector("data2"))));
EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
.Times(1);
@@ -254,7 +253,7 @@ TEST_F(SessionStorageNamespaceImplMojoTest, CloneBeforeBind) {
&database_, metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_),
std::map<std::vector<uint8_t>, SessionStorageDataMap*>());
- mojom::SessionStorageNamespacePtr ss_namespace1;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
namespace_impl1->Bind(mojo::MakeRequest(&ss_namespace1),
kTestProcessIdOrigin1);
ss_namespace1->Clone(test_namespace_id2_);
@@ -262,10 +261,10 @@ TEST_F(SessionStorageNamespaceImplMojoTest, CloneBeforeBind) {
ASSERT_TRUE(namespace_impl2->IsPopulated());
- mojom::SessionStorageNamespacePtr ss_namespace2;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace2;
namespace_impl2->Bind(mojo::MakeRequest(&ss_namespace2),
kTestProcessIdOrigin1);
- mojom::LevelDBWrapperAssociatedPtr leveldb_2;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_2;
ss_namespace2->OpenArea(test_origin1_, mojo::MakeRequest(&leveldb_2));
// Do a put in the cloned namespace.
@@ -276,16 +275,15 @@ TEST_F(SessionStorageNamespaceImplMojoTest, CloneBeforeBind) {
test::PutSync(leveldb_2.get(), StdStringToUint8Vector("key2"),
StdStringToUint8Vector("data2"), base::nullopt, "");
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(leveldb_2.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_2.get(), &data));
EXPECT_EQ(2ul, data.size());
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(StdStringToUint8Vector("key1"),
- StdStringToUint8Vector("data1"))));
+ data, blink::mojom::KeyValue::New(StdStringToUint8Vector("key1"),
+ StdStringToUint8Vector("data1"))));
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(StdStringToUint8Vector("key2"),
- StdStringToUint8Vector("data2"))));
+ data, blink::mojom::KeyValue::New(StdStringToUint8Vector("key2"),
+ StdStringToUint8Vector("data2"))));
EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
.Times(1);
@@ -311,7 +309,7 @@ TEST_F(SessionStorageNamespaceImplMojoTest, CloneAfterBind) {
&database_, metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_),
std::map<std::vector<uint8_t>, SessionStorageDataMap*>());
- mojom::SessionStorageNamespacePtr ss_namespace1;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace1;
namespace_impl1->Bind(mojo::MakeRequest(&ss_namespace1),
kTestProcessIdOrigin1);
@@ -322,11 +320,11 @@ TEST_F(SessionStorageNamespaceImplMojoTest, CloneAfterBind) {
OnDataMapCreation(StdStringToUint8Vector("1"), testing::_))
.Times(1);
// Get a new area.
- mojom::SessionStorageNamespacePtr ss_namespace2;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace2;
namespace_impl2->Bind(mojo::MakeRequest(&ss_namespace2),
kTestProcessIdAllOrigins);
- mojom::LevelDBWrapperAssociatedPtr leveldb_n2_o1;
- mojom::LevelDBWrapperAssociatedPtr leveldb_n2_o2;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n2_o1;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_n2_o2;
ss_namespace2->OpenArea(test_origin1_, mojo::MakeRequest(&leveldb_n2_o1));
ss_namespace2->OpenArea(test_origin2_, mojo::MakeRequest(&leveldb_n2_o2));
@@ -341,21 +339,19 @@ TEST_F(SessionStorageNamespaceImplMojoTest, CloneAfterBind) {
test::PutSync(leveldb_n2_o2.get(), StdStringToUint8Vector("key2"),
StdStringToUint8Vector("data2"), base::nullopt, "");
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(leveldb_n2_o1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_n2_o1.get(), &data));
EXPECT_EQ(1ul, data.size());
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(StdStringToUint8Vector("key1"),
- StdStringToUint8Vector("data1"))));
+ data, blink::mojom::KeyValue::New(StdStringToUint8Vector("key1"),
+ StdStringToUint8Vector("data1"))));
data.clear();
- status = test::GetAllSync(leveldb_n2_o2.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ EXPECT_TRUE(test::GetAllSync(leveldb_n2_o2.get(), &data));
EXPECT_EQ(1ul, data.size());
EXPECT_TRUE(base::ContainsValue(
- data, mojom::KeyValue::New(StdStringToUint8Vector("key2"),
- StdStringToUint8Vector("data2"))));
+ data, blink::mojom::KeyValue::New(StdStringToUint8Vector("key2"),
+ StdStringToUint8Vector("data2"))));
EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
.Times(1);
@@ -376,21 +372,59 @@ TEST_F(SessionStorageNamespaceImplMojoTest, RemoveOriginData) {
&database_, metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_),
std::map<std::vector<uint8_t>, SessionStorageDataMap*>());
- mojom::SessionStorageNamespacePtr ss_namespace;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace;
namespace_impl->Bind(mojo::MakeRequest(&ss_namespace), kTestProcessIdOrigin1);
- mojom::LevelDBWrapperAssociatedPtr leveldb_1;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_1;
ss_namespace->OpenArea(test_origin1_, mojo::MakeRequest(&leveldb_1));
ss_namespace.FlushForTesting();
+ // Create an observer to make sure the deletion is observed.
+ testing::StrictMock<test::MockLevelDBObserver> mock_observer;
+ mojo::AssociatedBinding<blink::mojom::StorageAreaObserver> observer_binding(
+ &mock_observer);
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo observer_ptr_info;
+ observer_binding.Bind(mojo::MakeRequest(&observer_ptr_info));
+ leveldb_1->AddObserver(std::move(observer_ptr_info));
+ leveldb_1.FlushForTesting();
+
+ base::RunLoop loop;
+ EXPECT_CALL(mock_observer, AllDeleted("\n"))
+ .WillOnce(base::test::RunClosure(loop.QuitClosure()));
+
EXPECT_CALL(listener_, OnCommitResult(DatabaseError::OK)).Times(1);
namespace_impl->RemoveOriginData(test_origin1_);
- std::vector<mojom::KeyValuePtr> data;
- DatabaseError status = test::GetAllSync(leveldb_1.get(), &data);
- EXPECT_EQ(DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(leveldb_1.get(), &data));
EXPECT_EQ(0ul, data.size());
+ // Check that the observer was notified.
+ loop.Run();
+
+ EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
+ .Times(1);
+ namespaces_.clear();
+}
+
+TEST_F(SessionStorageNamespaceImplMojoTest, RemoveOriginDataWithoutBinding) {
+ SessionStorageNamespaceImplMojo* namespace_impl =
+ CreateSessionStorageNamespaceImplMojo(test_namespace_id1_);
+
+ EXPECT_CALL(listener_,
+ OnDataMapCreation(StdStringToUint8Vector("0"), testing::_))
+ .Times(1);
+
+ namespace_impl->PopulateFromMetadata(
+ &database_, metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_),
+ std::map<std::vector<uint8_t>, SessionStorageDataMap*>());
+
+ base::RunLoop loop;
+ EXPECT_CALL(listener_, OnCommitResult(DatabaseError::OK))
+ .WillOnce(base::test::RunClosure(loop.QuitClosure()));
+ namespace_impl->RemoveOriginData(test_origin1_);
+ loop.Run();
+
EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
.Times(1);
namespaces_.clear();
@@ -410,9 +444,9 @@ TEST_F(SessionStorageNamespaceImplMojoTest, ProcessLockedToOtherOrigin) {
&database_, metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_),
std::map<std::vector<uint8_t>, SessionStorageDataMap*>());
- mojom::SessionStorageNamespacePtr ss_namespace;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace;
namespace_impl->Bind(mojo::MakeRequest(&ss_namespace), kTestProcessIdOrigin1);
- mojom::LevelDBWrapperAssociatedPtr leveldb_1;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_1;
ss_namespace->OpenArea(test_origin3_, mojo::MakeRequest(&leveldb_1));
ss_namespace.FlushForTesting();
EXPECT_TRUE(bad_message_called_);
@@ -423,7 +457,7 @@ TEST_F(SessionStorageNamespaceImplMojoTest, ProcessLockedToOtherOrigin) {
}
TEST_F(SessionStorageNamespaceImplMojoTest, PurgeUnused) {
- // Verifies that wrappers are kept alive after the area is unbound, and they
+ // Verifies that areas are kept alive after the area is unbound, and they
// are removed when PurgeUnboundWrappers() is called.
SessionStorageNamespaceImplMojo* namespace_impl =
CreateSessionStorageNamespaceImplMojo(test_namespace_id1_);
@@ -436,10 +470,10 @@ TEST_F(SessionStorageNamespaceImplMojoTest, PurgeUnused) {
&database_, metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_),
std::map<std::vector<uint8_t>, SessionStorageDataMap*>());
- mojom::SessionStorageNamespacePtr ss_namespace;
+ blink::mojom::SessionStorageNamespacePtr ss_namespace;
namespace_impl->Bind(mojo::MakeRequest(&ss_namespace), kTestProcessIdOrigin1);
- mojom::LevelDBWrapperAssociatedPtr leveldb_1;
+ blink::mojom::StorageAreaAssociatedPtr leveldb_1;
ss_namespace->OpenArea(test_origin1_, mojo::MakeRequest(&leveldb_1));
EXPECT_TRUE(namespace_impl->HasAreaForOrigin(test_origin1_));
@@ -448,11 +482,52 @@ TEST_F(SessionStorageNamespaceImplMojoTest, PurgeUnused) {
leveldb_1.reset();
EXPECT_TRUE(namespace_impl->HasAreaForOrigin(test_origin1_));
- namespace_impl->PurgeUnboundWrappers();
+ namespace_impl->PurgeUnboundAreas();
EXPECT_FALSE(namespace_impl->HasAreaForOrigin(test_origin1_));
namespaces_.clear();
}
+TEST_F(SessionStorageNamespaceImplMojoTest, NamespaceBindingPerOrigin) {
+ // Tries to open an area with a process that is locked to a different origin
+ // and verifies the bad message callback.
+ SessionStorageNamespaceImplMojo* namespace_impl =
+ CreateSessionStorageNamespaceImplMojo(test_namespace_id1_);
+
+ EXPECT_CALL(listener_,
+ OnDataMapCreation(StdStringToUint8Vector("0"), testing::_))
+ .Times(1);
+
+ namespace_impl->PopulateFromMetadata(
+ &database_, metadata_.GetOrCreateNamespaceEntry(test_namespace_id1_),
+ std::map<std::vector<uint8_t>, SessionStorageDataMap*>());
+
+ blink::mojom::SessionStorageNamespacePtr ss_namespace_o1;
+ namespace_impl->Bind(mojo::MakeRequest(&ss_namespace_o1),
+ kTestProcessIdOrigin1);
+ blink::mojom::StorageAreaAssociatedPtr leveldb_1;
+ ss_namespace_o1->OpenArea(test_origin1_, mojo::MakeRequest(&leveldb_1));
+ ss_namespace_o1.FlushForTesting();
+ EXPECT_FALSE(bad_message_called_);
+
+ EXPECT_CALL(listener_,
+ OnDataMapCreation(StdStringToUint8Vector("1"), testing::_))
+ .Times(1);
+
+ blink::mojom::SessionStorageNamespacePtr ss_namespace_o2;
+ namespace_impl->Bind(mojo::MakeRequest(&ss_namespace_o2),
+ kTestProcessIdOrigin3);
+ blink::mojom::StorageAreaAssociatedPtr leveldb_2;
+ ss_namespace_o2->OpenArea(test_origin3_, mojo::MakeRequest(&leveldb_2));
+ ss_namespace_o2.FlushForTesting();
+ EXPECT_FALSE(bad_message_called_);
+
+ EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("0")))
+ .Times(1);
+ EXPECT_CALL(listener_, OnDataMapDestruction(StdStringToUint8Vector("1")))
+ .Times(1);
+ namespaces_.clear();
+}
+
} // namespace
} // namespace content
diff --git a/chromium/content/browser/leveldb_wrapper_impl.cc b/chromium/content/browser/dom_storage/storage_area_impl.cc
index d3c5c994d71..63930ec6b94 100644
--- a/chromium/content/browser/leveldb_wrapper_impl.cc
+++ b/chromium/content/browser/dom_storage/storage_area_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/browser/leveldb_wrapper_impl.h"
+#include "content/browser/dom_storage/storage_area_impl.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
@@ -20,33 +20,33 @@ using leveldb::mojom::BatchedOperationPtr;
using leveldb::mojom::DatabaseError;
} // namespace
-LevelDBWrapperImpl::Delegate::~Delegate() {}
+StorageAreaImpl::Delegate::~Delegate() {}
-void LevelDBWrapperImpl::Delegate::MigrateData(
+void StorageAreaImpl::Delegate::MigrateData(
base::OnceCallback<void(std::unique_ptr<ValueMap>)> callback) {
std::move(callback).Run(nullptr);
}
-std::vector<LevelDBWrapperImpl::Change> LevelDBWrapperImpl::Delegate::FixUpData(
+std::vector<StorageAreaImpl::Change> StorageAreaImpl::Delegate::FixUpData(
const ValueMap& data) {
return std::vector<Change>();
}
-void LevelDBWrapperImpl::Delegate::OnMapLoaded(DatabaseError) {}
+void StorageAreaImpl::Delegate::OnMapLoaded(DatabaseError) {}
-bool LevelDBWrapperImpl::s_aggressive_flushing_enabled_ = false;
+bool StorageAreaImpl::s_aggressive_flushing_enabled_ = false;
-LevelDBWrapperImpl::RateLimiter::RateLimiter(size_t desired_rate,
- base::TimeDelta time_quantum)
+StorageAreaImpl::RateLimiter::RateLimiter(size_t desired_rate,
+ base::TimeDelta time_quantum)
: rate_(desired_rate), samples_(0), time_quantum_(time_quantum) {
DCHECK_GT(desired_rate, 0ul);
}
-base::TimeDelta LevelDBWrapperImpl::RateLimiter::ComputeTimeNeeded() const {
+base::TimeDelta StorageAreaImpl::RateLimiter::ComputeTimeNeeded() const {
return time_quantum_ * (samples_ / rate_);
}
-base::TimeDelta LevelDBWrapperImpl::RateLimiter::ComputeDelayNeeded(
+base::TimeDelta StorageAreaImpl::RateLimiter::ComputeDelayNeeded(
const base::TimeDelta elapsed_time) const {
base::TimeDelta time_needed = ComputeTimeNeeded();
if (time_needed > elapsed_time)
@@ -54,24 +54,22 @@ base::TimeDelta LevelDBWrapperImpl::RateLimiter::ComputeDelayNeeded(
return base::TimeDelta();
}
-LevelDBWrapperImpl::CommitBatch::CommitBatch() : clear_all_first(false) {}
-LevelDBWrapperImpl::CommitBatch::~CommitBatch() {}
+StorageAreaImpl::CommitBatch::CommitBatch() : clear_all_first(false) {}
+StorageAreaImpl::CommitBatch::~CommitBatch() {}
-LevelDBWrapperImpl::LevelDBWrapperImpl(
- leveldb::mojom::LevelDBDatabase* database,
- const std::string& prefix,
- Delegate* delegate,
- const Options& options)
- : LevelDBWrapperImpl(database,
- leveldb::StdStringToUint8Vector(prefix),
- delegate,
- options) {}
-
-LevelDBWrapperImpl::LevelDBWrapperImpl(
- leveldb::mojom::LevelDBDatabase* database,
- std::vector<uint8_t> prefix,
- Delegate* delegate,
- const Options& options)
+StorageAreaImpl::StorageAreaImpl(leveldb::mojom::LevelDBDatabase* database,
+ const std::string& prefix,
+ Delegate* delegate,
+ const Options& options)
+ : StorageAreaImpl(database,
+ leveldb::StdStringToUint8Vector(prefix),
+ delegate,
+ options) {}
+
+StorageAreaImpl::StorageAreaImpl(leveldb::mojom::LevelDBDatabase* database,
+ std::vector<uint8_t> prefix,
+ Delegate* delegate,
+ const Options& options)
: prefix_(std::move(prefix)),
delegate_(delegate),
database_(database),
@@ -86,17 +84,17 @@ LevelDBWrapperImpl::LevelDBWrapperImpl(
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)));
+ bindings_.set_connection_error_handler(
+ base::Bind(&StorageAreaImpl::OnConnectionError, base::Unretained(this)));
}
-LevelDBWrapperImpl::~LevelDBWrapperImpl() {
+StorageAreaImpl::~StorageAreaImpl() {
DCHECK(!has_pending_load_tasks());
if (commit_batch_)
CommitChanges();
}
-void LevelDBWrapperImpl::Bind(mojom::LevelDBWrapperRequest request) {
+void StorageAreaImpl::Bind(blink::mojom::StorageAreaRequest 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
@@ -106,11 +104,11 @@ void LevelDBWrapperImpl::Bind(mojom::LevelDBWrapperRequest request) {
// reaching late.
if (cache_mode_ == CacheMode::KEYS_ONLY_WHEN_POSSIBLE &&
bindings_.size() > 1) {
- SetCacheMode(LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES);
+ SetCacheMode(CacheMode::KEYS_AND_VALUES);
}
}
-std::unique_ptr<LevelDBWrapperImpl> LevelDBWrapperImpl::ForkToNewPrefix(
+std::unique_ptr<StorageAreaImpl> StorageAreaImpl::ForkToNewPrefix(
const std::string& new_prefix,
Delegate* delegate,
const Options& options) {
@@ -118,36 +116,36 @@ std::unique_ptr<LevelDBWrapperImpl> LevelDBWrapperImpl::ForkToNewPrefix(
options);
}
-std::unique_ptr<LevelDBWrapperImpl> LevelDBWrapperImpl::ForkToNewPrefix(
+std::unique_ptr<StorageAreaImpl> StorageAreaImpl::ForkToNewPrefix(
std::vector<uint8_t> new_prefix,
Delegate* delegate,
const Options& options) {
- auto forked_wrapper = std::make_unique<LevelDBWrapperImpl>(
+ auto forked_area = std::make_unique<StorageAreaImpl>(
database_, std::move(new_prefix), delegate, options);
- forked_wrapper->map_state_ = MapState::LOADING_FROM_FORK;
+ forked_area->map_state_ = MapState::LOADING_FROM_FORK;
if (IsMapLoaded()) {
- DoForkOperation(forked_wrapper->weak_ptr_factory_.GetWeakPtr());
+ DoForkOperation(forked_area->weak_ptr_factory_.GetWeakPtr());
} else {
- LoadMap(base::BindOnce(&LevelDBWrapperImpl::DoForkOperation,
+ LoadMap(base::BindOnce(&StorageAreaImpl::DoForkOperation,
weak_ptr_factory_.GetWeakPtr(),
- forked_wrapper->weak_ptr_factory_.GetWeakPtr()));
+ forked_area->weak_ptr_factory_.GetWeakPtr()));
}
- return forked_wrapper;
+ return forked_area;
}
-void LevelDBWrapperImpl::CancelAllPendingRequests() {
+void StorageAreaImpl::CancelAllPendingRequests() {
on_load_complete_tasks_.clear();
}
-void LevelDBWrapperImpl::EnableAggressiveCommitDelay() {
+void StorageAreaImpl::EnableAggressiveCommitDelay() {
s_aggressive_flushing_enabled_ = true;
}
-void LevelDBWrapperImpl::ScheduleImmediateCommit() {
+void StorageAreaImpl::ScheduleImmediateCommit() {
if (!on_load_complete_tasks_.empty()) {
- LoadMap(base::BindOnce(&LevelDBWrapperImpl::ScheduleImmediateCommit,
+ LoadMap(base::BindOnce(&StorageAreaImpl::ScheduleImmediateCommit,
base::Unretained(this)));
return;
}
@@ -157,9 +155,8 @@ void LevelDBWrapperImpl::ScheduleImmediateCommit() {
CommitChanges();
}
-void LevelDBWrapperImpl::OnMemoryDump(
- const std::string& name,
- base::trace_event::ProcessMemoryDump* pmd) {
+void StorageAreaImpl::OnMemoryDump(const std::string& name,
+ base::trace_event::ProcessMemoryDump* pmd) {
if (!IsMapLoaded())
return;
@@ -197,7 +194,7 @@ void LevelDBWrapperImpl::OnMemoryDump(
pmd->AddSuballocation(map_mad->guid(), system_allocator_name);
}
-void LevelDBWrapperImpl::PurgeMemory() {
+void StorageAreaImpl::PurgeMemory() {
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.
@@ -205,44 +202,46 @@ void LevelDBWrapperImpl::PurgeMemory() {
}
map_state_ = MapState::UNLOADED;
+ memory_used_ = 0;
keys_only_map_.clear();
keys_values_map_.clear();
}
-void LevelDBWrapperImpl::SetCacheModeForTesting(CacheMode cache_mode) {
+void StorageAreaImpl::SetCacheModeForTesting(CacheMode cache_mode) {
SetCacheMode(cache_mode);
}
-mojo::InterfacePtrSetElementId LevelDBWrapperImpl::AddObserver(
- mojom::LevelDBObserverAssociatedPtr observer) {
+mojo::InterfacePtrSetElementId StorageAreaImpl::AddObserver(
+ blink::mojom::StorageAreaObserverAssociatedPtr observer) {
if (cache_mode_ == CacheMode::KEYS_AND_VALUES)
observer->ShouldSendOldValueOnMutations(false);
return observers_.AddPtr(std::move(observer));
}
-bool LevelDBWrapperImpl::HasObserver(mojo::InterfacePtrSetElementId id) {
+bool StorageAreaImpl::HasObserver(mojo::InterfacePtrSetElementId id) {
return observers_.HasPtr(id);
}
-mojom::LevelDBObserverAssociatedPtr LevelDBWrapperImpl::RemoveObserver(
+blink::mojom::StorageAreaObserverAssociatedPtr StorageAreaImpl::RemoveObserver(
mojo::InterfacePtrSetElementId id) {
return observers_.RemovePtr(id);
}
-void LevelDBWrapperImpl::AddObserver(
- mojom::LevelDBObserverAssociatedPtrInfo observer) {
- AddObserver(mojom::LevelDBObserverAssociatedPtr(std::move(observer)));
+void StorageAreaImpl::AddObserver(
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo observer) {
+ AddObserver(
+ blink::mojom::StorageAreaObserverAssociatedPtr(std::move(observer)));
}
-void LevelDBWrapperImpl::Put(
+void StorageAreaImpl::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) {
if (!IsMapLoaded() || IsMapUpgradeNeeded()) {
- LoadMap(base::BindOnce(&LevelDBWrapperImpl::Put, base::Unretained(this),
- key, value, client_old_value, source,
+ LoadMap(base::BindOnce(&StorageAreaImpl::Put, base::Unretained(this), key,
+ value, client_old_value, source,
std::move(callback)));
return;
}
@@ -268,7 +267,7 @@ void LevelDBWrapperImpl::Put(
// 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 "
+ DVLOG(1) << "Storage area with prefix "
<< leveldb::Uint8VectorToStdString(prefix_)
<< ": past value has length of " << found->second << ", but:";
if (client_old_value) {
@@ -335,20 +334,20 @@ void LevelDBWrapperImpl::Put(
if (!old_value) {
// We added a new key/value pair.
observers_.ForAllPtrs(
- [&key, &value, &source](mojom::LevelDBObserver* observer) {
+ [&key, &value, &source](blink::mojom::StorageAreaObserver* observer) {
observer->KeyAdded(key, value, source);
});
} else {
// We changed the value for an existing key.
- observers_.ForAllPtrs(
- [&key, &value, &source, &old_value](mojom::LevelDBObserver* observer) {
- observer->KeyChanged(key, value, old_value.value(), source);
- });
+ observers_.ForAllPtrs([&key, &value, &source, &old_value](
+ blink::mojom::StorageAreaObserver* observer) {
+ observer->KeyChanged(key, value, old_value.value(), source);
+ });
}
std::move(callback).Run(true);
}
-void LevelDBWrapperImpl::Delete(
+void StorageAreaImpl::Delete(
const std::vector<uint8_t>& key,
const base::Optional<std::vector<uint8_t>>& client_old_value,
const std::string& source,
@@ -358,7 +357,7 @@ void LevelDBWrapperImpl::Delete(
// |client_old_value| can race. Thus any changes require checking for an
// upgrade.
if (!IsMapLoaded() || IsMapUpgradeNeeded()) {
- LoadMap(base::BindOnce(&LevelDBWrapperImpl::Delete, base::Unretained(this),
+ LoadMap(base::BindOnce(&StorageAreaImpl::Delete, base::Unretained(this),
key, client_old_value, source, std::move(callback)));
return;
}
@@ -381,7 +380,7 @@ void LevelDBWrapperImpl::Delete(
// 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 "
+ DVLOG(1) << "Storage area with prefix "
<< leveldb::Uint8VectorToStdString(prefix_)
<< ": past value has length of " << found->second << ", but:";
if (client_old_value) {
@@ -413,20 +412,19 @@ void LevelDBWrapperImpl::Delete(
}
observers_.ForAllPtrs(
- [&key, &source, &old_value](mojom::LevelDBObserver* observer) {
+ [&key, &source, &old_value](blink::mojom::StorageAreaObserver* observer) {
observer->KeyDeleted(key, old_value, source);
});
std::move(callback).Run(true);
}
-void LevelDBWrapperImpl::DeleteAll(const std::string& source,
- DeleteAllCallback callback) {
+void StorageAreaImpl::DeleteAll(const std::string& source,
+ DeleteAllCallback 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)));
+ LoadMap(base::BindOnce(&StorageAreaImpl::DeleteAll, base::Unretained(this),
+ source, std::move(callback)));
return;
}
@@ -455,15 +453,14 @@ void LevelDBWrapperImpl::DeleteAll(const std::string& source,
storage_used_ = 0;
memory_used_ = 0;
- observers_.ForAllPtrs(
- [&source](mojom::LevelDBObserver* observer) {
- observer->AllDeleted(source);
- });
+ observers_.ForAllPtrs([&source](blink::mojom::StorageAreaObserver* observer) {
+ observer->AllDeleted(source);
+ });
std::move(callback).Run(true);
}
-void LevelDBWrapperImpl::Get(const std::vector<uint8_t>& key,
- GetCallback callback) {
+void StorageAreaImpl::Get(const std::vector<uint8_t>& key,
+ GetCallback 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) {
@@ -471,8 +468,8 @@ void LevelDBWrapperImpl::Get(const std::vector<uint8_t>& key,
return;
}
if (!IsMapLoaded() || IsMapUpgradeNeeded()) {
- LoadMap(base::BindOnce(&LevelDBWrapperImpl::Get, base::Unretained(this),
- key, std::move(callback)));
+ LoadMap(base::BindOnce(&StorageAreaImpl::Get, base::Unretained(this), key,
+ std::move(callback)));
return;
}
@@ -484,41 +481,42 @@ void LevelDBWrapperImpl::Get(const std::vector<uint8_t>& key,
std::move(callback).Run(true, found->second);
}
-void LevelDBWrapperImpl::GetAll(
- mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo complete_callback,
+void StorageAreaImpl::GetAll(
+ blink::mojom::StorageAreaGetAllCallbackAssociatedPtrInfo complete_callback,
GetAllCallback 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),
+ LoadMap(base::BindOnce(&StorageAreaImpl::GetAll, base::Unretained(this),
std::move(complete_callback), std::move(callback)));
return;
}
- std::vector<mojom::KeyValuePtr> all;
+ std::vector<blink::mojom::KeyValuePtr> all;
for (const auto& it : keys_values_map_) {
- mojom::KeyValuePtr kv = mojom::KeyValue::New();
+ auto kv = blink::mojom::KeyValue::New();
kv->key = it.first;
kv->value = it.second;
all.push_back(std::move(kv));
}
- std::move(callback).Run(DatabaseError::OK, std::move(all));
+ std::move(callback).Run(true, std::move(all));
if (complete_callback.is_valid()) {
- mojom::LevelDBWrapperGetAllCallbackAssociatedPtr complete_ptr;
+ blink::mojom::StorageAreaGetAllCallbackAssociatedPtr complete_ptr;
complete_ptr.Bind(std::move(complete_callback));
complete_ptr->Complete(true);
}
}
-void LevelDBWrapperImpl::SetCacheMode(CacheMode cache_mode) {
+void StorageAreaImpl::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);
- });
+ observers_.ForAllPtrs(
+ [should_send_values](blink::mojom::StorageAreaObserver* 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
@@ -527,7 +525,7 @@ void LevelDBWrapperImpl::SetCacheMode(CacheMode cache_mode) {
UnloadMapIfPossible();
}
-void LevelDBWrapperImpl::OnConnectionError() {
+void StorageAreaImpl::OnConnectionError() {
if (!bindings_.empty())
return;
// If any tasks are waiting for load to complete, delay calling the
@@ -537,7 +535,7 @@ void LevelDBWrapperImpl::OnConnectionError() {
delegate_->OnNoBindings();
}
-void LevelDBWrapperImpl::LoadMap(base::OnceClosure completion_callback) {
+void StorageAreaImpl::LoadMap(base::OnceClosure completion_callback) {
DCHECK_NE(map_state_, MapState::LOADED_KEYS_AND_VALUES);
DCHECK(keys_values_map_.empty());
@@ -551,7 +549,7 @@ void LevelDBWrapperImpl::LoadMap(base::OnceClosure completion_callback) {
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.
+ // The changes to the area will be queued to on load tasks.
keys_only_map_.clear();
map_state_ = MapState::UNLOADED;
}
@@ -571,20 +569,19 @@ void LevelDBWrapperImpl::LoadMap(base::OnceClosure completion_callback) {
}
database_->GetPrefixed(prefix_,
- base::BindOnce(&LevelDBWrapperImpl::OnMapLoaded,
+ base::BindOnce(&StorageAreaImpl::OnMapLoaded,
weak_ptr_factory_.GetWeakPtr()));
}
-void LevelDBWrapperImpl::OnMapLoaded(
+void StorageAreaImpl::OnMapLoaded(
DatabaseError status,
std::vector<leveldb::mojom::KeyValuePtr> data) {
DCHECK(keys_values_map_.empty());
DCHECK_EQ(map_state_, MapState::LOADING_FROM_DATABASE);
if (data.empty() && status == DatabaseError::OK) {
- delegate_->MigrateData(
- base::BindOnce(&LevelDBWrapperImpl::OnGotMigrationData,
- weak_ptr_factory_.GetWeakPtr()));
+ delegate_->MigrateData(base::BindOnce(&StorageAreaImpl::OnGotMigrationData,
+ weak_ptr_factory_.GetWeakPtr()));
return;
}
keys_only_map_.clear();
@@ -635,7 +632,7 @@ void LevelDBWrapperImpl::OnMapLoaded(
OnLoadComplete();
}
-void LevelDBWrapperImpl::OnGotMigrationData(std::unique_ptr<ValueMap> data) {
+void StorageAreaImpl::OnGotMigrationData(std::unique_ptr<ValueMap> data) {
keys_only_map_.clear();
keys_values_map_ = data ? std::move(*data) : ValueMap();
map_state_ = MapState::LOADED_KEYS_AND_VALUES;
@@ -652,7 +649,7 @@ void LevelDBWrapperImpl::OnGotMigrationData(std::unique_ptr<ValueMap> data) {
OnLoadComplete();
}
-void LevelDBWrapperImpl::CalculateStorageAndMemoryUsed() {
+void StorageAreaImpl::CalculateStorageAndMemoryUsed() {
memory_used_ = 0;
storage_used_ = 0;
@@ -666,7 +663,7 @@ void LevelDBWrapperImpl::CalculateStorageAndMemoryUsed() {
}
}
-void LevelDBWrapperImpl::OnLoadComplete() {
+void StorageAreaImpl::OnLoadComplete() {
DCHECK(IsMapLoaded());
std::vector<base::OnceClosure> tasks;
@@ -695,7 +692,7 @@ void LevelDBWrapperImpl::OnLoadComplete() {
delegate_->OnNoBindings();
}
-void LevelDBWrapperImpl::CreateCommitBatchIfNeeded() {
+void StorageAreaImpl::CreateCommitBatchIfNeeded() {
if (commit_batch_)
return;
DCHECK(database_);
@@ -703,11 +700,11 @@ void LevelDBWrapperImpl::CreateCommitBatchIfNeeded() {
commit_batch_.reset(new CommitBatch());
BrowserThread::PostAfterStartupTask(
FROM_HERE, base::ThreadTaskRunnerHandle::Get(),
- base::BindOnce(&LevelDBWrapperImpl::StartCommitTimer,
+ base::BindOnce(&StorageAreaImpl::StartCommitTimer,
weak_ptr_factory_.GetWeakPtr()));
}
-void LevelDBWrapperImpl::StartCommitTimer() {
+void StorageAreaImpl::StartCommitTimer() {
if (!commit_batch_)
return;
@@ -719,25 +716,27 @@ void LevelDBWrapperImpl::StartCommitTimer() {
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
- base::BindOnce(&LevelDBWrapperImpl::CommitChanges,
+ base::BindOnce(&StorageAreaImpl::CommitChanges,
weak_ptr_factory_.GetWeakPtr()),
ComputeCommitDelay());
}
-base::TimeDelta LevelDBWrapperImpl::ComputeCommitDelay() const {
+base::TimeDelta StorageAreaImpl::ComputeCommitDelay() const {
if (s_aggressive_flushing_enabled_)
return base::TimeDelta::FromSeconds(1);
base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time_;
- base::TimeDelta delay = std::max(
- default_commit_delay_,
- std::max(commit_rate_limiter_.ComputeDelayNeeded(elapsed_time),
- data_rate_limiter_.ComputeDelayNeeded(elapsed_time)));
+ base::TimeDelta delay =
+ std::max(default_commit_delay_,
+ std::max(commit_rate_limiter_.ComputeDelayNeeded(elapsed_time),
+ data_rate_limiter_.ComputeDelayNeeded(elapsed_time)));
+ // TODO(mek): Rename histogram to match class name, or eliminate histogram
+ // entirely.
UMA_HISTOGRAM_LONG_TIMES("LevelDBWrapper.CommitDelay", delay);
return delay;
}
-void LevelDBWrapperImpl::CommitChanges() {
+void StorageAreaImpl::CommitChanges() {
// Note: commit_batch_ may be null if ScheduleImmediateCommit was called
// after a delayed commit task was scheduled.
if (!commit_batch_)
@@ -821,11 +820,11 @@ void LevelDBWrapperImpl::CommitChanges() {
// 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,
+ base::BindOnce(&StorageAreaImpl::OnCommitComplete,
weak_ptr_factory_.GetWeakPtr()));
}
-void LevelDBWrapperImpl::OnCommitComplete(DatabaseError error) {
+void StorageAreaImpl::OnCommitComplete(DatabaseError error) {
has_committed_data_ = true;
--commit_batches_in_flight_;
StartCommitTimer();
@@ -840,7 +839,7 @@ void LevelDBWrapperImpl::OnCommitComplete(DatabaseError error) {
delegate_->DidCommit(error);
}
-void LevelDBWrapperImpl::UnloadMapIfPossible() {
+void StorageAreaImpl::UnloadMapIfPossible() {
// Do not unload the map if:
// * The desired cache mode isn't key-only,
// * The map isn't a loaded key-value map,
@@ -876,9 +875,9 @@ void LevelDBWrapperImpl::UnloadMapIfPossible() {
CalculateStorageAndMemoryUsed();
}
-void LevelDBWrapperImpl::DoForkOperation(
- const base::WeakPtr<LevelDBWrapperImpl>& forked_wrapper) {
- if (!forked_wrapper)
+void StorageAreaImpl::DoForkOperation(
+ const base::WeakPtr<StorageAreaImpl>& forked_area) {
+ if (!forked_area)
return;
DCHECK(IsMapLoaded());
@@ -890,17 +889,17 @@ void LevelDBWrapperImpl::DoForkOperation(
if (has_changes_to_commit())
CommitChanges();
CreateCommitBatchIfNeeded();
- commit_batch_->copy_to_prefix = forked_wrapper->prefix_;
+ commit_batch_->copy_to_prefix = forked_area->prefix_;
CommitChanges();
}
- forked_wrapper->OnForkStateLoaded(database_ != nullptr, keys_values_map_,
- keys_only_map_);
+ forked_area->OnForkStateLoaded(database_ != nullptr, keys_values_map_,
+ keys_only_map_);
}
-void LevelDBWrapperImpl::OnForkStateLoaded(bool database_enabled,
- const ValueMap& value_map,
- const KeysOnlyMap& keys_only_map) {
+void StorageAreaImpl::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()) {
diff --git a/chromium/content/browser/leveldb_wrapper_impl.h b/chromium/content/browser/dom_storage/storage_area_impl.h
index 79075941452..4fbea92351d 100644
--- a/chromium/content/browser/leveldb_wrapper_impl.h
+++ b/chromium/content/browser/dom_storage/storage_area_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_BROWSER_LEVELDB_WRAPPER_IMPL_H_
-#define CONTENT_BROWSER_LEVELDB_WRAPPER_IMPL_H_
+#ifndef CONTENT_BROWSER_DOM_STORAGE_STORAGE_AREA_IMPL_H_
+#define CONTENT_BROWSER_DOM_STORAGE_STORAGE_AREA_IMPL_H_
#include <map>
#include <memory>
@@ -15,23 +15,23 @@
#include "base/macros.h"
#include "base/optional.h"
#include "base/time/time.h"
+#include "components/services/leveldb/public/interfaces/leveldb.mojom.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"
+#include "third_party/blink/public/mojom/dom_storage/storage_area.mojom.h"
namespace base {
namespace trace_event {
class ProcessMemoryDump;
}
-}
+} // namespace base
namespace content {
// This is a wrapper around a leveldb::mojom::LevelDBDatabase. Multiple
-// interface
-// pointers can be bound to the same object. The wrapper adds a couple of
-// features not found directly in leveldb.
+// interface pointers can be bound to the same object. The wrapper adds a couple
+// of features not found directly in leveldb.
// 1) Adds the given prefix, if any, to all keys. This allows the sharing of one
// database across many, possibly untrusted, consumers and ensuring that they
// can't access each other's values.
@@ -40,7 +40,7 @@ namespace content {
// 4) Throttles requests to avoid overwhelming the disk.
//
// The wrapper supports two different caching modes.
-class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
+class CONTENT_EXPORT StorageAreaImpl : public blink::mojom::StorageArea {
public:
using ValueMap = std::map<std::vector<uint8_t>, std::vector<uint8_t>>;
using ValueMapCallback = base::OnceCallback<void(std::unique_ptr<ValueMap>)>;
@@ -89,34 +89,34 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
// |Delegate::OnNoBindings| 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,
- Delegate* delegate,
- const Options& options);
- LevelDBWrapperImpl(leveldb::mojom::LevelDBDatabase* database,
- std::vector<uint8_t> prefix,
- Delegate* delegate,
- const Options& options);
+ StorageAreaImpl(leveldb::mojom::LevelDBDatabase* database,
+ const std::string& prefix,
+ Delegate* delegate,
+ const Options& options);
+ StorageAreaImpl(leveldb::mojom::LevelDBDatabase* database,
+ std::vector<uint8_t> prefix,
+ Delegate* delegate,
+ const Options& options);
- ~LevelDBWrapperImpl() override;
+ ~StorageAreaImpl() override;
- void Bind(mojom::LevelDBWrapperRequest request);
+ void Bind(blink::mojom::StorageAreaRequest request);
// Forks, or copies, all data in this prefix to another prefix.
- // Note: this object (the parent) must stay alive until the forked wrapper
+ // Note: this object (the parent) must stay alive until the forked area
// has been loaded (see initialized()).
- std::unique_ptr<LevelDBWrapperImpl> ForkToNewPrefix(
+ std::unique_ptr<StorageAreaImpl> ForkToNewPrefix(
const std::string& new_prefix,
Delegate* delegate,
const Options& options);
- std::unique_ptr<LevelDBWrapperImpl> ForkToNewPrefix(
+ std::unique_ptr<StorageAreaImpl> ForkToNewPrefix(
std::vector<uint8_t> 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
+ // area is unloaded (initialized() returns false), this will DROP all
+ // pending changes to the database, and any uninitialized areas created
// through |ForkToNewPrefix| will stay BROKEN and unresponsive.
void CancelAllPendingRequests();
@@ -127,7 +127,7 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
bool empty() const { return storage_used_ == 0; }
- // If this wrapper is loaded and sending changes to the database.
+ // If this ares is loaded and sending changes to the database.
bool initialized() const { return IsMapLoaded(); }
CacheMode cache_mode() const { return cache_mode_; }
@@ -169,13 +169,14 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
// Returns a pointer ID for use with HasObserver and RemoveObserver.
mojo::InterfacePtrSetElementId AddObserver(
- mojom::LevelDBObserverAssociatedPtr observer);
+ blink::mojom::StorageAreaObserverAssociatedPtr observer);
bool HasObserver(mojo::InterfacePtrSetElementId id);
- mojom::LevelDBObserverAssociatedPtr RemoveObserver(
+ blink::mojom::StorageAreaObserverAssociatedPtr RemoveObserver(
mojo::InterfacePtrSetElementId id);
- // LevelDBWrapper:
- void AddObserver(mojom::LevelDBObserverAssociatedPtrInfo observer) override;
+ // blink::mojom::StorageArea:
+ void AddObserver(
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo 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,
@@ -188,16 +189,16 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
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;
+ void GetAll(blink::mojom::StorageAreaGetAllCallbackAssociatedPtrInfo
+ complete_callback,
+ GetAllCallback callback) override;
private:
- FRIEND_TEST_ALL_PREFIXES(LevelDBWrapperImplTest, GetAllAfterSetCacheMode);
- FRIEND_TEST_ALL_PREFIXES(LevelDBWrapperImplTest,
+ FRIEND_TEST_ALL_PREFIXES(StorageAreaImplTest, GetAllAfterSetCacheMode);
+ FRIEND_TEST_ALL_PREFIXES(StorageAreaImplTest,
PutLoadsValuesAfterCacheModeUpgrade);
- FRIEND_TEST_ALL_PREFIXES(LevelDBWrapperImplTest, SetCacheModeConsistent);
- FRIEND_TEST_ALL_PREFIXES(LevelDBWrapperImplParamTest,
+ FRIEND_TEST_ALL_PREFIXES(StorageAreaImplTest, SetCacheModeConsistent);
+ FRIEND_TEST_ALL_PREFIXES(StorageAreaImplParamTest,
CommitOnDifferentCacheModes);
// Used to rate limit commits.
@@ -205,7 +206,7 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
public:
RateLimiter(size_t desired_rate, base::TimeDelta time_quantum);
- void add_samples(size_t samples) { samples_ += samples; }
+ void add_samples(size_t samples) { samples_ += samples; }
// Computes the total time needed to process the total samples seen
// at the desired rate.
@@ -243,7 +244,7 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
UNLOADED,
// Loading from the database connection.
LOADING_FROM_DATABASE,
- // Loading from another LevelDBWrapperImpl that we have forked from.
+ // Loading from another StorageAreaImpl that we have forked from.
LOADING_FROM_FORK,
LOADED_KEYS_ONLY,
LOADED_KEYS_AND_VALUES
@@ -254,7 +255,7 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
using ForkSourceEarlyDeathCallback =
base::OnceCallback<void(std::vector<uint8_t> source_prefix)>;
- // Changes the cache mode of the wrapper. If applicable, this will change the
+ // Changes the cache mode of the area. 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.
@@ -303,14 +304,14 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
keys_values_map_.empty());
}
- void DoForkOperation(const base::WeakPtr<LevelDBWrapperImpl>& forked_wrapper);
+ void DoForkOperation(const base::WeakPtr<StorageAreaImpl>& forked_area);
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_;
+ mojo::BindingSet<blink::mojom::StorageArea> bindings_;
+ mojo::AssociatedInterfacePtrSet<blink::mojom::StorageAreaObserver> observers_;
Delegate* delegate_;
leveldb::mojom::LevelDBDatabase* database_;
@@ -334,13 +335,13 @@ class CONTENT_EXPORT LevelDBWrapperImpl : public mojom::LevelDBWrapper {
bool has_committed_data_ = false;
std::unique_ptr<CommitBatch> commit_batch_;
- base::WeakPtrFactory<LevelDBWrapperImpl> weak_ptr_factory_;
+ base::WeakPtrFactory<StorageAreaImpl> weak_ptr_factory_;
static bool s_aggressive_flushing_enabled_;
- DISALLOW_COPY_AND_ASSIGN(LevelDBWrapperImpl);
+ DISALLOW_COPY_AND_ASSIGN(StorageAreaImpl);
};
} // namespace content
-#endif // CONTENT_BROWSER_LEVELDB_WRAPPER_IMPL_H_
+#endif // CONTENT_BROWSER_DOM_STORAGE_STORAGE_AREA_IMPL_H_
diff --git a/chromium/content/browser/leveldb_wrapper_impl_unittest.cc b/chromium/content/browser/dom_storage/storage_area_impl_unittest.cc
index ac80a72e4c4..4b0d1190af7 100644
--- a/chromium/content/browser/leveldb_wrapper_impl_unittest.cc
+++ b/chromium/content/browser/dom_storage/storage_area_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/leveldb_wrapper_impl.h"
+#include "content/browser/dom_storage/storage_area_impl.h"
#include "base/atomic_ref_count.h"
#include "base/bind.h"
@@ -15,9 +15,9 @@
#include "base/threading/thread.h"
#include "components/services/leveldb/public/cpp/util.h"
#include "components/services/leveldb/public/interfaces/leveldb.mojom.h"
+#include "content/browser/dom_storage/test/storage_area_test_util.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/test/fake_leveldb_database.h"
-#include "content/test/leveldb_wrapper_test_util.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"
@@ -29,7 +29,7 @@ namespace {
using test::MakeSuccessCallback;
using test::MakeGetAllCallback;
using test::GetAllCallback;
-using CacheMode = LevelDBWrapperImpl::CacheMode;
+using CacheMode = StorageAreaImpl::CacheMode;
using DatabaseError = leveldb::mojom::DatabaseError;
const char* kTestSource = "source";
@@ -90,7 +90,7 @@ class IncrementalBarrier {
DISALLOW_COPY_AND_ASSIGN(IncrementalBarrier);
};
-class MockDelegate : public LevelDBWrapperImpl::Delegate {
+class MockDelegate : public StorageAreaImpl::Delegate {
public:
MockDelegate() {}
~MockDelegate() override {}
@@ -106,13 +106,13 @@ class MockDelegate : public LevelDBWrapperImpl::Delegate {
std::move(committed_).Run();
}
void OnMapLoaded(DatabaseError error) override { map_load_count_++; }
- std::vector<LevelDBWrapperImpl::Change> FixUpData(
- const LevelDBWrapperImpl::ValueMap& data) override {
+ std::vector<StorageAreaImpl::Change> FixUpData(
+ const StorageAreaImpl::ValueMap& data) override {
return std::move(mock_changes_);
}
int map_load_count() const { return map_load_count_; }
- void set_mock_changes(std::vector<LevelDBWrapperImpl::Change> changes) {
+ void set_mock_changes(std::vector<StorageAreaImpl::Change> changes) {
mock_changes_ = std::move(changes);
}
@@ -122,7 +122,7 @@ class MockDelegate : public LevelDBWrapperImpl::Delegate {
private:
int map_load_count_ = 0;
- std::vector<LevelDBWrapperImpl::Change> mock_changes_;
+ std::vector<StorageAreaImpl::Change> mock_changes_;
base::OnceClosure committed_;
};
@@ -144,8 +144,8 @@ base::OnceCallback<void(bool, const std::vector<uint8_t>&)> MakeGetCallback(
value_out);
}
-LevelDBWrapperImpl::Options GetDefaultTestingOptions(CacheMode cache_mode) {
- LevelDBWrapperImpl::Options options;
+StorageAreaImpl::Options GetDefaultTestingOptions(CacheMode cache_mode) {
+ StorageAreaImpl::Options options;
options.max_size = kTestSizeLimit;
options.default_commit_delay = base::TimeDelta::FromSeconds(5);
options.max_bytes_per_hour = 10 * 1024 * 1024;
@@ -156,8 +156,8 @@ LevelDBWrapperImpl::Options GetDefaultTestingOptions(CacheMode cache_mode) {
} // namespace
-class LevelDBWrapperImplTest : public testing::Test,
- public mojom::LevelDBObserver {
+class StorageAreaImplTest : public testing::Test,
+ public blink::mojom::StorageAreaObserver {
public:
struct Observation {
enum { kAdd, kChange, kDelete, kDeleteAll, kSendOldValue } type;
@@ -168,26 +168,26 @@ class LevelDBWrapperImplTest : public testing::Test,
bool should_send_old_value;
};
- LevelDBWrapperImplTest() : db_(&mock_data_), observer_binding_(this) {
+ StorageAreaImplTest() : db_(&mock_data_), observer_binding_(this) {
auto request = mojo::MakeRequest(&level_db_database_ptr_);
db_.Bind(std::move(request));
- LevelDBWrapperImpl::Options options =
+ StorageAreaImpl::Options options =
GetDefaultTestingOptions(CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
- level_db_wrapper_ = std::make_unique<LevelDBWrapperImpl>(
+ storage_area_ = std::make_unique<StorageAreaImpl>(
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_));
- mojom::LevelDBObserverAssociatedPtrInfo ptr_info;
+ storage_area_->Bind(mojo::MakeRequest(&storage_area_ptr_));
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo ptr_info;
observer_binding_.Bind(mojo::MakeRequest(&ptr_info));
- level_db_wrapper_ptr_->AddObserver(std::move(ptr_info));
+ storage_area_ptr_->AddObserver(std::move(ptr_info));
}
- ~LevelDBWrapperImplTest() override {}
+ ~StorageAreaImplTest() override {}
void set_mock_data(const std::string& key, const std::string& value) {
mock_data_[ToBytes(key)] = ToBytes(value);
@@ -208,58 +208,57 @@ class LevelDBWrapperImplTest : public testing::Test,
void clear_mock_data() { mock_data_.clear(); }
- mojom::LevelDBWrapper* wrapper() { return level_db_wrapper_ptr_.get(); }
- LevelDBWrapperImpl* wrapper_impl() { return level_db_wrapper_.get(); }
+ blink::mojom::StorageArea* storage_area() { return storage_area_ptr_.get(); }
+ StorageAreaImpl* storage_area_impl() { return storage_area_.get(); }
- void FlushWrapperBinding() { level_db_wrapper_ptr_.FlushForTesting(); }
+ void FlushAreaBinding() { storage_area_ptr_.FlushForTesting(); }
- bool GetSync(mojom::LevelDBWrapper* wrapper,
+ bool GetSync(blink::mojom::StorageArea* area,
const std::vector<uint8_t>& key,
std::vector<uint8_t>* result) {
bool success = false;
base::RunLoop loop;
- wrapper->Get(key, MakeGetCallback(loop.QuitClosure(), &success, result));
+ area->Get(key, MakeGetCallback(loop.QuitClosure(), &success, result));
loop.Run();
return success;
}
bool DeleteSync(
- mojom::LevelDBWrapper* wrapper,
+ blink::mojom::StorageArea* area,
const std::vector<uint8_t>& key,
const base::Optional<std::vector<uint8_t>>& client_old_value) {
- return test::DeleteSync(wrapper, key, client_old_value, test_source_);
+ return test::DeleteSync(area, key, client_old_value, test_source_);
}
- bool DeleteAllSync(mojom::LevelDBWrapper* wrapper) {
- return test::DeleteAllSync(wrapper, test_source_);
+ bool DeleteAllSync(blink::mojom::StorageArea* area) {
+ return test::DeleteAllSync(area, test_source_);
}
bool GetSync(const std::vector<uint8_t>& key, std::vector<uint8_t>* result) {
- return GetSync(wrapper(), key, result);
+ return GetSync(storage_area(), 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 test::PutSync(wrapper(), key, value, client_old_value, source);
+ return test::PutSync(storage_area(), 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);
+ return DeleteSync(storage_area(), key, client_old_value);
}
- bool DeleteAllSync() { return DeleteAllSync(wrapper()); }
+ bool DeleteAllSync() { return DeleteAllSync(storage_area()); }
- std::string GetSyncStrUsingGetAll(LevelDBWrapperImpl* wrapper_impl,
+ std::string GetSyncStrUsingGetAll(StorageAreaImpl* area_impl,
const std::string& key) {
- std::vector<mojom::KeyValuePtr> data;
- leveldb::mojom::DatabaseError status =
- test::GetAllSyncOnDedicatedPipe(wrapper_impl, &data);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ bool success = test::GetAllSyncOnDedicatedPipe(area_impl, &data);
- if (status != leveldb::mojom::DatabaseError::OK)
+ if (!success)
return "";
for (const auto& key_value : data) {
@@ -270,14 +269,13 @@ class LevelDBWrapperImplTest : public testing::Test,
return "";
}
- void BlockingCommit() { BlockingCommit(&delegate_, level_db_wrapper_.get()); }
+ void BlockingCommit() { BlockingCommit(&delegate_, storage_area_.get()); }
- void BlockingCommit(MockDelegate* delegate, LevelDBWrapperImpl* wrapper) {
- while (wrapper->has_pending_load_tasks() ||
- wrapper->has_changes_to_commit()) {
+ void BlockingCommit(MockDelegate* delegate, StorageAreaImpl* area) {
+ while (area->has_pending_load_tasks() || area->has_changes_to_commit()) {
base::RunLoop loop;
delegate->SetDidCommitCallback(loop.QuitClosure());
- wrapper->ScheduleImmediateCommit();
+ area->ScheduleImmediateCommit();
loop.Run();
}
}
@@ -344,28 +342,27 @@ class LevelDBWrapperImplTest : public testing::Test,
FakeLevelDBDatabase db_;
leveldb::mojom::LevelDBDatabasePtr level_db_database_ptr_;
MockDelegate delegate_;
- std::unique_ptr<LevelDBWrapperImpl> level_db_wrapper_;
- mojom::LevelDBWrapperPtr level_db_wrapper_ptr_;
- mojo::AssociatedBinding<mojom::LevelDBObserver> observer_binding_;
+ std::unique_ptr<StorageAreaImpl> storage_area_;
+ blink::mojom::StorageAreaPtr storage_area_ptr_;
+ mojo::AssociatedBinding<blink::mojom::StorageAreaObserver> observer_binding_;
std::vector<Observation> observations_;
bool should_record_send_old_value_observations_ = false;
};
-class LevelDBWrapperImplParamTest
- : public LevelDBWrapperImplTest,
- public testing::WithParamInterface<CacheMode> {
+class StorageAreaImplParamTest : public StorageAreaImplTest,
+ public testing::WithParamInterface<CacheMode> {
public:
- LevelDBWrapperImplParamTest() {}
- ~LevelDBWrapperImplParamTest() override {}
+ StorageAreaImplParamTest() {}
+ ~StorageAreaImplParamTest() override {}
};
-INSTANTIATE_TEST_CASE_P(LevelDBWrapperImplTest,
- LevelDBWrapperImplParamTest,
+INSTANTIATE_TEST_CASE_P(StorageAreaImplTest,
+ StorageAreaImplParamTest,
testing::Values(CacheMode::KEYS_ONLY_WHEN_POSSIBLE,
CacheMode::KEYS_AND_VALUES));
-TEST_F(LevelDBWrapperImplTest, GetLoadedFromMap) {
- wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+TEST_F(StorageAreaImplTest, GetLoadedFromMap) {
+ storage_area_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
std::vector<uint8_t> result;
EXPECT_TRUE(GetSync(test_key2_bytes_, &result));
EXPECT_EQ(test_value2_bytes_, result);
@@ -373,8 +370,8 @@ TEST_F(LevelDBWrapperImplTest, GetLoadedFromMap) {
EXPECT_FALSE(GetSync(ToBytes("x"), &result));
}
-TEST_F(LevelDBWrapperImplTest, GetFromPutOverwrite) {
- wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+TEST_F(StorageAreaImplTest, GetFromPutOverwrite) {
+ storage_area_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
std::vector<uint8_t> key = test_key2_bytes_;
std::vector<uint8_t> value = ToBytes("foo");
@@ -384,9 +381,10 @@ TEST_F(LevelDBWrapperImplTest, GetFromPutOverwrite) {
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));
+ storage_area()->Put(key, value, test_value2_bytes_, test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success));
+ storage_area()->Get(key,
+ MakeGetCallback(barrier.Get(), &get_success, &result));
}
loop.Run();
@@ -396,8 +394,8 @@ TEST_F(LevelDBWrapperImplTest, GetFromPutOverwrite) {
EXPECT_EQ(value, result);
}
-TEST_F(LevelDBWrapperImplTest, GetFromPutNewKey) {
- wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+TEST_F(StorageAreaImplTest, GetFromPutNewKey) {
+ storage_area_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
std::vector<uint8_t> key = ToBytes("newkey");
std::vector<uint8_t> value = ToBytes("foo");
@@ -408,43 +406,42 @@ TEST_F(LevelDBWrapperImplTest, GetFromPutNewKey) {
EXPECT_EQ(value, result);
}
-TEST_F(LevelDBWrapperImplTest, PutLoadsValuesAfterCacheModeUpgrade) {
+TEST_F(StorageAreaImplTest, 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());
+ ASSERT_EQ(CacheMode::KEYS_ONLY_WHEN_POSSIBLE,
+ storage_area_impl()->cache_mode());
// Do a put to load the key-only cache.
EXPECT_TRUE(PutSync(key, value1, base::nullopt));
BlockingCommit();
- EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_ONLY,
- wrapper_impl()->map_state_);
+ EXPECT_EQ(StorageAreaImpl::MapState::LOADED_KEYS_ONLY,
+ storage_area_impl()->map_state_);
// Change cache mode.
- wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+ storage_area_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
// Loading new map isn't necessary yet.
- EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_ONLY,
- wrapper_impl()->map_state_);
+ EXPECT_EQ(StorageAreaImpl::MapState::LOADED_KEYS_ONLY,
+ storage_area_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_);
+ EXPECT_EQ(StorageAreaImpl::MapState::LOADED_KEYS_AND_VALUES,
+ storage_area_impl()->map_state_);
}
-TEST_P(LevelDBWrapperImplParamTest, GetAll) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
+TEST_P(StorageAreaImplParamTest, GetAll) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
- std::vector<mojom::KeyValuePtr> data;
- leveldb::mojom::DatabaseError status = test::GetAllSync(wrapper(), &data);
-
- EXPECT_EQ(leveldb::mojom::DatabaseError::OK, status);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(storage_area(), &data));
EXPECT_EQ(2u, data.size());
}
-TEST_P(LevelDBWrapperImplParamTest, CommitPutToDB) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
+TEST_P(StorageAreaImplParamTest, CommitPutToDB) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
std::string key1 = test_key2_;
std::string value1 = "foo";
std::string key2 = test_prefix_;
@@ -457,15 +454,15 @@ TEST_P(LevelDBWrapperImplParamTest, CommitPutToDB) {
{
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));
+ storage_area()->Put(ToBytes(key1), ToBytes(value1), test_value2_bytes_,
+ test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success1));
+ storage_area()->Put(ToBytes(key2), ToBytes("old value"), base::nullopt,
+ test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success2));
+ storage_area()->Put(ToBytes(key2), ToBytes(value2), ToBytes("old value"),
+ test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success3));
}
loop.Run();
@@ -482,8 +479,8 @@ TEST_P(LevelDBWrapperImplParamTest, CommitPutToDB) {
EXPECT_EQ(value2, get_mock_data(test_prefix_ + key2));
}
-TEST_P(LevelDBWrapperImplParamTest, PutObservations) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
+TEST_P(StorageAreaImplParamTest, PutObservations) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
std::string key = "new_key";
std::string value1 = "foo";
std::string value2 = "data abc";
@@ -510,14 +507,14 @@ TEST_P(LevelDBWrapperImplParamTest, PutObservations) {
ASSERT_EQ(2u, observations().size());
}
-TEST_P(LevelDBWrapperImplParamTest, DeleteNonExistingKey) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
+TEST_P(StorageAreaImplParamTest, DeleteNonExistingKey) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
EXPECT_TRUE(DeleteSync(ToBytes("doesn't exist"), std::vector<uint8_t>()));
EXPECT_EQ(0u, observations().size());
}
-TEST_P(LevelDBWrapperImplParamTest, DeleteExistingKey) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
+TEST_P(StorageAreaImplParamTest, DeleteExistingKey) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
std::string key = "newkey";
std::string value = "foo";
set_mock_data(test_prefix_ + key, value);
@@ -535,8 +532,8 @@ TEST_P(LevelDBWrapperImplParamTest, DeleteExistingKey) {
EXPECT_FALSE(has_mock_data(test_prefix_ + key));
}
-TEST_P(LevelDBWrapperImplParamTest, DeleteAllWithoutLoadedMap) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
+TEST_P(StorageAreaImplParamTest, DeleteAllWithoutLoadedMap) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
std::string key = "newkey";
std::string value = "foo";
std::string dummy_key = "foobar";
@@ -564,8 +561,8 @@ TEST_P(LevelDBWrapperImplParamTest, DeleteAllWithoutLoadedMap) {
std::vector<uint8_t>(), base::nullopt));
}
-TEST_P(LevelDBWrapperImplParamTest, DeleteAllWithLoadedMap) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
+TEST_P(StorageAreaImplParamTest, DeleteAllWithLoadedMap) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
std::string key = "newkey";
std::string value = "foo";
std::string dummy_key = "foobar";
@@ -585,15 +582,15 @@ TEST_P(LevelDBWrapperImplParamTest, DeleteAllWithLoadedMap) {
EXPECT_TRUE(has_mock_data(dummy_key));
}
-TEST_P(LevelDBWrapperImplParamTest, DeleteAllWithPendingMapLoad) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
+TEST_P(StorageAreaImplParamTest, DeleteAllWithPendingMapLoad) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
std::string key = "newkey";
std::string value = "foo";
std::string dummy_key = "foobar";
set_mock_data(dummy_key, value);
- wrapper()->Put(ToBytes(key), ToBytes(value), base::nullopt, kTestSource,
- base::DoNothing());
+ storage_area()->Put(ToBytes(key), ToBytes(value), base::nullopt, kTestSource,
+ base::DoNothing());
EXPECT_TRUE(DeleteAllSync());
ASSERT_EQ(2u, observations().size());
@@ -607,17 +604,16 @@ TEST_P(LevelDBWrapperImplParamTest, DeleteAllWithPendingMapLoad) {
EXPECT_TRUE(has_mock_data(dummy_key));
}
-TEST_P(LevelDBWrapperImplParamTest, DeleteAllWithoutLoadedEmptyMap) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
+TEST_P(StorageAreaImplParamTest, DeleteAllWithoutLoadedEmptyMap) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
clear_mock_data();
EXPECT_TRUE(DeleteAllSync());
ASSERT_EQ(0u, observations().size());
}
-TEST_F(LevelDBWrapperImplParamTest, PutOverQuotaLargeValue) {
- wrapper_impl()->SetCacheModeForTesting(
- LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES);
+TEST_F(StorageAreaImplParamTest, PutOverQuotaLargeValue) {
+ storage_area_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
std::vector<uint8_t> key = ToBytes("newkey");
std::vector<uint8_t> value(kTestSizeLimit, 4);
@@ -627,9 +623,8 @@ TEST_F(LevelDBWrapperImplParamTest, PutOverQuotaLargeValue) {
EXPECT_TRUE(PutSync(key, value, base::nullopt));
}
-TEST_F(LevelDBWrapperImplParamTest, PutOverQuotaLargeKey) {
- wrapper_impl()->SetCacheModeForTesting(
- LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES);
+TEST_F(StorageAreaImplParamTest, PutOverQuotaLargeKey) {
+ storage_area_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
std::vector<uint8_t> key(kTestSizeLimit, 'a');
std::vector<uint8_t> value = ToBytes("newvalue");
@@ -639,9 +634,8 @@ TEST_F(LevelDBWrapperImplParamTest, PutOverQuotaLargeKey) {
EXPECT_TRUE(PutSync(key, value, base::nullopt));
}
-TEST_F(LevelDBWrapperImplParamTest, PutWhenAlreadyOverQuota) {
- wrapper_impl()->SetCacheModeForTesting(
- LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES);
+TEST_F(StorageAreaImplParamTest, PutWhenAlreadyOverQuota) {
+ storage_area_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
std::string key = "largedata";
std::vector<uint8_t> value(kTestSizeLimit, 4);
std::vector<uint8_t> old_value = value;
@@ -674,9 +668,8 @@ TEST_F(LevelDBWrapperImplParamTest, PutWhenAlreadyOverQuota) {
EXPECT_FALSE(PutSync(ToBytes(key), value, old_value));
}
-TEST_F(LevelDBWrapperImplParamTest, PutWhenAlreadyOverQuotaBecauseOfLargeKey) {
- wrapper_impl()->SetCacheModeForTesting(
- LevelDBWrapperImpl::CacheMode::KEYS_AND_VALUES);
+TEST_F(StorageAreaImplParamTest, PutWhenAlreadyOverQuotaBecauseOfLargeKey) {
+ storage_area_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
std::vector<uint8_t> key(kTestSizeLimit, 'x');
std::vector<uint8_t> value = ToBytes("value");
std::vector<uint8_t> old_value = value;
@@ -698,8 +691,8 @@ TEST_F(LevelDBWrapperImplParamTest, PutWhenAlreadyOverQuotaBecauseOfLargeKey) {
EXPECT_FALSE(PutSync(key, value, old_value));
}
-TEST_P(LevelDBWrapperImplParamTest, PutAfterPurgeMemory) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
+TEST_P(StorageAreaImplParamTest, PutAfterPurgeMemory) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
std::vector<uint8_t> result;
const auto key = test_key2_bytes_;
const auto value = test_value2_bytes_;
@@ -710,15 +703,15 @@ TEST_P(LevelDBWrapperImplParamTest, PutAfterPurgeMemory) {
EXPECT_TRUE(PutSync(key, value, value));
EXPECT_EQ(delegate()->map_load_count(), 1);
- wrapper_impl()->PurgeMemory();
+ storage_area_impl()->PurgeMemory();
// Now adding should still work, and load map again.
EXPECT_TRUE(PutSync(key, value, value));
EXPECT_EQ(delegate()->map_load_count(), 2);
}
-TEST_P(LevelDBWrapperImplParamTest, PurgeMemoryWithPendingChanges) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
+TEST_P(StorageAreaImplParamTest, PurgeMemoryWithPendingChanges) {
+ storage_area_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_));
@@ -726,24 +719,23 @@ TEST_P(LevelDBWrapperImplParamTest, PurgeMemoryWithPendingChanges) {
// Purge memory, and read. Should not actually have purged, so should not have
// triggered a load.
- wrapper_impl()->PurgeMemory();
+ storage_area_impl()->PurgeMemory();
EXPECT_TRUE(PutSync(key, value, value));
EXPECT_EQ(delegate()->map_load_count(), 1);
}
-TEST_P(LevelDBWrapperImplParamTest, FixUpData) {
- wrapper_impl()->SetCacheModeForTesting(GetParam());
- std::vector<LevelDBWrapperImpl::Change> changes;
+TEST_P(StorageAreaImplParamTest, FixUpData) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
+ std::vector<StorageAreaImpl::Change> changes;
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));
- std::vector<mojom::KeyValuePtr> data;
- leveldb::mojom::DatabaseError status = test::GetAllSync(wrapper(), &data);
+ std::vector<blink::mojom::KeyValuePtr> data;
+ EXPECT_TRUE(test::GetAllSync(storage_area(), &data));
- 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));
@@ -755,46 +747,46 @@ TEST_P(LevelDBWrapperImplParamTest, FixUpData) {
EXPECT_EQ("bla", get_mock_data(test_prefix_ + test_prefix_));
}
-TEST_F(LevelDBWrapperImplTest, SetOnlyKeysWithoutDatabase) {
+TEST_F(StorageAreaImplTest, SetOnlyKeysWithoutDatabase) {
std::vector<uint8_t> key = test_key2_bytes_;
std::vector<uint8_t> value = ToBytes("foo");
MockDelegate delegate;
- LevelDBWrapperImpl level_db_wrapper(
+ StorageAreaImpl storage_area(
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));
+ blink::mojom::StorageAreaPtr storage_area_ptr;
+ storage_area.Bind(mojo::MakeRequest(&storage_area_ptr));
// Setting only keys mode is noop.
- level_db_wrapper.SetCacheModeForTesting(CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
+ storage_area.SetCacheModeForTesting(CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
- EXPECT_FALSE(level_db_wrapper.initialized());
- EXPECT_EQ(CacheMode::KEYS_AND_VALUES, level_db_wrapper.cache_mode());
+ EXPECT_FALSE(storage_area.initialized());
+ EXPECT_EQ(CacheMode::KEYS_AND_VALUES, storage_area.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));
+ storage_area.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));
+ storage_area.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());
+TEST_P(StorageAreaImplParamTest, CommitOnDifferentCacheModes) {
+ storage_area_impl()->SetCacheModeForTesting(GetParam());
std::vector<uint8_t> key = test_key2_bytes_;
std::vector<uint8_t> value = ToBytes("foo");
std::vector<uint8_t> value2 = ToBytes("foo2");
@@ -802,29 +794,29 @@ TEST_P(LevelDBWrapperImplParamTest, CommitOnDifferentCacheModes) {
// 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_);
+ ASSERT_TRUE(storage_area_impl()->commit_batch_);
- // Wrapper stays in CacheMode::KEYS_AND_VALUES until the first commit has
+ // Area stays in CacheMode::KEYS_AND_VALUES until the first commit has
// succeeded.
- EXPECT_TRUE(wrapper_impl()->commit_batch_->changed_values.empty());
- auto* changes = &wrapper_impl()->commit_batch_->changed_keys;
+ EXPECT_TRUE(storage_area_impl()->commit_batch_->changed_values.empty());
+ auto* changes = &storage_area_impl()->commit_batch_->changed_keys;
ASSERT_EQ(1u, changes->size());
EXPECT_EQ(key, *changes->begin());
BlockingCommit();
ASSERT_TRUE(PutSync(key, value2, value));
- ASSERT_TRUE(wrapper_impl()->commit_batch_);
+ ASSERT_TRUE(storage_area_impl()->commit_batch_);
// Commit has occured, so the map type will diverge based on the cache mode.
if (GetParam() == CacheMode::KEYS_AND_VALUES) {
- EXPECT_TRUE(wrapper_impl()->commit_batch_->changed_values.empty());
- auto* changes = &wrapper_impl()->commit_batch_->changed_keys;
+ EXPECT_TRUE(storage_area_impl()->commit_batch_->changed_values.empty());
+ auto* changes = &storage_area_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;
+ EXPECT_TRUE(storage_area_impl()->commit_batch_->changed_keys.empty());
+ auto* changes = &storage_area_impl()->commit_batch_->changed_values;
ASSERT_EQ(1u, changes->size());
auto it = changes->begin();
EXPECT_EQ(key, it->first);
@@ -835,21 +827,21 @@ TEST_P(LevelDBWrapperImplParamTest, CommitOnDifferentCacheModes) {
EXPECT_EQ("foo2", get_mock_data(test_prefix_ + test_key2_));
if (GetParam() == CacheMode::KEYS_AND_VALUES)
- EXPECT_EQ(2u, wrapper_impl()->keys_values_map_.size());
+ EXPECT_EQ(2u, storage_area_impl()->keys_values_map_.size());
else
- EXPECT_EQ(2u, wrapper_impl()->keys_only_map_.size());
+ EXPECT_EQ(2u, storage_area_impl()->keys_only_map_.size());
ASSERT_TRUE(PutSync(key, value2, value2));
- EXPECT_FALSE(wrapper_impl()->commit_batch_);
+ EXPECT_FALSE(storage_area_impl()->commit_batch_);
ASSERT_TRUE(PutSync(key, value3, value2));
- ASSERT_TRUE(wrapper_impl()->commit_batch_);
+ ASSERT_TRUE(storage_area_impl()->commit_batch_);
if (GetParam() == CacheMode::KEYS_AND_VALUES) {
- auto* changes = &wrapper_impl()->commit_batch_->changed_keys;
+ auto* changes = &storage_area_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;
+ auto* changes = &storage_area_impl()->commit_batch_->changed_values;
EXPECT_EQ(1u, changes->size());
auto it = changes->find(key);
ASSERT_NE(it, changes->end());
@@ -857,13 +849,13 @@ TEST_P(LevelDBWrapperImplParamTest, CommitOnDifferentCacheModes) {
}
clear_mock_data();
- EXPECT_TRUE(wrapper_impl()->has_changes_to_commit());
+ EXPECT_TRUE(storage_area_impl()->has_changes_to_commit());
BlockingCommit();
EXPECT_EQ("foobar", get_mock_data(test_prefix_ + test_key2_));
- EXPECT_FALSE(wrapper_impl()->has_changes_to_commit());
+ EXPECT_FALSE(storage_area_impl()->has_changes_to_commit());
}
-TEST_F(LevelDBWrapperImplTest, GetAllWhenCacheOnlyKeys) {
+TEST_F(StorageAreaImplTest, GetAllWhenCacheOnlyKeys) {
std::vector<uint8_t> key = test_key2_bytes_;
std::vector<uint8_t> value = ToBytes("foo");
std::vector<uint8_t> value2 = ToBytes("foobar");
@@ -872,10 +864,10 @@ TEST_F(LevelDBWrapperImplTest, GetAllWhenCacheOnlyKeys) {
ASSERT_TRUE(PutSync(key, value, base::nullopt));
BlockingCommit();
ASSERT_TRUE(PutSync(key, value2, value));
- EXPECT_TRUE(wrapper_impl()->has_changes_to_commit());
+ EXPECT_TRUE(storage_area_impl()->has_changes_to_commit());
- leveldb::mojom::DatabaseError status;
- std::vector<mojom::KeyValuePtr> data;
+ bool get_all_success = false;
+ std::vector<blink::mojom::KeyValuePtr> data;
bool result = false;
base::RunLoop loop;
@@ -885,14 +877,15 @@ TEST_F(LevelDBWrapperImplTest, GetAllWhenCacheOnlyKeys) {
{
IncrementalBarrier barrier(loop.QuitClosure());
- wrapper()->Put(key, value, value2, test_source_,
- MakeSuccessCallback(barrier.Get(), &put_result1));
+ storage_area()->Put(key, value, value2, test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_result1));
- wrapper()->GetAll(GetAllCallback::CreateAndBind(&result, barrier.Get()),
- MakeGetAllCallback(&status, &data));
- wrapper()->Put(key, value2, value, test_source_,
- MakeSuccessCallback(barrier.Get(), &put_result2));
- FlushWrapperBinding();
+ storage_area()->GetAll(
+ GetAllCallback::CreateAndBind(&result, barrier.Get()),
+ MakeGetAllCallback(&get_all_success, &data));
+ storage_area()->Put(key, value2, value, test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_result2));
+ FlushAreaBinding();
}
// GetAll triggers a commit when it's switching map types.
@@ -907,24 +900,24 @@ TEST_F(LevelDBWrapperImplTest, GetAllWhenCacheOnlyKeys) {
EXPECT_TRUE(put_result1);
EXPECT_EQ(2u, data.size());
- EXPECT_TRUE(
- data[1]->Equals(mojom::KeyValue(test_key1_bytes_, test_value1_bytes_)))
+ EXPECT_TRUE(data[1]->Equals(
+ blink::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)))
+ EXPECT_TRUE(data[0]->Equals(blink::mojom::KeyValue(key, value)))
<< ToString(data[0]->value) << " vs expected " << ToString(value);
- EXPECT_EQ(leveldb::mojom::DatabaseError::OK, status);
+ EXPECT_TRUE(get_all_success);
// 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());
+ ASSERT_TRUE(storage_area_impl()->has_changes_to_commit());
BlockingCommit();
EXPECT_EQ("foobar", get_mock_data(test_prefix_ + test_key2_));
}
-TEST_F(LevelDBWrapperImplTest, GetAllAfterSetCacheMode) {
+TEST_F(StorageAreaImplTest, GetAllAfterSetCacheMode) {
std::vector<uint8_t> key = test_key2_bytes_;
std::vector<uint8_t> value = ToBytes("foo");
std::vector<uint8_t> value2 = ToBytes("foobar");
@@ -932,55 +925,54 @@ TEST_F(LevelDBWrapperImplTest, GetAllAfterSetCacheMode) {
// 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);
+ EXPECT_TRUE(storage_area_impl()->map_state_ ==
+ StorageAreaImpl::MapState::LOADED_KEYS_ONLY);
ASSERT_TRUE(PutSync(key, value2, value));
- EXPECT_TRUE(wrapper_impl()->has_changes_to_commit());
+ EXPECT_TRUE(storage_area_impl()->has_changes_to_commit());
- wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+ storage_area_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);
+ EXPECT_TRUE(storage_area_impl()->map_state_ ==
+ StorageAreaImpl::MapState::LOADED_KEYS_ONLY);
base::RunLoop loop;
bool put_success = false;
- leveldb::mojom::DatabaseError status;
- std::vector<mojom::KeyValuePtr> data;
+ std::vector<blink::mojom::KeyValuePtr> data;
bool get_all_success = false;
+ bool get_all_callback_success = false;
bool delete_success = false;
{
IncrementalBarrier barrier(loop.QuitClosure());
- wrapper()->Put(key, value, value2, test_source_,
- MakeSuccessCallback(barrier.Get(), &put_success));
+ storage_area()->Put(key, value, value2, test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success));
// Put task triggers database upgrade, so there are no more changes
// to commit.
- FlushWrapperBinding();
- EXPECT_FALSE(wrapper_impl()->has_changes_to_commit());
- EXPECT_TRUE(wrapper_impl()->has_pending_load_tasks());
+ FlushAreaBinding();
+ EXPECT_FALSE(storage_area_impl()->has_changes_to_commit());
+ EXPECT_TRUE(storage_area_impl()->has_pending_load_tasks());
- wrapper()->GetAll(
+ storage_area()->GetAll(
GetAllCallback::CreateAndBind(&get_all_success, barrier.Get()),
- MakeGetAllCallback(&status, &data));
+ MakeGetAllCallback(&get_all_callback_success, &data));
// This Delete() should not affect the value returned by GetAll().
- wrapper()->Delete(key, value, test_source_,
- MakeSuccessCallback(barrier.Get(), &delete_success));
+ storage_area()->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_)))
+ EXPECT_TRUE(data[1]->Equals(
+ blink::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)))
+ EXPECT_TRUE(data[0]->Equals(blink::mojom::KeyValue(key, value)))
<< ToString(data[0]->value) << " vs expected " << ToString(value2);
- EXPECT_EQ(leveldb::mojom::DatabaseError::OK, status);
-
+ EXPECT_TRUE(get_all_callback_success);
EXPECT_TRUE(put_success);
EXPECT_TRUE(get_all_success);
EXPECT_TRUE(delete_success);
@@ -989,74 +981,77 @@ TEST_F(LevelDBWrapperImplTest, GetAllAfterSetCacheMode) {
// map should be loading.
EXPECT_EQ("foobar", get_mock_data(test_prefix_ + test_key2_));
- ASSERT_TRUE(wrapper_impl()->has_changes_to_commit());
+ ASSERT_TRUE(storage_area_impl()->has_changes_to_commit());
BlockingCommit();
EXPECT_FALSE(has_mock_data(test_prefix_ + test_key2_));
}
-TEST_F(LevelDBWrapperImplTest, SetCacheModeConsistent) {
+TEST_F(StorageAreaImplTest, 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() ==
+ EXPECT_FALSE(storage_area_impl()->IsMapLoaded());
+ EXPECT_TRUE(storage_area_impl()->cache_mode() ==
CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
- // Clear the database before the wrapper loads data.
+ // Clear the database before the area loads data.
clear_mock_data();
EXPECT_TRUE(PutSync(key, value, base::nullopt));
- EXPECT_TRUE(wrapper_impl()->has_changes_to_commit());
+ EXPECT_TRUE(storage_area_impl()->has_changes_to_commit());
BlockingCommit();
EXPECT_TRUE(PutSync(key, value2, value));
- EXPECT_TRUE(wrapper_impl()->has_changes_to_commit());
+ EXPECT_TRUE(storage_area_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_);
+ storage_area_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+ EXPECT_EQ(StorageAreaImpl::MapState::LOADED_KEYS_ONLY,
+ storage_area_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_);
+ EXPECT_TRUE(storage_area_impl()->has_changes_to_commit());
+ EXPECT_EQ(StorageAreaImpl::MapState::LOADED_KEYS_AND_VALUES,
+ storage_area_impl()->map_state_);
std::vector<uint8_t> result;
EXPECT_TRUE(GetSync(key, &result));
EXPECT_EQ(value, result);
- EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_AND_VALUES,
- wrapper_impl()->map_state_);
+ EXPECT_EQ(StorageAreaImpl::MapState::LOADED_KEYS_AND_VALUES,
+ storage_area_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_);
+ storage_area_impl()->SetCacheModeForTesting(
+ CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
+ EXPECT_EQ(StorageAreaImpl::MapState::LOADED_KEYS_ONLY,
+ storage_area_impl()->map_state_);
BlockingCommit();
- EXPECT_EQ(LevelDBWrapperImpl::MapState::LOADED_KEYS_ONLY,
- wrapper_impl()->map_state_);
+ EXPECT_EQ(StorageAreaImpl::MapState::LOADED_KEYS_ONLY,
+ storage_area_impl()->map_state_);
// Test the map will unload right away when there are no changes.
- wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+ storage_area_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_);
+ EXPECT_EQ(StorageAreaImpl::MapState::LOADED_KEYS_AND_VALUES,
+ storage_area_impl()->map_state_);
+ storage_area_impl()->SetCacheModeForTesting(
+ CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
+ EXPECT_EQ(StorageAreaImpl::MapState::LOADED_KEYS_ONLY,
+ storage_area_impl()->map_state_);
}
-TEST_F(LevelDBWrapperImplTest, SendOldValueObservations) {
+TEST_F(StorageAreaImplTest, SendOldValueObservations) {
should_record_send_old_value_observations(true);
- wrapper_impl()->SetCacheModeForTesting(CacheMode::KEYS_AND_VALUES);
+ storage_area_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);
+ storage_area_impl()->SetCacheModeForTesting(
+ CacheMode::KEYS_ONLY_WHEN_POSSIBLE);
// Flush tasks on mojo thread to observe callback.
EXPECT_TRUE(DeleteSync(ToBytes("doesn't exist"), base::nullopt));
@@ -1067,13 +1062,13 @@ TEST_F(LevelDBWrapperImplTest, SendOldValueObservations) {
EXPECT_TRUE(observations()[1].should_send_old_value);
}
-TEST_P(LevelDBWrapperImplParamTest, PrefixForking) {
+TEST_P(StorageAreaImplParamTest, 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
+ // forking can happen in between a request and reply to the area mojo
// service, all calls are done on the 'impl' object itself.
// Operations in the same run cycle:
@@ -1083,11 +1078,11 @@ TEST_P(LevelDBWrapperImplParamTest, PrefixForking) {
// Put on fork 1
// Put on original
// Fork 3 created from original
- std::unique_ptr<LevelDBWrapperImpl> fork1;
+ std::unique_ptr<StorageAreaImpl> fork1;
MockDelegate fork1_delegate;
- std::unique_ptr<LevelDBWrapperImpl> fork2;
+ std::unique_ptr<StorageAreaImpl> fork2;
MockDelegate fork2_delegate;
- std::unique_ptr<LevelDBWrapperImpl> fork3;
+ std::unique_ptr<StorageAreaImpl> fork3;
MockDelegate fork3_delegate;
auto options = GetDefaultTestingOptions(GetParam());
@@ -1099,8 +1094,8 @@ TEST_P(LevelDBWrapperImplParamTest, PrefixForking) {
IncrementalBarrier barrier(loop.QuitClosure());
// Create fork 1.
- fork1 = wrapper_impl()->ForkToNewPrefix(test_copy_prefix1_, &fork1_delegate,
- options);
+ fork1 = storage_area_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
@@ -1113,10 +1108,10 @@ TEST_P(LevelDBWrapperImplParamTest, PrefixForking) {
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(
+ storage_area_impl()->Put(test_key1_bytes_, ToBytes(value3),
+ test_value1_bytes_, test_source_,
+ MakeSuccessCallback(barrier.Get(), &put_success3));
+ fork3 = storage_area_impl()->ForkToNewPrefix(
test_copy_prefix3_, &fork3_delegate,
GetDefaultTestingOptions(CacheMode::KEYS_ONLY_WHEN_POSSIBLE));
}
@@ -1126,17 +1121,18 @@ TEST_P(LevelDBWrapperImplParamTest, PrefixForking) {
EXPECT_TRUE(fork2.get());
EXPECT_TRUE(fork3.get());
- EXPECT_EQ(value3, GetSyncStrUsingGetAll(wrapper_impl(), test_key1_));
+ EXPECT_EQ(value3, GetSyncStrUsingGetAll(storage_area_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(test_value2_,
+ GetSyncStrUsingGetAll(storage_area_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(delegate(), storage_area_impl());
BlockingCommit(&fork1_delegate, fork1.get());
// test_key1_ values.
@@ -1152,7 +1148,7 @@ TEST_P(LevelDBWrapperImplParamTest, PrefixForking) {
EXPECT_EQ(test_value2_, get_mock_data(test_copy_prefix3_ + test_key2_));
}
-TEST_P(LevelDBWrapperImplParamTest, PrefixForkAfterLoad) {
+TEST_P(StorageAreaImplParamTest, PrefixForkAfterLoad) {
const std::string kValue = "foo";
const std::vector<uint8_t> kValueVec = ToBytes(kValue);
@@ -1161,14 +1157,14 @@ TEST_P(LevelDBWrapperImplParamTest, PrefixForkAfterLoad) {
// Execute the fork.
MockDelegate fork1_delegate;
- std::unique_ptr<LevelDBWrapperImpl> fork1 =
- wrapper_impl()->ForkToNewPrefix(test_copy_prefix1_, &fork1_delegate,
- GetDefaultTestingOptions(GetParam()));
+ std::unique_ptr<StorageAreaImpl> fork1 = storage_area_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());
+ BlockingCommit(delegate(), storage_area_impl());
EXPECT_EQ(kValue, get_mock_data(test_copy_prefix1_ + test_key1_));
}
@@ -1186,38 +1182,38 @@ struct FuzzState {
};
} // namespace
-TEST_F(LevelDBWrapperImplTest, PrefixForkingPsuedoFuzzer) {
+TEST_F(StorageAreaImplTest, 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;
+ const int kTotalAreas = 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
+ // forking at areas. 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::vector<FuzzState> states(kTotalAreas);
+ std::vector<std::unique_ptr<StorageAreaImpl>> areas(kTotalAreas);
+ std::vector<MockDelegate> delegates(kTotalAreas);
std::list<bool> successes;
int curr_prefix = 0;
base::RunLoop loop;
{
IncrementalBarrier barrier(loop.QuitClosure());
- for (int64_t i = 0; i < kTotalWrappers; i++) {
+ for (int64_t i = 0; i < kTotalAreas; i++) {
FuzzState& state = states[i];
- if (!wrappers[i]) {
- wrappers[i] = wrapper_impl()->ForkToNewPrefix(
+ if (!areas[i]) {
+ areas[i] = storage_area_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) {
+ if ((i % 5 == 0 || i % 6 == 0) && forks + 1 < kTotalAreas) {
forks++;
states[forks] = state;
- wrappers[forks] = wrappers[i]->ForkToNewPrefix(
+ areas[forks] = areas[i]->ForkToNewPrefix(
GetNewPrefix(&curr_prefix), &delegates[forks],
GetDefaultTestingOptions(CacheMode::KEYS_AND_VALUES));
}
@@ -1225,42 +1221,41 @@ TEST_F(LevelDBWrapperImplTest, PrefixForkingPsuedoFuzzer) {
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()));
+ areas[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()));
+ areas[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()));
+ areas[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(
+ areas[i]->DeleteAll(
test_source_,
MakeSuccessCallback(barrier.Get(), &successes.back()));
}
- if (i % 2 == 0 && forks + 1 < kTotalWrappers) {
+ if (i % 2 == 0 && forks + 1 < kTotalAreas) {
CacheMode mode = i % 3 == 0 ? CacheMode::KEYS_AND_VALUES
: CacheMode::KEYS_ONLY_WHEN_POSSIBLE;
forks++;
states[forks] = state;
- wrappers[forks] = wrappers[i]->ForkToNewPrefix(
+ areas[forks] = areas[i]->ForkToNewPrefix(
GetNewPrefix(&curr_prefix), &delegates[forks],
GetDefaultTestingOptions(mode));
}
@@ -1269,23 +1264,23 @@ TEST_F(LevelDBWrapperImplTest, PrefixForkingPsuedoFuzzer) {
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()));
+ areas[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++) {
+ // areas (which may or may not be maintaining their own cache).
+ for (size_t i = 0; i < kTotalAreas; 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);
+ // Note: this will cause all keys-only areas to commit.
+ std::string result1 = GetSyncStrUsingGetAll(areas[i].get(), kKey1);
+ std::string result2 = GetSyncStrUsingGetAll(areas[i].get(), kKey2);
EXPECT_EQ(!!state.val1, !result1.empty()) << i;
if (state.val1)
EXPECT_EQ(state.val1.value(), ToBytes(result1));
@@ -1294,24 +1289,24 @@ TEST_F(LevelDBWrapperImplTest, PrefixForkingPsuedoFuzzer) {
EXPECT_EQ(state.val2.value(), ToBytes(result2)) << i;
}
- // This section verifies that all wrappers have committed their changes to
+ // This section verifies that all areas have committed their changes to
// the database.
- ASSERT_EQ(wrappers.size(), delegates.size());
- size_t half = kTotalWrappers / 2;
+ ASSERT_EQ(areas.size(), delegates.size());
+ size_t half = kTotalAreas / 2;
for (size_t i = 0; i < half; i++) {
- BlockingCommit(&delegates[i], wrappers[i].get());
+ BlockingCommit(&delegates[i], areas[i].get());
}
- for (size_t i = kTotalWrappers - 1; i >= half; i--) {
- BlockingCommit(&delegates[i], wrappers[i].get());
+ for (size_t i = kTotalAreas - 1; i >= half; i--) {
+ BlockingCommit(&delegates[i], areas[i].get());
}
- // This section checks the data in the database itself to verify all wrappers
+ // This section checks the data in the database itself to verify all areas
// committed changes correctly.
- for (size_t i = 0; i < kTotalWrappers; ++i) {
+ for (size_t i = 0; i < kTotalAreas; ++i) {
FuzzState& state = states[i];
- std::vector<uint8_t> prefix = wrappers[i]->prefix();
+ std::vector<uint8_t> prefix = areas[i]->prefix();
std::string key1 = ToString(prefix) + kKey1;
std::string key2 = ToString(prefix) + kKey2;
EXPECT_EQ(!!state.val1, has_mock_data(key1));
@@ -1321,7 +1316,7 @@ TEST_F(LevelDBWrapperImplTest, PrefixForkingPsuedoFuzzer) {
if (state.val2)
EXPECT_EQ(ToString(state.val2.value()), get_mock_data(key2));
- EXPECT_FALSE(wrappers[i]->has_pending_load_tasks()) << i;
+ EXPECT_FALSE(areas[i]->has_pending_load_tasks()) << i;
}
}
diff --git a/chromium/content/browser/download/blob_download_url_loader_factory_getter.cc b/chromium/content/browser/download/blob_download_url_loader_factory_getter.cc
deleted file mode 100644
index d5d418186a1..00000000000
--- a/chromium/content/browser/download/blob_download_url_loader_factory_getter.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/download/blob_download_url_loader_factory_getter.h"
-
-#include "components/download/public/common/download_task_runner.h"
-#include "content/browser/url_loader_factory_getter.h"
-#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
-#include "services/network/public/mojom/url_loader_factory.mojom.h"
-#include "storage/browser/blob/blob_data_handle.h"
-#include "storage/browser/blob/blob_url_loader_factory.h"
-
-namespace content {
-
-BlobDownloadURLLoaderFactoryGetter::BlobDownloadURLLoaderFactoryGetter(
- const GURL& url,
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle)
- : url_(url), blob_data_handle_(std::move(blob_data_handle)) {
- DCHECK(url.SchemeIs(url::kBlobScheme));
-}
-
-BlobDownloadURLLoaderFactoryGetter::~BlobDownloadURLLoaderFactoryGetter() =
- default;
-
-scoped_refptr<network::SharedURLLoaderFactory>
-BlobDownloadURLLoaderFactoryGetter::GetURLLoaderFactory() {
- DCHECK(download::GetIOTaskRunner());
- DCHECK(download::GetIOTaskRunner()->BelongsToCurrentThread());
- network::mojom::URLLoaderFactoryPtrInfo url_loader_factory_ptr_info;
- storage::BlobURLLoaderFactory::Create(
- std::move(blob_data_handle_), url_,
- mojo::MakeRequest(&url_loader_factory_ptr_info));
- return base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
- std::move(url_loader_factory_ptr_info));
-}
-
-} // namespace content
diff --git a/chromium/content/browser/download/blob_download_url_loader_factory_getter.h b/chromium/content/browser/download/blob_download_url_loader_factory_getter.h
deleted file mode 100644
index 10938f46c42..00000000000
--- a/chromium/content/browser/download/blob_download_url_loader_factory_getter.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_DOWNLOAD_BLOB_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
-#define CONTENT_BROWSER_DOWNLOAD_BLOB_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
-
-#include "components/download/public/common/download_url_loader_factory_getter.h"
-#include "url/gurl.h"
-
-namespace storage {
-class BlobDataHandle;
-}
-
-namespace content {
-
-// Class for retrieving the URLLoaderFactory for a blob URL.
-class BlobDownloadURLLoaderFactoryGetter
- : public download::DownloadURLLoaderFactoryGetter {
- public:
- BlobDownloadURLLoaderFactoryGetter(
- const GURL& url,
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle);
-
- // download::DownloadURLLoaderFactoryGetter implementation.
- scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
-
- protected:
- ~BlobDownloadURLLoaderFactoryGetter() override;
-
- private:
- GURL url_;
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle_;
-
- DISALLOW_COPY_AND_ASSIGN(BlobDownloadURLLoaderFactoryGetter);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_DOWNLOAD_BLOB_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
diff --git a/chromium/content/browser/download/download_browsertest.cc b/chromium/content/browser/download/download_browsertest.cc
index 1cae12047b7..58882960352 100644
--- a/chromium/content/browser/download/download_browsertest.cc
+++ b/chromium/content/browser/download/download_browsertest.cc
@@ -43,6 +43,7 @@
#include "content/public/browser/download_request_utils.h"
#include "content/public/browser/resource_throttle.h"
#include "content/public/common/content_paths.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/webplugininfo.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
@@ -67,6 +68,8 @@
#include "ppapi/buildflags/buildflags.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/platform/web_mouse_event.h"
#include "url/gurl.h"
#if BUILDFLAG(ENABLE_PLUGINS)
@@ -231,7 +234,7 @@ class DownloadFileWithDelayFactory : public download::DownloadFileFactory {
private:
std::vector<base::Closure> rename_callbacks_;
- bool waiting_;
+ base::OnceClosure stop_waiting_;
base::WeakPtrFactory<DownloadFileWithDelayFactory> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(DownloadFileWithDelayFactory);
@@ -288,8 +291,7 @@ void DownloadFileWithDelay::RenameCallbackWrapper(
}
DownloadFileWithDelayFactory::DownloadFileWithDelayFactory()
- : waiting_(false),
- weak_ptr_factory_(this) {}
+ : weak_ptr_factory_(this) {}
DownloadFileWithDelayFactory::~DownloadFileWithDelayFactory() {}
@@ -307,8 +309,8 @@ download::DownloadFile* DownloadFileWithDelayFactory::CreateFile(
void DownloadFileWithDelayFactory::AddRenameCallback(base::Closure callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
rename_callbacks_.push_back(std::move(callback));
- if (waiting_)
- base::RunLoop::QuitCurrentWhenIdleDeprecated();
+ if (stop_waiting_)
+ std::move(stop_waiting_).Run();
}
void DownloadFileWithDelayFactory::GetAllRenameCallbacks(
@@ -321,9 +323,9 @@ void DownloadFileWithDelayFactory::WaitForSomeCallback() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (rename_callbacks_.empty()) {
- waiting_ = true;
- RunMessageLoop();
- waiting_ = false;
+ base::RunLoop run_loop;
+ stop_waiting_ = run_loop.QuitClosure();
+ run_loop.Run();
}
}
@@ -366,11 +368,12 @@ class CountingDownloadFile : public download::DownloadFileImpl {
// until data is returned.
static int GetNumberActiveFilesFromFileThread() {
int result = -1;
+ base::RunLoop run_loop;
download::GetDownloadTaskRunner()->PostTaskAndReply(
FROM_HERE,
base::BindOnce(&CountingDownloadFile::GetNumberActiveFiles, &result),
- base::RunLoop::QuitCurrentWhenIdleClosureDeprecated());
- base::RunLoop().Run();
+ run_loop.QuitClosure());
+ run_loop.Run();
DCHECK_NE(-1, result);
return result;
}
@@ -2893,10 +2896,9 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete());
}
-// A filename suggestion specified via a @download attribute should be effective
-// if the final download URL is in the same origin as the initial download URL.
-// Test that this holds even if there are cross origin redirects in the middle
-// of the redirect chain.
+// A filename suggestion specified via a @download attribute should not be
+// effective if there are cross origin redirects in the middle of the redirect
+// chain.
IN_PROC_BROWSER_TEST_F(DownloadContentTest,
DownloadAttributeSameOriginRedirect) {
net::EmbeddedTestServer origin_one;
@@ -2939,12 +2941,135 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest,
DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
ASSERT_EQ(1u, downloads.size());
- EXPECT_EQ(FILE_PATH_LITERAL("suggested-filename"),
+ EXPECT_EQ(FILE_PATH_LITERAL("download"),
downloads[0]->GetTargetFilePath().BaseName().value());
ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete());
ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete());
}
+// A file type that Blink can handle should not be downloaded if there are cross
+// origin redirects in the middle of the redirect chain.
+IN_PROC_BROWSER_TEST_F(DownloadContentTest,
+ DownloadAttributeSameOriginRedirectNavigation) {
+ net::EmbeddedTestServer origin_one;
+ net::EmbeddedTestServer origin_two;
+ ASSERT_TRUE(origin_one.InitializeAndListen());
+ ASSERT_TRUE(origin_two.InitializeAndListen());
+
+ // The download-attribute.html page contains an anchor element whose href is
+ // set to the value of the query parameter (specified as |target| in the URL
+ // below). The suggested filename for the anchor is 'suggested-filename'. When
+ // the page is loaded, a script simulates a click on the anchor, triggering a
+ // download of the target URL.
+ //
+ // We construct two test servers; origin_one and origin_two. Once started, the
+ // server URLs will differ by the port number. Therefore they will be in
+ // different origins.
+ GURL download_url = origin_one.GetURL("/ping");
+ GURL referrer_url = origin_one.GetURL(
+ std::string("/download-attribute.html?target=") + download_url.spec());
+ origin_one.ServeFilesFromDirectory(GetTestFilePath("download", ""));
+
+ // <origin_one>/download-attribute.html initiates a download of
+ // <origin_one>/ping, which redirects to <origin_two>/download. The latter
+ // serves an HTML document.
+ origin_one.RegisterRequestHandler(
+ CreateRedirectHandler("/ping", origin_two.GetURL("/download")));
+ origin_two.RegisterRequestHandler(
+ CreateBasicResponseHandler("/download", net::HTTP_OK, base::StringPairs(),
+ "text/html", "<title>hello</title>"));
+
+ origin_one.StartAcceptingConnections();
+ origin_two.StartAcceptingConnections();
+
+ base::string16 expected_title(base::UTF8ToUTF16("hello"));
+ TitleWatcher observer(shell()->web_contents(), expected_title);
+ NavigateToURL(shell(), referrer_url);
+ ASSERT_EQ(expected_title, observer.WaitAndGetTitle());
+
+ std::vector<download::DownloadItem*> downloads;
+ DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
+ ASSERT_EQ(0u, downloads.size());
+
+ ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete());
+ ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete());
+}
+
+// A download initiated by the user via alt-click on a link should download,
+// even when redirected cross origin.
+//
+// Alt-click doesn't make sense on Android, and download a HTML file results
+// in an intent, so just skip.
+#if !defined(OS_ANDROID)
+IN_PROC_BROWSER_TEST_F(DownloadContentTest,
+ DownloadAttributeSameOriginRedirectAltClick) {
+ net::EmbeddedTestServer origin_one;
+ net::EmbeddedTestServer origin_two;
+ ASSERT_TRUE(origin_one.InitializeAndListen());
+ ASSERT_TRUE(origin_two.InitializeAndListen());
+
+ // The download-attribute.html page contains an anchor element whose href is
+ // set to the value of the query parameter (specified as |target| in the URL
+ // below). The suggested filename for the anchor is 'suggested-filename'. We
+ // will later send a "real" click to the anchor, triggering a download of the
+ // target URL.
+ //
+ // We construct two test servers; origin_one and origin_two. Once started, the
+ // server URLs will differ by the port number. Therefore they will be in
+ // different origins.
+ GURL download_url = origin_one.GetURL("/ping");
+ GURL referrer_url = origin_one.GetURL(
+ std::string("/download-attribute.html?noclick=") + download_url.spec());
+ origin_one.ServeFilesFromDirectory(GetTestFilePath("download", ""));
+
+ // <origin_one>/download-attribute.html initiates a download of
+ // <origin_one>/ping, which redirects to <origin_two>/download. The latter
+ // serves an HTML document.
+ origin_one.RegisterRequestHandler(
+ CreateRedirectHandler("/ping", origin_two.GetURL("/download")));
+ origin_two.RegisterRequestHandler(
+ CreateBasicResponseHandler("/download", net::HTTP_OK, base::StringPairs(),
+ "text/html", "<title>hello</title>"));
+
+ origin_one.StartAcceptingConnections();
+ origin_two.StartAcceptingConnections();
+
+ std::unique_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1));
+ NavigateToURL(shell(), referrer_url);
+
+ // Alt-click the link.
+ blink::WebMouseEvent mouse_event(
+ blink::WebInputEvent::kMouseDown, blink::WebInputEvent::kAltKey,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
+ mouse_event.button = blink::WebMouseEvent::Button::kLeft;
+ mouse_event.SetPositionInWidget(15, 15);
+ mouse_event.click_count = 1;
+ shell()->web_contents()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
+ mouse_event);
+ mouse_event.SetType(blink::WebInputEvent::kMouseUp);
+ shell()->web_contents()->GetRenderViewHost()->GetWidget()->ForwardMouseEvent(
+ mouse_event);
+
+ observer->WaitForFinished();
+ EXPECT_EQ(
+ 1u, observer->NumDownloadsSeenInState(download::DownloadItem::COMPLETE));
+
+ std::vector<download::DownloadItem*> downloads;
+ DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
+ ASSERT_EQ(1u, downloads.size());
+#if defined(OS_WIN)
+ EXPECT_EQ(FILE_PATH_LITERAL("download.htm"),
+ downloads[0]->GetTargetFilePath().BaseName().value());
+#else
+ EXPECT_EQ(FILE_PATH_LITERAL("download.html"),
+ downloads[0]->GetTargetFilePath().BaseName().value());
+#endif
+
+ ASSERT_TRUE(origin_one.ShutdownAndWaitUntilComplete());
+ ASSERT_TRUE(origin_two.ShutdownAndWaitUntilComplete());
+}
+#endif // !defined(OS_ANDROID)
+
// Test that the suggested filename for data: URLs works.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeDataUrl) {
net::EmbeddedTestServer server;
@@ -2988,23 +3113,33 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeServerError) {
// should result in a network error page.
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeNetworkError) {
SetupErrorInjectionDownloads();
+ WebContents* content = shell()->web_contents();
GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
GURL server_url = embedded_test_server()->GetURL(url.host(), url.path());
- TestDownloadHttpResponse::Parameters parameters;
+ GURL document_url = embedded_test_server()->GetURL(
+ std::string("/download/download-attribute.html?target=") +
+ server_url.spec());
+
// Simulate a network failure by injecting an error before the response
// header.
+ TestDownloadHttpResponse::Parameters parameters;
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=") +
- server_url.spec());
- auto observer = std::make_unique<content::TestNavigationObserver>(
- shell()->web_contents(), 2);
- NavigateToURL(shell(), document_url);
- observer->Wait();
- EXPECT_FALSE(observer->last_navigation_succeeded());
+ content::TestNavigationManager navigation_document(content, document_url);
+ content::TestNavigationManager navigation_download(content, server_url);
+ shell()->LoadURL(document_url);
+ navigation_document.WaitForNavigationFinished();
+ navigation_download.WaitForNavigationFinished();
+
+ EXPECT_TRUE(navigation_document.was_successful());
+ EXPECT_FALSE(navigation_download.was_successful());
+
+ NavigationEntry* navigation_entry =
+ shell()->web_contents()->GetController().GetLastCommittedEntry();
+ EXPECT_EQ(PAGE_TYPE_ERROR, navigation_entry->GetPageType());
+ EXPECT_EQ(server_url, navigation_entry->GetURL());
}
// A request that fails due to it being rejected by policy should result in a
@@ -3031,6 +3166,28 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeBlobURL) {
download->GetTargetFilePath().BaseName().value().c_str());
}
+class DownloadContentTestWithMojoBlobURLs : public DownloadContentTest {
+ public:
+ DownloadContentTestWithMojoBlobURLs() {
+ scoped_feature_list_.InitAndEnableFeature(blink::features::kMojoBlobURLs);
+ }
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(DownloadContentTestWithMojoBlobURLs,
+ DownloadAttributeBlobURL) {
+ GURL document_url =
+ embedded_test_server()->GetURL("/download/download-attribute-blob.html");
+ download::DownloadItem* download =
+ StartDownloadAndReturnItem(shell(), document_url);
+ WaitForCompletion(download);
+
+ EXPECT_STREQ(FILE_PATH_LITERAL("suggested-filename.txt"),
+ download->GetTargetFilePath().BaseName().value().c_str());
+}
+
IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeSameSiteCookie) {
base::ThreadRestrictions::ScopedAllowIO allow_io_during_test;
net::EmbeddedTestServer test_server;
@@ -3470,41 +3627,92 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, FetchErrorResponseBodyResumption) {
std::string("header_value"));
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest,
- DISABLED_ForceDownloadMultipartRelatedPage) {
- // Force downloading the MHTML.
- DownloadTestContentBrowserClient new_client;
- new_client.set_allowed_rendering_mhtml_over_http(false);
- ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
+IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadFromWebUI) {
+ GURL webui_url("chrome://resources/images/apps/blue_button.png");
+ NavigateToURL(shell(), webui_url);
+ SetupEnsureNoPendingDownloads();
+ std::unique_ptr<download::DownloadUrlParameters> download_parameters(
+ DownloadRequestUtils::CreateDownloadForWebContentsMainFrame(
+ shell()->web_contents(), webui_url, TRAFFIC_ANNOTATION_FOR_TESTS));
+ std::unique_ptr<DownloadTestObserver> observer(CreateWaiter(shell(), 1));
+ DownloadManagerForShell(shell())->DownloadUrl(std::move(download_parameters));
+ observer->WaitForFinished();
+
+ EXPECT_TRUE(EnsureNoPendingDownloads());
+
+ std::vector<download::DownloadItem*> downloads;
+ DownloadManagerForShell(shell())->GetAllDownloads(&downloads);
+ ASSERT_EQ(1u, downloads.size());
+ ASSERT_EQ(download::DownloadItem::COMPLETE, downloads[0]->GetState());
+}
+
+// Test fixture for forcing MHTML download.
+class MhtmlDownloadTest : public DownloadContentTest {
+ protected:
+ void SetUpOnMainThread() override {
+ DownloadContentTest::SetUpOnMainThread();
+
+ // Force downloading the MHTML.
+ new_client_.set_allowed_rendering_mhtml_over_http(false);
+ old_client_ = SetBrowserClientForTesting(&new_client_);
+ }
+ void TearDownOnMainThread() override {
+ SetBrowserClientForTesting(old_client_);
+ DownloadContentTest::TearDownOnMainThread();
+ }
+
+ private:
+ DownloadTestContentBrowserClient new_client_;
+ ContentBrowserClient* old_client_;
+};
+
+IN_PROC_BROWSER_TEST_F(MhtmlDownloadTest, ForceDownloadMultipartRelatedPage) {
NavigateToURLAndWaitForDownload(
shell(),
// .mhtml file is mapped to "multipart/related" by the test server.
embedded_test_server()->GetURL("/download/hello.mhtml"),
download::DownloadItem::COMPLETE);
- SetBrowserClientForTesting(old_client);
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, ForceDownloadMessageRfc822Page) {
- // Force downloading the MHTML.
- DownloadTestContentBrowserClient new_client;
- new_client.set_allowed_rendering_mhtml_over_http(false);
- ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
-
+#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(ADDRESS_SANITIZER)
+// Flaky https://crbug.com/852073
+#define MAYBE_ForceDownloadMessageRfc822Page \
+ DISABLED_ForceDownloadMessageRfc822Page
+#else
+#define MAYBE_ForceDownloadMessageRfc822Page ForceDownloadMessageRfc822Page
+#endif
+IN_PROC_BROWSER_TEST_F(MhtmlDownloadTest,
+ MAYBE_ForceDownloadMessageRfc822Page) {
NavigateToURLAndWaitForDownload(
shell(),
// .mht file is mapped to "message/rfc822" by the test server.
embedded_test_server()->GetURL("/download/test.mht"),
download::DownloadItem::COMPLETE);
- SetBrowserClientForTesting(old_client);
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, AllowRenderMultipartRelatedPage) {
- // Allows loading the MHTML, instead of downloading it.
- DownloadTestContentBrowserClient new_client;
- new_client.set_allowed_rendering_mhtml_over_http(true);
- ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
+// Test fixture for loading MHTML.
+class MhtmlLoadingTest : public DownloadContentTest {
+ protected:
+ void SetUpOnMainThread() override {
+ DownloadContentTest::SetUpOnMainThread();
+
+ // Allows loading the MHTML, instead of downloading it.
+ new_client_.set_allowed_rendering_mhtml_over_http(true);
+ old_client_ = SetBrowserClientForTesting(&new_client_);
+ }
+
+ void TearDownOnMainThread() override {
+ SetBrowserClientForTesting(old_client_);
+ DownloadContentTest::TearDownOnMainThread();
+ }
+ private:
+ DownloadTestContentBrowserClient new_client_;
+ ContentBrowserClient* old_client_;
+};
+
+IN_PROC_BROWSER_TEST_F(MhtmlLoadingTest, AllowRenderMultipartRelatedPage) {
// .mhtml file is mapped to "multipart/related" by the test server.
GURL url = embedded_test_server()->GetURL("/download/hello.mhtml");
auto observer = std::make_unique<content::TestNavigationObserver>(url);
@@ -3514,15 +3722,9 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, AllowRenderMultipartRelatedPage) {
NavigateToURL(shell(), url);
observer->WaitForNavigationFinished();
- SetBrowserClientForTesting(old_client);
}
-IN_PROC_BROWSER_TEST_F(DownloadContentTest, AllowRenderMessageRfc822Page) {
- // Allows loading the MHTML, instead of downloading it.
- DownloadTestContentBrowserClient new_client;
- new_client.set_allowed_rendering_mhtml_over_http(true);
- ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client);
-
+IN_PROC_BROWSER_TEST_F(MhtmlLoadingTest, AllowRenderMessageRfc822Page) {
// .mht file is mapped to "message/rfc822" by the test server.
GURL url = embedded_test_server()->GetURL("/download/test.mht");
auto observer = std::make_unique<content::TestNavigationObserver>(url);
@@ -3532,7 +3734,6 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, AllowRenderMessageRfc822Page) {
NavigateToURL(shell(), url);
observer->WaitForNavigationFinished();
- SetBrowserClientForTesting(old_client);
}
} // namespace content
diff --git a/chromium/content/browser/download/download_manager_impl.cc b/chromium/content/browser/download/download_manager_impl.cc
index 081c7a2c2f1..f8c137fe6d7 100644
--- a/chromium/content/browser/download/download_manager_impl.cc
+++ b/chromium/content/browser/download/download_manager_impl.cc
@@ -21,8 +21,9 @@
#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_impl.h"
+#include "components/download/database/in_progress/download_entry.h"
+#include "components/download/database/in_progress/in_progress_cache_impl.h"
+#include "components/download/database/switches.h"
#include "components/download/public/common/download_create_info.h"
#include "components/download/public/common/download_file.h"
#include "components/download/public/common/download_interrupt_reasons.h"
@@ -38,14 +39,15 @@
#include "content/browser/byte_stream.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
-#include "content/browser/download/blob_download_url_loader_factory_getter.h"
#include "content/browser/download/byte_stream_input_stream.h"
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/download/download_url_loader_factory_getter_impl.h"
#include "content/browser/download/download_utils.h"
+#include "content/browser/download/file_download_url_loader_factory_getter.h"
#include "content/browser/download/network_download_url_loader_factory_getter.h"
#include "content/browser/download/url_downloader.h"
#include "content/browser/download/url_downloader_factory.h"
+#include "content/browser/download/web_ui_download_url_loader_factory_getter.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -112,6 +114,18 @@ bool CanRequestURLFromRenderer(int render_process_id, GURL url) {
return true;
}
+void OnDownloadStarted(
+ download::DownloadItemImpl* download,
+ const download::DownloadUrlParameters::OnStartedCallback& on_started) {
+ if (on_started.is_null())
+ return;
+
+ if (!download || download->GetState() == download::DownloadItem::CANCELLED)
+ on_started.Run(nullptr, download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
+ else
+ on_started.Run(download, download::DOWNLOAD_INTERRUPT_REASON_NONE);
+}
+
// Creates an interrupted download and calls StartDownload. Can be called on
// any thread.
void CreateInterruptedDownload(
@@ -136,7 +150,7 @@ void CreateInterruptedDownload(
void BeginDownload(std::unique_ptr<download::DownloadUrlParameters> params,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
content::ResourceContext* resource_context,
- uint32_t download_id,
+ bool is_new_download,
base::WeakPtr<DownloadManagerImpl> download_manager) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -146,7 +160,8 @@ void BeginDownload(std::unique_ptr<download::DownloadUrlParameters> params,
params->set_blob_storage_context_getter(
base::BindOnce(&BlobStorageContextGetter, resource_context));
std::unique_ptr<net::URLRequest> url_request =
- DownloadRequestCore::CreateRequestOnIOThread(download_id, params.get());
+ DownloadRequestCore::CreateRequestOnIOThread(is_new_download,
+ params.get());
if (blob_data_handle) {
storage::BlobProtocolHandler::SetRequestedBlobDataHandle(
url_request.get(), std::move(blob_data_handle));
@@ -288,17 +303,15 @@ DownloadManagerImpl::DownloadManagerImpl(BrowserContext* browser_context)
if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
download::UrlDownloadHandlerFactory::Install(new UrlDownloaderFactory());
in_progress_manager_ = std::make_unique<download::InProgressDownloadManager>(
- this, base::BindRepeating(&IsOriginSecure));
- in_progress_manager_->Initialize(
- IsOffTheRecord() ? base::FilePath() : browser_context_->GetPath(),
- base::BindOnce(&DownloadManagerImpl::PostInitialization,
- weak_factory_.GetWeakPtr(),
- DOWNLOAD_INITIALIZATION_DEPENDENCY_IN_PROGRESS_CACHE));
+ this, IsOffTheRecord() ? base::FilePath() : browser_context_->GetPath(),
+ base::BindRepeating(&IsOriginSecure));
+ in_progress_manager_->NotifyWhenInitialized(base::BindOnce(
+ &DownloadManagerImpl::OnInProgressDownloadManagerInitialized,
+ weak_factory_.GetWeakPtr()));
}
DownloadManagerImpl::~DownloadManagerImpl() {
DCHECK(!shutdown_needed_);
- download::SetIOTaskRunner(nullptr);
}
download::DownloadItemImpl* DownloadManagerImpl::CreateActiveItem(
@@ -311,6 +324,10 @@ download::DownloadItemImpl* DownloadManagerImpl::CreateActiveItem(
downloads_[id] = base::WrapUnique(download);
downloads_by_guid_[download->GetGuid()] = download;
+ DownloadItemUtils::AttachInfo(
+ download, GetBrowserContext(),
+ WebContentsImpl::FromRenderFrameHostID(info.render_process_id,
+ info.render_frame_id));
return download;
}
@@ -419,6 +436,25 @@ bool DownloadManagerImpl::InterceptDownload(
const download::DownloadCreateInfo& info) {
WebContents* web_contents = WebContentsImpl::FromRenderFrameHostID(
info.render_process_id, info.render_frame_id);
+ if (info.is_new_download &&
+ info.result ==
+ download::DOWNLOAD_INTERRUPT_REASON_SERVER_CROSS_ORIGIN_REDIRECT) {
+ if (web_contents) {
+ std::vector<GURL> url_chain(info.url_chain);
+ GURL url = url_chain.back();
+ url_chain.pop_back();
+ NavigationController::LoadURLParams params(url);
+ params.has_user_gesture = info.has_user_gesture;
+ params.referrer = Referrer(
+ info.referrer_url, Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+ info.referrer_policy));
+ params.redirect_chain = url_chain;
+ web_contents->GetController().LoadURLWithParams(params);
+ }
+ if (info.request_handle)
+ info.request_handle->CancelRequest(false);
+ return true;
+ }
if (!delegate_ ||
!delegate_->InterceptDownloadIfApplicable(
info.url(), info.mime_type, info.request_origin, web_contents)) {
@@ -455,37 +491,59 @@ base::FilePath DownloadManagerImpl::GetDefaultDownloadDirectory() {
return default_download_directory;
}
-void DownloadManagerImpl::OnNewDownloadStarted(
- download::DownloadItem* download) {
- for (auto& observer : observers_)
- observer.OnDownloadCreated(this, download);
+void DownloadManagerImpl::OnInProgressDownloadManagerInitialized() {
+ std::vector<std::unique_ptr<download::DownloadItemImpl>>
+ in_progress_downloads = in_progress_manager_->TakeInProgressDownloads();
+ for (auto& download : in_progress_downloads) {
+ DCHECK(!base::ContainsKey(downloads_by_guid_, download->GetGuid()));
+ DCHECK(!base::ContainsKey(downloads_, download->GetId()));
+ DownloadItemUtils::AttachInfo(download.get(), GetBrowserContext(), nullptr);
+ download::DownloadItemImpl* item = download.get();
+ item->SetDelegate(this);
+ downloads_by_guid_[download->GetGuid()] = item;
+ downloads_[download->GetId()] = std::move(download);
+ for (auto& observer : observers_)
+ observer.OnDownloadCreated(this, item);
+ DVLOG(20) << __func__ << "() download = " << item->DebugString(true);
+ }
+ PostInitialization(DOWNLOAD_INITIALIZATION_DEPENDENCY_IN_PROGRESS_CACHE);
}
-download::DownloadItemImpl* DownloadManagerImpl::GetDownloadItem(
- uint32_t id,
- bool new_download,
- const download::DownloadCreateInfo& info) {
+void DownloadManagerImpl::StartDownloadItem(
+ std::unique_ptr<download::DownloadCreateInfo> info,
+ const download::DownloadUrlParameters::OnStartedCallback& on_started,
+ download::InProgressDownloadManager::StartDownloadItemCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK_NE(download::DownloadItem::kInvalidId, id);
- download::DownloadItemImpl* download = nullptr;
- if (new_download) {
- download = CreateActiveItem(id, info);
+ if (!info->is_new_download) {
+ download::DownloadItemImpl* download = downloads_by_guid_[info->guid];
+ if (!download || download->GetState() == download::DownloadItem::CANCELLED)
+ download = nullptr;
+ std::move(callback).Run(std::move(info), download);
+ OnDownloadStarted(download, on_started);
} else {
- auto item_iterator = downloads_.find(id);
- // Trying to resume an interrupted download.
- if (item_iterator == downloads_.end() ||
- (item_iterator->second->GetState() ==
- download::DownloadItem::CANCELLED)) {
- return nullptr;
- }
- download = item_iterator->second.get();
+ GetNextId(
+ base::BindRepeating(&DownloadManagerImpl::CreateNewDownloadItemToStart,
+ weak_factory_.GetWeakPtr(), base::Passed(&info),
+ on_started, base::Passed(&callback)));
}
- DownloadItemUtils::AttachInfo(
- download, GetBrowserContext(),
- WebContentsImpl::FromRenderFrameHostID(info.render_process_id,
- info.render_frame_id));
- return download;
+}
+
+void DownloadManagerImpl::CreateNewDownloadItemToStart(
+ std::unique_ptr<download::DownloadCreateInfo> info,
+ const download::DownloadUrlParameters::OnStartedCallback& on_started,
+ download::InProgressDownloadManager::StartDownloadItemCallback callback,
+ uint32_t id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ download::DownloadItemImpl* download = CreateActiveItem(id, *info);
+ std::move(callback).Run(std::move(info), download);
+ // For new downloads, we notify here, rather than earlier, so that
+ // the download_file is bound to download and all the usual
+ // setters (e.g. Cancel) work.
+ for (auto& observer : observers_)
+ observer.OnDownloadCreated(this, download);
+ OnDownloadStarted(download, on_started);
}
net::URLRequestContextGetter* DownloadManagerImpl::GetURLRequestContextGetter(
@@ -517,6 +575,18 @@ void DownloadManagerImpl::CheckForHistoryFilesRemoval() {
}
}
+void DownloadManagerImpl::OnHistoryQueryComplete(
+ base::OnceClosure load_history_downloads_cb) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ download::switches::kEnableDownloadDB) &&
+ !in_progress_cache_initialized_) {
+ load_history_downloads_cb_ = std::move(load_history_downloads_cb);
+ } else {
+ std::move(load_history_downloads_cb).Run();
+ }
+}
+
void DownloadManagerImpl::CheckForFileRemoval(
download::DownloadItemImpl* download_item) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -595,10 +665,9 @@ void DownloadManagerImpl::CreateSavePackageDownloadItemWithId(
// download.
void DownloadManagerImpl::ResumeInterruptedDownload(
std::unique_ptr<download::DownloadUrlParameters> params,
- uint32_t id,
const GURL& site_url) {
BeginDownloadInternal(std::move(params), nullptr /* blob_data_handle */,
- nullptr /* blob_url_loader_factory */, id, site_url);
+ nullptr /* blob_url_loader_factory */, false, site_url);
}
void DownloadManagerImpl::SetDownloadItemFactoryForTesting(
@@ -697,9 +766,9 @@ download::DownloadInterruptReason DownloadManagerImpl::BeginDownloadRequest(
// TODO(ananta)
// Find a better way to create the DownloadResourceHandler instance.
std::unique_ptr<ResourceHandler> handler(
- DownloadResourceHandler::CreateForNewRequest(url_request.get(),
- params->request_origin(),
- params->download_source()));
+ DownloadResourceHandler::CreateForNewRequest(
+ url_request.get(), params->request_origin(),
+ params->download_source(), params->follow_cross_origin_redirects()));
ResourceDispatcherHostImpl::Get()->BeginURLRequest(
std::move(url_request), std::move(handler), true, // download
@@ -784,8 +853,7 @@ void DownloadManagerImpl::DownloadUrl(
auto* rfh = RenderFrameHost::FromID(params->render_process_host_id(),
params->render_frame_host_routing_id());
BeginDownloadInternal(std::move(params), std::move(blob_data_handle),
- std::move(blob_url_loader_factory),
- download::DownloadItem::kInvalidId,
+ std::move(blob_url_loader_factory), true,
rfh ? rfh->GetSiteInstance()->GetSiteURL() : GURL());
}
@@ -824,10 +892,15 @@ download::DownloadItem* DownloadManagerImpl::CreateDownloadItem(
bool transient,
const std::vector<download::DownloadItem::ReceivedSlice>& received_slices) {
if (base::ContainsKey(downloads_, id)) {
- NOTREACHED();
- return nullptr;
+ // If a completed or cancelled download item is already in the history db,
+ // remove it from the in-progress db.
+ if (state == download::DownloadItem::COMPLETE ||
+ state == download::DownloadItem::CANCELLED) {
+ in_progress_manager_->RemoveInProgressDownload(guid);
+ } else {
+ return downloads_[id].get();
+ }
}
- DCHECK(!base::ContainsKey(downloads_by_guid_, guid));
download::DownloadItemImpl* item = item_factory_->CreatePersistedItem(
this, guid, id, current_path, target_path, url_chain, referrer_url,
site_url, tab_url, tab_refererr_url, mime_type, original_mime_type,
@@ -855,6 +928,8 @@ void DownloadManagerImpl::PostInitialization(
break;
case DOWNLOAD_INITIALIZATION_DEPENDENCY_IN_PROGRESS_CACHE:
in_progress_cache_initialized_ = true;
+ if (load_history_downloads_cb_)
+ std::move(load_history_downloads_cb_).Run();
break;
case DOWNLOAD_INITIALIZATION_DEPENDENCY_NONE:
default:
@@ -1016,9 +1091,8 @@ void DownloadManagerImpl::InterceptNavigationOnChecksComplete(
void DownloadManagerImpl::BeginResourceDownloadOnChecksComplete(
std::unique_ptr<download::DownloadUrlParameters> params,
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- uint32_t id,
+ bool is_new_download,
const GURL& site_url,
bool is_download_allowed) {
if (!is_download_allowed) {
@@ -1038,6 +1112,7 @@ void DownloadManagerImpl::BeginResourceDownloadOnChecksComplete(
}
}
+ DCHECK_EQ(params->url().SchemeIsBlob(), bool{blob_url_loader_factory});
scoped_refptr<download::DownloadURLLoaderFactoryGetter>
url_loader_factory_getter;
if (blob_url_loader_factory) {
@@ -1045,10 +1120,14 @@ void DownloadManagerImpl::BeginResourceDownloadOnChecksComplete(
url_loader_factory_getter =
base::MakeRefCounted<DownloadURLLoaderFactoryGetterImpl>(
blob_url_loader_factory->Clone());
- } else if (params->url().SchemeIsBlob()) {
+ } else if (params->url().SchemeIsFile()) {
url_loader_factory_getter =
- base::MakeRefCounted<BlobDownloadURLLoaderFactoryGetter>(
- params->url(), std::move(blob_data_handle));
+ base::MakeRefCounted<FileDownloadURLLoaderFactoryGetter>(
+ params->url(), browser_context_->GetPath());
+ } else if (params->url().SchemeIs(content::kChromeUIScheme)) {
+ url_loader_factory_getter =
+ base::MakeRefCounted<WebUIDownloadURLLoaderFactoryGetter>(
+ rfh, params->url());
} else {
StoragePartitionImpl* storage_partition =
static_cast<StoragePartitionImpl*>(
@@ -1058,16 +1137,16 @@ void DownloadManagerImpl::BeginResourceDownloadOnChecksComplete(
CreateDownloadURLLoaderFactoryGetter(storage_partition, rfh, true);
}
- in_progress_manager_->BeginDownload(std::move(params),
- std::move(url_loader_factory_getter), id,
- site_url, tab_url, tab_referrer_url);
+ in_progress_manager_->BeginDownload(
+ std::move(params), std::move(url_loader_factory_getter), is_new_download,
+ site_url, tab_url, tab_referrer_url);
}
void DownloadManagerImpl::BeginDownloadInternal(
std::unique_ptr<download::DownloadUrlParameters> params,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- uint32_t id,
+ bool is_new_download,
const GURL& site_url) {
// Check if the renderer is permitted to request the requested URL.
if (params->render_process_host_id() >= 0 &&
@@ -1096,8 +1175,7 @@ void DownloadManagerImpl::BeginDownloadInternal(
on_can_download_checks_done = base::BindOnce(
&DownloadManagerImpl::BeginResourceDownloadOnChecksComplete,
weak_factory_.GetWeakPtr(), std::move(params),
- std::move(blob_data_handle), std::move(blob_url_loader_factory),
- id, site_url);
+ std::move(blob_url_loader_factory), is_new_download, site_url);
if (delegate_) {
delegate_->CheckDownloadAllowed(std::move(web_contents_getter), url,
method,
@@ -1107,9 +1185,8 @@ void DownloadManagerImpl::BeginDownloadInternal(
}
BeginResourceDownloadOnChecksComplete(
- std::move(params), std::move(blob_data_handle),
- std::move(blob_url_loader_factory), id, site_url,
- rfh ? !content_initiated : true);
+ std::move(params), std::move(blob_url_loader_factory), is_new_download,
+ site_url, rfh ? !content_initiated : true);
} else {
StoragePartition* storage_partition =
BrowserContext::GetStoragePartitionForSite(browser_context_, site_url);
@@ -1119,7 +1196,7 @@ void DownloadManagerImpl::BeginDownloadInternal(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&BeginDownload, std::move(params),
std::move(blob_data_handle),
- browser_context_->GetResourceContext(), id,
+ browser_context_->GetResourceContext(), is_new_download,
weak_factory_.GetWeakPtr()));
}
}
diff --git a/chromium/content/browser/download/download_manager_impl.h b/chromium/content/browser/download/download_manager_impl.h
index 041492c4347..4f07f57f252 100644
--- a/chromium/content/browser/download/download_manager_impl.h
+++ b/chromium/content/browser/download/download_manager_impl.h
@@ -128,6 +128,8 @@ class CONTENT_EXPORT DownloadManagerImpl
int NonMaliciousInProgressCount() const override;
BrowserContext* GetBrowserContext() const override;
void CheckForHistoryFilesRemoval() override;
+ void OnHistoryQueryComplete(
+ base::OnceClosure load_history_downloads_cb) override;
download::DownloadItem* GetDownload(uint32_t id) override;
download::DownloadItem* GetDownloadByGuid(const std::string& guid) override;
@@ -194,14 +196,27 @@ class CONTENT_EXPORT DownloadManagerImpl
// InProgressDownloadManager::Delegate implementations.
bool InterceptDownload(const download::DownloadCreateInfo& info) override;
base::FilePath GetDefaultDownloadDirectory() override;
- download::DownloadItemImpl* GetDownloadItem(
- uint32_t id,
- bool new_download,
- const download::DownloadCreateInfo& info) override;
+ void StartDownloadItem(
+ std::unique_ptr<download::DownloadCreateInfo> info,
+ const download::DownloadUrlParameters::OnStartedCallback& on_started,
+ download::InProgressDownloadManager::StartDownloadItemCallback callback)
+ override;
net::URLRequestContextGetter* GetURLRequestContextGetter(
const download::DownloadCreateInfo& info) override;
- void OnNewDownloadStarted(download::DownloadItem* download) override;
- void GetNextId(const DownloadIdCallback& callback) override;
+
+ // Called when InProgressDownloadManager is initialzed.
+ void OnInProgressDownloadManagerInitialized();
+
+ // Creates a new download item and call |callback|.
+ void CreateNewDownloadItemToStart(
+ std::unique_ptr<download::DownloadCreateInfo> info,
+ const download::DownloadUrlParameters::OnStartedCallback& on_started,
+ download::InProgressDownloadManager::StartDownloadItemCallback callback,
+ uint32_t id);
+
+ // Called to get an ID for a new download. |callback| may be called
+ // synchronously.
+ void GetNextId(const DownloadIdCallback& callback);
// Create a new active item based on the info. Separate from
// StartDownload() for testing.
@@ -209,7 +224,6 @@ class CONTENT_EXPORT DownloadManagerImpl
uint32_t id,
const download::DownloadCreateInfo& info);
-
// Called with the result of DownloadManagerDelegate::CheckForFileExistence.
// Updates the state of the file and then notifies this update to the file's
// observer.
@@ -227,7 +241,6 @@ class CONTENT_EXPORT DownloadManagerImpl
std::string GetApplicationClientIdForFileScanning() const override;
void ResumeInterruptedDownload(
std::unique_ptr<download::DownloadUrlParameters> params,
- uint32_t id,
const GURL& site_url) override;
void OpenDownload(download::DownloadItemImpl* download) override;
bool IsMostRecentDownloadItemAtFilePath(
@@ -248,7 +261,7 @@ class CONTENT_EXPORT DownloadManagerImpl
std::unique_ptr<download::DownloadUrlParameters> params,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- uint32_t id,
+ bool is_new_download,
const GURL& site_url);
void InterceptNavigationOnChecksComplete(
@@ -261,9 +274,8 @@ class CONTENT_EXPORT DownloadManagerImpl
bool is_download_allowed);
void BeginResourceDownloadOnChecksComplete(
std::unique_ptr<download::DownloadUrlParameters> params,
- std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
- uint32_t id,
+ bool is_new_download,
const GURL& site_url,
bool is_download_allowed);
@@ -314,6 +326,9 @@ class CONTENT_EXPORT DownloadManagerImpl
std::unique_ptr<download::InProgressDownloadManager> in_progress_manager_;
+ // Callback to run to load all history downloads.
+ base::OnceClosure load_history_downloads_cb_;
+
base::WeakPtrFactory<DownloadManagerImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DownloadManagerImpl);
diff --git a/chromium/content/browser/download/download_manager_impl_unittest.cc b/chromium/content/browser/download/download_manager_impl_unittest.cc
index 9ccc49d3df7..c4e5f80b78f 100644
--- a/chromium/content/browser/download/download_manager_impl_unittest.cc
+++ b/chromium/content/browser/download/download_manager_impl_unittest.cc
@@ -320,6 +320,36 @@ class MockByteStreamReader : public ByteStreamReader {
MOCK_METHOD1(RegisterCallback, void(const base::Closure&));
};
+class TestInProgressManager : public download::InProgressDownloadManager {
+ public:
+ TestInProgressManager();
+ ~TestInProgressManager() override = default;
+
+ std::vector<std::unique_ptr<download::DownloadItemImpl>>
+ TakeInProgressDownloads() override;
+
+ void AddDownloadItem(std::unique_ptr<download::DownloadItemImpl> item);
+
+ private:
+ std::vector<std::unique_ptr<download::DownloadItemImpl>> download_items_;
+};
+
+TestInProgressManager::TestInProgressManager()
+ : download::InProgressDownloadManager(
+ nullptr,
+ base::FilePath(),
+ download::InProgressDownloadManager::IsOriginSecureCallback()) {}
+
+void TestInProgressManager::AddDownloadItem(
+ std::unique_ptr<download::DownloadItemImpl> item) {
+ download_items_.emplace_back(std::move(item));
+}
+
+std::vector<std::unique_ptr<download::DownloadItemImpl>>
+TestInProgressManager::TakeInProgressDownloads() {
+ return std::move(download_items_);
+}
+
} // namespace
class DownloadManagerTest : public testing::Test {
@@ -450,6 +480,15 @@ class DownloadManagerTest : public testing::Test {
base::Unretained(this)));
}
+ void OnInProgressDownloadManagerInitialized() {
+ download_manager_->OnInProgressDownloadManagerInitialized();
+ }
+
+ void SetInProgressDownloadManager(
+ std::unique_ptr<download::InProgressDownloadManager> manager) {
+ download_manager_->in_progress_manager_ = std::move(manager);
+ }
+
protected:
// Key test variable; we'll keep it available to sub-classes.
std::unique_ptr<DownloadManagerImpl> download_manager_;
@@ -609,4 +648,34 @@ TEST_F(DownloadManagerTest, RemoveDownloadsByURL) {
EXPECT_EQ(remove_count, 1);
}
+// Confirm that in-progress downloads will be taken and managed by
+// DownloadManager.
+TEST_F(DownloadManagerTest, OnInProgressDownloadsLoaded) {
+ auto in_progress_manager = std::make_unique<TestInProgressManager>();
+ const char kGuid[] = "8DF158E8-C980-4618-BB03-EBA3242EB48B";
+ auto in_progress_item = std::make_unique<download::DownloadItemImpl>(
+ in_progress_manager.get(), kGuid, 10, base::FilePath(), base::FilePath(),
+ std::vector<GURL>(), GURL("http://example.com/a"),
+ GURL("http://example.com/a"), GURL("http://example.com/a"),
+ GURL("http://example.com/a"), "application/octet-stream",
+ "application/octet-stream", base::Time::Now(), base::Time::Now(),
+ std::string(), std::string(), 10, 10, std::string(),
+ download::DownloadItem::INTERRUPTED,
+ download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED, false,
+ base::Time::Now(), true,
+ std::vector<download::DownloadItem::ReceivedSlice>());
+ in_progress_manager->AddDownloadItem(std::move(in_progress_item));
+ SetInProgressDownloadManager(std::move(in_progress_manager));
+ EXPECT_CALL(GetMockObserver(), OnDownloadCreated(download_manager_.get(), _))
+ .WillOnce(Return());
+ OnInProgressDownloadManagerInitialized();
+ ASSERT_TRUE(download_manager_->GetDownloadByGuid(kGuid));
+
+ download::DownloadItem* download =
+ download_manager_->GetDownloadByGuid(kGuid);
+ download->Remove();
+ ASSERT_FALSE(download_manager_->GetDownloadByGuid(kGuid));
+}
+
} // namespace content
diff --git a/chromium/content/browser/download/download_request_core.cc b/chromium/content/browser/download/download_request_core.cc
index 3b2045e18ee..fb6a33bcd83 100644
--- a/chromium/content/browser/download/download_request_core.cc
+++ b/chromium/content/browser/download/download_request_core.cc
@@ -56,14 +56,14 @@ class DownloadRequestData : public base::SupportsUserData::Data {
static void Attach(net::URLRequest* request,
download::DownloadUrlParameters* download_parameters,
- uint32_t download_id);
+ bool is_new_download);
static DownloadRequestData* Get(const net::URLRequest* request);
static void Detach(net::URLRequest* request);
std::unique_ptr<download::DownloadSaveInfo> TakeSaveInfo() {
return std::move(save_info_);
}
- uint32_t download_id() const { return download_id_; }
+ bool is_new_download() const { return is_new_download_; }
std::string guid() const { return guid_; }
bool is_transient() const { return transient_; }
bool fetch_error_body() const { return fetch_error_body_; }
@@ -80,7 +80,7 @@ class DownloadRequestData : public base::SupportsUserData::Data {
static const int kKey;
std::unique_ptr<download::DownloadSaveInfo> save_info_;
- uint32_t download_id_ = download::DownloadItem::kInvalidId;
+ bool is_new_download_;
std::string guid_;
bool fetch_error_body_ = false;
download::DownloadUrlParameters::RequestHeadersType request_headers_;
@@ -95,11 +95,11 @@ const int DownloadRequestData::kKey = 0;
// static
void DownloadRequestData::Attach(net::URLRequest* request,
download::DownloadUrlParameters* parameters,
- uint32_t download_id) {
+ bool is_new_download) {
auto request_data = std::make_unique<DownloadRequestData>();
request_data->save_info_.reset(
new download::DownloadSaveInfo(parameters->GetSaveInfo()));
- request_data->download_id_ = download_id;
+ request_data->is_new_download_ = is_new_download;
request_data->guid_ = parameters->guid();
request_data->fetch_error_body_ = parameters->fetch_error_body();
request_data->request_headers_ = parameters->request_headers();
@@ -125,16 +125,15 @@ const int DownloadRequestCore::kDownloadByteStreamSize = 100 * 1024;
// static
std::unique_ptr<net::URLRequest> DownloadRequestCore::CreateRequestOnIOThread(
- uint32_t download_id,
+ bool is_new_download,
download::DownloadUrlParameters* params) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(download_id == download::DownloadItem::kInvalidId ||
- !params->content_initiated())
- << "Content initiated downloads shouldn't specify a download ID";
+ DCHECK(is_new_download || !params->content_initiated())
+ << "Content initiated downloads should be a new download";
std::unique_ptr<net::URLRequest> request = CreateURLRequestOnIOThread(params);
- DownloadRequestData::Attach(request.get(), params, download_id);
+ DownloadRequestData::Attach(request.get(), params, is_new_download);
return request;
}
@@ -155,7 +154,7 @@ DownloadRequestCore::DownloadRequestCore(
download::DownloadSource download_source)
: delegate_(delegate),
request_(request),
- download_id_(download::DownloadItem::kInvalidId),
+ is_new_download_(true),
fetch_error_body_(false),
transient_(false),
bytes_read_(0),
@@ -193,7 +192,7 @@ DownloadRequestCore::DownloadRequestCore(
DownloadRequestData* request_data = DownloadRequestData::Get(request_);
if (request_data) {
save_info_ = request_data->TakeSaveInfo();
- download_id_ = request_data->download_id();
+ is_new_download_ = request_data->is_new_download();
guid_ = request_data->guid();
fetch_error_body_ = request_data->fetch_error_body();
request_headers_ = request_data->request_headers();
@@ -228,8 +227,9 @@ DownloadRequestCore::CreateDownloadCreateInfo(
create_info->connection_info = request()->response_info().connection_info;
create_info->url_chain = request()->url_chain();
create_info->referrer_url = GURL(request()->referrer());
+ create_info->referrer_policy = request()->referrer_policy();
create_info->result = result;
- create_info->download_id = download_id_;
+ create_info->is_new_download = is_new_download_;
create_info->guid = guid_;
create_info->transient = transient_;
create_info->response_headers = request()->response_headers();
diff --git a/chromium/content/browser/download/download_request_core.h b/chromium/content/browser/download/download_request_core.h
index 409e3e3912d..0fdd19edd45 100644
--- a/chromium/content/browser/download/download_request_core.h
+++ b/chromium/content/browser/download/download_request_core.h
@@ -109,7 +109,7 @@ class CONTENT_EXPORT DownloadRequestCore
std::string DebugString() const;
static std::unique_ptr<net::URLRequest> CreateRequestOnIOThread(
- uint32_t download_id,
+ bool is_new_download,
download::DownloadUrlParameters* params);
// Size of the buffer used between the DownloadRequestCore and the
@@ -129,7 +129,7 @@ class CONTENT_EXPORT DownloadRequestCore
// "Passthrough" fields. These are only kept here so that they can be used to
// populate the download::DownloadCreateInfo when the time comes.
std::unique_ptr<download::DownloadSaveInfo> save_info_;
- uint32_t download_id_;
+ bool is_new_download_;
std::string guid_;
bool fetch_error_body_;
download::DownloadUrlParameters::RequestHeadersType request_headers_;
diff --git a/chromium/content/browser/download/download_request_core_unittest.cc b/chromium/content/browser/download/download_request_core_unittest.cc
index 4d9c0db919d..5c6fb4e426b 100644
--- a/chromium/content/browser/download/download_request_core_unittest.cc
+++ b/chromium/content/browser/download/download_request_core_unittest.cc
@@ -46,8 +46,7 @@ class DownloadRequestCoreTest : public testing::Test {
}
void CreateRequestOnIOThread(download::DownloadUrlParameters* params) {
- url_request_ = DownloadRequestCore::CreateRequestOnIOThread(
- download::DownloadItem::kInvalidId, params);
+ url_request_ = DownloadRequestCore::CreateRequestOnIOThread(true, params);
DCHECK(url_request_.get());
}
diff --git a/chromium/content/browser/download/download_resource_handler.cc b/chromium/content/browser/download/download_resource_handler.cc
index d409db6c596..752cc1af42d 100644
--- a/chromium/content/browser/download/download_resource_handler.cc
+++ b/chromium/content/browser/download/download_resource_handler.cc
@@ -24,6 +24,7 @@
#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/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_request_utils.h"
#include "content/public/browser/navigation_entry.h"
@@ -109,10 +110,8 @@ void InitializeDownloadTabInfoOnUIThread(
tab_info->tab_url = entry->GetURL();
tab_info->tab_referrer_url = entry->GetReferrer().url;
- tab_info->ukm_source_id = ukm::UkmRecorder::GetNewSourceID();
- download::DownloadUkmHelper::UpdateSourceURL(
- ukm::UkmRecorder::Get(), tab_info->ukm_source_id,
- web_contents->GetLastCommittedURL());
+ tab_info->ukm_source_id = static_cast<WebContentsImpl*>(web_contents)
+ ->GetUkmSourceIdForLastCommittedSource();
}
}
}
@@ -120,14 +119,35 @@ void InitializeDownloadTabInfoOnUIThread(
void DeleteOnUIThread(
std::unique_ptr<DownloadResourceHandler::DownloadTabInfo> tab_info) {}
+void NavigateOnUIThread(
+ const GURL& url,
+ const std::vector<GURL> url_chain,
+ const Referrer& referrer,
+ bool has_user_gesture,
+ const ResourceRequestInfo::WebContentsGetter& wc_getter) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ WebContents* web_contents = wc_getter.Run();
+ if (web_contents) {
+ NavigationController::LoadURLParams params(url);
+ params.has_user_gesture = has_user_gesture;
+ params.referrer = referrer;
+ params.redirect_chain = url_chain;
+ web_contents->GetController().LoadURLWithParams(params);
+ }
+}
+
} // namespace
DownloadResourceHandler::DownloadResourceHandler(
net::URLRequest* request,
const std::string& request_origin,
- download::DownloadSource download_source)
+ download::DownloadSource download_source,
+ bool follow_cross_origin_redirects)
: ResourceHandler(request),
tab_info_(new DownloadTabInfo()),
+ follow_cross_origin_redirects_(follow_cross_origin_redirects),
+ first_origin_(url::Origin::Create(request->url())),
core_(request, this, false, request_origin, download_source) {
// Do UI thread initialization for tab_info_ asap after
// DownloadResourceHandler creation since the tab could be navigated
@@ -157,7 +177,7 @@ std::unique_ptr<ResourceHandler> DownloadResourceHandler::Create(
net::URLRequest* request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::unique_ptr<ResourceHandler> handler(new DownloadResourceHandler(
- request, std::string(), download::DownloadSource::NAVIGATION));
+ request, std::string(), download::DownloadSource::NAVIGATION, true));
return handler;
}
@@ -165,10 +185,11 @@ std::unique_ptr<ResourceHandler> DownloadResourceHandler::Create(
std::unique_ptr<ResourceHandler> DownloadResourceHandler::CreateForNewRequest(
net::URLRequest* request,
const std::string& request_origin,
- download::DownloadSource download_source) {
+ download::DownloadSource download_source,
+ bool follow_cross_origin_redirects) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- std::unique_ptr<ResourceHandler> handler(
- new DownloadResourceHandler(request, request_origin, download_source));
+ std::unique_ptr<ResourceHandler> handler(new DownloadResourceHandler(
+ request, request_origin, download_source, follow_cross_origin_redirects));
return handler;
}
@@ -176,6 +197,21 @@ void DownloadResourceHandler::OnRequestRedirected(
const net::RedirectInfo& redirect_info,
network::ResourceResponse* response,
std::unique_ptr<ResourceController> controller) {
+ url::Origin new_origin(url::Origin::Create(redirect_info.new_url));
+ if (!follow_cross_origin_redirects_ &&
+ !first_origin_.IsSameOriginWith(new_origin)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(
+ &NavigateOnUIThread, redirect_info.new_url, request()->url_chain(),
+ Referrer(GURL(redirect_info.new_referrer),
+ Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+ redirect_info.new_referrer_policy)),
+ GetRequestInfo()->HasUserGesture(),
+ GetRequestInfo()->GetWebContentsGetterForRequest()));
+ controller->Cancel();
+ return;
+ }
if (core_.OnRequestRedirected()) {
controller->Resume();
} else {
@@ -242,10 +278,6 @@ void DownloadResourceHandler::OnResponseCompleted(
controller->Resume();
}
-void DownloadResourceHandler::OnDataDownloaded(int bytes_downloaded) {
- NOTREACHED();
-}
-
void DownloadResourceHandler::PauseRequest() {
core_.PauseRequest();
}
@@ -262,7 +294,7 @@ void DownloadResourceHandler::OnStart(
// download entirely.
if (create_info->result ==
download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED &&
- create_info->download_id == download::DownloadItem::kInvalidId) {
+ create_info->is_new_download) {
if (!callback.is_null())
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
diff --git a/chromium/content/browser/download/download_resource_handler.h b/chromium/content/browser/download/download_resource_handler.h
index 39f1982b309..2d206330813 100644
--- a/chromium/content/browser/download/download_resource_handler.h
+++ b/chromium/content/browser/download/download_resource_handler.h
@@ -44,7 +44,8 @@ class CONTENT_EXPORT DownloadResourceHandler
// |id| should be invalid if the id should be automatically assigned.
DownloadResourceHandler(net::URLRequest* request,
const std::string& request_origin,
- download::DownloadSource download_source);
+ download::DownloadSource download_source,
+ bool follow_cross_origin_redirects);
// static
// This function is passed into ResourceDispatcherHostImpl during its
@@ -61,7 +62,8 @@ class CONTENT_EXPORT DownloadResourceHandler
static std::unique_ptr<ResourceHandler> CreateForNewRequest(
net::URLRequest* request,
const std::string& request_origin,
- download::DownloadSource download_source);
+ download::DownloadSource download_source,
+ bool follow_cross_origin_redirects);
void OnRequestRedirected(
const net::RedirectInfo& redirect_info,
@@ -90,9 +92,6 @@ class CONTENT_EXPORT DownloadResourceHandler
const net::URLRequestStatus& status,
std::unique_ptr<ResourceController> controller) override;
- // N/A to this flavor of DownloadHandler.
- void OnDataDownloaded(int bytes_downloaded) override;
-
void PauseRequest();
void ResumeRequest();
@@ -120,6 +119,9 @@ class CONTENT_EXPORT DownloadResourceHandler
// deletion must occur on the IO thread.
std::unique_ptr<DownloadTabInfo> tab_info_;
+ bool follow_cross_origin_redirects_;
+ url::Origin first_origin_;
+
DownloadRequestCore core_;
DISALLOW_COPY_AND_ASSIGN(DownloadResourceHandler);
diff --git a/chromium/content/browser/download/download_utils.cc b/chromium/content/browser/download/download_utils.cc
index ab0e360a306..fec2b6a861c 100644
--- a/chromium/content/browser/download/download_utils.cc
+++ b/chromium/content/browser/download/download_utils.cc
@@ -9,8 +9,8 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/task_scheduler/post_task.h"
-#include "components/download/downloader/in_progress/download_entry.h"
-#include "components/download/downloader/in_progress/in_progress_cache.h"
+#include "components/download/database/in_progress/download_entry.h"
+#include "components/download/database/in_progress/in_progress_cache.h"
#include "components/download/public/common/download_create_info.h"
#include "components/download/public/common/download_interrupt_reasons_utils.h"
#include "components/download/public/common/download_save_info.h"
diff --git a/chromium/content/browser/download/file_download_url_loader_factory_getter.cc b/chromium/content/browser/download/file_download_url_loader_factory_getter.cc
new file mode 100644
index 00000000000..973baed881d
--- /dev/null
+++ b/chromium/content/browser/download/file_download_url_loader_factory_getter.cc
@@ -0,0 +1,44 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/download/file_download_url_loader_factory_getter.h"
+
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_traits.h"
+#include "components/download/public/common/download_task_runner.h"
+#include "content/browser/file_url_loader_factory.h"
+#include "content/browser/url_loader_factory_getter.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+
+namespace content {
+
+FileDownloadURLLoaderFactoryGetter::FileDownloadURLLoaderFactoryGetter(
+ const GURL& url,
+ const base::FilePath& profile_path)
+ : url_(url), profile_path_(profile_path) {
+ DCHECK(url.SchemeIs(url::kFileScheme));
+}
+
+FileDownloadURLLoaderFactoryGetter::~FileDownloadURLLoaderFactoryGetter() =
+ default;
+
+scoped_refptr<network::SharedURLLoaderFactory>
+FileDownloadURLLoaderFactoryGetter::GetURLLoaderFactory() {
+ DCHECK(download::GetIOTaskRunner()->BelongsToCurrentThread());
+
+ network::mojom::URLLoaderFactoryPtrInfo url_loader_factory_ptr_info;
+ mojo::MakeStrongBinding(
+ std::make_unique<FileURLLoaderFactory>(
+ profile_path_, base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
+ MakeRequest(&url_loader_factory_ptr_info));
+
+ return base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
+ std::move(url_loader_factory_ptr_info));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/download/file_download_url_loader_factory_getter.h b/chromium/content/browser/download/file_download_url_loader_factory_getter.h
new file mode 100644
index 00000000000..9c3e79c7a13
--- /dev/null
+++ b/chromium/content/browser/download/file_download_url_loader_factory_getter.h
@@ -0,0 +1,36 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DOWNLOAD_FILE_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
+#define CONTENT_BROWSER_DOWNLOAD_FILE_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
+
+#include "base/files/file_path.h"
+#include "components/download/public/common/download_url_loader_factory_getter.h"
+#include "url/gurl.h"
+
+namespace content {
+
+// Class for retrieving the URLLoaderFactory for a file URL.
+class FileDownloadURLLoaderFactoryGetter
+ : public download::DownloadURLLoaderFactoryGetter {
+ public:
+ FileDownloadURLLoaderFactoryGetter(const GURL& url,
+ const base::FilePath& profile_path);
+
+ // download::DownloadURLLoaderFactoryGetter implementation.
+ scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
+
+ protected:
+ ~FileDownloadURLLoaderFactoryGetter() override;
+
+ private:
+ GURL url_;
+ base::FilePath profile_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileDownloadURLLoaderFactoryGetter);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DOWNLOAD_FILE_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
diff --git a/chromium/content/browser/download/mhtml_generation_browsertest.cc b/chromium/content/browser/download/mhtml_generation_browsertest.cc
index d3e9279628a..379cc3ac485 100644
--- a/chromium/content/browser/download/mhtml_generation_browsertest.cc
+++ b/chromium/content/browser/download/mhtml_generation_browsertest.cc
@@ -13,7 +13,7 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_restrictions.h"
#include "components/download/public/common/download_task_runner.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
diff --git a/chromium/content/browser/download/save_package.cc b/chromium/content/browser/download/save_package.cc
index 7035f3e49d4..0310f540c34 100644
--- a/chromium/content/browser/download/save_package.cc
+++ b/chromium/content/browser/download/save_package.cc
@@ -44,6 +44,7 @@
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
@@ -257,7 +258,8 @@ void SavePackage::InternalInit() {
download::RecordSavePackageEvent(download::SAVE_PACKAGE_STARTED);
- ukm_source_id_ = ukm::UkmRecorder::GetNewSourceID();
+ ukm_source_id_ = static_cast<WebContentsImpl*>(web_contents())
+ ->GetUkmSourceIdForLastCommittedSource();
ukm_download_id_ = download::GetUniqueDownloadId();
download::DownloadUkmHelper::RecordDownloadStarted(
ukm_download_id_, ukm_source_id_, download::DownloadContent::TEXT,
@@ -284,9 +286,6 @@ bool SavePackage::Init(
std::unique_ptr<download::DownloadRequestHandleInterface> request_handle(
new SavePackageRequestHandle(AsWeakPtr()));
- download::DownloadUkmHelper::UpdateSourceURL(
- ukm::UkmRecorder::Get(), ukm_source_id_,
- web_contents()->GetLastCommittedURL());
RenderFrameHost* frame_host = web_contents()->GetMainFrame();
download_manager_->CreateSavePackageDownloadItem(
saved_main_file_path_, page_url_,
diff --git a/chromium/content/browser/download/url_downloader.cc b/chromium/content/browser/download/url_downloader.cc
index 034fadddce8..e44234a31f5 100644
--- a/chromium/content/browser/download/url_downloader.cc
+++ b/chromium/content/browser/download/url_downloader.cc
@@ -13,6 +13,7 @@
#include "components/download/public/common/download_interrupt_reasons.h"
#include "components/download/public/common/download_request_handle_interface.h"
#include "components/download/public/common/download_url_parameters.h"
+#include "components/download/public/common/url_download_request_handle.h"
#include "content/browser/byte_stream.h"
#include "content/browser/download/byte_stream_input_stream.h"
#include "content/public/browser/browser_thread.h"
@@ -25,43 +26,6 @@
namespace content {
-class UrlDownloader::RequestHandle
- : public download::DownloadRequestHandleInterface {
- public:
- RequestHandle(base::WeakPtr<UrlDownloader> downloader,
- scoped_refptr<base::SequencedTaskRunner> downloader_task_runner)
- : downloader_(downloader),
- downloader_task_runner_(downloader_task_runner) {}
- RequestHandle(RequestHandle&& other)
- : downloader_(std::move(other.downloader_)),
- downloader_task_runner_(std::move(other.downloader_task_runner_)) {}
- RequestHandle& operator=(RequestHandle&& other) {
- downloader_ = std::move(other.downloader_);
- downloader_task_runner_ = std::move(other.downloader_task_runner_);
- return *this;
- }
-
- // DownloadRequestHandleInterface
- void PauseRequest() override {
- downloader_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&UrlDownloader::PauseRequest, downloader_));
- }
- void ResumeRequest() override {
- downloader_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&UrlDownloader::ResumeRequest, downloader_));
- }
- void CancelRequest(bool user_cancel) override {
- downloader_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&UrlDownloader::CancelRequest, downloader_));
- }
-
- private:
- base::WeakPtr<UrlDownloader> downloader_;
- scoped_refptr<base::SequencedTaskRunner> downloader_task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(RequestHandle);
-};
-
// static
std::unique_ptr<UrlDownloader> UrlDownloader::BeginDownload(
base::WeakPtr<download::UrlDownloadHandler::Delegate> delegate,
@@ -221,7 +185,7 @@ void UrlDownloader::OnStart(
std::unique_ptr<download::DownloadCreateInfo> create_info,
std::unique_ptr<ByteStreamReader> stream_reader,
const download::DownloadUrlParameters::OnStartedCallback& callback) {
- create_info->request_handle.reset(new RequestHandle(
+ create_info->request_handle.reset(new download::UrlDownloadRequestHandle(
weak_ptr_factory_.GetWeakPtr(), base::SequencedTaskRunnerHandle::Get()));
BrowserThread::PostTask(
diff --git a/chromium/content/browser/download/url_downloader.h b/chromium/content/browser/download/url_downloader.h
index 0ee10feddf7..e5b7289ea15 100644
--- a/chromium/content/browser/download/url_downloader.h
+++ b/chromium/content/browser/download/url_downloader.h
@@ -42,8 +42,6 @@ class UrlDownloader : public net::URLRequest::Delegate,
bool is_parallel_request);
private:
- class RequestHandle;
-
void Start();
// URLRequest::Delegate:
@@ -64,9 +62,10 @@ class UrlDownloader : public net::URLRequest::Delegate,
override;
void OnReadyToRead() override;
- void PauseRequest();
- void ResumeRequest();
- void CancelRequest();
+ // UrlDownloadHandler implementations.
+ void PauseRequest() override;
+ void ResumeRequest() override;
+ void CancelRequest() override;
// Called when the UrlDownloader is done with the request. Posts a task to
// remove itself from its download manager, which in turn would cause the
diff --git a/chromium/content/browser/download/url_downloader_factory.cc b/chromium/content/browser/download/url_downloader_factory.cc
index 752cea70a5d..5a66bd2b9fa 100644
--- a/chromium/content/browser/download/url_downloader_factory.cc
+++ b/chromium/content/browser/download/url_downloader_factory.cc
@@ -23,8 +23,7 @@ UrlDownloaderFactory::CreateUrlDownloadHandler(
url_loader_factory_getter,
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
std::unique_ptr<net::URLRequest> url_request =
- DownloadRequestCore::CreateRequestOnIOThread(
- download::DownloadItem::kInvalidId, params.get());
+ DownloadRequestCore::CreateRequestOnIOThread(true, params.get());
return download::UrlDownloadHandler::UniqueUrlDownloadHandlerPtr(
UrlDownloader::BeginDownload(delegate, std::move(url_request),
diff --git a/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc b/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc
new file mode 100644
index 00000000000..c4873157c81
--- /dev/null
+++ b/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.cc
@@ -0,0 +1,33 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/download/web_ui_download_url_loader_factory_getter.h"
+
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_ui_url_loader_factory.h"
+#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
+
+namespace content {
+
+WebUIDownloadURLLoaderFactoryGetter::WebUIDownloadURLLoaderFactoryGetter(
+ RenderFrameHost* rfh,
+ const GURL& url) {
+ auto factory_request = mojo::MakeRequest(&factory_info_);
+ factory_ =
+ CreateWebUIURLLoader(rfh, url.scheme(), base::flat_set<std::string>());
+ factory_->Clone(std::move(factory_request));
+}
+
+WebUIDownloadURLLoaderFactoryGetter::~WebUIDownloadURLLoaderFactoryGetter() {
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)
+ ->DeleteSoon(FROM_HERE, std::move(factory_));
+}
+
+scoped_refptr<network::SharedURLLoaderFactory>
+WebUIDownloadURLLoaderFactoryGetter::GetURLLoaderFactory() {
+ return base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
+ std::move(factory_info_));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.h b/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.h
new file mode 100644
index 00000000000..5f39fd718c4
--- /dev/null
+++ b/chromium/content/browser/download/web_ui_download_url_loader_factory_getter.h
@@ -0,0 +1,40 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_DOWNLOAD_WEB_UI_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
+#define CONTENT_BROWSER_DOWNLOAD_WEB_UI_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
+
+#include "base/files/file_path.h"
+#include "components/download/public/common/download_url_loader_factory_getter.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+
+class GURL;
+
+namespace content {
+class RenderFrameHost;
+
+// Class for retrieving the URLLoaderFactory for a webui URL.
+class WebUIDownloadURLLoaderFactoryGetter
+ : public download::DownloadURLLoaderFactoryGetter {
+ public:
+ WebUIDownloadURLLoaderFactoryGetter(RenderFrameHost* rfh, const GURL& url);
+
+ // download::DownloadURLLoaderFactoryGetter implementation.
+ scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
+
+ protected:
+ ~WebUIDownloadURLLoaderFactoryGetter() override;
+
+ private:
+ network::mojom::URLLoaderFactoryPtrInfo factory_info_;
+
+ // Lives on the UI thread and must be deleted there.
+ std::unique_ptr<network::mojom::URLLoaderFactory> factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebUIDownloadURLLoaderFactoryGetter);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DOWNLOAD_WEB_UI_DOWNLOAD_URL_LOADER_FACTORY_GETTER_H_
diff --git a/chromium/content/browser/file_url_loader_factory.cc b/chromium/content/browser/file_url_loader_factory.cc
index f260e71a625..44eb522466d 100644
--- a/chromium/content/browser/file_url_loader_factory.cc
+++ b/chromium/content/browser/file_url_loader_factory.cc
@@ -107,7 +107,9 @@ class FileURLDirectoryLoader
}
// network::mojom::URLLoader:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override {}
void ProceedWithResponse() override { NOTREACHED(); }
void SetPriority(net::RequestPriority priority,
@@ -160,7 +162,7 @@ class FileURLDirectoryLoader
network::ResourceResponseHead head;
head.mime_type = "text/html";
head.charset = "utf-8";
- client->OnReceiveResponse(head, nullptr);
+ client->OnReceiveResponse(head);
client->OnStartLoadingResponseBody(std::move(pipe.consumer_handle));
client_ = std::move(client);
@@ -316,7 +318,9 @@ class FileURLLoader : public network::mojom::URLLoader {
}
// network::mojom::URLLoader:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override {}
void ProceedWithResponse() override {}
void SetPriority(net::RequestPriority priority,
@@ -559,7 +563,7 @@ class FileURLLoader : public network::mojom::URLLoader {
base::StringPrintf("%s: %s", net::HttpRequestHeaders::kContentType,
head.mime_type.c_str()));
}
- client->OnReceiveResponse(head, nullptr);
+ client->OnReceiveResponse(head);
client->OnStartLoadingResponseBody(std::move(pipe.consumer_handle));
client_ = std::move(client);
@@ -635,7 +639,6 @@ void FileURLLoaderFactory::CreateLoaderAndStart(
const network::ResourceRequest& request,
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
- DCHECK(!request.download_to_file);
base::FilePath file_path;
const bool is_file = net::FileURLToFilePath(request.url, &file_path);
if (is_file && file_path.EndsWithSeparator() && file_path.IsAbsolute()) {
diff --git a/chromium/content/browser/fileapi/browser_file_system_helper.cc b/chromium/content/browser/fileapi/browser_file_system_helper.cc
index aef88c1d686..acf067a117b 100644
--- a/chromium/content/browser/fileapi/browser_file_system_helper.cc
+++ b/chromium/content/browser/fileapi/browser_file_system_helper.cc
@@ -151,8 +151,12 @@ void PrepareDropDataForChildProcess(
#if defined(OS_CHROMEOS)
// The externalfile:// scheme is used in Chrome OS to open external files in a
// browser tab.
+ // TODO(https://crbug.com/858972): This seems like it could be forged by the
+ // renderer. This probably needs to check that this didn't originate from the
+ // renderer... Also, this probably can just be GrantRequestURL (which doesn't
+ // yet exist) instead of GrantCommitURL.
if (drop_data->url.SchemeIs(content::kExternalFileScheme))
- security_policy->GrantRequestURL(child_id, drop_data->url);
+ security_policy->GrantCommitURL(child_id, drop_data->url);
#endif
// The filenames vector represents a capability to access the given files.
diff --git a/chromium/content/browser/fileapi/file_system_url_loader_factory.cc b/chromium/content/browser/fileapi/file_system_url_loader_factory.cc
index 0b426204681..7ef37b18b9f 100644
--- a/chromium/content/browser/fileapi/file_system_url_loader_factory.cc
+++ b/chromium/content/browser/fileapi/file_system_url_loader_factory.cc
@@ -94,7 +94,9 @@ class FileSystemEntryURLLoader
: binding_(this), params_(std::move(params)) {}
// network::mojom::URLLoader:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override {}
void ProceedWithResponse() override {}
void SetPriority(net::RequestPriority priority,
@@ -339,7 +341,7 @@ class FileSystemDirectoryURLLoader : public FileSystemEntryURLLoader {
head.content_length = data_.size();
head.headers = CreateHttpResponseHeaders(200);
- client_->OnReceiveResponse(head, /*downloaded_file=*/nullptr);
+ client_->OnReceiveResponse(head);
client_->OnStartLoadingResponseBody(std::move(pipe.consumer_handle));
data_producer_ = std::make_unique<mojo::StringDataPipeProducer>(
@@ -487,6 +489,11 @@ class FileSystemFileURLLoader : public FileSystemEntryURLLoader {
int64_t bytes_to_read = std::min(
static_cast<int64_t>(kDefaultFileSystemUrlPipeSize), remaining_bytes_);
if (!bytes_to_read) {
+ if (consumer_handle_.is_valid()) {
+ // This was an empty file; make sure to call OnReceiveResponse
+ // regardless.
+ client_->OnReceiveResponse(head_);
+ }
OnFileWritten(MOJO_RESULT_OK);
return;
}
@@ -517,7 +524,7 @@ class FileSystemFileURLLoader : public FileSystemEntryURLLoader {
&head_.mime_type);
}
- client_->OnReceiveResponse(head_, /*downloaded_file=*/nullptr);
+ client_->OnReceiveResponse(head_);
client_->OnStartLoadingResponseBody(std::move(consumer_handle_));
}
remaining_bytes_ -= result;
diff --git a/chromium/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc b/chromium/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc
index 79fd580333d..82cfc2765d2 100644
--- a/chromium/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc
+++ b/chromium/content/browser/fileapi/file_system_url_loader_factory_browsertest.cc
@@ -34,6 +34,7 @@
#include "storage/browser/test/mock_special_storage_policy.h"
#include "storage/browser/test/test_file_system_backend.h"
#include "storage/browser/test/test_file_system_context.h"
+#include "storage/browser/test/test_file_system_options.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/icu/source/i18n/unicode/datefmt.h"
#include "third_party/icu/source/i18n/unicode/regex.h"
@@ -154,25 +155,27 @@ void ShutdownFileSystemContextOnIOThread(
class FileSystemURLLoaderFactoryTest : public ContentBrowserTest {
protected:
- FileSystemURLLoaderFactoryTest() : weak_factory_(this) {}
+ FileSystemURLLoaderFactoryTest() {}
~FileSystemURLLoaderFactoryTest() override = default;
void SetUpOnMainThread() override {
feature_list_.InitAndEnableFeature(network::features::kNetworkService);
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-
special_storage_policy_ = new MockSpecialStoragePolicy;
+
+ // We use a test FileSystemContext which runs on the main thread, so we
+ // can work with it synchronously.
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
file_system_context_ =
CreateFileSystemContextForTesting(nullptr, temp_dir_.GetPath());
-
- // We use the main thread so that we can get the root path synchronously.
+ base::RunLoop run_loop;
file_system_context_->OpenFileSystem(
GURL("http://remote/"), storage::kFileSystemTypeTemporary,
storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
base::BindOnce(&FileSystemURLLoaderFactoryTest::OnOpenFileSystem,
- weak_factory_.GetWeakPtr()));
- base::RunLoop().RunUntilIdle();
+ run_loop.QuitWhenIdleClosure()));
+ run_loop.Run();
+
ContentBrowserTest::SetUpOnMainThread();
}
@@ -333,6 +336,14 @@ class FileSystemURLLoaderFactoryTest : public ContentBrowserTest {
network::mojom::URLLoaderPtr loader_;
private:
+ static void OnOpenFileSystem(base::OnceClosure done_closure,
+ const GURL& root_url,
+ const std::string& name,
+ base::File::Error result) {
+ ASSERT_EQ(base::File::FILE_OK, result);
+ std::move(done_closure).Run();
+ }
+
storage::FileSystemFileUtil* file_util() {
return file_system_context_->sandbox_delegate()->sync_file_util();
}
@@ -344,12 +355,6 @@ class FileSystemURLLoaderFactoryTest : public ContentBrowserTest {
return context;
}
- void OnOpenFileSystem(const GURL& root_url,
- const std::string& name,
- base::File::Error result) {
- ASSERT_EQ(base::File::FILE_OK, result);
- }
-
RenderFrameHost* render_frame_host() const {
return shell()->web_contents()->GetMainFrame();
}
@@ -393,7 +398,6 @@ class FileSystemURLLoaderFactoryTest : public ContentBrowserTest {
base::test::ScopedFeatureList feature_list_;
scoped_refptr<MockSpecialStoragePolicy> special_storage_policy_;
scoped_refptr<FileSystemContext> file_system_context_;
- base::WeakPtrFactory<FileSystemURLLoaderFactoryTest> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(FileSystemURLLoaderFactoryTest);
};
diff --git a/chromium/content/browser/find_request_manager_browsertest.cc b/chromium/content/browser/find_request_manager_browsertest.cc
index c639245949f..f0d21d59c56 100644
--- a/chromium/content/browser/find_request_manager_browsertest.cc
+++ b/chromium/content/browser/find_request_manager_browsertest.cc
@@ -328,14 +328,9 @@ IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(CharacterByCharacter)) {
// TODO(crbug.com/615291): This test frequently fails on Android.
// TODO(crbug.com/674742): This test is flaky on Win
-#if defined(OS_ANDROID) || defined(OS_WIN)
-#define MAYBE_RapidFire DISABLED_RapidFire
-#else
-#define MAYBE_RapidFire RapidFire
-#endif
-
+// TODO(crbug.com/850286): Flaky on CrOS MSan
// Tests sending a large number of find requests subsequently.
-IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE_RapidFire) {
+IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, DISABLED_RapidFire) {
LoadAndWait("/find_in_page.html");
if (GetParam())
MakeChildFrameCrossProcess();
diff --git a/chromium/content/browser/frame_host/blocked_scheme_navigation_browsertest.cc b/chromium/content/browser/frame_host/blocked_scheme_navigation_browsertest.cc
index f25ed52f307..af837fc7f06 100644
--- a/chromium/content/browser/frame_host/blocked_scheme_navigation_browsertest.cc
+++ b/chromium/content/browser/frame_host/blocked_scheme_navigation_browsertest.cc
@@ -450,12 +450,12 @@ class BlockedSchemeNavigationBrowserTest
DownloadManager* download_manager = BrowserContext::GetDownloadManager(
shell()->web_contents()->GetBrowserContext());
- EXPECT_TRUE(ExecuteScript(rfh, javascript));
- Shell* new_shell = new_shell_observer.GetShell();
-
DownloadTestObserverTerminal download_observer(
download_manager, 1, DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
+ EXPECT_TRUE(ExecuteScript(rfh, javascript));
+ Shell* new_shell = new_shell_observer.GetShell();
+
WaitForLoadStop(new_shell->web_contents());
// If no download happens, this will timeout.
download_observer.WaitForFinished();
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 337d713ddfa..1017d3ce539 100644
--- a/chromium/content/browser/frame_host/cross_process_frame_connector.cc
+++ b/chromium/content/browser/frame_host/cross_process_frame_connector.cc
@@ -118,7 +118,7 @@ void CrossProcessFrameConnector::SetView(RenderWidgetHostViewChildFrame* view) {
if (is_hidden_)
OnVisibilityChanged(false);
FrameMsg_ViewChanged_Params params;
- if (!base::FeatureList::IsEnabled(::features::kMash))
+ if (features::IsAshInBrowserProcess())
params.frame_sink_id = view_->GetFrameSinkId();
frame_proxy_in_parent_renderer_->Send(new FrameMsg_ViewChanged(
frame_proxy_in_parent_renderer_->GetRoutingID(), params));
@@ -145,9 +145,9 @@ void CrossProcessFrameConnector::RenderProcessGone() {
frame_proxy_in_parent_renderer_->GetRoutingID()));
}
-void CrossProcessFrameConnector::SetChildFrameSurface(
+void CrossProcessFrameConnector::FirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) {
- frame_proxy_in_parent_renderer_->Send(new FrameMsg_SetChildFrameSurface(
+ frame_proxy_in_parent_renderer_->Send(new FrameMsg_FirstSurfaceActivation(
frame_proxy_in_parent_renderer_->GetRoutingID(), surface_info));
}
@@ -229,14 +229,30 @@ void CrossProcessFrameConnector::ForwardProcessAckedTouchEvent(
const TouchEventWithLatencyInfo& touch,
InputEventAckState ack_result) {
auto* main_view = GetRootRenderWidgetHostView();
+ // Note that the event's coordinates are in |view_|'s coordinate space, but
+ // since |ProcessAckedTouchEvent| doesn't use the coordinates, we don't
+ // bother to transform them back to the root coordinate space.
if (main_view)
main_view->ProcessAckedTouchEvent(touch, ack_result);
}
+void CrossProcessFrameConnector::ForwardAckedTouchpadPinchGestureEvent(
+ const blink::WebGestureEvent& event,
+ InputEventAckState ack_result) {
+ auto* root_view = GetRootRenderWidgetHostView();
+ if (!root_view)
+ return;
+
+ blink::WebGestureEvent pinch_event(event);
+ const gfx::PointF root_point =
+ view_->TransformPointToRootCoordSpaceF(event.PositionInWidget());
+ pinch_event.SetPositionInWidget(root_point);
+ root_view->GestureEventAck(pinch_event, ack_result);
+}
+
void CrossProcessFrameConnector::BubbleScrollEvent(
const blink::WebGestureEvent& event) {
- DCHECK((view_->wheel_scroll_latching_enabled() &&
- event.GetType() == blink::WebInputEvent::kGestureScrollBegin) ||
+ DCHECK(event.GetType() == blink::WebInputEvent::kGestureScrollBegin ||
event.GetType() == blink::WebInputEvent::kGestureScrollUpdate ||
event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
event.GetType() == blink::WebInputEvent::kGestureFlingStart);
@@ -255,28 +271,19 @@ void CrossProcessFrameConnector::BubbleScrollEvent(
const gfx::PointF root_point =
view_->TransformPointToRootCoordSpaceF(event.PositionInWidget());
resent_gesture_event.SetPositionInWidget(root_point);
-
- if (view_->wheel_scroll_latching_enabled()) {
- if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
- event_router->BubbleScrollEvent(parent_view, resent_gesture_event, view_);
- is_scroll_bubbling_ = true;
- } else if (is_scroll_bubbling_) {
- event_router->BubbleScrollEvent(parent_view, resent_gesture_event, view_);
- }
- if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
- event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
- is_scroll_bubbling_ = false;
- }
- } else { // !view_->wheel_scroll_latching_enabled()
- if (event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) {
- event_router->BubbleScrollEvent(parent_view, resent_gesture_event, view_);
- is_scroll_bubbling_ = true;
- } else if ((event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
- event.GetType() == blink::WebInputEvent::kGestureFlingStart) &&
- is_scroll_bubbling_) {
- event_router->BubbleScrollEvent(parent_view, resent_gesture_event, view_);
- is_scroll_bubbling_ = false;
- }
+ // When a gesture event is bubbled to the parent frame, set the allowed touch
+ // action of the parent frame to Auto so that this gesture event is allowed.
+ parent_view->host()->input_router()->ForceSetTouchActionAuto();
+
+ if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
+ event_router->BubbleScrollEvent(parent_view, resent_gesture_event, view_);
+ is_scroll_bubbling_ = true;
+ } else if (is_scroll_bubbling_) {
+ event_router->BubbleScrollEvent(parent_view, resent_gesture_event, view_);
+ }
+ if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
+ event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
+ is_scroll_bubbling_ = false;
}
}
@@ -313,8 +320,8 @@ void CrossProcessFrameConnector::OnSynchronizeVisualProperties(
// the viz::LocalSurfaceId must also change.
if ((last_received_local_frame_size_ != visual_properties.local_frame_size ||
screen_info_ != visual_properties.screen_info ||
- capture_sequence_number() !=
- visual_properties.capture_sequence_number) &&
+ capture_sequence_number() != visual_properties.capture_sequence_number ||
+ last_received_zoom_level_ != visual_properties.zoom_level) &&
local_surface_id_ == surface_id.local_surface_id()) {
bad_message::ReceivedBadMessage(
frame_proxy_in_parent_renderer_->GetProcess(),
@@ -322,6 +329,7 @@ void CrossProcessFrameConnector::OnSynchronizeVisualProperties(
return;
}
+ last_received_zoom_level_ = visual_properties.zoom_level;
last_received_local_frame_size_ = visual_properties.local_frame_size;
SynchronizeVisualProperties(surface_id, visual_properties);
}
@@ -544,6 +552,16 @@ void CrossProcessFrameConnector::MaybeLogCrash(CrashVisibility visibility) {
// Actually log the UMA.
UMA_HISTOGRAM_ENUMERATION("Stability.ChildFrameCrash.Visibility", visibility);
+
+ if (visibility == CrashVisibility::kShownAfterCrashing) {
+ auto* rfh = frame_proxy_in_parent_renderer_->frame_tree_node()
+ ->current_frame_host();
+ if (rfh->GetParent() && rfh->is_local_root()) {
+ UMA_HISTOGRAM_BOOLEAN(
+ "RenderFrameHostImpl.ReceivedPostMessageFromNonDescendant",
+ rfh->received_post_message_from_non_descendant());
+ }
+ }
}
bool CrossProcessFrameConnector::IsVisible() {
diff --git a/chromium/content/browser/frame_host/cross_process_frame_connector.h b/chromium/content/browser/frame_host/cross_process_frame_connector.h
index 21759b18be7..b0dc031915c 100644
--- a/chromium/content/browser/frame_host/cross_process_frame_connector.h
+++ b/chromium/content/browser/frame_host/cross_process_frame_connector.h
@@ -77,7 +77,7 @@ class CONTENT_EXPORT CrossProcessFrameConnector
RenderWidgetHostViewBase* GetParentRenderWidgetHostView() override;
RenderWidgetHostViewBase* GetRootRenderWidgetHostView() override;
void RenderProcessGone() override;
- void SetChildFrameSurface(const viz::SurfaceInfo& surface_info) override;
+ void FirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
void SendIntrinsicSizingInfoToParent(
const blink::WebIntrinsicSizingInfo&) override;
@@ -98,6 +98,9 @@ class CONTENT_EXPORT CrossProcessFrameConnector
viz::EventSource source = viz::EventSource::ANY) override;
void ForwardProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
InputEventAckState ack_result) override;
+ void ForwardAckedTouchpadPinchGestureEvent(
+ const blink::WebGestureEvent& event,
+ InputEventAckState ack_result) override;
void BubbleScrollEvent(const blink::WebGestureEvent& event) override;
bool HasFocus() override;
void FocusRootView() override;
@@ -198,6 +201,10 @@ class CONTENT_EXPORT CrossProcessFrameConnector
// off.
gfx::Size last_received_local_frame_size_;
+ // The last zoom level received from parent renderer, which is used to check
+ // if a new surface is created in case of zoom level change.
+ double last_received_zoom_level_ = 0.0;
+
DISALLOW_COPY_AND_ASSIGN(CrossProcessFrameConnector);
};
diff --git a/chromium/content/browser/frame_host/frame_navigation_entry.h b/chromium/content/browser/frame_host/frame_navigation_entry.h
index 50076c1af7e..ee599312d4a 100644
--- a/chromium/content/browser/frame_host/frame_navigation_entry.h
+++ b/chromium/content/browser/frame_host/frame_navigation_entry.h
@@ -88,11 +88,15 @@ class CONTENT_EXPORT FrameNavigationEntry
void set_document_sequence_number(int64_t document_sequence_number);
int64_t document_sequence_number() const { return document_sequence_number_; }
- // The SiteInstance responsible for rendering this frame. All frames sharing
- // a SiteInstance must live in the same process. This is a refcounted pointer
- // that keeps the SiteInstance (not necessarily the process) alive as long as
- // this object remains in the session history.
+ // The SiteInstance, as assigned at commit time, responsible for rendering
+ // this frame. All frames sharing a SiteInstance must live in the same
+ // process. This is a refcounted pointer that keeps the SiteInstance (not
+ // necessarily the process) alive as long as this object remains in the
+ // session history.
+ // TODO(nasko, creis): The SiteInstance of a FrameNavigationEntry should
+ // not change once it has been assigned. See https://crbug.com/849430.
void set_site_instance(scoped_refptr<SiteInstanceImpl> site_instance) {
+ CHECK(!site_instance_ || site_instance_ == site_instance);
site_instance_ = std::move(site_instance);
}
SiteInstanceImpl* site_instance() const { return site_instance_.get(); }
diff --git a/chromium/content/browser/frame_host/frame_tree.cc b/chromium/content/browser/frame_host/frame_tree.cc
index 5f7134c4f2b..ed5a3d823ac 100644
--- a/chromium/content/browser/frame_host/frame_tree.cc
+++ b/chromium/content/browser/frame_host/frame_tree.cc
@@ -353,6 +353,7 @@ RenderViewHostImpl* FrameTree::CreateRenderViewHost(
SiteInstance* site_instance,
int32_t routing_id,
int32_t main_frame_routing_id,
+ int32_t widget_routing_id,
bool swapped_out,
bool hidden) {
RenderViewHostMap::iterator iter =
@@ -363,7 +364,8 @@ RenderViewHostImpl* FrameTree::CreateRenderViewHost(
RenderViewHostImpl* rvh =
static_cast<RenderViewHostImpl*>(RenderViewHostFactory::Create(
site_instance, render_view_delegate_, render_widget_delegate_,
- routing_id, main_frame_routing_id, swapped_out, hidden));
+ routing_id, main_frame_routing_id, widget_routing_id, swapped_out,
+ hidden));
render_view_host_map_[site_instance->GetId()] = rvh;
return rvh;
diff --git a/chromium/content/browser/frame_host/frame_tree.h b/chromium/content/browser/frame_host/frame_tree.h
index 3b24e06febd..248489e5aa5 100644
--- a/chromium/content/browser/frame_host/frame_tree.h
+++ b/chromium/content/browser/frame_host/frame_tree.h
@@ -183,6 +183,7 @@ class CONTENT_EXPORT FrameTree {
RenderViewHostImpl* CreateRenderViewHost(SiteInstance* site_instance,
int32_t routing_id,
int32_t main_frame_routing_id,
+ int32_t widget_routing_id,
bool swapped_out,
bool hidden);
diff --git a/chromium/content/browser/frame_host/frame_tree_node.cc b/chromium/content/browser/frame_host/frame_tree_node.cc
index a99f5ab0ee5..46e3d2a7678 100644
--- a/chromium/content/browser/frame_host/frame_tree_node.cc
+++ b/chromium/content/browser/frame_host/frame_tree_node.cc
@@ -24,6 +24,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "third_party/blink/public/common/frame/sandbox_flags.h"
+#include "third_party/blink/public/common/frame/user_activation_update_type.h"
namespace content {
@@ -466,8 +467,9 @@ void FrameTreeNode::ResetNavigationRequest(bool keep_state,
// 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 =
- inform_renderer && navigation_request_->from_begin_navigation();
+ bool need_to_inform_renderer =
+ !IsPerNavigationMojoInterfaceEnabled() & inform_renderer &&
+ navigation_request_->from_begin_navigation();
NavigationRequest::AssociatedSiteInstanceType site_instance_type =
navigation_request_->associated_site_instance_type();
@@ -597,9 +599,31 @@ void FrameTreeNode::BeforeUnloadCanceled() {
ResetNavigationRequest(false, true);
}
-void FrameTreeNode::OnSetHasReceivedUserGesture() {
- render_manager_.OnSetHasReceivedUserGesture();
+bool FrameTreeNode::NotifyUserActivation() {
+ for (FrameTreeNode* node = this; node; node = node->parent())
+ node->user_activation_state_.Activate();
replication_state_.has_received_user_gesture = true;
+ return true;
+}
+
+bool FrameTreeNode::ConsumeTransientUserActivation() {
+ bool was_active = user_activation_state_.IsActive();
+ for (FrameTreeNode* node : frame_tree()->Nodes())
+ node->user_activation_state_.ConsumeIfActive();
+ return was_active;
+}
+
+bool FrameTreeNode::UpdateUserActivationState(
+ blink::UserActivationUpdateType update_type) {
+ render_manager_.UpdateUserActivationState(update_type);
+ switch (update_type) {
+ case blink::UserActivationUpdateType::kConsumeTransientActivation:
+ return ConsumeTransientUserActivation();
+
+ case blink::UserActivationUpdateType::kNotifyActivation:
+ return NotifyUserActivation();
+ }
+ NOTREACHED() << "Invalid update_type.";
}
void FrameTreeNode::OnSetHasReceivedUserGestureBeforeNavigation(bool value) {
diff --git a/chromium/content/browser/frame_host/frame_tree_node.h b/chromium/content/browser/frame_host/frame_tree_node.h
index db49e3691d9..4e589ac428f 100644
--- a/chromium/content/browser/frame_host/frame_tree_node.h
+++ b/chromium/content/browser/frame_host/frame_tree_node.h
@@ -21,6 +21,8 @@
#include "content/common/frame_owner_properties.h"
#include "content/common/frame_replication_state.h"
#include "third_party/blink/public/common/frame/frame_policy.h"
+#include "third_party/blink/public/common/frame/user_activation_state.h"
+#include "third_party/blink/public/common/frame/user_activation_update_type.h"
#include "third_party/blink/public/platform/web_insecure_request_policy.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -342,7 +344,13 @@ class CONTENT_EXPORT FrameTreeNode {
// Returns the BlameContext associated with this node.
FrameTreeNodeBlameContext& blame_context() { return blame_context_; }
- void OnSetHasReceivedUserGesture();
+ // Updates the user activation state in the browser frame tree and in the
+ // frame trees in all renderer processes except the renderer for this node
+ // (which initiated the update). Returns |false| if the update tries to
+ // consume an already consumed/expired transient state, |true| otherwise. See
+ // the comment on user_activation_state_ below.
+ bool UpdateUserActivationState(blink::UserActivationUpdateType update_type);
+
void OnSetHasReceivedUserGestureBeforeNavigation(bool value);
// Returns the sandbox flags currently in effect for this frame. This includes
@@ -380,6 +388,18 @@ class CONTENT_EXPORT FrameTreeNode {
// request and reset to false in FrameTreeNode.
void set_was_discarded() { was_discarded_ = true; }
+ // Returns the sticky bit of the User Activation v2 state of the
+ // |FrameTreeNode|.
+ bool HasBeenActivated() const {
+ return user_activation_state_.HasBeenActive();
+ }
+
+ // Returns the transient bit of the User Activation v2 state of the
+ // |FrameTreeNode|.
+ bool HasTransientUserActivation() {
+ return user_activation_state_.IsActive();
+ }
+
private:
FRIEND_TEST_ALL_PREFIXES(SitePerProcessFeaturePolicyBrowserTest,
ContainerPolicyDynamic);
@@ -390,6 +410,10 @@ class CONTENT_EXPORT FrameTreeNode {
FrameTreeNode* GetSibling(int relative_offset) const;
+ bool NotifyUserActivation();
+
+ bool ConsumeTransientUserActivation();
+
// The next available browser-global FrameTreeNode ID.
static int next_frame_tree_node_id_;
@@ -492,6 +516,34 @@ class CONTENT_EXPORT FrameTreeNode {
bool was_discarded_;
+ // The user activation state of the current frame.
+ //
+ // Changes to this state update other FrameTreeNodes as follows: for
+ // notification updates (on user inputs) all ancestor nodes are updated; for
+ // activation consumption calls, the whole frame tree is updated (w/o such
+ // exhaustive consumption, a rouge iframe can cause multiple consumptions per
+ // user activation).
+ //
+ // The user activation state is replicated in the browser process (in
+ // FrameTreeNode) and in the renderer processes (in LocalFrame and
+ // RemoteFrames). The replicated states across the browser and renderer
+ // processes are kept in sync as follows:
+ //
+ // [A] Consumption of activation state for popups starts in the frame tree of
+ // the browser process and propagate to the renderer trees through direct IPCs
+ // (one IPC sent to each renderer).
+ //
+ // [B] Consumption calls from JS/blink side (e.g. video picture-in-picture)
+ // update the originating renderer's local frame tree and send an IPC to the
+ // browser; the browser updates its frame tree and sends IPCs to all other
+ // renderers each of which then updates its local frame tree.
+ //
+ // [B'] Notification updates on user inputs still follow [B] but they should
+ // really follow [A]. TODO(mustaq): fix through https://crbug.com/848778.
+ //
+ // [C] Expiration of an active state is tracked independently in each process.
+ blink::UserActivationState user_activation_state_;
+
// A helper for tracing the snapshots of this FrameTreeNode and attributing
// browser process activities to this node (when possible). It is unrelated
// to the core logic of FrameTreeNode.
diff --git a/chromium/content/browser/frame_host/frame_tree_unittest.cc b/chromium/content/browser/frame_host/frame_tree_unittest.cc
index 40a35831d96..015150461cd 100644
--- a/chromium/content/browser/frame_host/frame_tree_unittest.cc
+++ b/chromium/content/browser/frame_host/frame_tree_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright 2013 The Chromium Authors.All rights reserved.
+// 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.
@@ -159,7 +159,7 @@ TEST_F(FrameTreeTest, Shape) {
// itself. Instead, leave them in "not live" state, which is indicated by the
// * after the frame id, since this test cares about the shape, not the
// frame liveness.
- EXPECT_EQ("2: []", GetTreeState(frame_tree));
+ EXPECT_EQ("3: []", GetTreeState(frame_tree));
// Simulate attaching a series of frames to build the frame tree.
frame_tree->AddFrame(root, process_id, 14,
@@ -194,7 +194,7 @@ TEST_F(FrameTreeTest, Shape) {
blink::FramePolicy(), FrameOwnerProperties(), false);
EXPECT_EQ(
- "2: [14: [244: [], 245: []], "
+ "3: [14: [244: [], 245: []], "
"15: [255 'no children node': []], "
"16: []]",
GetTreeState(frame_tree));
@@ -250,7 +250,7 @@ TEST_F(FrameTreeTest, Shape) {
// Now that's it's fully built, verify the tree structure is as expected.
EXPECT_EQ(
- "2: [14: [244: [], 245: []], "
+ "3: [14: [244: [], 245: []], "
"15: [255 'no children node': []], "
"16: [264: [], 265: [], 266: [], "
"267 'node with deep subtree': "
@@ -264,27 +264,27 @@ TEST_F(FrameTreeTest, Shape) {
FrameTreeNode* child_245 = child_14->child_at(1);
FrameTreeNode* child_555 = child_267->child_at(0)->child_at(0)->child_at(0);
FrameTreeNode* child_655 = child_555->child_at(0);
- EXPECT_EQ("2 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
+ EXPECT_EQ("3 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
GetTraversalOrder(frame_tree, nullptr));
- EXPECT_EQ("2", GetTraversalOrder(frame_tree, root));
- EXPECT_EQ("2 14 15 16 255 264 265 266 267 268 365 455 555 655",
+ EXPECT_EQ("3", GetTraversalOrder(frame_tree, root));
+ EXPECT_EQ("3 14 15 16 255 264 265 266 267 268 365 455 555 655",
GetTraversalOrder(frame_tree, child_14));
- EXPECT_EQ("2 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
+ EXPECT_EQ("3 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
GetTraversalOrder(frame_tree, child_244));
- EXPECT_EQ("2 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
+ EXPECT_EQ("3 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
GetTraversalOrder(frame_tree, child_245));
- EXPECT_EQ("2 14 15 16 244 245 264 265 266 267 268 365 455 555 655",
+ EXPECT_EQ("3 14 15 16 244 245 264 265 266 267 268 365 455 555 655",
GetTraversalOrder(frame_tree, child_15));
- EXPECT_EQ("2 14 15 16 244 245 255 264 265 266 267 268",
+ EXPECT_EQ("3 14 15 16 244 245 255 264 265 266 267 268",
GetTraversalOrder(frame_tree, child_267));
- EXPECT_EQ("2 14 15 16 244 245 255 264 265 266 267 268 365 455 555",
+ EXPECT_EQ("3 14 15 16 244 245 255 264 265 266 267 268 365 455 555",
GetTraversalOrder(frame_tree, child_555));
- EXPECT_EQ("2 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
+ EXPECT_EQ("3 14 15 16 244 245 255 264 265 266 267 268 365 455 555 655",
GetTraversalOrder(frame_tree, child_655));
frame_tree->RemoveFrame(child_555);
EXPECT_EQ(
- "2: [14: [244: [], 245: []], "
+ "3: [14: [244: [], 245: []], "
"15: [255 'no children node': []], "
"16: [264: [], 265: [], 266: [], "
"267 'node with deep subtree': "
@@ -293,7 +293,7 @@ TEST_F(FrameTreeTest, Shape) {
frame_tree->RemoveFrame(child_16->child_at(1));
EXPECT_EQ(
- "2: [14: [244: [], 245: []], "
+ "3: [14: [244: [], 245: []], "
"15: [255 'no children node': []], "
"16: [264: [], 266: [], "
"267 'node with deep subtree': "
@@ -302,7 +302,7 @@ TEST_F(FrameTreeTest, Shape) {
frame_tree->RemoveFrame(root->child_at(1));
EXPECT_EQ(
- "2: [14: [244: [], 245: []], "
+ "3: [14: [244: [], 245: []], "
"16: [264: [], 266: [], "
"267 'node with deep subtree': "
"[365: [455: []]], 268: []]]",
@@ -424,7 +424,7 @@ TEST_F(FrameTreeTest, GetSibling) {
TEST_F(FrameTreeTest, ObserverWalksTreeDuringFrameCreation) {
TreeWalkingWebContentsLogger activity(contents());
contents()->NavigateAndCommit(GURL("http://www.google.com"));
- EXPECT_EQ("RenderFrameCreated(2) -> 2: []", activity.GetLog());
+ EXPECT_EQ("RenderFrameCreated(3) -> 3: []", activity.GetLog());
FrameTree* frame_tree = contents()->GetFrameTree();
FrameTreeNode* root = frame_tree->root();
@@ -436,8 +436,8 @@ TEST_F(FrameTreeTest, ObserverWalksTreeDuringFrameCreation) {
base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
EXPECT_EQ(
- "RenderFrameHostChanged(new)(14) -> 2: []\n"
- "RenderFrameCreated(14) -> 2: [14: []]",
+ "RenderFrameHostChanged(new)(14) -> 3: []\n"
+ "RenderFrameCreated(14) -> 3: [14: []]",
activity.GetLog());
main_test_rfh()->OnCreateChildFrame(
18, CreateStubInterfaceProviderRequest(),
@@ -445,13 +445,13 @@ TEST_F(FrameTreeTest, ObserverWalksTreeDuringFrameCreation) {
base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
EXPECT_EQ(
- "RenderFrameHostChanged(new)(18) -> 2: [14: []]\n"
- "RenderFrameCreated(18) -> 2: [14: [], 18: []]",
+ "RenderFrameHostChanged(new)(18) -> 3: [14: []]\n"
+ "RenderFrameCreated(18) -> 3: [14: [], 18: []]",
activity.GetLog());
frame_tree->RemoveFrame(root->child_at(0));
- EXPECT_EQ("RenderFrameDeleted(14) -> 2: [18: []]", activity.GetLog());
+ EXPECT_EQ("RenderFrameDeleted(14) -> 3: [18: []]", activity.GetLog());
frame_tree->RemoveFrame(root->child_at(0));
- EXPECT_EQ("RenderFrameDeleted(18) -> 2: []", activity.GetLog());
+ EXPECT_EQ("RenderFrameDeleted(18) -> 3: []", activity.GetLog());
}
// Make sure that WebContentsObservers see a consistent view of the tree after
@@ -459,7 +459,7 @@ TEST_F(FrameTreeTest, ObserverWalksTreeDuringFrameCreation) {
TEST_F(FrameTreeTest, ObserverWalksTreeAfterCrash) {
TreeWalkingWebContentsLogger activity(contents());
contents()->NavigateAndCommit(GURL("http://www.google.com"));
- EXPECT_EQ("RenderFrameCreated(2) -> 2: []", activity.GetLog());
+ EXPECT_EQ("RenderFrameCreated(3) -> 3: []", activity.GetLog());
main_test_rfh()->OnCreateChildFrame(
22, CreateStubInterfaceProviderRequest(),
@@ -467,8 +467,8 @@ TEST_F(FrameTreeTest, ObserverWalksTreeAfterCrash) {
base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
EXPECT_EQ(
- "RenderFrameHostChanged(new)(22) -> 2: []\n"
- "RenderFrameCreated(22) -> 2: [22: []]",
+ "RenderFrameHostChanged(new)(22) -> 3: []\n"
+ "RenderFrameCreated(22) -> 3: [22: []]",
activity.GetLog());
main_test_rfh()->OnCreateChildFrame(
23, CreateStubInterfaceProviderRequest(),
@@ -476,17 +476,17 @@ TEST_F(FrameTreeTest, ObserverWalksTreeAfterCrash) {
base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties());
EXPECT_EQ(
- "RenderFrameHostChanged(new)(23) -> 2: [22: []]\n"
- "RenderFrameCreated(23) -> 2: [22: [], 23: []]",
+ "RenderFrameHostChanged(new)(23) -> 3: [22: []]\n"
+ "RenderFrameCreated(23) -> 3: [22: [], 23: []]",
activity.GetLog());
// Crash the renderer
main_test_rfh()->GetProcess()->SimulateCrash();
EXPECT_EQ(
- "RenderProcessGone -> 2*: [22*: [], 23*: []]\n"
- "RenderFrameDeleted(23) -> 2*: [22*: [], 23*: []]\n"
- "RenderFrameDeleted(22) -> 2*: [22*: [], 23*: []]\n"
- "RenderFrameDeleted(2) -> 2*: []",
+ "RenderProcessGone -> 3*: [22*: [], 23*: []]\n"
+ "RenderFrameDeleted(23) -> 3*: [22*: [], 23*: []]\n"
+ "RenderFrameDeleted(22) -> 3*: [22*: [], 23*: []]\n"
+ "RenderFrameDeleted(3) -> 3*: []",
activity.GetLog());
}
@@ -498,7 +498,7 @@ TEST_F(FrameTreeTest, FailAddFrameWithWrongProcessId) {
FrameTreeNode* root = frame_tree->root();
int process_id = root->current_frame_host()->GetProcess()->GetID();
- ASSERT_EQ("2: []", GetTreeState(frame_tree));
+ ASSERT_EQ("3: []", GetTreeState(frame_tree));
// Simulate attaching a frame from mismatched process id.
ASSERT_FALSE(frame_tree->AddFrame(
@@ -506,7 +506,7 @@ TEST_F(FrameTreeTest, FailAddFrameWithWrongProcessId) {
blink::WebTreeScopeType::kDocument, std::string(), "uniqueName0", false,
base::UnguessableToken::Create(), blink::FramePolicy(),
FrameOwnerProperties(), false));
- ASSERT_EQ("2: []", GetTreeState(frame_tree));
+ ASSERT_EQ("3: []", GetTreeState(frame_tree));
}
// Ensure that frames removed while a process has crashed are not preserved in
diff --git a/chromium/content/browser/frame_host/interstitial_page_impl.cc b/chromium/content/browser/frame_host/interstitial_page_impl.cc
index ad9de41d1e3..f839f62061b 100644
--- a/chromium/content/browser/frame_host/interstitial_page_impl.cc
+++ b/chromium/content/browser/frame_host/interstitial_page_impl.cc
@@ -607,12 +607,9 @@ RenderViewHostImpl* InterstitialPageImpl::CreateRenderViewHost() {
SessionStorageNamespaceImpl::Create(dom_storage_context);
// Use the RenderViewHost from our FrameTree.
- // TODO(avi): The view routing ID can be restored to MSG_ROUTING_NONE once
- // RenderViewHostImpl has-a RenderWidgetHostImpl. https://crbug.com/545684
- int32_t widget_routing_id = site_instance->GetProcess()->GetNextRoutingID();
frame_tree_->root()->render_manager()->Init(
- site_instance.get(), widget_routing_id, MSG_ROUTING_NONE,
- widget_routing_id, false);
+ site_instance.get(), MSG_ROUTING_NONE, MSG_ROUTING_NONE, MSG_ROUTING_NONE,
+ false);
return frame_tree_->root()->current_frame_host()->render_view_host();
}
diff --git a/chromium/content/browser/frame_host/navigation_controller_delegate.h b/chromium/content/browser/frame_host/navigation_controller_delegate.h
index 1b9f0c935c7..64c22ec9869 100644
--- a/chromium/content/browser/frame_host/navigation_controller_delegate.h
+++ b/chromium/content/browser/frame_host/navigation_controller_delegate.h
@@ -11,6 +11,7 @@
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_details.h"
+#include "content/public/common/previews_state.h"
namespace content {
@@ -69,6 +70,14 @@ class NavigationControllerDelegate {
virtual void DetachInterstitialPage(bool has_focus) = 0;
virtual void UpdateOverridingUserAgent() = 0;
+
+ // Gives the delegate a chance to adjust the previews state during navigation.
+ // When called, previews_state will be pointing to a valid set of previews, or
+ // an enum value disabling previews. The call will change the value of
+ // previews_state in place, and must change it to either a value disabling
+ // previews, or a subset of the previews passed in.
+ virtual void AdjustPreviewsStateForNavigation(
+ PreviewsState* previews_state) = 0;
};
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl.cc b/chromium/content/browser/frame_host/navigation_controller_impl.cc
index 74ff6b4286c..d8aca9e2cbf 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl.cc
@@ -50,6 +50,7 @@
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "content/browser/bad_message.h"
+#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/browser_url_handler_impl.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
@@ -80,6 +81,7 @@
#include "media/base/mime_util.h"
#include "net/base/escape.h"
#include "skia/ext/platform_canvas.h"
+#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
#include "url/url_constants.h"
@@ -230,6 +232,60 @@ void CopyReplacedNavigationEntryDataIfPreviouslyEmpty(
output_entry->SetReplacedEntryData(data);
}
+FrameMsg_Navigate_Type::Value GetNavigationType(
+ const GURL& old_url,
+ const GURL& new_url,
+ ReloadType reload_type,
+ const NavigationEntryImpl& entry,
+ const FrameNavigationEntry& frame_entry,
+ bool is_same_document_history_load) {
+ // Reload navigations
+ switch (reload_type) {
+ case ReloadType::NORMAL:
+ return FrameMsg_Navigate_Type::RELOAD;
+ case ReloadType::BYPASSING_CACHE:
+ return FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE;
+ case ReloadType::ORIGINAL_REQUEST_URL:
+ return FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL;
+ case ReloadType::NONE:
+ break; // Fall through to rest of function.
+ }
+
+ if (entry.restore_type() == RestoreType::LAST_SESSION_EXITED_CLEANLY) {
+ if (entry.GetHasPostData())
+ return FrameMsg_Navigate_Type::RESTORE_WITH_POST;
+ else
+ return FrameMsg_Navigate_Type::RESTORE;
+ }
+
+ // History navigations.
+ if (frame_entry.page_state().IsValid()) {
+ if (is_same_document_history_load)
+ return FrameMsg_Navigate_Type::HISTORY_SAME_DOCUMENT;
+ else
+ return FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;
+ }
+ DCHECK(!is_same_document_history_load);
+
+ // A same-document fragment-navigation happens when the only part of the url
+ // that is modified is after the '#' character.
+ //
+ // When modifying this condition, please take a look at:
+ // FrameLoader::shouldPerformFragmentNavigation.
+ //
+ // Note: this check is only valid for navigations that are not history
+ // navigations. For instance, if the history is: 'A#bar' -> 'B' -> 'A#foo', a
+ // history navigation from 'A#foo' to 'A#bar' is not a same-document
+ // navigation, but a different-document one. This is why history navigation
+ // are classified before this check.
+ if (new_url.has_ref() && old_url.EqualsIgnoringRef(new_url) &&
+ frame_entry.method() == "GET") {
+ return FrameMsg_Navigate_Type::SAME_DOCUMENT;
+ } else {
+ return FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
+ }
+}
+
} // namespace
// NavigationControllerImpl ----------------------------------------------------
@@ -433,43 +489,11 @@ void NavigationControllerImpl::Reload(ReloadType reload_type,
if (!IsInitialNavigation())
DiscardNonCommittedEntriesInternal();
- // If we are reloading an entry that no longer belongs to the current
- // SiteInstance (for example, refreshing a page for just installed app), the
- // reload must happen in a new process. The new entry behaves as new
- // navigation (which happens to clear forward history). Tabs that are
- // discarded due to low memory conditions may not have a SiteInstance, and
- // should not be treated as a cross-site reload.
- SiteInstanceImpl* site_instance = entry->site_instance();
- // Permit reloading guests without further checks.
- bool is_for_guests_only = site_instance && site_instance->HasProcess() &&
- site_instance->GetProcess()->IsForGuestsOnly();
- if (!is_for_guests_only && site_instance &&
- site_instance->HasWrongProcessForURL(entry->GetURL())) {
- // Create a navigation entry that resembles the current one, but do not
- // copy page id, site instance, content state, or timestamp.
- NavigationEntryImpl* nav_entry = NavigationEntryImpl::FromNavigationEntry(
- CreateNavigationEntry(entry->GetURL(), entry->GetReferrer(),
- entry->GetTransitionType(), false,
- entry->extra_headers(), browser_context_,
- nullptr /* blob_url_loader_factory */)
- .release());
-
- // Mark the reload type as NO_RELOAD, so navigation will not be considered
- // a reload in the renderer.
- reload_type = ReloadType::NONE;
-
- nav_entry->set_should_replace_entry(true);
- nav_entry->set_is_renderer_initiated(entry->is_renderer_initiated());
- pending_entry_ = nav_entry;
- DCHECK_EQ(-1, pending_entry_index_);
- } else {
- pending_entry_ = entry;
- pending_entry_index_ = current_index;
-
- pending_entry_->SetTransitionType(ui::PAGE_TRANSITION_RELOAD);
- }
+ pending_entry_ = entry;
+ pending_entry_index_ = current_index;
+ pending_entry_->SetTransitionType(ui::PAGE_TRANSITION_RELOAD);
- NavigateToPendingEntry(reload_type, nullptr /* navigation_ui_data */);
+ NavigateToExistingPendingEntry(reload_type);
}
}
@@ -504,18 +528,6 @@ NavigationControllerImpl::GetEntryWithUniqueID(int nav_entry_id) const {
return (index != -1) ? entries_[index].get() : nullptr;
}
-void NavigationControllerImpl::LoadEntry(
- std::unique_ptr<NavigationEntryImpl> entry,
- std::unique_ptr<NavigationUIData> navigation_ui_data) {
- DiscardPendingEntry(false);
-
- // When navigating to a new page, we don't know for sure if we will actually
- // end up leaving the current page. The new page load could for example
- // result in a download or a 'no content' response (e.g., a mailto: URL).
- SetPendingEntry(std::move(entry));
- NavigateToPendingEntry(ReloadType::NONE, std::move(navigation_ui_data));
-}
-
void NavigationControllerImpl::SetPendingEntry(
std::unique_ptr<NavigationEntryImpl> entry) {
DiscardNonCommittedEntriesInternal();
@@ -684,7 +696,7 @@ void NavigationControllerImpl::GoToIndex(int index) {
pending_entry_index_ = index;
pending_entry_->SetTransitionType(ui::PageTransitionFromInt(
pending_entry_->GetTransitionType() | ui::PAGE_TRANSITION_FORWARD_BACK));
- NavigateToPendingEntry(ReloadType::NONE, nullptr /* navigation_ui_data */);
+ NavigateToExistingPendingEntry(ReloadType::NONE);
}
void NavigationControllerImpl::GoToOffset(int offset) {
@@ -756,124 +768,7 @@ void NavigationControllerImpl::LoadURLWithParams(const LoadURLParams& params) {
// The user initiated a load, we don't need to reload anymore.
needs_reload_ = false;
- bool override = false;
- switch (params.override_user_agent) {
- case UA_OVERRIDE_INHERIT:
- override = ShouldKeepOverride(GetLastCommittedEntry());
- break;
- case UA_OVERRIDE_TRUE:
- override = true;
- break;
- case UA_OVERRIDE_FALSE:
- override = false;
- break;
- default:
- NOTREACHED();
- break;
- }
-
- std::unique_ptr<NavigationEntryImpl> entry;
-
- int frame_tree_node_id = params.frame_tree_node_id;
- // navigation_ui_data should only be present for main frame navigations.
- DCHECK(frame_tree_node_id == RenderFrameHost::kNoFrameTreeNodeId ||
- !params.navigation_ui_data);
-
- if (frame_tree_node_id != RenderFrameHost::kNoFrameTreeNodeId ||
- !params.frame_name.empty()) {
- FrameTreeNode* node =
- params.frame_tree_node_id != RenderFrameHost::kNoFrameTreeNodeId
- ? delegate_->GetFrameTree()->FindByID(params.frame_tree_node_id)
- : delegate_->GetFrameTree()->FindByName(params.frame_name);
- if (node && !node->IsMainFrame()) {
- DCHECK(GetLastCommittedEntry());
-
- // Update the FTN ID to use below in case we found a named frame.
- frame_tree_node_id = node->frame_tree_node_id();
-
- // Create an identical NavigationEntry with a new FrameNavigationEntry for
- // the target subframe.
- entry = GetLastCommittedEntry()->Clone();
- entry->AddOrUpdateFrameEntry(
- node, -1, -1, nullptr,
- static_cast<SiteInstanceImpl*>(params.source_site_instance.get()),
- params.url, params.referrer, params.redirect_chain, PageState(),
- "GET", -1, params.blob_url_loader_factory);
- }
- }
-
- // Otherwise, create a pending entry for the main frame.
- if (!entry) {
- // extra_headers in params are \n separated, navigation entries want \r\n.
- std::string extra_headers_crlf;
- base::ReplaceChars(params.extra_headers, "\n", "\r\n", &extra_headers_crlf);
- entry = NavigationEntryImpl::FromNavigationEntry(CreateNavigationEntry(
- params.url, params.referrer, params.transition_type,
- params.is_renderer_initiated, extra_headers_crlf, browser_context_,
- params.blob_url_loader_factory));
- entry->set_source_site_instance(
- static_cast<SiteInstanceImpl*>(params.source_site_instance.get()));
- entry->SetRedirectChain(params.redirect_chain);
- }
-
- // Set the FTN ID (only used in non-site-per-process, for tests).
- entry->set_frame_tree_node_id(frame_tree_node_id);
- // Don't allow an entry replacement if there is no entry to replace.
- // http://crbug.com/457149
- if (params.should_replace_current_entry && entries_.size() > 0)
- entry->set_should_replace_entry(true);
- entry->set_should_clear_history_list(params.should_clear_history_list);
- entry->SetIsOverridingUserAgent(override);
- entry->set_transferred_global_request_id(
- params.transferred_global_request_id);
-
-// Always propagate `has_user_gesture` on Android but only when the request
-// was originated by the renderer on other platforms. This is merely for
-// backward compatibility as browser process user gestures create confusion
-// in many tests.
-#if defined(OS_ANDROID)
- entry->set_has_user_gesture(params.has_user_gesture);
-#else
- if (params.is_renderer_initiated)
- entry->set_has_user_gesture(params.has_user_gesture);
-#endif
-
-#if defined(OS_ANDROID)
- if (params.intent_received_timestamp > 0) {
- entry->set_intent_received_timestamp(
- base::TimeTicks() +
- base::TimeDelta::FromMilliseconds(params.intent_received_timestamp));
- }
-#endif
-
- switch (params.load_type) {
- case LOAD_TYPE_DEFAULT:
- break;
- case LOAD_TYPE_HTTP_POST:
- entry->SetHasPostData(true);
- entry->SetPostData(params.post_data);
- break;
- case LOAD_TYPE_DATA:
- entry->SetBaseURLForDataURL(params.base_url_for_data_url);
- entry->SetVirtualURL(params.virtual_url_for_data_url);
-#if defined(OS_ANDROID)
- entry->SetDataURLAsString(params.data_url_as_string);
-#endif
- entry->SetCanLoadLocalResources(params.can_load_local_resources);
- break;
- default:
- NOTREACHED();
- break;
- }
-
- // TODO(clamy): NavigationEntry is meant for information that will be kept
- // after the navigation ended and therefore is not appropriate for
- // started_from_context_menu. Move started_from_context_menu to
- // NavigationUIData.
- entry->set_started_from_context_menu(params.started_from_context_menu);
- LoadEntry(std::move(entry), params.navigation_ui_data
- ? params.navigation_ui_data->Clone()
- : nullptr);
+ NavigateWithoutEntry(params);
}
bool NavigationControllerImpl::PendingEntryMatchesHandle(
@@ -914,8 +809,25 @@ bool NavigationControllerImpl::RendererDidNavigate(
was_restored = true;
}
- // The renderer tells us whether the navigation replaces the current entry.
- details->did_replace_entry = params.should_replace_current_entry;
+ // If this is a navigation to a matching pending_entry_ and the SiteInstance
+ // has changed, this must be treated as a new navigation with replacement.
+ // Set the replacement bit here and ClassifyNavigation will identify this
+ // case and return NEW_PAGE.
+ if (!rfh->GetParent() && pending_entry_ &&
+ pending_entry_->GetUniqueID() == params.nav_entry_id &&
+ pending_entry_->site_instance() &&
+ pending_entry_->site_instance() != rfh->GetSiteInstance()) {
+ DCHECK_NE(-1, pending_entry_index_);
+ // TODO(nasko,creis): Instead of setting this value here, set
+ // should_replace_current_entry on the parameters we send to the
+ // renderer process as part of CommitNavigation. The renderer should
+ // in turn send it back here as part of |params| and it can be just
+ // enforced and renderer process terminated on mismatch.
+ details->did_replace_entry = true;
+ } else {
+ // The renderer tells us whether the navigation replaces the current entry.
+ details->did_replace_entry = params.should_replace_current_entry;
+ }
// Do navigation-type specific actions. These will make and commit an entry.
details->type = ClassifyNavigation(rfh, params);
@@ -1110,28 +1022,44 @@ NavigationType NavigationControllerImpl::ClassifyNavigation(
return NAVIGATION_TYPE_NAV_IGNORE;
// This is history.replaceState() or history.reload().
+ // TODO(nasko): With error page isolation, reloading an existing session
+ // history entry can result in change of SiteInstance. Check for such a case
+ // here and classify it as NEW_PAGE, as such navigations should be treated
+ // as new with replacement.
return NAVIGATION_TYPE_EXISTING_PAGE;
}
- if (pending_entry_ && pending_entry_index_ == -1 &&
- pending_entry_->GetUniqueID() == params.nav_entry_id) {
- // In this case, we have a pending entry for a load of a new URL but Blink
- // didn't do a new navigation (params.did_create_new_entry). First check to
- // make sure Blink didn't treat a new cross-process navigation as inert, and
- // thus set params.did_create_new_entry to false. In that case, we must
- // treat it as NEW since the SiteInstance doesn't match the entry.
- if (!GetLastCommittedEntry() ||
- GetLastCommittedEntry()->site_instance() != rfh->GetSiteInstance())
+ if (pending_entry_ && pending_entry_->GetUniqueID() == params.nav_entry_id) {
+ // If the SiteInstance of the |pending_entry_| does not match the
+ // SiteInstance that got committed, treat this as a new navigation with
+ // replacement. This can happen if back/forward/reload encounters a server
+ // redirect to a different site or an isolated error page gets successfully
+ // reloaded into a different SiteInstance.
+ if (pending_entry_->site_instance() &&
+ pending_entry_->site_instance() != rfh->GetSiteInstance()) {
return NAVIGATION_TYPE_NEW_PAGE;
+ }
- // Otherwise, this happens when you press enter in the URL bar to reload. We
- // will create a pending entry, but Blink will convert it to a reload since
- // it's the same page and not create a new entry for it (the user doesn't
- // want to have a new back/forward entry when they do this). Therefore we
- // want to just ignore the pending entry and go back to where we were (the
- // "existing entry").
- // TODO(creis,avi): Eliminate SAME_PAGE in https://crbug.com/536102.
- return NAVIGATION_TYPE_SAME_PAGE;
+ if (pending_entry_index_ == -1) {
+ // In this case, we have a pending entry for a load of a new URL but Blink
+ // didn't do a new navigation (params.did_create_new_entry). First check
+ // to make sure Blink didn't treat a new cross-process navigation as
+ // inert, and thus set params.did_create_new_entry to false. In that case,
+ // we must treat it as NEW since the SiteInstance doesn't match the entry.
+ if (!GetLastCommittedEntry() ||
+ GetLastCommittedEntry()->site_instance() != rfh->GetSiteInstance()) {
+ return NAVIGATION_TYPE_NEW_PAGE;
+ }
+
+ // Otherwise, this happens when you press enter in the URL bar to reload.
+ // We will create a pending entry, but Blink will convert it to a reload
+ // since it's the same page and not create a new entry for it (the user
+ // doesn't want to have a new back/forward entry when they do this).
+ // Therefore we want to just ignore the pending entry and go back to where
+ // we were (the "existing entry").
+ // TODO(creis,avi): Eliminate SAME_PAGE in https://crbug.com/536102.
+ return NAVIGATION_TYPE_SAME_PAGE;
+ }
}
// Everything below here is assumed to be an existing entry, but if there is
@@ -1315,6 +1243,15 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage(
last_committed_entry_index_ = -1;
}
+ // If this is a new navigation with replacement and there is a
+ // pending_entry_ which matches the navigation reported by the renderer
+ // process, then it should be the one replaced, so update the
+ // last_committed_entry_index_ to use it.
+ if (replace_entry && pending_entry_index_ != -1 &&
+ pending_entry_->GetUniqueID() == params.nav_entry_id) {
+ last_committed_entry_index_ = pending_entry_index_;
+ }
+
InsertOrReplaceEntry(std::move(new_entry), replace_entry);
}
@@ -1908,12 +1845,18 @@ bool NavigationControllerImpl::StartHistoryNavigationInNewSubframe(
}
}
- // TODO(clamy): Create a NavigationRequest here and pass it to Navigator for
- // navigating.
- return render_frame_host->frame_tree_node()->navigator()->NavigateToEntry(
- render_frame_host->frame_tree_node(), *frame_entry, *entry,
- ReloadType::NONE, false, true, false, nullptr,
- nullptr /* navigation_ui_data */);
+ std::unique_ptr<NavigationRequest> request = CreateNavigationRequest(
+ render_frame_host->frame_tree_node(), *entry, frame_entry,
+ ReloadType::NONE, false /* is_same_document_history_load */,
+ true /* is_history_navigation_in_new_child */, nullptr, nullptr);
+
+ if (!request)
+ return false;
+
+ render_frame_host->frame_tree_node()->navigator()->Navigate(
+ std::move(request), ReloadType::NONE, RestoreType::NONE);
+
+ return true;
}
void NavigationControllerImpl::NavigateFromFrameProxy(
@@ -1992,11 +1935,16 @@ void NavigationControllerImpl::NavigateFromFrameProxy(
std::vector<GURL>(), PageState(), method, -1, blob_url_loader_factory);
}
- // TODO(clamy): Create a NavigationRequest here and pass it to Navigator for
- // navigating.
- render_frame_host->frame_tree_node()->navigator()->NavigateToEntry(
- node, *frame_entry, *entry.get(), ReloadType::NONE, false, false, false,
- post_body, nullptr /* navigation_ui_data */);
+ std::unique_ptr<NavigationRequest> request = CreateNavigationRequest(
+ render_frame_host->frame_tree_node(), *entry, frame_entry.get(),
+ ReloadType::NONE, false /* is_same_document_history_load */,
+ false /* is_history_navigation_in_new_child */, post_body, nullptr);
+
+ if (!request)
+ return;
+
+ render_frame_host->frame_tree_node()->navigator()->Navigate(
+ std::move(request), ReloadType::NONE, RestoreType::NONE);
}
void NavigationControllerImpl::ClearAllScreenshots() {
@@ -2189,10 +2137,11 @@ void NavigationControllerImpl::PruneOldestEntryIfFull() {
}
}
-void NavigationControllerImpl::NavigateToPendingEntry(
- ReloadType reload_type,
- std::unique_ptr<NavigationUIData> navigation_ui_data) {
+void NavigationControllerImpl::NavigateToExistingPendingEntry(
+ ReloadType reload_type) {
DCHECK(pending_entry_);
+ DCHECK(IsInitialNavigation() || pending_entry_index_ != -1);
+ DCHECK(!IsRendererDebugURL(pending_entry_->GetURL()));
needs_reload_ = false;
// If we were navigating to a slow-to-commit page, and the user performs
@@ -2201,8 +2150,7 @@ void NavigationControllerImpl::NavigateToPendingEntry(
// navigation, and won't send a message to stop the throbber. To prevent this
// from happening, we drop the navigation here and stop the slow-to-commit
// page from loading (which would normally happen during the navigation).
- if (pending_entry_index_ != -1 &&
- pending_entry_index_ == last_committed_entry_index_ &&
+ if (pending_entry_index_ == last_committed_entry_index_ &&
pending_entry_->restore_type() == RestoreType::NONE &&
pending_entry_->GetTransitionType() & ui::PAGE_TRANSITION_FORWARD_BACK) {
delegate_->Stop();
@@ -2224,64 +2172,15 @@ void NavigationControllerImpl::NavigateToPendingEntry(
return;
}
- // If an interstitial page is showing, the previous renderer is blocked and
- // cannot make new requests. Unblock (and disable) it to allow this
- // navigation to succeed. The interstitial will stay visible until the
- // resulting DidNavigate.
- if (delegate_->GetInterstitialPage()) {
- static_cast<InterstitialPageImpl*>(delegate_->GetInterstitialPage())
- ->CancelForNavigation();
- }
-
- // Convert navigations to the current URL to a reload.
- if (ShouldTreatNavigationAsReload(
- pending_entry_->GetURL(), pending_entry_->GetVirtualURL(),
- pending_entry_->GetBaseURLForDataURL(),
- pending_entry_->GetTransitionType(),
- pending_entry_->frame_tree_node_id() == -1 /* is_main_frame */,
- pending_entry_->GetHasPostData() /* is _post */,
- reload_type != ReloadType::NONE /* is_reload */,
- pending_entry_index_ != -1 /* is_navigation_to_existing_entry */,
- transient_entry_index_ != -1 /* has_interstitial */,
- GetLastCommittedEntry())) {
- reload_type = ReloadType::NORMAL;
- }
-
- // Any renderer-side debug URLs or javascript: URLs should be ignored if the
- // renderer process is not live, unless it is the initial navigation of the
- // tab.
- if (IsRendererDebugURL(pending_entry_->GetURL())) {
- // TODO(creis): Find the RVH for the correct frame.
- if (!delegate_->GetRenderViewHost()->IsRenderViewLive() &&
- !IsInitialNavigation()) {
- DiscardNonCommittedEntries();
- return;
- }
- }
-
- // This call does not support re-entrancy. See http://crbug.com/347742.
- CHECK(!in_navigate_to_pending_entry_);
- in_navigate_to_pending_entry_ = true;
- bool success = NavigateToPendingEntryInternal(reload_type,
- std::move(navigation_ui_data));
- in_navigate_to_pending_entry_ = false;
-
- if (!success)
- DiscardNonCommittedEntries();
-}
-
-bool NavigationControllerImpl::NavigateToPendingEntryInternal(
- ReloadType reload_type,
- std::unique_ptr<NavigationUIData> navigation_ui_data) {
- DCHECK(pending_entry_);
FrameTreeNode* root = delegate_->GetFrameTree()->root();
// Compare FrameNavigationEntries to see which frames in the tree need to be
// navigated.
- FrameLoadVector same_document_loads;
- FrameLoadVector different_document_loads;
+ std::vector<std::unique_ptr<NavigationRequest>> same_document_loads;
+ std::vector<std::unique_ptr<NavigationRequest>> different_document_loads;
if (GetLastCommittedEntry()) {
- FindFramesToNavigate(root, &same_document_loads, &different_document_loads);
+ FindFramesToNavigate(root, reload_type, &same_document_loads,
+ &different_document_loads);
}
if (same_document_loads.empty() && different_document_loads.empty()) {
@@ -2292,35 +2191,55 @@ bool NavigationControllerImpl::NavigateToPendingEntryInternal(
// thing to do. In the second case, we should have been able to find a
// frame to navigate based on names if this were a same document
// navigation, so we can safely assume this is the different document case.
- different_document_loads.push_back(
- std::make_pair(root, pending_entry_->GetFrameEntry(root)));
+ std::unique_ptr<NavigationRequest> navigation_request =
+ CreateNavigationRequest(
+ root, *pending_entry_, pending_entry_->GetFrameEntry(root),
+ reload_type, false /* is_same_document_history_load */,
+ false /* is_history_navigation_in_new_child */, nullptr, nullptr);
+ if (!navigation_request) {
+ // This navigation cannot start (e.g. the URL is invalid), delete the
+ // pending NavigationEntry.
+ DiscardPendingEntry(false);
+ return;
+ }
+ different_document_loads.push_back(std::move(navigation_request));
+ }
+
+ // If an interstitial page is showing, the previous renderer is blocked and
+ // cannot make new requests. Unblock (and disable) it to allow this
+ // navigation to succeed. The interstitial will stay visible until the
+ // resulting DidNavigate.
+ // TODO(clamy): See if this can be removed now that PlzNavigate has shipped.
+ // See https://crbug.com/849250
+ if (delegate_->GetInterstitialPage()) {
+ static_cast<InterstitialPageImpl*>(delegate_->GetInterstitialPage())
+ ->CancelForNavigation();
}
- // If all the frame loads fail, we will discard the pending entry.
- bool success = false;
+ // This call does not support re-entrancy. See http://crbug.com/347742.
+ CHECK(!in_navigate_to_pending_entry_);
+ in_navigate_to_pending_entry_ = true;
// Send all the same document frame loads before the different document loads.
- for (const auto& item : same_document_loads) {
- FrameTreeNode* frame = item.first;
- success |= frame->navigator()->NavigateToPendingEntry(
- frame, *item.second, reload_type, true,
- nullptr /* navigation_ui_data */);
+ for (auto& item : same_document_loads) {
+ FrameTreeNode* frame = item->frame_tree_node();
+ frame->navigator()->Navigate(std::move(item), reload_type,
+ pending_entry_->restore_type());
}
- for (const auto& item : different_document_loads) {
- FrameTreeNode* frame = item.first;
- success |= frame->navigator()->NavigateToPendingEntry(
- frame, *item.second, reload_type, false,
- // The NavigationUIData has only been initialized for main frames. Do
- // not pass it to subframes.
- frame->IsMainFrame() ? std::move(navigation_ui_data) : nullptr);
+ for (auto& item : different_document_loads) {
+ FrameTreeNode* frame = item->frame_tree_node();
+ frame->navigator()->Navigate(std::move(item), reload_type,
+ pending_entry_->restore_type());
}
- return success;
+
+ in_navigate_to_pending_entry_ = false;
}
void NavigationControllerImpl::FindFramesToNavigate(
FrameTreeNode* frame,
- FrameLoadVector* same_document_loads,
- FrameLoadVector* different_document_loads) {
+ ReloadType reload_type,
+ std::vector<std::unique_ptr<NavigationRequest>>* same_document_loads,
+ std::vector<std::unique_ptr<NavigationRequest>>* different_document_loads) {
DCHECK(pending_entry_);
DCHECK_GE(last_committed_entry_index_, 0);
FrameNavigationEntry* new_item = pending_entry_->GetFrameEntry(frame);
@@ -2348,7 +2267,16 @@ void NavigationControllerImpl::FindFramesToNavigate(
new_item->document_sequence_number() ==
old_item->document_sequence_number() &&
!frame->current_frame_host()->GetLastCommittedURL().is_empty()) {
- same_document_loads->push_back(std::make_pair(frame, new_item));
+ std::unique_ptr<NavigationRequest> navigation_request =
+ CreateNavigationRequest(
+ frame, *pending_entry_, new_item, reload_type,
+ true /* is_same_document_history_load */,
+ false /* is_history_navigation_in_new_child */, nullptr, nullptr);
+ if (navigation_request) {
+ // Only add the request if was properly created. It's possible for the
+ // creation to fail in certain cases, e.g. when the URL is invalid.
+ same_document_loads->push_back(std::move(navigation_request));
+ }
// TODO(avi, creis): This is a bug; we should not return here. Rather, we
// should continue on and navigate all child frames which have also
@@ -2365,7 +2293,16 @@ void NavigationControllerImpl::FindFramesToNavigate(
// different way that will one day allow us to fix this.
return;
} else {
- different_document_loads->push_back(std::make_pair(frame, new_item));
+ std::unique_ptr<NavigationRequest> navigation_request =
+ CreateNavigationRequest(
+ frame, *pending_entry_, new_item, reload_type,
+ false /* is_same_document_history_load */,
+ false /* is_history_navigation_in_new_child */, nullptr, nullptr);
+ if (navigation_request) {
+ // Only add the request if was properly created. It's possible for the
+ // creation to fail in certain cases, e.g. when the URL is invalid.
+ different_document_loads->push_back(std::move(navigation_request));
+ }
// For a different document, the subframes will be destroyed, so there's
// no need to consider them.
return;
@@ -2373,11 +2310,315 @@ void NavigationControllerImpl::FindFramesToNavigate(
}
for (size_t i = 0; i < frame->child_count(); i++) {
- FindFramesToNavigate(frame->child_at(i), same_document_loads,
+ FindFramesToNavigate(frame->child_at(i), reload_type, same_document_loads,
different_document_loads);
}
}
+void NavigationControllerImpl::NavigateWithoutEntry(
+ const LoadURLParams& params) {
+ // Find the appropriate FrameTreeNode.
+ FrameTreeNode* node = nullptr;
+ if (params.frame_tree_node_id != RenderFrameHost::kNoFrameTreeNodeId ||
+ !params.frame_name.empty()) {
+ node = params.frame_tree_node_id != RenderFrameHost::kNoFrameTreeNodeId
+ ? delegate_->GetFrameTree()->FindByID(params.frame_tree_node_id)
+ : delegate_->GetFrameTree()->FindByName(params.frame_name);
+ }
+
+ // If no FrameTreeNode was specified, navigate the main frame.
+ if (!node)
+ node = delegate_->GetFrameTree()->root();
+
+ // Javascript URLs should not create NavigationEntries. All other navigations
+ // do, including navigations to chrome renderer debug URLs.
+ std::unique_ptr<NavigationEntryImpl> entry;
+ if (!params.url.SchemeIs(url::kJavaScriptScheme)) {
+ entry = CreateNavigationEntryFromLoadParams(node, params);
+ DiscardPendingEntry(false);
+ SetPendingEntry(std::move(entry));
+ }
+
+ // Renderer-debug URLs are sent to the renderer process immediately for
+ // processing and don't need to create a NavigationRequest.
+ // Note: this includes navigations to JavaScript URLs, which are considered
+ // renderer-debug URLs.
+ // Note: we intentionally leave the pending entry in place for renderer debug
+ // URLs, unlike the cases below where we clear it if the navigation doesn't
+ // proceed.
+ if (IsRendererDebugURL(params.url)) {
+ HandleRendererDebugURL(node, params.url);
+ return;
+ }
+
+ // Convert navigations to the current URL to a reload.
+ // TODO(clamy): We should be using FrameTreeNode::IsMainFrame here instead of
+ // relying on the frame tree node id from LoadURLParams. Unfortunately,
+ // DevTools sometimes issues navigations to main frames that they do not
+ // expect to see treated as reload, and it only works because they pass a
+ // FrameTreeNode id in their LoadURLParams. Change this once they no longer do
+ // that. See https://crbug.com/850926.
+ ReloadType reload_type = ReloadType::NONE;
+ if (ShouldTreatNavigationAsReload(
+ params.url, pending_entry_->GetVirtualURL(),
+ params.base_url_for_data_url, params.transition_type,
+ params.frame_tree_node_id == RenderFrameHost::kNoFrameTreeNodeId,
+ params.load_type ==
+ NavigationController::LOAD_TYPE_HTTP_POST /* is_post */,
+ false /* is_reload */, false /* is_navigation_to_existing_entry */,
+ transient_entry_index_ != -1 /* has_interstitial */,
+ GetLastCommittedEntry())) {
+ reload_type = ReloadType::NORMAL;
+ }
+
+ // navigation_ui_data should only be present for main frame navigations.
+ DCHECK(node->IsMainFrame() || !params.navigation_ui_data);
+
+ // TODO(clamy): Create the NavigationRequest directly from the LoadURLParams
+ // instead of relying on the NavigationEntry.
+ DCHECK(pending_entry_);
+ std::unique_ptr<NavigationRequest> request = CreateNavigationRequest(
+ node, *pending_entry_, pending_entry_->GetFrameEntry(node), reload_type,
+ false /* is_same_document_history_load */,
+ false /* is_history_navigation_in_new_child */, nullptr,
+ params.navigation_ui_data ? params.navigation_ui_data->Clone() : nullptr);
+
+ // If the navigation couldn't start, return immediately and discard the
+ // pending NavigationEntry.
+ if (!request) {
+ DiscardPendingEntry(false);
+ return;
+ }
+
+ // If an interstitial page is showing, the previous renderer is blocked and
+ // cannot make new requests. Unblock (and disable) it to allow this
+ // navigation to succeed. The interstitial will stay visible until the
+ // resulting DidNavigate.
+ if (delegate_->GetInterstitialPage()) {
+ static_cast<InterstitialPageImpl*>(delegate_->GetInterstitialPage())
+ ->CancelForNavigation();
+ }
+
+ // This call does not support re-entrancy. See http://crbug.com/347742.
+ CHECK(!in_navigate_to_pending_entry_);
+ in_navigate_to_pending_entry_ = true;
+
+ node->navigator()->Navigate(std::move(request), reload_type,
+ RestoreType::NONE);
+
+ in_navigate_to_pending_entry_ = false;
+}
+
+void NavigationControllerImpl::HandleRendererDebugURL(
+ FrameTreeNode* frame_tree_node,
+ const GURL& url) {
+ if (!frame_tree_node->current_frame_host()->IsRenderFrameLive()) {
+ // Any renderer-side debug URLs or javascript: URLs should be ignored if
+ // the renderer process is not live, unless it is the initial navigation
+ // of the tab.
+ if (!IsInitialNavigation()) {
+ DiscardNonCommittedEntries();
+ return;
+ }
+ frame_tree_node->render_manager()->InitializeRenderFrameIfNecessary(
+ frame_tree_node->current_frame_host());
+ }
+ frame_tree_node->current_frame_host()->HandleRendererDebugURL(url);
+}
+
+std::unique_ptr<NavigationEntryImpl>
+NavigationControllerImpl::CreateNavigationEntryFromLoadParams(
+ FrameTreeNode* node,
+ const LoadURLParams& params) {
+ // Browser initiated navigations might not have a blob_url_loader_factory set
+ // in params even if the navigation is to a blob URL. If that happens, lookup
+ // the correct url loader factory to use here.
+ auto blob_url_loader_factory = params.blob_url_loader_factory;
+ if (!blob_url_loader_factory && blink::BlobUtils::MojoBlobURLsEnabled() &&
+ params.url.SchemeIsBlob()) {
+ blob_url_loader_factory = ChromeBlobStorageContext::URLLoaderFactoryForUrl(
+ GetBrowserContext(), params.url);
+ }
+
+ std::unique_ptr<NavigationEntryImpl> entry;
+
+ // For subframes, create a pending entry with a corresponding frame entry.
+ if (!node->IsMainFrame()) {
+ DCHECK(GetLastCommittedEntry());
+
+ // Create an identical NavigationEntry with a new FrameNavigationEntry for
+ // the target subframe.
+ entry = GetLastCommittedEntry()->Clone();
+ entry->AddOrUpdateFrameEntry(
+ node, -1, -1, nullptr,
+ static_cast<SiteInstanceImpl*>(params.source_site_instance.get()),
+ params.url, params.referrer, params.redirect_chain, PageState(), "GET",
+ -1, blob_url_loader_factory);
+ } else {
+ // Otherwise, create a pending entry for the main frame.
+
+ // extra_headers in params are \n separated; navigation entries want \r\n.
+ std::string extra_headers_crlf;
+ base::ReplaceChars(params.extra_headers, "\n", "\r\n", &extra_headers_crlf);
+ entry = NavigationEntryImpl::FromNavigationEntry(CreateNavigationEntry(
+ params.url, params.referrer, params.transition_type,
+ params.is_renderer_initiated, extra_headers_crlf, browser_context_,
+ blob_url_loader_factory));
+ entry->set_source_site_instance(
+ static_cast<SiteInstanceImpl*>(params.source_site_instance.get()));
+ entry->SetRedirectChain(params.redirect_chain);
+ }
+
+ // Set the FTN ID (only used in non-site-per-process, for tests).
+ entry->set_frame_tree_node_id(node->frame_tree_node_id());
+ // Don't allow an entry replacement if there is no entry to replace.
+ // http://crbug.com/457149
+ if (params.should_replace_current_entry && entries_.size() > 0)
+ entry->set_should_replace_entry(true);
+ entry->set_should_clear_history_list(params.should_clear_history_list);
+
+ bool override = false;
+ switch (params.override_user_agent) {
+ case UA_OVERRIDE_INHERIT:
+ override = ShouldKeepOverride(GetLastCommittedEntry());
+ break;
+ case UA_OVERRIDE_TRUE:
+ override = true;
+ break;
+ case UA_OVERRIDE_FALSE:
+ override = false;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ entry->SetIsOverridingUserAgent(override);
+
+// Always propagate `has_user_gesture` on Android but only when the request
+// was originated by the renderer on other platforms. This is merely for
+// backward compatibility as browser process user gestures create confusion in
+// many tests.
+#if defined(OS_ANDROID)
+ entry->set_has_user_gesture(params.has_user_gesture);
+#else
+ if (params.is_renderer_initiated)
+ entry->set_has_user_gesture(params.has_user_gesture);
+#endif
+
+ switch (params.load_type) {
+ case LOAD_TYPE_DEFAULT:
+ break;
+ case LOAD_TYPE_HTTP_POST:
+ entry->SetHasPostData(true);
+ entry->SetPostData(params.post_data);
+ break;
+ case LOAD_TYPE_DATA:
+ entry->SetBaseURLForDataURL(params.base_url_for_data_url);
+ entry->SetVirtualURL(params.virtual_url_for_data_url);
+#if defined(OS_ANDROID)
+ entry->SetDataURLAsString(params.data_url_as_string);
+#endif
+ entry->SetCanLoadLocalResources(params.can_load_local_resources);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ // TODO(clamy): NavigationEntry is meant for information that will be kept
+ // after the navigation ended and therefore is not appropriate for
+ // started_from_context_menu. Move started_from_context_menu to
+ // NavigationUIData.
+ entry->set_started_from_context_menu(params.started_from_context_menu);
+
+ return entry;
+}
+
+std::unique_ptr<NavigationRequest>
+NavigationControllerImpl::CreateNavigationRequest(
+ FrameTreeNode* frame_tree_node,
+ const NavigationEntryImpl& entry,
+ FrameNavigationEntry* frame_entry,
+ ReloadType reload_type,
+ bool is_same_document_history_load,
+ bool is_history_navigation_in_new_child,
+ const scoped_refptr<network::ResourceRequestBody>& post_body,
+ std::unique_ptr<NavigationUIData> navigation_ui_data) {
+ GURL dest_url = frame_entry->url();
+ Referrer dest_referrer = frame_entry->referrer();
+ if (reload_type == ReloadType::ORIGINAL_REQUEST_URL &&
+ entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) {
+ // We may have been redirected when navigating to the current URL.
+ // Use the URL the user originally intended to visit as signaled by the
+ // ReloadType, if it's valid and if a POST wasn't involved; the latter
+ // case avoids issues with sending data to the wrong page.
+ dest_url = entry.GetOriginalRequestURL();
+ dest_referrer = Referrer();
+ }
+
+ // Don't attempt to navigate if the virtual URL is non-empty and invalid.
+ if (frame_tree_node->IsMainFrame()) {
+ const GURL& virtual_url = entry.GetVirtualURL();
+ if (!virtual_url.is_valid() && !virtual_url.is_empty()) {
+ LOG(WARNING) << "Refusing to load for invalid virtual URL: "
+ << virtual_url.possibly_invalid_spec();
+ return nullptr;
+ }
+ }
+
+ // Don't attempt to navigate to non-empty invalid URLs.
+ if (!dest_url.is_valid() && !dest_url.is_empty()) {
+ LOG(WARNING) << "Refusing to load invalid URL: "
+ << dest_url.possibly_invalid_spec();
+ return nullptr;
+ }
+
+ // The renderer will reject IPC messages with URLs longer than
+ // this limit, so don't attempt to navigate with a longer URL.
+ if (dest_url.spec().size() > url::kMaxURLChars) {
+ LOG(WARNING) << "Refusing to load URL as it exceeds " << url::kMaxURLChars
+ << " characters.";
+ return nullptr;
+ }
+
+ // Determine if Previews should be used for the navigation.
+ PreviewsState previews_state = PREVIEWS_UNSPECIFIED;
+ if (!frame_tree_node->IsMainFrame()) {
+ // For subframes, use the state of the top-level frame.
+ previews_state = frame_tree_node->frame_tree()
+ ->root()
+ ->current_frame_host()
+ ->last_navigation_previews_state();
+ }
+
+ // Give the delegate an opportunity to adjust the previews state.
+ if (delegate_)
+ delegate_->AdjustPreviewsStateForNavigation(&previews_state);
+
+ // This will be used to set the Navigation Timing API navigationStart
+ // parameter for browser navigations in new tabs (intents, tabs opened through
+ // "Open link in new tab"). If the navigation must wait on the current
+ // RenderFrameHost to execute its BeforeUnload event, the navigation start
+ // will be updated when the BeforeUnload ack is received.
+ base::TimeTicks navigation_start = base::TimeTicks::Now();
+ TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(
+ "navigation,rail", "NavigationTiming navigationStart",
+ TRACE_EVENT_SCOPE_GLOBAL, navigation_start);
+
+ FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType(
+ frame_tree_node->current_url(), // old_url
+ dest_url, // new_url
+ reload_type, // reload_type
+ entry, // entry
+ *frame_entry, // frame_entry
+ is_same_document_history_load); // is_same_document_history_load
+ return NavigationRequest::CreateBrowserInitiated(
+ frame_tree_node, dest_url, dest_referrer, *frame_entry, entry,
+ navigation_type, previews_state, is_same_document_history_load,
+ is_history_navigation_in_new_child, post_body, navigation_start, this,
+ std::move(navigation_ui_data));
+}
+
void NavigationControllerImpl::NotifyNavigationEntryCommitted(
LoadCommittedDetails* details) {
details->entry = GetLastCommittedEntry();
@@ -2419,11 +2660,11 @@ void NavigationControllerImpl::LoadIfNecessary() {
// Explicitly use NavigateToPendingEntry so that the renderer uses the
// cached state.
if (pending_entry_) {
- NavigateToPendingEntry(ReloadType::NONE, nullptr /* navigation_ui_data */);
+ NavigateToExistingPendingEntry(ReloadType::NONE);
} else if (last_committed_entry_index_ != -1) {
pending_entry_ = entries_[last_committed_entry_index_].get();
pending_entry_index_ = last_committed_entry_index_;
- NavigateToPendingEntry(ReloadType::NONE, nullptr /* navigation_ui_data */);
+ NavigateToExistingPendingEntry(ReloadType::NONE);
} else {
// If there is something to reload, the successful reload will clear the
// |needs_reload_| flag. Otherwise, just do it here.
diff --git a/chromium/content/browser/frame_host/navigation_controller_impl.h b/chromium/content/browser/frame_host/navigation_controller_impl.h
index 3f1f1ceff6d..8b3502ccbc1 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl.h
+++ b/chromium/content/browser/frame_host/navigation_controller_impl.h
@@ -241,10 +241,6 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController {
FRIEND_TEST_ALL_PREFIXES(TimeSmoother, ManyDuplicates);
FRIEND_TEST_ALL_PREFIXES(TimeSmoother, ClockBackwardsJump);
- // Used for identifying which frames need to navigate.
- using FrameLoadVector =
- std::vector<std::pair<FrameTreeNode*, FrameNavigationEntry*>>;
-
// Helper class to smooth out runs of duplicate timestamps while still
// allowing time to jump backwards.
class CONTENT_EXPORT TimeSmoother {
@@ -259,26 +255,46 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController {
base::Time high_water_mark_;
};
- // Causes the controller to load the specified entry. The function assumes
- // ownership of the pointer since it is put in the navigation list.
- // NOTE: Do not pass an entry that the controller already owns!
- void LoadEntry(std::unique_ptr<NavigationEntryImpl> entry,
- std::unique_ptr<NavigationUIData> navigation_ui_data);
+ // Starts a navigation to an already existing pending NavigationEntry.
+ void NavigateToExistingPendingEntry(ReloadType reload_type);
- // Identifies which frames need to be navigated for the pending
- // NavigationEntry and instructs their Navigator to navigate them. Returns
- // whether any frame successfully started a navigation.
- bool NavigateToPendingEntryInternal(
+ // Recursively identifies which frames need to be navigated for a navigation
+ // to |pending_entry_|, starting at |frame| and exploring its children.
+ // |same_document_loads| and |different_document_loads| will be filled with
+ // the NavigationRequests needed to navigate to |pending_entry_|.
+ void FindFramesToNavigate(
+ FrameTreeNode* frame,
+ ReloadType reload_type,
+ std::vector<std::unique_ptr<NavigationRequest>>* same_document_loads,
+ std::vector<std::unique_ptr<NavigationRequest>>*
+ different_document_loads);
+
+ // Starts a new navigation based on |load_params|, that doesn't correspond to
+ // an exisiting NavigationEntry.
+ void NavigateWithoutEntry(const LoadURLParams& load_params);
+
+ // Handles a navigation to a renderer-debug URL.
+ void HandleRendererDebugURL(FrameTreeNode* frame_tree_node, const GURL& url);
+
+ // Creates and returns a NavigationEntry based on |load_params| for a
+ // navigation in |node|.
+ std::unique_ptr<NavigationEntryImpl> CreateNavigationEntryFromLoadParams(
+ FrameTreeNode* node,
+ const LoadURLParams& load_params);
+
+ // Creates and returns a NavigationRequest based on the provided parameters.
+ // Will return nullptr if the parameters are invalid and the navigation cannot
+ // start.
+ std::unique_ptr<NavigationRequest> CreateNavigationRequest(
+ FrameTreeNode* frame_tree_node,
+ const NavigationEntryImpl& entry,
+ FrameNavigationEntry* frame_entry,
ReloadType reload_type,
+ bool is_same_document_history_load,
+ bool is_history_navigation_in_new_child,
+ const scoped_refptr<network::ResourceRequestBody>& post_body,
std::unique_ptr<NavigationUIData> navigation_ui_data);
- // Recursively identifies which frames need to be navigated for the pending
- // NavigationEntry, starting at |frame| and exploring its children. Only used
- // in --site-per-process.
- void FindFramesToNavigate(FrameTreeNode* frame,
- FrameLoadVector* sameDocumentLoads,
- FrameLoadVector* differentDocumentLoads);
-
// Returns whether there is a pending NavigationEntry whose unique ID matches
// the given NavigationHandle's pending_nav_entry_id.
bool PendingEntryMatchesHandle(NavigationHandleImpl* handle) const;
@@ -327,11 +343,6 @@ class CONTENT_EXPORT NavigationControllerImpl : public NavigationController {
RenderFrameHostImpl* rfh,
const FrameHostMsg_DidCommitProvisionalLoad_Params& params);
- // Actually issues the navigation held in pending_entry.
- void NavigateToPendingEntry(
- ReloadType reload_type,
- std::unique_ptr<NavigationUIData> navigation_ui_data);
-
// Allows the derived class to issue notifications that a load has been
// committed. This will fill in the active entry to the details structure.
void NotifyNavigationEntryCommitted(LoadCommittedDetails* details);
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 bfe29504506..b1ed11f1561 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -18,7 +18,7 @@
#include "base/sequenced_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
@@ -4991,9 +4991,10 @@ void DoReplaceStateWhilePending(Shell* shell,
} // namespace
+// Flaky on Linux TSan: https://crbug.com/847326
IN_PROC_BROWSER_TEST_F(
NavigationControllerBrowserTest,
- NavigationTypeClassification_On1SameDocumentToXWhile2Pending) {
+ DISABLED_NavigationTypeClassification_On1SameDocumentToXWhile2Pending) {
GURL url1(embedded_test_server()->GetURL(
"/navigation_controller/simple_page_1.html"));
GURL url2(embedded_test_server()->GetURL(
@@ -5019,9 +5020,10 @@ IN_PROC_BROWSER_TEST_F(
DoReplaceStateWhilePending(shell(), url, url, "x");
}
+// Flaky on Linux TSan: https://crbug.com/847326
IN_PROC_BROWSER_TEST_F(
NavigationControllerBrowserTest,
- NavigationTypeClassification_On1SameDocumentTo1While1Pending) {
+ DISABLED_NavigationTypeClassification_On1SameDocumentTo1While1Pending) {
GURL url(embedded_test_server()->GetURL(
"/navigation_controller/simple_page_1.html"));
DoReplaceStateWhilePending(shell(), url, url, "simple_page_1.html");
@@ -6670,7 +6672,7 @@ class HistoryNavigationBeforeCommitInjector
private:
// DidCommitProvisionalLoadInterceptor:
- void WillDispatchDidCommitProvisionalLoad(
+ bool WillDispatchDidCommitProvisionalLoad(
RenderFrameHost* render_frame_host,
::FrameHostMsg_DidCommitProvisionalLoad_Params* params,
service_manager::mojom::InterfaceProviderRequest*
@@ -6679,6 +6681,7 @@ class HistoryNavigationBeforeCommitInjector
did_trigger_history_navigation_ = true;
web_contents()->GetController().GoBack();
}
+ return true;
}
bool did_trigger_history_navigation_;
@@ -7934,111 +7937,6 @@ class NavigationControllerControllableResponseBrowserTest
}
};
-IN_PROC_BROWSER_TEST_F(NavigationControllerControllableResponseBrowserTest,
- ReloadDisablePreviewReloadsOriginalRequestURL) {
- const std::string kOriginalPath = "/original.html";
- const std::string kRedirectPath = "/redirect.html";
- net::test_server::ControllableHttpResponse original_response1(
- embedded_test_server(), kOriginalPath);
- net::test_server::ControllableHttpResponse original_response2(
- embedded_test_server(), kOriginalPath);
- net::test_server::ControllableHttpResponse redirect_response1(
- embedded_test_server(), kRedirectPath);
- net::test_server::ControllableHttpResponse redirect_response2(
- embedded_test_server(), kRedirectPath);
-
- EXPECT_TRUE(embedded_test_server()->Start());
-
- const GURL kOriginalURL =
- embedded_test_server()->GetURL("a.com", kOriginalPath);
- const GURL kRedirectURL =
- embedded_test_server()->GetURL("b.com", kRedirectPath);
- const GURL kReloadRedirectURL =
- embedded_test_server()->GetURL("c.com", kRedirectPath);
-
- // First navigate to the initial URL. This page will have a cross-site
- // redirect to a 2nd domain.
- shell()->LoadURL(kOriginalURL);
- original_response1.WaitForRequest();
- original_response1.Send(
- "HTTP/1.1 302 FOUND\r\n"
- "Location: " +
- kRedirectURL.spec() +
- "\r\n"
- "\r\n");
- original_response1.Done();
- redirect_response1.WaitForRequest();
- redirect_response1.Send(
- "HTTP/1.1 200 OK\r\n"
- "Content-Type: text/html; charset=utf-8\r\n"
- "\r\n");
- redirect_response1.Send(
- "<html>"
- "<body></body>"
- "</html>");
- redirect_response1.Done();
- EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
- EXPECT_EQ(kRedirectURL, shell()->web_contents()->GetVisibleURL());
-
- if (content::AreAllSitesIsolatedForTesting()) {
- RenderFrameHostImpl* rfh =
- static_cast<WebContentsImpl*>(shell()->web_contents())->GetMainFrame();
- EXPECT_EQ(GURL("http://b.com"), rfh->GetSiteInstance()->GetSiteURL());
- }
-
- // Now simulate a 'Show original' reload via ReloadType::DISABLE_PREVIEWS.
- // This reload will have a cross-site redirect to a 3rd domain.
- TestNavigationManager reload(shell()->web_contents(), kOriginalURL);
- shell()->web_contents()->GetController().Reload(ReloadType::DISABLE_PREVIEWS,
- false);
- EXPECT_TRUE(reload.WaitForRequestStart());
-
- // Verify reload is using the original request URL and no previews allowed.
- EXPECT_EQ(kOriginalURL, reload.GetNavigationHandle()->GetURL());
- NavigationRequest* navigation_request =
- static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()
- ->root()
- ->navigation_request();
- CHECK(navigation_request);
- EXPECT_EQ(content::PREVIEWS_NO_TRANSFORM,
- navigation_request->common_params().previews_state);
-
- reload.ResumeNavigation();
- original_response2.WaitForRequest();
- original_response2.Send(
- "HTTP/1.1 302 FOUND\r\n"
- "Location: " +
- kReloadRedirectURL.spec() +
- "\r\n"
- "\r\n");
- original_response2.Done();
- redirect_response2.WaitForRequest();
-
- // Verify now using new redirect URL.
- EXPECT_EQ(kReloadRedirectURL, reload.GetNavigationHandle()->GetURL());
-
- redirect_response2.Send(
- "HTTP/1.1 200 OK\r\n"
- "Content-Type: text/html; charset=utf-8\r\n"
- "\r\n");
- redirect_response2.Send(
- "<html>"
- "<body></body>"
- "</html>");
- redirect_response2.Done();
- EXPECT_TRUE(reload.WaitForResponse());
- reload.WaitForNavigationFinished();
- EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
- EXPECT_EQ(kReloadRedirectURL, shell()->web_contents()->GetVisibleURL());
-
- if (content::AreAllSitesIsolatedForTesting()) {
- RenderFrameHostImpl* rfh =
- static_cast<WebContentsImpl*>(shell()->web_contents())->GetMainFrame();
- EXPECT_EQ(GURL("http://c.com"), rfh->GetSiteInstance()->GetSiteURL());
- }
-}
-
// 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
@@ -8137,4 +8035,75 @@ IN_PROC_BROWSER_TEST_F(ContentBrowserTest, DataURLSameDocumentNavigation) {
EXPECT_TRUE(capturer.is_same_document());
}
+// Verify that a session history navigation which results in a different
+// SiteInstance from the original commit is correctly handled - classified
+// as new navigation with replacement, resulting in no new navigation
+// entries.
+IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest,
+ SiteInstanceChangeOnHistoryNavigation) {
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+ GURL url1(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ GURL url2(embedded_test_server()->GetURL("b.com", "/title2.html"));
+ GURL url3(embedded_test_server()->GetURL("c.com", "/title3.html"));
+ GURL redirecting_url(embedded_test_server()->GetURL(
+ "a.com", "/server-redirect?" + url3.spec()));
+
+ // Start with an initial URL.
+ EXPECT_TRUE(NavigateToURL(shell(), url1));
+ EXPECT_EQ(1, controller.GetEntryCount());
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());
+ scoped_refptr<SiteInstance> initial_site_instance =
+ root->current_frame_host()->GetSiteInstance();
+
+ {
+ // history.replaceState(), pointing to a URL that would redirect to |url3|.
+ FrameNavigateParamsCapturer capturer(root);
+ std::string script =
+ "history.replaceState({}, '', '" + redirecting_url.spec() + "')";
+ EXPECT_TRUE(ExecuteScript(root, script));
+ capturer.Wait();
+ }
+ EXPECT_EQ(1, controller.GetEntryCount());
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(redirecting_url, controller.GetEntryAtIndex(0)->GetURL());
+ EXPECT_EQ(initial_site_instance,
+ root->current_frame_host()->GetSiteInstance());
+
+ // Navigate to a new URL to get new session history entry.
+ EXPECT_TRUE(NavigateToURL(shell(), url2));
+ EXPECT_EQ(2, controller.GetEntryCount());
+ EXPECT_EQ(1, controller.GetLastCommittedEntryIndex());
+ EXPECT_NE(initial_site_instance,
+ root->current_frame_host()->GetSiteInstance());
+
+ // Back, which should redirect to |url3|.
+ FrameNavigateParamsCapturer capturer(root);
+ shell()->web_contents()->GetController().GoBack();
+ capturer.Wait();
+ EXPECT_EQ(2, controller.GetEntryCount());
+ EXPECT_EQ(0, controller.GetLastCommittedEntryIndex());
+
+ NavigationEntry* entry = controller.GetEntryAtIndex(0);
+ EXPECT_EQ(entry, controller.GetLastCommittedEntry());
+ EXPECT_EQ(url3, entry->GetURL());
+ if (AreAllSitesIsolatedForTesting()) {
+ EXPECT_NE(initial_site_instance,
+ root->current_frame_host()->GetSiteInstance());
+ EXPECT_EQ(SiteInstance::GetSiteForURL(
+ shell()->web_contents()->GetBrowserContext(), url3),
+ root->current_frame_host()->GetSiteInstance()->GetSiteURL());
+ EXPECT_EQ(NAVIGATION_TYPE_NEW_PAGE, capturer.navigation_type());
+ } else {
+ EXPECT_EQ(initial_site_instance,
+ root->current_frame_host()->GetSiteInstance());
+ EXPECT_EQ(NAVIGATION_TYPE_EXISTING_PAGE, capturer.navigation_type());
+ }
+}
+
} // 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 56e15a9b56f..ebff6f11cc9 100644
--- a/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -38,6 +38,7 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
+#include "content/public/common/bindings_policy.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/page_state.h"
#include "content/public/common/page_type.h"
@@ -673,7 +674,6 @@ TEST_F(NavigationControllerTest, LoadURLWithParams) {
load_params.load_type = NavigationController::LOAD_TYPE_DEFAULT;
load_params.is_renderer_initiated = true;
load_params.override_user_agent = NavigationController::UA_OVERRIDE_TRUE;
- load_params.transferred_global_request_id = GlobalRequestID(2, 3);
controller.LoadURLWithParams(load_params);
NavigationEntryImpl* entry = controller.GetPendingEntry();
@@ -1011,7 +1011,7 @@ TEST_F(NavigationControllerTest, LoadURL_PrivilegedPending) {
kExistingURL1, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
int entry_id = controller.GetPendingEntry()->GetUniqueID();
// Pretend it has bindings so we can tell if we incorrectly copy it.
- main_test_rfh()->AllowBindings(2);
+ main_test_rfh()->AllowBindings(BINDINGS_POLICY_MOJO_WEB_UI);
main_test_rfh()->PrepareForCommit();
main_test_rfh()->SendNavigate(entry_id, true, kExistingURL1);
EXPECT_EQ(1U, navigation_entry_committed_counter_);
@@ -1306,7 +1306,7 @@ TEST_F(NavigationControllerTest, LoadURL_WithBindings) {
int entry_id = controller.GetPendingEntry()->GetUniqueID();
orig_rfh->PrepareForCommit();
TestRenderFrameHost* new_rfh = contents()->GetPendingMainFrame();
- new_rfh->AllowBindings(1);
+ new_rfh->AllowBindings(BINDINGS_POLICY_WEB_UI);
new_rfh->SendNavigate(entry_id, true, url2);
// The second load should be committed, and bindings should be remembered.
@@ -1508,49 +1508,6 @@ TEST_F(NavigationControllerTest, ReloadOriginalRequestURL) {
EXPECT_FALSE(controller.CanGoForward());
}
-TEST_F(NavigationControllerTest,
- ReloadDisablePreviewReloadsOriginalRequestURL) {
- NavigationControllerImpl& controller = controller_impl();
-
- const GURL original_url("http://foo1");
- const GURL final_url("http://foo2");
- auto set_original_url_callback = base::Bind(SetOriginalURL, original_url);
-
- // Load up the original URL, but get redirected.
- controller.LoadURL(original_url, Referrer(), ui::PAGE_TRANSITION_TYPED,
- std::string());
- int entry_id = controller.GetPendingEntry()->GetUniqueID();
- EXPECT_EQ(0U, navigation_entry_changed_counter_);
- EXPECT_EQ(0U, navigation_list_pruned_counter_);
- main_test_rfh()->PrepareForCommitWithServerRedirect(final_url);
- main_test_rfh()->SendNavigateWithModificationCallback(
- entry_id, true, final_url, std::move(set_original_url_callback));
- EXPECT_EQ(1U, navigation_entry_committed_counter_);
- navigation_entry_committed_counter_ = 0;
- entry_id = controller.GetLastCommittedEntry()->GetUniqueID();
-
- // The NavigationEntry should save both the original URL and the final
- // redirected URL.
- EXPECT_EQ(original_url,
- controller.GetVisibleEntry()->GetOriginalRequestURL());
- EXPECT_EQ(final_url, controller.GetVisibleEntry()->GetURL());
-
- // Reload with previews disabled.
- controller.Reload(ReloadType::DISABLE_PREVIEWS, false);
- EXPECT_EQ(0U, navigation_entry_changed_counter_);
- EXPECT_EQ(0U, navigation_list_pruned_counter_);
-
- // The reload is pending. The request should point to the original URL.
- EXPECT_EQ(original_url, navigated_url());
- EXPECT_EQ(controller.GetEntryCount(), 1);
- EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0);
- EXPECT_EQ(controller.GetPendingEntryIndex(), 0);
- EXPECT_TRUE(controller.GetLastCommittedEntry());
- EXPECT_TRUE(controller.GetPendingEntry());
- EXPECT_TRUE(HasNavigationRequest());
- EXPECT_EQ(content::PREVIEWS_NO_TRANSFORM, GetLastNavigationPreviewsState());
-}
-
// Test that certain non-persisted NavigationEntryImpl values get reset after
// commit.
TEST_F(NavigationControllerTest, ResetEntryValuesAfterCommit) {
@@ -1574,19 +1531,16 @@ TEST_F(NavigationControllerTest, ResetEntryValuesAfterCommit) {
// Set up some sample values.
const char* raw_data = "post\n\n\0data";
const int length = 11;
- GlobalRequestID transfer_id(3, 4);
// Set non-persisted values on the pending entry.
NavigationEntryImpl* pending_entry = controller.GetPendingEntry();
pending_entry->SetPostData(
network::ResourceRequestBody::CreateFromBytes(raw_data, length));
pending_entry->set_is_renderer_initiated(true);
- pending_entry->set_transferred_global_request_id(transfer_id);
pending_entry->set_should_replace_entry(true);
pending_entry->set_should_clear_history_list(true);
EXPECT_TRUE(pending_entry->GetPostData());
EXPECT_TRUE(pending_entry->is_renderer_initiated());
- EXPECT_EQ(transfer_id, pending_entry->transferred_global_request_id());
EXPECT_TRUE(pending_entry->should_replace_entry());
EXPECT_TRUE(pending_entry->should_clear_history_list());
@@ -1599,8 +1553,6 @@ TEST_F(NavigationControllerTest, ResetEntryValuesAfterCommit) {
NavigationEntryImpl* committed_entry = controller.GetLastCommittedEntry();
EXPECT_FALSE(committed_entry->GetPostData());
EXPECT_FALSE(committed_entry->is_renderer_initiated());
- EXPECT_EQ(GlobalRequestID(-1, -1),
- committed_entry->transferred_global_request_id());
EXPECT_FALSE(committed_entry->should_replace_entry());
EXPECT_FALSE(committed_entry->should_clear_history_list());
}
@@ -4540,17 +4492,19 @@ TEST_F(NavigationControllerTest, CopyRestoredStateAndNavigate) {
// Go back to the first entry one at a time and
// verify that it works as expected.
EXPECT_EQ(2, controller_impl().GetCurrentEntryIndex());
- EXPECT_EQ(kInitialUrl, controller_impl().GetActiveEntry()->GetURL());
+ EXPECT_EQ(kInitialUrl, controller_impl().GetLastCommittedEntry()->GetURL());
controller_impl().GoBack();
contents()->CommitPendingNavigation();
EXPECT_EQ(1, controller_impl().GetCurrentEntryIndex());
- EXPECT_EQ(kRestoredUrls[1], controller_impl().GetActiveEntry()->GetURL());
+ EXPECT_EQ(kRestoredUrls[1],
+ controller_impl().GetLastCommittedEntry()->GetURL());
controller_impl().GoBack();
contents()->CommitPendingNavigation();
EXPECT_EQ(0, controller_impl().GetCurrentEntryIndex());
- EXPECT_EQ(kRestoredUrls[0], controller_impl().GetActiveEntry()->GetURL());
+ EXPECT_EQ(kRestoredUrls[0],
+ controller_impl().GetLastCommittedEntry()->GetURL());
}
// Tests that navigations initiated from the page (with the history object)
@@ -5333,7 +5287,14 @@ TEST_F(NavigationControllerTest, MainFrameNavigationUIData) {
controller.LoadURLWithParams(params);
int entry_id = controller.GetPendingEntry()->GetUniqueID();
+ NavigationRequest* request =
+ main_test_rfh()->frame_tree_node()->navigation_request();
+ CHECK(request);
+
main_test_rfh()->PrepareForCommit();
+ main_test_rfh()->SimulateCommitProcessed(
+ request->navigation_handle()->GetNavigationId(),
+ true /* was_successful */);
main_test_rfh()->SendNavigate(entry_id, true, url1);
EXPECT_TRUE(observer.is_main_frame());
diff --git a/chromium/content/browser/frame_host/navigation_entry_impl.cc b/chromium/content/browser/frame_host/navigation_entry_impl.cc
index c434d64daa7..aa9c80e2ce7 100644
--- a/chromium/content/browser/frame_host/navigation_entry_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_entry_impl.cc
@@ -12,6 +12,7 @@
#include <utility>
#include "base/containers/queue.h"
+#include "base/files/file_path.h"
#include "base/i18n/rtl.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
@@ -28,6 +29,10 @@
#include "content/public/common/url_constants.h"
#include "ui/gfx/text_elider.h"
+#if defined(OS_ANDROID)
+#include "base/android/content_uri_utils.h"
+#endif
+
using base::UTF16ToUTF8;
namespace content {
@@ -457,6 +462,16 @@ const base::string16& NavigationEntryImpl::GetTitleForDisplay() const {
base::i18n::WrapStringWithLTRFormatting(&title);
}
+#if defined(OS_ANDROID)
+ if (GetURL().SchemeIs(url::kContentScheme)) {
+ base::string16 file_display_name;
+ if (base::MaybeGetFileDisplayName(base::FilePath(GetURL().spec()),
+ &file_display_name)) {
+ title = file_display_name;
+ }
+ }
+#endif
+
gfx::ElideString(title, kMaxTitleChars, &cached_display_title_);
return cached_display_title_;
}
@@ -653,11 +668,9 @@ std::unique_ptr<NavigationEntryImpl> NavigationEntryImpl::CloneAndReplace(
#endif
// ResetForCommit: is_renderer_initiated_
copy->cached_display_title_ = cached_display_title_;
- // ResetForCommit: transferred_global_request_id_
// ResetForCommit: should_replace_entry_
// ResetForCommit: should_clear_history_list_
// ResetForCommit: frame_tree_node_id_
- // ResetForCommit: intent_received_timestamp_
copy->has_user_gesture_ = has_user_gesture_;
// ResetForCommit: reload_type_
copy->extra_data_ = extra_data_;
@@ -674,30 +687,11 @@ CommonNavigationParams NavigationEntryImpl::ConstructCommonNavigationParams(
FrameMsg_Navigate_Type::Value navigation_type,
PreviewsState previews_state,
const base::TimeTicks& navigation_start) const {
- FrameMsg_UILoadMetricsReportType::Value report_type =
- FrameMsg_UILoadMetricsReportType::NO_REPORT;
- base::TimeTicks ui_timestamp = base::TimeTicks();
-
-#if defined(OS_ANDROID)
- if (!intent_received_timestamp().is_null())
- report_type = FrameMsg_UILoadMetricsReportType::REPORT_INTENT;
- ui_timestamp = intent_received_timestamp();
-#endif
-
- std::string method;
-
- // TODO(clamy): Consult the FrameNavigationEntry in all modes that use
- // subframe navigation entries.
- if (IsBrowserSideNavigationEnabled())
- method = frame_entry.method();
- else
- method = (post_body.get() || GetHasPostData()) ? "POST" : "GET";
-
return CommonNavigationParams(
dest_url, dest_referrer, GetTransitionType(), navigation_type,
- !IsViewSourceMode(), should_replace_entry(), ui_timestamp, report_type,
- GetBaseURLForDataURL(), GetHistoryURLForDataURL(), previews_state,
- navigation_start, method, post_body ? post_body : post_data_,
+ !IsViewSourceMode(), should_replace_entry(), GetBaseURLForDataURL(),
+ GetHistoryURLForDataURL(), previews_state, navigation_start,
+ frame_entry.method(), post_body ? post_body : post_data_,
base::Optional<SourceLocation>(),
CSPDisposition::CHECK /* should_check_main_world_csp */,
has_started_from_context_menu(), has_user_gesture(),
@@ -765,7 +759,6 @@ void NavigationEntryImpl::ResetForCommit(FrameNavigationEntry* frame_entry) {
// PlzNavigate is enabled.
SetPostData(nullptr);
set_is_renderer_initiated(false);
- set_transferred_global_request_id(GlobalRequestID());
set_should_replace_entry(false);
set_should_clear_history_list(false);
@@ -776,12 +769,6 @@ void NavigationEntryImpl::ResetForCommit(FrameNavigationEntry* frame_entry) {
frame_entry->set_source_site_instance(nullptr);
frame_entry->set_blob_url_loader_factory(nullptr);
}
-
-#if defined(OS_ANDROID)
- // Reset the time stamp so that the metrics are not reported if this entry is
- // loaded again in the future.
- set_intent_received_timestamp(base::TimeTicks());
-#endif
}
NavigationEntryImpl::TreeNode* NavigationEntryImpl::GetTreeNode(
diff --git a/chromium/content/browser/frame_host/navigation_entry_impl.h b/chromium/content/browser/frame_host/navigation_entry_impl.h
index edfec89b1bc..8c398afe158 100644
--- a/chromium/content/browser/frame_host/navigation_entry_impl.h
+++ b/chromium/content/browser/frame_host/navigation_entry_impl.h
@@ -358,15 +358,6 @@ class CONTENT_EXPORT NavigationEntryImpl : public NavigationEntry {
void set_reload_type(ReloadType type) { reload_type_ = type; }
ReloadType reload_type() const { return reload_type_; }
- void set_transferred_global_request_id(
- const GlobalRequestID& transferred_global_request_id) {
- transferred_global_request_id_ = transferred_global_request_id;
- }
-
- GlobalRequestID transferred_global_request_id() const {
- return transferred_global_request_id_;
- }
-
// Whether this (pending) navigation needs to replace current entry.
// Resets to false after commit.
bool should_replace_entry() const {
@@ -408,17 +399,6 @@ class CONTENT_EXPORT NavigationEntryImpl : public NavigationEntry {
void set_ssl_error(bool error) { ssl_error_ = error; }
bool ssl_error() const { return ssl_error_; }
-#if defined(OS_ANDROID)
- base::TimeTicks intent_received_timestamp() const {
- return intent_received_timestamp_;
- }
-
- void set_intent_received_timestamp(
- const base::TimeTicks intent_received_timestamp) {
- intent_received_timestamp_ = intent_received_timestamp;
- }
-#endif
-
bool has_user_gesture() const {
return has_user_gesture_;
}
@@ -505,16 +485,6 @@ class CONTENT_EXPORT NavigationEntryImpl : public NavigationEntry {
// cleared to force a refresh.
mutable base::string16 cached_display_title_;
- // In case a navigation is transferred to a new RVH but the request has
- // been generated in the renderer already, this identifies the old request so
- // that it can be resumed. The old request is stored until the
- // ResourceDispatcher receives the navigation from the renderer which
- // carries this |transferred_global_request_id_| annotation. Once the request
- // is transferred to the new process, this is cleared and the request
- // continues as normal.
- // Cleared in |ResetForCommit|.
- GlobalRequestID transferred_global_request_id_;
-
// This is set to true when this entry is being reloaded and due to changes in
// the state of the URL, it has to be reloaded in a different site instance.
// In such case, we must treat it as an existing navigation in the new site
@@ -544,12 +514,6 @@ class CONTENT_EXPORT NavigationEntryImpl : public NavigationEntry {
// TODO(creis): Move this to FrameNavigationEntry.
int frame_tree_node_id_;
-#if defined(OS_ANDROID)
- // The time at which Chrome received the Android Intent that triggered this
- // URL load operation. Reset at commit and not persisted.
- base::TimeTicks intent_received_timestamp_;
-#endif
-
// Whether the URL load carries a user gesture.
bool has_user_gesture_;
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 c592771aa78..a95cedbd6cb 100644
--- a/chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigation_entry_impl_unittest.cc
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "content/browser/frame_host/navigation_entry_impl.h"
+
+#include "base/path_service.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/test_file_util.h"
#include "base/time/time.h"
#include "build/build_config.h"
-#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/site_instance_impl.h"
#include "content/public/browser/ssl_status.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -328,4 +331,22 @@ TEST_F(NavigationEntryTest, NavigationEntryExtraData) {
EXPECT_EQ(ASCIIToUTF16(""), output2);
}
+#if defined(OS_ANDROID)
+// Test that content URIs correctly show the file display name as the title.
+TEST_F(NavigationEntryTest, NavigationEntryContentUri) {
+ base::FilePath image_path;
+ EXPECT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &image_path));
+ image_path = image_path.Append(FILE_PATH_LITERAL("content"));
+ image_path = image_path.Append(FILE_PATH_LITERAL("test"));
+ image_path = image_path.Append(FILE_PATH_LITERAL("data"));
+ image_path = image_path.Append(FILE_PATH_LITERAL("blank.jpg"));
+ EXPECT_TRUE(base::PathExists(image_path));
+
+ base::FilePath content_uri = base::InsertImageIntoMediaStore(image_path);
+
+ entry1_->SetURL(GURL(content_uri.value()));
+ EXPECT_EQ(ASCIIToUTF16("blank.jpg"), entry1_->GetTitleForDisplay());
+}
+#endif
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl.cc b/chromium/content/browser/frame_host/navigation_handle_impl.cc
index b23698013a0..201f23b9b42 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl.cc
+++ b/chromium/content/browser/frame_host/navigation_handle_impl.cc
@@ -22,6 +22,7 @@
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/frame_host/navigator_delegate.h"
+#include "content/browser/frame_host/origin_policy_throttle.h"
#include "content/browser/frame_host/webui_navigation_throttle.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
@@ -950,8 +951,7 @@ void NavigationHandleImpl::DidCommitNavigation(
subframe_entry_committed_ = navigation_entry_committed;
// For successful navigations, ensure the frame owner element is no longer
- // collapsed as a result of a prior navigation having been blocked with
- // BLOCK_REQUEST_AND_COLLAPSE.
+ // collapsed as a result of a prior navigation.
if (!IsErrorPage() && !frame_tree_node()->IsMainFrame()) {
// The last committed load in collapsed frames will be an error page with
// |kUnreachableWebDataURL|. Same-document navigation should not be
@@ -1022,8 +1022,6 @@ NavigationHandleImpl::CheckWillStartRequest() {
continue;
case NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE:
- frame_tree_node_->SetCollapsed(true);
- FALLTHROUGH;
case NavigationThrottle::BLOCK_REQUEST:
case NavigationThrottle::CANCEL:
case NavigationThrottle::CANCEL_AND_IGNORE:
@@ -1070,8 +1068,6 @@ NavigationHandleImpl::CheckWillRedirectRequest() {
continue;
case NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE:
- frame_tree_node_->SetCollapsed(true);
- FALLTHROUGH;
case NavigationThrottle::BLOCK_REQUEST:
case NavigationThrottle::CANCEL:
case NavigationThrottle::CANCEL_AND_IGNORE:
@@ -1250,9 +1246,6 @@ void NavigationHandleImpl::CancelDeferredNavigationInternal(
DCHECK(result.action() != NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE ||
state_ == DEFERRING_START || state_ == DEFERRING_REDIRECT);
- if (result.action() == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE)
- frame_tree_node_->SetCollapsed(true);
-
TRACE_EVENT_ASYNC_STEP_INTO0("navigation", "NavigationHandle", this,
"CancelDeferredNavigation");
state_ = CANCELING;
@@ -1309,6 +1302,9 @@ void NavigationHandleImpl::RegisterNavigationThrottles() {
AddThrottle(
MixedContentNavigationThrottle::CreateThrottleForNavigation(this));
+ // Handle Origin Policy (if enabled)
+ AddThrottle(OriginPolicyThrottle::MaybeCreateThrottleFor(this));
+
for (auto& throttle :
RenderFrameDevToolsAgentHost::CreateNavigationThrottles(this)) {
AddThrottle(std::move(throttle));
diff --git a/chromium/content/browser/frame_host/navigation_handle_impl.h b/chromium/content/browser/frame_host/navigation_handle_impl.h
index f11fe8d88e0..fe477a944b9 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl.h
+++ b/chromium/content/browser/frame_host/navigation_handle_impl.h
@@ -160,6 +160,11 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
bool IsDownload() override;
bool IsFormSubmission() override;
+ const std::string& origin_policy() const { return origin_policy_; }
+ void set_origin_policy(const std::string& origin_policy) {
+ origin_policy_ = origin_policy;
+ }
+
// Resume and CancelDeferredNavigation must only be called by the
// NavigationThrottle that is currently deferring the navigation.
// |resuming_throttle| and |cancelling_throttle| are the throttles calling
@@ -368,6 +373,10 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
// url we're navigating to.
void SetExpectedProcess(RenderProcessHost* expected_process);
+ NavigationThrottle* GetDeferringThrottleForTesting() const {
+ return GetDeferringThrottle();
+ }
+
private:
friend class NavigationHandleImplTest;
@@ -557,6 +566,9 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
// in it.
int expected_render_process_host_id_;
+ // The origin policy that applies to this navigation. Empty if none applies.
+ std::string origin_policy_;
+
// Whether the navigation is in the middle of a transfer. Set to false when
// the DidStartProvisionalLoad is received from the new renderer.
bool is_transferring_;
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 fd806c769b3..c199bfb8bb9 100644
--- a/chromium/content/browser/frame_host/navigation_handle_impl_browsertest.cc
+++ b/chromium/content/browser/frame_host/navigation_handle_impl_browsertest.cc
@@ -6,7 +6,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "content/browser/frame_host/debug_urls.h"
#include "content/browser/frame_host/navigation_handle_impl.h"
#include "content/browser/frame_host/navigation_request.h"
diff --git a/chromium/content/browser/frame_host/navigation_request.cc b/chromium/content/browser/frame_host/navigation_request.cc
index ecc9736c95c..7fab20e8173 100644
--- a/chromium/content/browser/frame_host/navigation_request.cc
+++ b/chromium/content/browser/frame_host/navigation_request.cc
@@ -24,6 +24,7 @@
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/frame_host/navigator_impl.h"
+#include "content/browser/frame_host/origin_policy_throttle.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/loader/navigation_url_loader.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
@@ -66,7 +67,9 @@
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
#include "third_party/blink/public/common/frame/sandbox_flags.h"
+#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
#include "third_party/blink/public/platform/web_mixed_content_context_type.h"
+#include "url/url_constants.h"
namespace content {
@@ -207,13 +210,21 @@ void AddAdditionalRequestHeaders(
}
}
std::string value = base::StringPrintf(
- "cause=%s, destination=document, target=%s, site=%s",
+ "cause=\"%s\", destination=\"document\", target=\"%s\", site=\"%s\"",
has_user_gesture ? "user-activated" : "forced",
frame_tree_node->IsMainFrame() ? "top-level" : "nested",
site_value.c_str());
headers->SetHeaderIfMissing("Sec-Metadata", value);
}
+ // Ask whether we should request a policy.
+ std::string origin_policy_request;
+ if (OriginPolicyThrottle::ShouldRequestOriginPolicy(url,
+ &origin_policy_request)) {
+ headers->SetHeader(net::HttpRequestHeaders::kSecOriginPolicy,
+ origin_policy_request);
+ }
+
// Next, set the HTTP Origin if needed.
if (!NeedsHTTPOrigin(headers, method))
return;
@@ -335,7 +346,7 @@ std::unique_ptr<NavigationRequest> NavigationRequest::CreateBrowserInitiated(
GURL() /* client_side_redirect_url */,
base::nullopt /* devtools_initiator_info */),
request_params, browser_initiated, false /* from_begin_navigation */,
- &frame_entry, &entry, std::move(navigation_ui_data)));
+ &frame_entry, &entry, std::move(navigation_ui_data), nullptr));
navigation_request->blob_url_loader_factory_ =
frame_entry.blob_url_loader_factory();
return navigation_request;
@@ -350,7 +361,8 @@ std::unique_ptr<NavigationRequest> NavigationRequest::CreateRendererInitiated(
int current_history_list_offset,
int current_history_list_length,
bool override_user_agent,
- scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory) {
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client) {
// Only normal navigations to a different document or reloads are expected.
// - Renderer-initiated fragment-navigations never take place in the browser,
// even with PlzNavigate.
@@ -384,7 +396,8 @@ std::unique_ptr<NavigationRequest> NavigationRequest::CreateRendererInitiated(
false, // browser_initiated
true, // from_begin_navigation
nullptr, entry,
- nullptr)); // navigation_ui_data
+ nullptr, // navigation_ui_data
+ std::move(navigation_client)));
navigation_request->blob_url_loader_factory_ =
std::move(blob_url_loader_factory);
return navigation_request;
@@ -399,7 +412,8 @@ NavigationRequest::NavigationRequest(
bool from_begin_navigation,
const FrameNavigationEntry* frame_entry,
const NavigationEntryImpl* entry,
- std::unique_ptr<NavigationUIData> navigation_ui_data)
+ std::unique_ptr<NavigationUIData> navigation_ui_data,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client)
: frame_tree_node_(frame_tree_node),
common_params_(common_params),
begin_params_(std::move(begin_params)),
@@ -416,6 +430,8 @@ NavigationRequest::NavigationRequest(
has_stale_copy_in_cache_(false),
net_error_(net::OK),
devtools_navigation_token_(base::UnguessableToken::Create()),
+ request_navigation_client_(nullptr),
+ commit_navigation_client_(nullptr),
weak_factory_(this) {
DCHECK(!browser_initiated || (entry != nullptr && frame_entry != nullptr));
DCHECK(!IsRendererDebugURL(common_params_.url));
@@ -433,7 +449,19 @@ NavigationRequest::NavigationRequest(
// initiating renderer.
source_site_instance_ =
frame_tree_node->current_frame_host()->GetSiteInstance();
+
+ if (IsPerNavigationMojoInterfaceEnabled()) {
+ DCHECK(navigation_client.is_valid());
+ request_navigation_client_ = mojom::NavigationClientAssociatedPtr();
+ request_navigation_client_.Bind(std::move(navigation_client));
+ // Binds the OnAbort callback
+ request_navigation_client_.set_connection_error_handler(
+ base::BindOnce(&NavigationRequest::OnRendererAbortedNavigation,
+ base::Unretained(this)));
+ associated_site_instance_id_ = source_site_instance_->GetId();
+ }
} else {
+ DCHECK(!navigation_client.is_valid());
FrameNavigationEntry* frame_navigation_entry =
entry->GetFrameEntry(frame_tree_node);
if (frame_navigation_entry) {
@@ -551,7 +579,10 @@ void NavigationRequest::BeginNavigation() {
// Don't create a NavigationHandle here to simulate what happened with the
// old navigation code path (i.e. doesn't fire onPageFinished notification
// for aborted loads).
- OnRequestFailed(network::URLLoaderCompletionStatus(net::ERR_ABORTED));
+ OnRequestFailedInternal(
+ network::URLLoaderCompletionStatus(net::ERR_ABORTED),
+ false /*skip_throttles*/, base::nullopt /*error_page_content*/,
+ false /*collapse_frame*/);
return;
}
#endif
@@ -561,16 +592,18 @@ void NavigationRequest::BeginNavigation() {
// otherwise block. Similarly, the NavigationHandle is created afterwards, so
// that it gets the request URL after potentially being modified by CSP.
net::Error net_error = CheckContentSecurityPolicy(
- false /* is redirect */, false /* is_response_check */);
+ false /* is redirect */, false /* url_upgraded_after_redirect */,
+ false /* is_response_check */);
if (net_error != net::OK) {
// Create a navigation handle so that the correct error code can be set on
- // it by OnRequestFailed().
+ // it by OnRequestFailedInternal().
CreateNavigationHandle();
OnRequestFailedInternal(network::URLLoaderCompletionStatus(net_error),
false /* skip_throttles */,
- base::nullopt /* error_page_content */);
- // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
- // destroyed the NavigationRequest.
+ base::nullopt /* error_page_content */,
+ false /* collapse_frame */);
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailedInternal
+ // has destroyed the NavigationRequest.
return;
}
@@ -579,14 +612,15 @@ void NavigationRequest::BeginNavigation() {
CheckLegacyProtocolInSubresource() ==
LegacyProtocolInSubresourceCheckResult::BLOCK_REQUEST) {
// Create a navigation handle so that the correct error code can be set on
- // it by OnRequestFailed().
+ // it by OnRequestFailedInternal().
CreateNavigationHandle();
OnRequestFailedInternal(
network::URLLoaderCompletionStatus(net::ERR_ABORTED),
- false /* skip_throttles */, base::nullopt /* error_page_content */);
+ false /* skip_throttles */, base::nullopt /* error_page_content */,
+ false /* collapse_frame */);
- // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
- // destroyed the NavigationRequest.
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailedInternal
+ // has destroyed the NavigationRequest.
return;
}
@@ -692,7 +726,9 @@ void NavigationRequest::ResetForCrossDocumentRestart() {
FrameMsg_Navigate_Type::IsSameDocument(common_params_.navigation_type));
// Reset the NavigationHandle, which is now incorrectly marked as
- // same-document.
+ // same-document. Ensure |loader_| does not exist as it can hold raw pointers
+ // to objects owned by the handle (see the comment in the header).
+ DCHECK(!loader_);
navigation_handle_.reset();
// Convert the navigation type to the appropriate cross-document one.
@@ -718,6 +754,12 @@ void NavigationRequest::RegisterSubresourceOverride(
subresource_overrides_->push_back(std::move(transferrable_loader));
}
+mojom::NavigationClient* NavigationRequest::GetCommitNavigationClient() {
+ if (commit_navigation_client_ && commit_navigation_client_.is_bound())
+ return commit_navigation_client_.get();
+ return nullptr;
+}
+
void NavigationRequest::OnRequestRedirected(
const net::RedirectInfo& redirect_info,
const scoped_refptr<network::ResourceResponse>& response) {
@@ -760,7 +802,6 @@ void NavigationRequest::OnRequestRedirected(
return;
}
#endif
-
if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRedirectToURL(
redirect_info.new_url)) {
DVLOG(1) << "Denied redirect for "
@@ -784,10 +825,6 @@ void NavigationRequest::OnRequestRedirected(
return;
}
- // If a redirect occurs, the original site instance we thought is the
- // destination could change.
- dest_site_instance_ = nullptr;
-
// For now, DevTools needs the POST data sent to the renderer process even if
// it is no longer a POST after the redirect.
if (redirect_info.new_method != "POST")
@@ -815,12 +852,15 @@ void NavigationRequest::OnRequestRedirected(
// gives CSP a chance to modify requests that NavigationThrottles would
// otherwise block.
net::Error net_error = CheckContentSecurityPolicy(
- true /* is redirect */, false /* is_response_check */);
+ true /* is redirect */, redirect_info.insecure_scheme_was_upgraded,
+ false /* is_response_check */);
if (net_error != net::OK) {
- OnRequestFailed(network::URLLoaderCompletionStatus(net_error));
+ OnRequestFailedInternal(
+ network::URLLoaderCompletionStatus(net_error), false /*skip_throttles*/,
+ base::nullopt /*error_page_content*/, false /*collapse_frame*/);
- // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
- // destroyed the NavigationRequest.
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailedInternal
+ // has destroyed the NavigationRequest.
return;
}
@@ -828,10 +868,13 @@ void NavigationRequest::OnRequestRedirected(
CredentialedSubresourceCheckResult::BLOCK_REQUEST ||
CheckLegacyProtocolInSubresource() ==
LegacyProtocolInSubresourceCheckResult::BLOCK_REQUEST) {
- OnRequestFailed(network::URLLoaderCompletionStatus(net::ERR_ABORTED));
+ OnRequestFailedInternal(
+ network::URLLoaderCompletionStatus(net::ERR_ABORTED),
+ false /*skip_throttles*/, base::nullopt /*error_page_content*/,
+ false /*collapse_frame*/);
- // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
- // destroyed the NavigationRequest.
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailedInternal
+ // has destroyed the NavigationRequest.
return;
}
@@ -1039,14 +1082,16 @@ void NavigationRequest::OnResponseStarted(
// redirect or not in order to perform its checks. This is the reason
// why we need to check the CSP both on request and response.
net::Error net_error = CheckContentSecurityPolicy(
- navigation_handle_->WasServerRedirect(), true /* is_response_check */);
+ navigation_handle_->WasServerRedirect(),
+ false /* url_upgraded_after_redirect */, true /* is_response_check */);
if (net_error != net::OK) {
OnRequestFailedInternal(network::URLLoaderCompletionStatus(net_error),
false /* skip_throttles */,
- base::nullopt /* error_page_content */);
+ base::nullopt /* error_page_content */,
+ false /* collapse_frame */);
- // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
- // destroyed the NavigationRequest.
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailedInternal
+ // has destroyed the NavigationRequest.
return;
}
@@ -1062,15 +1107,19 @@ void NavigationRequest::OnResponseStarted(
void NavigationRequest::OnRequestFailed(
const network::URLLoaderCompletionStatus& status) {
- NavigationRequest::OnRequestFailedInternal(
- status, false /* skip_throttles */,
- base::nullopt /* error_page_content */);
+ bool collapse_frame =
+ status.extended_error_code ==
+ static_cast<int>(blink::ResourceRequestBlockedReason::kCollapsedByClient);
+ OnRequestFailedInternal(status, false /* skip_throttles */,
+ base::nullopt /* error_page_content */,
+ collapse_frame);
}
void NavigationRequest::OnRequestFailedInternal(
const network::URLLoaderCompletionStatus& status,
bool skip_throttles,
- const base::Optional<std::string>& error_page_content) {
+ const base::Optional<std::string>& error_page_content,
+ bool collapse_frame) {
DCHECK(state_ == STARTED || state_ == RESPONSE_STARTED);
DCHECK(!(status.error_code == net::ERR_ABORTED &&
error_page_content.has_value()));
@@ -1099,6 +1148,12 @@ void NavigationRequest::OnRequestFailedInternal(
return;
}
+ if (collapse_frame) {
+ DCHECK(!frame_tree_node_->IsMainFrame());
+ DCHECK_EQ(net::ERR_BLOCKED_BY_CLIENT, status.error_code);
+ frame_tree_node_->SetCollapsed(true);
+ }
+
RenderFrameHostImpl* render_frame_host = nullptr;
if (SiteIsolationPolicy::IsErrorPageIsolationEnabled(
frame_tree_node_->IsMainFrame())) {
@@ -1125,10 +1180,6 @@ void NavigationRequest::OnRequestFailedInternal(
DCHECK(render_frame_host);
- // Don't ask the renderer to commit an URL if the browser will kill it when
- // it does.
- DCHECK(render_frame_host->CanCommitURL(common_params_.url));
-
NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL(render_frame_host,
common_params_.url);
@@ -1202,6 +1253,9 @@ void NavigationRequest::OnStartChecksComplete(
}
#endif
+ bool collapse_frame =
+ result.action() == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE;
+
// If the start checks completed synchronously, which could happen if there
// is no onbeforeunload handler or if a NavigationThrottle cancelled it,
// then this could cause reentrancy into NavigationController. So use a
@@ -1212,10 +1266,11 @@ void NavigationRequest::OnStartChecksComplete(
&NavigationRequest::OnRequestFailedInternal,
weak_factory_.GetWeakPtr(),
network::URLLoaderCompletionStatus(result.net_error_code()),
- true /* skip_throttles */, result.error_page_content()));
+ true /* skip_throttles */, result.error_page_content(),
+ collapse_frame));
- // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
- // destroyed the NavigationRequest.
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailedInternal
+ // has destroyed the NavigationRequest.
return;
}
@@ -1237,6 +1292,11 @@ void NavigationRequest::OnStartChecksComplete(
browser_context, navigating_frame_host->GetSiteInstance());
DCHECK(partition);
+ // |loader_| should not exist if the service worker handle and app cache
+ // handles will be destroyed, since it holds raw pointers to them. See the
+ // comment in the header for |loader_|.
+ DCHECK(!loader_);
+
// Only initialize the ServiceWorkerNavigationHandle if it can be created for
// this frame.
bool can_create_service_worker =
@@ -1326,9 +1386,11 @@ void NavigationRequest::OnStartChecksComplete(
report_raw_headers,
navigating_frame_host->GetVisibilityState() ==
blink::mojom::PageVisibilityState::kPrerender,
+ upgrade_if_insecure_,
blob_url_loader_factory_ ? blob_url_loader_factory_->Clone()
: nullptr,
- devtools_navigation_token()),
+ devtools_navigation_token(),
+ frame_tree_node_->devtools_frame_token()),
std::move(navigation_ui_data),
navigation_handle_->service_worker_handle(),
navigation_handle_->appcache_handle(), this);
@@ -1339,6 +1401,9 @@ void NavigationRequest::OnRedirectChecksComplete(
DCHECK(result.action() != NavigationThrottle::DEFER);
DCHECK(result.action() != NavigationThrottle::BLOCK_RESPONSE);
+ bool collapse_frame =
+ result.action() == NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE;
+
// Abort the request if needed. This will destroy the NavigationRequest.
if (result.action() == NavigationThrottle::CANCEL_AND_IGNORE ||
result.action() == NavigationThrottle::CANCEL) {
@@ -1347,10 +1412,10 @@ void NavigationRequest::OnRedirectChecksComplete(
result.net_error_code() == net::ERR_ABORTED);
OnRequestFailedInternal(
network::URLLoaderCompletionStatus(result.net_error_code()),
- true /* skip_throttles */, result.error_page_content());
+ true /* skip_throttles */, result.error_page_content(), collapse_frame);
- // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
- // destroyed the NavigationRequest.
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailedInternal
+ // has destroyed the NavigationRequest.
return;
}
@@ -1360,15 +1425,21 @@ void NavigationRequest::OnRedirectChecksComplete(
result.net_error_code() == net::ERR_BLOCKED_BY_ADMINISTRATOR);
OnRequestFailedInternal(
network::URLLoaderCompletionStatus(result.net_error_code()),
- true /* skip_throttles */, result.error_page_content());
- // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
- // destroyed the NavigationRequest.
+ true /* skip_throttles */, result.error_page_content(), collapse_frame);
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailedInternal
+ // has destroyed the NavigationRequest.
return;
}
RenderFrameDevToolsAgentHost::OnNavigationRequestWillBeSent(*this);
- loader_->FollowRedirect();
+ base::Optional<net::HttpRequestHeaders> embedder_additional_headers;
+ GetContentClient()->browser()->NavigationRequestRedirected(
+ frame_tree_node_->frame_tree_node_id(), common_params_.url,
+ &embedder_additional_headers);
+
+ loader_->FollowRedirect(base::nullopt,
+ std::move(embedder_additional_headers));
}
void NavigationRequest::OnFailureChecksComplete(
@@ -1436,7 +1507,10 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
response_, std::move(url_loader_client_endpoints_),
ssl_info_.cert_status, frame_tree_node_->frame_tree_node_id());
- OnRequestFailed(network::URLLoaderCompletionStatus(net::ERR_ABORTED));
+ OnRequestFailedInternal(
+ network::URLLoaderCompletionStatus(net::ERR_ABORTED),
+ false /*skip_throttles*/, base::nullopt /*error_page_content*/,
+ false /*collapse_frame*/);
// DO NOT ADD CODE after this. The previous call to OnRequestFailed has
// destroyed the NavigationRequest.
return;
@@ -1471,7 +1545,8 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
// destroyed the NavigationRequest.
OnRequestFailedInternal(
network::URLLoaderCompletionStatus(net::ERR_ABORTED),
- true /* skip_throttles */, base::nullopt /* error_page_content */);
+ true /* skip_throttles */, base::nullopt /* error_page_content */,
+ false /* collapse_frame */);
return;
}
@@ -1479,10 +1554,11 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
result.net_error_code() == net::ERR_ABORTED);
OnRequestFailedInternal(
network::URLLoaderCompletionStatus(result.net_error_code()),
- true /* skip_throttles */, result.error_page_content());
+ true /* skip_throttles */, result.error_page_content(),
+ false /* collapse_frame */);
- // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
- // destroyed the NavigationRequest.
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailedInternal
+ // has destroyed the NavigationRequest.
return;
}
@@ -1490,9 +1566,10 @@ void NavigationRequest::OnWillProcessResponseChecksComplete(
DCHECK_EQ(net::ERR_BLOCKED_BY_RESPONSE, result.net_error_code());
OnRequestFailedInternal(
network::URLLoaderCompletionStatus(result.net_error_code()),
- true /* skip_throttles */, result.error_page_content());
- // DO NOT ADD CODE after this. The previous call to OnRequestFailed has
- // destroyed the NavigationRequest.
+ true /* skip_throttles */, result.error_page_content(),
+ false /* collapse_frame */);
+ // DO NOT ADD CODE after this. The previous call to OnRequestFailedInternal
+ // has destroyed the NavigationRequest.
return;
}
@@ -1507,10 +1584,28 @@ void NavigationRequest::CommitErrorPage(
const base::Optional<std::string>& error_page_content) {
UpdateRequestNavigationParamsHistory();
frame_tree_node_->TransferNavigationRequestOwnership(render_frame_host);
+ if (IsPerNavigationMojoInterfaceEnabled() && request_navigation_client_ &&
+ request_navigation_client_.is_bound()) {
+ // Two cases are possible here:
+ // Either we have a same-site navigation in which case the navigation
+ // request needs to be canceled in the RFH, so we need to rebind the handler
+ // to a post-ReadyToCommit handler.
+ // TODO(ahemery): Implement this second abort handler.
+ // Or this navigation is cross-site: the original document should no longer
+ // be able to cancel it.
+ IgnorePipeDisconnection();
+ if (associated_site_instance_id_ ==
+ render_frame_host->GetSiteInstance()->GetId()) {
+ // Reuse the request NavigationClient for commit.
+ commit_navigation_client_ = std::move(request_navigation_client_);
+ }
+ associated_site_instance_id_.reset();
+ }
+
navigation_handle_->ReadyToCommitNavigation(render_frame_host, true);
- render_frame_host->FailedNavigation(common_params_, request_params_,
- has_stale_copy_in_cache_, net_error_,
- error_page_content);
+ render_frame_host->FailedNavigation(
+ navigation_handle_->GetNavigationId(), common_params_, request_params_,
+ has_stale_copy_in_cache_, net_error_, error_page_content);
}
void NavigationRequest::CommitNavigation() {
@@ -1519,6 +1614,11 @@ void NavigationRequest::CommitNavigation() {
navigation_handle_->IsSameDocument());
DCHECK(!common_params_.url.SchemeIs(url::kJavaScriptScheme));
+ // Send the applicable origin policy (if any) along with the request.
+ // (The policy is fetched by a throttle and is thus available only now.)
+ DCHECK(common_params_.origin_policy.empty());
+ common_params_.origin_policy = navigation_handle_->origin_policy();
+
// Retrieve the RenderFrameHost that needs to commit the navigation.
RenderFrameHostImpl* render_frame_host =
navigation_handle_->GetRenderFrameHost();
@@ -1528,9 +1628,27 @@ void NavigationRequest::CommitNavigation() {
frame_tree_node_->render_manager()->speculative_frame_host());
frame_tree_node_->TransferNavigationRequestOwnership(render_frame_host);
+ if (IsPerNavigationMojoInterfaceEnabled() && request_navigation_client_ &&
+ request_navigation_client_.is_bound()) {
+ // Two cases are possible here:
+ // Either we have a same-site navigation in which case the navigation
+ // request needs to be canceled in the RFH, so we need to rebind the handler
+ // to a post-ReadyToCommit handler.
+ // TODO(ahemery): Implement this second abort handler.
+ // Or this navigation is cross-site: the original document should no longer
+ // be able to cancel it.
+ IgnorePipeDisconnection();
+ if (associated_site_instance_id_ ==
+ render_frame_host->GetSiteInstance()->GetId()) {
+ // Reuse the request NavigationClient for commit.
+ commit_navigation_client_ = std::move(request_navigation_client_);
+ }
+ associated_site_instance_id_.reset();
+ }
render_frame_host->CommitNavigation(
- response_.get(), std::move(url_loader_client_endpoints_), common_params_,
- request_params_, is_view_source_, std::move(subresource_loader_params_),
+ navigation_handle_->GetNavigationId(), response_.get(),
+ std::move(url_loader_client_endpoints_), common_params_, request_params_,
+ is_view_source_, std::move(subresource_loader_params_),
std::move(subresource_overrides_), devtools_navigation_token_);
// Give SpareRenderProcessHostManager a heads-up about the most recently used
@@ -1544,10 +1662,23 @@ bool NavigationRequest::IsAllowedByCSPDirective(
CSPContext* context,
CSPDirective::Name directive,
bool is_redirect,
+ bool url_upgraded_after_redirect,
bool is_response_check,
CSPContext::CheckCSPDisposition disposition) {
+ GURL url;
+ // If this request was upgraded in the net stack, downgrade the URL back to
+ // HTTP before checking report only policies.
+ if (url_upgraded_after_redirect &&
+ disposition == CSPContext::CheckCSPDisposition::CHECK_REPORT_ONLY_CSP &&
+ common_params_.url.SchemeIs(url::kHttpsScheme)) {
+ GURL::Replacements replacements;
+ replacements.SetSchemeStr(url::kHttpScheme);
+ url = common_params_.url.ReplaceComponents(replacements);
+ } else {
+ url = common_params_.url;
+ }
return context->IsAllowedByCsp(
- directive, common_params_.url, is_redirect, is_response_check,
+ directive, url, is_redirect, is_response_check,
common_params_.source_location.value_or(SourceLocation()), disposition,
begin_params_->is_form_submission);
}
@@ -1555,17 +1686,18 @@ bool NavigationRequest::IsAllowedByCSPDirective(
net::Error NavigationRequest::CheckCSPDirectives(
RenderFrameHostImpl* parent,
bool is_redirect,
+ bool url_upgraded_after_redirect,
bool is_response_check,
CSPContext::CheckCSPDisposition disposition) {
bool navigate_to_allowed = IsAllowedByCSPDirective(
initiator_csp_context_.get(), CSPDirective::NavigateTo, is_redirect,
- is_response_check, disposition);
+ url_upgraded_after_redirect, is_response_check, disposition);
bool frame_src_allowed = true;
if (parent) {
- frame_src_allowed =
- IsAllowedByCSPDirective(parent, CSPDirective::FrameSrc, is_redirect,
- is_response_check, disposition);
+ frame_src_allowed = IsAllowedByCSPDirective(
+ parent, CSPDirective::FrameSrc, is_redirect,
+ url_upgraded_after_redirect, is_response_check, disposition);
}
if (navigate_to_allowed && frame_src_allowed)
@@ -1585,6 +1717,7 @@ net::Error NavigationRequest::CheckCSPDirectives(
net::Error NavigationRequest::CheckContentSecurityPolicy(
bool is_redirect,
+ bool url_upgraded_after_redirect,
bool is_response_check) {
if (common_params_.url.SchemeIs(url::kAboutScheme))
return net::OK;
@@ -1616,23 +1749,23 @@ net::Error NavigationRequest::CheckContentSecurityPolicy(
// requests that are upgraded in step 2.
net::Error report_only_csp_status =
- CheckCSPDirectives(parent, is_redirect, is_response_check,
- CSPContext::CHECK_REPORT_ONLY_CSP);
+ CheckCSPDirectives(parent, is_redirect, url_upgraded_after_redirect,
+ is_response_check, CSPContext::CHECK_REPORT_ONLY_CSP);
- // TODO(mkwst,estark): upgrade-insecure-requests does not work when following
- // redirects. Trying to uprade the new URL on redirect here is fruitless: the
- // redirect URL cannot be changed at this point. upgrade-insecure-requests
- // needs to move to the net stack to resolve this. https://crbug.com/615885
+ // upgrade-insecure-requests is handled in the network code for redirects,
+ // only do the upgrade here if this is not a redirect.
if (!is_redirect && !frame_tree_node()->IsMainFrame()) {
if (parent &&
parent->ShouldModifyRequestUrlForCsp(true /* is subresource */)) {
+ upgrade_if_insecure_ = true;
parent->ModifyRequestUrlForCsp(&common_params_.url);
request_params_.original_url = common_params_.url;
}
}
- net::Error enforced_csp_status = CheckCSPDirectives(
- parent, is_redirect, is_response_check, CSPContext::CHECK_ENFORCED_CSP);
+ net::Error enforced_csp_status =
+ CheckCSPDirectives(parent, is_redirect, url_upgraded_after_redirect,
+ is_response_check, CSPContext::CHECK_ENFORCED_CSP);
if (enforced_csp_status != net::OK)
return enforced_csp_status;
return report_only_csp_status;
@@ -1713,4 +1846,15 @@ void NavigationRequest::UpdateRequestNavigationParamsHistory() {
navigation_controller->GetEntryCount();
}
+void NavigationRequest::OnRendererAbortedNavigation() {
+ frame_tree_node_->navigator()->CancelNavigation(frame_tree_node_, false);
+
+ // Do not add code after this, NavigationRequest has been destroyed.
+}
+
+void NavigationRequest::IgnorePipeDisconnection() {
+ return request_navigation_client_.set_connection_error_handler(
+ base::DoNothing());
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigation_request.h b/chromium/content/browser/frame_host/navigation_request.h
index 164401d6db4..10440a4a70c 100644
--- a/chromium/content/browser/frame_host/navigation_request.h
+++ b/chromium/content/browser/frame_host/navigation_request.h
@@ -108,7 +108,8 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
int current_history_list_offset,
int current_history_list_length,
bool override_user_agent,
- scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory);
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client);
~NavigationRequest() override;
@@ -208,6 +209,11 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
void RegisterSubresourceOverride(
mojom::TransferrableURLLoaderPtr transferrable_loader);
+ // Returns the NavigationClient held by this navigation request that is ready
+ // to commit, or nullptr if there isn't any.
+ // Only used with PerNavigationMojoInterface enabled.
+ mojom::NavigationClient* GetCommitNavigationClient();
+
private:
NavigationRequest(FrameTreeNode* frame_tree_node,
const CommonNavigationParams& common_params,
@@ -217,7 +223,8 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
bool from_begin_navigation,
const FrameNavigationEntry* frame_navigation_entry,
const NavigationEntryImpl* navitation_entry,
- std::unique_ptr<NavigationUIData> navigation_ui_data);
+ std::unique_ptr<NavigationUIData> navigation_ui_data,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client);
// NavigationURLLoaderDelegate implementation.
void OnRequestRedirected(
@@ -236,13 +243,17 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
const network::URLLoaderCompletionStatus& status) 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. |error_page_content|
- // is only used when |skip_throttles| is true.
+ // To be called whenever a navigation request fails. If |skip_throttles| is
+ // true, the registered NavigationThrottle(s) won't get a chance to intercept
+ // NavigationThrottle::WillFailRequest. It should be used when a request
+ // failed due to a throttle result itself. |error_page_content| is only used
+ // when |skip_throttles| is true. If |collapse_frame| is true, the associated
+ // frame tree node is collapsed.
void OnRequestFailedInternal(
const network::URLLoaderCompletionStatus& status,
bool skip_throttles,
- const base::Optional<std::string>& error_page_content);
+ const base::Optional<std::string>& error_page_content,
+ bool collapse_frame);
// Helper to determine whether an error page for the provided error code
// should stay in the current process.
@@ -273,6 +284,7 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
bool IsAllowedByCSPDirective(CSPContext* context,
CSPDirective::Name directive,
bool is_redirect,
+ bool url_upgraded_after_redirect,
bool is_response_check,
CSPContext::CheckCSPDisposition disposition);
@@ -282,6 +294,7 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
// net::ERR_BLOCKED_BY_CLIENT depending on which checks fail.
net::Error CheckCSPDirectives(RenderFrameHostImpl* parent,
bool is_redirect,
+ bool url_upgraded_after_redirect,
bool is_response_check,
CSPContext::CheckCSPDisposition disposition);
@@ -292,6 +305,7 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
// - The navigation request may be upgraded from HTTP to HTTPS if a CSP is
// configured to upgrade insecure requests.
net::Error CheckContentSecurityPolicy(bool is_redirect,
+ bool url_upgraded_after_redirect,
bool is_response_check);
// This enum describes the result of the credentialed subresource check for
@@ -323,6 +337,17 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
// renderer process.
void UpdateRequestNavigationParamsHistory();
+ // Called when an ongoing renderer-initiated navigation is aborted.
+ // Only used with PerNavigationMojoInterface enabled.
+ void OnRendererAbortedNavigation();
+
+ // When called, this NavigationRequest will no longer interpret the pipe
+ // disconnection on the renderer side as an AbortNavigation.
+ // TODO(ahemery): remove this function when NavigationRequest properly handles
+ // pipe disconnection in all cases. Only used with PerNavigationMojoInterface
+ // enabled.
+ void IgnorePipeDisconnection();
+
FrameTreeNode* frame_tree_node_;
// Initialized on creation of the NavigationRequest. Sent to the renderer when
@@ -349,6 +374,12 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
NavigationState state_;
+ // It's important to ensure |navigation_handle_| outlives |loader_|, since the
+ // loader holds raw pointers to objects owned by the navigation handle
+ // (namely, the AppCache and service worker handles). The destruction order
+ // matters because it occurs over separate tasks on the IO thread. So, declare
+ // the handle before the loader.
+ std::unique_ptr<NavigationHandleImpl> navigation_handle_;
std::unique_ptr<NavigationURLLoader> loader_;
// These next items are used in browser-initiated navigations to store
@@ -380,8 +411,6 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
// process expects to be notified if the navigation is aborted.
bool from_begin_navigation_;
- std::unique_ptr<NavigationHandleImpl> navigation_handle_;
-
// Holds objects received from OnResponseStarted while the WillProcessResponse
// checks are performed by the NavigationHandle. Once the checks have been
// completed, these objects will be used to continue the navigation.
@@ -409,6 +438,24 @@ class CONTENT_EXPORT NavigationRequest : public NavigationURLLoaderDelegate {
base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
subresource_overrides_;
+ // The NavigationClient interface for that requested this navigation in the
+ // case of a renderer initiated navigation. It is expected to be bound until
+ // this navigation commits or is canceled.
+ // Only valid when PerNavigationMojoInterface is enabled.
+ mojom::NavigationClientAssociatedPtr request_navigation_client_;
+ base::Optional<int32_t> associated_site_instance_id_;
+
+ // The NavigationClient interface used to commit the navigation. For now, this
+ // is only used for same-site renderer-initiated navigation.
+ // TODO(clamy, ahemery): Extend to all types of navigation.
+ // Only valid when PerNavigationMojoInterface is enabled.
+ mojom::NavigationClientAssociatedPtr commit_navigation_client_;
+
+ // If set, any redirects to HTTP for this navigation will be upgraded to
+ // HTTPS. This is used only on subframe navigations, when
+ // upgrade-insecure-requests is set as a CSP policy.
+ bool upgrade_if_insecure_ = false;
+
base::WeakPtrFactory<NavigationRequest> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(NavigationRequest);
diff --git a/chromium/content/browser/frame_host/navigation_request_info.cc b/chromium/content/browser/frame_host/navigation_request_info.cc
index 51d8563db09..f02f9a18f6a 100644
--- a/chromium/content/browser/frame_host/navigation_request_info.cc
+++ b/chromium/content/browser/frame_host/navigation_request_info.cc
@@ -18,9 +18,11 @@ NavigationRequestInfo::NavigationRequestInfo(
bool is_for_guests_only,
bool report_raw_headers,
bool is_prerendering,
+ bool upgrade_if_insecure,
std::unique_ptr<network::SharedURLLoaderFactoryInfo>
blob_url_loader_factory,
- const base::UnguessableToken& devtools_navigation_token)
+ const base::UnguessableToken& devtools_navigation_token,
+ const base::UnguessableToken& devtools_frame_token)
: common_params(common_params),
begin_params(std::move(begin_params)),
site_for_cookies(site_for_cookies),
@@ -31,8 +33,10 @@ NavigationRequestInfo::NavigationRequestInfo(
is_for_guests_only(is_for_guests_only),
report_raw_headers(report_raw_headers),
is_prerendering(is_prerendering),
+ upgrade_if_insecure(upgrade_if_insecure),
blob_url_loader_factory(std::move(blob_url_loader_factory)),
- devtools_navigation_token(devtools_navigation_token) {}
+ devtools_navigation_token(devtools_navigation_token),
+ devtools_frame_token(devtools_frame_token) {}
NavigationRequestInfo::NavigationRequestInfo(const NavigationRequestInfo& other)
: common_params(other.common_params),
@@ -45,7 +49,8 @@ NavigationRequestInfo::NavigationRequestInfo(const NavigationRequestInfo& other)
is_for_guests_only(other.is_for_guests_only),
report_raw_headers(other.report_raw_headers),
is_prerendering(other.is_prerendering),
- devtools_navigation_token(other.devtools_navigation_token) {}
+ upgrade_if_insecure(other.upgrade_if_insecure),
+ devtools_frame_token(other.devtools_frame_token) {}
NavigationRequestInfo::~NavigationRequestInfo() {}
diff --git a/chromium/content/browser/frame_host/navigation_request_info.h b/chromium/content/browser/frame_host/navigation_request_info.h
index 304502f0a25..8b6a81c92d9 100644
--- a/chromium/content/browser/frame_host/navigation_request_info.h
+++ b/chromium/content/browser/frame_host/navigation_request_info.h
@@ -23,20 +23,21 @@ 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,
- mojom::BeginNavigationParamsPtr 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,
- bool is_prerendering,
- std::unique_ptr<network::SharedURLLoaderFactoryInfo>
- blob_url_loader_factory,
- const base::UnguessableToken& devtools_navigation_token);
+ NavigationRequestInfo(const CommonNavigationParams& common_params,
+ mojom::BeginNavigationParamsPtr 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,
+ bool is_prerendering,
+ bool upgrade_if_insecure,
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ blob_url_loader_factory,
+ const base::UnguessableToken& devtools_navigation_token,
+ const base::UnguessableToken& devtools_frame_token);
NavigationRequestInfo(const NavigationRequestInfo& other);
~NavigationRequestInfo();
@@ -62,10 +63,16 @@ struct CONTENT_EXPORT NavigationRequestInfo {
const bool is_prerendering;
+ // If set to true, any HTTP redirects of this request will be upgraded to
+ // HTTPS. This only applies for subframe navigations.
+ const bool upgrade_if_insecure;
+
// URLLoaderFactory to facilitate loading blob URLs.
std::unique_ptr<network::SharedURLLoaderFactoryInfo> blob_url_loader_factory;
const base::UnguessableToken devtools_navigation_token;
+
+ const base::UnguessableToken devtools_frame_token;
};
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigator.cc b/chromium/content/browser/frame_host/navigator.cc
index 0876a3899ad..59cea6fbf74 100644
--- a/chromium/content/browser/frame_host/navigator.cc
+++ b/chromium/content/browser/frame_host/navigator.cc
@@ -17,28 +17,6 @@ NavigationController* Navigator::GetController() {
return nullptr;
}
-bool Navigator::NavigateToPendingEntry(
- FrameTreeNode* frame_tree_node,
- const FrameNavigationEntry& frame_entry,
- ReloadType reload_type,
- bool is_same_document_history_load,
- std::unique_ptr<NavigationUIData> navigation_ui_data) {
- return false;
-}
-
-bool Navigator::NavigateToEntry(
- FrameTreeNode* frame_tree_node,
- const FrameNavigationEntry& frame_entry,
- const NavigationEntryImpl& entry,
- ReloadType reload_type,
- bool is_same_document_history_load,
- bool is_history_navigation_in_new_child,
- bool is_pending_entry,
- const scoped_refptr<network::ResourceRequestBody>& post_body,
- std::unique_ptr<NavigationUIData> navigation_ui_data) {
- return false;
-}
-
bool Navigator::StartHistoryNavigationInNewSubframe(
RenderFrameHostImpl* render_frame_host,
const GURL& default_url) {
@@ -53,6 +31,7 @@ void Navigator::OnBeginNavigation(
FrameTreeNode* frame_tree_node,
const CommonNavigationParams& common_params,
mojom::BeginNavigationParamsPtr begin_params,
- scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory) {}
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client) {}
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigator.h b/chromium/content/browser/frame_host/navigator.h
index 5290287896d..fe5fe87f06f 100644
--- a/chromium/content/browser/frame_host/navigator.h
+++ b/chromium/content/browser/frame_host/navigator.h
@@ -84,37 +84,6 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
std::unique_ptr<NavigationHandleImpl> navigation_handle,
bool was_within_same_document) {}
- // Called by the NavigationController to cause the Navigator to navigate
- // to the current pending entry. The NavigationController should be called
- // back with RendererDidNavigate on success or DiscardPendingEntry on failure.
- // The callbacks can be inside of this function, or at some future time.
- //
- // If this method returns false, then the navigation is discarded (equivalent
- // to calling DiscardPendingEntry on the NavigationController).
- //
- // TODO(nasko): Remove this method from the interface, since Navigator and
- // NavigationController know about each other. This will be possible once
- // initialization of Navigator and NavigationController is properly done.
- virtual bool NavigateToPendingEntry(
- FrameTreeNode* frame_tree_node,
- const FrameNavigationEntry& frame_entry,
- ReloadType reload_type,
- bool is_same_document_history_load,
- std::unique_ptr<NavigationUIData> navigation_ui_data);
- // DEPRECATED. Callers should use NavigateToPendingEntry instead.
- // TODO(clamy): This is only briefly exposed to facilitate a larger
- // refactoring of NavigationController and will go away soon.
- virtual bool NavigateToEntry(
- FrameTreeNode* frame_tree_node,
- const FrameNavigationEntry& frame_entry,
- const NavigationEntryImpl& entry,
- ReloadType reload_type,
- bool is_same_document_history_load,
- bool is_history_navigation_in_new_child,
- bool is_pending_entry,
- const scoped_refptr<network::ResourceRequestBody>& post_body,
- std::unique_ptr<NavigationUIData> navigation_ui_data);
-
// Called on a newly created subframe during a history navigation. The browser
// process looks up the corresponding FrameNavigationEntry for the new frame
// navigates it in the correct process. Returns false if the
@@ -127,6 +96,14 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
// Navigation requests -------------------------------------------------------
+ // Called by the NavigationController to cause the Navigator to navigate to
+ // |navigation_request|. The NavigationController should be called back with
+ // RendererDidNavigate on success or DiscardPendingEntry on failure. The
+ // callbacks should be called in a future iteration of the message loop.
+ virtual void Navigate(std::unique_ptr<NavigationRequest> request,
+ ReloadType reload_type,
+ RestoreType restore_type) {}
+
virtual base::TimeTicks GetCurrentLoadStart();
// The RenderFrameHostImpl has received a request to open a URL with the
@@ -173,7 +150,8 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
FrameTreeNode* frame_tree_node,
const CommonNavigationParams& common_params,
mojom::BeginNavigationParamsPtr begin_params,
- scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory);
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client);
// Used to restart a navigation that was thought to be same-document in
// cross-document mode.
@@ -181,6 +159,7 @@ class CONTENT_EXPORT Navigator : public base::RefCounted<Navigator> {
std::unique_ptr<NavigationRequest> navigation_request) {}
// Used to abort an ongoing renderer-initiated navigation.
+ // Only used with PerNavigationMojoInterface disabled.
virtual void OnAbortNavigation(FrameTreeNode* frame_tree_node) {}
// Cancel a NavigationRequest for |frame_tree_node|. If the request is
diff --git a/chromium/content/browser/frame_host/navigator_delegate.cc b/chromium/content/browser/frame_host/navigator_delegate.cc
index 11b17d4f597..5ab06ef5a4b 100644
--- a/chromium/content/browser/frame_host/navigator_delegate.cc
+++ b/chromium/content/browser/frame_host/navigator_delegate.cc
@@ -34,7 +34,4 @@ std::unique_ptr<NavigationUIData> NavigatorDelegate::GetNavigationUIData(
return nullptr;
}
-void NavigatorDelegate::AdjustPreviewsStateForNavigation(
- PreviewsState* previews_state) {}
-
} // namespace content
diff --git a/chromium/content/browser/frame_host/navigator_delegate.h b/chromium/content/browser/frame_host/navigator_delegate.h
index fe0275288b5..cc58d99bfe5 100644
--- a/chromium/content/browser/frame_host/navigator_delegate.h
+++ b/chromium/content/browser/frame_host/navigator_delegate.h
@@ -11,7 +11,6 @@
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/navigation_ui_data.h"
#include "content/public/browser/reload_type.h"
-#include "content/public/common/previews_state.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/window_open_disposition.h"
@@ -134,13 +133,6 @@ class CONTENT_EXPORT NavigatorDelegate {
// Whether the delegate is displaying an interstitial page over the current
// page.
virtual bool ShowingInterstitialPage() const = 0;
-
- // Gives the delegate a chance to adjust the previews state during navigation.
- // When called, previews_state will be pointing to a valid set of previews, or
- // an enum value disabling previews. The call will change the value of
- // previews_state in place, and must change it to either a value disabling
- // previews, or a subset of the previews passed in.
- virtual void AdjustPreviewsStateForNavigation(PreviewsState* previews_state);
};
} // namspace content
diff --git a/chromium/content/browser/frame_host/navigator_impl.cc b/chromium/content/browser/frame_host/navigator_impl.cc
index e098e1bc69e..f53badc0816 100644
--- a/chromium/content/browser/frame_host/navigator_impl.cc
+++ b/chromium/content/browser/frame_host/navigator_impl.cc
@@ -39,6 +39,7 @@
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/stream_handle.h"
#include "content/public/common/bindings_policy.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/url_utils.h"
@@ -50,67 +51,6 @@
namespace content {
-namespace {
-
-FrameMsg_Navigate_Type::Value GetNavigationType(
- const GURL& old_url,
- const GURL& new_url,
- ReloadType reload_type,
- const NavigationEntryImpl& entry,
- const FrameNavigationEntry& frame_entry,
- bool is_same_document_history_load) {
- // Reload navigations
- switch (reload_type) {
- case ReloadType::NORMAL:
- return FrameMsg_Navigate_Type::RELOAD;
- case ReloadType::BYPASSING_CACHE:
- case ReloadType::DISABLE_PREVIEWS:
- return FrameMsg_Navigate_Type::RELOAD_BYPASSING_CACHE;
- case ReloadType::ORIGINAL_REQUEST_URL:
- return FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL;
- case ReloadType::NONE:
- break; // Fall through to rest of function.
- }
-
- // |RenderViewImpl::PopulateStateFromPendingNavigationParams| differentiates
- // between |RESTORE_WITH_POST| and |RESTORE|.
- if (entry.restore_type() == RestoreType::LAST_SESSION_EXITED_CLEANLY) {
- if (entry.GetHasPostData())
- return FrameMsg_Navigate_Type::RESTORE_WITH_POST;
- else
- return FrameMsg_Navigate_Type::RESTORE;
- }
-
- // History navigations.
- if (frame_entry.page_state().IsValid()) {
- if (is_same_document_history_load)
- return FrameMsg_Navigate_Type::HISTORY_SAME_DOCUMENT;
- else
- return FrameMsg_Navigate_Type::HISTORY_DIFFERENT_DOCUMENT;
- }
- DCHECK(!is_same_document_history_load);
-
- // A same-document fragment-navigation happens when the only part of the url
- // that is modified is after the '#' character.
- //
- // Be careful not to consider history navigations. For instance, if the
- // history is: 'A#bar' -> 'B' -> 'A#foo'. Then an history navigation from
- // 'A#foo' to 'A#bar' is not a same-document navigation, but a
- // different-document one! The two FrameNavigationEntry doesn't share the same
- // document_sequence_number.
- //
- // When modifying this condition, please take a look at:
- // FrameLoader::shouldPerformFragmentNavigation.
- if (new_url.has_ref() && old_url.EqualsIgnoringRef(new_url) &&
- frame_entry.method() == "GET") {
- return FrameMsg_Navigate_Type::SAME_DOCUMENT;
- } else {
- return FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
- }
-}
-
-} // namespace
-
struct NavigatorImpl::NavigationMetricsData {
NavigationMetricsData(base::TimeTicks start_time,
GURL url,
@@ -146,7 +86,7 @@ void NavigatorImpl::CheckWebUIRendererDoesNotDisplayNormalURL(
->GetController()
->GetBrowserContext(),
url);
- if ((enabled_bindings & BINDINGS_POLICY_WEB_UI) &&
+ if ((enabled_bindings & kWebUIBindingsPolicyMask) &&
!is_allowed_in_web_ui_renderer) {
// Log the URL to help us diagnose any future failures of this CHECK.
FrameTreeNode* root_node =
@@ -255,142 +195,6 @@ void NavigatorImpl::DidFailLoadWithError(
}
}
-bool NavigatorImpl::NavigateToEntry(
- FrameTreeNode* frame_tree_node,
- const FrameNavigationEntry& frame_entry,
- const NavigationEntryImpl& entry,
- ReloadType reload_type,
- bool is_same_document_history_load,
- bool is_history_navigation_in_new_child,
- bool is_pending_entry,
- const scoped_refptr<network::ResourceRequestBody>& post_body,
- std::unique_ptr<NavigationUIData> navigation_ui_data) {
- TRACE_EVENT0("browser,navigation", "NavigatorImpl::NavigateToEntry");
-
- GURL dest_url = frame_entry.url();
- Referrer dest_referrer = frame_entry.referrer();
- if ((reload_type == ReloadType::ORIGINAL_REQUEST_URL ||
- reload_type == ReloadType::DISABLE_PREVIEWS) &&
- entry.GetOriginalRequestURL().is_valid() && !entry.GetHasPostData()) {
- // We may have been redirected when navigating to the current URL.
- // Use the URL the user originally intended to visit as signaled by the
- // ReloadType, if it's valid and if a POST wasn't involved; the latter
- // case avoids issues with sending data to the wrong page. The
- // DISABLE_PREVIEWS case is triggered from a user action to view the
- // original URL without any preview intervention treatment.
- dest_url = entry.GetOriginalRequestURL();
- dest_referrer = Referrer();
- }
-
- // Don't attempt to navigate if the virtual URL is non-empty and invalid.
- if (frame_tree_node->IsMainFrame()) {
- const GURL& virtual_url = entry.GetVirtualURL();
- if (!virtual_url.is_valid() && !virtual_url.is_empty()) {
- LOG(WARNING) << "Refusing to load for invalid virtual URL: "
- << virtual_url.possibly_invalid_spec();
- return false;
- }
- }
-
- // Don't attempt to navigate to non-empty invalid URLs.
- if (!dest_url.is_valid() && !dest_url.is_empty()) {
- LOG(WARNING) << "Refusing to load invalid URL: "
- << dest_url.possibly_invalid_spec();
- return false;
- }
-
- // The renderer will reject IPC messages with URLs longer than
- // this limit, so don't attempt to navigate with a longer URL.
- if (dest_url.spec().size() > url::kMaxURLChars) {
- LOG(WARNING) << "Refusing to load URL as it exceeds " << url::kMaxURLChars
- << " characters.";
- return false;
- }
-
- // This will be used to set the Navigation Timing API navigationStart
- // parameter for browser navigations in new tabs (intents, tabs opened through
- // "Open link in new tab"). We need to keep it above RFHM::Navigate() call to
- // capture the time needed for the RenderFrameHost initialization.
- base::TimeTicks navigation_start = base::TimeTicks::Now();
- base::TimeTicks tracing_navigation_start = TRACE_TIME_TICKS_NOW();
- TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(
- "navigation,rail", "NavigationTiming navigationStart",
- TRACE_EVENT_SCOPE_GLOBAL, tracing_navigation_start);
-
- // Determine if Previews should be used for the navigation.
- PreviewsState previews_state = PREVIEWS_UNSPECIFIED;
- if (!frame_tree_node->IsMainFrame()) {
- // For subframes, use the state of the top-level frame.
- previews_state = frame_tree_node->frame_tree()
- ->root()
- ->current_frame_host()
- ->last_navigation_previews_state();
- } else if (reload_type == ReloadType::DISABLE_PREVIEWS) {
- // Disable LoFi when asked for it explicitly.
- previews_state = PREVIEWS_NO_TRANSFORM;
- }
-
- // Give the delegate an opportunity to adjust the previews state.
- if (delegate_)
- delegate_->AdjustPreviewsStateForNavigation(&previews_state);
-
- navigation_data_.reset(new NavigationMetricsData(navigation_start, dest_url,
- entry.restore_type()));
- RequestNavigation(frame_tree_node, dest_url, dest_referrer, frame_entry,
- entry, reload_type, previews_state,
- is_same_document_history_load,
- is_history_navigation_in_new_child, post_body,
- navigation_start, std::move(navigation_ui_data));
- if (frame_tree_node->IsMainFrame() && frame_tree_node->navigation_request()) {
- // For the trace below we're using the navigation handle as the async
- // trace id, |navigation_start| as the timestamp and reporting the
- // FrameTreeNode id as a parameter. For navigations where no network
- // request is made (data URLs, JavaScript URLs, etc) there is no handle
- // and so no tracing is done.
- TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
- "navigation", "Navigation timeToNetworkStack",
- frame_tree_node->navigation_request()->navigation_handle(),
- tracing_navigation_start, "FrameTreeNode id",
- frame_tree_node->frame_tree_node_id());
- }
-
- // Make sure no code called via RFH::Navigate clears the pending entry.
- if (is_pending_entry)
- CHECK_EQ(controller_->GetPendingEntry(), &entry);
-
- if (controller_->GetPendingEntryIndex() == -1 &&
- dest_url.SchemeIs(url::kJavaScriptScheme)) {
- // If the pending entry index is -1 (which means a new navigation rather
- // than a history one), and the user typed in a javascript: URL, don't add
- // it to the session history.
- //
- // This is a hack. What we really want is to avoid adding to the history
- // any URL that doesn't generate content, and what would be great would be
- // if we had a message from the renderer telling us that a new page was
- // not created. The same message could be used for mailto: URLs and the
- // like.
- return false;
- }
-
- // Notify observers about navigation.
- if (delegate_ && is_pending_entry)
- delegate_->DidStartNavigationToPendingEntry(dest_url, reload_type);
-
- return true;
-}
-
-bool NavigatorImpl::NavigateToPendingEntry(
- FrameTreeNode* frame_tree_node,
- const FrameNavigationEntry& frame_entry,
- ReloadType reload_type,
- bool is_same_document_history_load,
- std::unique_ptr<NavigationUIData> navigation_ui_data) {
- return NavigateToEntry(frame_tree_node, frame_entry,
- *controller_->GetPendingEntry(), reload_type,
- is_same_document_history_load, false, true, nullptr,
- std::move(navigation_ui_data));
-}
-
bool NavigatorImpl::StartHistoryNavigationInNewSubframe(
RenderFrameHostImpl* render_frame_host,
const GURL& default_url) {
@@ -545,6 +349,77 @@ void NavigatorImpl::DidNavigate(
}
}
+void NavigatorImpl::Navigate(std::unique_ptr<NavigationRequest> request,
+ ReloadType reload_type,
+ RestoreType restore_type) {
+ TRACE_EVENT0("browser,navigation", "NavigatorImpl::Navigate");
+
+ const GURL& dest_url = request->common_params().url;
+ FrameTreeNode* frame_tree_node = request->frame_tree_node();
+
+ navigation_data_.reset(new NavigationMetricsData(
+ request->common_params().navigation_start, dest_url, restore_type));
+
+ // Check if the BeforeUnload event needs to execute before assigning the
+ // NavigationRequest to the FrameTreeNode. Assigning it to the FrameTreeNode
+ // has the side effect of initializing the current RenderFrameHost, which will
+ // return that it should execute the BeforeUnload event (even though we don't
+ // need to wait for it in the case of a brand new RenderFrameHost).
+ //
+ // We don't want to dispatch a beforeunload handler if
+ // is_history_navigation_in_new_child is true. This indicates a newly created
+ // child frame which does not have a beforeunload handler.
+ bool should_dispatch_beforeunload =
+ !FrameMsg_Navigate_Type::IsSameDocument(
+ request->common_params().navigation_type) &&
+ !request->request_params().is_history_navigation_in_new_child &&
+ frame_tree_node->current_frame_host()->ShouldDispatchBeforeUnload(
+ false /* check_subframes_only */);
+
+ int nav_entry_id = request->nav_entry_id();
+ bool is_pending_entry =
+ controller_->GetPendingEntry() &&
+ (nav_entry_id == controller_->GetPendingEntry()->GetUniqueID());
+ frame_tree_node->CreatedNavigationRequest(std::move(request));
+ DCHECK(frame_tree_node->navigation_request());
+
+ // Have the current renderer execute its beforeunload event if needed. If it
+ // is not needed then NavigationRequest::BeginNavigation should be directly
+ // called instead.
+ if (should_dispatch_beforeunload) {
+ frame_tree_node->navigation_request()->SetWaitingForRendererResponse();
+ frame_tree_node->current_frame_host()->DispatchBeforeUnload(
+ RenderFrameHostImpl::BeforeUnloadType::BROWSER_INITIATED_NAVIGATION,
+ reload_type != ReloadType::NONE);
+ } else {
+ frame_tree_node->navigation_request()->BeginNavigation();
+ // WARNING: The NavigationRequest might have been destroyed in
+ // BeginNavigation(). Do not use |frame_tree_node->navigation_request()|
+ // after this point without null checking it first.
+ }
+
+ if (frame_tree_node->IsMainFrame() && frame_tree_node->navigation_request()) {
+ // For the trace below we're using the navigation handle as the async
+ // trace id, |navigation_start| as the timestamp and reporting the
+ // FrameTreeNode id as a parameter. For navigations where no network
+ // request is made (data URLs, JavaScript URLs, etc) there is no handle
+ // and so no tracing is done.
+ TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
+ "navigation", "Navigation timeToNetworkStack",
+ frame_tree_node->navigation_request()->navigation_handle(),
+ frame_tree_node->navigation_request()->common_params().navigation_start,
+ "FrameTreeNode id", frame_tree_node->frame_tree_node_id());
+ }
+
+ // Make sure no code called via RFH::Navigate clears the pending entry.
+ if (is_pending_entry)
+ CHECK_EQ(nav_entry_id, controller_->GetPendingEntry()->GetUniqueID());
+
+ // Notify observers about navigation.
+ if (delegate_ && is_pending_entry)
+ delegate_->DidStartNavigationToPendingEntry(dest_url, reload_type);
+}
+
void NavigatorImpl::RequestOpenURL(
RenderFrameHostImpl* render_frame_host,
const GURL& url,
@@ -748,7 +623,8 @@ void NavigatorImpl::OnBeginNavigation(
FrameTreeNode* frame_tree_node,
const CommonNavigationParams& common_params,
mojom::BeginNavigationParamsPtr begin_params,
- scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory) {
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client) {
// TODO(clamy): the url sent by the renderer should be validated with
// FilterURL.
// This is a renderer-initiated navigation.
@@ -773,10 +649,12 @@ void NavigatorImpl::OnBeginNavigation(
if (ongoing_navigation_request &&
ongoing_navigation_request->browser_initiated() &&
!common_params.has_user_gesture) {
- RenderFrameHost* current_frame_host =
- frame_tree_node->render_manager()->current_frame_host();
- current_frame_host->Send(
- new FrameMsg_DroppedNavigation(current_frame_host->GetRoutingID()));
+ if (!IsPerNavigationMojoInterfaceEnabled()) {
+ RenderFrameHost* current_frame_host =
+ frame_tree_node->render_manager()->current_frame_host();
+ current_frame_host->Send(
+ new FrameMsg_DroppedNavigation(current_frame_host->GetRoutingID()));
+ }
return;
}
@@ -809,7 +687,7 @@ void NavigatorImpl::OnBeginNavigation(
frame_tree_node, pending_entry, common_params,
std::move(begin_params), controller_->GetLastCommittedEntryIndex(),
controller_->GetEntryCount(), override_user_agent,
- std::move(blob_url_loader_factory)));
+ std::move(blob_url_loader_factory), std::move(navigation_client)));
NavigationRequest* navigation_request = frame_tree_node->navigation_request();
// This frame has already run beforeunload before it sent this IPC. See if
@@ -854,6 +732,7 @@ void NavigatorImpl::RestartNavigationAsCrossDocument(
}
void NavigatorImpl::OnAbortNavigation(FrameTreeNode* frame_tree_node) {
+ DCHECK(!IsPerNavigationMojoInterfaceEnabled());
NavigationRequest* ongoing_navigation_request =
frame_tree_node->navigation_request();
if (!ongoing_navigation_request ||
@@ -940,82 +819,6 @@ void NavigatorImpl::DiscardPendingEntryIfNeeded(int expected_pending_entry_id) {
}
}
-void NavigatorImpl::RequestNavigation(
- FrameTreeNode* frame_tree_node,
- const GURL& dest_url,
- const Referrer& dest_referrer,
- const FrameNavigationEntry& frame_entry,
- const NavigationEntryImpl& entry,
- ReloadType reload_type,
- PreviewsState previews_state,
- bool is_same_document_history_load,
- bool is_history_navigation_in_new_child,
- const scoped_refptr<network::ResourceRequestBody>& post_body,
- base::TimeTicks navigation_start,
- std::unique_ptr<NavigationUIData> navigation_ui_data) {
- DCHECK(frame_tree_node);
-
- // This is not a real navigation. Send the URL to the renderer process
- // immediately for handling.
- // Note: this includes navigations to JavaScript URLs, which are considered
- // renderer-debug URLs.
- if (IsRendererDebugURL(dest_url)) {
- RenderFrameHostImpl* render_frame_host =
- frame_tree_node->current_frame_host();
- frame_tree_node->render_manager()->InitializeRenderFrameIfNecessary(
- render_frame_host);
- render_frame_host->HandleRendererDebugURL(dest_url);
- return;
- }
-
- // This value must be set here because creating a NavigationRequest might
- // change the renderer live/non-live status and change this result.
- // We don't want to dispatch a beforeunload handler if
- // is_history_navigation_in_new_child is true. This indicates a newly created
- // child frame which does not have a beforunload handler.
- FrameMsg_Navigate_Type::Value navigation_type = GetNavigationType(
- frame_tree_node->current_url(), // old_url
- dest_url, // new_url
- reload_type, // reload_type
- entry, // entry
- frame_entry, // frame_entry
- is_same_document_history_load); // is_same_document_history_load
- bool is_same_document =
- FrameMsg_Navigate_Type::IsSameDocument(navigation_type);
- bool should_dispatch_beforeunload =
- !is_same_document && !is_history_navigation_in_new_child &&
- frame_tree_node->current_frame_host()->ShouldDispatchBeforeUnload(
- false /* check_subframes_only */);
- std::unique_ptr<NavigationRequest> scoped_request =
- NavigationRequest::CreateBrowserInitiated(
- frame_tree_node, dest_url, dest_referrer, frame_entry, entry,
- navigation_type, previews_state, is_same_document_history_load,
- is_history_navigation_in_new_child, post_body, navigation_start,
- controller_, std::move(navigation_ui_data));
-
- frame_tree_node->CreatedNavigationRequest(std::move(scoped_request));
-
- NavigationRequest* navigation_request = frame_tree_node->navigation_request();
- if (!navigation_request)
- return; // Navigation was synchronously stopped.
-
- // Have the current renderer execute its beforeunload event if needed. If it
- // is not needed then NavigationRequest::BeginNavigation should be directly
- // called instead.
- if (should_dispatch_beforeunload) {
- navigation_request->SetWaitingForRendererResponse();
- frame_tree_node->current_frame_host()->DispatchBeforeUnload(
- RenderFrameHostImpl::BeforeUnloadType::BROWSER_INITIATED_NAVIGATION,
- reload_type != ReloadType::NONE);
- } else {
- navigation_request->BeginNavigation();
- // DO NOT USE |navigation_request| BEYOND THIS POINT. It might have been
- // destroyed in BeginNavigation().
- // See https://crbug.com/770157.
- return;
- }
-}
-
void NavigatorImpl::RecordNavigationMetrics(
const LoadCommittedDetails& details,
const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
@@ -1072,10 +875,11 @@ void NavigatorImpl::DidStartMainFrameNavigation(
SiteInstanceImpl* site_instance,
NavigationHandleImpl* navigation_handle) {
// If there is no browser-initiated pending entry for this navigation and it
- // is not for the error URL, create a pending entry using the current
- // SiteInstance, and ensure the address bar updates accordingly. We don't
- // know the referrer or extra headers at this point, but the referrer will
- // be set properly upon commit.
+ // is not for the error URL, create a pending entry and ensure the address bar
+ // updates accordingly. We don't know the referrer or extra headers at this
+ // point, but the referrer will be set properly upon commit. This does not
+ // set the SiteInstance for the pending entry, because it may change
+ // before the URL commits.
NavigationEntryImpl* pending_entry = controller_->GetPendingEntry();
bool has_browser_initiated_pending_entry =
pending_entry && !pending_entry->is_renderer_initiated();
@@ -1100,13 +904,10 @@ void NavigatorImpl::DidStartMainFrameNavigation(
true /* is_renderer_initiated */, std::string(),
controller_->GetBrowserContext(),
nullptr /* blob_url_loader_factory */));
- entry->set_site_instance(site_instance);
// TODO(creis): If there's a pending entry already, find a safe way to
// update it instead of replacing it and copying over things like this.
// That will allow us to skip the NavigationHandle update below as well.
if (pending_entry) {
- entry->set_transferred_global_request_id(
- pending_entry->transferred_global_request_id());
entry->set_should_replace_entry(pending_entry->should_replace_entry());
entry->SetRedirectChain(pending_entry->GetRedirectChain());
}
diff --git a/chromium/content/browser/frame_host/navigator_impl.h b/chromium/content/browser/frame_host/navigator_impl.h
index 21557ba9c0c..b97af7081e4 100644
--- a/chromium/content/browser/frame_host/navigator_impl.h
+++ b/chromium/content/browser/frame_host/navigator_impl.h
@@ -57,25 +57,12 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
std::unique_ptr<NavigationHandleImpl> navigation_handle,
bool was_within_same_document) override;
- bool NavigateToPendingEntry(
- FrameTreeNode* frame_tree_node,
- const FrameNavigationEntry& frame_entry,
- ReloadType reload_type,
- bool is_same_document_history_load,
- std::unique_ptr<NavigationUIData> navigation_ui_data) override;
- bool NavigateToEntry(
- FrameTreeNode* frame_tree_node,
- const FrameNavigationEntry& frame_entry,
- const NavigationEntryImpl& entry,
- ReloadType reload_type,
- bool is_same_document_history_load,
- bool is_history_navigation_in_new_child,
- bool is_pending_entry,
- const scoped_refptr<network::ResourceRequestBody>& post_body,
- std::unique_ptr<NavigationUIData> navigation_ui_data) override;
bool StartHistoryNavigationInNewSubframe(
RenderFrameHostImpl* render_frame_host,
const GURL& default_url) override;
+ void Navigate(std::unique_ptr<NavigationRequest> request,
+ ReloadType reload_type,
+ RestoreType restore_type) override;
void RequestOpenURL(RenderFrameHostImpl* render_frame_host,
const GURL& url,
bool uses_post,
@@ -103,11 +90,12 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
void OnBeforeUnloadACK(FrameTreeNode* frame_tree_node,
bool proceed,
const base::TimeTicks& proceed_time) override;
- void OnBeginNavigation(FrameTreeNode* frame_tree_node,
- const CommonNavigationParams& common_params,
- mojom::BeginNavigationParamsPtr begin_params,
- scoped_refptr<network::SharedURLLoaderFactory>
- blob_url_loader_factory) override;
+ void OnBeginNavigation(
+ FrameTreeNode* frame_tree_node,
+ const CommonNavigationParams& common_params,
+ mojom::BeginNavigationParamsPtr begin_params,
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client) override;
void RestartNavigationAsCrossDocument(
std::unique_ptr<NavigationRequest> navigation_request) override;
void OnAbortNavigation(FrameTreeNode* frame_tree_node) override;
@@ -127,22 +115,6 @@ class CONTENT_EXPORT NavigatorImpl : public Navigator {
friend class NavigatorTestWithBrowserSideNavigation;
~NavigatorImpl() override;
- // If needed, sends a BeforeUnload IPC to the renderer to ask it to execute
- // the beforeUnload event. Otherwise, the navigation request will be started.
- void RequestNavigation(
- FrameTreeNode* frame_tree_node,
- const GURL& dest_url,
- const Referrer& dest_referrer,
- const FrameNavigationEntry& frame_entry,
- const NavigationEntryImpl& entry,
- ReloadType reload_type,
- PreviewsState previews_state,
- bool is_same_document_history_load,
- bool is_history_navigation_in_new_child,
- const scoped_refptr<network::ResourceRequestBody>& post_body,
- base::TimeTicks navigation_start,
- std::unique_ptr<NavigationUIData> navigation_ui_data);
-
void RecordNavigationMetrics(
const LoadCommittedDetails& details,
const FrameHostMsg_DidCommitProvisionalLoad_Params& params,
diff --git a/chromium/content/browser/frame_host/navigator_impl_unittest.cc b/chromium/content/browser/frame_host/navigator_impl_unittest.cc
index 3f560d4d333..78c1a044c48 100644
--- a/chromium/content/browser/frame_host/navigator_impl_unittest.cc
+++ b/chromium/content/browser/frame_host/navigator_impl_unittest.cc
@@ -117,17 +117,20 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
EXPECT_EQ(NavigationRequest::STARTED, request->state());
ASSERT_TRUE(GetLoaderForNavigationRequest(request));
EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
+ int64_t navigation_id = request->navigation_handle()->GetNavigationId();
// Have the current RenderFrameHost commit the navigation.
scoped_refptr<network::ResourceResponse> response(
new network::ResourceResponse);
GetLoaderForNavigationRequest(request)->CallOnResponseStarted(response,
nullptr);
- EXPECT_TRUE(main_test_rfh()->navigation_request());
EXPECT_TRUE(main_test_rfh()->is_loading());
EXPECT_FALSE(node->navigation_request());
// Commit the navigation.
+ main_test_rfh()->SimulateCommitProcessed(navigation_id,
+ true /* was_successful */);
+ EXPECT_TRUE(main_test_rfh()->navigation_request());
main_test_rfh()->SendNavigate(entry_id, true, kUrl);
EXPECT_TRUE(main_test_rfh()->is_active());
EXPECT_EQ(SiteInstanceImpl::GetSiteForURL(browser_context(), kUrl),
@@ -178,7 +181,6 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Have the current RenderFrameHost commit the navigation
navigation->ReadyToCommit();
- EXPECT_TRUE(main_test_rfh()->navigation_request());
EXPECT_TRUE(main_test_rfh()->is_loading());
EXPECT_FALSE(node->navigation_request());
@@ -231,9 +233,6 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
if (AreAllSitesIsolatedForTesting()) {
EXPECT_EQ(navigation->GetFinalRenderFrameHost(),
GetSpeculativeRenderFrameHost(node));
- EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)->navigation_request());
- } else {
- EXPECT_TRUE(main_test_rfh()->navigation_request());
}
EXPECT_FALSE(node->navigation_request());
@@ -444,6 +443,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, CrossSiteNavigation) {
// Receive the beforeUnload ACK.
main_test_rfh()->SendBeforeUnloadACK(true);
+ int64_t navigation_id = main_request->navigation_handle()->GetNavigationId();
EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
scoped_refptr<network::ResourceResponse> response(
@@ -451,9 +451,12 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, CrossSiteNavigation) {
GetLoaderForNavigationRequest(main_request)
->CallOnResponseStarted(response, nullptr);
EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
- EXPECT_TRUE(speculative_rfh->navigation_request());
EXPECT_FALSE(main_test_rfh()->navigation_request());
+ speculative_rfh->SimulateCommitProcessed(navigation_id,
+ true /* was_successful */);
+ EXPECT_TRUE(speculative_rfh->navigation_request());
+
speculative_rfh->SendNavigate(entry_id, true, kUrl2);
RenderFrameHostImpl* final_rfh = main_test_rfh();
@@ -489,6 +492,8 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, RedirectCrossSite) {
EXPECT_EQ(1, GetLoaderForNavigationRequest(main_request)->redirect_count());
EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
+ int64_t navigation_id = main_request->navigation_handle()->GetNavigationId();
+
// Have the RenderFrameHost commit the navigation.
scoped_refptr<network::ResourceResponse> response(
new network::ResourceResponse);
@@ -497,9 +502,11 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, RedirectCrossSite) {
TestRenderFrameHost* final_speculative_rfh =
GetSpeculativeRenderFrameHost(node);
EXPECT_TRUE(final_speculative_rfh);
- EXPECT_TRUE(final_speculative_rfh->navigation_request());
// Commit the navigation.
+ final_speculative_rfh->SimulateCommitProcessed(navigation_id,
+ true /* was_successful */);
+ EXPECT_TRUE(final_speculative_rfh->navigation_request());
final_speculative_rfh->SendNavigate(entry_id, true, kUrl2);
RenderFrameHostImpl* final_rfh = main_test_rfh();
ASSERT_TRUE(final_rfh);
@@ -548,6 +555,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
int entry_id = RequestNavigation(node, kUrl2);
main_test_rfh()->SendBeforeUnloadACK(true);
NavigationRequest* request2 = node->navigation_request();
+ int64_t navigation_id = request2->navigation_handle()->GetNavigationId();
ASSERT_TRUE(request2);
EXPECT_EQ(kUrl2, request2->common_params().url);
EXPECT_TRUE(request2->browser_initiated());
@@ -566,10 +574,11 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
new network::ResourceResponse);
GetLoaderForNavigationRequest(request2)->CallOnResponseStarted(response,
nullptr);
+ // Commit the navigation.
+ speculative_rfh->SimulateCommitProcessed(navigation_id,
+ true /* was_successful */);
EXPECT_TRUE(speculative_rfh->navigation_request());
EXPECT_FALSE(main_test_rfh()->navigation_request());
-
- // Commit the navigation.
speculative_rfh->SendNavigate(entry_id, true, kUrl2);
// Confirm that the commit corresponds to the new request.
@@ -633,14 +642,6 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
}
- // Have the RenderFrameHost commit the navigation.
- navigation->ReadyToCommit();
- if (AreAllSitesIsolatedForTesting()) {
- EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)->navigation_request());
- } else {
- EXPECT_TRUE(main_test_rfh()->navigation_request());
- }
-
// Commit the navigation.
navigation->Commit();
@@ -700,14 +701,6 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
}
- // Have the RenderFrameHost commit the navigation.
- non_user_initiated_navigation->ReadyToCommit();
- if (AreAllSitesIsolatedForTesting()) {
- EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)->navigation_request());
- } else {
- EXPECT_TRUE(main_test_rfh()->navigation_request());
- }
-
// Commit the navigation.
non_user_initiated_navigation->Commit();
EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
@@ -747,6 +740,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Now receive the beforeUnload ACK from the still ongoing navigation.
main_test_rfh()->SendBeforeUnloadACK(true);
+ int64_t navigation_id = request1->navigation_handle()->GetNavigationId();
TestRenderFrameHost* speculative_rfh = GetSpeculativeRenderFrameHost(node);
ASSERT_TRUE(speculative_rfh);
@@ -755,6 +749,8 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
new network::ResourceResponse);
GetLoaderForNavigationRequest(request2)->CallOnResponseStarted(response,
nullptr);
+ speculative_rfh->SimulateCommitProcessed(navigation_id,
+ true /* was_successful */);
EXPECT_TRUE(speculative_rfh->navigation_request());
EXPECT_FALSE(main_test_rfh()->navigation_request());
@@ -818,14 +814,6 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// Confirm that the first loader got destroyed.
EXPECT_FALSE(loader1);
- // Have the RenderFrameHost commit the navigation.
- navigation2->ReadyToCommit();
- if (AreAllSitesIsolatedForTesting()) {
- EXPECT_TRUE(GetSpeculativeRenderFrameHost(node)->navigation_request());
- } else {
- EXPECT_TRUE(main_test_rfh()->navigation_request());
- }
-
// Commit the navigation.
navigation2->Commit();
EXPECT_EQ(kUrl2, contents()->GetLastCommittedURL());
@@ -893,6 +881,8 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
EXPECT_EQ(SiteInstanceImpl::GetSiteForURL(browser_context(), kUrl),
speculative_rfh->GetSiteInstance()->GetSiteURL());
int32_t site_instance_id = speculative_rfh->GetSiteInstance()->GetId();
+ int64_t navigation_id =
+ node->navigation_request()->navigation_handle()->GetNavigationId();
// Ask Navigator to commit the navigation by simulating a call to
// OnResponseStarted.
@@ -901,10 +891,12 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
GetLoaderForNavigationRequest(node->navigation_request())
->CallOnResponseStarted(response, nullptr);
EXPECT_EQ(speculative_rfh, GetSpeculativeRenderFrameHost(node));
- EXPECT_TRUE(speculative_rfh->navigation_request());
EXPECT_EQ(site_instance_id, speculative_rfh->GetSiteInstance()->GetId());
// Invoke DidCommitProvisionalLoad.
+ speculative_rfh->SimulateCommitProcessed(navigation_id,
+ true /* was_successful */);
+ EXPECT_TRUE(speculative_rfh->navigation_request());
speculative_rfh->SendNavigate(entry_id, true, kUrl);
EXPECT_EQ(site_instance_id, main_test_rfh()->GetSiteInstance()->GetId());
EXPECT_FALSE(GetSpeculativeRenderFrameHost(node));
@@ -940,6 +932,7 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
// It then redirects to yet another site.
NavigationRequest* main_request = node->navigation_request();
+ int64_t navigation_id = main_request->navigation_handle()->GetNavigationId();
ASSERT_TRUE(main_request);
const GURL kUrlRedirect("https://www.google.com/");
GetLoaderForNavigationRequest(main_request)
@@ -962,7 +955,6 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
->CallOnResponseStarted(response, nullptr);
speculative_rfh = GetSpeculativeRenderFrameHost(node);
ASSERT_TRUE(speculative_rfh);
- EXPECT_TRUE(speculative_rfh->navigation_request());
EXPECT_EQ(init_site_instance_id, main_test_rfh()->GetSiteInstance()->GetId());
EXPECT_TRUE(rfh_deleted_observer.deleted());
@@ -976,6 +968,9 @@ TEST_F(NavigatorTestWithBrowserSideNavigation,
EXPECT_NE(site_instance_id, redirect_site_instance_id);
// Invoke DidCommitProvisionalLoad.
+ speculative_rfh->SimulateCommitProcessed(navigation_id,
+ true /* was_successful */);
+ EXPECT_TRUE(speculative_rfh->navigation_request());
speculative_rfh->SendNavigate(entry_id, true, kUrlRedirect);
// Check that the speculative RenderFrameHost was swapped in.
@@ -1309,4 +1304,31 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, FeaturePolicyNewChild) {
ASSERT_FALSE(subframe_feature_policy->GetOriginForTest().unique());
}
+TEST_F(NavigatorTestWithBrowserSideNavigation, TwoNavigationsRacingCommit) {
+ const GURL kUrl1("http://www.chromium.org/");
+ const GURL kUrl2("http://www.chromium.org/Home");
+
+ EXPECT_EQ(0u, contents()->GetMainFrame()->navigation_requests_.size());
+
+ // Have the first navigation reach ReadyToCommit.
+ auto first_navigation =
+ NavigationSimulator::CreateBrowserInitiated(kUrl1, contents());
+ first_navigation->ReadyToCommit();
+ EXPECT_EQ(1u, contents()->GetMainFrame()->navigation_requests_.size());
+
+ // A second navigation starts and reaches ReadyToCommit.
+ auto second_navigation =
+ NavigationSimulator::CreateBrowserInitiated(kUrl1, contents());
+ second_navigation->ReadyToCommit();
+ EXPECT_EQ(2u, contents()->GetMainFrame()->navigation_requests_.size());
+
+ // The first navigation commits.
+ first_navigation->Commit();
+ EXPECT_EQ(1u, contents()->GetMainFrame()->navigation_requests_.size());
+
+ // The second navigation commits.
+ second_navigation->Commit();
+ EXPECT_EQ(0u, contents()->GetMainFrame()->navigation_requests_.size());
+}
+
} // namespace content
diff --git a/chromium/content/browser/frame_host/origin_policy_throttle.cc b/chromium/content/browser/frame_host/origin_policy_throttle.cc
new file mode 100644
index 00000000000..ab137232754
--- /dev/null
+++ b/chromium/content/browser/frame_host/origin_policy_throttle.cc
@@ -0,0 +1,249 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/frame_host/origin_policy_throttle.h"
+
+#include "base/command_line.h"
+#include "base/feature_list.h"
+#include "base/no_destructor.h"
+#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/network_service_instance.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
+#include "net/http/http_request_headers.h"
+#include "services/network/network_context.h"
+#include "services/network/network_service.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+#include "url/origin.h"
+
+namespace {
+// Constants derived from the spec, https://github.com/WICG/origin-policy
+static const char* kDefaultPolicy = "1";
+static const char* kDeletePolicy = "0";
+static const char* kWellKnown = "/.well-known/origin-policy/";
+
+// Maximum policy size (implementation-defined limit in bytes).
+// (Limit copied from network::SimpleURLLoader::kMaxBoundedStringDownloadSize.)
+static const size_t kMaxPolicySize = 1024 * 1024;
+} // namespace
+
+namespace content {
+
+// static
+bool OriginPolicyThrottle::ShouldRequestOriginPolicy(
+ const GURL& url,
+ std::string* request_version) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ if (!base::FeatureList::IsEnabled(features::kOriginPolicy))
+ return false;
+
+ if (!url.SchemeIs(url::kHttpsScheme))
+ return false;
+
+ if (request_version) {
+ const KnownVersionMap& versions = GetKnownVersions();
+ const auto iter = versions.find(url::Origin::Create(url));
+ *request_version =
+ iter == versions.end() ? std::string(kDefaultPolicy) : iter->second;
+ }
+ return true;
+}
+
+// static
+std::unique_ptr<NavigationThrottle>
+OriginPolicyThrottle::MaybeCreateThrottleFor(NavigationHandle* handle) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK(handle);
+
+ // We use presence of the origin policy request header to determine
+ // whether we should create the throttle.
+ if (!handle->GetRequestHeaders().HasHeader(
+ net::HttpRequestHeaders::kSecOriginPolicy))
+ return nullptr;
+
+ DCHECK(base::FeatureList::IsEnabled(features::kOriginPolicy));
+ return base::WrapUnique(new OriginPolicyThrottle(handle));
+}
+
+OriginPolicyThrottle::~OriginPolicyThrottle() {}
+
+NavigationThrottle::ThrottleCheckResult
+OriginPolicyThrottle::WillStartRequest() {
+ // TODO(vogelheim): It might be faster in the common case to optimistically
+ // fetch the policy indicated in the request already here. This would
+ // be faster if the last known version is the current version, but
+ // slower (and wasteful of bandwidth) if the server sends us a new
+ // version. It's unclear how much the upside is, though.
+ return NavigationThrottle::PROCEED;
+}
+
+NavigationThrottle::ThrottleCheckResult
+OriginPolicyThrottle::WillProcessResponse() {
+ DCHECK(navigation_handle());
+
+ // Per spec, Origin Policies are only fetched for https:-requests. So we
+ // should always have HTTP headers at this point.
+ // However, some unit tests generate responses without headers, so we still
+ // need to check.
+ if (!navigation_handle()->GetResponseHeaders())
+ return NavigationThrottle::PROCEED;
+
+ // This determines whether and which policy version applies and fetches it.
+ //
+ // Inputs are the kSecOriginPolicy HTTP header, and the version
+ // we've last seen from this particular origin.
+ //
+ // - header with kDeletePolicy received: No policy applies, and delete the
+ // last-known policy for this origin.
+ // - header received: Use header version and update last-known policy.
+ // - no header received, last-known version exists: Use last-known version
+ // - no header, no last-known version: No policy applies.
+
+ std::string response_version;
+ bool header_found =
+ navigation_handle()->GetResponseHeaders()->GetNormalizedHeader(
+ net::HttpRequestHeaders::kSecOriginPolicy, &response_version);
+
+ url::Origin origin = GetRequestOrigin();
+ DCHECK(!origin.Serialize().empty());
+ DCHECK(!origin.unique());
+ KnownVersionMap& versions = GetKnownVersions();
+ KnownVersionMap::iterator iter = versions.find(origin);
+
+ // Process policy deletion first!
+ if (header_found && response_version == kDeletePolicy) {
+ if (iter != versions.end())
+ versions.erase(iter);
+ return NavigationThrottle::PROCEED;
+ }
+
+ // No policy applies to this request?
+ if (!header_found && iter == versions.end()) {
+ return NavigationThrottle::PROCEED;
+ }
+
+ if (!header_found)
+ response_version = iter->second;
+ else if (iter == versions.end())
+ versions.insert(std::make_pair(origin, response_version));
+ else
+ iter->second = response_version;
+
+ GURL policy = GURL(origin.Serialize() + kWellKnown + response_version);
+ FetchCallback done =
+ base::BindOnce(&OriginPolicyThrottle::OnTheGloriousPolicyHasArrived,
+ base::Unretained(this));
+ FetchPolicy(policy, std::move(done));
+ return NavigationThrottle::DEFER;
+}
+
+const char* OriginPolicyThrottle::GetNameForLogging() {
+ return "OriginPolicyThrottle";
+}
+
+// static
+OriginPolicyThrottle::KnownVersionMap&
+OriginPolicyThrottle::GetKnownVersionsForTesting() {
+ return GetKnownVersions();
+}
+
+OriginPolicyThrottle::OriginPolicyThrottle(NavigationHandle* handle)
+ : NavigationThrottle(handle) {}
+
+OriginPolicyThrottle::KnownVersionMap&
+OriginPolicyThrottle::GetKnownVersions() {
+ static base::NoDestructor<KnownVersionMap> map_instance;
+ return *map_instance;
+}
+
+const url::Origin OriginPolicyThrottle::GetRequestOrigin() {
+ return url::Origin::Create(navigation_handle()->GetURL());
+}
+
+void OriginPolicyThrottle::FetchPolicy(const GURL& url, FetchCallback done) {
+ // Obtain a network context from the network service.
+ network::mojom::NetworkContextParamsPtr context_params =
+ network::mojom::NetworkContextParams::New();
+ content::GetNetworkService()->CreateNetworkContext(
+ mojo::MakeRequest(&network_context_ptr_), std::move(context_params));
+
+ // Create URLLoaderFactory
+ network::mojom::URLLoaderFactoryParamsPtr url_loader_factory_params =
+ network::mojom::URLLoaderFactoryParams::New();
+ url_loader_factory_params->process_id = network::mojom::kBrowserProcessId;
+ url_loader_factory_params->is_corb_enabled = false;
+ url_loader_factory_params->disable_web_security =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableWebSecurity);
+ network_context_ptr_->CreateURLLoaderFactory(
+ mojo::MakeRequest(&url_loader_factory_),
+ std::move(url_loader_factory_params));
+
+ // Create the traffic annotation
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation("origin_policy_loader", R"(
+ semantics {
+ sender: "Origin Policy URL Loader Throttle"
+ description:
+ "Fetches the Origin Policy with a given version from an origin."
+ trigger:
+ "In case the Origin Policy with a given version does not "
+ "exist in the cache, it is fetched from the origin at a "
+ "well-known location."
+ data:
+ "None, the URL itself contains the origin and Origin Policy "
+ "version."
+ destination: OTHER
+ }
+ policy {
+ cookies_allowed: NO
+ setting: "This feature cannot be disabled by settings. Server "
+ "opt-in or out of this mechanism."
+ policy_exception_justification:
+ "Not implemented, considered not useful."})");
+
+ // Create the SimpleURLLoader for the policy.
+ std::unique_ptr<network::ResourceRequest> policy_request =
+ std::make_unique<network::ResourceRequest>();
+ policy_request->url = url;
+ policy_request->fetch_redirect_mode =
+ network::mojom::FetchRedirectMode::kError;
+ url_loader_ = network::SimpleURLLoader::Create(std::move(policy_request),
+ traffic_annotation);
+ url_loader_->SetAllowHttpErrorResults(false);
+
+ // Start the download, and pass the callback for when we're finished.
+ url_loader_->DownloadToString(url_loader_factory_.get(), std::move(done),
+ kMaxPolicySize);
+}
+
+void OriginPolicyThrottle::InjectPolicyForTesting(
+ const std::string& policy_content) {
+ OnTheGloriousPolicyHasArrived(std::make_unique<std::string>(policy_content));
+}
+
+void OriginPolicyThrottle::OnTheGloriousPolicyHasArrived(
+ std::unique_ptr<std::string> policy_content) {
+ // Release resources associated with the loading.
+ url_loader_.reset();
+ url_loader_factory_.reset();
+ network_context_ptr_.reset();
+
+ // Fail hard if the policy could not be loaded.
+ if (!policy_content) {
+ CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
+ return;
+ }
+
+ // TODO(vogelheim): Determine whether we need to parse or sanity check
+ // the policy content at this point.
+
+ static_cast<NavigationHandleImpl*>(navigation_handle())
+ ->set_origin_policy(*policy_content);
+ Resume();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/frame_host/origin_policy_throttle.h b/chromium/content/browser/frame_host/origin_policy_throttle.h
new file mode 100644
index 00000000000..ac200046c8c
--- /dev/null
+++ b/chromium/content/browser/frame_host/origin_policy_throttle.h
@@ -0,0 +1,86 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_FRAME_HOST_ORIGIN_POLICY_THROTTLE_H_
+#define CONTENT_BROWSER_FRAME_HOST_ORIGIN_POLICY_THROTTLE_H_
+
+#include <map>
+#include <string>
+#include "base/gtest_prod_util.h"
+#include "base/macros.h"
+#include "content/public/browser/navigation_throttle.h"
+#include "services/network/public/mojom/network_service.mojom.h"
+
+class GURL;
+
+namespace url {
+class Origin;
+}
+namespace network {
+class SimpleURLLoader;
+} // namespace network
+
+namespace content {
+class NavigationHandle;
+
+// The OriginPolicyThrottle is responsible for deciding whether an origin
+// policy should be fetched, and doing so when that is positive.
+//
+// The intended use is that the navigation request will
+// - call OriginPolicyThrottle::ShouldRequestOriginPolicy to determine whether
+// a policy should be requested and which version, and should add the
+// appropriate SecOriginPolicy: header.
+// - call OriginPolicyThrottle::MaybeCreateThrottleFor a given navigation.
+// This will use presence of the header to decide whether to create a
+// throttle or not.
+class CONTENT_EXPORT OriginPolicyThrottle : public NavigationThrottle {
+ public:
+ // Determine whether to request a policy (or advertise origin policy
+ // support) and which version.
+ // Returns whether the policy header should be sent. It it returns true,
+ // |version| will contain the policy version to use.
+ static bool ShouldRequestOriginPolicy(const GURL& url, std::string* version);
+
+ // Create a throttle (if the request contains the appropriate header.
+ // The throttle will handle fetching of the policy and updating the
+ // navigation request with the result.
+ static std::unique_ptr<NavigationThrottle> MaybeCreateThrottleFor(
+ NavigationHandle* handle);
+
+ ~OriginPolicyThrottle() override;
+
+ ThrottleCheckResult WillStartRequest() override;
+ ThrottleCheckResult WillProcessResponse() override;
+ const char* GetNameForLogging() override;
+
+ using KnownVersionMap = std::map<url::Origin, std::string>;
+ static KnownVersionMap& GetKnownVersionsForTesting();
+
+ void InjectPolicyForTesting(const std::string& policy_content);
+
+ private:
+ using FetchCallback = base::OnceCallback<void(std::unique_ptr<std::string>)>;
+
+ explicit OriginPolicyThrottle(NavigationHandle* handle);
+
+ static KnownVersionMap& GetKnownVersions();
+
+ const url::Origin GetRequestOrigin();
+ void FetchPolicy(const GURL& url, FetchCallback done);
+ void OnTheGloriousPolicyHasArrived(
+ std::unique_ptr<std::string> policy_content);
+
+ // We may need the SimpleURLLoader to download the policy.
+ // The network context and url loader must be kept alive while the load is
+ // ongoing.
+ network::mojom::NetworkContextPtr network_context_ptr_;
+ network::mojom::URLLoaderFactoryPtr url_loader_factory_;
+ std::unique_ptr<network::SimpleURLLoader> url_loader_;
+
+ DISALLOW_COPY_AND_ASSIGN(OriginPolicyThrottle);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_FRAME_HOST_ORIGIN_POLICY_THROTTLE_H_
diff --git a/chromium/content/browser/frame_host/origin_policy_throttle_unittest.cc b/chromium/content/browser/frame_host/origin_policy_throttle_unittest.cc
new file mode 100644
index 00000000000..859a318dfc7
--- /dev/null
+++ b/chromium/content/browser/frame_host/origin_policy_throttle_unittest.cc
@@ -0,0 +1,155 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/frame_host/origin_policy_throttle.h"
+
+#include "base/feature_list.h"
+#include "base/macros.h"
+#include "base/test/scoped_feature_list.h"
+#include "content/browser/frame_host/navigation_handle_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/common/content_features.h"
+#include "content/public/test/test_renderer_host.h"
+#include "net/http/http_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class OriginPolicyThrottleTest : public RenderViewHostTestHarness,
+ public testing::WithParamInterface<bool> {
+ public:
+ void SetUp() override {
+ // Some tests below should be run with the feature en- and disabled, since
+ // they test the feature functionality when enabled and feature
+ // non-funcionality (that is, that the feature is inert) when disabled.
+ // Hence, we run this test in both variants.
+ features_.InitWithFeatureState(features::kOriginPolicy, GetParam());
+
+ RenderViewHostTestHarness::SetUp();
+ OriginPolicyThrottle::GetKnownVersionsForTesting().clear();
+ }
+ void TearDown() override {
+ OriginPolicyThrottle::GetKnownVersionsForTesting().clear();
+ nav_handle_.reset();
+ RenderViewHostTestHarness::TearDown();
+ }
+ bool enabled() {
+ return base::FeatureList::IsEnabled(features::kOriginPolicy);
+ }
+
+ void CreateHandleFor(const GURL& url) {
+ net::HttpRequestHeaders headers;
+ if (OriginPolicyThrottle::ShouldRequestOriginPolicy(url, nullptr))
+ headers.SetHeader(net::HttpRequestHeaders::kSecOriginPolicy, "1");
+
+ // Except for url and headers (which are determined by the test case)
+ // all parameters below are cargo-culted from
+ // NavigationHandleImplTest::CreateNavigationHandle.
+ nav_handle_ = NavigationHandleImpl::Create(
+ url, // url, as requested by caller
+ std::vector<GURL>(), // redirect chain
+ static_cast<WebContentsImpl*>(web_contents())
+ ->GetFrameTree()
+ ->root(), // render_tree_node
+ true, // is_renderer_initialized
+ false, // is_same_document
+ base::TimeTicks::Now(), // navigation_start
+ 0, // pending_nav_entry_id
+ false, // started_from_context_menu
+ CSPDisposition::CHECK, // should_check_main_world_csp
+ false, // is_form_submission
+ nullptr, // navigation_ui_data
+ "GET", // HTTP method
+ headers); // headers, as created above
+ }
+
+ protected:
+ std::unique_ptr<NavigationHandleImpl> nav_handle_;
+ base::test::ScopedFeatureList features_;
+};
+
+INSTANTIATE_TEST_CASE_P(OriginPolicyThrottleTests,
+ OriginPolicyThrottleTest,
+ testing::Bool());
+
+TEST_P(OriginPolicyThrottleTest, ShouldRequestOriginPolicy) {
+ struct {
+ const char* url;
+ bool expect;
+ } test_cases[] = {
+ {"https://example.org/bla", true},
+ {"http://example.org/bla", false},
+ {"file:///etc/passwd", false},
+ };
+
+ for (const auto& test_case : test_cases) {
+ SCOPED_TRACE(testing::Message() << "URL: " << test_case.url);
+ EXPECT_EQ(enabled() && test_case.expect,
+ OriginPolicyThrottle::ShouldRequestOriginPolicy(
+ GURL(test_case.url), nullptr));
+ }
+}
+
+TEST_P(OriginPolicyThrottleTest, ShouldRequestLastKnownVersion) {
+ if (!enabled())
+ return;
+
+ GURL url("https://example.org/bla");
+ EXPECT_TRUE(OriginPolicyThrottle::ShouldRequestOriginPolicy(url, nullptr));
+
+ std::string version;
+
+ OriginPolicyThrottle::ShouldRequestOriginPolicy(url, &version);
+ EXPECT_EQ(version, "1");
+
+ OriginPolicyThrottle::GetKnownVersionsForTesting()[url::Origin::Create(url)] =
+ "abcd";
+ OriginPolicyThrottle::ShouldRequestOriginPolicy(url, &version);
+ EXPECT_EQ(version, "abcd");
+}
+
+TEST_P(OriginPolicyThrottleTest, MaybeCreateThrottleFor) {
+ CreateHandleFor(GURL("https://example.org/bla"));
+ EXPECT_EQ(enabled(),
+ !!OriginPolicyThrottle::MaybeCreateThrottleFor(nav_handle_.get()));
+
+ CreateHandleFor(GURL("http://insecure.org/bla"));
+ EXPECT_FALSE(
+ !!OriginPolicyThrottle::MaybeCreateThrottleFor(nav_handle_.get()));
+}
+
+TEST_P(OriginPolicyThrottleTest, RunRequestEndToEnd) {
+ if (!enabled())
+ return;
+
+ // Create a handle and start the request.
+ CreateHandleFor(GURL("https://example.org/bla"));
+ EXPECT_EQ(NavigationThrottle::PROCEED,
+ nav_handle_->CallWillStartRequestForTesting().action());
+
+ // Fake a response with a policy header. Check whether the navigation
+ // is deferred.
+ const char* headers = "HTTP/1.1 200 OK\nSec-Origin-Policy: policy-1\n\n";
+ EXPECT_EQ(NavigationThrottle::DEFER,
+ nav_handle_
+ ->CallWillProcessResponseForTesting(
+ main_rfh(),
+ net::HttpUtil::AssembleRawHeaders(headers, strlen(headers)))
+ .action());
+ EXPECT_EQ(NavigationHandleImpl::DEFERRING_RESPONSE,
+ nav_handle_->state_for_testing());
+
+ // For the purpose of this unit test we don't care about policy content,
+ // only that it's non-empty. We check whether the throttle will pass it on.
+ const char* policy = "{}";
+ static_cast<OriginPolicyThrottle*>(
+ nav_handle_->GetDeferringThrottleForTesting())
+ ->InjectPolicyForTesting(policy);
+
+ // At the end of the navigation, the navigation handle should have a copy
+ // of the origin policy.
+ EXPECT_EQ(policy, nav_handle_->origin_policy());
+}
+
+} // 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 8ef72144652..63de23c20a9 100644
--- a/chromium/content/browser/frame_host/render_frame_host_android.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_android.cc
@@ -4,6 +4,8 @@
#include "content/browser/frame_host/render_frame_host_android.h"
+#include <utility>
+
#include "base/android/callback_android.h"
#include "base/android/jni_string.h"
#include "base/android/unguessable_token_android.h"
@@ -28,12 +30,12 @@ void OnGetCanonicalUrlForSharing(
const base::android::JavaRef<jobject>& jcallback,
const base::Optional<GURL>& url) {
if (!url) {
- base::android::RunCallbackAndroid(jcallback, ScopedJavaLocalRef<jstring>());
+ base::android::RunObjectCallbackAndroid(jcallback,
+ ScopedJavaLocalRef<jstring>());
return;
}
- base::android::RunCallbackAndroid(
- jcallback, ConvertUTF8ToJavaString(AttachCurrentThread(), url->spec()));
+ base::android::RunStringCallbackAndroid(jcallback, url->spec());
}
} // namespace
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 390bcf09995..26b8eec2bb7 100644
--- a/chromium/content/browser/frame_host/render_frame_host_delegate.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_delegate.cc
@@ -43,11 +43,11 @@ InterstitialPage* RenderFrameHostDelegate::GetAsInterstitialPage() {
void RenderFrameHostDelegate::RequestMediaAccessPermission(
const MediaStreamRequest& request,
- const MediaResponseCallback& callback) {
+ MediaResponseCallback callback) {
LOG(ERROR) << "RenderFrameHostDelegate::RequestMediaAccessPermission: "
<< "Not supported.";
- callback.Run(MediaStreamDevices(), MEDIA_DEVICE_NOT_SUPPORTED,
- std::unique_ptr<MediaStreamUI>());
+ std::move(callback).Run(MediaStreamDevices(), MEDIA_DEVICE_NOT_SUPPORTED,
+ std::unique_ptr<MediaStreamUI>());
}
bool RenderFrameHostDelegate::CheckMediaAccessPermission(
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 cd4a295dfa3..7919ac1e579 100644
--- a/chromium/content/browser/frame_host/render_frame_host_delegate.h
+++ b/chromium/content/browser/frame_host/render_frame_host_delegate.h
@@ -177,9 +177,8 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
// The render frame has requested access to media devices listed in
// |request|, and the client should grant or deny that permission by
// calling |callback|.
- virtual void RequestMediaAccessPermission(
- const MediaStreamRequest& request,
- const MediaResponseCallback& callback);
+ virtual void RequestMediaAccessPermission(const MediaStreamRequest& request,
+ MediaResponseCallback callback);
// Checks if we have permission to access the microphone or camera. Note that
// this does not query the user. |type| must be MEDIA_DEVICE_AUDIO_CAPTURE
@@ -200,7 +199,7 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
// from a render frame, when the accessibility mode has the
// ui::AXMode::kWebContents flag set.
virtual void AccessibilityEventReceived(
- const std::vector<AXEventNotificationDetails>& details) {}
+ const AXEventNotificationDetails& details) {}
virtual void AccessibilityLocationChangesReceived(
const std::vector<AXLocationChangeNotificationDetails>& details) {}
@@ -233,6 +232,10 @@ class CONTENT_EXPORT RenderFrameHostDelegate {
// browser fullscreen.
virtual void ExitFullscreenMode(bool will_cause_resize) {}
+ // Notification that this frame has changed fullscreen state.
+ virtual void FullscreenStateChanged(RenderFrameHost* rfh,
+ bool is_fullscreen) {}
+
// Let the delegate decide whether postMessage should be delivered to
// |target_rfh| from a source frame in the given SiteInstance. This defaults
// to false and overrides the RenderFrameHost's decision if true.
diff --git a/chromium/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc b/chromium/content/browser/frame_host/render_frame_host_feature_policy_unittest.cc
index 687bd02154e..b730cee3bcb 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
@@ -30,7 +30,7 @@ class RenderFrameHostFeaturePolicyTest
static constexpr const char* kOrigin4 = "https://test.com";
static const blink::mojom::FeaturePolicyFeature kDefaultEnabledFeature =
- blink::mojom::FeaturePolicyFeature::kDocumentStreamInsertion;
+ blink::mojom::FeaturePolicyFeature::kDocumentWrite;
static const blink::mojom::FeaturePolicyFeature kDefaultSelfFeature =
blink::mojom::FeaturePolicyFeature::kGeolocation;
@@ -113,7 +113,7 @@ TEST_F(RenderFrameHostFeaturePolicyTest, HeaderPolicy) {
EXPECT_TRUE(parent->IsFeatureEnabled(kDefaultSelfFeature));
EXPECT_TRUE(child->IsFeatureEnabled(kDefaultSelfFeature));
- // Set an empty whitelist in the child to test that the policies combine
+ // Set an empty allowlist in the child to test that the policies combine
// correctly.
RefreshPageAndSetHeaderPolicy(&child, kDefaultSelfFeature,
std::vector<std::string>());
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 cd755cbc3f2..8e5af3e3b9c 100644
--- a/chromium/content/browser/frame_host/render_frame_host_impl.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_impl.cc
@@ -22,6 +22,7 @@
#include "base/metrics/user_metrics.h"
#include "base/numerics/safe_conversions.h"
#include "base/process/kill.h"
+#include "base/stl_util.h"
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
@@ -64,6 +65,7 @@
#include "content/browser/media/media_interface_proxy.h"
#include "content/browser/media/session/media_session_service_impl.h"
#include "content/browser/payments/payment_app_context_impl.h"
+#include "content/browser/permissions/permission_controller_impl.h"
#include "content/browser/permissions/permission_service_context.h"
#include "content/browser/permissions/permission_service_impl.h"
#include "content/browser/presentation/presentation_service_impl.h"
@@ -116,14 +118,15 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_plugin_guest_manager.h"
#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/permission_manager.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host_view.h"
+#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/stream_handle.h"
#include "content/public/browser/webvr_service_provider.h"
#include "content/public/common/bindings_policy.h"
+#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
@@ -134,6 +137,7 @@
#include "content/public/common/service_names.mojom.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
+#include "device/gamepad/gamepad_monitor.h"
#include "device/vr/public/mojom/vr_service.mojom.h"
#include "media/audio/audio_manager.h"
#include "media/base/media_switches.h"
@@ -142,6 +146,7 @@
#include "media/mojo/interfaces/remoting.mojom.h"
#include "media/mojo/services/media_interface_provider.h"
#include "media/mojo/services/media_metrics_provider.h"
+#include "media/mojo/services/video_decode_perf_history.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
@@ -153,12 +158,12 @@
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/network_service.mojom.h"
-#include "services/network/restricted_cookie_manager.h"
#include "services/resource_coordinator/public/cpp/frame_resource_coordinator.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "storage/browser/blob/blob_storage_context.h"
+#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/common/frame/frame_policy.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
@@ -390,17 +395,16 @@ base::Histogram::Sample HashInterfaceNameToHistogramSample(
static_cast<int32_t>(base::HashMetricName(name) & 0x7fffffffull));
}
-} // namespace
-
-RenderFrameHostImpl::PendingNavigation::PendingNavigation(
- const CommonNavigationParams& common_params,
- mojom::BeginNavigationParamsPtr begin_params,
- scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory)
- : common_params(common_params),
- begin_params(std::move(begin_params)),
- blob_url_loader_factory(std::move(blob_url_loader_factory)) {}
+// Set crash keys that will help understand the circumstances of a renderer
+// kill. Note that the commit URL is already reported in a crash key, and
+// additional keys are logged in RenderProcessHostImpl::ShutdownForBadMessage.
+void LogRendererKillCrashKeys(const GURL& site_url) {
+ static auto* site_url_key = base::debug::AllocateCrashKeyString(
+ "current_site_url", base::debug::CrashKeySize::Size64);
+ base::debug::SetCrashKeyString(site_url_key, site_url.spec());
+}
-RenderFrameHostImpl::PendingNavigation::~PendingNavigation() = default;
+} // namespace
class RenderFrameHostImpl::DroppedInterfaceRequestLogger
: public service_manager::mojom::InterfaceProvider {
@@ -436,6 +440,29 @@ class RenderFrameHostImpl::DroppedInterfaceRequestLogger
DISALLOW_COPY_AND_ASSIGN(DroppedInterfaceRequestLogger);
};
+struct PendingNavigation {
+ CommonNavigationParams common_params;
+ mojom::BeginNavigationParamsPtr begin_navigation_params;
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory;
+ mojom::NavigationClientAssociatedPtrInfo navigation_client;
+
+ PendingNavigation(
+ CommonNavigationParams common_params,
+ mojom::BeginNavigationParamsPtr begin_navigation_params,
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client);
+};
+
+PendingNavigation::PendingNavigation(
+ CommonNavigationParams common_params,
+ mojom::BeginNavigationParamsPtr begin_navigation_params,
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client)
+ : common_params(common_params),
+ begin_navigation_params(std::move(begin_navigation_params)),
+ blob_url_loader_factory(std::move(blob_url_loader_factory)),
+ navigation_client(std::move(navigation_client)) {}
+
// static
RenderFrameHost* RenderFrameHost::FromID(int render_process_id,
int render_frame_id) {
@@ -544,9 +571,8 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance,
weak_ptr_factory_(this) {
frame_tree_->AddRenderViewHostRef(render_view_host_);
GetProcess()->AddRoute(routing_id_, this);
- g_routing_id_frame_map.Get().insert(std::make_pair(
- RenderFrameHostID(GetProcess()->GetID(), routing_id_),
- this));
+ g_routing_id_frame_map.Get().emplace(
+ RenderFrameHostID(GetProcess()->GetID(), routing_id_), this);
site_instance_->AddObserver(this);
GetSiteInstance()->IncrementActiveFrameCount();
@@ -681,8 +707,8 @@ RenderFrameHostImpl::~RenderFrameHostImpl() {
// the dtor has run. (It may also be null in tests.)
swapout_event_monitor_timeout_.reset();
- for (const auto& iter : visual_state_callbacks_)
- iter.second.Run(false);
+ for (auto& iter : visual_state_callbacks_)
+ std::move(iter.second).Run(false);
if (render_widget_host_ &&
render_widget_host_->owned_by_render_frame_host()) {
@@ -725,6 +751,14 @@ const base::UnguessableToken& RenderFrameHostImpl::GetOverlayRoutingToken() {
return *overlay_routing_token_;
}
+void RenderFrameHostImpl::DidCommitProvisionalLoadForTesting(
+ std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params,
+ service_manager::mojom::InterfaceProviderRequest
+ interface_provider_request) {
+ DidCommitProvisionalLoad(std::move(params),
+ std::move(interface_provider_request));
+}
+
SiteInstanceImpl* RenderFrameHostImpl::GetSiteInstance() {
return site_instance_.get();
}
@@ -774,6 +808,56 @@ void RenderFrameHostImpl::GetCanonicalUrlForSharing(
}
}
+blink::mojom::PauseSubresourceLoadingHandlePtr
+RenderFrameHostImpl::PauseSubresourceLoading() {
+ DCHECK(frame_);
+ blink::mojom::PauseSubresourceLoadingHandlePtr
+ pause_subresource_loading_handle;
+ GetRemoteInterfaces()->GetInterface(&pause_subresource_loading_handle);
+
+ return pause_subresource_loading_handle;
+}
+
+void RenderFrameHostImpl::ExecuteMediaPlayerActionAtLocation(
+ const gfx::Point& location,
+ const blink::WebMediaPlayerAction& action) {
+ gfx::PointF point_in_view = GetView()->TransformRootPointToViewCoordSpace(
+ gfx::PointF(location.x(), location.y()));
+ Send(new FrameMsg_MediaPlayerActionAt(routing_id_, point_in_view, action));
+}
+
+void RenderFrameHostImpl::CreateNetworkServiceDefaultFactory(
+ network::mojom::URLLoaderFactoryRequest default_factory_request) {
+ network::mojom::URLLoaderFactoryParamsPtr params =
+ network::mojom::URLLoaderFactoryParams::New();
+ params->process_id = GetProcess()->GetID();
+ params->disable_web_security =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableWebSecurity);
+ SiteIsolationPolicy::PopulateURLLoaderFactoryParamsPtrForCORB(params.get());
+
+ auto* context = GetSiteInstance()->GetBrowserContext();
+ GetContentClient()->browser()->WillCreateURLLoaderFactory(
+ context, this, false /* is_navigation */, &default_factory_request);
+ // Keep DevTools proxy lasy, i.e. closest to the network.
+ RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory(
+ this, false /* is_navigation */, false /* is_download */,
+ &default_factory_request);
+ StoragePartitionImpl* storage_partition = static_cast<StoragePartitionImpl*>(
+ BrowserContext::GetStoragePartition(context, GetSiteInstance()));
+ if (g_create_network_factory_callback_for_test.Get().is_null()) {
+ storage_partition->GetNetworkContext()->CreateURLLoaderFactory(
+ std::move(default_factory_request), std::move(params));
+ } else {
+ network::mojom::URLLoaderFactoryPtr original_factory;
+ storage_partition->GetNetworkContext()->CreateURLLoaderFactory(
+ mojo::MakeRequest(&original_factory), std::move(params));
+ g_create_network_factory_callback_for_test.Get().Run(
+ std::move(default_factory_request), GetProcess()->GetID(),
+ original_factory.PassInterface());
+ }
+}
+
gfx::NativeView RenderFrameHostImpl::GetNativeView() {
RenderWidgetHostView* view = render_view_host_->GetWidget()->GetView();
if (!view)
@@ -802,7 +886,7 @@ void RenderFrameHostImpl::ExecuteJavaScript(
Send(new FrameMsg_JavaScriptExecuteRequest(routing_id_,
javascript,
key, true));
- javascript_callbacks_.insert(std::make_pair(key, callback));
+ javascript_callbacks_.emplace(key, callback);
}
void RenderFrameHostImpl::ExecuteJavaScriptForTests(
@@ -818,7 +902,7 @@ void RenderFrameHostImpl::ExecuteJavaScriptForTests(
int key = g_next_javascript_callback_id++;
Send(new FrameMsg_JavaScriptExecuteRequestForTests(routing_id_, javascript,
key, true, false));
- javascript_callbacks_.insert(std::make_pair(key, callback));
+ javascript_callbacks_.emplace(key, callback);
}
@@ -845,7 +929,7 @@ void RenderFrameHostImpl::ExecuteJavaScriptInIsolatedWorld(
if (!callback.is_null()) {
request_reply = true;
key = g_next_javascript_callback_id++;
- javascript_callbacks_.insert(std::make_pair(key, callback));
+ javascript_callbacks_.emplace(key, callback);
}
Send(new FrameMsg_JavaScriptExecuteRequestInIsolatedWorld(
@@ -1007,7 +1091,7 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
OnForwardResourceTimingToParent)
IPC_MESSAGE_HANDLER(FrameHostMsg_TextSurroundingSelectionResponse,
OnTextSurroundingSelectionResponse)
- IPC_MESSAGE_HANDLER(AccessibilityHostMsg_Events, OnAccessibilityEvents)
+ IPC_MESSAGE_HANDLER(AccessibilityHostMsg_EventBundle, OnAccessibilityEvents)
IPC_MESSAGE_HANDLER(AccessibilityHostMsg_LocationChanges,
OnAccessibilityLocationChanges)
IPC_MESSAGE_HANDLER(AccessibilityHostMsg_FindInPageResult,
@@ -1028,8 +1112,8 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) {
OnSerializeAsMHTMLResponse)
IPC_MESSAGE_HANDLER(FrameHostMsg_SelectionChanged, OnSelectionChanged)
IPC_MESSAGE_HANDLER(FrameHostMsg_FocusedNodeChanged, OnFocusedNodeChanged)
- IPC_MESSAGE_HANDLER(FrameHostMsg_SetHasReceivedUserGesture,
- OnSetHasReceivedUserGesture)
+ IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateUserActivationState,
+ OnUpdateUserActivationState)
IPC_MESSAGE_HANDLER(FrameHostMsg_SetHasReceivedUserGestureBeforeNavigation,
OnSetHasReceivedUserGestureBeforeNavigation)
IPC_MESSAGE_HANDLER(FrameHostMsg_ScrollRectToVisibleInParentFrame,
@@ -1210,8 +1294,7 @@ bool RenderFrameHostImpl::SchemeShouldBypassCSP(
// TODO(arthursonzogni): url::GetBypassingCSPScheme() is used instead of the
// blink::SchemeRegistry. It contains 1) but not 2).
const auto& bypassing_schemes = url::GetCSPBypassingSchemes();
- return std::find(bypassing_schemes.begin(), bypassing_schemes.end(),
- scheme) != bypassing_schemes.end();
+ return base::ContainsValue(bypassing_schemes, scheme);
}
mojom::FrameInputHandler* RenderFrameHostImpl::GetFrameInputHandler() {
@@ -1232,7 +1315,7 @@ bool RenderFrameHostImpl::CreateRenderFrame(int proxy_routing_id,
if (!GetProcess()->Init())
return false;
- DCHECK(GetProcess()->HasConnection());
+ DCHECK(GetProcess()->IsInitializedAndNotDead());
service_manager::mojom::InterfaceProviderPtr interface_provider;
BindInterfaceProviderRequest(mojo::MakeRequest(&interface_provider));
@@ -1364,8 +1447,9 @@ void RenderFrameHostImpl::Init() {
if (pending_navigate_) {
frame_tree_node()->navigator()->OnBeginNavigation(
frame_tree_node(), pending_navigate_->common_params,
- std::move(pending_navigate_->begin_params),
- std::move(pending_navigate_->blob_url_loader_factory));
+ std::move(pending_navigate_->begin_navigation_params),
+ std::move(pending_navigate_->blob_url_loader_factory),
+ std::move(pending_navigate_->navigation_client));
pending_navigate_.reset();
}
}
@@ -1551,20 +1635,7 @@ void RenderFrameHostImpl::CancelInitialHistoryLoad() {
NOTIMPLEMENTED();
}
-void RenderFrameHostImpl::OnDocumentOnLoadCompleted(
- FrameMsg_UILoadMetricsReportType::Value report_type,
- base::TimeTicks ui_timestamp) {
- if (report_type == FrameMsg_UILoadMetricsReportType::REPORT_LINK) {
- UMA_HISTOGRAM_CUSTOM_TIMES("Navigation.UI_OnLoadComplete.Link",
- base::TimeTicks::Now() - ui_timestamp,
- base::TimeDelta::FromMilliseconds(10),
- base::TimeDelta::FromMinutes(10), 100);
- } else if (report_type == FrameMsg_UILoadMetricsReportType::REPORT_INTENT) {
- UMA_HISTOGRAM_CUSTOM_TIMES("Navigation.UI_OnLoadComplete.Intent",
- base::TimeTicks::Now() - ui_timestamp,
- base::TimeDelta::FromMilliseconds(10),
- base::TimeDelta::FromMinutes(10), 100);
- }
+void RenderFrameHostImpl::OnDocumentOnLoadCompleted() {
// This message is only sent for top-level frames. TODO(avi): when frame tree
// mirroring works correctly, add a check here to enforce it.
delegate_->DocumentOnLoadCompleted(this);
@@ -1806,6 +1877,7 @@ NavigationHandleImpl* RenderFrameHostImpl::GetNavigationHandle() {
void RenderFrameHostImpl::ResetNavigationRequests() {
navigation_request_.reset();
same_document_navigation_request_.reset();
+ navigation_requests_.clear();
}
void RenderFrameHostImpl::SetNavigationRequest(
@@ -1816,7 +1888,8 @@ void RenderFrameHostImpl::SetNavigationRequest(
same_document_navigation_request_ = std::move(navigation_request);
return;
}
- navigation_request_ = std::move(navigation_request);
+ navigation_requests_[navigation_request->navigation_handle()
+ ->GetNavigationId()] = std::move(navigation_request);
}
void RenderFrameHostImpl::SwapOut(
@@ -1852,6 +1925,10 @@ void RenderFrameHostImpl::SwapOut(
proxy->frame_tree_node()->current_replication_state();
Send(new FrameMsg_SwapOut(routing_id_, proxy->GetRoutingID(), is_loading,
replication_state));
+
+ // Remember that a RenderFrameProxy was created as part of processing the
+ // SwapOut message above.
+ proxy->set_render_frame_proxy_created(true);
}
if (web_ui())
@@ -2188,7 +2265,7 @@ void RenderFrameHostImpl::OnSmartClipDataExtracted(int32_t callback_id,
void RenderFrameHostImpl::OnVisualStateResponse(uint64_t id) {
auto it = visual_state_callbacks_.find(id);
if (it != visual_state_callbacks_.end()) {
- it->second.Run(true);
+ std::move(it->second).Run(true);
visual_state_callbacks_.erase(it);
} else {
NOTREACHED() << "Received script response for unknown request";
@@ -2210,13 +2287,6 @@ void RenderFrameHostImpl::OnRunJavaScriptDialog(
return;
}
- int32_t message_length = static_cast<int32_t>(message.length());
- if (GetParent()) {
- UMA_HISTOGRAM_COUNTS("JSDialogs.CharacterCount.Subframe", message_length);
- } else {
- UMA_HISTOGRAM_COUNTS("JSDialogs.CharacterCount.MainFrame", message_length);
- }
-
// While a JS message dialog is showing, tabs in the same process shouldn't
// process input events.
GetProcess()->SetIgnoreInputEvents(true);
@@ -2324,10 +2394,11 @@ void RenderFrameHostImpl::AllowBindings(int bindings_flags) {
"frame_tree_node", frame_tree_node_->frame_tree_node_id(),
"bindings flags", bindings_flags);
+ int webui_bindings = bindings_flags & kWebUIBindingsPolicyMask;
+
// Ensure we aren't granting WebUI bindings to a process that has already
// been used for non-privileged views.
- if (bindings_flags & BINDINGS_POLICY_WEB_UI &&
- GetProcess()->HasConnection() &&
+ if (webui_bindings && GetProcess()->IsInitializedAndNotDead() &&
!ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
GetProcess()->GetID())) {
// This process has no bindings yet. Make sure it does not have more
@@ -2339,9 +2410,9 @@ void RenderFrameHostImpl::AllowBindings(int bindings_flags) {
return;
}
- if (bindings_flags & BINDINGS_POLICY_WEB_UI) {
+ if (webui_bindings) {
ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
- GetProcess()->GetID());
+ GetProcess()->GetID(), webui_bindings);
}
enabled_bindings_ |= bindings_flags;
@@ -2533,6 +2604,12 @@ void RenderFrameHostImpl::FrameSizeChanged(const gfx::Size& frame_size) {
frame_size_ = frame_size;
}
+void RenderFrameHostImpl::FullscreenStateChanged(bool is_fullscreen) {
+ if (!is_active())
+ return;
+ delegate_->FullscreenStateChanged(this, is_fullscreen);
+}
+
void RenderFrameHostImpl::OnDidBlockFramebust(const GURL& url) {
delegate_->OnDidBlockFramebust(url);
}
@@ -2604,13 +2681,14 @@ RenderWidgetHostViewBase* RenderFrameHostImpl::GetViewForAccessibility() {
}
void RenderFrameHostImpl::OnAccessibilityEvents(
- const std::vector<AccessibilityHostMsg_EventParams>& params,
- int reset_token, int ack_token) {
+ const AccessibilityHostMsg_EventBundleParams& bundle,
+ int reset_token,
+ int ack_token) {
// Don't process this IPC if either we're waiting on a reset and this
// IPC doesn't have the matching token ID, or if we're not waiting on a
// reset but this message includes a reset token.
if (accessibility_reset_token_ != reset_token) {
- Send(new AccessibilityMsg_Events_ACK(routing_id_, ack_token));
+ Send(new AccessibilityMsg_EventBundle_ACK(routing_id_, ack_token));
return;
}
accessibility_reset_token_ = 0;
@@ -2621,29 +2699,27 @@ void RenderFrameHostImpl::OnAccessibilityEvents(
if (accessibility_mode.has_mode(ui::AXMode::kNativeAPIs))
GetOrCreateBrowserAccessibilityManager();
- std::vector<AXEventNotificationDetails> details;
- details.reserve(params.size());
- for (size_t i = 0; i < params.size(); ++i) {
- const AccessibilityHostMsg_EventParams& param = params[i];
- AXEventNotificationDetails detail;
- detail.event_type = param.event_type;
- detail.id = param.id;
- detail.ax_tree_id = GetAXTreeID();
- detail.event_from = param.event_from;
- detail.action_request_id = param.action_request_id;
- if (param.update.has_tree_data) {
- detail.update.has_tree_data = true;
- ax_content_tree_data_ = param.update.tree_data;
- AXContentTreeDataToAXTreeData(&detail.update.tree_data);
+ AXEventNotificationDetails details;
+ details.ax_tree_id = GetAXTreeID();
+ details.events = bundle.events;
+
+ details.updates.resize(bundle.updates.size());
+ for (size_t i = 0; i < bundle.updates.size(); ++i) {
+ const AXContentTreeUpdate& src_update = bundle.updates[i];
+ ui::AXTreeUpdate* dst_update = &details.updates[i];
+ if (src_update.has_tree_data) {
+ dst_update->has_tree_data = true;
+ ax_content_tree_data_ = src_update.tree_data;
+ AXContentTreeDataToAXTreeData(&dst_update->tree_data);
}
- detail.update.root_id = param.update.root_id;
- detail.update.node_id_to_clear = param.update.node_id_to_clear;
- detail.update.nodes.resize(param.update.nodes.size());
- for (size_t j = 0; j < param.update.nodes.size(); ++j) {
- AXContentNodeDataToAXNodeData(param.update.nodes[j],
- &detail.update.nodes[j]);
+ dst_update->root_id = src_update.root_id;
+ dst_update->node_id_to_clear = src_update.node_id_to_clear;
+ dst_update->event_from = src_update.event_from;
+ dst_update->nodes.resize(src_update.nodes.size());
+ for (size_t j = 0; j < src_update.nodes.size(); ++j) {
+ AXContentNodeDataToAXNodeData(src_update.nodes[j],
+ &dst_update->nodes[j]);
}
- details.push_back(detail);
}
if (accessibility_mode.has_mode(ui::AXMode::kNativeAPIs)) {
@@ -2655,31 +2731,36 @@ void RenderFrameHostImpl::OnAccessibilityEvents(
// For testing only.
if (!accessibility_testing_callback_.is_null()) {
- for (size_t i = 0; i < details.size(); i++) {
- const AXEventNotificationDetails& detail = details[i];
- if (static_cast<int>(detail.event_type) < 0)
- continue;
-
+ // Apply tree updates to test tree.
+ for (size_t i = 0; i < details.updates.size(); i++) {
if (!ax_tree_for_testing_) {
if (browser_accessibility_manager_) {
ax_tree_for_testing_.reset(new ui::AXTree(
browser_accessibility_manager_->SnapshotAXTreeForTesting()));
} else {
ax_tree_for_testing_.reset(new ui::AXTree());
- CHECK(ax_tree_for_testing_->Unserialize(detail.update))
+ CHECK(ax_tree_for_testing_->Unserialize(details.updates[i]))
<< ax_tree_for_testing_->error();
}
} else {
- CHECK(ax_tree_for_testing_->Unserialize(detail.update))
+ CHECK(ax_tree_for_testing_->Unserialize(details.updates[i]))
<< ax_tree_for_testing_->error();
}
- accessibility_testing_callback_.Run(this, detail.event_type, detail.id);
+ }
+
+ // Call testing callback functions for each event to fire.
+ for (size_t i = 0; i < details.events.size(); i++) {
+ if (static_cast<int>(details.events[i].event_type) < 0)
+ continue;
+
+ accessibility_testing_callback_.Run(this, details.events[i].event_type,
+ details.events[i].id);
}
}
}
// Always send an ACK or the renderer can be in a bad state.
- Send(new AccessibilityMsg_Events_ACK(routing_id_, ack_token));
+ Send(new AccessibilityMsg_EventBundle_ACK(routing_id_, ack_token));
}
void RenderFrameHostImpl::OnAccessibilityLocationChanges(
@@ -2817,6 +2898,7 @@ void RenderFrameHostImpl::OnEnterFullscreen(
// TODO(alexmos): See if this can use the last committed origin instead.
delegate_->EnterFullscreenMode(GetLastCommittedURL().GetOrigin(), options);
+ delegate_->FullscreenStateChanged(this, true /* is_fullscreen */);
// The previous call might change the fullscreen state. We need to make sure
// the renderer is aware of that, which is done via the resize message.
@@ -2898,7 +2980,6 @@ void RenderFrameHostImpl::OnDidStopLoading() {
was_discarded_ = false;
is_loading_ = false;
- navigation_request_.reset();
// Only inform the FrameTreeNode of a change in load state if the load state
// of this RenderFrameHost is being tracked.
@@ -2945,8 +3026,11 @@ void RenderFrameHostImpl::NotifyUserActivation() {
Send(new FrameMsg_NotifyUserActivation(routing_id_));
}
-void RenderFrameHostImpl::OnSetHasReceivedUserGesture() {
- frame_tree_node_->OnSetHasReceivedUserGesture();
+void RenderFrameHostImpl::OnUpdateUserActivationState(
+ blink::UserActivationUpdateType update_type) {
+ if (!is_active())
+ return;
+ frame_tree_node_->UpdateUserActivationState(update_type);
}
void RenderFrameHostImpl::OnSetHasReceivedUserGestureBeforeNavigation(
@@ -3069,6 +3153,11 @@ void RenderFrameHostImpl::CreateNewWindow(
params->target_url = GURL(url::kAboutBlankURL);
}
+ bool effective_transient_activation_state =
+ params->mimic_user_gesture ||
+ (base::FeatureList::IsEnabled(features::kUserActivationV2) &&
+ frame_tree_node_->HasTransientUserActivation());
+
// Ignore window creation when sent from a frame that's not current or
// created.
bool can_create_window =
@@ -3078,8 +3167,16 @@ void RenderFrameHostImpl::CreateNewWindow(
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);
+ params->disposition, *params->features,
+ effective_transient_activation_state, params->opener_suppressed,
+ &no_javascript_access);
+
+ if (can_create_window) {
+ // Consume activation even w/o User Activation v2, to sync other renderers
+ // with calling renderer.
+ frame_tree_node_->UpdateUserActivationState(
+ blink::UserActivationUpdateType::kConsumeTransientActivation);
+ }
if (!can_create_window) {
std::move(callback).Run(mojom::CreateNewWindowStatus::kIgnore, nullptr);
@@ -3102,18 +3199,10 @@ void RenderFrameHostImpl::CreateNewWindow(
static_cast<DOMStorageContextWrapper*>(
storage_partition->GetDOMStorageContext());
- scoped_refptr<SessionStorageNamespaceImpl> cloned_namespace;
- if (base::FeatureList::IsEnabled(features::kMojoSessionStorage)) {
- // Any cloning should / will happen using the
- // SessionStorageNamespace::Clone in storage_partition_service.mojom.
- cloned_namespace = SessionStorageNamespaceImpl::CloneFrom(
- dom_storage_context, params->session_storage_namespace_id,
- params->clone_from_session_storage_namespace_id);
- } else {
- cloned_namespace = SessionStorageNamespaceImpl::CloneFrom(
- dom_storage_context, params->session_storage_namespace_id,
- params->clone_from_session_storage_namespace_id);
- }
+ scoped_refptr<SessionStorageNamespaceImpl> cloned_namespace =
+ SessionStorageNamespaceImpl::CloneFrom(
+ dom_storage_context, params->session_storage_namespace_id,
+ params->clone_from_session_storage_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
@@ -3127,10 +3216,7 @@ void RenderFrameHostImpl::CreateNewWindow(
if (!params->opener_suppressed && !no_javascript_access) {
render_view_route_id = GetProcess()->GetNextRoutingID();
main_frame_route_id = GetProcess()->GetNextRoutingID();
- // TODO(avi): When RenderViewHostImpl has-a RenderWidgetHostImpl, this
- // should be updated to give the widget a distinct routing ID.
- // https://crbug.com/545684
- main_frame_widget_route_id = render_view_route_id;
+ main_frame_widget_route_id = GetProcess()->GetNextRoutingID();
// Block resource requests until the frame is created, since the HWND might
// be needed if a response ends up creating a plugin. We'll only have a
// single frame at this point. These requests will be resumed either in
@@ -3207,12 +3293,12 @@ void RenderFrameHostImpl::IssueKeepAliveHandle(
keep_alive_handle_factory_->Create(std::move(request));
}
-// TODO(ahemery): Move message checks to a StructTraits file when possible,
-// otherwise mojo bad message reporting.
+// TODO(ahemery): Move checks to mojo bad message reporting.
void RenderFrameHostImpl::BeginNavigation(
const CommonNavigationParams& common_params,
mojom::BeginNavigationParamsPtr begin_params,
- blink::mojom::BlobURLTokenPtr blob_url_token) {
+ blink::mojom::BlobURLTokenPtr blob_url_token,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client) {
if (!is_active())
return;
@@ -3220,6 +3306,8 @@ void RenderFrameHostImpl::BeginNavigation(
"frame_tree_node", frame_tree_node_->frame_tree_node_id(), "url",
common_params.url.possibly_invalid_spec());
+ DCHECK(IsPerNavigationMojoInterfaceEnabled() == navigation_client.is_valid());
+
CommonNavigationParams validated_params = common_params;
GetProcess()->FilterURL(false, &validated_params.url);
if (!validated_params.base_url_for_data_url.is_empty()) {
@@ -3243,6 +3331,12 @@ void RenderFrameHostImpl::BeginNavigation(
return;
}
+ // If the request was for a blob URL, but the validated URL is no longer a
+ // blob URL, reset the blob_url_token to prevent hitting the ReportBadMessage
+ // below, and to make sure we don't incorrectly try to use the blob_url_token.
+ if (common_params.url.SchemeIsBlob() && !validated_params.url.SchemeIsBlob())
+ blob_url_token = nullptr;
+
if (blob_url_token && !validated_params.url.SchemeIsBlob()) {
mojo::ReportBadMessage("Blob URL Token, but not a blob: URL");
return;
@@ -3254,16 +3348,27 @@ void RenderFrameHostImpl::BeginNavigation(
GetSiteInstance()->GetBrowserContext(), std::move(blob_url_token));
}
+ // If the request was for a blob URL, but no blob_url_token was passed in this
+ // is not necessarily an error. Renderer initiated reloads for example are one
+ // situation where a renderer currently doesn't have an easy way of resolving
+ // the blob URL. For those situations resolve the blob URL here, as we don't
+ // care about ordering with other blob URL manipulation anyway.
+ if (blink::BlobUtils::MojoBlobURLsEnabled() &&
+ validated_params.url.SchemeIsBlob() && !blob_url_loader_factory) {
+ blob_url_loader_factory = ChromeBlobStorageContext::URLLoaderFactoryForUrl(
+ GetSiteInstance()->GetBrowserContext(), validated_params.url);
+ }
+
if (waiting_for_init_) {
pending_navigate_ = std::make_unique<PendingNavigation>(
validated_params, std::move(begin_params),
- std::move(blob_url_loader_factory));
+ std::move(blob_url_loader_factory), std::move(navigation_client));
return;
}
frame_tree_node()->navigator()->OnBeginNavigation(
frame_tree_node(), validated_params, std::move(begin_params),
- std::move(blob_url_loader_factory));
+ std::move(blob_url_loader_factory), std::move(navigation_client));
}
void RenderFrameHostImpl::SubresourceResponseStarted(
@@ -3277,30 +3382,6 @@ void RenderFrameHostImpl::ResourceLoadComplete(
delegate_->ResourceLoadComplete(this, std::move(resource_load_info));
}
-namespace {
-
-void GetRestrictedCookieManager(
- RenderFrameHostImpl* render_frame_host_impl,
- network::mojom::RestrictedCookieManagerRequest request) {
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableExperimentalWebPlatformFeatures)) {
- return;
- }
-
- BrowserContext* browser_context =
- render_frame_host_impl->GetProcess()->GetBrowserContext();
- StoragePartition* storage_partition =
- BrowserContext::GetDefaultStoragePartition(browser_context);
- network::mojom::NetworkContext* network_context =
- storage_partition->GetNetworkContext();
- uint32_t render_process_id = render_frame_host_impl->GetProcess()->GetID();
- uint32_t render_frame_id = render_frame_host_impl->GetRoutingID();
- network_context->GetRestrictedCookieManager(
- std::move(request), render_process_id, render_frame_id);
-}
-
-} // anonymous namespace
-
void RenderFrameHostImpl::RegisterMojoInterfaces() {
#if !defined(OS_ANDROID)
// The default (no-op) implementation of InstalledAppProvider. On Android, the
@@ -3308,14 +3389,14 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
registry_->AddInterface(base::Bind(&InstalledAppProviderImplDefault::Create));
#endif // !defined(OS_ANDROID)
- PermissionManager* permission_manager =
- GetProcess()->GetBrowserContext()->GetPermissionManager();
-
+ PermissionControllerImpl* permission_controller =
+ PermissionControllerImpl::FromBrowserContext(
+ GetProcess()->GetBrowserContext());
if (delegate_) {
auto* geolocation_context = delegate_->GetGeolocationContext();
- if (geolocation_context && permission_manager) {
+ if (geolocation_context) {
geolocation_service_.reset(new GeolocationServiceImpl(
- geolocation_context, permission_manager, this));
+ geolocation_context, permission_controller, this));
// NOTE: Both the |interface_registry_| and |geolocation_service_| are
// owned by |this|, so their destruction will be triggered together.
// |interface_registry_| is declared after |geolocation_service_|, so it
@@ -3374,6 +3455,8 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
registry_->AddInterface(base::Bind(&SharedWorkerConnectorImpl::Create,
process_->GetID(), routing_id_));
+ registry_->AddInterface(base::BindRepeating(&device::GamepadMonitor::Create));
+
registry_->AddInterface<device::mojom::VRService>(base::Bind(
&WebvrServiceProvider::BindWebvrService, base::Unretained(this)));
@@ -3437,22 +3520,23 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
}
#endif // !defined(OS_ANDROID)
- if (permission_manager) {
- sensor_provider_proxy_.reset(
- new SensorProviderProxyImpl(permission_manager, this));
- registry_->AddInterface(
- base::Bind(&SensorProviderProxyImpl::Bind,
- base::Unretained(sensor_provider_proxy_.get())));
+ sensor_provider_proxy_.reset(
+ new SensorProviderProxyImpl(permission_controller, this));
+ registry_->AddInterface(
+ base::Bind(&SensorProviderProxyImpl::Bind,
+ base::Unretained(sensor_provider_proxy_.get())));
+
+ // Only save decode stats when BrowserContext provides a VideoPerfHistory.
+ // Off-the-record contexts will internally use an ephemeral history DB.
+ media::VideoDecodePerfHistory::SaveCallback save_stats_cb;
+ if (GetSiteInstance()->GetBrowserContext()->GetVideoDecodePerfHistory()) {
+ save_stats_cb = GetSiteInstance()
+ ->GetBrowserContext()
+ ->GetVideoDecodePerfHistory()
+ ->GetSaveCallback();
}
-
registry_->AddInterface(base::BindRepeating(
- &media::MediaMetricsProvider::Create,
- // Only save decode stats when on-the-record.
- GetSiteInstance()->GetBrowserContext()->IsOffTheRecord()
- ? nullptr
- : GetSiteInstance()
- ->GetBrowserContext()
- ->GetVideoDecodePerfHistory()));
+ &media::MediaMetricsProvider::Create, std::move(save_stats_cb)));
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
cc::switches::kEnableGpuBenchmarking)) {
@@ -3460,37 +3544,14 @@ void RenderFrameHostImpl::RegisterMojoInterfaces() {
base::Bind(&InputInjectorImpl::Create, weak_ptr_factory_.GetWeakPtr()));
}
- registry_->AddInterface(
- base::BindRepeating(GetRestrictedCookieManager, base::Unretained(this)));
-
// TODO(crbug.com/775792): Move to RendererInterfaceBinders.
registry_->AddInterface(base::BindRepeating(
&QuotaDispatcherHost::CreateForFrame, GetProcess(), routing_id_));
registry_->AddInterface(
- base::BindRepeating(
- SpeechRecognitionDispatcherHost::Create, GetProcess()->GetID(),
- routing_id_,
- base::WrapRefCounted(
- GetProcess()->GetStoragePartition()->GetURLRequestContext())),
+ base::BindRepeating(SpeechRecognitionDispatcherHost::Create,
+ GetProcess()->GetID(), routing_id_),
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
-
- if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- StoragePartitionImpl* storage_partition =
- static_cast<StoragePartitionImpl*>(BrowserContext::GetStoragePartition(
- GetSiteInstance()->GetBrowserContext(), GetSiteInstance()));
- // TODO(https://crbug.com/813479): Investigate why we need to explicitly
- // specify task runner for BrowserThread::IO here.
- // Bind calls to the BindRegistry should come on to the IO thread by
- // default, but it looks we need this in browser tests (but not in full
- // chrome build), i.e. in content/browser/loader/prefetch_browsertest.cc.
- registry_->AddInterface(
- base::BindRepeating(
- &PrefetchURLLoaderService::ConnectToService,
- base::RetainedRef(storage_partition->GetPrefetchURLLoaderService()),
- frame_tree_node_->frame_tree_node_id()),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
- }
}
void RenderFrameHostImpl::ResetWaitingState() {
@@ -3554,14 +3615,13 @@ void RenderFrameHostImpl::NavigateToInterstitialURL(const GURL& data_url) {
CommonNavigationParams common_params(
data_url, Referrer(), ui::PAGE_TRANSITION_LINK,
FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT, false, false,
- base::TimeTicks::Now(), FrameMsg_UILoadMetricsReportType::NO_REPORT,
GURL(), GURL(), PREVIEWS_OFF, base::TimeTicks::Now(), "GET", nullptr,
base::Optional<SourceLocation>(),
CSPDisposition::CHECK /* should_check_main_world_csp */,
false /* started_from_context_menu */, false /* has_user_gesture */,
std::vector<ContentSecurityPolicy>() /* initiator_csp */,
CSPSource() /* initiator_self_source */);
- CommitNavigation(nullptr, network::mojom::URLLoaderClientEndpointsPtr(),
+ CommitNavigation(0, nullptr, network::mojom::URLLoaderClientEndpointsPtr(),
common_params, RequestNavigationParams(), false,
base::nullopt, base::nullopt /* subresource_overrides */,
base::UnguessableToken::Create() /* not traced */);
@@ -3829,6 +3889,7 @@ void RenderFrameHostImpl::SendJavaScriptDialogReply(
}
void RenderFrameHostImpl::CommitNavigation(
+ int64_t navigation_id,
network::ResourceResponse* response,
network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
const CommonNavigationParams& common_params,
@@ -3880,9 +3941,6 @@ void RenderFrameHostImpl::CommitNavigation(
// however only do this for cross-document navigations, because the
// alternative would be redundant effort.
network::mojom::URLLoaderFactoryPtrInfo default_factory_info;
- StoragePartitionImpl* storage_partition =
- static_cast<StoragePartitionImpl*>(BrowserContext::GetStoragePartition(
- browser_context, GetSiteInstance()));
if (subresource_loader_params &&
subresource_loader_params->loader_factory_info.is_valid()) {
// If the caller has supplied a default URLLoaderFactory override (for
@@ -3892,12 +3950,16 @@ void RenderFrameHostImpl::CommitNavigation(
} else {
std::string scheme = common_params.url.scheme();
const auto& schemes = URLDataManagerBackend::GetWebUISchemes();
- if (std::find(schemes.begin(), schemes.end(), scheme) != schemes.end()) {
+ if (base::ContainsValue(schemes, scheme)) {
network::mojom::URLLoaderFactoryPtr factory_for_webui =
CreateWebUIURLLoaderBinding(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.
+ // If the renderer has webui bindings, then don't give it access to
+ // network loader for security reasons.
+ // http://crbug.com/829412: make an exception for a small whitelist
+ // of WebUIs that need to be fixed to not make network requests in JS.
+ if ((enabled_bindings_ & kWebUIBindingsPolicyMask) &&
+ !GetContentClient()->browser()->IsWebUIAllowedToMakeNetworkRequests(
+ url::Origin::Create(common_params.url.GetOrigin()))) {
default_factory_info = factory_for_webui.PassInterface();
} else {
// This is a webui scheme that doesn't have webui bindings. Give it
@@ -3918,12 +3980,6 @@ void RenderFrameHostImpl::CommitNavigation(
DCHECK(default_factory_info);
subresource_loader_factories->default_factory_info() =
std::move(default_factory_info);
- // Everyone gets a blob loader.
- network::mojom::URLLoaderFactoryPtrInfo blob_factory_info;
- storage_partition->GetBlobURLLoaderFactory()->HandleRequest(
- mojo::MakeRequest(&blob_factory_info));
- subresource_loader_factories->factories_info().emplace(
- url::kBlobScheme, std::move(blob_factory_info));
non_network_url_loader_factories_.clear();
@@ -3963,7 +4019,7 @@ void RenderFrameHostImpl::CommitNavigation(
network::mojom::URLLoaderFactoryPtrInfo factory_proxy_info;
auto factory_request = mojo::MakeRequest(&factory_proxy_info);
GetContentClient()->browser()->WillCreateURLLoaderFactory(
- this, false /* is_navigation */, &factory_request);
+ browser_context, this, false /* is_navigation */, &factory_request);
// Keep DevTools proxy lasy, i.e. closest to the network.
RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory(
this, false /* is_navigation */, false /* is_download */,
@@ -4004,22 +4060,61 @@ void RenderFrameHostImpl::CommitNavigation(
}
}
- GetNavigationControl()->CommitNavigation(
- head, common_params, request_params,
- std::move(url_loader_client_endpoints),
- std::move(subresource_loader_factories),
- std::move(subresource_overrides), std::move(controller),
- devtools_navigation_token);
+ network::mojom::URLLoaderFactoryPtr prefetch_loader_factory;
+ if (subresource_loader_factories) {
+ SaveSubresourceFactories(std::move(subresource_loader_factories));
+
+ // Also set-up URLLoaderFactory for prefetch using the same loader
+ // factories. TODO(kinuko): Consider setting this up only when prefetch
+ // is used. Currently we have this here to make sure we have non-racy
+ // situation (https://crbug.com/849929).
+ DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
+ auto* storage_partition = static_cast<StoragePartitionImpl*>(
+ BrowserContext::GetStoragePartition(
+ GetSiteInstance()->GetBrowserContext(), GetSiteInstance()));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&PrefetchURLLoaderService::GetFactory,
+ storage_partition->GetPrefetchURLLoaderService(),
+ mojo::MakeRequest(&prefetch_loader_factory),
+ frame_tree_node_->frame_tree_node_id(),
+ CloneSubresourceFactories()));
+ }
+
+ auto find_request = navigation_requests_.find(navigation_id);
+ NavigationRequest* request = find_request != navigation_requests_.end()
+ ? find_request->second.get()
+ : nullptr;
+
+ if (IsPerNavigationMojoInterfaceEnabled() && navigation_request_ &&
+ navigation_request_->GetCommitNavigationClient()) {
+ navigation_request_->GetCommitNavigationClient()->CommitNavigation(
+ head, common_params, request_params,
+ std::move(url_loader_client_endpoints), CloneSubresourceFactories(),
+ std::move(subresource_overrides), std::move(controller),
+ std::move(prefetch_loader_factory), devtools_navigation_token);
+ } else {
+ GetNavigationControl()->CommitNavigation(
+ head, common_params, request_params,
+ std::move(url_loader_client_endpoints), CloneSubresourceFactories(),
+ std::move(subresource_overrides), std::move(controller),
+ std::move(prefetch_loader_factory), devtools_navigation_token,
+ request ? base::BindOnce(
+ &RenderFrameHostImpl::OnCrossDocumentCommitProcessed,
+ base::Unretained(this), navigation_id)
+ : content::mojom::FrameNavigationControl::
+ CommitNavigationCallback());
+ }
// |remote_object| is an associated interface ptr, so calls can't be made on
// it until its request endpoint is sent. Now that the request endpoint was
- // sent, it can be used, so add it to ServiceWorkerHandle.
+ // sent, it can be used, so add it to ServiceWorkerObjectHost.
if (remote_object.is_valid()) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
- &ServiceWorkerHandle::AddRemoteObjectPtrAndUpdateState,
- subresource_loader_params->controller_service_worker_handle,
+ &ServiceWorkerObjectHost::AddRemoteObjectPtrAndUpdateState,
+ subresource_loader_params->controller_service_worker_object_host,
std::move(remote_object), sent_state));
}
@@ -4032,6 +4127,7 @@ void RenderFrameHostImpl::CommitNavigation(
}
void RenderFrameHostImpl::FailedNavigation(
+ int64_t navigation_id,
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
bool has_stale_copy_in_cache,
@@ -4058,15 +4154,29 @@ void RenderFrameHostImpl::FailedNavigation(
std::move(default_factory_info),
std::map<std::string, network::mojom::URLLoaderFactoryPtrInfo>());
}
-
- GetNavigationControl()->CommitFailedNavigation(
- common_params, request_params, has_stale_copy_in_cache, error_code,
- error_page_content, std::move(subresource_loader_factories));
+ SaveSubresourceFactories(std::move(subresource_loader_factories));
+
+ auto find_request = navigation_requests_.find(navigation_id);
+ NavigationRequest* request = find_request != navigation_requests_.end()
+ ? find_request->second.get()
+ : nullptr;
+ if (IsPerNavigationMojoInterfaceEnabled() && request &&
+ request->GetCommitNavigationClient()) {
+ request->GetCommitNavigationClient()->CommitFailedNavigation(
+ common_params, request_params, has_stale_copy_in_cache, error_code,
+ error_page_content, CloneSubresourceFactories());
+ } else {
+ GetNavigationControl()->CommitFailedNavigation(
+ common_params, request_params, has_stale_copy_in_cache, error_code,
+ error_page_content, CloneSubresourceFactories(),
+ base::BindOnce(&RenderFrameHostImpl::OnCrossDocumentCommitProcessed,
+ base::Unretained(this), navigation_id));
+ }
// An error page is expected to commit, hence why is_loading_ is set to true.
is_loading_ = true;
- DCHECK(GetNavigationHandle() &&
- GetNavigationHandle()->GetNetErrorCode() != net::OK);
+ DCHECK(request && request->navigation_handle() &&
+ request->navigation_handle()->GetNetErrorCode() != net::OK);
}
void RenderFrameHostImpl::HandleRendererDebugURL(const GURL& url) {
@@ -4155,6 +4265,12 @@ bool RenderFrameHostImpl::UpdatePendingWebUI(const GURL& dest_url,
// Reset the pending WebUI as from this point it will certainly not be reused.
ClearPendingWebUI();
+ // If error page isolation is enabled and this RenderFrameHost is going to
+ // commit an error page, there is no reason to create WebUI and give the
+ // process any bindings.
+ if (GetSiteInstance()->GetSiteURL() == GURL(kUnreachableWebDataURL))
+ return true;
+
// If this navigation is not to a WebUI, skip directly to bindings work.
if (new_web_ui_type != WebUI::kNoWebUI) {
if (new_web_ui_type == web_ui_type_) {
@@ -4238,7 +4354,8 @@ RenderFrameHostImpl::GetMojoImageDownloader() {
const blink::mojom::FindInPageAssociatedPtr&
RenderFrameHostImpl::GetFindInPage() {
- if (!find_in_page_)
+ if (!find_in_page_ || !find_in_page_.is_bound() ||
+ find_in_page_.encountered_error())
GetRemoteAssociatedInterfaces()->GetInterface(&find_in_page_);
return find_in_page_;
}
@@ -4338,8 +4455,7 @@ void RenderFrameHostImpl::RequestAXTreeSnapshot(AXTreeSnapshotCallback callback,
int callback_id = next_id++;
Send(new AccessibilityMsg_SnapshotTree(routing_id_, callback_id,
ax_mode.mode()));
- ax_tree_snapshot_callbacks_.insert(
- std::make_pair(callback_id, std::move(callback)));
+ ax_tree_snapshot_callbacks_.emplace(callback_id, std::move(callback));
}
void RenderFrameHostImpl::SetAccessibilityCallbackForTesting(
@@ -4354,18 +4470,16 @@ void RenderFrameHostImpl::UpdateAXTreeData() {
return;
}
- std::vector<AXEventNotificationDetails> details;
- details.reserve(1U);
AXEventNotificationDetails detail;
detail.ax_tree_id = GetAXTreeID();
- detail.update.has_tree_data = true;
- AXContentTreeDataToAXTreeData(&detail.update.tree_data);
- details.push_back(detail);
+ detail.updates.resize(1);
+ detail.updates[0].has_tree_data = true;
+ AXContentTreeDataToAXTreeData(&detail.updates[0].tree_data);
if (browser_accessibility_manager_)
- browser_accessibility_manager_->OnAccessibilityEvents(details);
+ browser_accessibility_manager_->OnAccessibilityEvents(detail);
- delegate_->AccessibilityEventReceived(details);
+ delegate_->AccessibilityEventReceived(detail);
}
void RenderFrameHostImpl::SetTextTrackSettings(
@@ -4403,15 +4517,16 @@ void RenderFrameHostImpl::ActivateFindInPageResultForAccessibility(
}
void RenderFrameHostImpl::InsertVisualStateCallback(
- const VisualStateCallback& callback) {
+ VisualStateCallback callback) {
static uint64_t next_id = 1;
uint64_t key = next_id++;
Send(new FrameMsg_VisualStateRequest(routing_id_, key));
- visual_state_callbacks_.insert(std::make_pair(key, callback));
+ visual_state_callbacks_.emplace(key, std::move(callback));
}
bool RenderFrameHostImpl::IsRenderFrameLive() {
- bool is_live = GetProcess()->HasConnection() && render_frame_created_;
+ bool is_live =
+ GetProcess()->IsInitializedAndNotDead() && render_frame_created_;
// Sanity check: the RenderView should always be live if the RenderFrame is.
DCHECK(!is_live || render_view_host_->IsRenderViewLive());
@@ -4504,9 +4619,9 @@ void RenderFrameHostImpl::UpdatePermissionsForNavigation(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params) {
// Browser plugin guests are not allowed to navigate outside web-safe schemes,
- // so do not grant them the ability to request additional URLs.
+ // so do not grant them the ability to commit additional URLs.
if (!GetProcess()->IsForGuestsOnly()) {
- ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL(
+ ChildProcessSecurityPolicyImpl::GetInstance()->GrantCommitURL(
GetProcess()->GetID(), common_params.url);
if (common_params.url.SchemeIs(url::kDataScheme) &&
!common_params.base_url_for_data_url.is_empty()) {
@@ -4514,7 +4629,7 @@ void RenderFrameHostImpl::UpdatePermissionsForNavigation(
// grant access to the base URL. This allows file: and other unexpected
// schemes to be accepted at commit time and during CORS checks (e.g., for
// font requests).
- ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL(
+ ChildProcessSecurityPolicyImpl::GetInstance()->GrantCommitURL(
GetProcess()->GetID(), common_params.base_url_for_data_url);
}
}
@@ -4553,47 +4668,37 @@ void RenderFrameHostImpl::UpdateSubresourceLoaderFactories() {
std::make_unique<URLLoaderFactoryBundleInfo>();
subresource_loader_factories->default_factory_info() =
std::move(default_factory_info);
+ SaveSubresourceFactories(std::move(subresource_loader_factories));
GetNavigationControl()->UpdateSubresourceLoaderFactories(
- std::move(subresource_loader_factories));
+ CloneSubresourceFactories());
+}
+
+std::set<int> RenderFrameHostImpl::GetNavigationEntryIdsPendingCommit() {
+ std::set<int> result;
+ if (navigation_request_)
+ result.insert(navigation_request_->nav_entry_id());
+ for (auto const& requests : navigation_requests_)
+ result.insert(requests.second->nav_entry_id());
+ return result;
}
void RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryAndObserve(
network::mojom::URLLoaderFactoryRequest default_factory_request) {
- network::mojom::URLLoaderFactoryParamsPtr params =
- network::mojom::URLLoaderFactoryParams::New();
- params->process_id = GetProcess()->GetID();
- // TODO(lukasza): https://crbug.com/792546: Start using CORB.
- params->is_corb_enabled = false;
- network::mojom::URLLoaderFactoryParamsPtr params_for_error_monitoring =
- params->Clone();
-
- auto* context = GetSiteInstance()->GetBrowserContext();
- GetContentClient()->browser()->WillCreateURLLoaderFactory(
- this, false /* is_navigation */, &default_factory_request);
- // Keep DevTools proxy lasy, i.e. closest to the network.
- RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory(
- this, false /* is_navigation */, false /* is_download */,
- &default_factory_request);
- StoragePartitionImpl* storage_partition = static_cast<StoragePartitionImpl*>(
- BrowserContext::GetStoragePartition(context, GetSiteInstance()));
- if (g_create_network_factory_callback_for_test.Get().is_null()) {
- storage_partition->GetNetworkContext()->CreateURLLoaderFactory(
- std::move(default_factory_request), std::move(params));
- } else {
- network::mojom::URLLoaderFactoryPtr original_factory;
- storage_partition->GetNetworkContext()->CreateURLLoaderFactory(
- mojo::MakeRequest(&original_factory), std::move(params));
- g_create_network_factory_callback_for_test.Get().Run(
- std::move(default_factory_request), GetProcess()->GetID(),
- original_factory.PassInterface());
- }
+ CreateNetworkServiceDefaultFactory(std::move(default_factory_request));
// Add connection error observer when Network Service is running
// out-of-process.
- if (IsOutOfProcessNetworkService()) {
+ if (IsOutOfProcessNetworkService() &&
+ (!network_service_connection_error_handler_holder_ ||
+ network_service_connection_error_handler_holder_.encountered_error())) {
+ StoragePartition* storage_partition = BrowserContext::GetStoragePartition(
+ GetSiteInstance()->GetBrowserContext(), GetSiteInstance());
+ network::mojom::URLLoaderFactoryParamsPtr params =
+ network::mojom::URLLoaderFactoryParams::New();
+ params->process_id = GetProcess()->GetID();
storage_partition->GetNetworkContext()->CreateURLLoaderFactory(
mojo::MakeRequest(&network_service_connection_error_handler_holder_),
- std::move(params_for_error_monitoring));
+ std::move(params));
network_service_connection_error_handler_holder_
.set_connection_error_handler(base::BindOnce(
&RenderFrameHostImpl::UpdateSubresourceLoaderFactories,
@@ -4838,11 +4943,16 @@ void RenderFrameHostImpl::BindMediaInterfaceFactoryRequest(
void RenderFrameHostImpl::CreateWebSocket(
network::mojom::WebSocketRequest request) {
+ network::mojom::AuthenticationHandlerPtr auth_handler;
+ GetContentClient()->browser()->WillCreateWebSocket(this, &request,
+ &auth_handler);
+
// This is to support usage of WebSockets in cases in which there is an
// associated RenderFrame. This is important for showing the correct security
// state of the page and also honoring user override of bad certificates.
- WebSocketManager::CreateWebSocket(process_->GetID(), routing_id_,
- last_committed_origin_, std::move(request));
+ WebSocketManager::CreateWebSocket(
+ process_->GetID(), routing_id_, last_committed_origin_,
+ std::move(auth_handler), std::move(request));
}
void RenderFrameHostImpl::CreateDedicatedWorkerHostFactory(
@@ -4882,7 +4992,7 @@ void RenderFrameHostImpl::BindPresentationServiceRequest(
#if !defined(OS_ANDROID)
void RenderFrameHostImpl::BindAuthenticatorRequest(
- webauth::mojom::AuthenticatorRequest request) {
+ blink::mojom::AuthenticatorRequest request) {
if (!authenticator_impl_)
authenticator_impl_.reset(new AuthenticatorImpl(this));
@@ -4965,7 +5075,8 @@ RenderFrameHostImpl::TakeNavigationHandleForCommit(
if (navigation_handle && navigation_handle->GetURL() == params.url) {
std::unique_ptr<NavigationHandleImpl> result_navigation_handle =
navigation_request()->TakeNavigationHandle();
- navigation_request_.reset();
+ if (!IsPerNavigationMojoInterfaceEnabled())
+ navigation_request_.reset();
return result_navigation_handle;
}
@@ -5151,11 +5262,38 @@ bool RenderFrameHostImpl::ValidateDidCommitParams(
FrameHostMsg_DidCommitProvisionalLoad_Params* validated_params) {
RenderProcessHost* process = GetProcess();
+ // Error pages may sometimes commit a URL in the wrong process, which requires
+ // an exception for the CanCommitURL checks. This is ok as long as the origin
+ // is unique.
+ // TODO(creis): Kill the renderer if it claims an error page has a non-unique
+ // origin.
+ bool is_permitted_error_page = false;
+ if (validated_params->origin.unique()) {
+ if (SiteIsolationPolicy::IsErrorPageIsolationEnabled(
+ frame_tree_node_->IsMainFrame())) {
+ // With error page isolation, any URL can commit in an error page process.
+ if (GetSiteInstance()->GetSiteURL() ==
+ GURL(content::kUnreachableWebDataURL)) {
+ is_permitted_error_page = true;
+ }
+ } else {
+ // Without error page isolation, a blocked navigation is expected to
+ // commit in the old renderer process. This may be true for subframe
+ // navigations even when error page isolation is enabled for main frames.
+ if (GetNavigationHandle() && GetNavigationHandle()->GetNetErrorCode() ==
+ net::ERR_BLOCKED_BY_CLIENT) {
+ is_permitted_error_page = true;
+ }
+ }
+ }
+
// Attempts to commit certain off-limits URL should be caught more strictly
// than our FilterURL checks. If a renderer violates this policy, it
// should be killed.
- if (!CanCommitURL(validated_params->url)) {
+ if (!is_permitted_error_page && !CanCommitURL(validated_params->url)) {
VLOG(1) << "Blocked URL " << validated_params->url.spec();
+ LogRendererKillCrashKeys(GetSiteInstance()->GetSiteURL());
+
// Kills the process.
bad_message::ReceivedBadMessage(process,
bad_message::RFH_CAN_COMMIT_URL_BLOCKED);
@@ -5166,6 +5304,9 @@ bool RenderFrameHostImpl::ValidateDidCommitParams(
// be allowed to commit in this RenderFrameHost.
if (!CanCommitOrigin(validated_params->origin, validated_params->url)) {
DEBUG_ALIAS_FOR_ORIGIN(origin_debug_alias, validated_params->origin);
+ LogRendererKillCrashKeys(GetSiteInstance()->GetSiteURL());
+
+ // Kills the process.
bad_message::ReceivedBadMessage(process,
bad_message::RFH_INVALID_ORIGIN_ON_COMMIT);
return false;
@@ -5203,22 +5344,6 @@ bool RenderFrameHostImpl::ValidateDidCommitParams(
return true;
}
-void RenderFrameHostImpl::UMACommitReport(
- FrameMsg_UILoadMetricsReportType::Value report_type,
- const base::TimeTicks& ui_timestamp) {
- if (report_type == FrameMsg_UILoadMetricsReportType::REPORT_LINK) {
- UMA_HISTOGRAM_CUSTOM_TIMES("Navigation.UI_OnCommitProvisionalLoad.Link",
- base::TimeTicks::Now() - ui_timestamp,
- base::TimeDelta::FromMilliseconds(10),
- base::TimeDelta::FromMinutes(10), 100);
- } else if (report_type == FrameMsg_UILoadMetricsReportType::REPORT_INTENT) {
- UMA_HISTOGRAM_CUSTOM_TIMES("Navigation.UI_OnCommitProvisionalLoad.Intent",
- base::TimeTicks::Now() - ui_timestamp,
- base::TimeDelta::FromMilliseconds(10),
- base::TimeDelta::FromMinutes(10), 100);
- }
-}
-
void RenderFrameHostImpl::UpdateSiteURL(const GURL& url,
bool url_is_unreachable) {
if (url_is_unreachable || delegate_->GetAsInterstitialPage()) {
@@ -5235,25 +5360,15 @@ bool RenderFrameHostImpl::DidCommitNavigationInternal(
DCHECK_EQ(ui::PageTransitionIsMainFrame(validated_params->transition),
!GetParent());
- UMACommitReport(validated_params->report_type,
- validated_params->ui_timestamp);
-
if (!ValidateDidCommitParams(validated_params))
return false;
- if (!navigation_request_) {
- // The browser has not been notified about the start of the
- // load in this renderer yet (e.g., for same-document navigations that start
- // in the renderer). Do it now.
- // TODO(ahemery): This should never be true for cross-document navigation
- // apart from race conditions. Move to same navigation specific code when
- // the full mojo interface is in place.
- // (https://bugs.chromium.org/p/chromium/issues/detail?id=784904)
- if (!is_loading()) {
- bool was_loading = frame_tree_node()->frame_tree()->IsLoading();
- is_loading_ = true;
- frame_tree_node()->DidStartLoading(true, was_loading);
- }
+ // A racy DidStopLoading IPC might have reset the loading state that was set
+ // to true in CommitNavigation. Set it to true now.
+ if (!is_loading()) {
+ bool was_loading = frame_tree_node()->frame_tree()->IsLoading();
+ is_loading_ = true;
+ frame_tree_node()->DidStartLoading(true, was_loading);
}
if (navigation_request_)
@@ -5275,6 +5390,8 @@ bool RenderFrameHostImpl::DidCommitNavigationInternal(
frame_tree_node()->navigator()->DidNavigate(this, *validated_params,
std::move(navigation_handle),
is_same_document_navigation);
+ if (IsPerNavigationMojoInterfaceEnabled() && !is_same_document_navigation)
+ navigation_request_.reset();
return true;
}
@@ -5298,10 +5415,49 @@ void RenderFrameHostImpl::OnSameDocumentCommitProcessed(
}
if (result == blink::mojom::CommitResult::Aborted) {
- // Note: if the commit was successful, navigation_handle_ is reset in
+ // Note: if the commit was successful, navigation_request_ is reset in
// DidCommitProvisionalLoad.
same_document_navigation_request_.reset();
}
}
+void RenderFrameHostImpl::OnCrossDocumentCommitProcessed(
+ int64_t navigation_id,
+ blink::mojom::CommitResult result) {
+ DCHECK_NE(blink::mojom::CommitResult::RestartCrossDocument, result);
+ if (result == blink::mojom::CommitResult::Ok) {
+ // The navigation will soon be committed. Move it out of the map to the
+ // NavigationRequest that is about to commit.
+ auto find_request = navigation_requests_.find(navigation_id);
+ if (find_request != navigation_requests_.end()) {
+ navigation_request_ = std::move(find_request->second);
+ } else {
+ NOTREACHED();
+ }
+ }
+ // Remove the requests from the list of NavigationRequests waiting to commit.
+ navigation_requests_.erase(navigation_id);
+}
+
+void RenderFrameHostImpl::SaveSubresourceFactories(
+ std::unique_ptr<URLLoaderFactoryBundleInfo> bundle_info) {
+ // CHECK for https://crbug.com/849929.
+ CHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService) ||
+ bundle_info);
+ subresource_loader_factories_bundle_ = nullptr;
+ if (bundle_info) {
+ subresource_loader_factories_bundle_ =
+ base::MakeRefCounted<URLLoaderFactoryBundle>(std::move(bundle_info));
+ }
+}
+
+std::unique_ptr<URLLoaderFactoryBundleInfo>
+RenderFrameHostImpl::CloneSubresourceFactories() {
+ if (subresource_loader_factories_bundle_) {
+ return base::WrapUnique(static_cast<URLLoaderFactoryBundleInfo*>(
+ subresource_loader_factories_bundle_->Clone().release()));
+ }
+ return nullptr;
+}
+
} // 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 e5c6b19d148..6c6f78fec35 100644
--- a/chromium/content/browser/frame_host/render_frame_host_impl.h
+++ b/chromium/content/browser/frame_host/render_frame_host_impl.h
@@ -63,6 +63,7 @@
#include "services/service_manager/public/mojom/interface_provider.mojom.h"
#include "services/viz/public/interfaces/hit_test/input_target_client.mojom.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
+#include "third_party/blink/public/common/frame/user_activation_update_type.h"
#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h"
#include "third_party/blink/public/platform/dedicated_worker_factory.mojom.h"
#include "third_party/blink/public/platform/modules/bluetooth/web_bluetooth.mojom.h"
@@ -86,7 +87,7 @@
#endif
class GURL;
-struct AccessibilityHostMsg_EventParams;
+struct AccessibilityHostMsg_EventBundleParams;
struct AccessibilityHostMsg_FindInPageResultParams;
struct AccessibilityHostMsg_LocationChangeParams;
struct FrameHostMsg_DidCommitProvisionalLoad_Params;
@@ -144,6 +145,7 @@ struct CommonNavigationParams;
struct ContextMenuParams;
struct FileChooserParams;
struct FrameOwnerProperties;
+struct PendingNavigation;
struct RequestNavigationParams;
struct ResourceTimingInfo;
struct SubresourceLoaderParams;
@@ -216,7 +218,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
void ExecuteJavaScriptWithUserGestureForTests(
const base::string16& javascript) override;
void ActivateFindInPageResultForAccessibility(int request_id) override;
- void InsertVisualStateCallback(const VisualStateCallback& callback) override;
+ void InsertVisualStateCallback(VisualStateCallback callback) override;
void CopyImageAt(int x, int y) override;
void SaveImageAt(int x, int y) override;
RenderViewHost* GetRenderViewHost() override;
@@ -240,6 +242,13 @@ class CONTENT_EXPORT RenderFrameHostImpl
blink::WebSuddenTerminationDisablerType disabler_type) override;
bool IsFeatureEnabled(blink::mojom::FeaturePolicyFeature feature) override;
void ViewSource() override;
+ blink::mojom::PauseSubresourceLoadingHandlePtr PauseSubresourceLoading()
+ override;
+ void ExecuteMediaPlayerActionAtLocation(
+ const gfx::Point&,
+ const blink::WebMediaPlayerAction& action) override;
+ void CreateNetworkServiceDefaultFactory(
+ network::mojom::URLLoaderFactoryRequest default_factory_request) override;
// IPC::Sender
bool Send(IPC::Message* msg) override;
@@ -573,7 +582,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
// |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.
+ // TODO(clamy): Pass the NavigationRequest directly to this function when
+ // interstitials have been refactored to no longer call CommitNavigation
+ // without a NavigationRequest.
void CommitNavigation(
+ int64_t navigation_id,
network::ResourceResponse* response,
network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
const CommonNavigationParams& common_params,
@@ -586,7 +599,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
// Indicates that a navigation failed and that this RenderFrame should display
// an error page.
- void FailedNavigation(const CommonNavigationParams& common_params,
+ void FailedNavigation(int64_t navigation_id,
+ const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
bool has_stale_copy_in_cache,
int error_code,
@@ -745,6 +759,23 @@ class CONTENT_EXPORT RenderFrameHostImpl
// for unload handler processing.
void SetSubframeUnloadTimeoutForTesting(const base::TimeDelta& timeout);
+ bool received_post_message_from_non_descendant() const {
+ return received_post_message_from_non_descendant_;
+ }
+
+ void did_receive_post_message_from_non_descendant() {
+ received_post_message_from_non_descendant_ = true;
+ }
+
+ // Returns the list of NavigationEntry ids corresponding to NavigationRequests
+ // waiting to commit in this RenderFrameHost.
+ std::set<int> GetNavigationEntryIdsPendingCommit();
+
+ void DidCommitProvisionalLoadForTesting(
+ std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params,
+ service_manager::mojom::InterfaceProviderRequest
+ interface_provider_request);
+
protected:
friend class RenderFrameHostFactory;
@@ -768,6 +799,8 @@ class CONTENT_EXPORT RenderFrameHostImpl
friend class TestRenderFrameHost;
friend class TestRenderViewHost;
+ FRIEND_TEST_ALL_PREFIXES(NavigatorTestWithBrowserSideNavigation,
+ TwoNavigationsRacingCommit);
FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBeforeUnloadBrowserTest,
SubframeShowsDialogWhenMainFrameNavigates);
FRIEND_TEST_ALL_PREFIXES(RenderFrameHostImplBeforeUnloadBrowserTest,
@@ -800,6 +833,10 @@ class CONTENT_EXPORT RenderFrameHostImpl
ActiveSandboxFlagsRetainedAfterSwapOut);
FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest,
LastCommittedURLRetainedAfterSwapOut);
+ FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest,
+ RenderFrameProxyNotRecreatedDuringProcessShutdown);
+ FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest,
+ SwapOutACKArrivesPriorToProcessShutdownRequest);
FRIEND_TEST_ALL_PREFIXES(SecurityExploitBrowserTest,
AttemptDuplicateRenderViewHost);
@@ -813,9 +850,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
void OnDetach();
void OnFrameFocused();
void OnOpenURL(const FrameHostMsg_OpenURL_Params& params);
- void OnDocumentOnLoadCompleted(
- FrameMsg_UILoadMetricsReportType::Value report_type,
- base::TimeTicks ui_timestamp);
+ void OnDocumentOnLoadCompleted();
void OnDidStartProvisionalLoad(
const GURL& url,
const std::vector<GURL>& redirect_chain,
@@ -858,12 +893,13 @@ class CONTENT_EXPORT RenderFrameHostImpl
void OnUpdateTitle(const base::string16& title,
blink::WebTextDirection title_direction);
void OnDidBlockFramebust(const GURL& url);
+ // Only used with PerNavigationMojoInterface disabled.
void OnAbortNavigation();
void OnForwardResourceTimingToParent(
const ResourceTimingInfo& resource_timing);
void OnDispatchLoad();
void OnAccessibilityEvents(
- const std::vector<AccessibilityHostMsg_EventParams>& params,
+ const AccessibilityHostMsg_EventBundleParams& params,
int reset_token,
int ack_token);
void OnAccessibilityLocationChanges(
@@ -897,7 +933,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
const gfx::Range& range);
void OnFocusedNodeChanged(bool is_editable_element,
const gfx::Rect& bounds_in_frame_widget);
- void OnSetHasReceivedUserGesture();
+ void OnUpdateUserActivationState(blink::UserActivationUpdateType update_type);
void OnSetHasReceivedUserGestureBeforeNavigation(bool value);
void OnScrollRectToVisibleInParentFrame(
const gfx::Rect& rect_to_scroll,
@@ -937,9 +973,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
void DidCommitSameDocumentNavigation(
std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
validated_params) override;
- void BeginNavigation(const CommonNavigationParams& common_params,
- mojom::BeginNavigationParamsPtr begin_params,
- blink::mojom::BlobURLTokenPtr blob_url_token) override;
+ void BeginNavigation(
+ const CommonNavigationParams& common_params,
+ mojom::BeginNavigationParamsPtr begin_params,
+ blink::mojom::BlobURLTokenPtr blob_url_token,
+ mojom::NavigationClientAssociatedPtrInfo navigation_client) override;
void SubresourceResponseStarted(const GURL& url,
net::CertStatus cert_status) override;
void ResourceLoadComplete(
@@ -955,6 +993,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
void CancelInitialHistoryLoad() override;
void UpdateEncoding(const std::string& encoding) override;
void FrameSizeChanged(const gfx::Size& frame_size) override;
+ void FullscreenStateChanged(bool is_fullscreen) override;
// Registers Mojo interfaces that this frame host makes available.
void RegisterMojoInterfaces();
@@ -1078,7 +1117,7 @@ class CONTENT_EXPORT RenderFrameHostImpl
blink::mojom::PresentationServiceRequest request);
#if !defined(OS_ANDROID)
- void BindAuthenticatorRequest(webauth::mojom::AuthenticatorRequest request);
+ void BindAuthenticatorRequest(blink::mojom::AuthenticatorRequest request);
#endif
// service_manager::mojom::InterfaceProvider:
@@ -1171,11 +1210,11 @@ class CONTENT_EXPORT RenderFrameHostImpl
// local roots which are under this frame and their first ancestor which is a
// local root is either this frame or this frame's local root. For instance,
// in a frame tree such as:
- // A0
- // / | \
- // B A1 E
- // / / \ \
- // D A2 C F
+ // A0 //
+ // / | \ //
+ // B A1 E //
+ // / / \ \ //
+ // D A2 C F //
// RFHs at nodes B, E, D, C, and F are all local roots in the given frame tree
// under the root at A0, but only B, C, and E are considered immediate local
// roots of A0. Note that this will exclude any speculative or pending RFHs.
@@ -1193,11 +1232,6 @@ class CONTENT_EXPORT RenderFrameHostImpl
bool ValidateDidCommitParams(
FrameHostMsg_DidCommitProvisionalLoad_Params* validated_params);
- // Utility function that does UMA reporting for link click or intent to
- // commit timings depending on |report_type|.
- void UMACommitReport(FrameMsg_UILoadMetricsReportType::Value report_type,
- const base::TimeTicks& ui_timestamp);
-
// Updates the site url if the navigation was successful and the page is not
// an interstitial.
void UpdateSiteURL(const GURL& url, bool url_is_unreachable);
@@ -1217,6 +1251,17 @@ class CONTENT_EXPORT RenderFrameHostImpl
bool should_replace_current_entry,
blink::mojom::CommitResult result);
+ // Called by the renderer process when it is done processing a cross-document
+ // commit request.
+ void OnCrossDocumentCommitProcessed(int64_t navigation_id,
+ blink::mojom::CommitResult result);
+
+ // Saves and clones URLLoaderFactoryBundleInfo for subresource loading.
+ // Must be called every time subresource_factories_bundle is updated.
+ void SaveSubresourceFactories(
+ std::unique_ptr<URLLoaderFactoryBundleInfo> bundle_info);
+ std::unique_ptr<URLLoaderFactoryBundleInfo> CloneSubresourceFactories();
+
// 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
@@ -1350,6 +1395,12 @@ class CONTENT_EXPORT RenderFrameHostImpl
// relevant NavigationEntry.
int nav_entry_id_;
+ // Tracks if a frame has been influenced by post message from
+ // non-descendant frames. Useful for determining if silently reloading a
+ // crashed frame is safe. Post messages from descendants to not matter for
+ // this decision since they will be reloaded as well.
+ bool received_post_message_from_non_descendant_ = false;
+
// Used to swap out or shut down this RFH when the unload event is taking too
// long to execute, depending on the number of active frames in the
// SiteInstance. May be null in tests.
@@ -1423,10 +1474,18 @@ class CONTENT_EXPORT RenderFrameHostImpl
std::unique_ptr<resource_coordinator::FrameResourceCoordinator>
frame_resource_coordinator_;
- // Holds a NavigationRequest while waiting for the navigation it is tracking
- // to commit. This NavigationRequest is for a cross-document navigation.
+ // Holds a NavigationRequest when it's about to commit, ie. after
+ // OnCrossDocumentCommitProcessed has returned a positive answer for this
+ // NavigationRequest but before receiving DidCommitProvisionalLoad. This
+ // NavigationRequest is for a cross-document navigation.
std::unique_ptr<NavigationRequest> navigation_request_;
+ // Holds the cross-document NavigationRequests that are waiting to commit,
+ // indexed by IDs. These are navigations that have passed ReadyToCommit stage
+ // and are waiting for the renderer to send back a matching
+ // OnCrossDocumentCommitProcessed.
+ std::map<int64_t, std::unique_ptr<NavigationRequest>> navigation_requests_;
+
// Holds a same-document NavigationRequest while waiting for the navigation it
// is tracking to commit.
std::unique_ptr<NavigationRequest> same_document_navigation_request_;
@@ -1477,16 +1536,6 @@ class CONTENT_EXPORT RenderFrameHostImpl
// If true then this frame's document has a focused element which is editable.
bool has_focused_editable_element_;
- struct PendingNavigation {
- PendingNavigation(
- const CommonNavigationParams& common_params,
- mojom::BeginNavigationParamsPtr begin_params,
- scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory);
- ~PendingNavigation();
- CommonNavigationParams common_params;
- mojom::BeginNavigationParamsPtr begin_params;
- scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory;
- };
std::unique_ptr<PendingNavigation> pending_navigate_;
// A collection of non-network URLLoaderFactory implementations which are used
@@ -1495,6 +1544,10 @@ class CONTENT_EXPORT RenderFrameHostImpl
ContentBrowserClient::NonNetworkURLLoaderFactoryMap
non_network_url_loader_factories_;
+ // A bundle of subresource loader factories used by this frame.
+ // A clone of this bundle is sent to the renderer process.
+ scoped_refptr<URLLoaderFactoryBundle> subresource_loader_factories_bundle_;
+
// Bitfield for renderer-side state that blocks fast shutdown of the frame.
blink::WebSuddenTerminationDisablerType
sudden_termination_disabler_types_enabled_ = 0;
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 cd82082fbb7..87210e4c20e 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
@@ -10,7 +10,7 @@
#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
#include "base/test/test_timeouts.h"
#include "build/build_config.h"
@@ -1036,7 +1036,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, POSTNavigation) {
EXPECT_TRUE(shell()
->web_contents()
->GetController()
- .GetActiveEntry()
+ .GetLastCommittedEntry()
->GetHasPostData());
// Reload and verify the form was submitted.
@@ -1349,7 +1349,7 @@ class ScopedFakeInterfaceProviderRequestInjector
}
protected:
- void WillDispatchDidCommitProvisionalLoad(
+ bool WillDispatchDidCommitProvisionalLoad(
RenderFrameHost* render_frame_host,
::FrameHostMsg_DidCommitProvisionalLoad_Params* params,
service_manager::mojom::InterfaceProviderRequest*
@@ -1357,6 +1357,7 @@ class ScopedFakeInterfaceProviderRequestInjector
url_of_last_commit_ = params->url;
original_request_of_last_commit_ = std::move(*interface_provider_request);
*interface_provider_request = std::move(next_fake_request_);
+ return true;
}
private:
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 b682235b0f8..872e4609c94 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager.cc
+++ b/chromium/content/browser/frame_host/render_frame_host_manager.cc
@@ -58,6 +58,16 @@
namespace content {
+namespace {
+
+bool IsDataOrAbout(const GURL& url) {
+ GURL about_srcdoc(content::kAboutSrcDocURL);
+ return url == about_srcdoc || url.IsAboutBlank() ||
+ url.scheme() == url::kDataScheme;
+}
+
+} // namespace
+
RenderFrameHostManager::RenderFrameHostManager(
FrameTreeNode* frame_tree_node,
RenderFrameHostDelegate* render_frame_delegate,
@@ -92,11 +102,6 @@ void RenderFrameHostManager::Init(SiteInstance* site_instance,
int32_t widget_routing_id,
bool renderer_initiated_creation) {
DCHECK(site_instance);
- // TODO(avi): While RenderViewHostImpl is-a RenderWidgetHostImpl, this must
- // hold true to avoid having two RenderWidgetHosts for the top-level frame.
- // https://crbug.com/545684
- DCHECK(!frame_tree_node_->IsMainFrame() ||
- view_routing_id == widget_routing_id);
SetRenderFrameHost(CreateRenderFrameHost(site_instance, view_routing_id,
frame_routing_id, widget_routing_id,
delegate_->IsHidden(),
@@ -395,9 +400,6 @@ void RenderFrameHostManager::SwapOutOldFrame(
// Tell the old RenderFrameHost to swap out and be replaced by the proxy.
old_render_frame_host->SwapOut(proxy, true);
- // SwapOut creates a RenderFrameProxy, so set the proxy to be initialized.
- proxy->set_render_frame_proxy_created(true);
-
// |old_render_frame_host| will be deleted when its SwapOut ACK is received,
// or when the timer times out, or when the RFHM itself is deleted (whichever
// comes first).
@@ -521,11 +523,16 @@ RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
// 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_->GetNavigationHandle() &&
- request.from_begin_navigation()) {
- frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded(
- speculative_render_frame_host_->GetNavigationHandle()
- ->pending_nav_entry_id());
+ // Note: We query all NavigationEntry IDs fom the RenderFrameHost, however
+ // at most one call to DiscardPendingEntryIfNeeded will succeed. Since we
+ // don't know which of the entries is the pending one, we have to try them
+ // all.
+ // TODO(clamy): Clean this up.
+ if (request.from_begin_navigation()) {
+ std::set<int> ids = speculative_render_frame_host_
+ ->GetNavigationEntryIdsPendingCommit();
+ for (int id : ids)
+ frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded(id);
}
DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost());
}
@@ -559,12 +566,16 @@ RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
// 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_->GetNavigationHandle() &&
- request.from_begin_navigation()) {
- frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded(
- speculative_render_frame_host_->GetNavigationHandle()
- ->pending_nav_entry_id());
+ // Note: We query all NavigationEntry IDs fom the RenderFrameHost, however
+ // at most one call to DiscardPendingEntryIfNeeded will succeed. Since we
+ // don't know which of the entries is the pending one, we have to try them
+ // all.
+ // TODO(clamy): Clean this up.
+ if (request.from_begin_navigation() && speculative_render_frame_host_) {
+ std::set<int> ids = speculative_render_frame_host_
+ ->GetNavigationEntryIdsPendingCommit();
+ for (int id : ids)
+ frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded(id);
}
// If a previous speculative RenderFrameHost didn't exist or if its
@@ -644,7 +655,7 @@ RenderFrameHostImpl* RenderFrameHostManager::GetFrameHostForNavigation(
// removed once the process manager moves away from NotificationService.
// See https://crbug.com/462682.
delegate_->NotifyMainFrameSwappedFromRenderManager(
- nullptr, render_frame_host_->render_view_host());
+ nullptr, render_frame_host_.get());
}
}
@@ -817,10 +828,11 @@ void RenderFrameHostManager::CancelPendingIfNecessary(
}
}
-void RenderFrameHostManager::OnSetHasReceivedUserGesture() {
+void RenderFrameHostManager::UpdateUserActivationState(
+ blink::UserActivationUpdateType update_type) {
for (const auto& pair : proxy_hosts_) {
- pair.second->Send(
- new FrameMsg_SetHasReceivedUserGesture(pair.second->GetRoutingID()));
+ pair.second->Send(new FrameMsg_UpdateUserActivationState(
+ pair.second->GetRoutingID(), update_type));
}
}
@@ -873,13 +885,23 @@ bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation(
bool current_is_view_source_mode,
SiteInstance* new_site_instance,
const GURL& new_effective_url,
- bool new_is_view_source_mode) const {
+ bool new_is_view_source_mode,
+ bool is_failure) const {
// A subframe must stay in the same BrowsingInstance as its parent.
// TODO(nasko): Ensure that SiteInstance swap is still triggered for subframes
// in the cases covered by the rest of the checks in this method.
if (!frame_tree_node_->IsMainFrame())
return false;
+ // If the navigation has resulted in an error page, do not swap
+ // BrowsingInstance and keep the error page in a related SiteInstance. If
+ // later a reload of this navigation is successful, it will correctly
+ // create a new BrowsingInstance.
+ if (is_failure && SiteIsolationPolicy::IsErrorPageIsolationEnabled(
+ frame_tree_node_->IsMainFrame())) {
+ return false;
+ }
+
// If new_entry already has a SiteInstance, assume it is correct. We only
// need to force a swap if it is in a different BrowsingInstance.
if (new_site_instance) {
@@ -1018,11 +1040,9 @@ RenderFrameHostManager::GetSiteInstanceForNavigation(
current_entry->IsViewSourceMode() : dest_is_view_source_mode;
bool force_swap = ShouldSwapBrowsingInstancesForNavigation(
- current_effective_url,
- current_is_view_source_mode,
- dest_instance,
+ current_effective_url, current_is_view_source_mode, dest_instance,
SiteInstanceImpl::GetEffectiveURL(browser_context, dest_url),
- dest_is_view_source_mode);
+ dest_is_view_source_mode, is_failure);
SiteInstanceDescriptor new_instance_descriptor =
SiteInstanceDescriptor(current_instance);
if (ShouldTransitionCrossSite() || force_swap) {
@@ -1093,8 +1113,8 @@ void RenderFrameHostManager::InitializeRenderFrameIfNecessary(
// RenderFrameHostManager are completely initialized. This should be
// removed once the process manager moves away from NotificationService.
// See https://crbug.com/462682.
- delegate_->NotifyMainFrameSwappedFromRenderManager(
- nullptr, render_frame_host_->render_view_host());
+ delegate_->NotifyMainFrameSwappedFromRenderManager(nullptr,
+ render_frame_host_.get());
}
RenderFrameHostManager::SiteInstanceDescriptor
@@ -1115,14 +1135,39 @@ RenderFrameHostManager::DetermineSiteInstanceForURL(
delegate_->GetControllerForRenderManager();
BrowserContext* browser_context = controller.GetBrowserContext();
- // If the entry has an instance already we should use it.
+ // If the entry has an instance already we should use it, unless it is no
+ // longer suitable.
if (dest_instance) {
- // If we are forcing a swap, this should be in a different BrowsingInstance.
- if (force_browsing_instance_swap) {
- CHECK(!dest_instance->IsRelatedSiteInstance(
- render_frame_host_->GetSiteInstance()));
+ // When error page isolation is enabled, don't reuse |dest_instance| if it's
+ // an error page SiteInstance, but the navigation will no longer fail.
+ // Similarly, don't reuse |dest_instance| if it's not an error page
+ // SiteInstance but the navigation will fail and actually need an error page
+ // SiteInstance.
+ // Note: The later call to HasWrongProcessForURL does not have context about
+ // error page navigaions, so we cannot rely on it to return correct value
+ // when error pages are involved.
+ if (!SiteIsolationPolicy::IsErrorPageIsolationEnabled(
+ frame_tree_node_->IsMainFrame()) ||
+ ((dest_instance->GetSiteURL() == GURL(kUnreachableWebDataURL)) ==
+ is_failure)) {
+ // TODO(nasko,creis): The check whether data: or about: URLs are allowed
+ // to commit in the current process should be in HasWrongProcessForURL.
+ // However, making this change has further implications and needs more
+ // investigation of what behavior changes. For now, use a conservative
+ // approach and explicitly check before calling HasWrongProcessForURL.
+ SiteInstanceImpl* dest_instance_impl =
+ static_cast<SiteInstanceImpl*>(dest_instance);
+ if (IsDataOrAbout(dest_url) ||
+ !dest_instance_impl->HasWrongProcessForURL(dest_url)) {
+ // If we are forcing a swap, this should be in a different
+ // BrowsingInstance.
+ if (force_browsing_instance_swap) {
+ CHECK(!dest_instance->IsRelatedSiteInstance(
+ render_frame_host_->GetSiteInstance()));
+ }
+ return SiteInstanceDescriptor(dest_instance);
+ }
}
- return SiteInstanceDescriptor(dest_instance);
}
// If a swap is required, we need to force the SiteInstance AND
@@ -1263,11 +1308,7 @@ RenderFrameHostManager::DetermineSiteInstanceForURL(
// redirect arbitary requests to those URLs using webRequest or
// declarativeWebRequest API. For these cases, the content isn't controlled
// by the source SiteInstance, so it need not use it.
- GURL about_srcdoc(content::kAboutSrcDocURL);
- bool dest_is_data_or_about = dest_url == about_srcdoc ||
- dest_url.IsAboutBlank() ||
- dest_url.scheme() == url::kDataScheme;
- if (source_instance && dest_is_data_or_about && !was_server_redirect)
+ if (source_instance && IsDataOrAbout(dest_url) && !was_server_redirect)
return SiteInstanceDescriptor(source_instance);
// Use the current SiteInstance for same site navigations.
@@ -1641,7 +1682,8 @@ RenderFrameHostManager::CreateRenderFrameHost(
RenderViewHostImpl* render_view_host = nullptr;
if (frame_tree_node_->IsMainFrame()) {
render_view_host = frame_tree->CreateRenderViewHost(
- site_instance, view_routing_id, frame_routing_id, false, hidden);
+ site_instance, view_routing_id, frame_routing_id, widget_routing_id,
+ false, hidden);
// TODO(avi): It's a bit bizarre that this logic lives here instead of in
// CreateRenderFrame(). It turns out that FrameTree::CreateRenderViewHost
// doesn't /always/ create a new RenderViewHost. It first tries to find an
@@ -1652,8 +1694,9 @@ RenderFrameHostManager::CreateRenderFrameHost(
// if just ignored, should be an easy cleanup once RenderViewHostImpl has-a
// RenderWidgetHostImpl. https://crbug.com/545684
if (view_routing_id == MSG_ROUTING_NONE) {
- widget_routing_id = render_view_host->GetRoutingID();
+ widget_routing_id = render_view_host->GetWidget()->GetRoutingID();
} else {
+ DCHECK_NE(view_routing_id, widget_routing_id);
DCHECK_EQ(view_routing_id, render_view_host->GetRoutingID());
}
} else {
@@ -1718,6 +1761,10 @@ std::unique_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
// A RenderFrame in a different process from its parent RenderFrame
// requires a RenderWidget for input/layout/painting.
+ //
+ // TODO(ajwong): When RVH no longer owns a RWH, this logic should be
+ // simplified as the decision to create a RWH will be centralized here.
+ // https://crbug.com/545684
if (frame_tree_node_->parent() &&
frame_tree_node_->parent()->current_frame_host()->GetSiteInstance() !=
instance) {
@@ -1796,7 +1843,8 @@ int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) {
if (!render_view_host) {
CHECK(frame_tree_node_->IsMainFrame());
render_view_host = frame_tree_node_->frame_tree()->CreateRenderViewHost(
- instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, true, true);
+ instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, MSG_ROUTING_NONE, true,
+ true);
}
proxy = CreateRenderFrameProxyHost(instance, render_view_host);
@@ -1936,7 +1984,7 @@ RenderFrameHostManager::GetSiteInstanceForNavigationRequest(
// allowed to swap processes.
no_renderer_swap_allowed |= !CanSubframeSwapProcess(
request.common_params().url, request.source_site_instance(),
- request.dest_site_instance(), was_server_redirect);
+ request.dest_site_instance());
}
if (no_renderer_swap_allowed)
@@ -2508,8 +2556,7 @@ void RenderFrameHostManager::SendPageMessage(IPC::Message* msg,
bool RenderFrameHostManager::CanSubframeSwapProcess(
const GURL& dest_url,
SiteInstance* source_instance,
- SiteInstance* dest_instance,
- bool was_server_redirect) {
+ SiteInstance* dest_instance) {
// On renderer-initiated navigations, when the frame initiating the navigation
// and the frame being navigated differ, |source_instance| is set to the
// SiteInstance of the initiating frame. |dest_instance| is present on session
@@ -2526,22 +2573,25 @@ bool RenderFrameHostManager::CanSubframeSwapProcess(
resolved_url = dest_instance->GetSiteURL();
} else {
// If there is no SiteInstance this unique origin can be associated with,
- // there are two cases:
- // (1) If there was a server redirect, allow a process swap. Normally,
- // redirects to data: or about: URLs are disallowed as
+ // then check whether it is safe to put into the parent frame's process.
+ // This is the case for about:blank URLs (with or without fragments),
+ // since they contain no active data. This is also the case for
+ // about:srcdoc, since such URLs only get active content from their parent
+ // frame. Using the parent frame's process avoids putting blank frames
+ // into OOPIFs and preserves scripting for about:srcdoc.
+ //
+ // Allow a process swap for other unique origin URLs, such as data: URLs.
+ // These have active content and may have come from an untrusted source,
+ // such as a restored frame from a different site or a redirect.
+ // (Normally, redirects to data: or about: URLs are disallowed as
// net::ERR_UNSAFE_REDIRECT. However, extensions can still redirect
// arbitary requests to those URLs using the chrome.webRequest or
// chrome.declarativeWebRequest API, which will end up here (for an
- // example, see ExtensionWebRequestApiTest.WebRequestDeclarative1). It's
- // safest to swap processes for those redirects if we are in an
- // appropriate OOPIF-enabled mode.
- //
- // (2) Otherwise, avoid a process swap. We can get here during session
- // restore, and this avoids putting all data: and about:blank subframes
- // in OOPIFs. We can also get here in tests with browser-initiated
- // subframe navigations (NavigateFrameToURL).
- if (!was_server_redirect)
+ // example, see ExtensionWebRequestApiTest.WebRequestDeclarative1).)
+ if (resolved_url.IsAboutBlank() ||
+ resolved_url == GURL(content::kAboutSrcDocURL)) {
return false;
+ }
}
}
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 e53920fc916..d8cf377f4e2 100644
--- a/chromium/content/browser/frame_host/render_frame_host_manager.h
+++ b/chromium/content/browser/frame_host/render_frame_host_manager.h
@@ -22,6 +22,7 @@
#include "content/common/content_export.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/common/referrer.h"
+#include "third_party/blink/public/common/frame/user_activation_update_type.h"
#include "ui/base/page_transition_types.h"
#include "url/origin.h"
@@ -139,8 +140,8 @@ class CONTENT_EXPORT RenderFrameHostManager
// TODO(nasko): This should be removed once extensions no longer use
// NotificationService. See https://crbug.com/462682.
virtual void NotifyMainFrameSwappedFromRenderManager(
- RenderViewHost* old_host,
- RenderViewHost* new_host) = 0;
+ RenderFrameHost* old_host,
+ RenderFrameHost* new_host) = 0;
virtual NavigationControllerImpl&
GetControllerForRenderManager() = 0;
@@ -467,7 +468,10 @@ class CONTENT_EXPORT RenderFrameHostManager
// match the provided |render_frame_host|.
void CancelPendingIfNecessary(RenderFrameHostImpl* render_frame_host);
- void OnSetHasReceivedUserGesture();
+ // Updates the user activation state in all proxies of this frame. For
+ // more details, see the comment on FrameTreeNode::user_activation_state_.
+ void UpdateUserActivationState(blink::UserActivationUpdateType update_type);
+
void OnSetHasReceivedUserGestureBeforeNavigation(bool value);
// Sets up the necessary state for a new RenderViewHost. If |proxy| is not
@@ -561,7 +565,8 @@ class CONTENT_EXPORT RenderFrameHostManager
bool current_is_view_source_mode,
SiteInstance* new_site_instance,
const GURL& new_effective_url,
- bool new_is_view_source_mode) const;
+ bool new_is_view_source_mode,
+ bool is_failure) const;
// Returns the SiteInstance to use for the navigation.
scoped_refptr<SiteInstance> GetSiteInstanceForNavigation(
@@ -725,8 +730,7 @@ class CONTENT_EXPORT RenderFrameHostManager
// Returns true if a subframe can navigate cross-process.
bool CanSubframeSwapProcess(const GURL& dest_url,
SiteInstance* source_instance,
- SiteInstance* dest_instance,
- bool was_server_redirect);
+ SiteInstance* dest_instance);
// After a renderer process crash we'd have marked the host as invisible, so
// we need to set the visibility of the new View to the correct value here
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 0828c4263a3..c49de36a819 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
@@ -50,10 +50,12 @@
#include "content/public/test/navigation_handle_observer.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/test_navigation_throttle_inserter.h"
#include "content/public/test/test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
+#include "content/test/test_content_browser_client.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
@@ -651,8 +653,9 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// Test for crbug.com/116192. Targeted links should still work after the
// named target window has swapped processes.
+// Disabled Flaky test - crbug.com/859487
IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
- AllowTargetedNavigationsAfterSwap) {
+ DISABLED_AllowTargetedNavigationsAfterSwap) {
StartEmbeddedServer();
// Load a page with links that open in a new window.
@@ -1247,7 +1250,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
// The original process should still be alive, since it is still used in the
// first window.
RenderProcessHost* orig_process = orig_site_instance->GetProcess();
- EXPECT_TRUE(orig_process->HasConnection());
+ EXPECT_TRUE(orig_process->IsInitializedAndNotDead());
// Navigate the first window to a different site as well. The original
// process should exit, since all of its views are now swapped out.
@@ -1745,7 +1748,7 @@ IN_PROC_BROWSER_TEST_F(
"</html>");
first_redirect_response.Done();
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
- EXPECT_EQ(kFirstRedirectURL, shell()->web_contents()->GetVisibleURL());
+ EXPECT_EQ(kFirstRedirectURL, shell()->web_contents()->GetLastCommittedURL());
// Now reload the original request, but redirect to yet another site.
TestNavigationManager first_reload(shell()->web_contents(), kOriginalURL);
@@ -1771,19 +1774,24 @@ IN_PROC_BROWSER_TEST_F(
first_reload.ResumeNavigation();
// The navigation is ready to commit: it has been handed to the speculative
- // RenderFrameHost for commit.
+ // RenderFrameHost for commit if Site Isolation is enabled, otherwise it
+ // commits in the same RenderFrameHost.
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());
+ if (AreAllSitesIsolatedForTesting()) {
+ CHECK(speculative_rfh);
+ } else {
+ CHECK(!speculative_rfh);
+ }
// 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.
+ // supposed to commit the browser-initiated navigation, unless Site Isolation
+ // is enabled. This should not crash.
TestNavigationManager second_reload(shell()->web_contents(), kOriginalURL);
shell()->web_contents()->GetController().Reload(
ReloadType::ORIGINAL_REQUEST_URL, false);
@@ -1793,7 +1801,11 @@ IN_PROC_BROWSER_TEST_F(
->root()
->render_manager()
->speculative_frame_host();
- EXPECT_FALSE(speculative_rfh);
+ if (AreAllSitesIsolatedForTesting()) {
+ EXPECT_TRUE(speculative_rfh);
+ } else {
+ EXPECT_FALSE(speculative_rfh);
+ }
// The second reload results in a 204.
second_reload.ResumeNavigation();
@@ -1815,7 +1827,7 @@ IN_PROC_BROWSER_TEST_F(
// navigation to the pending NavigationEntry will not crash if it happens
// because a new navigation to the same pending NavigationEntry started. This
// is a variant of the previous test, where we destroy the speculative
-// RenderFrameHost to create another speculative RenderFrameHost.This is a
+// RenderFrameHost to create another speculative RenderFrameHost. This is a
// regression test for crbug.com/796135.
IN_PROC_BROWSER_TEST_F(
RenderFrameHostManagerTest,
@@ -1837,6 +1849,11 @@ IN_PROC_BROWSER_TEST_F(
const GURL kCrossSiteURL =
embedded_test_server()->GetURL("c.com", "/title1.html");
+ const GURL kOriginalSiteURL = SiteInstance::GetSiteForURL(
+ shell()->web_contents()->GetBrowserContext(), kOriginalURL);
+ const GURL kRedirectSiteURL = SiteInstance::GetSiteForURL(
+ shell()->web_contents()->GetBrowserContext(), kRedirectURL);
+
// First navigate to the initial URL.
shell()->LoadURL(kOriginalURL);
original_response1.WaitForRequest();
@@ -1852,7 +1869,7 @@ IN_PROC_BROWSER_TEST_F(
"</html>");
original_response1.Done();
EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
- EXPECT_EQ(kOriginalURL, shell()->web_contents()->GetVisibleURL());
+ EXPECT_EQ(kOriginalURL, shell()->web_contents()->GetLastCommittedURL());
// Navigate cross-site.
NavigateToURL(shell(), kCrossSiteURL);
@@ -1889,6 +1906,13 @@ IN_PROC_BROWSER_TEST_F(
->speculative_frame_host();
CHECK(speculative_rfh);
EXPECT_TRUE(speculative_rfh->is_loading());
+ if (AreAllSitesIsolatedForTesting()) {
+ EXPECT_EQ(kRedirectSiteURL,
+ speculative_rfh->GetSiteInstance()->GetSiteURL());
+ } else {
+ EXPECT_EQ(kOriginalSiteURL,
+ speculative_rfh->GetSiteInstance()->GetSiteURL());
+ }
int site_instance_id = speculative_rfh->GetSiteInstance()->GetId();
// The user starts a navigation towards the redirected URL, for which we have
@@ -1904,7 +1928,9 @@ IN_PROC_BROWSER_TEST_F(
->render_manager()
->speculative_frame_host();
CHECK(speculative_rfh);
- EXPECT_EQ(site_instance_id, speculative_rfh->GetSiteInstance()->GetId());
+ EXPECT_EQ(kRedirectSiteURL, speculative_rfh->GetSiteInstance()->GetSiteURL());
+ if (AreAllSitesIsolatedForTesting())
+ EXPECT_EQ(site_instance_id, speculative_rfh->GetSiteInstance()->GetId());
// The user requests to go back again while the previous back hasn't committed
// yet. This should delete the speculative RenderFrameHost trying to commit
@@ -1919,7 +1945,9 @@ IN_PROC_BROWSER_TEST_F(
->render_manager()
->speculative_frame_host();
CHECK(speculative_rfh);
- EXPECT_NE(site_instance_id, speculative_rfh->GetSiteInstance()->GetId());
+ EXPECT_EQ(kOriginalSiteURL, speculative_rfh->GetSiteInstance()->GetSiteURL());
+ if (AreAllSitesIsolatedForTesting())
+ EXPECT_NE(site_instance_id, speculative_rfh->GetSiteInstance()->GetId());
}
// Test for crbug.com/9682. We should not show the URL for a pending renderer-
@@ -4081,6 +4109,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
GURL error_url(embedded_test_server()->GetURL("/empty.html"));
std::unique_ptr<URLLoaderInterceptor> url_interceptor =
SetupRequestFailForURL(error_url);
+ auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
// Start with a successful navigation to a document.
EXPECT_TRUE(NavigateToURL(shell(), url));
@@ -4105,7 +4134,6 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
EXPECT_EQ(GURL(kUnreachableWebDataURL), error_site_instance->GetSiteURL());
// Verify that the error page process is locked to origin
- auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
EXPECT_EQ(
GURL(kUnreachableWebDataURL),
policy->GetOriginLock(error_site_instance->GetProcess()->GetID()));
@@ -4116,6 +4144,10 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
EXPECT_TRUE(NavigateToURL(shell(), url));
success_site_instance =
shell()->web_contents()->GetMainFrame()->GetSiteInstance();
+ EXPECT_NE(
+ GURL(kUnreachableWebDataURL),
+ policy->GetOriginLock(
+ shell()->web_contents()->GetSiteInstance()->GetProcess()->GetID()));
{
NavigationHandleObserver observer(shell()->web_contents(), error_url);
@@ -4134,6 +4166,11 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
EXPECT_NE(success_site_instance->GetProcess()->GetID(),
error_site_instance->GetProcess()->GetID());
EXPECT_EQ(GURL(kUnreachableWebDataURL), error_site_instance->GetSiteURL());
+
+ // Verify that the error page process is locked to origin
+ EXPECT_EQ(
+ GURL(kUnreachableWebDataURL),
+ policy->GetOriginLock(error_site_instance->GetProcess()->GetID()));
}
}
@@ -4206,6 +4243,11 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
new_shell->web_contents()->GetMainFrame()->GetSiteInstance();
EXPECT_NE(main_site_instance, error_site_instance);
EXPECT_EQ(GURL(kUnreachableWebDataURL), error_site_instance->GetSiteURL());
+
+ // Verify that the error page process is locked to origin
+ EXPECT_EQ(GURL(kUnreachableWebDataURL),
+ ChildProcessSecurityPolicyImpl::GetInstance()->GetOriginLock(
+ error_site_instance->GetProcess()->GetID()));
}
// Test to verify that windows that are not part of the same
@@ -4253,6 +4295,446 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
new_shell->web_contents()->GetSiteInstance()));
EXPECT_EQ(shell()->web_contents()->GetSiteInstance()->GetProcess(),
new_shell->web_contents()->GetSiteInstance()->GetProcess());
+
+ // Verify that the process is locked to origin
+ EXPECT_EQ(
+ GURL(kUnreachableWebDataURL),
+ ChildProcessSecurityPolicyImpl::GetInstance()->GetOriginLock(
+ shell()->web_contents()->GetSiteInstance()->GetProcess()->GetID()));
+}
+
+// Test to verify that reloading an error page once the error condition has
+// cleared up is successful and does not create a new navigation entry.
+// See https://crbug.com/840485.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, ErrorPageNavigationReload) {
+ // This test is only valid if error page isolation is enabled.
+ if (!SiteIsolationPolicy::IsErrorPageIsolationEnabled(true))
+ return;
+
+ StartEmbeddedServer();
+ GURL start_url(embedded_test_server()->GetURL("/title1.html"));
+ GURL error_url(embedded_test_server()->GetURL("/empty.html"));
+ GURL end_url(embedded_test_server()->GetURL("/title2.html"));
+ NavigationControllerImpl& nav_controller =
+ static_cast<NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+ auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
+
+ // Build session history with three entries, where the middle one will be
+ // tested for successful and failed reloads. This allows checking whether
+ // reload accidentally clears the forward session history if it is
+ // incorrectly classified.
+ EXPECT_TRUE(NavigateToURL(shell(), start_url));
+ EXPECT_TRUE(NavigateToURL(shell(), error_url));
+ EXPECT_TRUE(NavigateToURL(shell(), end_url));
+ {
+ TestNavigationObserver back_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().GoBack();
+ back_observer.Wait();
+ EXPECT_TRUE(back_observer.last_navigation_succeeded());
+ }
+ EXPECT_EQ(3, nav_controller.GetEntryCount());
+ EXPECT_EQ(1, nav_controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(error_url, shell()->web_contents()->GetLastCommittedURL());
+
+ scoped_refptr<SiteInstance> success_site_instance =
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance();
+
+ // Install an interceptor which will cause network failure for |error_url|,
+ // reload the existing entry and verify.
+ std::unique_ptr<URLLoaderInterceptor> url_interceptor =
+ SetupRequestFailForURL(error_url);
+ {
+ TestNavigationObserver reload_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().Reload(ReloadType::NORMAL, false);
+ reload_observer.Wait();
+ EXPECT_FALSE(reload_observer.last_navigation_succeeded());
+ // TODO(nasko): Investigate making a failing reload of a successful
+ // navigation be classified as NEW_PAGE instead, since with error page
+ // isolation it involves a SiteInstance swap.
+ EXPECT_EQ(NavigationType::NAVIGATION_TYPE_EXISTING_PAGE,
+ reload_observer.last_navigation_type());
+ }
+ EXPECT_EQ(3, nav_controller.GetEntryCount());
+ EXPECT_EQ(1, nav_controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(
+ GURL(kUnreachableWebDataURL),
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+ int process_id =
+ shell()->web_contents()->GetMainFrame()->GetProcess()->GetID();
+ EXPECT_EQ(GURL(kUnreachableWebDataURL), policy->GetOriginLock(process_id));
+
+ // Reload while it will still fail to ensure it stays in the same process.
+ {
+ TestNavigationObserver reload_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().Reload(ReloadType::NORMAL, false);
+ reload_observer.Wait();
+ EXPECT_FALSE(reload_observer.last_navigation_succeeded());
+ EXPECT_EQ(NavigationType::NAVIGATION_TYPE_EXISTING_PAGE,
+ reload_observer.last_navigation_type());
+ }
+ EXPECT_EQ(process_id,
+ shell()->web_contents()->GetMainFrame()->GetProcess()->GetID());
+
+ // Reload the error page after clearing the error condition, such that the
+ // navigation is successful and verify that no new entry was added to
+ // session history and forward history is not pruned.
+ url_interceptor.reset();
+ {
+ TestNavigationObserver reload_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().Reload(ReloadType::NORMAL, false);
+ reload_observer.Wait();
+ EXPECT_TRUE(reload_observer.last_navigation_succeeded());
+ // The successful reload should be classified as a NEW_PAGE navigation
+ // with replacement, since it needs to stay at the same entry in session
+ // history, but needs a new entry because of the change in SiteInstance.
+ EXPECT_EQ(NavigationType::NAVIGATION_TYPE_NEW_PAGE,
+ reload_observer.last_navigation_type());
+ }
+ EXPECT_EQ(3, nav_controller.GetEntryCount());
+ EXPECT_EQ(1, nav_controller.GetLastCommittedEntryIndex());
+ EXPECT_NE(
+ GURL(kUnreachableWebDataURL),
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+ EXPECT_NE(
+ GURL(kUnreachableWebDataURL),
+ policy->GetOriginLock(
+ shell()->web_contents()->GetSiteInstance()->GetProcess()->GetID()));
+
+ // Test the same scenario as above, but this time initiated by the
+ // renderer process.
+ url_interceptor = SetupRequestFailForURL(error_url);
+ {
+ TestNavigationObserver reload_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().Reload(ReloadType::NORMAL, false);
+ reload_observer.Wait();
+ EXPECT_FALSE(reload_observer.last_navigation_succeeded());
+ // TODO(nasko): Investigate making a failing reload of a successful
+ // navigation be classified as NEW_PAGE instead, since with error page
+ // isolation it involves a SiteInstance swap.
+ EXPECT_EQ(NavigationType::NAVIGATION_TYPE_EXISTING_PAGE,
+ reload_observer.last_navigation_type());
+ }
+ EXPECT_EQ(3, nav_controller.GetEntryCount());
+ EXPECT_EQ(1, nav_controller.GetLastCommittedEntryIndex());
+ EXPECT_EQ(
+ GURL(kUnreachableWebDataURL),
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+ EXPECT_EQ(
+ GURL(kUnreachableWebDataURL),
+ policy->GetOriginLock(
+ shell()->web_contents()->GetSiteInstance()->GetProcess()->GetID()));
+
+ url_interceptor.reset();
+ {
+ TestNavigationObserver reload_observer(shell()->web_contents());
+ EXPECT_TRUE(ExecuteScript(shell(), "location.reload();"));
+ reload_observer.Wait();
+ EXPECT_TRUE(reload_observer.last_navigation_succeeded());
+ // TODO(nasko): Investigate making renderer initiated reloads that change
+ // SiteInstance be classified as NEW_PAGE as well.
+ EXPECT_EQ(NavigationType::NAVIGATION_TYPE_EXISTING_PAGE,
+ reload_observer.last_navigation_type());
+ }
+ EXPECT_EQ(3, nav_controller.GetEntryCount());
+ EXPECT_EQ(1, nav_controller.GetLastCommittedEntryIndex());
+ EXPECT_NE(
+ GURL(kUnreachableWebDataURL),
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+ EXPECT_NE(
+ GURL(kUnreachableWebDataURL),
+ policy->GetOriginLock(
+ shell()->web_contents()->GetSiteInstance()->GetProcess()->GetID()));
+}
+
+// Test to verify that navigating away from an error page results in correct
+// change in SiteInstance.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ ErrorPageNavigationAfterError) {
+ // This test is only valid if error page isolation is enabled.
+ if (!SiteIsolationPolicy::IsErrorPageIsolationEnabled(true))
+ return;
+
+ StartEmbeddedServer();
+ GURL url(embedded_test_server()->GetURL("/title1.html"));
+ GURL error_url(embedded_test_server()->GetURL("/empty.html"));
+ std::unique_ptr<URLLoaderInterceptor> url_interceptor =
+ SetupRequestFailForURL(error_url);
+ NavigationControllerImpl& nav_controller =
+ static_cast<NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+
+ // Start with a successful navigation to a document.
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+ scoped_refptr<SiteInstance> success_site_instance =
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance();
+ EXPECT_EQ(1, nav_controller.GetEntryCount());
+
+ // Navigate to an url resulting in an error page.
+ EXPECT_FALSE(NavigateToURL(shell(), error_url));
+ EXPECT_EQ(
+ GURL(kUnreachableWebDataURL),
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+ EXPECT_EQ(
+ GURL(kUnreachableWebDataURL),
+ ChildProcessSecurityPolicyImpl::GetInstance()->GetOriginLock(
+ shell()->web_contents()->GetSiteInstance()->GetProcess()->GetID()));
+ EXPECT_EQ(2, nav_controller.GetEntryCount());
+
+ // Navigate again to the initial successful document, expecting a new
+ // navigation and new SiteInstance.
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+ EXPECT_NE(
+ GURL(kUnreachableWebDataURL),
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+ EXPECT_EQ(
+ success_site_instance->GetSiteURL(),
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+ EXPECT_NE(success_site_instance,
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance());
+ EXPECT_EQ(3, nav_controller.GetEntryCount());
+
+ // Repeat again using a renderer-initiated navigation for the successful one.
+ EXPECT_FALSE(NavigateToURL(shell(), error_url));
+ EXPECT_EQ(
+ GURL(kUnreachableWebDataURL),
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+ EXPECT_EQ(
+ GURL(kUnreachableWebDataURL),
+ ChildProcessSecurityPolicyImpl::GetInstance()->GetOriginLock(
+ shell()->web_contents()->GetSiteInstance()->GetProcess()->GetID()));
+ EXPECT_EQ(4, nav_controller.GetEntryCount());
+ {
+ TestNavigationObserver observer(shell()->web_contents());
+ EXPECT_TRUE(
+ ExecuteScript(shell(), "location.href = '" + url.spec() + "';"));
+ observer.Wait();
+ EXPECT_TRUE(observer.last_navigation_succeeded());
+ }
+ EXPECT_EQ(5, nav_controller.GetEntryCount());
+ EXPECT_NE(
+ GURL(kUnreachableWebDataURL),
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+}
+
+// Test to verify that when an error page is hit and its process is terminated,
+// a successful reload correctly commits in a different process.
+// See https://crbug.com/866549.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ ErrorPageNavigationReloadWithTerminatedProcess) {
+ // This test is only valid if error page isolation is enabled.
+ if (!SiteIsolationPolicy::IsErrorPageIsolationEnabled(true))
+ return;
+
+ StartEmbeddedServer();
+ GURL url(embedded_test_server()->GetURL("/title1.html"));
+ GURL error_url(embedded_test_server()->GetURL("/empty.html"));
+ std::unique_ptr<URLLoaderInterceptor> url_interceptor =
+ SetupRequestFailForURL(error_url);
+ WebContents* web_contents = shell()->web_contents();
+ NavigationControllerImpl& nav_controller =
+ static_cast<NavigationControllerImpl&>(web_contents->GetController());
+
+ // Start with a successful navigation to a document.
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+ scoped_refptr<SiteInstance> success_site_instance =
+ web_contents->GetMainFrame()->GetSiteInstance();
+ EXPECT_EQ(1, nav_controller.GetEntryCount());
+
+ // Navigate to an url resulting in an error page.
+ EXPECT_FALSE(NavigateToURL(shell(), error_url));
+ EXPECT_EQ(GURL(kUnreachableWebDataURL),
+ web_contents->GetMainFrame()->GetSiteInstance()->GetSiteURL());
+ EXPECT_EQ(GURL(kUnreachableWebDataURL),
+ ChildProcessSecurityPolicyImpl::GetInstance()->GetOriginLock(
+ web_contents->GetSiteInstance()->GetProcess()->GetID()));
+ EXPECT_EQ(2, nav_controller.GetEntryCount());
+
+ // Terminate the renderer process.
+ {
+ RenderProcessHostWatcher termination_observer(
+ web_contents->GetMainFrame()->GetProcess(),
+ RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ web_contents->GetMainFrame()->GetProcess()->Shutdown(0);
+ termination_observer.Wait();
+ }
+
+ // Clear the interceptor so the navigation will succeed on reload.
+ url_interceptor.reset();
+
+ // Reload the URL and execute a Javascript statement to verify that the
+ // renderer process is still around and responsive.
+ TestNavigationObserver reload_observer(shell()->web_contents());
+ nav_controller.Reload(ReloadType::NORMAL, false);
+ reload_observer.Wait();
+ EXPECT_TRUE(reload_observer.last_navigation_succeeded());
+
+ std::string result;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ shell(), "window.domAutomationController.send(location.href);", &result));
+ EXPECT_EQ(error_url.spec(), result);
+}
+
+// A NavigationThrottle implementation that blocks all outgoing navigation
+// requests for a specific WebContents. It is used to block navigations to
+// WebUI URLs in the following test.
+class RequestBlockingNavigationThrottle : public NavigationThrottle {
+ public:
+ explicit RequestBlockingNavigationThrottle(NavigationHandle* handle)
+ : NavigationThrottle(handle) {}
+
+ static std::unique_ptr<NavigationThrottle> Create(NavigationHandle* handle) {
+ return std::make_unique<RequestBlockingNavigationThrottle>(handle);
+ }
+
+ private:
+ ThrottleCheckResult WillStartRequest() override {
+ return NavigationThrottle::BLOCK_REQUEST;
+ }
+
+ const char* GetNameForLogging() override {
+ return "RequestBlockingNavigationThrottle";
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(RequestBlockingNavigationThrottle);
+};
+
+// Test to verify that navigations to WebUI URL which results in an error
+// commits properly in the error page process and does not give it WebUI
+// bindings.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ ErrorPageNavigationToWebUIResourceWithError) {
+ // This test is only valid if error page isolation is enabled.
+ if (!SiteIsolationPolicy::IsErrorPageIsolationEnabled(true))
+ return;
+
+ StartEmbeddedServer();
+ GURL webui_url = GURL(std::string(kChromeUIScheme) + "://" +
+ std::string(kChromeUIGpuHost));
+ GURL error_url(webui_url.Resolve("/foo"));
+
+ // Navigate to the main WebUI URL and ensure it is successful.
+ EXPECT_TRUE(NavigateToURL(shell(), webui_url));
+
+ // Ensure that the subsequent navigation is blocked, resulting in an
+ // error.
+ TestNavigationThrottleInserter throttle_inserter(
+ shell()->web_contents(),
+ base::BindRepeating(&RequestBlockingNavigationThrottle::Create));
+
+ // Navigate to an error URL and verify the error page process does not get
+ // WebUI bindings.
+ NavigationHandleObserver observer(shell()->web_contents(), error_url);
+ EXPECT_FALSE(NavigateToURL(shell(), error_url));
+ scoped_refptr<SiteInstance> error_site_instance =
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance();
+ EXPECT_TRUE(observer.is_error());
+ EXPECT_EQ(GURL(kUnreachableWebDataURL), error_site_instance->GetSiteURL());
+ EXPECT_EQ(GURL(kUnreachableWebDataURL),
+ ChildProcessSecurityPolicyImpl::GetInstance()->GetOriginLock(
+ error_site_instance->GetProcess()->GetID()));
+ EXPECT_FALSE(ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings(
+ error_site_instance->GetProcess()->GetID()));
+}
+
+// A test ContentBrowserClient implementation which enforces
+// BrowsingInstance swap on every navigation. It is used to verify that
+// reloading of an error page to an URL that requires BrowsingInstance swap
+// works correctly.
+class BrowsingInstanceSwapContentBrowserClient
+ : public TestContentBrowserClient {
+ public:
+ BrowsingInstanceSwapContentBrowserClient() = default;
+
+ bool ShouldIsolateErrorPage(bool in_main_frame) override {
+ return in_main_frame;
+ }
+
+ bool ShouldSwapBrowsingInstancesForNavigation(
+ content::SiteInstance* site_instance,
+ const GURL& current_url,
+ const GURL& new_url) override {
+ return true;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BrowsingInstanceSwapContentBrowserClient);
+};
+
+// Test to verify that reloading of an error page which resulted from a
+// navigation to an URL which requires a BrowsingInstance swap, correcly
+// reloads in the same SiteInstance for the error page.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
+ ErrorPageNavigationReloadBrowsingInstanceSwap) {
+ StartEmbeddedServer();
+ GURL url(embedded_test_server()->GetURL("/title1.html"));
+ GURL error_url(embedded_test_server()->GetURL("/empty.html"));
+ std::unique_ptr<URLLoaderInterceptor> url_interceptor =
+ SetupRequestFailForURL(error_url);
+ NavigationControllerImpl& nav_controller =
+ static_cast<NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+
+ // Start with a successful navigation to a document and verify there is
+ // only one entry in session history.
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+ scoped_refptr<SiteInstance> success_site_instance =
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance();
+ EXPECT_EQ(1, nav_controller.GetEntryCount());
+
+ BrowsingInstanceSwapContentBrowserClient content_browser_client;
+ ContentBrowserClient* old_client =
+ SetBrowserClientForTesting(&content_browser_client);
+
+ // Navigate to an url resulting in an error page and ensure a new entry
+ // was added to session history.
+ EXPECT_FALSE(NavigateToURL(shell(), error_url));
+ EXPECT_EQ(2, nav_controller.GetEntryCount());
+
+ scoped_refptr<SiteInstance> initial_instance =
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance();
+ EXPECT_EQ(GURL(kUnreachableWebDataURL), initial_instance->GetSiteURL());
+ EXPECT_TRUE(
+ success_site_instance->IsRelatedSiteInstance(initial_instance.get()));
+
+ // Reload of the error page that still results in an error should stay in
+ // the same SiteInstance. Ensure this works for both browser-initiated
+ // reloads and renderer-initiated ones.
+ {
+ TestNavigationObserver reload_observer(shell()->web_contents());
+ shell()->web_contents()->GetController().Reload(ReloadType::NORMAL, false);
+ reload_observer.Wait();
+ EXPECT_FALSE(reload_observer.last_navigation_succeeded());
+ EXPECT_EQ(2, nav_controller.GetEntryCount());
+ EXPECT_EQ(initial_instance,
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance());
+ }
+ {
+ TestNavigationObserver reload_observer(shell()->web_contents());
+ EXPECT_TRUE(ExecuteScript(shell(), "location.reload();"));
+ reload_observer.Wait();
+ EXPECT_FALSE(reload_observer.last_navigation_succeeded());
+ EXPECT_EQ(2, nav_controller.GetEntryCount());
+ EXPECT_EQ(initial_instance,
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance());
+ }
+
+ // Allow the navigation to succeed and ensure it swapped to a non-related
+ // SiteInstance.
+ url_interceptor.reset();
+ {
+ TestNavigationObserver reload_observer(shell()->web_contents());
+ EXPECT_TRUE(ExecuteScript(shell(), "location.reload();"));
+ reload_observer.Wait();
+ EXPECT_TRUE(reload_observer.last_navigation_succeeded());
+ EXPECT_EQ(2, nav_controller.GetEntryCount());
+ EXPECT_FALSE(initial_instance->IsRelatedSiteInstance(
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance()));
+ EXPECT_FALSE(success_site_instance->IsRelatedSiteInstance(
+ shell()->web_contents()->GetMainFrame()->GetSiteInstance()));
+ }
+
+ SetBrowserClientForTesting(old_client);
}
// Helper class to simplify testing of unload handlers. It allows waiting for
@@ -4472,4 +4954,51 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerUnloadBrowserTest,
process_exit_observer.Wait();
}
+// Verify that when an OOPIF with an unload handler navigates cross-process,
+// its unload handler is able to send a postMessage to the parent frame.
+// See https://crbug.com/857274.
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerUnloadBrowserTest,
+ PostMessageToParentWhenSubframeNavigates) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ FrameTreeNode* child = root->child_at(0);
+
+ // Add an onmessage listener in the main frame.
+ EXPECT_TRUE(ExecuteScript(root, R"(
+ window.addEventListener('message', function(e) {
+ domAutomationController.send(e.data);
+ });)"));
+
+ // Add an unload handler in the child frame to send a postMessage to the
+ // parent frame.
+ AddUnloadHandler(child->current_frame_host(),
+ "parent.postMessage('foo', '*')");
+
+ // Navigate the subframe cross-site to c.com and wait for the message.
+ GURL c_url(embedded_test_server()->GetURL("c.com", "/title1.html"));
+ std::string message;
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ root,
+ base::StringPrintf("document.querySelector('iframe').src = '%s';",
+ c_url.spec().c_str()),
+ &message));
+ EXPECT_EQ("foo", message);
+
+ // Now repeat the test with a remote-to-local navigation that brings the
+ // subframe back to a.com.
+ AddUnloadHandler(child->current_frame_host(),
+ "parent.postMessage('bar', '*')");
+ GURL a_url(embedded_test_server()->GetURL("a.com", "/title2.html"));
+ EXPECT_TRUE(ExecuteScriptAndExtractString(
+ root,
+ base::StringPrintf("document.querySelector('iframe').src = '%s';",
+ a_url.spec().c_str()),
+ &message));
+ EXPECT_EQ("bar", message);
+}
+
} // namespace content
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 e1c1162d38b..b4fb251d110 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
@@ -17,7 +17,7 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "build/build_config.h"
@@ -131,12 +131,13 @@ class RenderFrameHostManagerTestWebUIControllerFactory
}
// WebUIFactory implementation.
- WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
- const GURL& url) const override {
+ std::unique_ptr<WebUIController> CreateWebUIControllerForURL(
+ WebUI* web_ui,
+ const GURL& url) const override {
// If WebUI creation is enabled for the test and this is a WebUI URL,
// returns a new instance.
if (should_create_webui_ && HasWebUIScheme(url))
- return new WebUIController(web_ui);
+ return std::make_unique<WebUIController>(web_ui);
return nullptr;
}
@@ -391,11 +392,10 @@ class RenderFrameHostManagerTest : public RenderViewHostImplTestHarness {
bool current_is_view_source_mode = current_entry ?
current_entry->IsViewSourceMode() : new_entry->IsViewSourceMode();
return manager->ShouldSwapBrowsingInstancesForNavigation(
- current_effective_url,
- current_is_view_source_mode,
+ current_effective_url, current_is_view_source_mode,
new_entry->site_instance(),
SiteInstanceImpl::GetEffectiveURL(browser_context, new_entry->GetURL()),
- new_entry->IsViewSourceMode());
+ new_entry->IsViewSourceMode(), false);
}
// Creates a test RenderViewHost that's swapped out.
@@ -837,11 +837,18 @@ TEST_F(RenderFrameHostManagerTest, AlwaysSendEnableViewSourceMode) {
kViewSourceUrl, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
int entry_id = controller().GetPendingEntry()->GetUniqueID();
+ NavigationRequest* request =
+ main_test_rfh()->frame_tree_node()->navigation_request();
+ CHECK(request);
+
// Simulate response from RenderFrame for DispatchBeforeUnload.
contents()->GetMainFrame()->PrepareForCommit();
ASSERT_TRUE(contents()->GetPendingMainFrame())
<< "Expected new pending RenderFrameHost to be created.";
RenderFrameHost* last_rfh = contents()->GetPendingMainFrame();
+ contents()->GetPendingMainFrame()->SimulateCommitProcessed(
+ request->navigation_handle()->GetNavigationId(),
+ true /* was_successful */);
contents()->GetPendingMainFrame()->SendNavigate(entry_id, true, kUrl);
EXPECT_EQ(1, controller().GetLastCommittedEntryIndex());
@@ -860,6 +867,8 @@ TEST_F(RenderFrameHostManagerTest, AlwaysSendEnableViewSourceMode) {
// Navigate, again.
controller().LoadURL(
kViewSourceUrl, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
+ request = main_test_rfh()->frame_tree_node()->navigation_request();
+ CHECK(request);
entry_id = controller().GetPendingEntry()->GetUniqueID();
contents()->GetMainFrame()->PrepareForCommit();
@@ -868,6 +877,9 @@ TEST_F(RenderFrameHostManagerTest, AlwaysSendEnableViewSourceMode) {
EXPECT_EQ(last_rfh, contents()->GetMainFrame());
// The renderer sends a commit.
+ contents()->GetMainFrame()->SimulateCommitProcessed(
+ request->navigation_handle()->GetNavigationId(),
+ true /* was_successful */);
contents()->GetMainFrame()->SendNavigateWithTransition(
entry_id, false, kUrl, ui::PAGE_TRANSITION_TYPED);
EXPECT_EQ(1, controller().GetLastCommittedEntryIndex());
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 91bf248a67a..2f32390f0b4 100644
--- a/chromium/content/browser/frame_host/render_frame_message_filter.cc
+++ b/chromium/content/browser/frame_host/render_frame_message_filter.cc
@@ -35,6 +35,7 @@
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_constants.h"
#include "gpu/GLES2/gl2extchromium.h"
+#include "mojo/public/cpp/bindings/callback_helpers.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"
@@ -66,10 +67,6 @@ namespace content {
namespace {
-#if BUILDFLAG(ENABLE_PLUGINS)
-const int kPluginsRefreshThresholdInSeconds = 3;
-#endif
-
void CreateChildFrameOnUI(
int process_id,
int parent_routing_id,
@@ -129,6 +126,29 @@ void DownloadUrlOnUIThread(
std::move(blob_url_loader_factory));
}
+// With network service disabled the downloads code wouldn't know what to do
+// with a BlobURLToken, so this method is used to convert from a token to a
+// BlobDataHandle to be passed on to the rest of the downloads system.
+void DownloadBlobURLFromToken(
+ std::unique_ptr<download::DownloadUrlParameters> params,
+ blink::mojom::BlobURLTokenPtr,
+ const base::WeakPtr<storage::BlobStorageContext>& context,
+ const base::UnguessableToken& token) {
+ std::unique_ptr<storage::BlobDataHandle> blob_handle;
+ GURL blob_url;
+ if (context) {
+ std::string uuid;
+ if (context->registry().GetTokenMapping(token, &blob_url, &uuid) &&
+ blob_url == params->url()) {
+ blob_handle = context->GetBlobDataFromUUID(uuid);
+ }
+ }
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&DownloadUrlOnUIThread, std::move(params),
+ std::move(blob_handle), nullptr));
+}
+
// Common functionality for converting a sync renderer message to a callback
// function in the browser. Derive from this, create it on the heap when
// issuing your callback. When done, write your reply parameters into
@@ -288,7 +308,6 @@ bool RenderFrameMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER_GENERIC(FrameHostMsg_RenderProcessGone,
OnRenderProcessGone())
#if BUILDFLAG(ENABLE_PLUGINS)
- IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_GetPlugins, OnGetPlugins)
IPC_MESSAGE_HANDLER(FrameHostMsg_GetPluginInfo, OnGetPluginInfo)
IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_OpenChannelToPepperPlugin,
OnOpenChannelToPepperPlugin)
@@ -319,6 +338,7 @@ void RenderFrameMessageFilter::DownloadUrl(
const url::Origin& initiator,
const base::string16& suggested_name,
const bool use_prompt,
+ const bool follow_cross_origin_redirects,
blink::mojom::BlobURLTokenPtrInfo blob_url_token) const {
if (!resource_context_)
return;
@@ -355,6 +375,7 @@ void RenderFrameMessageFilter::DownloadUrl(
parameters->set_content_initiated(true);
parameters->set_suggested_name(suggested_name);
parameters->set_prompt(use_prompt);
+ parameters->set_follow_cross_origin_redirects(follow_cross_origin_redirects);
parameters->set_referrer(referrer.url);
parameters->set_referrer_policy(
Referrer::ReferrerPolicyForUrlRequest(referrer.policy));
@@ -368,6 +389,24 @@ void RenderFrameMessageFilter::DownloadUrl(
if (url.SchemeIsBlob()) {
ChromeBlobStorageContext* blob_context =
GetChromeBlobStorageContextForResourceContext(resource_context_);
+
+ // With network service disabled the downloads code wouldn't know what to do
+ // with the BlobURLToken (or the resulting URLLoaderFactory). So for that
+ // case convert the token to a BlobDataHandle before passing it of to the
+ // rest of the downloads system.
+ if (blob_url_token &&
+ !base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ blink::mojom::BlobURLTokenPtr blob_url_token_ptr(
+ std::move(blob_url_token));
+ auto* raw_token = blob_url_token_ptr.get();
+ raw_token->GetToken(mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+ base::BindOnce(&DownloadBlobURLFromToken, std::move(parameters),
+ std::move(blob_url_token_ptr),
+ blob_context->context()->AsWeakPtr()),
+ base::UnguessableToken()));
+ return;
+ }
+
blob_data_handle = blob_context->context()->GetBlobDataFromPublicURL(url);
// Don't care if the above fails. We are going to let the download go
// through and allow it to be interrupted so that the embedder can deal.
@@ -446,7 +485,8 @@ void RenderFrameMessageFilter::OnDownloadUrl(
DownloadUrl(params.render_view_id, params.render_frame_id, params.url,
params.referrer, params.initiator_origin, params.suggested_name,
- false, std::move(blob_url_token));
+ false, params.follow_cross_origin_redirects,
+ std::move(blob_url_token));
}
void RenderFrameMessageFilter::OnSaveImageFromDataURL(
@@ -462,7 +502,7 @@ void RenderFrameMessageFilter::OnSaveImageFromDataURL(
return;
DownloadUrl(render_view_id, render_frame_id, data_url, Referrer(),
- url::Origin(), base::string16(), true, nullptr);
+ url::Origin(), base::string16(), true, true, nullptr);
}
void RenderFrameMessageFilter::OnAre3DAPIsBlocked(int render_frame_id,
@@ -507,7 +547,7 @@ void RenderFrameMessageFilter::SetCookie(int32_t render_frame_id,
if (!GetContentClient()->browser()->AllowSetCookie(
url, site_for_cookies, *cookie, resource_context_, render_process_id_,
- render_frame_id, options))
+ render_frame_id))
return;
net::URLRequestContext* context = GetRequestContextForURL(url);
@@ -586,58 +626,6 @@ void RenderFrameMessageFilter::GetCookies(int render_frame_id,
#if BUILDFLAG(ENABLE_PLUGINS)
-void RenderFrameMessageFilter::OnGetPlugins(
- bool refresh,
- const url::Origin& main_frame_origin,
- IPC::Message* reply_msg) {
- // Don't refresh if the specified threshold has not been passed. Note that
- // this check is performed before off-loading to the file thread. The reason
- // we do this is that some pages tend to request that the list of plugins be
- // refreshed at an excessive rate. This instigates disk scanning, as the list
- // is accumulated by doing multiple reads from disk. This effect is
- // multiplied when we have several pages requesting this operation.
- if (refresh) {
- const base::TimeDelta threshold = base::TimeDelta::FromSeconds(
- kPluginsRefreshThresholdInSeconds);
- const base::TimeTicks now = base::TimeTicks::Now();
- if (now - last_plugin_refresh_time_ >= threshold) {
- // Only refresh if the threshold hasn't been exceeded yet.
- PluginServiceImpl::GetInstance()->RefreshPlugins();
- last_plugin_refresh_time_ = now;
- }
- }
-
- PluginServiceImpl::GetInstance()->GetPlugins(
- base::BindOnce(&RenderFrameMessageFilter::GetPluginsCallback, this,
- reply_msg, main_frame_origin));
-}
-
-void RenderFrameMessageFilter::GetPluginsCallback(
- IPC::Message* reply_msg,
- const url::Origin& main_frame_origin,
- const std::vector<WebPluginInfo>& all_plugins) {
- // Filter the plugin list.
- PluginServiceFilter* filter = PluginServiceImpl::GetInstance()->GetFilter();
- std::vector<WebPluginInfo> plugins;
-
- int child_process_id = -1;
- int routing_id = MSG_ROUTING_NONE;
- // In this loop, copy the WebPluginInfo (and do not use a reference) because
- // the filter might mutate it.
- for (WebPluginInfo plugin : all_plugins) {
- // TODO(crbug.com/621724): Pass an url::Origin instead of a GURL.
- if (!filter ||
- filter->IsPluginAvailable(child_process_id, routing_id,
- resource_context_, main_frame_origin.GetURL(),
- main_frame_origin, &plugin)) {
- plugins.push_back(plugin);
- }
- }
-
- FrameHostMsg_GetPlugins::WriteReplyParams(reply_msg, plugins);
- Send(reply_msg);
-}
-
void RenderFrameMessageFilter::OnGetPluginInfo(
int render_frame_id,
const GURL& url,
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 7f3ab224bd1..9716b200806 100644
--- a/chromium/content/browser/frame_host/render_frame_message_filter.h
+++ b/chromium/content/browser/frame_host/render_frame_message_filter.h
@@ -85,6 +85,7 @@ class CONTENT_EXPORT RenderFrameMessageFilter
const url::Origin& initiator,
const base::string16& suggested_name,
const bool use_prompt,
+ const bool follow_cross_origin_redirects,
blink::mojom::BlobURLTokenPtrInfo blob_url_token) const;
private:
@@ -141,12 +142,6 @@ class CONTENT_EXPORT RenderFrameMessageFilter
GetCookiesCallback callback) override;
#if BUILDFLAG(ENABLE_PLUGINS)
- void OnGetPlugins(bool refresh,
- const url::Origin& main_frame_origin,
- IPC::Message* reply_msg);
- void GetPluginsCallback(IPC::Message* reply_msg,
- const url::Origin& main_frame_origin,
- const std::vector<WebPluginInfo>& plugins);
void OnGetPluginInfo(int render_frame_id,
const GURL& url,
const url::Origin& main_frame_origin,
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 9c11ebe6935..6f1ed61980a 100644
--- a/chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc
+++ b/chromium/content/browser/frame_host/render_frame_message_filter_browsertest.cc
@@ -8,7 +8,7 @@
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "content/browser/bad_message.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/render_frame_message_filter.h"
@@ -126,6 +126,32 @@ IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, Cookies) {
EXPECT_EQ("B=2; D=4", GetCookieFromJS(web_contents_http->GetMainFrame()));
}
+// Ensure "priority" cookie option is settable via document.cookie.
+IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, CookiePriority) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ struct {
+ std::string param;
+ net::CookiePriority priority;
+ } cases[] = {{"name=value", net::COOKIE_PRIORITY_DEFAULT},
+ {"name=value;priority=Low", net::COOKIE_PRIORITY_LOW},
+ {"name=value;priority=Medium", net::COOKIE_PRIORITY_MEDIUM},
+ {"name=value;priority=High", net::COOKIE_PRIORITY_HIGH}};
+
+ for (auto test_case : cases) {
+ GURL url = embedded_test_server()->GetURL("/set_document_cookie.html?" +
+ test_case.param);
+ NavigateToURL(shell(), url);
+ std::vector<net::CanonicalCookie> cookies =
+ GetCanonicalCookies(shell()->web_contents()->GetBrowserContext(), url);
+
+ EXPECT_EQ(1u, cookies.size());
+ EXPECT_EQ("name", cookies[0].Name());
+ EXPECT_EQ("value", cookies[0].Value());
+ EXPECT_EQ(test_case.priority, cookies[0].Priority());
+ }
+}
+
// SameSite cookies (that aren't marked as http-only) should be available to
// JavaScript.
IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, SameSiteCookies) {
@@ -278,7 +304,7 @@ IN_PROC_BROWSER_TEST_F(RenderFrameMessageFilterBrowserTest, RenderProcessGone) {
// left the RPH and its connection alive, and the Wait below would hang.
EXPECT_EQ(bad_message::RFMF_RENDERER_FAKED_ITS_OWN_DEATH, kill_waiter.Wait());
- ASSERT_FALSE(web_rfh->GetProcess()->HasConnection());
+ ASSERT_FALSE(web_rfh->GetProcess()->IsInitializedAndNotDead());
ASSERT_FALSE(web_rfh->IsRenderFrameLive());
}
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 838bc1e20c3..b06a4b9242d 100644
--- a/chromium/content/browser/frame_host/render_frame_proxy_host.cc
+++ b/chromium/content/browser/frame_host/render_frame_proxy_host.cc
@@ -8,6 +8,8 @@
#include <vector>
#include "base/callback.h"
+#include "base/debug/alias.h"
+#include "base/debug/dump_without_crashing.h"
#include "base/lazy_instance.h"
#include "content/browser/bad_message.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
@@ -98,7 +100,7 @@ RenderFrameProxyHost::~RenderFrameProxyHost() {
if (!destruction_callback_.is_null())
std::move(destruction_callback_).Run();
- if (GetProcess()->HasConnection()) {
+ if (GetProcess()->IsInitializedAndNotDead()) {
// TODO(nasko): For now, don't send this IPC for top-level frames, as
// the top-level RenderFrame will delete the RenderFrameProxy.
// This can be removed once we don't have a swapped out state on
@@ -172,7 +174,7 @@ bool RenderFrameProxyHost::InitRenderFrameProxy() {
// RenderFrame. When that happens, the process will be reinitialized, and
// all necessary proxies, including any of the ones we skipped here, will be
// created by CreateProxiesForSiteInstance. See https://crbug.com/476846
- if (!GetProcess()->HasConnection())
+ if (!GetProcess()->IsInitializedAndNotDead())
return false;
int parent_routing_id = MSG_ROUTING_NONE;
@@ -202,6 +204,30 @@ bool RenderFrameProxyHost::InitRenderFrameProxy() {
site_instance_.get());
}
+ // Temporary debugging code for https://crbug.com/794625 to see if we're ever
+ // sending a message to create a RenderFrameProxy when one already exists.
+ // TODO(alexmos): Remove after the investigation.
+ if (render_frame_proxy_created_) {
+ SiteInstanceImpl* site_instance =
+ static_cast<SiteInstanceImpl*>(site_instance_.get());
+ GURL site_url(site_instance->GetSiteURL());
+ DEBUG_ALIAS_FOR_GURL(site_url_copy, site_url);
+ GURL current_rfh_site_url(frame_tree_node_->render_manager()
+ ->current_frame_host()
+ ->GetSiteInstance()
+ ->GetSiteURL());
+ DEBUG_ALIAS_FOR_GURL(current_rfh_site_url_copy, current_rfh_site_url);
+
+ int routing_id_copy = routing_id_;
+ base::debug::Alias(&routing_id_copy);
+ int parent_routing_id_copy = parent_routing_id;
+ base::debug::Alias(&parent_routing_id_copy);
+ int active_frame_count = site_instance->active_frame_count();
+ base::debug::Alias(&active_frame_count);
+
+ base::debug::DumpWithoutCrashing();
+ }
+
int view_routing_id = frame_tree_node_->frame_tree()
->GetRenderViewHost(site_instance_.get())->GetRoutingID();
GetProcess()->GetRendererInterface()->CreateFrameProxy(
@@ -381,6 +407,11 @@ void RenderFrameProxyHost::OnRouteMessageEvent(
->SynchronizeVisualPropertiesIgnoringPendingAck();
}
+ if (!source_rfh->frame_tree_node()->IsDescendantOf(
+ target_rfh->frame_tree_node())) {
+ target_rfh->did_receive_post_message_from_non_descendant();
+ }
+
// Ensure that we have a swapped-out RVH and proxy for the source frame
// in the target SiteInstance. If it doesn't exist, create it on demand
// and also create its opener chain, since that will also be accessible
diff --git a/chromium/content/browser/frame_host/render_widget_host_view_guest.cc b/chromium/content/browser/frame_host/render_widget_host_view_guest.cc
index a0bc38e7f05..7c08ae7a4ee 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
@@ -11,6 +11,7 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "build/build_config.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.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"
@@ -153,10 +154,9 @@ void RenderWidgetHostViewGuest::Show() {
// Since we were last shown, our renderer may have had a different surface
// set (e.g. showing an interstitial), so we resend our current surface to
// the renderer.
- if (last_received_local_surface_id_.is_valid())
- SendSurfaceInfoToEmbedder();
+ SendSurfaceInfoToEmbedder();
}
- host()->WasShown(ui::LatencyInfo());
+ host()->WasShown(false /* record_presentation_time */);
}
void RenderWidgetHostViewGuest::Hide() {
@@ -251,7 +251,7 @@ gfx::PointF RenderWidgetHostViewGuest::TransformPointToRootCoordSpaceF(
const gfx::PointF& point) {
// LocalSurfaceId is not needed in Viz hit-test.
if (!guest_ ||
- (!use_viz_hit_test_ && !last_received_local_surface_id_.is_valid())) {
+ (!use_viz_hit_test_ && !last_activated_surface_info_.is_valid())) {
return point;
}
@@ -264,9 +264,7 @@ gfx::PointF RenderWidgetHostViewGuest::TransformPointToRootCoordSpaceF(
// 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)) {
+ point, last_activated_surface_info_.id(), &transformed_point)) {
return point;
}
return transformed_point;
@@ -277,19 +275,18 @@ bool RenderWidgetHostViewGuest::TransformPointToLocalCoordSpaceLegacy(
const viz::SurfaceId& original_surface,
gfx::PointF* transformed_point) {
*transformed_point = point;
- if (!guest_ || !last_received_local_surface_id_.is_valid())
+ if (!guest_ || !last_activated_surface_info_.is_valid())
return false;
- auto local_surface_id =
- viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_);
- if (original_surface == local_surface_id)
+ if (original_surface == last_activated_surface_info_.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,
+ if (!hittest.TransformPointToTargetSurface(original_surface,
+ last_activated_surface_info_.id(),
transformed_point)) {
return false;
}
@@ -349,6 +346,14 @@ base::string16 RenderWidgetHostViewGuest::GetSelectedText() {
return platform_view_->GetSelectedText();
}
+base::string16 RenderWidgetHostViewGuest::GetSurroundingText() {
+ return platform_view_->GetSurroundingText();
+}
+
+gfx::Range RenderWidgetHostViewGuest::GetSelectedRange() {
+ return platform_view_->GetSelectedRange();
+}
+
void RenderWidgetHostViewGuest::SetNeedsBeginFrames(bool needs_begin_frames) {
if (platform_view_)
platform_view_->SetNeedsBeginFrames(needs_begin_frames);
@@ -371,10 +376,10 @@ void RenderWidgetHostViewGuest::SetTooltipText(
root_view->GetCursorManager()->SetTooltipTextForView(this, tooltip_text);
}
-void RenderWidgetHostViewGuest::SendSurfaceInfoToEmbedderImpl(
+void RenderWidgetHostViewGuest::FirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) {
if (guest_ && !guest_->is_in_destruction())
- guest_->SetChildFrameSurface(surface_info);
+ guest_->FirstSurfaceActivation(surface_info);
}
void RenderWidgetHostViewGuest::OnDidUpdateVisualPropertiesComplete(
@@ -387,13 +392,14 @@ void RenderWidgetHostViewGuest::OnDidUpdateVisualPropertiesComplete(
void RenderWidgetHostViewGuest::OnAttached() {
RegisterFrameSinkId();
#if defined(USE_AURA)
- if (base::FeatureList::IsEnabled(::features::kMash)) {
+ if (!features::IsAshInBrowserProcess()) {
aura::Env::GetInstance()->ScheduleEmbed(
GetWindowTreeClientFromRenderer(),
base::BindOnce(&RenderWidgetHostViewGuest::OnGotEmbedToken,
weak_ptr_factory_.GetWeakPtr()));
}
#endif
+ SendSurfaceInfoToEmbedder();
}
bool RenderWidgetHostViewGuest::OnMessageReceived(const IPC::Message& msg) {
@@ -568,10 +574,11 @@ viz::FrameSinkId RenderWidgetHostViewGuest::GetRootFrameSinkId() {
return viz::FrameSinkId();
}
-viz::LocalSurfaceId RenderWidgetHostViewGuest::GetLocalSurfaceId() const {
+const viz::LocalSurfaceId& RenderWidgetHostViewGuest::GetLocalSurfaceId()
+ const {
if (guest_)
return guest_->local_surface_id();
- return viz::LocalSurfaceId();
+ return viz::ParentLocalSurfaceIdAllocator::InvalidLocalSurfaceId();
}
void RenderWidgetHostViewGuest::DidCreateNewRendererCompositorFrameSink(
@@ -664,6 +671,25 @@ void RenderWidgetHostViewGuest::GestureEventAck(
event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
GetOwnerRenderWidgetHostView()->GestureEventAck(event, ack_result);
}
+
+ if (blink::WebInputEvent::IsPinchGestureEventType(event.GetType()))
+ ProcessTouchpadPinchAckInRoot(event, ack_result);
+}
+
+void RenderWidgetHostViewGuest::ProcessTouchpadPinchAckInRoot(
+ const blink::WebGestureEvent& event,
+ InputEventAckState ack_result) {
+ DCHECK(blink::WebInputEvent::IsPinchGestureEventType(event.GetType()));
+
+ RenderWidgetHostViewBase* root_rwhv = GetRootView(this);
+ if (!root_rwhv)
+ return;
+
+ blink::WebGestureEvent pinch_event(event);
+ const gfx::PointF root_point =
+ TransformPointToRootCoordSpaceF(event.PositionInWidget());
+ pinch_event.SetPositionInWidget(root_point);
+ root_rwhv->GestureEventAck(pinch_event, ack_result);
}
InputEventAckState RenderWidgetHostViewGuest::FilterInputEvent(
@@ -798,10 +824,6 @@ void RenderWidgetHostViewGuest::OnHandleInputEvent(
}
}
-bool RenderWidgetHostViewGuest::HasEmbedderChanged() {
- return guest_ && guest_->has_attached_since_surface_set();
-}
-
#if defined(USE_AURA)
void RenderWidgetHostViewGuest::OnGotEmbedToken(
const base::UnguessableToken& token) {
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 1e2687b945e..864dd4bed93 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
@@ -80,6 +80,8 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
gfx::Rect GetBoundsInRootWindow() override;
gfx::Size GetCompositorViewportPixelSize() const override;
base::string16 GetSelectedText() override;
+ base::string16 GetSurroundingText() override;
+ gfx::Range GetSelectedRange() override;
void SetNeedsBeginFrames(bool needs_begin_frames) override;
TouchSelectionControllerClientManager*
GetTouchSelectionControllerClientManager() override;
@@ -126,7 +128,7 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
bool LockMouse() override;
void UnlockMouse() override;
viz::FrameSinkId GetRootFrameSinkId() override;
- viz::LocalSurfaceId GetLocalSurfaceId() const override;
+ const viz::LocalSurfaceId& GetLocalSurfaceId() const override;
void DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink)
override;
@@ -162,8 +164,7 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
private:
friend class RenderWidgetHostView;
- void SendSurfaceInfoToEmbedderImpl(
- const viz::SurfaceInfo& surface_info) override;
+ void FirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
void OnDidUpdateVisualPropertiesComplete(
const cc::RenderFrameMetadata& metadata);
@@ -187,7 +188,8 @@ class CONTENT_EXPORT RenderWidgetHostViewGuest
int browser_plugin_instance_id,
const blink::WebInputEvent* event);
- bool HasEmbedderChanged() override;
+ void ProcessTouchpadPinchAckInRoot(const blink::WebGestureEvent& event,
+ InputEventAckState ack_result);
#if defined(USE_AURA)
void OnGotEmbedToken(const base::UnguessableToken& token);
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 8c69857ab3f..fa97ccfa39b 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
@@ -28,7 +28,6 @@
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
-#include "content/test/fake_renderer_compositor_frame_sink.h"
#include "content/test/mock_render_widget_host_delegate.h"
#include "content/test/mock_widget_impl.h"
#include "content/test/test_render_view_host.h"
@@ -114,16 +113,11 @@ class TestBrowserPluginGuest : public BrowserPluginGuest {
void ResetTestData() { last_surface_info_ = viz::SurfaceInfo(); }
- void set_has_attached_since_surface_set(bool has_attached_since_surface_set) {
- BrowserPluginGuest::set_has_attached_since_surface_set_for_test(
- has_attached_since_surface_set);
- }
-
void set_attached(bool attached) {
BrowserPluginGuest::set_attached_for_test(attached);
}
- void SetChildFrameSurface(const viz::SurfaceInfo& surface_info) override {
+ void FirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override {
last_surface_info_ = surface_info;
}
@@ -131,9 +125,7 @@ class TestBrowserPluginGuest : public BrowserPluginGuest {
};
// TODO(wjmaclean): we should restructure RenderWidgetHostViewChildFrameTest to
-// look more like this one, and then this one could be derived from it. Also,
-// include CreateDelegatedFrame as part of the test class so we don't have to
-// repeat it here.
+// look more like this one, and then this one could be derived from it.
class RenderWidgetHostViewGuestSurfaceTest
: public testing::Test {
public:
@@ -162,16 +154,6 @@ class RenderWidgetHostViewGuestSurfaceTest
view_ = RenderWidgetHostViewGuest::Create(
widget_host_, browser_plugin_guest_,
(new TestRenderWidgetHostView(widget_host_))->GetWeakPtr());
- viz::mojom::CompositorFrameSinkPtr sink;
- viz::mojom::CompositorFrameSinkRequest sink_request =
- mojo::MakeRequest(&sink);
- viz::mojom::CompositorFrameSinkClientRequest client_request =
- mojo::MakeRequest(&renderer_compositor_frame_sink_ptr_);
- renderer_compositor_frame_sink_ =
- std::make_unique<FakeRendererCompositorFrameSink>(
- std::move(sink), std::move(client_request));
- view_->DidCreateNewRendererCompositorFrameSink(
- renderer_compositor_frame_sink_ptr_.get());
}
void TearDown() override {
@@ -192,10 +174,7 @@ class RenderWidgetHostViewGuestSurfaceTest
DCHECK(view_);
RenderWidgetHostViewChildFrame* rwhvcf =
static_cast<RenderWidgetHostViewChildFrame*>(view_);
- if (!rwhvcf->last_received_local_surface_id_.is_valid())
- return viz::SurfaceId();
- return viz::SurfaceId(rwhvcf->frame_sink_id_,
- rwhvcf->last_received_local_surface_id_);
+ return rwhvcf->last_activated_surface_info_.id();
}
protected:
@@ -211,8 +190,6 @@ class RenderWidgetHostViewGuestSurfaceTest
std::unique_ptr<MockWidgetImpl> widget_impl_;
RenderWidgetHostImpl* widget_host_;
RenderWidgetHostViewGuest* view_;
- std::unique_ptr<FakeRendererCompositorFrameSink>
- renderer_compositor_frame_sink_;
private:
viz::mojom::CompositorFrameSinkClientPtr renderer_compositor_frame_sink_ptr_;
@@ -220,33 +197,13 @@ class RenderWidgetHostViewGuestSurfaceTest
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewGuestSurfaceTest);
};
-namespace {
-viz::CompositorFrame CreateDelegatedFrame(float scale_factor,
- gfx::Size size,
- const gfx::Rect& damage) {
- viz::CompositorFrame frame;
- frame.metadata.device_scale_factor = scale_factor;
- frame.metadata.begin_frame_ack = viz::BeginFrameAck(0, 1, true);
-
- std::unique_ptr<viz::RenderPass> pass = viz::RenderPass::Create();
- pass->SetNew(1, gfx::Rect(size), damage, gfx::Transform());
- frame.render_pass_list.push_back(std::move(pass));
- return frame;
-}
-} // anonymous namespace
-
TEST_F(RenderWidgetHostViewGuestSurfaceTest, TestGuestSurface) {
- // TODO(jonross): Delete this test once Viz launches as it will be obsolete.
- // https://crbug.com/844469
- if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
- base::FeatureList::IsEnabled(features::kMash)) {
- return;
- }
-
gfx::Size view_size(100, 100);
gfx::Rect view_rect(view_size);
float scale_factor = 1.f;
viz::LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create());
+ viz::SurfaceId surface_id(view_->GetFrameSinkId(), local_surface_id);
+ viz::SurfaceInfo surface_info(surface_id, scale_factor, view_size);
ASSERT_TRUE(browser_plugin_guest_);
@@ -254,46 +211,24 @@ TEST_F(RenderWidgetHostViewGuestSurfaceTest, TestGuestSurface) {
view_->Show();
browser_plugin_guest_->set_attached(true);
- view_->SubmitCompositorFrame(
- local_surface_id,
- CreateDelegatedFrame(scale_factor, view_size, view_rect), base::nullopt);
- viz::SurfaceId id = GetSurfaceId();
+ view_->OnFirstSurfaceActivation(surface_info);
- EXPECT_TRUE(id.is_valid());
+ EXPECT_EQ(surface_id, GetSurfaceId());
-#if !defined(OS_ANDROID)
- viz::SurfaceManager* manager = ImageTransportFactory::GetInstance()
- ->GetContextFactoryPrivate()
- ->GetFrameSinkManager()
- ->surface_manager();
- viz::Surface* surface = manager->GetSurfaceForId(id);
- EXPECT_TRUE(surface);
-#endif
// Surface ID should have been passed to BrowserPluginGuest to
// be sent to the embedding renderer.
- EXPECT_EQ(viz::SurfaceInfo(id, scale_factor, view_size),
- browser_plugin_guest_->last_surface_info_);
+ EXPECT_EQ(surface_info, browser_plugin_guest_->last_surface_info_);
browser_plugin_guest_->ResetTestData();
- browser_plugin_guest_->set_has_attached_since_surface_set(true);
- view_->SubmitCompositorFrame(
- local_surface_id,
- CreateDelegatedFrame(scale_factor, view_size, view_rect), base::nullopt);
+ // The last received SurfaceInfo must be sent to BrowserPluginGuest on
+ // attachment.
+ view_->OnAttached();
- // Since we have not changed the frame size and scale factor, the same surface
- // id must be used.
- DCHECK_EQ(id, GetSurfaceId());
-
-#if !defined(OS_ANDROID)
- surface = manager->GetSurfaceForId(id);
- EXPECT_TRUE(surface);
-#endif
// Surface ID should have been passed to BrowserPluginGuest to
// be sent to the embedding renderer.
- EXPECT_EQ(viz::SurfaceInfo(id, scale_factor, view_size),
- browser_plugin_guest_->last_surface_info_);
+ EXPECT_EQ(surface_info, browser_plugin_guest_->last_surface_info_);
browser_plugin_guest_->set_attached(false);
browser_plugin_guest_->ResetTestData();
diff --git a/chromium/content/browser/frame_host/webui_navigation_browsertest.cc b/chromium/content/browser/frame_host/webui_navigation_browsertest.cc
index 23f8a793303..7add77190dd 100644
--- a/chromium/content/browser/frame_host/webui_navigation_browsertest.cc
+++ b/chromium/content/browser/frame_host/webui_navigation_browsertest.cc
@@ -6,6 +6,7 @@
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/bindings_policy.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"
@@ -28,6 +29,107 @@ class WebUINavigationBrowserTest : public ContentBrowserTest {
ASSERT_TRUE(embedded_test_server()->Start());
}
+ // Verify that no web content can be loaded in a process that has WebUI
+ // bindings, regardless of what scheme the content was loaded from.
+ void TestWebFrameInWebUIProcessDisallowed(int bindings) {
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+ GURL data_url("data:text/html,a data url document");
+ EXPECT_TRUE(NavigateToURL(shell(), data_url));
+ EXPECT_EQ(data_url, root->current_frame_host()->GetLastCommittedURL());
+ EXPECT_FALSE(
+ ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+ root->current_frame_host()->GetProcess()->GetID()));
+
+ // Grant WebUI bindings to the process. This will ensure that if there is
+ // a mistake in the navigation logic and a process gets somehow WebUI
+ // bindings, it cannot include web content regardless of the scheme of the
+ // document.
+ ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
+ root->current_frame_host()->GetProcess()->GetID(), bindings);
+ EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+ root->current_frame_host()->GetProcess()->GetID()));
+ {
+ GURL web_url(embedded_test_server()->GetURL("/title2.html"));
+ std::string script = base::StringPrintf(
+ "var frame = document.createElement('iframe');\n"
+ "frame.src = '%s';\n"
+ "document.body.appendChild(frame);\n",
+ web_url.spec().c_str());
+
+ TestNavigationObserver navigation_observer(shell()->web_contents());
+ EXPECT_TRUE(ExecuteScript(shell(), script));
+ navigation_observer.Wait();
+
+ EXPECT_EQ(1U, root->child_count());
+ EXPECT_FALSE(navigation_observer.last_navigation_succeeded());
+ }
+ }
+
+ // Verify that a WebUI document in a subframe is allowed to target a new
+ // window and navigate it to web content.
+ void TestWebUISubframeNewWindowToWebAllowed(int bindings) {
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
+ ->GetFrameTree()
+ ->root();
+
+ // TODO(nasko): Replace this URL with one with a custom WebUI object that
+ // doesn't have restrictive CSP, so the test can successfully add an
+ // iframe which gets WebUI bindings in the renderer process.
+ GURL chrome_url = GURL(std::string(kChromeUIScheme) + "://" +
+ std::string(kChromeUIBlobInternalsHost));
+ EXPECT_TRUE(NavigateToURL(shell(), chrome_url));
+ RenderFrameHost* webui_rfh = root->current_frame_host();
+ scoped_refptr<SiteInstance> webui_site_instance =
+ webui_rfh->GetSiteInstance();
+
+ ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
+ webui_rfh->GetProcess()->GetID(), bindings);
+
+ EXPECT_EQ(chrome_url, webui_rfh->GetLastCommittedURL());
+ EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
+ webui_rfh->GetProcess()->GetID()));
+
+ // Create a subframe with a WebUI document in it.
+ {
+ std::string script = base::StringPrintf(
+ "var frame = document.createElement('iframe');\n"
+ "frame.src = '%s';\n"
+ "document.body.appendChild(frame);\n",
+ chrome_url.spec().c_str());
+
+ TestNavigationObserver navigation_observer(shell()->web_contents());
+ EXPECT_TRUE(ExecuteScript(shell(), script));
+ navigation_observer.Wait();
+
+ EXPECT_EQ(1U, root->child_count());
+ EXPECT_TRUE(navigation_observer.last_navigation_succeeded());
+ }
+
+ // Add a link that targets a new window and click it.
+ GURL web_url(embedded_test_server()->GetURL("/title2.html"));
+ std::string script = base::StringPrintf(
+ "var a = document.createElement('a');"
+ "a.href = '%s'; a.target = '_blank'; a.click()",
+ web_url.spec().c_str());
+
+ ShellAddedObserver new_shell_observer;
+ EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(), script));
+ Shell* new_shell = new_shell_observer.GetShell();
+ WaitForLoadStop(new_shell->web_contents());
+
+ EXPECT_EQ(web_url, new_shell->web_contents()->GetLastCommittedURL());
+
+ // TODO(nasko): Verify the SiteInstance is different once
+ // https://crbug.com/776900 is fixed.
+ // Without a WebUI object which requires WebUI bindings, the RenderFrame is
+ // not notified that it has WebUI bindings. This in turn causes link clicks
+ // to use the BeginNavigation path, where otherwise the WebUI bindings will
+ // cause the OpenURL path to be taken. When using BeginNavigation, the
+ // navigation is committed same process, since it is renderer initiated.
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(WebUINavigationBrowserTest);
};
@@ -101,44 +203,6 @@ IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
}
}
-// Verify that no web content can be loaded in a process that has WebUI
-// bindings, regardless of what scheme the content was loaded from.
-IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
- WebFrameInWebUIProcessDisallowed) {
- FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()
- ->root();
- GURL data_url("data:text/html,a data url document");
- EXPECT_TRUE(NavigateToURL(shell(), data_url));
- EXPECT_EQ(data_url, root->current_frame_host()->GetLastCommittedURL());
- EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
- root->current_frame_host()->GetProcess()->GetID()));
-
- // Grant WebUI bindings to the process. This will ensure that if there is
- // a mistake in the navigation logic and a process gets somehow WebUI
- // bindings, it cannot include web content regardless of the scheme of the
- // document.
- ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
- root->current_frame_host()->GetProcess()->GetID());
- EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
- root->current_frame_host()->GetProcess()->GetID()));
- {
- GURL web_url(embedded_test_server()->GetURL("/title2.html"));
- std::string script = base::StringPrintf(
- "var frame = document.createElement('iframe');\n"
- "frame.src = '%s';\n"
- "document.body.appendChild(frame);\n",
- web_url.spec().c_str());
-
- TestNavigationObserver navigation_observer(shell()->web_contents());
- EXPECT_TRUE(ExecuteScript(shell(), script));
- navigation_observer.Wait();
-
- EXPECT_EQ(1U, root->child_count());
- EXPECT_FALSE(navigation_observer.last_navigation_succeeded());
- }
-}
-
// Verify that a WebUI document in the main frame is allowed to navigate to
// web content and it properly does cross-process navigation.
IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest, WebUIMainFrameToWebAllowed) {
@@ -171,68 +235,36 @@ IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest, WebUIMainFrameToWebAllowed) {
root->current_frame_host()->GetSiteInstance()));
}
-// Verify that a WebUI document in a subframe is allowed to target a new
-// window and navigate it to web content.
IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
- WebUISubframeNewWindowToWebAllowed) {
- FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
- ->GetFrameTree()
- ->root();
-
- // TODO(nasko): Replace this URL with one with a custom WebUI object that
- // doesn't have restrictive CSP, so the test can successfully add an
- // iframe which gets WebUI bindings in the renderer process.
- GURL chrome_url = GURL(std::string(kChromeUIScheme) + "://" +
- std::string(kChromeUIBlobInternalsHost));
- EXPECT_TRUE(NavigateToURL(shell(), chrome_url));
- RenderFrameHost* webui_rfh = root->current_frame_host();
- scoped_refptr<SiteInstance> webui_site_instance =
- webui_rfh->GetSiteInstance();
-
- ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
- webui_rfh->GetProcess()->GetID());
+ WebFrameInWebUIProcessDisallowed) {
+ TestWebFrameInWebUIProcessDisallowed(BINDINGS_POLICY_WEB_UI);
+}
- EXPECT_EQ(chrome_url, webui_rfh->GetLastCommittedURL());
- EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
- webui_rfh->GetProcess()->GetID()));
+IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
+ WebFrameInMojoWebUIProcessDisallowed) {
+ TestWebFrameInWebUIProcessDisallowed(BINDINGS_POLICY_MOJO_WEB_UI);
+}
- // Create a subframe with a WebUI document in it.
- {
- std::string script = base::StringPrintf(
- "var frame = document.createElement('iframe');\n"
- "frame.src = '%s';\n"
- "document.body.appendChild(frame);\n",
- chrome_url.spec().c_str());
+IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
+ WebFrameInHybridWebUIProcessDisallowed) {
+ TestWebFrameInWebUIProcessDisallowed(BINDINGS_POLICY_MOJO_WEB_UI |
+ BINDINGS_POLICY_WEB_UI);
+}
- TestNavigationObserver navigation_observer(shell()->web_contents());
- EXPECT_TRUE(ExecuteScript(shell(), script));
- navigation_observer.Wait();
+IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
+ WebUISubframeNewWindowToWebAllowed) {
+ TestWebUISubframeNewWindowToWebAllowed(BINDINGS_POLICY_WEB_UI);
+}
- EXPECT_EQ(1U, root->child_count());
- EXPECT_TRUE(navigation_observer.last_navigation_succeeded());
- }
+IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
+ MojoWebUISubframeNewWindowToWebAllowed) {
+ TestWebUISubframeNewWindowToWebAllowed(BINDINGS_POLICY_MOJO_WEB_UI);
+}
- // Add a link that targets a new window and click it.
- GURL web_url(embedded_test_server()->GetURL("/title2.html"));
- std::string script = base::StringPrintf(
- "var a = document.createElement('a');"
- "a.href = '%s'; a.target = '_blank'; a.click()",
- web_url.spec().c_str());
-
- ShellAddedObserver new_shell_observer;
- EXPECT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(), script));
- Shell* new_shell = new_shell_observer.GetShell();
- WaitForLoadStop(new_shell->web_contents());
-
- EXPECT_EQ(web_url, new_shell->web_contents()->GetLastCommittedURL());
-
- // TODO(nasko): Verify the SiteInstance is different once
- // https://crbug.com/776900 is fixed.
- // Without a WebUI object which requires WebUI bindings, the RenderFrame is
- // not notified that it has WebUI bindings. This in turn causes link clicks
- // to use the BeginNavigation path, where otherwise the WebUI bindings will
- // cause the OpenURL path to be taken. When using BeginNavigation, the
- // navigation is committed same process, since it is renderer initiated.
+IN_PROC_BROWSER_TEST_F(WebUINavigationBrowserTest,
+ HybridWebUISubframeNewWindowToWebAllowed) {
+ TestWebUISubframeNewWindowToWebAllowed(BINDINGS_POLICY_MOJO_WEB_UI |
+ BINDINGS_POLICY_WEB_UI);
}
} // namespace content
diff --git a/chromium/content/browser/generic_sensor/generic_sensor_browsertest.cc b/chromium/content/browser/generic_sensor/generic_sensor_browsertest.cc
index ec3dff1a554..216f03d8869 100644
--- a/chromium/content/browser/generic_sensor/generic_sensor_browsertest.cc
+++ b/chromium/content/browser/generic_sensor/generic_sensor_browsertest.cc
@@ -4,7 +4,6 @@
#include "base/bind.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"
@@ -42,15 +41,24 @@ using device::FakeSensorProvider;
class GenericSensorBrowserTest : public ContentBrowserTest {
public:
- GenericSensorBrowserTest()
- : io_loop_finished_event_(
- base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED) {
+ GenericSensorBrowserTest() {
scoped_feature_list_.InitWithFeatures(
{features::kGenericSensor, features::kGenericSensorExtraClasses}, {});
+
+ // Because Device Service also runs in this process (browser process), here
+ // we can directly set our binder to intercept interface requests against
+ // it.
+ service_manager::ServiceContext::SetGlobalBinderForTesting(
+ device::mojom::kServiceName, device::mojom::SensorProvider::Name_,
+ base::BindRepeating(
+ &GenericSensorBrowserTest::BindSensorProviderRequest,
+ base::Unretained(this)));
}
- ~GenericSensorBrowserTest() override {}
+ ~GenericSensorBrowserTest() override {
+ service_manager::ServiceContext::ClearGlobalBindersForTesting(
+ device::mojom::kServiceName);
+ }
void SetUpOnMainThread() override {
https_embedded_test_server_.reset(
@@ -62,13 +70,6 @@ class GenericSensorBrowserTest : public ContentBrowserTest {
https_embedded_test_server_->ServeFilesFromSourceDirectory(
"content/test/data/generic_sensor");
https_embedded_test_server_->StartAcceptingConnections();
-
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&GenericSensorBrowserTest::SetBinderOnIOThread,
- base::Unretained(this)));
-
- io_loop_finished_event_.Wait();
}
void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -77,19 +78,6 @@ class GenericSensorBrowserTest : public ContentBrowserTest {
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
- // it.
- service_manager::ServiceContext::SetGlobalBinderForTesting(
- device::mojom::kServiceName, device::mojom::SensorProvider::Name_,
- base::BindRepeating(
- &GenericSensorBrowserTest::BindSensorProviderRequest,
- base::Unretained(this)));
-
- io_loop_finished_event_.Signal();
- }
-
void BindSensorProviderRequest(
const std::string& interface_name,
mojo::ScopedMessagePipeHandle handle,
@@ -115,21 +103,13 @@ class GenericSensorBrowserTest : public ContentBrowserTest {
private:
base::test::ScopedFeatureList scoped_feature_list_;
- base::WaitableEvent io_loop_finished_event_;
bool sensor_provider_available_ = true;
std::unique_ptr<FakeSensorProvider> fake_sensor_provider_;
DISALLOW_COPY_AND_ASSIGN(GenericSensorBrowserTest);
};
-// Flakily crashes on Linux ASAN/TSAN bots. https://crbug.com/789515
-// Flakily times out on Windows bots. https://crbug.com/809537
-#if defined(OS_LINUX) || defined(OS_WIN)
-#define MAYBE_AmbientLightSensorTest DISABLED_AmbientLightSensorTest
-#else
-#define MAYBE_AmbientLightSensorTest AmbientLightSensorTest
-#endif
-IN_PROC_BROWSER_TEST_F(GenericSensorBrowserTest, MAYBE_AmbientLightSensorTest) {
+IN_PROC_BROWSER_TEST_F(GenericSensorBrowserTest, AmbientLightSensorTest) {
// The test page will create an AmbientLightSensor object in Javascript,
// expects to get events with fake values then navigates to #pass.
GURL test_url =
diff --git a/chromium/content/browser/generic_sensor/sensor_provider_proxy_impl.cc b/chromium/content/browser/generic_sensor/sensor_provider_proxy_impl.cc
index 552320b0d36..174388b58fb 100644
--- a/chromium/content/browser/generic_sensor/sensor_provider_proxy_impl.cc
+++ b/chromium/content/browser/generic_sensor/sensor_provider_proxy_impl.cc
@@ -8,8 +8,8 @@
#include <utility>
#include <vector>
+#include "content/browser/permissions/permission_controller_impl.h"
#include "content/public/browser/browser_context.h"
-#include "content/public/browser/permission_manager.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -26,11 +26,12 @@ using device::mojom::SensorCreationResult;
namespace content {
SensorProviderProxyImpl::SensorProviderProxyImpl(
- PermissionManager* permission_manager,
+ PermissionControllerImpl* permission_controller,
RenderFrameHost* render_frame_host)
- : permission_manager_(permission_manager),
- render_frame_host_(render_frame_host) {
- DCHECK(permission_manager);
+ : permission_controller_(permission_controller),
+ render_frame_host_(render_frame_host),
+ weak_factory_(this) {
+ DCHECK(permission_controller);
DCHECK(render_frame_host);
}
@@ -43,36 +44,46 @@ void SensorProviderProxyImpl::Bind(
void SensorProviderProxyImpl::GetSensor(SensorType type,
GetSensorCallback callback) {
- ServiceManagerConnection* connection =
- ServiceManagerConnection::GetForProcess();
-
- if (!connection) {
- std::move(callback).Run(SensorCreationResult::ERROR_NOT_AVAILABLE, nullptr);
- return;
- }
-
- if (!CheckFeaturePolicies(type) || !CheckPermission()) {
+ if (!CheckFeaturePolicies(type)) {
std::move(callback).Run(SensorCreationResult::ERROR_NOT_ALLOWED, nullptr);
return;
}
if (!sensor_provider_) {
+ auto* connection = ServiceManagerConnection::GetForProcess();
+
+ if (!connection) {
+ std::move(callback).Run(SensorCreationResult::ERROR_NOT_AVAILABLE,
+ nullptr);
+ return;
+ }
+
connection->GetConnector()->BindInterface(
device::mojom::kServiceName, mojo::MakeRequest(&sensor_provider_));
sensor_provider_.set_connection_error_handler(base::BindOnce(
&SensorProviderProxyImpl::OnConnectionError, base::Unretained(this)));
}
- sensor_provider_->GetSensor(type, std::move(callback));
-}
-bool SensorProviderProxyImpl::CheckPermission() const {
- const GURL& requesting_origin =
- render_frame_host_->GetLastCommittedURL().GetOrigin();
+ // TODO(shalamov): base::BindOnce should be used (https://crbug.com/714018),
+ // however, PermissionController::RequestPermission enforces use of repeating
+ // callback.
+ permission_controller_->RequestPermission(
+ PermissionType::SENSORS, render_frame_host_,
+ render_frame_host_->GetLastCommittedURL().GetOrigin(), false,
+ base::BindRepeating(
+ &SensorProviderProxyImpl::OnPermissionRequestCompleted,
+ weak_factory_.GetWeakPtr(), type, base::Passed(std::move(callback))));
+}
- blink::mojom::PermissionStatus permission_status =
- permission_manager_->GetPermissionStatusForFrame(
- PermissionType::SENSORS, render_frame_host_, requesting_origin);
- return permission_status == blink::mojom::PermissionStatus::GRANTED;
+void SensorProviderProxyImpl::OnPermissionRequestCompleted(
+ device::mojom::SensorType type,
+ GetSensorCallback callback,
+ blink::mojom::PermissionStatus status) {
+ if (status != blink::mojom::PermissionStatus::GRANTED || !sensor_provider_) {
+ std::move(callback).Run(SensorCreationResult::ERROR_NOT_ALLOWED, nullptr);
+ return;
+ }
+ sensor_provider_->GetSensor(type, std::move(callback));
}
namespace {
diff --git a/chromium/content/browser/generic_sensor/sensor_provider_proxy_impl.h b/chromium/content/browser/generic_sensor/sensor_provider_proxy_impl.h
index 5947fab761e..41e673bddf4 100644
--- a/chromium/content/browser/generic_sensor/sensor_provider_proxy_impl.h
+++ b/chromium/content/browser/generic_sensor/sensor_provider_proxy_impl.h
@@ -5,21 +5,23 @@
#ifndef CONTENT_BROWSER_GENERIC_SENSOR_SENSOR_PROVIDER_PROXY_IMPL_H_
#define CONTENT_BROWSER_GENERIC_SENSOR_SENSOR_PROVIDER_PROXY_IMPL_H_
+#include "base/memory/weak_ptr.h"
#include "content/public/browser/web_contents_observer.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/device/public/mojom/sensor_provider.mojom.h"
+#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
namespace content {
-class PermissionManager;
+class PermissionControllerImpl;
class RenderFrameHost;
// This proxy acts as a gatekeeper to the real sensor provider so that this
// proxy can intercept sensor requests and allow or deny them based on
-// the permission statuses retrieved from a permission manager.
+// the permission statuses retrieved from a permission controller.
class SensorProviderProxyImpl final : public device::mojom::SensorProvider {
public:
- SensorProviderProxyImpl(PermissionManager* permission_manager,
+ SensorProviderProxyImpl(PermissionControllerImpl* permission_controller,
RenderFrameHost* render_frame_host);
~SensorProviderProxyImpl() override;
@@ -30,16 +32,19 @@ class SensorProviderProxyImpl final : public device::mojom::SensorProvider {
void GetSensor(device::mojom::SensorType type,
GetSensorCallback callback) override;
- bool CheckPermission() const;
bool CheckFeaturePolicies(device::mojom::SensorType type) const;
-
+ void OnPermissionRequestCompleted(device::mojom::SensorType type,
+ GetSensorCallback callback,
+ blink::mojom::PermissionStatus);
void OnConnectionError();
mojo::BindingSet<device::mojom::SensorProvider> binding_set_;
- PermissionManager* permission_manager_;
+ PermissionControllerImpl* permission_controller_;
RenderFrameHost* render_frame_host_;
device::mojom::SensorProviderPtr sensor_provider_;
+ base::WeakPtrFactory<SensorProviderProxyImpl> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(SensorProviderProxyImpl);
};
diff --git a/chromium/content/browser/geolocation/geolocation_service_impl.cc b/chromium/content/browser/geolocation/geolocation_service_impl.cc
index 80bdba2932e..342e68a8317 100644
--- a/chromium/content/browser/geolocation/geolocation_service_impl.cc
+++ b/chromium/content/browser/geolocation/geolocation_service_impl.cc
@@ -4,7 +4,7 @@
#include "content/browser/geolocation/geolocation_service_impl.h"
-#include "content/public/browser/permission_manager.h"
+#include "content/browser/permissions/permission_controller_impl.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_features.h"
@@ -13,9 +13,9 @@
namespace content {
GeolocationServiceImplContext::GeolocationServiceImplContext(
- PermissionManager* permission_manager)
- : permission_manager_(permission_manager),
- request_id_(PermissionManager::kNoPendingOperation),
+ PermissionControllerImpl* permission_controller)
+ : permission_controller_(permission_controller),
+ request_id_(PermissionController::kNoPendingOperation),
weak_factory_(this) {}
GeolocationServiceImplContext::~GeolocationServiceImplContext() {
@@ -25,14 +25,14 @@ void GeolocationServiceImplContext::RequestPermission(
RenderFrameHost* render_frame_host,
bool user_gesture,
const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
- if (request_id_ != PermissionManager::kNoPendingOperation) {
+ if (request_id_ != PermissionController::kNoPendingOperation) {
mojo::ReportBadMessage(
"GeolocationService client may only create one Geolocation at a "
"time.");
return;
}
- request_id_ = permission_manager_->RequestPermission(
+ request_id_ = permission_controller_->RequestPermission(
PermissionType::GEOLOCATION, render_frame_host,
render_frame_host->GetLastCommittedOrigin().GetURL(), user_gesture,
// NOTE: The permission request is canceled in the destructor, so it is
@@ -44,19 +44,19 @@ void GeolocationServiceImplContext::RequestPermission(
void GeolocationServiceImplContext::HandlePermissionStatus(
const base::Callback<void(blink::mojom::PermissionStatus)>& callback,
blink::mojom::PermissionStatus permission_status) {
- request_id_ = PermissionManager::kNoPendingOperation;
+ request_id_ = PermissionController::kNoPendingOperation;
callback.Run(permission_status);
}
GeolocationServiceImpl::GeolocationServiceImpl(
device::mojom::GeolocationContext* geolocation_context,
- PermissionManager* permission_manager,
+ PermissionControllerImpl* permission_controller,
RenderFrameHost* render_frame_host)
: geolocation_context_(geolocation_context),
- permission_manager_(permission_manager),
+ permission_controller_(permission_controller),
render_frame_host_(render_frame_host) {
DCHECK(geolocation_context);
- DCHECK(permission_manager);
+ DCHECK(permission_controller);
DCHECK(render_frame_host);
}
@@ -66,7 +66,7 @@ void GeolocationServiceImpl::Bind(
blink::mojom::GeolocationServiceRequest request) {
binding_set_.AddBinding(
this, std::move(request),
- std::make_unique<GeolocationServiceImplContext>(permission_manager_));
+ std::make_unique<GeolocationServiceImplContext>(permission_controller_));
}
void GeolocationServiceImpl::CreateGeolocation(
diff --git a/chromium/content/browser/geolocation/geolocation_service_impl.h b/chromium/content/browser/geolocation/geolocation_service_impl.h
index 68f6a2000bd..42548d97ad4 100644
--- a/chromium/content/browser/geolocation/geolocation_service_impl.h
+++ b/chromium/content/browser/geolocation/geolocation_service_impl.h
@@ -20,11 +20,12 @@ enum class PermissionStatus;
namespace content {
class RenderFrameHost;
-class PermissionManager;
+class PermissionControllerImpl;
class GeolocationServiceImplContext {
public:
- GeolocationServiceImplContext(PermissionManager* permission_manager_);
+ explicit GeolocationServiceImplContext(
+ PermissionControllerImpl* permission_controller);
~GeolocationServiceImplContext();
void RequestPermission(
RenderFrameHost* render_frame_host,
@@ -32,7 +33,7 @@ class GeolocationServiceImplContext {
const base::Callback<void(blink::mojom::PermissionStatus)>& callback);
private:
- PermissionManager* permission_manager_;
+ PermissionControllerImpl* permission_controller_;
int request_id_;
void HandlePermissionStatus(
@@ -48,7 +49,7 @@ class CONTENT_EXPORT GeolocationServiceImpl
: public blink::mojom::GeolocationService {
public:
GeolocationServiceImpl(device::mojom::GeolocationContext* geolocation_context,
- PermissionManager* permission_manager,
+ PermissionControllerImpl* permission_controller,
RenderFrameHost* render_frame_host);
~GeolocationServiceImpl() override;
@@ -68,7 +69,7 @@ class CONTENT_EXPORT GeolocationServiceImpl
blink::mojom::PermissionStatus permission_status);
device::mojom::GeolocationContext* geolocation_context_;
- PermissionManager* permission_manager_;
+ PermissionControllerImpl* permission_controller_;
RenderFrameHost* render_frame_host_;
// Along with each GeolocationService, we store a
diff --git a/chromium/content/browser/geolocation/geolocation_service_impl_unittest.cc b/chromium/content/browser/geolocation/geolocation_service_impl_unittest.cc
index 895cd610fe8..bb1ec33adf4 100644
--- a/chromium/content/browser/geolocation/geolocation_service_impl_unittest.cc
+++ b/chromium/content/browser/geolocation/geolocation_service_impl_unittest.cc
@@ -7,15 +7,17 @@
#include "base/bind_helpers.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
-#include "content/public/browser/permission_manager.h"
+#include "content/browser/permissions/permission_controller_impl.h"
+#include "content/public/browser/permission_controller.h"
#include "content/public/browser/permission_type.h"
#include "content/public/common/content_features.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/test/mock_permission_manager.h"
#include "content/public/test/navigation_simulator.h"
+#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_service_manager_context.h"
#include "content/test/test_render_frame_host.h"
-#include "device/geolocation/public/cpp/scoped_geolocation_overrider.h"
+#include "services/device/public/cpp/test/scoped_geolocation_overrider.h"
#include "services/device/public/mojom/constants.mojom.h"
#include "services/device/public/mojom/geolocation.mojom.h"
#include "services/device/public/mojom/geolocation_context.mojom.h"
@@ -45,7 +47,7 @@ GURL kEmbeddedUrl = GURL("https://embeddables.com/someframe");
class TestPermissionManager : public MockPermissionManager {
public:
TestPermissionManager()
- : request_id_(PermissionManager::kNoPendingOperation) {}
+ : request_id_(PermissionController::kNoPendingOperation) {}
~TestPermissionManager() override = default;
int RequestPermission(PermissionType permissions,
@@ -81,7 +83,11 @@ class GeolocationServiceTest : public RenderViewHostImplTestHarness {
void SetUp() override {
RenderViewHostImplTestHarness::SetUp();
NavigateAndCommit(kMainUrl);
- permission_manager_.reset(new TestPermissionManager);
+ browser_context_.reset(new content::TestBrowserContext());
+ browser_context_->SetPermissionControllerDelegate(
+ std::make_unique<TestPermissionManager>());
+ permission_controller_.reset(
+ new PermissionControllerImpl(browser_context_.get()));
service_manager_context_ = std::make_unique<TestServiceManagerContext>();
geolocation_overrider_ =
@@ -97,6 +103,7 @@ class GeolocationServiceTest : public RenderViewHostImplTestHarness {
context_ptr_.reset();
geolocation_overrider_.reset();
service_manager_context_.reset();
+ browser_context_.reset();
RenderViewHostImplTestHarness::TearDown();
}
@@ -116,7 +123,7 @@ class GeolocationServiceTest : public RenderViewHostImplTestHarness {
embedded_rfh = navigation_simulator->GetFinalRenderFrameHost();
service_.reset(new GeolocationServiceImpl(
- context_ptr_.get(), permission_manager_.get(), embedded_rfh));
+ context_ptr_.get(), permission_controller_.get(), embedded_rfh));
service_->Bind(mojo::MakeRequest(&service_ptr_));
}
@@ -125,7 +132,8 @@ class GeolocationServiceTest : public RenderViewHostImplTestHarness {
GeolocationService* service() { return &*service_ptr_; }
TestPermissionManager* permission_manager() {
- return permission_manager_.get();
+ return static_cast<TestPermissionManager*>(
+ browser_context_->GetPermissionControllerDelegate());
}
private:
@@ -134,7 +142,8 @@ class GeolocationServiceTest : public RenderViewHostImplTestHarness {
// 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<TestBrowserContext> browser_context_;
+ std::unique_ptr<PermissionControllerImpl> permission_controller_;
std::unique_ptr<GeolocationServiceImpl> service_;
GeolocationServicePtr service_ptr_;
device::mojom::GeolocationContextPtr context_ptr_;
diff --git a/chromium/content/browser/gpu/OWNERS b/chromium/content/browser/gpu/OWNERS
index c45f8fa6e23..55d9b9bde3d 100644
--- a/chromium/content/browser/gpu/OWNERS
+++ b/chromium/content/browser/gpu/OWNERS
@@ -1,5 +1,6 @@
kbr@chromium.org
piman@chromium.org
zmo@chromium.org
+backer@chromium.org
# COMPONENT: Internals>GPU>Internals
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 cdc4d3d678a..ca32413b3f3 100644
--- a/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/chromium/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -4,6 +4,7 @@
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
+#include "base/android/orderfile/orderfile_buildflags.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
@@ -15,6 +16,7 @@
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "components/viz/common/features.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
@@ -26,10 +28,15 @@
#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/in_process_command_buffer.h"
#include "services/resource_coordinator/public/mojom/memory_instrumentation/constants.mojom.h"
#include "services/service_manager/runner/common/client_util.h"
#include "ui/base/ui_base_features.h"
+#if defined(OS_MACOSX)
+#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
+#endif
+
namespace content {
#if defined(OS_ANDROID)
@@ -105,7 +112,13 @@ BrowserGpuChannelHostFactory::EstablishRequest::EstablishRequest(
gpu_client_id_(gpu_client_id),
gpu_client_tracing_id_(gpu_client_tracing_id),
finished_(false),
- main_task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
+#if defined(OS_MACOSX)
+ main_task_runner_(ui::WindowResizeHelperMac::Get()->task_runner())
+#else
+ main_task_runner_(base::ThreadTaskRunnerHandle::Get())
+#endif
+{
+}
void BrowserGpuChannelHostFactory::EstablishRequest::RestartTimeout() {
BrowserGpuChannelHostFactory* factory =
@@ -273,7 +286,7 @@ BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() {
void BrowserGpuChannelHostFactory::EstablishGpuChannel(
gpu::GpuChannelEstablishedCallback callback) {
#if defined(USE_AURA)
- DCHECK(!base::FeatureList::IsEnabled(::features::kMash));
+ DCHECK(features::IsAshInBrowserProcess());
#endif
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (gpu_channel_.get() && gpu_channel_->IsLost()) {
@@ -352,7 +365,7 @@ void BrowserGpuChannelHostFactory::RestartTimeout() {
return;
#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
- defined(CYGPROFILE_INSTRUMENTATION)
+ BUILDFLAG(ORDERFILE_INSTRUMENTATION)
constexpr int64_t kGpuChannelTimeoutInSeconds = 40;
#else
// The GPU watchdog timeout is 15 seconds (1.5x the kGpuTimeout value due to
@@ -371,6 +384,10 @@ void BrowserGpuChannelHostFactory::InitializeShaderDiskCacheOnIO(
int gpu_client_id,
const base::FilePath& cache_dir) {
GetShaderCacheFactorySingleton()->SetCacheInfo(gpu_client_id, cache_dir);
+ if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
+ GetShaderCacheFactorySingleton()->SetCacheInfo(
+ gpu::InProcessCommandBuffer::kGpuClientId, cache_dir);
+ }
}
} // namespace content
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 22d03d380b4..8568d3f5885 100644
--- a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
+++ b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.cc
@@ -141,7 +141,7 @@ void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess(
auto handle = gpu::GpuMemoryBufferImplSharedMemory::CreateGpuMemoryBuffer(
id, size, format, usage);
buffers.find(id)->second.shared_memory_guid = handle.handle.GetGUID();
- std::move(callback).Run(handle);
+ std::move(callback).Run(std::move(handle));
}
void BrowserGpuMemoryBufferManager::SetDestructionSyncToken(
@@ -310,7 +310,7 @@ void BrowserGpuMemoryBufferManager::HandleCreateGpuMemoryBufferOnIO(
void BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO(
CreateGpuMemoryBufferRequest* request,
- const gfx::GpuMemoryBufferHandle& handle) {
+ gfx::GpuMemoryBufferHandle handle) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Early out if factory failed to create the buffer.
@@ -321,15 +321,16 @@ void BrowserGpuMemoryBufferManager::HandleGpuMemoryBufferCreatedOnIO(
// Note: Unretained is safe as IO thread is stopped before manager is
// destroyed.
+ auto handle_id = handle.id;
request->result =
gpu_memory_buffer_support_->CreateGpuMemoryBufferImplFromHandle(
- handle, request->size, request->format, request->usage,
+ std::move(handle), request->size, request->format, request->usage,
base::Bind(
&GpuMemoryBufferDeleted,
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
base::Bind(
&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO,
- base::Unretained(this), handle.id, request->client_id)));
+ base::Unretained(this), handle_id, request->client_id)));
request->event.Signal();
}
@@ -377,7 +378,7 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO(
int client_id,
int gpu_host_id,
CreateCallback callback,
- const gfx::GpuMemoryBufferHandle& handle,
+ gfx::GpuMemoryBufferHandle handle,
GpuProcessHost::BufferCreationStatus status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -432,7 +433,7 @@ void BrowserGpuMemoryBufferManager::GpuMemoryBufferCreatedOnIO(
buffer_it->second.gpu_host_id = gpu_host_id;
buffer_it->second.shared_memory_guid = handle.handle.GetGUID();
- std::move(callback).Run(handle);
+ std::move(callback).Run(std::move(handle));
}
void BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO(
diff --git a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h
index 41843a9309c..4cf2b632fb0 100644
--- a/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h
+++ b/chromium/content/browser/gpu/browser_gpu_memory_buffer_manager.h
@@ -33,7 +33,7 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
public base::trace_event::MemoryDumpProvider {
public:
using CreateCallback =
- base::OnceCallback<void(const gfx::GpuMemoryBufferHandle& handle)>;
+ base::OnceCallback<void(gfx::GpuMemoryBufferHandle handle)>;
using AllocationCallback = CreateCallback;
BrowserGpuMemoryBufferManager(int gpu_client_id,
@@ -98,9 +98,8 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
// Functions that handle synchronous buffer creation requests.
void HandleCreateGpuMemoryBufferOnIO(CreateGpuMemoryBufferRequest* request);
- void HandleGpuMemoryBufferCreatedOnIO(
- CreateGpuMemoryBufferRequest* request,
- const gfx::GpuMemoryBufferHandle& handle);
+ void HandleGpuMemoryBufferCreatedOnIO(CreateGpuMemoryBufferRequest* request,
+ gfx::GpuMemoryBufferHandle handle);
// Functions that implement asynchronous buffer creation.
void CreateGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id,
@@ -115,7 +114,7 @@ class CONTENT_EXPORT BrowserGpuMemoryBufferManager
int client_id,
int gpu_host_id,
CreateCallback callback,
- const gfx::GpuMemoryBufferHandle& handle,
+ gfx::GpuMemoryBufferHandle handle,
GpuProcessHost::BufferCreationStatus status);
void DestroyGpuMemoryBufferOnIO(gfx::GpuMemoryBufferId id,
int client_id,
diff --git a/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc b/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc
new file mode 100644
index 00000000000..8f3efa6a705
--- /dev/null
+++ b/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.cc
@@ -0,0 +1,115 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/gpu/ca_transaction_gpu_coordinator.h"
+
+#include "base/cancelable_callback.h"
+#include "content/browser/gpu/gpu_process_host.h"
+#include "content/public/browser/browser_thread.h"
+#include "services/viz/privileged/interfaces/gl/gpu_service.mojom.h"
+#include "ui/accelerated_widget_mac/ca_transaction_observer.h"
+#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
+
+namespace content {
+
+// static
+scoped_refptr<CATransactionGPUCoordinator> CATransactionGPUCoordinator::Create(
+ GpuProcessHost* host) {
+ scoped_refptr<CATransactionGPUCoordinator> result(
+ new CATransactionGPUCoordinator(host));
+ // Avoid modifying result's refcount in the constructor by performing this
+ // PostTask afterward.
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ui::WindowResizeHelperMac::Get()->task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &CATransactionGPUCoordinator::AddPostCommitObserverOnUIThread,
+ result));
+ return result;
+}
+
+CATransactionGPUCoordinator::CATransactionGPUCoordinator(GpuProcessHost* host)
+ : host_(host) {}
+
+CATransactionGPUCoordinator::~CATransactionGPUCoordinator() {
+ DCHECK(!host_);
+ DCHECK(!registered_as_observer_);
+}
+
+void CATransactionGPUCoordinator::HostWillBeDestroyed() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ui::WindowResizeHelperMac::Get()->task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &CATransactionGPUCoordinator::RemovePostCommitObserverOnUIThread,
+ this));
+ host_ = nullptr;
+}
+
+void CATransactionGPUCoordinator::AddPostCommitObserverOnUIThread() {
+ DCHECK(!registered_as_observer_);
+ ui::CATransactionCoordinator::Get().AddPostCommitObserver(this);
+ registered_as_observer_ = true;
+}
+
+void CATransactionGPUCoordinator::RemovePostCommitObserverOnUIThread() {
+ DCHECK(registered_as_observer_);
+ ui::CATransactionCoordinator::Get().RemovePostCommitObserver(this);
+ registered_as_observer_ = false;
+}
+
+void CATransactionGPUCoordinator::OnActivateForTransaction() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&CATransactionGPUCoordinator::OnActivateForTransactionOnIO,
+ this));
+}
+
+void CATransactionGPUCoordinator::OnEnterPostCommit() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ // If HostWillBeDestroyed() is called during a commit, pending_commit_count_
+ // may be left non-zero. That's fine as long as this instance is destroyed
+ // (and removed from the list of post-commit observers) soon after.
+ pending_commit_count_++;
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&CATransactionGPUCoordinator::OnEnterPostCommitOnIO,
+ this));
+}
+
+bool CATransactionGPUCoordinator::ShouldWaitInPostCommit() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return pending_commit_count_ > 0;
+}
+
+void CATransactionGPUCoordinator::OnActivateForTransactionOnIO() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (host_)
+ host_->gpu_service()->BeginCATransaction();
+}
+
+void CATransactionGPUCoordinator::OnEnterPostCommitOnIO() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (host_)
+ host_->gpu_service()->CommitCATransaction(base::BindOnce(
+ &CATransactionGPUCoordinator::OnCommitCompletedOnIO, this));
+}
+
+void CATransactionGPUCoordinator::OnCommitCompletedOnIO() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ ui::WindowResizeHelperMac::Get()->task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&CATransactionGPUCoordinator::OnCommitCompletedOnUI,
+ this));
+}
+
+void CATransactionGPUCoordinator::OnCommitCompletedOnUI() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ pending_commit_count_--;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.h b/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.h
new file mode 100644
index 00000000000..53b52a25d3f
--- /dev/null
+++ b/chromium/content/browser/gpu/ca_transaction_gpu_coordinator.h
@@ -0,0 +1,60 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_GPU_CA_TRANSACTION_GPU_COORDINATOR_H_
+#define CONTENT_BROWSER_GPU_CA_TRANSACTION_GPU_COORDINATOR_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "ui/accelerated_widget_mac/ca_transaction_observer.h"
+
+#include <memory>
+
+namespace content {
+
+class GpuProcessHost;
+
+// Synchronizes CATransaction commits between the browser and GPU processes.
+class CATransactionGPUCoordinator
+ : public ui::CATransactionCoordinator::PostCommitObserver {
+ public:
+ static scoped_refptr<CATransactionGPUCoordinator> Create(
+ GpuProcessHost* host);
+ void HostWillBeDestroyed();
+
+ private:
+ friend class base::RefCountedThreadSafe<CATransactionGPUCoordinator>;
+ CATransactionGPUCoordinator(GpuProcessHost* host);
+ ~CATransactionGPUCoordinator() override;
+
+ // ui::CATransactionObserver implementation
+ void OnActivateForTransaction() override;
+ void OnEnterPostCommit() override;
+ bool ShouldWaitInPostCommit() override;
+
+ void AddPostCommitObserverOnUIThread();
+ void RemovePostCommitObserverOnUIThread();
+
+ void OnActivateForTransactionOnIO();
+ void OnEnterPostCommitOnIO();
+ void OnCommitCompletedOnIO();
+ void OnCommitCompletedOnUI();
+
+ // The GpuProcessHost to use to initiate GPU-side CATransactions. This is only
+ // to be accessed on the IO thread.
+ GpuProcessHost* host_ = nullptr;
+
+ // The number CATransactions that have not yet completed. This is only to be
+ // accessed on the UI thread.
+ int pending_commit_count_ = 0;
+
+ // Egregious state tracking to debug https://crbug.com/871430
+ bool registered_as_observer_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(CATransactionGPUCoordinator);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_GPU_CA_TRANSACTION_GPU_COORDINATOR_H_
diff --git a/chromium/content/browser/gpu/compositor_util.cc b/chromium/content/browser/gpu/compositor_util.cc
index db3b6606770..9773ec885ea 100644
--- a/chromium/content/browser/gpu/compositor_util.cc
+++ b/chromium/content/browser/gpu/compositor_util.cc
@@ -161,6 +161,13 @@ const GpuFeatureData GetGpuFeatureData(
"Accelerated rasterization has been disabled, either via blacklist, "
"about:flags or the command line.",
true, true},
+ {"oop_rasterization",
+ SafeGetFeatureStatus(gpu_feature_info,
+ gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION),
+ command_line.HasSwitch(switches::kDisableOopRasterization),
+ "Out-of-process accelerated rasterization has been disabled, either "
+ "via blacklist, about:flags or the command line.",
+ false, true},
{"multiple_raster_threads", gpu::kGpuFeatureStatusEnabled,
NumberOfRendererRasterThreads() == 1, "Raster is using a single thread.",
false, true},
@@ -215,8 +222,12 @@ std::unique_ptr<base::DictionaryValue> GetFeatureStatusImpl(
const GpuFeatureData gpu_feature_data =
GetGpuFeatureData(gpu_feature_info, type, i, &eof);
std::string status;
- if (gpu_feature_data.disabled || gpu_access_blocked ||
- gpu_feature_data.status == gpu::kGpuFeatureStatusDisabled) {
+ if (gpu_feature_data.name == "surface_synchronization") {
+ status = (!gpu_feature_data.disabled ? "enabled_on" : "disabled_off");
+ } else if (gpu_feature_data.name == "viz_display_compositor") {
+ status = (!gpu_feature_data.disabled ? "enabled_on" : "disabled_off");
+ } else if (gpu_feature_data.disabled || gpu_access_blocked ||
+ gpu_feature_data.status == gpu::kGpuFeatureStatusDisabled) {
status = "disabled";
if (gpu_feature_data.fallback_to_software)
status += "_software";
@@ -244,14 +255,6 @@ std::unique_ptr<base::DictionaryValue> GetFeatureStatusImpl(
status += "_force";
status += "_on";
}
- if (gpu_feature_data.name == "surface_synchronization") {
- if (features::IsSurfaceSynchronizationEnabled())
- status += "_on";
- }
- if (gpu_feature_data.name == "viz_display_compositor") {
- if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor))
- status += "_on";
- }
if (gpu_feature_data.name == "skia_renderer") {
if (features::IsUsingSkiaRenderer())
status += "_on";
diff --git a/chromium/content/browser/gpu/gpu_client_impl.cc b/chromium/content/browser/gpu/gpu_client_impl.cc
index a591794d329..c2ef9591cd3 100644
--- a/chromium/content/browser/gpu/gpu_client_impl.cc
+++ b/chromium/content/browser/gpu/gpu_client_impl.cc
@@ -7,7 +7,6 @@
#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"
-#include "content/public/browser/browser_thread.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "gpu/ipc/common/gpu_memory_buffer_impl.h"
#include "gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.h"
@@ -15,51 +14,67 @@
namespace content {
// static
-std::unique_ptr<GpuClient, BrowserThread::DeleteOnIOThread> GpuClient::Create(
+std::unique_ptr<GpuClient, base::OnTaskRunnerDeleter> GpuClient::Create(
ui::mojom::GpuRequest request,
- ConnectionErrorHandlerClosure connection_error_handler) {
- std::unique_ptr<GpuClientImpl, BrowserThread::DeleteOnIOThread> gpu_client(
- new GpuClientImpl(ChildProcessHostImpl::GenerateChildProcessUniqueId()));
+ ConnectionErrorHandlerClosure connection_error_handler,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ const int client_id = ChildProcessHostImpl::GenerateChildProcessUniqueId();
+ const uint64_t client_tracing_id =
+ ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(client_id);
+ std::unique_ptr<GpuClientImpl, base::OnTaskRunnerDeleter> gpu_client(
+ new GpuClientImpl(client_id, client_tracing_id, task_runner),
+ base::OnTaskRunnerDeleter(task_runner));
gpu_client->SetConnectionErrorHandler(std::move(connection_error_handler));
gpu_client->Add(std::move(request));
return gpu_client;
}
-GpuClientImpl::GpuClientImpl(int render_process_id)
- : render_process_id_(render_process_id), weak_factory_(this) {
- bindings_.set_connection_error_handler(
- base::Bind(&GpuClientImpl::OnError, base::Unretained(this),
- ErrorReason::kConnectionLost));
+GpuClientImpl::GpuClientImpl(
+ int client_id,
+ uint64_t client_tracing_id,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : client_id_(client_id),
+ client_tracing_id_(client_tracing_id),
+ task_runner_(std::move(task_runner)),
+ weak_factory_(this) {
+ gpu_bindings_.set_connection_error_handler(
+ base::BindRepeating(&GpuClientImpl::OnError, base::Unretained(this),
+ ErrorReason::kConnectionLost));
}
GpuClientImpl::~GpuClientImpl() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- bindings_.CloseAllBindings();
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ gpu_bindings_.CloseAllBindings();
OnError(ErrorReason::kInDestructor);
}
void GpuClientImpl::Add(ui::mojom::GpuRequest request) {
- bindings_.AddBinding(this, std::move(request));
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ gpu_bindings_.AddBinding(this, std::move(request));
}
void GpuClientImpl::OnError(ErrorReason reason) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
ClearCallback();
- if (bindings_.empty()) {
+ if (gpu_bindings_.empty()) {
BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager =
BrowserGpuMemoryBufferManager::current();
if (gpu_memory_buffer_manager)
- gpu_memory_buffer_manager->ProcessRemoved(render_process_id_);
+ gpu_memory_buffer_manager->ProcessRemoved(client_id_);
}
if (reason == ErrorReason::kConnectionLost && connection_error_handler_)
std::move(connection_error_handler_).Run(this);
}
void GpuClientImpl::PreEstablishGpuChannel() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&GpuClientImpl::EstablishGpuChannel,
- base::Unretained(this), EstablishGpuChannelCallback()));
+ if (task_runner_->RunsTasksInCurrentSequence()) {
+ EstablishGpuChannel(EstablishGpuChannelCallback());
+ } else {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&GpuClientImpl::EstablishGpuChannel,
+ base::Unretained(this), EstablishGpuChannelCallback()));
+ }
}
void GpuClientImpl::SetConnectionErrorHandler(
@@ -85,8 +100,8 @@ void GpuClientImpl::OnEstablishGpuChannel(
}
if (callback) {
// A request is waiting.
- std::move(callback).Run(render_process_id_, std::move(channel_handle),
- gpu_info, gpu_feature_info);
+ std::move(callback).Run(client_id_, std::move(channel_handle), gpu_info,
+ gpu_feature_info);
return;
}
if (status == GpuProcessHost::EstablishChannelStatus::SUCCESS) {
@@ -100,21 +115,21 @@ void GpuClientImpl::OnEstablishGpuChannel(
void GpuClientImpl::OnCreateGpuMemoryBuffer(
CreateGpuMemoryBufferCallback callback,
- const gfx::GpuMemoryBufferHandle& handle) {
- std::move(callback).Run(handle);
+ gfx::GpuMemoryBufferHandle handle) {
+ std::move(callback).Run(std::move(handle));
}
void GpuClientImpl::ClearCallback() {
if (!callback_)
return;
EstablishGpuChannelCallback callback = std::move(callback_);
- std::move(callback).Run(render_process_id_, mojo::ScopedMessagePipeHandle(),
+ std::move(callback).Run(client_id_, mojo::ScopedMessagePipeHandle(),
gpu::GPUInfo(), gpu::GpuFeatureInfo());
DCHECK(!callback_);
}
void GpuClientImpl::EstablishGpuChannel(EstablishGpuChannelCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
// At most one channel should be requested. So clear previous request first.
ClearCallback();
if (channel_handle_.is_valid()) {
@@ -123,8 +138,8 @@ void GpuClientImpl::EstablishGpuChannel(EstablishGpuChannelCallback callback) {
// 2) if callback is empty, it's PreEstablishGpyChannel() being called
// more than once, no need to do anything.
if (callback) {
- std::move(callback).Run(render_process_id_, std::move(channel_handle_),
- gpu_info_, gpu_feature_info_);
+ std::move(callback).Run(client_id_, std::move(channel_handle_), gpu_info_,
+ gpu_feature_info_);
DCHECK(!channel_handle_.is_valid());
}
return;
@@ -132,9 +147,8 @@ void GpuClientImpl::EstablishGpuChannel(EstablishGpuChannelCallback callback) {
GpuProcessHost* host = GpuProcessHost::Get();
if (!host) {
if (callback) {
- std::move(callback).Run(render_process_id_,
- mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
- gpu::GpuFeatureInfo());
+ std::move(callback).Run(client_id_, mojo::ScopedMessagePipeHandle(),
+ gpu::GPUInfo(), gpu::GpuFeatureInfo());
}
return;
}
@@ -146,12 +160,10 @@ void GpuClientImpl::EstablishGpuChannel(EstablishGpuChannelCallback callback) {
bool allow_view_command_buffers = false;
bool allow_real_time_streams = false;
host->EstablishGpuChannel(
- render_process_id_,
- ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(
- render_process_id_),
- preempts, allow_view_command_buffers, allow_real_time_streams,
- base::Bind(&GpuClientImpl::OnEstablishGpuChannel,
- weak_factory_.GetWeakPtr()));
+ client_id_, client_tracing_id_, preempts, allow_view_command_buffers,
+ allow_real_time_streams,
+ base::BindRepeating(&GpuClientImpl::OnEstablishGpuChannel,
+ weak_factory_.GetWeakPtr()));
}
void GpuClientImpl::CreateJpegDecodeAccelerator(
@@ -175,7 +187,7 @@ void GpuClientImpl::CreateGpuMemoryBuffer(
const gfx::Size& size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
- ui::mojom::Gpu::CreateGpuMemoryBufferCallback callback) {
+ ui::mojom::GpuMemoryBufferFactory::CreateGpuMemoryBufferCallback callback) {
DCHECK(BrowserGpuMemoryBufferManager::current());
base::CheckedNumeric<int> bytes = size.width();
@@ -187,7 +199,7 @@ void GpuClientImpl::CreateGpuMemoryBuffer(
BrowserGpuMemoryBufferManager::current()
->AllocateGpuMemoryBufferForChildProcess(
- id, size, format, usage, render_process_id_,
+ id, size, format, usage, client_id_,
base::BindOnce(&GpuClientImpl::OnCreateGpuMemoryBuffer,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
@@ -197,7 +209,12 @@ void GpuClientImpl::DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
DCHECK(BrowserGpuMemoryBufferManager::current());
BrowserGpuMemoryBufferManager::current()->ChildProcessDeletedGpuMemoryBuffer(
- id, render_process_id_, sync_token);
+ id, client_id_, sync_token);
+}
+
+void GpuClientImpl::CreateGpuMemoryBufferFactory(
+ ui::mojom::GpuMemoryBufferFactoryRequest request) {
+ gpu_memory_buffer_factory_bindings_.AddBinding(this, std::move(request));
}
} // namespace content
diff --git a/chromium/content/browser/gpu/gpu_client_impl.h b/chromium/content/browser/gpu/gpu_client_impl.h
index 03e29bf4b5f..70e684a68be 100644
--- a/chromium/content/browser/gpu/gpu_client_impl.h
+++ b/chromium/content/browser/gpu/gpu_client_impl.h
@@ -13,11 +13,19 @@
namespace content {
-class GpuClientImpl : public ui::mojom::Gpu, public GpuClient {
+class GpuClientImpl : public ui::mojom::GpuMemoryBufferFactory,
+ public ui::mojom::Gpu,
+ public GpuClient {
public:
- explicit GpuClientImpl(int render_process_id);
+ // GpuClientImpl must be destroyed on the thread associated with
+ // |task_runner|.
+ GpuClientImpl(int client_id,
+ uint64_t client_tracing_id,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
+
~GpuClientImpl() override;
+ // This needs to be run on the thread associated with |task_runner_|.
void Add(ui::mojom::GpuRequest request);
void PreEstablishGpuChannel();
@@ -25,6 +33,27 @@ class GpuClientImpl : public ui::mojom::Gpu, public GpuClient {
void SetConnectionErrorHandler(
ConnectionErrorHandlerClosure connection_error_handler);
+ // ui::mojom::GpuMemoryBufferFactory overrides:
+ void CreateGpuMemoryBuffer(
+ gfx::GpuMemoryBufferId id,
+ const gfx::Size& size,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ ui::mojom::GpuMemoryBufferFactory::CreateGpuMemoryBufferCallback callback)
+ override;
+ void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
+ const gpu::SyncToken& sync_token) override;
+
+ // ui::mojom::Gpu overrides:
+ void CreateGpuMemoryBufferFactory(
+ ui::mojom::GpuMemoryBufferFactoryRequest request) override;
+ void EstablishGpuChannel(EstablishGpuChannelCallback callback) override;
+ void CreateJpegDecodeAccelerator(
+ media::mojom::JpegDecodeAcceleratorRequest jda_request) override;
+ void CreateVideoEncodeAcceleratorProvider(
+ media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request)
+ override;
+
private:
enum class ErrorReason {
// OnError() is being called from the destructor.
@@ -38,33 +67,24 @@ class GpuClientImpl : public ui::mojom::Gpu, public GpuClient {
const gpu::GpuFeatureInfo& gpu_feature_info,
GpuProcessHost::EstablishChannelStatus status);
void OnCreateGpuMemoryBuffer(CreateGpuMemoryBufferCallback callback,
- const gfx::GpuMemoryBufferHandle& handle);
+ gfx::GpuMemoryBufferHandle handle);
void ClearCallback();
- // ui::mojom::Gpu overrides:
- void EstablishGpuChannel(EstablishGpuChannelCallback callback) override;
- void CreateJpegDecodeAccelerator(
- media::mojom::JpegDecodeAcceleratorRequest jda_request) override;
- void CreateVideoEncodeAcceleratorProvider(
- media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request)
- override;
- void CreateGpuMemoryBuffer(
- gfx::GpuMemoryBufferId id,
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::BufferUsage usage,
- ui::mojom::Gpu::CreateGpuMemoryBufferCallback callback) override;
- void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id,
- const gpu::SyncToken& sync_token) override;
-
- const int render_process_id_;
- mojo::BindingSet<ui::mojom::Gpu> bindings_;
+ const int client_id_;
+ const uint64_t client_tracing_id_;
+ mojo::BindingSet<ui::mojom::GpuMemoryBufferFactory>
+ gpu_memory_buffer_factory_bindings_;
+ mojo::BindingSet<ui::mojom::Gpu> gpu_bindings_;
bool gpu_channel_requested_ = false;
EstablishGpuChannelCallback callback_;
mojo::ScopedMessagePipeHandle channel_handle_;
gpu::GPUInfo gpu_info_;
gpu::GpuFeatureInfo gpu_feature_info_;
ConnectionErrorHandlerClosure connection_error_handler_;
+ // |task_runner_| is associated with the thread |gpu_bindings_| is bound on.
+ // GpuClientImpl instance is bound to this thread, and must be destroyed on
+ // this thread.
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::WeakPtrFactory<GpuClientImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(GpuClientImpl);
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl.cc b/chromium/content/browser/gpu/gpu_data_manager_impl.cc
index 3c8b665a48a..f6d3d4c18f1 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl.cc
@@ -16,7 +16,8 @@ GpuDataManager* GpuDataManager::GetInstance() {
// static
GpuDataManagerImpl* GpuDataManagerImpl::GetInstance() {
- return base::Singleton<GpuDataManagerImpl>::get();
+ static base::NoDestructor<GpuDataManagerImpl> instance;
+ return instance.get();
}
void GpuDataManagerImpl::BlacklistWebGLForTesting() {
@@ -79,16 +80,6 @@ void GpuDataManagerImpl::DisableHardwareAcceleration() {
private_->DisableHardwareAcceleration();
}
-void GpuDataManagerImpl::BlockSwiftShader() {
- base::AutoLock auto_lock(lock_);
- private_->BlockSwiftShader();
-}
-
-bool GpuDataManagerImpl::SwiftShaderAllowed() const {
- base::AutoLock auto_lock(lock_);
- return private_->SwiftShaderAllowed();
-}
-
bool GpuDataManagerImpl::HardwareAccelerationEnabled() const {
base::AutoLock auto_lock(lock_);
return private_->HardwareAccelerationEnabled();
@@ -207,9 +198,14 @@ void GpuDataManagerImpl::NotifyGpuInfoUpdate() {
private_->NotifyGpuInfoUpdate();
}
-void GpuDataManagerImpl::OnGpuProcessInitFailure() {
+gpu::GpuMode GpuDataManagerImpl::GetGpuMode() const {
+ base::AutoLock auto_lock(lock_);
+ return private_->GetGpuMode();
+}
+
+void GpuDataManagerImpl::FallBackToNextGpuMode() {
base::AutoLock auto_lock(lock_);
- private_->OnGpuProcessInitFailure();
+ private_->FallBackToNextGpuMode();
}
bool GpuDataManagerImpl::IsGpuProcessUsingHardwareGpu() const {
@@ -217,11 +213,14 @@ bool GpuDataManagerImpl::IsGpuProcessUsingHardwareGpu() const {
return private_->IsGpuProcessUsingHardwareGpu();
}
-GpuDataManagerImpl::GpuDataManagerImpl()
- : private_(GpuDataManagerImplPrivate::Create(this)) {
+void GpuDataManagerImpl::SetApplicationVisible(bool is_visible) {
+ base::AutoLock auto_lock(lock_);
+ private_->SetApplicationVisible(is_visible);
}
-GpuDataManagerImpl::~GpuDataManagerImpl() {
-}
+GpuDataManagerImpl::GpuDataManagerImpl()
+ : private_(std::make_unique<GpuDataManagerImplPrivate>(this)) {}
+
+GpuDataManagerImpl::~GpuDataManagerImpl() = default;
} // namespace content
diff --git a/chromium/content/browser/gpu/gpu_data_manager_impl.h b/chromium/content/browser/gpu/gpu_data_manager_impl.h
index 06210a34e80..d91d77659f3 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl.h
@@ -14,7 +14,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/macros.h"
-#include "base/memory/singleton.h"
+#include "base/no_destructor.h"
#include "base/process/kill.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
@@ -24,6 +24,7 @@
#include "gpu/config/gpu_control_list.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_info.h"
+#include "gpu/config/gpu_mode.h"
class GURL;
@@ -149,44 +150,27 @@ class CONTENT_EXPORT GpuDataManagerImpl : public GpuDataManager {
// status update.
void NotifyGpuInfoUpdate();
- // Called when GPU process initialization failed.
- void OnGpuProcessInitFailure();
+ // Return mode describing what the GPU process will be launched to run.
+ gpu::GpuMode GetGpuMode() const;
- void BlockSwiftShader();
- bool SwiftShaderAllowed() const;
+ // Called when GPU process initialization failed or the GPU process has
+ // crashed repeatedly. This will try to disable hardware acceleration and then
+ // SwiftShader WebGL. It will also crash the browser process as a last resort
+ // on Android and Chrome OS.
+ void FallBackToNextGpuMode();
// Returns false if the latest GPUInfo gl_renderer is from SwiftShader or
// Disabled (in the viz case).
bool IsGpuProcessUsingHardwareGpu() const;
+ // State tracking allows us to customize GPU process launch depending on
+ // whether we are in the foreground or background.
+ void SetApplicationVisible(bool is_visible);
+
private:
friend class GpuDataManagerImplPrivate;
friend class GpuDataManagerImplPrivateTest;
- friend struct base::DefaultSingletonTraits<GpuDataManagerImpl>;
-
- // It's similar to AutoUnlock, but we want to make it a no-op
- // if the owner GpuDataManagerImpl is null.
- // This should only be used by GpuDataManagerImplPrivate where
- // callbacks are called, during which re-entering
- // GpuDataManagerImpl is possible.
- class UnlockedSession {
- public:
- explicit UnlockedSession(GpuDataManagerImpl* owner)
- : owner_(owner) {
- DCHECK(owner_);
- owner_->lock_.AssertAcquired();
- owner_->lock_.Release();
- }
-
- ~UnlockedSession() {
- DCHECK(owner_);
- owner_->lock_.Acquire();
- }
-
- private:
- GpuDataManagerImpl* owner_;
- DISALLOW_COPY_AND_ASSIGN(UnlockedSession);
- };
+ friend class base::NoDestructor<GpuDataManagerImpl>;
GpuDataManagerImpl();
~GpuDataManagerImpl() override;
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 e3b41337158..63797576500 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -32,17 +32,16 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
-#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/config/gpu_blacklist.h"
#include "gpu/config/gpu_driver_bug_list.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/config/gpu_finch_features.h"
#include "gpu/config/gpu_info_collector.h"
+#include "gpu/config/gpu_preferences.h"
#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/gpu_memory_buffer_support.h"
#include "gpu/ipc/host/shader_disk_cache.h"
@@ -118,18 +117,21 @@ void UpdateFeatureStats(const gpu::GpuFeatureInfo& gpu_feature_info) {
gpu::GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS,
gpu::GPU_FEATURE_TYPE_GPU_COMPOSITING,
gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION,
+ gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION,
gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL,
gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL2};
const std::string kGpuBlacklistFeatureHistogramNames[] = {
"GPU.BlacklistFeatureTestResults.Accelerated2dCanvas",
"GPU.BlacklistFeatureTestResults.GpuCompositing",
"GPU.BlacklistFeatureTestResults.GpuRasterization",
+ "GPU.BlacklistFeatureTestResults.OopRasterization",
"GPU.BlacklistFeatureTestResults.Webgl",
"GPU.BlacklistFeatureTestResults.Webgl2"};
const bool kGpuFeatureUserFlags[] = {
command_line.HasSwitch(switches::kDisableAccelerated2dCanvas),
command_line.HasSwitch(switches::kDisableGpu),
command_line.HasSwitch(switches::kDisableGpuRasterization),
+ command_line.HasSwitch(switches::kDisableOopRasterization),
command_line.HasSwitch(switches::kDisableWebGL),
(command_line.HasSwitch(switches::kDisableWebGL) ||
command_line.HasSwitch(switches::kDisableWebGL2))};
@@ -138,6 +140,7 @@ void UpdateFeatureStats(const gpu::GpuFeatureInfo& gpu_feature_info) {
"GPU.BlacklistFeatureTestResultsWindows2.Accelerated2dCanvas",
"GPU.BlacklistFeatureTestResultsWindows2.GpuCompositing",
"GPU.BlacklistFeatureTestResultsWindows2.GpuRasterization",
+ "GPU.BlacklistFeatureTestResultsWindows2.OopRasterization",
"GPU.BlacklistFeatureTestResultsWindows2.Webgl",
"GPU.BlacklistFeatureTestResultsWindows2.Webgl2"};
#endif
@@ -263,6 +266,35 @@ void UpdateGpuInfoOnIO(const gpu::GPUInfo& gpu_info) {
} // anonymous namespace
+GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(GpuDataManagerImpl* owner)
+ : owner_(owner),
+ observer_list_(base::MakeRefCounted<GpuDataManagerObserverList>()) {
+ DCHECK(owner_);
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kDisableGpu))
+ DisableHardwareAcceleration();
+
+ if (command_line->HasSwitch(switches::kSingleProcess) ||
+ command_line->HasSwitch(switches::kInProcessGPU)) {
+ in_process_gpu_ = true;
+ AppendGpuCommandLine(command_line);
+ }
+
+#if defined(OS_MACOSX)
+ CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, owner_);
+#endif // OS_MACOSX
+
+ // For testing only.
+ if (command_line->HasSwitch(switches::kDisableDomainBlockingFor3DAPIs))
+ domain_blocking_enabled_ = false;
+}
+
+GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() {
+#if defined(OS_MACOSX)
+ CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, owner_);
+#endif
+}
+
void GpuDataManagerImplPrivate::BlacklistWebGLForTesting() {
// This function is for testing only, so disable histograms.
update_histograms_ = false;
@@ -286,8 +318,7 @@ gpu::GPUInfo GpuDataManagerImplPrivate::GetGPUInfoForHardwareGpu() const {
return gpu_info_for_hardware_gpu_;
}
-bool GpuDataManagerImplPrivate::GpuAccessAllowed(
- std::string* reason) const {
+bool GpuDataManagerImplPrivate::GpuAccessAllowed(std::string* reason) const {
bool swiftshader_available = false;
#if BUILDFLAG(ENABLE_SWIFTSHADER)
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -322,8 +353,19 @@ bool GpuDataManagerImplPrivate::GpuAccessAllowed(
}
bool GpuDataManagerImplPrivate::GpuProcessStartAllowed() const {
- return base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
- GpuAccessAllowed(nullptr);
+ if (GpuAccessAllowed(nullptr))
+ return true;
+
+#if defined(USE_X11) || defined(OS_MACOSX)
+ // If GPU access is disabled with OOP-D we run the display compositor in:
+ // Browser process: Windows
+ // GPU process: Linux and Mac
+ // N/A: Android and Chrome OS (GPU access can't be disabled)
+ if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor))
+ return true;
+#endif
+
+ return false;
}
void GpuDataManagerImplPrivate::RequestCompleteGpuInfoIfNeeded() {
@@ -395,13 +437,11 @@ void GpuDataManagerImplPrivate::RequestVideoMemoryUsageStatsUpdate(
}
void GpuDataManagerImplPrivate::AddObserver(GpuDataManagerObserver* observer) {
- GpuDataManagerImpl::UnlockedSession session(owner_);
observer_list_->AddObserver(observer);
}
void GpuDataManagerImplPrivate::RemoveObserver(
GpuDataManagerObserver* observer) {
- GpuDataManagerImpl::UnlockedSession session(owner_);
observer_list_->RemoveObserver(observer);
}
@@ -514,7 +554,7 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine(
gpu::GpuPreferences gpu_prefs = GetGpuPreferencesFromCommandLine();
UpdateGpuPreferences(&gpu_prefs);
command_line->AppendSwitchASCII(switches::kGpuPreferences,
- gpu::GpuPreferencesToSwitchValue(gpu_prefs));
+ gpu_prefs.ToSwitchValue());
std::string use_gl;
if (card_disabled_ && SwiftShaderAllowed()) {
@@ -560,6 +600,8 @@ void GpuDataManagerImplPrivate::UpdateGpuPreferences(
gpu_preferences->texture_target_exception_list =
gpu::CreateBufferUsageAndFormatExceptionList();
+
+ gpu_preferences->watchdog_starts_backgrounded = !application_is_visible_;
}
void GpuDataManagerImplPrivate::DisableHardwareAcceleration() {
@@ -572,11 +614,6 @@ bool GpuDataManagerImplPrivate::HardwareAccelerationEnabled() const {
return !card_disabled_;
}
-void GpuDataManagerImplPrivate::BlockSwiftShader() {
- swiftshader_blocked_ = true;
- OnGpuBlocked();
-}
-
bool GpuDataManagerImplPrivate::SwiftShaderAllowed() const {
#if !BUILDFLAG(ENABLE_SWIFTSHADER)
return false;
@@ -613,27 +650,15 @@ void GpuDataManagerImplPrivate::AddLogMessage(
void GpuDataManagerImplPrivate::ProcessCrashed(
base::TerminationStatus exit_code) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- // Unretained is ok, because it's posted to UI thread, the thread
- // where the singleton GpuDataManagerImpl lives until the end.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&GpuDataManagerImpl::ProcessCrashed,
- base::Unretained(owner_), exit_code));
- return;
- }
- {
- GpuDataManagerImpl::UnlockedSession session(owner_);
- observer_list_->Notify(
- FROM_HERE, &GpuDataManagerObserver::OnGpuProcessCrashed, exit_code);
- }
+ observer_list_->Notify(
+ FROM_HERE, &GpuDataManagerObserver::OnGpuProcessCrashed, exit_code);
}
std::unique_ptr<base::ListValue> GpuDataManagerImplPrivate::GetLogMessages()
const {
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());
+ auto dict = std::make_unique<base::DictionaryValue>();
dict->SetInteger("level", log_messages_[ii].level);
dict->SetString("header", log_messages_[ii].header);
dict->SetString("message", log_messages_[ii].message);
@@ -643,7 +668,7 @@ std::unique_ptr<base::ListValue> GpuDataManagerImplPrivate::GetLogMessages()
}
void GpuDataManagerImplPrivate::HandleGpuSwitch() {
- GpuDataManagerImpl::UnlockedSession session(owner_);
+ base::AutoUnlock unlock(owner_->lock_);
// Notify observers in the browser process.
ui::GpuSwitchingManager::GetInstance()->NotifyGpuSwitched();
// Pass the notification to the GPU process to notify observers there.
@@ -701,48 +726,6 @@ void GpuDataManagerImplPrivate::DisableDomainBlockingFor3DAPIsForTesting() {
domain_blocking_enabled_ = false;
}
-// static
-GpuDataManagerImplPrivate* GpuDataManagerImplPrivate::Create(
- GpuDataManagerImpl* owner) {
- return new GpuDataManagerImplPrivate(owner);
-}
-
-GpuDataManagerImplPrivate::GpuDataManagerImplPrivate(GpuDataManagerImpl* owner)
- : complete_gpu_info_already_requested_(false),
- observer_list_(new GpuDataManagerObserverList),
- card_disabled_(false),
- swiftshader_blocked_(false),
- update_histograms_(true),
- domain_blocking_enabled_(true),
- owner_(owner),
- in_process_gpu_(false) {
- DCHECK(owner_);
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kDisableGpu))
- DisableHardwareAcceleration();
-
- if (command_line->HasSwitch(switches::kSingleProcess) ||
- command_line->HasSwitch(switches::kInProcessGPU)) {
- in_process_gpu_ = true;
- AppendGpuCommandLine(command_line);
- }
-
-#if defined(OS_MACOSX)
- CGDisplayRegisterReconfigurationCallback(DisplayReconfigCallback, owner_);
-#endif // OS_MACOSX
-
- // For testing only.
- if (command_line->HasSwitch(switches::kDisableDomainBlockingFor3DAPIs)) {
- domain_blocking_enabled_ = false;
- }
-}
-
-GpuDataManagerImplPrivate::~GpuDataManagerImplPrivate() {
-#if defined(OS_MACOSX)
- CGDisplayRemoveReconfigurationCallback(DisplayReconfigCallback, owner_);
-#endif
-}
-
void GpuDataManagerImplPrivate::NotifyGpuInfoUpdate() {
observer_list_->Notify(FROM_HERE, &GpuDataManagerObserver::OnGpuInfoUpdate);
}
@@ -756,8 +739,11 @@ bool GpuDataManagerImplPrivate::IsGpuProcessUsingHardwareGpu() const {
return true;
}
-std::string GpuDataManagerImplPrivate::GetDomainFromURL(
- const GURL& url) const {
+void GpuDataManagerImplPrivate::SetApplicationVisible(bool is_visible) {
+ application_is_visible_ = is_visible;
+}
+
+std::string GpuDataManagerImplPrivate::GetDomainFromURL(const GURL& url) const {
// For the moment, we just use the host, or its IP address, as the
// entry in the set, rather than trying to figure out the top-level
// domain. This does mean that a.foo.com and b.foo.com will be
@@ -860,21 +846,44 @@ bool GpuDataManagerImplPrivate::NeedsCompleteGpuInfoCollection() const {
#endif
}
-void GpuDataManagerImplPrivate::OnGpuProcessInitFailure() {
+gpu::GpuMode GpuDataManagerImplPrivate::GetGpuMode() const {
+ if (HardwareAccelerationEnabled()) {
+ return gpu::GpuMode::HARDWARE_ACCELERATED;
+ } else if (SwiftShaderAllowed()) {
+ return gpu::GpuMode::SWIFTSHADER;
+ } else if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
+ return gpu::GpuMode::DISPLAY_COMPOSITOR;
+ } else {
+ return gpu::GpuMode::DISABLED;
+ }
+}
+
+void GpuDataManagerImplPrivate::FallBackToNextGpuMode() {
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+ // Android and Chrome OS can't switch to software compositing. If the GPU
+ // process initialization fails or GPU process is too unstable then crash the
+ // browser process to reset everything.
+ LOG(FATAL) << "GPU process isn't usable. Goodbye.";
+#else
+ // TODO(kylechar): Use GpuMode to store the current mode instead of
+ // multiple bools.
+
if (!card_disabled_) {
DisableHardwareAcceleration();
- return;
- }
- if (SwiftShaderAllowed()) {
- BlockSwiftShader();
- return;
- }
- if (!base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
- // When Viz display compositor is not enabled, if GPU process fails to
- // launch with hardware GPU, and then fails to launch with SwiftShader if
- // available, then GPU process should not launch again.
+ } else if (SwiftShaderAllowed()) {
+ swiftshader_blocked_ = true;
+ OnGpuBlocked();
+ } else if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
+ // The GPU process is frequently crashing with only the display compositor
+ // running. This should never happen so something is wrong. Crash the
+ // browser process to reset everything.
+ LOG(FATAL) << "The display compositor is frequently crashing. Goodbye.";
+ } else {
+ // We are already at GpuMode::DISABLED. We shouldn't be launching the GPU
+ // process for it to fail.
NOTREACHED();
}
+#endif
}
} // namespace content
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 a84efd1a461..68fc14b5286 100644
--- a/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
+++ b/chromium/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -37,7 +37,8 @@ namespace content {
class CONTENT_EXPORT GpuDataManagerImplPrivate {
public:
- static GpuDataManagerImplPrivate* Create(GpuDataManagerImpl* owner);
+ explicit GpuDataManagerImplPrivate(GpuDataManagerImpl* owner);
+ virtual ~GpuDataManagerImplPrivate();
void BlacklistWebGLForTesting();
gpu::GPUInfo GetGPUInfo() const;
@@ -57,7 +58,6 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
void UnblockDomainFrom3DAPIs(const GURL& url);
void DisableHardwareAcceleration();
bool HardwareAccelerationEnabled() const;
- void BlockSwiftShader();
bool SwiftShaderAllowed() const;
void UpdateGpuInfo(
@@ -99,14 +99,15 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
bool UpdateActiveGpu(uint32_t vendor_id, uint32_t device_id);
- void OnGpuProcessInitFailure();
+ gpu::GpuMode GetGpuMode() const;
+ void FallBackToNextGpuMode();
// Notify all observers whenever there is a GPU info update.
void NotifyGpuInfoUpdate();
bool IsGpuProcessUsingHardwareGpu() const;
- virtual ~GpuDataManagerImplPrivate();
+ void SetApplicationVisible(bool is_visible);
private:
friend class GpuDataManagerImplPrivateTest;
@@ -128,10 +129,10 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
GpuDataManagerImpl::DomainGuilt last_guilt;
};
- typedef std::map<std::string, DomainBlockEntry> DomainBlockMap;
+ using DomainBlockMap = std::map<std::string, DomainBlockEntry>;
- typedef base::ObserverListThreadSafe<GpuDataManagerObserver>
- GpuDataManagerObserverList;
+ using GpuDataManagerObserverList =
+ base::ObserverListThreadSafe<GpuDataManagerObserver>;
struct LogMessage {
int level;
@@ -146,8 +147,6 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
message(_message) { }
};
- explicit GpuDataManagerImplPrivate(GpuDataManagerImpl* owner);
-
// Called when GPU access (hardware acceleration and swiftshader) becomes
// blocked.
void OnGpuBlocked();
@@ -170,7 +169,9 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
// 3) all other platforms, this returns false.
bool NeedsCompleteGpuInfoCollection() const;
- bool complete_gpu_info_already_requested_;
+ GpuDataManagerImpl* const owner_;
+
+ bool complete_gpu_info_already_requested_ = false;
gpu::GpuFeatureInfo gpu_feature_info_;
gpu::GPUInfo gpu_info_;
@@ -187,23 +188,23 @@ class CONTENT_EXPORT GpuDataManagerImplPrivate {
// Current card force-disabled due to GPU crashes, or disabled through
// the --disable-gpu commandline switch.
- bool card_disabled_;
+ bool card_disabled_ = false;
// SwiftShader force-blocked due to GPU crashes using SwiftShader.
- bool swiftshader_blocked_;
+ bool swiftshader_blocked_ = false;
// We disable histogram stuff in testing, especially in unit tests because
// they cause random failures.
- bool update_histograms_;
+ bool update_histograms_ = true;
DomainBlockMap blocked_domains_;
mutable std::list<base::Time> timestamps_of_gpu_resets_;
- bool domain_blocking_enabled_;
+ bool domain_blocking_enabled_ = true;
- GpuDataManagerImpl* owner_;
+ bool application_is_visible_ = true;
// True if --single-process or --in-process-gpu is passed in.
- bool in_process_gpu_;
+ bool in_process_gpu_ = false;
DISALLOW_COPY_AND_ASSIGN(GpuDataManagerImplPrivate);
};
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 a105555d01f..bb1ddc7b334 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
@@ -21,12 +21,6 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#endif
-
-#define LONG_STRING_CONST(...) #__VA_ARGS__
-
namespace content {
namespace {
@@ -72,18 +66,14 @@ class GpuDataManagerImplPrivateTest : public testing::Test {
// so we can make a little helper class here.
class ScopedGpuDataManagerImpl {
public:
- ScopedGpuDataManagerImpl() : impl_(new GpuDataManagerImpl()) {
- EXPECT_TRUE(impl_);
- EXPECT_TRUE(impl_->private_.get());
- }
- ~ScopedGpuDataManagerImpl() { delete impl_; }
-
- GpuDataManagerImpl* get() const { return impl_; }
+ ScopedGpuDataManagerImpl() { EXPECT_TRUE(impl_.private_.get()); }
+ ~ScopedGpuDataManagerImpl() = default;
- GpuDataManagerImpl* operator->() const { return impl_; }
+ GpuDataManagerImpl* get() { return &impl_; }
+ GpuDataManagerImpl* operator->() { return &impl_; }
private:
- GpuDataManagerImpl* impl_;
+ GpuDataManagerImpl impl_;
DISALLOW_COPY_AND_ASSIGN(ScopedGpuDataManagerImpl);
};
@@ -91,29 +81,17 @@ class GpuDataManagerImplPrivateTest : public testing::Test {
// in the GpuDataManagerImpl constructor.
class ScopedGpuDataManagerImplPrivate {
public:
- ScopedGpuDataManagerImplPrivate() : impl_(new GpuDataManagerImpl()) {
- EXPECT_TRUE(impl_);
- EXPECT_TRUE(impl_->private_.get());
- }
- ~ScopedGpuDataManagerImplPrivate() { delete impl_; }
+ ScopedGpuDataManagerImplPrivate() { EXPECT_TRUE(impl_.private_.get()); }
+ ~ScopedGpuDataManagerImplPrivate() = default;
- GpuDataManagerImplPrivate* get() const {
- return impl_->private_.get();
- }
-
- GpuDataManagerImplPrivate* operator->() const {
- return impl_->private_.get();
- }
+ GpuDataManagerImplPrivate* get() { return impl_.private_.get(); }
+ GpuDataManagerImplPrivate* operator->() { return impl_.private_.get(); }
private:
- GpuDataManagerImpl* impl_;
+ GpuDataManagerImpl impl_;
DISALLOW_COPY_AND_ASSIGN(ScopedGpuDataManagerImplPrivate);
};
- void SetUp() override {}
-
- void TearDown() override {}
-
base::Time JustBeforeExpiration(const GpuDataManagerImplPrivate* manager);
base::Time JustAfterExpiration(const GpuDataManagerImplPrivate* manager);
void TestBlockingDomainFrom3DAPIs(
diff --git a/chromium/content/browser/gpu/gpu_internals_ui.cc b/chromium/content/browser/gpu/gpu_internals_ui.cc
index 54537e236ac..a64a4419064 100644
--- a/chromium/content/browser/gpu/gpu_internals_ui.cc
+++ b/chromium/content/browser/gpu/gpu_internals_ui.cc
@@ -64,6 +64,8 @@ namespace {
WebUIDataSource* CreateGpuHTMLSource() {
WebUIDataSource* source = WebUIDataSource::Create(kChromeUIGpuHost);
+ source->OverrideContentSecurityPolicyScriptSrc(
+ "script-src chrome://resources 'self' 'unsafe-eval';");
source->SetJsonPath("strings.js");
source->AddResourcePath("gpu_internals.js", IDR_GPU_INTERNALS_JS);
@@ -147,6 +149,7 @@ std::string GPUDeviceToString(const gpu::GPUInfo::GPUDevice& gpu) {
std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info) {
+ const gpu::GPUInfo::GPUDevice& active_gpu = gpu_info.active_gpu();
auto basic_info = std::make_unique<base::ListValue>();
basic_info->Append(NewDescriptionValuePair(
"Initialization time",
@@ -158,15 +161,9 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
"Passthrough Command Decoder",
std::make_unique<base::Value>(gpu_info.passthrough_cmd_decoder)));
basic_info->Append(NewDescriptionValuePair(
- "Direct Composition",
- std::make_unique<base::Value>(gpu_info.direct_composition)));
- basic_info->Append(NewDescriptionValuePair(
- "Supports overlays",
- std::make_unique<base::Value>(gpu_info.supports_overlays)));
- basic_info->Append(NewDescriptionValuePair(
"Sandboxed", std::make_unique<base::Value>(gpu_info.sandboxed)));
- basic_info->Append(NewDescriptionValuePair(
- "GPU0", GPUDeviceToString(gpu_info.gpu)));
+ basic_info->Append(
+ NewDescriptionValuePair("GPU0", GPUDeviceToString(gpu_info.gpu)));
for (size_t i = 0; i < gpu_info.secondary_gpus.size(); ++i) {
basic_info->Append(NewDescriptionValuePair(
base::StringPrintf("GPU%d", static_cast<int>(i + 1)),
@@ -183,6 +180,22 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
basic_info->Append(
NewDescriptionValuePair("Desktop compositing", compositor));
+ basic_info->Append(NewDescriptionValuePair(
+ "Direct Composition",
+ std::make_unique<base::Value>(gpu_info.direct_composition)));
+ basic_info->Append(NewDescriptionValuePair(
+ "Supports overlays",
+ std::make_unique<base::Value>(gpu_info.supports_overlays)));
+
+ auto overlay_capabilities = std::make_unique<base::ListValue>();
+ for (const auto& cap : gpu_info.overlay_capabilities) {
+ overlay_capabilities->Append(NewDescriptionValuePair(
+ gpu::OverlayFormatToString(cap.format),
+ cap.is_scaling_supported ? "SCALING" : "DIRECT"));
+ }
+ basic_info->Append(NewDescriptionValuePair("Overlay capabilities",
+ std::move(overlay_capabilities)));
+
std::vector<gfx::PhysicalDisplaySize> display_sizes =
gfx::GetPhysicalSizeForDisplays();
for (const auto& display_size : display_sizes) {
@@ -208,29 +221,28 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
#endif
basic_info->Append(
- NewDescriptionValuePair("Driver vendor", gpu_info.driver_vendor));
- basic_info->Append(NewDescriptionValuePair("Driver version",
- gpu_info.driver_version));
- basic_info->Append(NewDescriptionValuePair("Driver date",
- gpu_info.driver_date));
+ NewDescriptionValuePair("Driver vendor", active_gpu.driver_vendor));
+ basic_info->Append(
+ NewDescriptionValuePair("Driver version", active_gpu.driver_version));
+ basic_info->Append(
+ NewDescriptionValuePair("Driver date", active_gpu.driver_date));
basic_info->Append(NewDescriptionValuePair("Pixel shader version",
gpu_info.pixel_shader_version));
basic_info->Append(NewDescriptionValuePair("Vertex shader version",
gpu_info.vertex_shader_version));
- basic_info->Append(NewDescriptionValuePair("Max. MSAA samples",
- gpu_info.max_msaa_samples));
+ basic_info->Append(
+ NewDescriptionValuePair("Max. MSAA samples", gpu_info.max_msaa_samples));
basic_info->Append(NewDescriptionValuePair("Machine model name",
gpu_info.machine_model_name));
basic_info->Append(NewDescriptionValuePair("Machine model version",
gpu_info.machine_model_version));
- basic_info->Append(NewDescriptionValuePair("GL_VENDOR",
- gpu_info.gl_vendor));
- basic_info->Append(NewDescriptionValuePair("GL_RENDERER",
- gpu_info.gl_renderer));
- basic_info->Append(NewDescriptionValuePair("GL_VERSION",
- gpu_info.gl_version));
- basic_info->Append(NewDescriptionValuePair("GL_EXTENSIONS",
- gpu_info.gl_extensions));
+ basic_info->Append(NewDescriptionValuePair("GL_VENDOR", gpu_info.gl_vendor));
+ basic_info->Append(
+ NewDescriptionValuePair("GL_RENDERER", gpu_info.gl_renderer));
+ basic_info->Append(
+ NewDescriptionValuePair("GL_VERSION", gpu_info.gl_version));
+ basic_info->Append(
+ NewDescriptionValuePair("GL_EXTENSIONS", gpu_info.gl_extensions));
basic_info->Append(NewDescriptionValuePair(
"Disabled Extensions", gpu_feature_info.disabled_extensions));
basic_info->Append(NewDescriptionValuePair(
@@ -242,8 +254,8 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
basic_info->Append(NewDescriptionValuePair("Window system binding extensions",
gpu_info.gl_ws_extensions));
#if defined(USE_X11)
- basic_info->Append(NewDescriptionValuePair("Window manager",
- ui::GuessWindowManagerName()));
+ basic_info->Append(
+ NewDescriptionValuePair("Window manager", ui::GuessWindowManagerName()));
{
std::unique_ptr<base::Environment> env(base::Environment::Create());
std::string value;
@@ -264,8 +276,8 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
std::string reset_strategy =
base::StringPrintf("0x%04x", gpu_info.gl_reset_notification_strategy);
- basic_info->Append(NewDescriptionValuePair(
- "Reset notification strategy", reset_strategy));
+ basic_info->Append(
+ NewDescriptionValuePair("Reset notification strategy", reset_strategy));
basic_info->Append(NewDescriptionValuePair(
"GPU process crash count",
@@ -436,8 +448,12 @@ std::string GetProfileName(gpu::VideoCodecProfile profile) {
return "dolby vision profile 7";
case gpu::THEORAPROFILE_ANY:
return "theora";
- case gpu::AV1PROFILE_PROFILE0:
- return "av1 profile0";
+ case gpu::AV1PROFILE_PROFILE_MAIN:
+ return "av1 profile main";
+ case gpu::AV1PROFILE_PROFILE_HIGH:
+ return "av1 profile high";
+ case gpu::AV1PROFILE_PROFILE_PRO:
+ return "av1 profile pro";
}
NOTREACHED();
return "";
diff --git a/chromium/content/browser/gpu/gpu_process_host.cc b/chromium/content/browser/gpu/gpu_process_host.cc
index 72708d0f0c7..bdecceea7e6 100644
--- a/chromium/content/browser/gpu/gpu_process_host.cc
+++ b/chromium/content/browser/gpu/gpu_process_host.cc
@@ -15,6 +15,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
+#include "base/debug/alias.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -23,6 +24,7 @@
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -34,14 +36,17 @@
#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/compositor/image_transport_factory.h"
#include "content/browser/field_trial_recorder.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_main_thread_factory.h"
#include "content/browser/gpu/shader_cache_factory.h"
+#include "content/browser/memory/memory_coordinator_impl.h"
#include "content/browser/service_manager/service_manager_context.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/in_process_child_thread_params.h"
+#include "content/common/memory_coordinator.mojom.h"
#include "content/common/service_manager/child_connection.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_thread.h"
@@ -55,14 +60,14 @@
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/common/service_manager_connection.h"
#include "content/public/common/service_names.mojom.h"
-#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/config/gpu_driver_bug_list.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
+#include "gpu/config/gpu_preferences.h"
#include "gpu/ipc/host/shader_disk_cache.h"
+#include "gpu/ipc/in_process_command_buffer.h"
#include "media/base/media_switches.h"
#include "media/media_buildflags.h"
-#include "mojo/edk/embedder/embedder.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"
@@ -73,6 +78,7 @@
#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/display/display_switches.h"
+#include "ui/gfx/font_render_params.h"
#include "ui/gfx/switches.h"
#include "ui/gl/gl_switches.h"
#include "ui/latency/latency_info.h"
@@ -104,18 +110,35 @@
#include "gpu/ipc/common/gpu_surface_tracker.h"
#endif
+#if defined(OS_MACOSX)
+#include "content/browser/gpu/ca_transaction_gpu_coordinator.h"
+#endif
+
namespace content {
base::subtle::Atomic32 GpuProcessHost::gpu_crash_count_ = 0;
-int GpuProcessHost::gpu_recent_crash_count_ = 0;
bool GpuProcessHost::crashed_before_ = false;
-int GpuProcessHost::swiftshader_crash_count_ = 0;
+int GpuProcessHost::hardware_accelerated_recent_crash_count_ = 0;
int GpuProcessHost::swiftshader_recent_crash_count_ = 0;
-int GpuProcessHost::display_compositor_crash_count_ = 0;
int GpuProcessHost::display_compositor_recent_crash_count_ = 0;
namespace {
+// UMA histogram names.
+constexpr char kProcessLifetimeEventsHardwareAccelerated[] =
+ "GPU.ProcessLifetimeEvents.HardwareAccelerated";
+constexpr char kProcessLifetimeEventsSwiftShader[] =
+ "GPU.ProcessLifetimeEvents.SwiftShader";
+constexpr char kProcessLifetimeEventsDisplayCompositor[] =
+ "GPU.ProcessLifetimeEvents.DisplayCompositor";
+
+// Forgive one GPU process crash after this many minutes.
+constexpr int kForgiveGpuCrashMinutes = 60;
+
+// Forgive one GPU process crash, when the GPU process is launched to run only
+// the display compositor, after this many minutes.
+constexpr int kForgiveDisplayCompositorCrashMinutes = 10;
+
// This matches base::TerminationStatus.
// These values are persisted to logs. Entries (except MAX_ENUM) should not be
// renumbered and numeric values should never be reused. Should also avoid
@@ -185,19 +208,21 @@ static const char* const kSwitchNames[] = {
switches::kDisableGLExtensions,
switches::kDisableLogging,
switches::kDisableShaderNameHashing,
+ switches::kDisableSkiaRuntimeOpts,
switches::kDisableWebRtcHWEncoding,
#if defined(OS_WIN)
switches::kEnableAcceleratedVpxDecode,
#endif
switches::kEnableGpuRasterization,
switches::kEnableLogging,
- switches::kEnableOOPRasterization,
switches::kEnableVizDevTools,
switches::kHeadless,
switches::kLoggingLevel,
switches::kEnableLowEndDeviceMode,
switches::kDisableLowEndDeviceMode,
switches::kRunAllCompositorStagesBeforeDraw,
+ switches::kSkiaFontCacheLimitMb,
+ switches::kSkiaResourceCacheLimitMb,
switches::kTestGLLib,
switches::kTraceToConsole,
switches::kUseFakeJpegDecodeAccelerator,
@@ -226,15 +251,19 @@ static const char* const kSwitchNames[] = {
#if defined(OS_ANDROID)
switches::kOrderfileMemoryOptimization,
#endif
+ switches::kWebglAntialiasingMode,
+ switches::kWebglMSAASampleCount,
};
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
enum GPUProcessLifetimeEvent {
- LAUNCHED,
- DIED_FIRST_TIME,
- DIED_SECOND_TIME,
- DIED_THIRD_TIME,
- DIED_FOURTH_TIME,
- GPU_PROCESS_LIFETIME_EVENT_MAX = 100
+ LAUNCHED = 0,
+ // When the GPU process crashes the (DIED_FIRST_TIME + recent_crash_count - 1)
+ // bucket in the appropriate UMA histogram will be incremented. The first
+ // crash will be DIED_FIRST_TIME, the second DIED_FIRST_TIME+1, etc.
+ DIED_FIRST_TIME = 1,
+ GPU_PROCESS_LIFETIME_EVENT_MAX = 100,
};
// Indexed by GpuProcessKind. There is one of each kind maximum. This array may
@@ -442,7 +471,7 @@ void BindDiscardableMemoryRequestOnUI(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(USE_AURA)
- if (features::IsMashEnabled()) {
+ if (!features::IsAshInBrowserProcess()) {
ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
ui::mojom::kServiceName, std::move(request));
return;
@@ -455,11 +484,28 @@ void BindDiscardableMemoryRequestOnUI(
BrowserMainLoop::GetInstance()->discardable_shared_memory_manager()));
}
+struct FontRenderParamsOnIO {
+ bool initialized = false;
+ gfx::FontRenderParams params;
+};
+
+FontRenderParamsOnIO& GetFontRenderParamsOnIO() {
+ static base::NoDestructor<FontRenderParamsOnIO> instance;
+ return *instance;
+}
+
+void CreateMemoryCoordinatorHandleForGpuProcess(
+ int gpu_process_id,
+ mojom::MemoryCoordinatorHandleRequest request) {
+ MemoryCoordinatorImpl::GetInstance()->CreateHandle(gpu_process_id,
+ std::move(request));
+}
+
} // anonymous namespace
class GpuProcessHost::ConnectionFilterImpl : public ConnectionFilter {
public:
- ConnectionFilterImpl() {
+ explicit ConnectionFilterImpl(int gpu_process_id) {
auto task_runner = BrowserThread::GetTaskRunnerForThread(BrowserThread::UI);
registry_.AddInterface(base::Bind(&FieldTrialRecorder::Create),
task_runner);
@@ -468,6 +514,11 @@ class GpuProcessHost::ConnectionFilterImpl : public ConnectionFilter {
base::Bind(&BindJavaInterface<media::mojom::AndroidOverlayProvider>),
task_runner);
#endif
+
+ registry_.AddInterface(
+ base::BindRepeating(&CreateMemoryCoordinatorHandleForGpuProcess,
+ gpu_process_id),
+ task_runner);
}
private:
@@ -488,6 +539,16 @@ class GpuProcessHost::ConnectionFilterImpl : public ConnectionFilter {
};
// static
+void GpuProcessHost::InitFontRenderParamsOnIO(
+ const gfx::FontRenderParams& params) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(!GetFontRenderParamsOnIO().initialized);
+
+ GetFontRenderParamsOnIO().initialized = true;
+ GetFontRenderParamsOnIO().params = params;
+}
+
+// static
bool GpuProcessHost::ValidateHost(GpuProcessHost* host) {
// The Gpu process is invalid if it's not using SwiftShader, the card is
// blacklisted, and we can kill it and start over.
@@ -612,17 +673,20 @@ int GpuProcessHost::GetGpuCrashCount() {
}
// static
-void GpuProcessHost::IncrementCrashCount(int* crash_count) {
+void GpuProcessHost::IncrementCrashCount(int forgive_minutes,
+ int* crash_count) {
+ DCHECK_GT(forgive_minutes, 0);
+
// Last time the process crashed.
- static base::Time last_crash_time;
+ static base::TimeTicks last_crash_time;
- // Allow about 1 crash per hour to be removed from the crash count, so very
- // occasional crashes won't eventually add up and prevent the process from
- // launching.
- base::Time current_time = base::Time::Now();
+ // Remove one crash per |forgive_minutes| from the crash count, so occasional
+ // crashes won't add up and eventually prevent using the GPU process.
+ base::TimeTicks current_time = base::TimeTicks::Now();
if (crashed_before_) {
- int hours_different = (current_time - last_crash_time).InHours();
- *crash_count = std::max(0, *crash_count - hours_different);
+ int minutes_delta = (current_time - last_crash_time).InMinutes();
+ int crashes_to_forgive = minutes_delta / forgive_minutes;
+ *crash_count = std::max(0, *crash_count - crashes_to_forgive);
}
++(*crash_count);
@@ -663,6 +727,13 @@ GpuProcessHost::~GpuProcessHost() {
SendOutstandingReplies(EstablishChannelStatus::GPU_HOST_INVALID);
+#if defined(OS_MACOSX)
+ if (ca_transaction_gpu_coordinator_) {
+ ca_transaction_gpu_coordinator_->HostWillBeDestroyed();
+ ca_transaction_gpu_coordinator_ = nullptr;
+ }
+#endif
+
if (status_ == UNKNOWN) {
RunRequestGPUInfoCallbacks(gpu::GPUInfo());
} else {
@@ -806,11 +877,14 @@ bool GpuProcessHost::Init() {
// May be null during test execution.
if (ServiceManagerConnection::GetForProcess()) {
ServiceManagerConnection::GetForProcess()->AddConnectionFilter(
- std::make_unique<ConnectionFilterImpl>());
+ std::make_unique<ConnectionFilterImpl>(process_->GetData().id));
}
process_->GetHost()->CreateChannelMojo();
+ mode_ = GpuDataManagerImpl::GetInstance()->GetGpuMode();
+ DCHECK_NE(mode_, gpu::GpuMode::DISABLED);
+
if (in_process_) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(GetGpuMainThreadFactory());
@@ -819,7 +893,7 @@ bool GpuProcessHost::Init() {
in_process_gpu_thread_.reset(GetGpuMainThreadFactory()(
InProcessChildThreadParams(
base::ThreadTaskRunnerHandle::Get(),
- process_->GetInProcessBrokerClientInvitation(),
+ process_->GetInProcessMojoInvitation(),
process_->child_connection()->service_token()),
gpu_preferences));
base::Thread::Options options;
@@ -850,14 +924,20 @@ bool GpuProcessHost::Init() {
base::BindOnce(&BindDiscardableMemoryRequestOnUI,
std::move(discardable_request)));
+ DCHECK(GetFontRenderParamsOnIO().initialized);
gpu_main_ptr_->CreateGpuService(
mojo::MakeRequest(&gpu_service_ptr_), std::move(host_proxy),
- std::move(discardable_manager_ptr), activity_flags_.CloneHandle());
+ std::move(discardable_manager_ptr), activity_flags_.CloneHandle(),
+ GetFontRenderParamsOnIO().params.subpixel_rendering);
#if defined(USE_OZONE)
InitOzone();
#endif // defined(USE_OZONE)
+#if defined(OS_MACOSX)
+ ca_transaction_gpu_coordinator_ = CATransactionGPUCoordinator::Create(this);
+#endif
+
return true;
}
@@ -916,6 +996,16 @@ void GpuProcessHost::EstablishGpuChannel(
return;
}
+ bool oopd_enabled =
+ base::FeatureList::IsEnabled(features::kVizDisplayCompositor);
+ if (oopd_enabled && client_id == gpu::InProcessCommandBuffer::kGpuClientId) {
+ // The display-compositor in the gpu process uses this special client id.
+ callback.Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
+ gpu::GpuFeatureInfo(),
+ EstablishChannelStatus::GPU_ACCESS_DENIED);
+ return;
+ }
+
DCHECK_EQ(preempts, allow_view_command_buffers);
DCHECK_EQ(preempts, allow_real_time_streams);
bool is_gpu_host = preempts;
@@ -929,6 +1019,8 @@ void GpuProcessHost::EstablishGpuChannel(
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGpuShaderDiskCache)) {
CreateChannelCache(client_id);
+ if (oopd_enabled)
+ CreateChannelCache(gpu::InProcessCommandBuffer::kGpuClientId);
}
}
@@ -987,19 +1079,6 @@ 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) {
- TRACE_EVENT0("gpu", "GpuProcessHost::SendDestroyingVideoSurface");
- DCHECK(send_destroying_video_surface_done_cb_.is_null());
- DCHECK(!done_cb.is_null());
- send_destroying_video_surface_done_cb_ = done_cb;
- gpu_service_ptr_->DestroyingVideoSurface(
- surface_id, base::Bind(&GpuProcessHost::OnDestroyingVideoSurfaceAck,
- weak_ptr_factory_.GetWeakPtr()));
-}
-#endif
-
void GpuProcessHost::OnChannelEstablished(
int client_id,
const EstablishChannelCallback& callback,
@@ -1029,13 +1108,13 @@ void GpuProcessHost::OnChannelEstablished(
}
void GpuProcessHost::OnGpuMemoryBufferCreated(
- const gfx::GpuMemoryBufferHandle& handle) {
+ gfx::GpuMemoryBufferHandle handle) {
TRACE_EVENT0("gpu", "GpuProcessHost::OnGpuMemoryBufferCreated");
DCHECK(!create_gpu_memory_buffer_requests_.empty());
auto callback = std::move(create_gpu_memory_buffer_requests_.front());
create_gpu_memory_buffer_requests_.pop();
- std::move(callback).Run(handle, BufferCreationStatus::SUCCESS);
+ std::move(callback).Run(std::move(handle), BufferCreationStatus::SUCCESS);
}
#if defined(OS_ANDROID)
@@ -1056,6 +1135,11 @@ void GpuProcessHost::OnProcessLaunched() {
}
void GpuProcessHost::OnProcessLaunchFailed(int error_code) {
+ // TODO(crbug.com/849639): Ensure |error_code| is included in crash minidumps.
+ // This is for debugging and should be removed when bug is closed.
+ int process_launch_error_code = error_code;
+ base::debug::Alias(&process_launch_error_code);
+
#if defined(OS_WIN)
if (kind_ == GPU_PROCESS_KIND_SANDBOXED)
RecordAppContainerStatus(error_code, crashed_before_);
@@ -1064,6 +1148,14 @@ void GpuProcessHost::OnProcessLaunchFailed(int error_code) {
}
void GpuProcessHost::OnProcessCrashed(int exit_code) {
+ // TODO(crbug.com/849639): Ensure |exit_code| is included in crash minidumps.
+ // This is for debugging and should be removed when bug is closed.
+ int process_crash_exit_code = exit_code;
+ base::debug::Alias(&process_crash_exit_code);
+
+ // Record crash before doing anything that could start a new GPU process.
+ RecordProcessCrash();
+
// If the GPU process crashed while compiling a shader, we may have invalid
// cached binaries. Completely clear the shader cache to force shader binaries
// to be re-created.
@@ -1079,7 +1171,6 @@ void GpuProcessHost::OnProcessCrashed(int exit_code) {
}
}
SendOutstandingReplies(EstablishChannelStatus::GPU_HOST_INVALID);
- RecordProcessCrash();
ChildProcessTerminationInfo info =
process_->GetTerminationInfo(true /* known_dead */);
@@ -1117,7 +1208,8 @@ void GpuProcessHost::DidFailInitialize() {
UMA_HISTOGRAM_BOOLEAN("GPU.GPUProcessInitialized", false);
status_ = FAILURE;
GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance();
- gpu_data_manager->OnGpuProcessInitFailure();
+ if (kind_ == GPU_PROCESS_KIND_SANDBOXED)
+ gpu_data_manager->FallBackToNextGpuMode();
RunRequestGPUInfoCallbacks(gpu_data_manager->GetGPUInfo());
}
@@ -1126,7 +1218,7 @@ void GpuProcessHost::DidCreateContextSuccessfully() {
// 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;
+ hardware_accelerated_recent_crash_count_ = 0;
#endif
}
@@ -1193,6 +1285,18 @@ void GpuProcessHost::DidLoseContext(bool offscreen,
GpuDataManagerImpl::GetInstance()->BlockDomainFrom3DAPIs(active_url, guilt);
}
+void GpuProcessHost::DisableGpuCompositing() {
+#if !defined(OS_ANDROID)
+ // TODO(crbug.com/819474): The switch from GPU to software compositing should
+ // be handled here instead of by ImageTransportFactory.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE, base::BindOnce([]() {
+ if (auto* factory = ImageTransportFactory::GetInstance())
+ factory->DisableGpuCompositing();
+ }));
+#endif
+}
+
void GpuProcessHost::SetChildSurface(gpu::SurfaceHandle parent_handle,
gpu::SurfaceHandle window_handle) {
#if defined(OS_WIN)
@@ -1317,6 +1421,8 @@ bool GpuProcessHost::LaunchGpuProcess() {
GetContentClient()->browser()->AppendExtraCommandLineSwitches(
cmd_line.get(), process_->GetData().id);
+ // TODO(kylechar): The command line flags added here should be based on
+ // |mode_|.
GpuDataManagerImpl::GetInstance()->AppendGpuCommandLine(cmd_line.get());
bool swiftshader_rendering =
(cmd_line->GetSwitchValueASCII(switches::kUseGL) ==
@@ -1338,8 +1444,19 @@ bool GpuProcessHost::LaunchGpuProcess() {
process_->Launch(std::move(delegate), std::move(cmd_line), true);
process_launched_ = true;
- UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLifetimeEvents",
- LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX);
+ if (kind_ == GPU_PROCESS_KIND_SANDBOXED) {
+ if (mode_ == gpu::GpuMode::HARDWARE_ACCELERATED) {
+ UMA_HISTOGRAM_ENUMERATION(kProcessLifetimeEventsHardwareAccelerated,
+ LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX);
+ } else if (mode_ == gpu::GpuMode::SWIFTSHADER) {
+ UMA_HISTOGRAM_ENUMERATION(kProcessLifetimeEventsSwiftShader, LAUNCHED,
+ GPU_PROCESS_LIFETIME_EVENT_MAX);
+ } else if (mode_ == gpu::GpuMode::DISPLAY_COMPOSITOR) {
+ UMA_HISTOGRAM_ENUMERATION(kProcessLifetimeEventsDisplayCompositor,
+ LAUNCHED, GPU_PROCESS_LIFETIME_EVENT_MAX);
+ }
+ }
+
return true;
}
@@ -1384,89 +1501,85 @@ 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;
+#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
+ // Maximum number of times the GPU process can crash before we try something
+ // different, like disabling hardware acceleration or all GL.
+ constexpr int kGpuFallbackCrashCount = 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;
+ // Android and Chrome OS switch to software compositing and fallback crashes
+ // the browser process. For Android the OS can also kill the GPU process
+ // arbitrarily. Use a larger maximum crash count here.
+ constexpr int kGpuFallbackCrashCount = 6;
#endif
- bool disable_crash_limit = base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableGpuProcessCrashLimit);
-
// Ending only acts as a failure if the GPU process was actually started and
// was intended for actual rendering (and not just checking caps or other
// options).
- if (process_launched_ && kind_ == GPU_PROCESS_KIND_SANDBOXED) {
- if (GpuDataManagerImpl::GetInstance()->HardwareAccelerationEnabled()) {
- int count = static_cast<int>(
- base::subtle::NoBarrier_AtomicIncrement(&gpu_crash_count_, 1));
- UMA_HISTOGRAM_EXACT_LINEAR(
- "GPU.GPUProcessLifetimeEvents",
- std::min(DIED_FIRST_TIME + count, GPU_PROCESS_LIFETIME_EVENT_MAX - 1),
- static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
-
- IncrementCrashCount(&gpu_recent_crash_count_);
- if ((gpu_recent_crash_count_ >= kGpuMaxCrashCount ||
- status_ == FAILURE) &&
- !disable_crash_limit) {
-#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.
- GpuDataManagerImpl::GetInstance()->DisableHardwareAcceleration();
-#endif
- }
- } else if (GpuDataManagerImpl::GetInstance()->SwiftShaderAllowed()) {
- UMA_HISTOGRAM_EXACT_LINEAR(
- "GPU.SwiftShaderLifetimeEvents",
- DIED_FIRST_TIME + swiftshader_crash_count_,
- static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
- ++swiftshader_crash_count_;
-
- IncrementCrashCount(&swiftshader_recent_crash_count_);
- if (swiftshader_recent_crash_count_ >= kGpuMaxCrashCount &&
- !disable_crash_limit) {
- // SwiftShader is too unstable to use. Disable it for current session.
- GpuDataManagerImpl::GetInstance()->BlockSwiftShader();
- }
- } else {
- UMA_HISTOGRAM_EXACT_LINEAR(
- "GPU.DisplayCompositorLifetimeEvents",
- DIED_FIRST_TIME + display_compositor_crash_count_,
- static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
- ++display_compositor_crash_count_;
-
- IncrementCrashCount(&display_compositor_recent_crash_count_);
- if (display_compositor_recent_crash_count_ >= kGpuMaxCrashCount &&
- !disable_crash_limit) {
- // Viz display compositor is too unstable. Crash chrome to reset
- // everything.
- LOG(FATAL) << "Unable to start viz process, giving up.";
- }
- }
+ if (!process_launched_ || kind_ != GPU_PROCESS_KIND_SANDBOXED)
+ return;
+
+ // Keep track of the total number of GPU crashes.
+ base::subtle::NoBarrier_AtomicIncrement(&gpu_crash_count_, 1);
+
+ int recent_crash_count = 0;
+ if (mode_ == gpu::GpuMode::HARDWARE_ACCELERATED) {
+ IncrementCrashCount(kForgiveGpuCrashMinutes,
+ &hardware_accelerated_recent_crash_count_);
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ kProcessLifetimeEventsHardwareAccelerated,
+ DIED_FIRST_TIME + hardware_accelerated_recent_crash_count_ - 1,
+ static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
+ recent_crash_count = hardware_accelerated_recent_crash_count_;
+ } else if (mode_ == gpu::GpuMode::SWIFTSHADER) {
+ IncrementCrashCount(kForgiveGpuCrashMinutes,
+ &swiftshader_recent_crash_count_);
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ kProcessLifetimeEventsSwiftShader,
+ DIED_FIRST_TIME + swiftshader_recent_crash_count_ - 1,
+ static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
+ recent_crash_count = swiftshader_recent_crash_count_;
+ } else if (mode_ == gpu::GpuMode::DISPLAY_COMPOSITOR) {
+ IncrementCrashCount(kForgiveDisplayCompositorCrashMinutes,
+ &display_compositor_recent_crash_count_);
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ kProcessLifetimeEventsDisplayCompositor,
+ DIED_FIRST_TIME + display_compositor_recent_crash_count_ - 1,
+ static_cast<int>(GPU_PROCESS_LIFETIME_EVENT_MAX));
+ recent_crash_count = display_compositor_recent_crash_count_;
}
+
+ // TODO(crbug.com/849639): Ensure crash counts are included in crash
+ // minidumps. This is for debugging and should be removed when bug is closed.
+ int hardware_accelerated_crash_count =
+ hardware_accelerated_recent_crash_count_;
+ base::debug::Alias(&hardware_accelerated_crash_count);
+ int swiftshader_crash_count = swiftshader_recent_crash_count_;
+ base::debug::Alias(&swiftshader_crash_count);
+ int display_compositor_crash_count = display_compositor_recent_crash_count_;
+ base::debug::Alias(&display_compositor_crash_count);
+
+ // GPU process initialization failed and fallback already happened.
+ if (status_ == FAILURE)
+ return;
+
+ bool disable_crash_limit = base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableGpuProcessCrashLimit);
+
+ // GPU process crashed too many times, fallback on a different GPU process
+ // mode.
+ if (recent_crash_count >= kGpuFallbackCrashCount && !disable_crash_limit)
+ GpuDataManagerImpl::GetInstance()->FallBackToNextGpuMode();
}
std::string GpuProcessHost::GetShaderPrefixKey() {
if (shader_prefix_key_.empty()) {
- gpu::GPUInfo info = GpuDataManagerImpl::GetInstance()->GetGPUInfo();
+ const gpu::GPUInfo info = GpuDataManagerImpl::GetInstance()->GetGPUInfo();
+ const gpu::GPUInfo::GPUDevice& active_gpu = info.active_gpu();
shader_prefix_key_ = GetContentClient()->GetProduct() + "-" +
info.gl_vendor + "-" + info.gl_renderer + "-" +
- info.driver_version + "-" + info.driver_vendor;
+ active_gpu.driver_version + "-" +
+ active_gpu.driver_vendor;
#if defined(OS_ANDROID)
std::string build_fp =
@@ -1511,4 +1624,8 @@ void GpuProcessHost::CreateChannelCache(int32_t client_id) {
client_id_to_shader_cache_[client_id] = cache;
}
+int GpuProcessHost::GetIDForTesting() const {
+ return process_->GetData().id;
+}
+
} // namespace content
diff --git a/chromium/content/browser/gpu/gpu_process_host.h b/chromium/content/browser/gpu/gpu_process_host.h
index e08bcf72fc1..3ca9cf5c561 100644
--- a/chromium/content/browser/gpu/gpu_process_host.h
+++ b/chromium/content/browser/gpu/gpu_process_host.h
@@ -28,6 +28,7 @@
#include "gpu/command_buffer/common/constants.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_info.h"
+#include "gpu/config/gpu_mode.h"
#include "gpu/ipc/common/surface_handle.h"
#include "ipc/ipc_sender.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -43,6 +44,10 @@ namespace base {
class Thread;
}
+namespace gfx {
+struct FontRenderParams;
+}
+
namespace gpu {
class ShaderDiskCache;
struct SyncToken;
@@ -51,6 +56,10 @@ struct SyncToken;
namespace content {
class BrowserChildProcessHostImpl;
+#if defined(OS_MACOSX)
+class CATransactionGPUCoordinator;
+#endif
+
class GpuProcessHost : public BrowserChildProcessHostDelegate,
public IPC::Sender,
public viz::mojom::GpuHost {
@@ -80,7 +89,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
SUCCESS,
};
using CreateGpuMemoryBufferCallback =
- base::OnceCallback<void(const gfx::GpuMemoryBufferHandle& handle,
+ base::OnceCallback<void(gfx::GpuMemoryBufferHandle handle,
BufferCreationStatus status)>;
using RequestGPUInfoCallback = base::Callback<void(const gpu::GPUInfo&)>;
@@ -110,6 +119,8 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
bool force_create,
const base::Callback<void(GpuProcessHost*)>& callback);
+ static void InitFontRenderParamsOnIO(const gfx::FontRenderParams& params);
+
void BindInterface(const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe);
@@ -155,12 +166,6 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
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
- // can stop using it.
- void SendDestroyingVideoSurface(int surface_id, const base::Closure& done_cb);
-#endif
-
// What kind of GPU process, e.g. sandboxed or unsandboxed.
GpuProcessKind kind();
@@ -175,6 +180,8 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
return wake_up_gpu_before_drawing_;
}
+ CONTENT_EXPORT int GetIDForTesting() const;
+
private:
class ConnectionFilterImpl;
@@ -182,9 +189,10 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
static bool ValidateHost(GpuProcessHost* host);
- // Increments the given crash count. Also, for each hour passed since the
- // previous crash, removes an old crash from the count.
- static void IncrementCrashCount(int* crash_count);
+ // Increments |crash_count| by one. Before incrementing |crash_count|, for
+ // each |forgive_minutes| that has passed since the previous crash remove one
+ // old crash.
+ static void IncrementCrashCount(int forgive_minutes, int* crash_count);
GpuProcessHost(int host_id, GpuProcessKind kind);
~GpuProcessHost() override;
@@ -217,6 +225,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
void DidLoseContext(bool offscreen,
gpu::error::ContextLostReason reason,
const GURL& active_url) override;
+ void DisableGpuCompositing() override;
void SetChildSurface(gpu::SurfaceHandle parent,
gpu::SurfaceHandle child) override;
void StoreShaderToDisk(int32_t client_id,
@@ -229,7 +238,7 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
void OnChannelEstablished(int client_id,
const EstablishChannelCallback& callback,
mojo::ScopedMessagePipeHandle channel_handle);
- void OnGpuMemoryBufferCreated(const gfx::GpuMemoryBufferHandle& handle);
+ void OnGpuMemoryBufferCreated(gfx::GpuMemoryBufferHandle handle);
// Message handlers.
#if defined(OS_ANDROID)
@@ -279,6 +288,8 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
GpuProcessKind kind_;
+ gpu::GpuMode mode_ = gpu::GpuMode::UNKNOWN;
+
// Whether we actually launched a GPU process.
bool process_launched_;
@@ -287,12 +298,11 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
// Time Init started. Used to log total GPU process startup time to UMA.
base::TimeTicks init_start_time_;
+ // The total number of GPU process crashes.
static base::subtle::Atomic32 gpu_crash_count_;
- static int gpu_recent_crash_count_;
static bool crashed_before_;
- static int swiftshader_crash_count_;
+ static int hardware_accelerated_recent_crash_count_;
static int swiftshader_recent_crash_count_;
- static int display_compositor_crash_count_;
static int display_compositor_recent_crash_count_;
// Here the bottom-up destruction order matters:
@@ -302,6 +312,10 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
std::unique_ptr<BrowserChildProcessHostImpl> process_;
std::unique_ptr<base::Thread> in_process_gpu_thread_;
+#if defined(OS_MACOSX)
+ scoped_refptr<CATransactionGPUCoordinator> ca_transaction_gpu_coordinator_;
+#endif
+
// Track the URLs of the pages which have live offscreen contexts,
// assumed to be associated with untrusted content such as WebGL.
// For best robustness, when any context lost notification is
diff --git a/chromium/content/browser/host_zoom_map_impl.cc b/chromium/content/browser/host_zoom_map_impl.cc
index 939d89cc27f..34775d0204d 100644
--- a/chromium/content/browser/host_zoom_map_impl.cc
+++ b/chromium/content/browser/host_zoom_map_impl.cc
@@ -238,7 +238,7 @@ void HostZoomMapImpl::SetZoomLevelForHostInternal(const std::string& host,
}
// TODO(wjmaclean) Should we use a GURL here? crbug.com/384486
- SendZoomLevelChange(std::string(), host, level);
+ SendZoomLevelChange(std::string(), host);
HostZoomMap::ZoomLevelChange change;
change.mode = HostZoomMap::ZOOM_CHANGED_FOR_HOST;
@@ -257,7 +257,7 @@ void HostZoomMapImpl::SetZoomLevelForHostAndScheme(const std::string& scheme,
// not persistet and are used for special cases only.
scheme_host_zoom_levels_[scheme][host].level = level;
- SendZoomLevelChange(scheme, host, level);
+ SendZoomLevelChange(scheme, host);
HostZoomMap::ZoomLevelChange change;
change.mode = HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST;
@@ -324,7 +324,7 @@ void HostZoomMapImpl::SetDefaultZoomLevel(double level) {
!UsesTemporaryZoomLevel(render_process_id, render_view_id);
if (uses_default_zoom) {
- web_contents->UpdateZoom(level);
+ web_contents->UpdateZoom();
HostZoomMap::ZoomLevelChange change;
change.mode = HostZoomMap::ZOOM_CHANGED_FOR_HOST;
@@ -460,7 +460,7 @@ void HostZoomMapImpl::SetTemporaryZoomLevel(int render_process_id,
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(
RenderViewHost::FromID(render_process_id, render_view_id)));
- web_contents->SetTemporaryZoomLevel(level, true);
+ web_contents->UpdateZoom();
HostZoomMap::ZoomLevelChange change;
change.mode = HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM;
@@ -507,13 +507,11 @@ void HostZoomMapImpl::ClearTemporaryZoomLevel(int render_process_id,
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(
RenderViewHost::FromID(render_process_id, render_view_id)));
- web_contents->SetTemporaryZoomLevel(GetZoomLevelForHost(
- GetHostFromProcessView(render_process_id, render_view_id)), false);
+ web_contents->UpdateZoom();
}
void HostZoomMapImpl::SendZoomLevelChange(const std::string& scheme,
- const std::string& host,
- double level) {
+ const std::string& host) {
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;
@@ -530,7 +528,7 @@ void HostZoomMapImpl::SendZoomLevelChange(const std::string& scheme,
int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
if (!UsesTemporaryZoomLevel(render_process_id, render_view_id))
- web_contents->UpdateZoomIfNecessary(scheme, host, level);
+ web_contents->UpdateZoomIfNecessary(scheme, host);
}
}
@@ -538,9 +536,8 @@ 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);
- SendZoomLevelChange(std::string(), host, error_page_zoom_level);
+ SendZoomLevelChange(std::string(), host);
}
void HostZoomMapImpl::WillCloseRenderView(int render_process_id,
diff --git a/chromium/content/browser/host_zoom_map_impl.h b/chromium/content/browser/host_zoom_map_impl.h
index b7eef9b1983..51a26a5272e 100644
--- a/chromium/content/browser/host_zoom_map_impl.h
+++ b/chromium/content/browser/host_zoom_map_impl.h
@@ -129,10 +129,10 @@ class CONTENT_EXPORT HostZoomMapImpl : public HostZoomMap {
// Notifies the renderers from this browser context to change the zoom level
// for the specified host and scheme.
+ // |zoom level| will be extracted from |host_zoom_levels_| when needed, so no
+ // need to pass them in.
// TODO(wjmaclean) Should we use a GURL here? crbug.com/384486
- void SendZoomLevelChange(const std::string& scheme,
- const std::string& host,
- double level);
+ void SendZoomLevelChange(const std::string& scheme, const std::string& host);
// Callbacks called when zoom level changes.
base::CallbackList<void(const ZoomLevelChange&)>
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 6dde8e246d8..8dc3131ee8a 100644
--- a/chromium/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -3072,9 +3072,7 @@ bool IndexedDBBackingStore::IsBlobCleanupPending() {
}
void IndexedDBBackingStore::ForceRunBlobCleanup() {
- base::OnceClosure task = journal_cleaning_timer_.user_task();
- journal_cleaning_timer_.AbandonAndStop();
- std::move(task).Run();
+ journal_cleaning_timer_.FireNow();
}
IndexedDBBackingStore::Transaction::Transaction(
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 e976df908b2..eaa915e6d42 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
@@ -1446,7 +1446,7 @@ TEST_F(IndexedDBBackingStoreTest, ReadCorruptionInfo) {
TEST_F(IndexedDBBackingStoreTest, SchemaUpgradeWithoutBlobsSurvives) {
struct TestState {
int64_t database_id;
- const int64_t object_store_id = 99;
+ int64_t object_store_id = 99;
} state;
// The database metadata needs to be written so we can verify the blob entry
@@ -1568,6 +1568,9 @@ TEST_F(IndexedDBBackingStoreTest, SchemaUpgradeWithoutBlobsSurvives) {
EXPECT_TRUE(found);
EXPECT_EQ(3, found_int);
+
+ // Clean up Transactions, etc on the IDB thread.
+ *state = TestState();
},
base::Unretained(backing_store()), key1_, value1_,
base::Unretained(&state)));
@@ -1582,7 +1585,7 @@ TEST_F(IndexedDBBackingStoreTest, SchemaUpgradeWithoutBlobsSurvives) {
TEST_F(IndexedDBBackingStoreTestWithBlobs, SchemaUpgradeWithBlobsCorrupt) {
struct TestState {
int64_t database_id;
- const int64_t object_store_id = 99;
+ int64_t object_store_id = 99;
std::unique_ptr<IndexedDBBackingStore::Transaction> transaction1;
scoped_refptr<TestCallback> callback1;
std::unique_ptr<IndexedDBBackingStore::Transaction> transaction3;
@@ -1677,6 +1680,9 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, SchemaUpgradeWithBlobsCorrupt) {
const std::string schema_version_key = SchemaVersionKey::Encode();
indexed_db::PutInt(transaction.get(), schema_version_key, 2);
ASSERT_TRUE(transaction->Commit().ok());
+
+ // Clean up Transactions, etc on the IDB thread.
+ *state = TestState();
},
base::Unretained(this), base::Unretained(&state)));
RunAllTasksUntilIdle();
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 f063f01ae1d..cd079aedd08 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -10,6 +10,7 @@
#include <vector>
#include "base/callback_helpers.h"
+#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
@@ -110,7 +111,7 @@ const base::Feature kIDBTombstoneStatistics{"IDBTombstoneStatistics",
base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kIDBTombstoneDeletion{"IDBTombstoneDeletion",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
constexpr const base::TimeDelta
IndexedDBFactoryImpl::kMaxEarliestGlobalSweepFromNow;
@@ -179,6 +180,12 @@ void IndexedDBFactoryImpl::ReleaseBackingStore(const Origin& origin,
return;
}
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ kIDBCloseImmediatelySwitch)) {
+ MaybeCloseBackingStore(origin);
+ return;
+ }
+
// Start a timer to close the backing store, unless something else opens it
// in the mean time.
DCHECK(!backing_store_map_[origin]->close_timer()->IsRunning());
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 4ae17600381..3935f9b319f 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_impl.h
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_impl.h
@@ -32,6 +32,8 @@ class IndexedDBContextImpl;
CONTENT_EXPORT extern const base::Feature kIDBTombstoneStatistics;
CONTENT_EXPORT extern const base::Feature kIDBTombstoneDeletion;
+constexpr const char kIDBCloseImmediatelySwitch[] = "idb-close-immediately";
+
class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
public:
// Maximum time interval between runs of the IndexedDBSweeper. Sweeping only
@@ -141,6 +143,8 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest,
BackingStoreReleaseDelayedOnClose);
FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest, BackingStoreRunPreCloseTasks);
+ FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest,
+ BackingStoreCloseImmediatelySwitch);
FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest, BackingStoreNoSweeping);
FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest, DatabaseFailedOpen);
FRIEND_TEST_ALL_PREFIXES(IndexedDBFactoryTest,
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 2384f769124..0031ef8024b 100644
--- a/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -180,6 +180,9 @@ TEST_F(IndexedDBFactoryTest, BackingStoreLazyClose) {
}
TEST_F(IndexedDBFactoryTest, BackingStoreNoSweeping) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatures(
+ {}, {kIDBTombstoneDeletion, kIDBTombstoneStatistics});
context()->TaskRunner()->PostTask(
FROM_HERE,
base::BindOnce(
@@ -209,7 +212,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreNoSweeping) {
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();
+ store_ptr->close_timer()->FireNow();
// Backing store should be totally closed.
EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
@@ -225,7 +228,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreNoSweeping) {
// Sweep should NOT be occurring.
EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
- store_ptr->close_timer()->user_task().Run();
+ store_ptr->close_timer()->FireNow();
// Backing store should be totally closed.
EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
@@ -268,7 +271,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreRunPreCloseTasks) {
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();
+ store_ptr->close_timer()->FireNow();
// Backing store should be totally closed.
EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
@@ -284,8 +287,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreRunPreCloseTasks) {
// Sweep should be occuring.
EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
- store_ptr->close_timer()->user_task().Run();
- store_ptr->close_timer()->AbandonAndStop();
+ store_ptr->close_timer()->FireNow();
ASSERT_NE(nullptr, store_ptr->pre_close_task_queue());
EXPECT_TRUE(store_ptr->pre_close_task_queue()->started());
@@ -309,8 +311,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreRunPreCloseTasks) {
// Sweep should be occuring.
EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
- store_ptr->close_timer()->user_task().Run();
- store_ptr->close_timer()->AbandonAndStop();
+ store_ptr->close_timer()->FireNow();
ASSERT_NE(nullptr, store_ptr->pre_close_task_queue());
EXPECT_TRUE(store_ptr->pre_close_task_queue()->started());
@@ -324,6 +325,41 @@ TEST_F(IndexedDBFactoryTest, BackingStoreRunPreCloseTasks) {
RunAllTasksUntilIdle();
}
+TEST_F(IndexedDBFactoryTest, BackingStoreCloseImmediatelySwitch) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitWithFeatures({kIDBTombstoneStatistics},
+ {kIDBTombstoneDeletion});
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ kIDBCloseImmediatelySwitch);
+
+ 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_FALSE(factory->IsBackingStoreOpen(origin));
+ },
+ base::Unretained(context())));
+
+ RunAllTasksUntilIdle();
+}
+
TEST_F(IndexedDBFactoryTest, MemoryBackingStoreLifetime) {
context()->TaskRunner()->PostTask(
FROM_HERE,
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 616d0b0f0d5..b548e8953e4 100644
--- a/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_internals_ui.cc
@@ -65,6 +65,8 @@ IndexedDBInternalsUI::IndexedDBInternalsUI(WebUI* web_ui)
WebUIDataSource* source =
WebUIDataSource::Create(kChromeUIIndexedDBInternalsHost);
+ source->OverrideContentSecurityPolicyScriptSrc(
+ "script-src chrome://resources 'self' 'unsafe-eval';");
source->SetJsonPath("strings.js");
source->AddResourcePath("indexeddb_internals.js",
IDR_INDEXED_DB_INTERNALS_JS);
diff --git a/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue.cc b/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue.cc
index e04bbb4e965..0be77f326e1 100644
--- a/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue.cc
@@ -16,7 +16,7 @@ IndexedDBPreCloseTaskQueue::IndexedDBPreCloseTaskQueue(
std::list<std::unique_ptr<IndexedDBPreCloseTaskQueue::PreCloseTask>> tasks,
base::OnceClosure on_complete,
base::TimeDelta max_run_time,
- std::unique_ptr<base::Timer> timer)
+ std::unique_ptr<base::OneShotTimer> timer)
: tasks_(std::move(tasks)),
on_done_(std::move(on_complete)),
timeout_time_(max_run_time),
diff --git a/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue.h b/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue.h
index 4010a5a4271..7e2aa847c55 100644
--- a/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue.h
+++ b/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue.h
@@ -64,7 +64,7 @@ class CONTENT_EXPORT IndexedDBPreCloseTaskQueue {
IndexedDBPreCloseTaskQueue(std::list<std::unique_ptr<PreCloseTask>> tasks,
base::OnceClosure on_complete,
base::TimeDelta max_run_time,
- std::unique_ptr<base::Timer> timer);
+ std::unique_ptr<base::OneShotTimer> timer);
~IndexedDBPreCloseTaskQueue();
bool started() const { return started_; }
@@ -96,7 +96,7 @@ class CONTENT_EXPORT IndexedDBPreCloseTaskQueue {
base::OnceClosure on_done_;
base::TimeDelta timeout_time_;
- std::unique_ptr<base::Timer> timeout_timer_;
+ std::unique_ptr<base::OneShotTimer> timeout_timer_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
base::WeakPtrFactory<IndexedDBPreCloseTaskQueue> ptr_factory_;
diff --git a/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue_unittest.cc b/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue_unittest.cc
index 138b8d149ca..48bf2edc32f 100644
--- a/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue_unittest.cc
+++ b/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue_unittest.cc
@@ -80,7 +80,7 @@ TEST_F(IndexedDBPreCloseTaskQueueTest, NoTasks) {
bool done_called = false;
bool metadata_called = false;
- base::MockTimer* fake_timer = new base::MockTimer(true, false);
+ base::MockOneShotTimer* fake_timer = new base::MockOneShotTimer;
IndexedDBPreCloseTaskQueue queue(
std::list<std::unique_ptr<PreCloseTask>>(),
base::BindOnce(&SetBoolValue, &done_called, true), kTestMaxRunTime,
@@ -104,7 +104,7 @@ TEST_F(IndexedDBPreCloseTaskQueueTest, TaskOneRound) {
EXPECT_CALL(*task,
SetMetadata(testing::Pointee(testing::ContainerEq(metadata_))));
- base::MockTimer* fake_timer = new base::MockTimer(true, false);
+ base::MockOneShotTimer* fake_timer = new base::MockOneShotTimer;
std::list<std::unique_ptr<PreCloseTask>> tasks;
tasks.push_back(base::WrapUnique(task));
IndexedDBPreCloseTaskQueue queue(
@@ -134,7 +134,7 @@ TEST_F(IndexedDBPreCloseTaskQueueTest, TaskTwoRounds) {
EXPECT_CALL(*task,
SetMetadata(testing::Pointee(testing::ContainerEq(metadata_))));
- base::MockTimer* fake_timer = new base::MockTimer(true, false);
+ base::MockOneShotTimer* fake_timer = new base::MockOneShotTimer;
std::list<std::unique_ptr<PreCloseTask>> tasks;
tasks.push_back(base::WrapUnique(task));
IndexedDBPreCloseTaskQueue queue(
@@ -178,7 +178,7 @@ TEST_F(IndexedDBPreCloseTaskQueueTest, TwoTasks) {
EXPECT_CALL(*task1,
SetMetadata(testing::Pointee(testing::ContainerEq(metadata_))));
- base::MockTimer* fake_timer = new base::MockTimer(true, false);
+ base::MockOneShotTimer* fake_timer = new base::MockOneShotTimer;
std::list<std::unique_ptr<PreCloseTask>> tasks;
tasks.push_back(base::WrapUnique(task1));
tasks.push_back(base::WrapUnique(task2));
@@ -227,7 +227,7 @@ TEST_F(IndexedDBPreCloseTaskQueueTest, StopForNewConnectionBeforeStart) {
EXPECT_CALL(*task1,
SetMetadata(testing::Pointee(testing::ContainerEq(metadata_))));
- base::MockTimer* fake_timer = new base::MockTimer(true, false);
+ base::MockOneShotTimer* fake_timer = new base::MockOneShotTimer;
std::list<std::unique_ptr<PreCloseTask>> tasks;
tasks.push_back(base::WrapUnique(task1));
tasks.push_back(base::WrapUnique(task2));
@@ -260,7 +260,7 @@ TEST_F(IndexedDBPreCloseTaskQueueTest, StopForNewConnectionAfterRound) {
EXPECT_CALL(*task,
SetMetadata(testing::Pointee(testing::ContainerEq(metadata_))));
- base::MockTimer* fake_timer = new base::MockTimer(true, false);
+ base::MockOneShotTimer* fake_timer = new base::MockOneShotTimer;
std::list<std::unique_ptr<PreCloseTask>> tasks;
tasks.push_back(base::WrapUnique(task));
IndexedDBPreCloseTaskQueue queue(
@@ -301,7 +301,7 @@ TEST_F(IndexedDBPreCloseTaskQueueTest, StopForNewConnectionAfterTaskCompletes) {
EXPECT_CALL(*task1,
SetMetadata(testing::Pointee(testing::ContainerEq(metadata_))));
- base::MockTimer* fake_timer = new base::MockTimer(true, false);
+ base::MockOneShotTimer* fake_timer = new base::MockOneShotTimer;
std::list<std::unique_ptr<PreCloseTask>> tasks;
tasks.push_back(base::WrapUnique(task1));
tasks.push_back(base::WrapUnique(task2));
@@ -345,7 +345,7 @@ TEST_F(IndexedDBPreCloseTaskQueueTest, StopForTimout) {
EXPECT_CALL(*task1,
SetMetadata(testing::Pointee(testing::ContainerEq(metadata_))));
- base::MockTimer* fake_timer = new base::MockTimer(true, false);
+ base::MockOneShotTimer* fake_timer = new base::MockOneShotTimer;
std::list<std::unique_ptr<PreCloseTask>> tasks;
tasks.push_back(base::WrapUnique(task1));
tasks.push_back(base::WrapUnique(task2));
@@ -387,7 +387,7 @@ TEST_F(IndexedDBPreCloseTaskQueueTest, MetadataError) {
MockPreCloseTask* task1 = new testing::StrictMock<MockPreCloseTask>();
MockPreCloseTask* task2 = new testing::StrictMock<MockPreCloseTask>();
- base::MockTimer* fake_timer = new base::MockTimer(true, false);
+ base::MockOneShotTimer* fake_timer = new base::MockOneShotTimer;
std::list<std::unique_ptr<PreCloseTask>> tasks;
tasks.push_back(base::WrapUnique(task1));
tasks.push_back(base::WrapUnique(task2));
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 d53addc85b2..2793b7449b7 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
@@ -9,7 +9,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/time/tick_clock.h"
#include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
#include "content/browser/indexed_db/leveldb/leveldb_database.h"
diff --git a/chromium/content/browser/isolated_origin_browsertest.cc b/chromium/content/browser/isolated_origin_browsertest.cc
index 417972f21b9..365f03302cb 100644
--- a/chromium/content/browser/isolated_origin_browsertest.cc
+++ b/chromium/content/browser/isolated_origin_browsertest.cc
@@ -30,6 +30,7 @@
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/network/public/cpp/features.h"
+#include "third_party/blink/public/common/features.h"
#include "url/gurl.h"
namespace content {
@@ -997,11 +998,12 @@ IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, IsolatedOriginWithSubdomain) {
// This class allows intercepting the OpenLocalStorage method and changing
// the parameters to the real implementation of it.
class StoragePartitonInterceptor
- : public mojom::StoragePartitionServiceInterceptorForTesting,
+ : public blink::mojom::StoragePartitionServiceInterceptorForTesting,
public RenderProcessHostObserver {
public:
- StoragePartitonInterceptor(RenderProcessHostImpl* rph,
- mojom::StoragePartitionServiceRequest request) {
+ StoragePartitonInterceptor(
+ RenderProcessHostImpl* rph,
+ blink::mojom::StoragePartitionServiceRequest request) {
StoragePartitionImpl* storage_partition =
static_cast<StoragePartitionImpl*>(rph->GetStoragePartition());
@@ -1030,7 +1032,7 @@ class StoragePartitonInterceptor
// Allow all methods that aren't explicitly overriden to pass through
// unmodified.
- mojom::StoragePartitionService* GetForwardingInterface() override {
+ blink::mojom::StoragePartitionService* GetForwardingInterface() override {
return storage_partition_service_;
}
@@ -1038,7 +1040,7 @@ class StoragePartitonInterceptor
// renderer process sending incorrect data to the browser process, so
// security checks can be tested.
void OpenLocalStorage(const url::Origin& origin,
- mojom::LevelDBWrapperRequest request) override {
+ blink::mojom::StorageAreaRequest request) override {
url::Origin mismatched_origin =
url::Origin::Create(GURL("http://abc.foo.com"));
GetForwardingInterface()->OpenLocalStorage(mismatched_origin,
@@ -1048,14 +1050,14 @@ class StoragePartitonInterceptor
private:
// Keep a pointer to the original implementation of the service, so all
// calls can be forwarded to it.
- mojom::StoragePartitionService* storage_partition_service_;
+ blink::mojom::StoragePartitionService* storage_partition_service_;
DISALLOW_COPY_AND_ASSIGN(StoragePartitonInterceptor);
};
void CreateTestStoragePartitionService(
RenderProcessHostImpl* rph,
- mojom::StoragePartitionServiceRequest request) {
+ blink::mojom::StoragePartitionServiceRequest request) {
// This object will register as RenderProcessHostObserver, so it will
// clean itself automatically on process exit.
new StoragePartitonInterceptor(rph, std::move(request));
@@ -1235,25 +1237,14 @@ IN_PROC_BROWSER_TEST_F(IsolatedOriginTest, SubframeErrorPages) {
class IsolatedOriginTestWithMojoBlobURLs : public IsolatedOriginTest {
public:
IsolatedOriginTestWithMojoBlobURLs() {
- // Enabling NetworkService implies enabling MojoBlobURLs.
- scoped_feature_list_.InitAndEnableFeature(
- network::features::kNetworkService);
+ scoped_feature_list_.InitAndEnableFeature(blink::features::kMojoBlobURLs);
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
-#if defined(OS_ANDROID) || defined(OS_MACOSX)
-// Times out on android, and crashes on mac due to its dependency on network
-// service.
-#define MAYBE_NavigateToBlobURL DISABLED_NavigateToBlobURL
-#else
-#define MAYBE_NavigateToBlobURL NavigateToBlobURL
-#endif
-
-IN_PROC_BROWSER_TEST_F(IsolatedOriginTestWithMojoBlobURLs,
- MAYBE_NavigateToBlobURL) {
+IN_PROC_BROWSER_TEST_F(IsolatedOriginTestWithMojoBlobURLs, NavigateToBlobURL) {
GURL top_url(
embedded_test_server()->GetURL("www.foo.com", "/page_with_iframe.html"));
EXPECT_TRUE(NavigateToURL(shell(), top_url));
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 a0b9c10d77b..f783d5356c8 100644
--- a/chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
+++ b/chromium/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
@@ -80,21 +80,24 @@ void KeyboardLockServiceImpl::RequestKeyboardLock(
// Per base::flat_set usage notes, the proper way to init a flat_set is
// inserting into a vector and using that to init the flat_set.
std::vector<ui::DomCode> dom_codes;
+ bool invalid_key_code_found = false;
for (const std::string& code : key_codes) {
ui::DomCode dom_code = ui::KeycodeConverter::CodeStringToDomCode(code);
if (dom_code != ui::DomCode::NONE) {
dom_codes.push_back(dom_code);
} else {
+ invalid_key_code_found = true;
render_frame_host_->AddMessageToConsole(
ConsoleMessageLevel::CONSOLE_MESSAGE_LEVEL_WARNING,
"Invalid DOMString passed into keyboard.lock(): '" + code + "'");
}
}
- // If we are provided with a vector containing only invalid keycodes, then
- // exit without enabling keyboard lock. An empty vector is treated as
- // 'capture all keys' which is not what the caller intended.
- if (!key_codes.empty() && dom_codes.empty()) {
+ // If we are provided with a vector containing one or more invalid key codes,
+ // then exit without enabling keyboard lock. Also cancel any previous
+ // keyboard lock request since the most recent request failed.
+ if (invalid_key_code_found) {
+ render_frame_host_->GetRenderWidgetHost()->CancelKeyboardLock();
std::move(callback).Run(KeyboardLockRequestResult::kNoValidKeyCodesError);
return;
}
diff --git a/chromium/content/browser/keyboard_lock_browsertest.cc b/chromium/content/browser/keyboard_lock_browsertest.cc
index 2a4739de4af..4894106e59f 100644
--- a/chromium/content/browser/keyboard_lock_browsertest.cc
+++ b/chromium/content/browser/keyboard_lock_browsertest.cc
@@ -8,7 +8,7 @@
#include "base/macros.h"
#include "base/metrics/histogram_base.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "components/network_session_configurator/common/network_switches.h"
@@ -90,10 +90,11 @@ constexpr char kKeyboardLockMethodCallWithAllInvalidKeys[] =
" () => { window.domAutomationController.send(true); },"
");";
+// Calling lock() with some invalid key codes will reject the promise.
constexpr char kKeyboardLockMethodCallWithSomeInvalidKeys[] =
"navigator.keyboard.lock(['Tab', 'BlarghTab', 'Space', 'BlerghLeft']).then("
- " () => { window.domAutomationController.send(true); },"
" () => { window.domAutomationController.send(false); },"
+ " () => { window.domAutomationController.send(true); },"
");";
constexpr char kKeyboardUnlockMethodCall[] = "navigator.keyboard.unlock()";
@@ -634,7 +635,7 @@ IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, LockCallWithAllInvalidKeys) {
web_contents(), kKeyboardLockMethodCallWithAllInvalidKeys, &result));
ASSERT_TRUE(result);
- // If no valid Keys are passed in, then KeyboardLock will not be requested.
+ // If no valid Keys are passed in, then keyboard lock will not be requested.
ASSERT_FALSE(web_contents()->GetKeyboardLockWidget());
EnterFullscreen(FROM_HERE, url_for_test);
@@ -649,10 +650,24 @@ IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, LockCallWithSomeInvalidKeys) {
web_contents(), kKeyboardLockMethodCallWithSomeInvalidKeys, &result));
ASSERT_TRUE(result);
- // If some valid Keys are passed in, then KeyboardLock will be requested.
+ // If some valid Keys are passed in, then keyboard lock will not be requested.
+ ASSERT_FALSE(web_contents()->GetKeyboardLockWidget());
+}
+
+IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
+ ValidLockCallFollowedByInvalidLockCall) {
+ NavigateToTestURL(https_fullscreen_frame());
+
+ RequestKeyboardLock(FROM_HERE);
ASSERT_TRUE(web_contents()->GetKeyboardLockWidget());
- EnterFullscreen(FROM_HERE, url_for_test);
+ bool result;
+ ASSERT_TRUE(ExecuteScriptAndExtractBool(
+ web_contents(), kKeyboardLockMethodCallWithSomeInvalidKeys, &result));
+ ASSERT_TRUE(result);
+
+ // An invalid call will cancel any previous lock request.
+ ASSERT_FALSE(web_contents()->GetKeyboardLockWidget());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockDisabledBrowserTest,
@@ -917,26 +932,6 @@ IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
- SubsequentLockCallSupersedesPreviousCall) {
- // TODO(joedow): Added per code review feedback.
- // Steps: 1. Request all keys, verify keys are locked
- // 2. Request subset of keys, verify the subset of keys are locked, but
- // non-requested keys are no longer locked
- // 3. Request all keys again, verify keys are now locked
-}
-
-IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
- BrowserShortcutsHandledCorrectly) {
- // TODO(joedow): Added per code review feedback.
- // Steps: 1. Request keyboard lock for all keys
- // 2. Simulate browser shortcut (Ctrl+T)
- // 3. Verify new tab is not created
- // 4. Unlock keyboard
- // 5. Simulate browser shortcut (Ctrl+T)
- // 6. Verify new tab was created
-}
-
-IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
InnerContentsFullscreenBehavior) {
// TODO(joedow): Added per code review feedback. Need to define the behavior
// for KeyboardLock when an attached InnerWebContents goes fullscreen.
diff --git a/chromium/content/browser/linux_ipc_browsertest.cc b/chromium/content/browser/linux_ipc_browsertest.cc
deleted file mode 100644
index 7be05896fec..00000000000
--- a/chromium/content/browser/linux_ipc_browsertest.cc
+++ /dev/null
@@ -1,91 +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 <map>
-#include <set>
-#include <string>
-
-#include "base/command_line.h"
-#include "base/macros.h"
-#include "base/synchronization/lock.h"
-#include "content/browser/sandbox_ipc_linux.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/test/content_browser_test.h"
-#include "content/public/test/content_browser_test_utils.h"
-#include "services/service_manager/sandbox/switches.h"
-#include "testing/gmock/include/gmock/gmock-matchers.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-class LinuxIPCBrowserTest : public ContentBrowserTest,
- public SandboxIPCHandler::TestObserver,
- public testing::WithParamInterface<std::string> {
- public:
- LinuxIPCBrowserTest() {
- SandboxIPCHandler::SetObserverForTests(this);
- }
- ~LinuxIPCBrowserTest() override {}
-
- protected:
- void SetUpCommandLine(base::CommandLine* command_line) override {
- ContentBrowserTest::SetUpCommandLine(command_line);
- if (GetParam() == "no-zygote") {
- command_line->AppendSwitch(service_manager::switches::kNoSandbox);
- command_line->AppendSwitch(switches::kNoZygote);
- }
- }
-
- void OnFontOpen(int id) override {
- base::AutoLock lock(lock_);
- opened_fonts_.insert(font_names_[id]);
- }
-
- void OnGetFallbackFontForChar(UChar32 c, std::string name, int id) override {
- base::AutoLock lock(lock_);
- fallback_fonts_[c] = name;
- font_names_[id] = name;
- }
-
- std::string FallbackFontName(UChar32 c) {
- base::AutoLock lock(lock_);
- return fallback_fonts_[c];
- }
-
- std::set<std::string> OpenedFonts() {
- base::AutoLock lock(lock_);
- return opened_fonts_;
- }
-
- // These variables are accessed on the IPC thread and the test thread.
- // All accesses on the IPC thread should be before the renderer process
- // completes navigation, and all accesses on the test thread should be after.
- // However we still need a mutex for the accesses to be sequenced according to
- // the C++ memory model.
- base::Lock lock_;
- std::map<UChar32, std::string> fallback_fonts_;
- std::map<int, std::string> font_names_;
- std::set<std::string> opened_fonts_;
-
- DISALLOW_COPY_AND_ASSIGN(LinuxIPCBrowserTest);
-};
-
-// Tests that Linux IPC font fallback code runs round-trip when Zygote is
-// disabled. It doesn't care what font is chosen, just that the IPC messages are
-// flowing. This test assumes that U+65E5 (CJK "Sun" character) will trigger the
-// font fallback codepath.
-IN_PROC_BROWSER_TEST_P(LinuxIPCBrowserTest, FontFallbackIPCWorks) {
- GURL test_url = GetTestUrl("font", "font_fallback.html");
- EXPECT_TRUE(NavigateToURL(shell(), test_url));
- EXPECT_THAT(FallbackFontName(U'\U000065E5'), testing::Ne(""));
- EXPECT_THAT(OpenedFonts(),
- testing::Contains(FallbackFontName(U'\U000065E5')));
-}
-
-INSTANTIATE_TEST_CASE_P(LinuxIPCBrowserTest,
- LinuxIPCBrowserTest,
- ::testing::Values("zygote", "no-zygote"));
-
-} // namespace
diff --git a/chromium/content/browser/loader/cors_file_origin_browsertest.cc b/chromium/content/browser/loader/cors_file_origin_browsertest.cc
index af3ed282f18..2b0e7a609ba 100644
--- a/chromium/content/browser/loader/cors_file_origin_browsertest.cc
+++ b/chromium/content/browser/loader/cors_file_origin_browsertest.cc
@@ -12,7 +12,10 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_command_line.h"
+#include "base/test/scoped_feature_list.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"
@@ -24,6 +27,7 @@
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "services/network/public/cpp/cors/cors.h"
+#include "services/network/public/cpp/features.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -37,11 +41,20 @@ using net::test_server::HttpResponse;
// Tests end to end Origin header and CORS check behaviors without
// --allow-file-access-from-files flag.
-class CORSFileOriginBrowserTest : public ContentBrowserTest {
+class CORSFileOriginBrowserTest : public ContentBrowserTest,
+ public testing::WithParamInterface<bool> {
public:
CORSFileOriginBrowserTest()
: pass_string_(base::ASCIIToUTF16("PASS")),
- fail_string_(base::ASCIIToUTF16("FAIL")) {}
+ fail_string_(base::ASCIIToUTF16("FAIL")) {
+ if (GetParam()) {
+ scoped_feature_list_.InitAndEnableFeature(
+ network::features::kOutOfBlinkCORS);
+ } else {
+ scoped_feature_list_.InitAndDisableFeature(
+ network::features::kOutOfBlinkCORS);
+ }
+ }
~CORSFileOriginBrowserTest() override = default;
protected:
@@ -84,7 +97,15 @@ class CORSFileOriginBrowserTest : public ContentBrowserTest {
private:
bool AllowFileAccessFromFiles() const override { return false; }
+ virtual bool IsWebSecurityEnabled() const { return true; }
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ if (!IsWebSecurityEnabled()) {
+ command_line->AppendSwitch(switches::kDisableWebSecurity);
+ }
+ ContentBrowserTest::SetUpCommandLine(command_line);
+ }
void SetUpOnMainThread() override {
base::AutoLock lock(lock_);
@@ -147,6 +168,9 @@ class CORSFileOriginBrowserTest : public ContentBrowserTest {
const base::string16 pass_string_;
const base::string16 fail_string_;
+ base::test::ScopedFeatureList scoped_command_line_;
+ base::test::ScopedFeatureList scoped_feature_list_;
+
DISALLOW_COPY_AND_ASSIGN(CORSFileOriginBrowserTest);
};
@@ -158,7 +182,16 @@ class CORSFileOriginBrowserTestWithAllowFileAccessFromFiles
bool AllowFileAccessFromFiles() const override { return true; }
};
-IN_PROC_BROWSER_TEST_F(CORSFileOriginBrowserTest,
+// Tests end to end Origin header and CORS check behaviors with
+// --disable-web-security flag.
+class CORSFileOriginBrowserTestWithDisableWebSecurity
+ : public CORSFileOriginBrowserTest {
+ private:
+ bool AllowFileAccessFromFiles() const override { return false; }
+ bool IsWebSecurityEnabled() const override { return false; }
+};
+
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTest,
AccessControlAllowOriginIsNull) {
std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL(
@@ -170,7 +203,7 @@ IN_PROC_BROWSER_TEST_F(CORSFileOriginBrowserTest,
EXPECT_TRUE(is_preflight_requested());
}
-IN_PROC_BROWSER_TEST_F(CORSFileOriginBrowserTest,
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTest,
AccessControlAllowOriginIsFile) {
std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL(
@@ -182,7 +215,7 @@ IN_PROC_BROWSER_TEST_F(CORSFileOriginBrowserTest,
EXPECT_TRUE(is_preflight_requested());
}
-IN_PROC_BROWSER_TEST_F(CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
AccessControlAllowOriginIsNull) {
std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL(
@@ -194,7 +227,7 @@ IN_PROC_BROWSER_TEST_F(CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
EXPECT_TRUE(is_preflight_requested());
}
-IN_PROC_BROWSER_TEST_F(CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
AccessControlAllowOriginIsFile) {
std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
EXPECT_TRUE(NavigateToURL(
@@ -206,6 +239,47 @@ IN_PROC_BROWSER_TEST_F(CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
EXPECT_TRUE(is_preflight_requested());
}
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithDisableWebSecurity,
+ AccessControlAllowOriginIsNull) {
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(), CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?port=%d&allow=%s&origin=%s",
+ port(), "unused", ""))));
+
+ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle());
+ EXPECT_FALSE(is_preflight_requested());
+}
+
+IN_PROC_BROWSER_TEST_P(CORSFileOriginBrowserTestWithDisableWebSecurity,
+ AccessControlAllowOriginIsFile) {
+ std::unique_ptr<TitleWatcher> watcher = CreateWatcher();
+ EXPECT_TRUE(NavigateToURL(
+ shell(), CreateTestDataURL(base::StringPrintf(
+ "cors_file_origin_test.html?port=%d&allow=%s&origin=%s",
+ port(), "unused", ""))));
+
+ EXPECT_EQ(pass_string(), watcher->WaitAndGetTitle());
+ EXPECT_FALSE(is_preflight_requested());
+}
+
+// --allow-file-access-from-files is currently not supported by OOR-CORS.
+// We may remove the feature.
+INSTANTIATE_TEST_CASE_P(
+ /* No test prefix */,
+ CORSFileOriginBrowserTest,
+ ::testing::Values(false));
+
+INSTANTIATE_TEST_CASE_P(
+ /* No test prefix */,
+ CORSFileOriginBrowserTestWithAllowFileAccessFromFiles,
+ ::testing::Values(false));
+
+INSTANTIATE_TEST_CASE_P(
+ /* No test prefix */,
+ CORSFileOriginBrowserTestWithDisableWebSecurity,
+ ::testing::Values(false, true));
+
} // namespace
} // namespace content
diff --git a/chromium/content/browser/loader/cross_site_document_blocking_browsertest.cc b/chromium/content/browser/loader/cross_site_document_blocking_browsertest.cc
index 494ecda070c..321ab2c8e87 100644
--- a/chromium/content/browser/loader/cross_site_document_blocking_browsertest.cc
+++ b/chromium/content/browser/loader/cross_site_document_blocking_browsertest.cc
@@ -7,11 +7,12 @@
#include <utility>
#include "base/command_line.h"
+#include "base/feature_list.h"
#include "base/macros.h"
#include "base/strings/pattern.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/loader/cross_site_document_resource_handler.h"
@@ -31,15 +32,19 @@
#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
#include "content/test/test_content_browser_client.h"
+#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/test/test_url_loader_client.h"
#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
using testing::Not;
using testing::HasSubstr;
+using Action = network::CrossOriginReadBlocking::Action;
namespace {
@@ -83,6 +88,14 @@ void InspectHistograms(const base::HistogramTester& histograms,
const HistogramExpectations& expectations,
const std::string& resource_name,
ResourceType resource_type) {
+ // //services/network doesn't have access to content::ResourceType and
+ // therefore cannot log some XSDB UMAs.
+ bool is_restricted_uma_expected = false;
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ is_restricted_uma_expected = true;
+ FetchHistogramsFromChildProcesses();
+ }
+
std::string bucket;
if (base::MatchPattern(resource_name, "*.html")) {
bucket = "HTML";
@@ -103,16 +116,23 @@ void InspectHistograms(const base::HistogramTester& histograms,
std::string base = "SiteIsolation.XSD.Browser";
expected_counts[base + ".Action"] = 2;
if ((base::MatchPattern(resource_name, "*prefixed*") || bucket == "Others") &&
- (0 != (expectations & kShouldBeBlocked))) {
+ (0 != (expectations & kShouldBeBlocked)) && !is_restricted_uma_expected) {
expected_counts[base + ".BlockedForParserBreaker"] = 1;
}
if (0 != (expectations & kShouldBeSniffed))
expected_counts[base + ".BytesReadForSniffing"] = 1;
- if (0 != (expectations & kShouldBeBlocked)) {
+ if (0 != (expectations & kShouldBeBlocked && !is_restricted_uma_expected)) {
expected_counts[base + ".Blocked"] = 1;
expected_counts[base + ".Blocked." + bucket] = 1;
+ }
+ if (0 != (expectations & kShouldBeBlocked)) {
expected_counts[base + ".Blocked.ContentLength.WasAvailable"] = 1;
- if (0 != (expectations & kShouldHaveContentLength))
+ bool should_have_content_length =
+ 0 != (expectations & kShouldHaveContentLength);
+ histograms.ExpectBucketCount(base + ".Blocked.ContentLength.WasAvailable",
+ should_have_content_length, 1);
+
+ if (should_have_content_length)
expected_counts[base + ".Blocked.ContentLength.ValueIfAvailable"] = 1;
}
@@ -124,7 +144,7 @@ void InspectHistograms(const base::HistogramTester& histograms,
<< ", expectations=" << expectations;
// Determine if the bucket for the resource type (XHR) was incremented.
- if (0 != (expectations & kShouldBeBlocked)) {
+ if (0 != (expectations & kShouldBeBlocked) && !is_restricted_uma_expected) {
EXPECT_THAT(histograms.GetAllSamples(base + ".Blocked"),
testing::ElementsAre(base::Bucket(resource_type, 1)))
<< "The wrong Blocked bucket was incremented.";
@@ -132,6 +152,26 @@ void InspectHistograms(const base::HistogramTester& histograms,
testing::ElementsAre(base::Bucket(resource_type, 1)))
<< "The wrong Blocked bucket was incremented.";
}
+
+ // SiteIsolation.XSD.Browser.Action should always include kResponseStarted.
+ histograms.ExpectBucketCount(base + ".Action",
+ static_cast<int>(Action::kResponseStarted), 1);
+
+ // Second value in SiteIsolation.XSD.Browser.Action depends on |expectations|.
+ Action expected_action = static_cast<Action>(-1);
+ if (expectations & kShouldBeBlocked) {
+ if (expectations & kShouldBeSniffed)
+ expected_action = Action::kBlockedAfterSniffing;
+ else
+ expected_action = Action::kBlockedWithoutSniffing;
+ } else {
+ if (expectations & kShouldBeSniffed)
+ expected_action = Action::kAllowedAfterSniffing;
+ else
+ expected_action = Action::kAllowedWithoutSniffing;
+ }
+ histograms.ExpectBucketCount(base + ".Action",
+ static_cast<int>(expected_action), 1);
}
// Helper for intercepting a resource request to the given URL and capturing the
@@ -290,16 +330,18 @@ class DisableWebSecurityContentBrowserClient : public TestContentBrowserClient {
// Note that this BaseTest class does not specify an isolation mode via
// command-line flags. Most of the tests are in the --site-per-process subclass
// below.
-class CrossSiteDocumentBlockingBaseTest : public ContentBrowserTest {
+class CrossSiteDocumentBlockingTest : public ContentBrowserTest {
public:
- CrossSiteDocumentBlockingBaseTest() {}
- ~CrossSiteDocumentBlockingBaseTest() override {}
+ CrossSiteDocumentBlockingTest() {}
+ ~CrossSiteDocumentBlockingTest() override {}
void SetUpCommandLine(base::CommandLine* command_line) override {
// EmbeddedTestServer::InitializeAndListen() initializes its |base_url_|
// which is required below. This cannot invoke Start() however as that kicks
// off the "EmbeddedTestServer IO Thread" which then races with
// initialization in ContentBrowserTest::SetUp(), http://crbug.com/674545.
+ // Additionally the server should not be started prior to setting up
+ // ControllableHttpResponse(s) in some individual tests below.
ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
// Add a host resolver rule to map all outgoing requests to the test server.
@@ -313,10 +355,6 @@ class CrossSiteDocumentBlockingBaseTest : public ContentBrowserTest {
}
void SetUpOnMainThread() override {
- // Complete the manual Start() after ContentBrowserTest's own
- // initialization, ref. comment on InitializeAndListen() above.
- embedded_test_server()->StartAcceptingConnections();
-
// Disable web security via the ContentBrowserClient and notify the current
// renderer process.
old_client = SetBrowserClientForTesting(&new_client);
@@ -329,22 +367,6 @@ class CrossSiteDocumentBlockingBaseTest : public ContentBrowserTest {
DisableWebSecurityContentBrowserClient new_client;
ContentBrowserClient* old_client = nullptr;
- DISALLOW_COPY_AND_ASSIGN(CrossSiteDocumentBlockingBaseTest);
-};
-
-// Most tests here use --site-per-process, which enables document blocking
-// everywhere.
-class CrossSiteDocumentBlockingTest : public CrossSiteDocumentBlockingBaseTest {
- public:
- CrossSiteDocumentBlockingTest() {}
- ~CrossSiteDocumentBlockingTest() override {}
-
- void SetUpCommandLine(base::CommandLine* command_line) override {
- IsolateAllSitesForTesting(command_line);
- CrossSiteDocumentBlockingBaseTest::SetUpCommandLine(command_line);
- }
-
- private:
DISALLOW_COPY_AND_ASSIGN(CrossSiteDocumentBlockingTest);
};
@@ -355,6 +377,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockDocuments) {
// possible since we run the browser without the same origin policy, allowing
// it to see the response body if it makes it to the renderer (even if the
// renderer would normally block access to it).
+ embedded_test_server()->StartAcceptingConnections();
GURL foo_url("http://foo.com/cross_site_document_blocking/request.html");
EXPECT_TRUE(NavigateToURL(shell(), foo_url));
@@ -417,7 +440,8 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockDocuments) {
// jsonp.* - JSONP (i.e., script) mislabeled as a document.
// img.* - Contents that won't match the document label.
// valid.* - Correctly labeled responses of non-document types.
- const char* sniff_allowed_resources[] = {"js.html",
+ const char* sniff_allowed_resources[] = {"html-prefix.txt",
+ "js.html",
"comment_js.html",
"js.xml",
"js.json",
@@ -469,6 +493,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockDocuments) {
// be a problem for script files mislabeled as HTML/XML/JSON/text (i.e., the
// reason for sniffing), since script tags won't send Range headers.
IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, RangeRequest) {
+ embedded_test_server()->StartAcceptingConnections();
GURL foo_url("http://foo.com/cross_site_document_blocking/request.html");
EXPECT_TRUE(NavigateToURL(shell(), foo_url));
@@ -519,6 +544,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockForVariousTargets) {
// TODO(nick): Split up these cases, and add positive assertions here about
// what actually happens in these various resource-block cases.
+ embedded_test_server()->StartAcceptingConnections();
GURL foo("http://foo.com/cross_site_document_blocking/request_target.html");
EXPECT_TRUE(NavigateToURL(shell(), foo));
@@ -530,6 +556,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockForVariousTargets) {
// Regression test for https://crbug.com/814913.
IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest,
BlockRequestFromErrorPage) {
+ embedded_test_server()->StartAcceptingConnections();
GURL error_url = embedded_test_server()->GetURL("bar.com", "/close-socket");
GURL subresource_url =
embedded_test_server()->GetURL("foo.com", "/site_isolation/json.js");
@@ -560,10 +587,10 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest,
}
IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockHeaders) {
- GURL foo_url("http://foo.com/title1.html");
- EXPECT_TRUE(NavigateToURL(shell(), foo_url));
+ embedded_test_server()->StartAcceptingConnections();
// Prepare to intercept the network request at the IPC layer.
+ // This has to be done before the RenderFrameHostImpl is created.
//
// Note: we want to verify that the blocking prevents the data from being sent
// over IPC. Testing later (e.g. via Response/Headers Web APIs) might give a
@@ -572,6 +599,10 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockHeaders) {
GURL bar_url("http://bar.com/cross_site_document_blocking/headers-test.json");
RequestInterceptor interceptor(bar_url);
+ // Navigate to the test page.
+ GURL foo_url("http://foo.com/title1.html");
+ EXPECT_TRUE(NavigateToURL(shell(), foo_url));
+
// Issue the request that will be intercepted
EXPECT_TRUE(ExecuteScript(shell(),
base::StringPrintf("fetch('%s').catch(error => {})",
@@ -580,7 +611,7 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockHeaders) {
// Verify that the response completed successfully and was blocked.
ASSERT_EQ(net::OK, interceptor.completion_status().error_code);
- ASSERT_TRUE(interceptor.completion_status().blocked_cross_site_document);
+ ASSERT_TRUE(interceptor.completion_status().should_report_corb_blocking);
// Verify that safelisted headers have not been removed by XSDB.
// See https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name.
@@ -623,6 +654,113 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, BlockHeaders) {
EXPECT_EQ(0u, interceptor.response_head().content_length);
}
+IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingTest, PrefetchIsNotImpacted) {
+ // Prepare for intercepting the resource request for testing prefetching.
+ const char* kPrefetchResourcePath = "/prefetch-test";
+ net::test_server::ControllableHttpResponse response(embedded_test_server(),
+ kPrefetchResourcePath);
+
+ // Navigate to a webpage containing a cross-origin frame.
+ embedded_test_server()->StartAcceptingConnections();
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ // Inject a cross-origin <link rel="prefetch" ...> into the main frame.
+ // TODO(lukasza): https://crbug.com/827633#c5: We might need to switch to
+ // listening to the onload event below (after/if CORB starts to consistently
+ // avoid injecting net errors).
+ const char* prefetch_injection_script_template = R"(
+ var link = document.createElement("link");
+ link.rel = "prefetch";
+ link.href = "/cross-site/b.com%s";
+ link.as = "fetch";
+
+ window.is_prefetch_done = false;
+ function mark_prefetch_as_done() { window.is_prefetch_done = true }
+ link.onerror = mark_prefetch_as_done;
+
+ document.getElementsByTagName('head')[0].appendChild(link);
+ )";
+ std::string prefetch_injection_script = base::StringPrintf(
+ prefetch_injection_script_template, kPrefetchResourcePath);
+ EXPECT_TRUE(
+ ExecuteScript(shell()->web_contents(), prefetch_injection_script));
+
+ // Respond to the prefetch request in a way that:
+ // 1) will enable caching
+ // 2) won't finish until after CORB has blocked the response.
+ FetchHistogramsFromChildProcesses();
+ base::HistogramTester histograms;
+ std::string response_bytes =
+ "HTTP/1.1 200 OK\r\n"
+ "Cache-Control: public, max-age=10\r\n"
+ "Content-Type: text/html\r\n"
+ "X-Content-Type-Options: nosniff\r\n"
+ "\r\n"
+ "<p>contents of the response</p>";
+ response.WaitForRequest();
+ response.Send(response_bytes);
+
+ // Verify that CORB blocked the response.
+ // TODO(lukasza): https://crbug.com/827633#c5: We might need to switch to
+ // listening to the onload event below (after/if CORB starts to consistently
+ // avoid injecting net errors).
+ std::string wait_script = R"(
+ function notify_prefetch_is_done() { domAutomationController.send(123); }
+
+ if (window.is_prefetch_done) {
+ // Can notify immediately if |window.is_prefetch_done| has already been
+ // set by |prefetch_injection_script|.
+ notify_prefetch_is_done();
+ } else {
+ // Otherwise wait for CORB's empty response to reach the renderer.
+ link = document.getElementsByTagName('link')[0];
+ link.onerror = notify_prefetch_is_done;
+ }
+ )";
+ int answer;
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(shell()->web_contents(), wait_script,
+ &answer));
+ EXPECT_EQ(123, answer);
+ InspectHistograms(histograms, kShouldBeBlockedWithoutSniffing, "x.html",
+ RESOURCE_TYPE_PREFETCH);
+
+ // Finish the HTTP response - this should store the response in the cache.
+ response.Done();
+
+ // Stop the HTTP server - this means the only way to get the response in
+ // the |fetch_script| below is to get it from the cache (e.g. if the request
+ // goes to the network there will be no HTTP server to handle it).
+ // Note that stopping the HTTP server is not strictly required for the test to
+ // be robust - ControllableHttpResponse handles only a single request, so
+ // wouldn't handle the |fetch_script| request even if the HTTP server was
+ // still running.
+ EXPECT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());
+
+ // Verify that the cached response is available to the same-origin subframe
+ // (e.g. that the network cache in the browser process got populated despite
+ // CORB blocking).
+ const char* fetch_script_template = R"(
+ fetch('%s')
+ .then(response => response.text())
+ .then(responseBody => {
+ domAutomationController.send(responseBody);
+ })
+ .catch(error => {
+ var errorMessage = 'error: ' + error;
+ console.log(errorMessage);
+ domAutomationController.send(errorMessage);
+ }); )";
+ std::string fetch_script =
+ base::StringPrintf(fetch_script_template, kPrefetchResourcePath);
+ std::string response_body;
+ EXPECT_TRUE(
+ ExecuteScriptAndExtractString(shell()->web_contents()->GetAllFrames()[1],
+ fetch_script, &response_body));
+ EXPECT_EQ("<p>contents of the response</p>", response_body);
+}
+
// This test class sets up a service worker that can be used to try to respond
// to same-origin requests with cross-origin responses.
class CrossSiteDocumentBlockingServiceWorkerTest : public ContentBrowserTest {
@@ -735,6 +873,12 @@ class CrossSiteDocumentBlockingServiceWorkerTest : public ContentBrowserTest {
// TODO(lukasza): https://crbug.com/715640: This test might become invalid
// after servicification of service workers.
IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingServiceWorkerTest, NoNetwork) {
+ // Skip this test when servicification of service workers (S13nServiceWorker)
+ // is enabled because the browser process doesn't see the request or response
+ // when the request is handled entirely within the service worker.
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
+ return;
+
SetUpServiceWorker();
base::HistogramTester histograms;
@@ -766,6 +910,11 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingServiceWorkerTest,
NetworkToServiceWorkerResponse) {
SetUpServiceWorker();
+ // Make sure that the histograms generated by a service worker registration
+ // have been recorded.
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService))
+ FetchHistogramsFromChildProcesses();
+
// Build a script for XHR-ing a cross-origin, nosniff HTML document.
GURL cross_origin_url =
GetURLOnCrossOriginServer("/site_isolation/nosniff.txt");
@@ -826,6 +975,7 @@ class CrossSiteDocumentBlockingKillSwitchTest
IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingKillSwitchTest,
NoBlockingWithKillSwitch) {
// Load a page that issues illegal cross-site document requests to bar.com.
+ embedded_test_server()->StartAcceptingConnections();
GURL foo_url("http://foo.com/cross_site_document_blocking/request.html");
EXPECT_TRUE(NavigateToURL(shell(), foo_url));
@@ -855,6 +1005,7 @@ class CrossSiteDocumentBlockingDisableWebSecurityTest
IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingDisableWebSecurityTest,
DisableBlocking) {
// Load a page that issues illegal cross-site document requests.
+ embedded_test_server()->StartAcceptingConnections();
GURL foo_url("http://foo.com/cross_site_document_blocking/request.html");
EXPECT_TRUE(NavigateToURL(shell(), foo_url));
@@ -885,6 +1036,7 @@ class CrossSiteDocumentBlockingDisableVsFeatureTest
IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingDisableVsFeatureTest,
DisableBlocking) {
// Load a page that issues illegal cross-site document requests.
+ embedded_test_server()->StartAcceptingConnections();
GURL foo_url("http://foo.com/cross_site_document_blocking/request.html");
EXPECT_TRUE(NavigateToURL(shell(), foo_url));
@@ -894,23 +1046,9 @@ IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingDisableVsFeatureTest,
EXPECT_FALSE(was_blocked);
}
-// Even without any Site Isolation, document blocking should be turned on by
-// default.
-IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingBaseTest,
- BlockDocumentsByDefault) {
- // Load a page that issues illegal cross-site document requests to bar.com.
- GURL foo_url("http://foo.com/cross_site_document_blocking/request.html");
- EXPECT_TRUE(NavigateToURL(shell(), foo_url));
-
- bool was_blocked;
- ASSERT_TRUE(ExecuteScriptAndExtractBool(
- shell(), "sendRequest(\"valid.html\");", &was_blocked));
- EXPECT_TRUE(was_blocked);
-}
-
// Test class to verify that documents are blocked for isolated origins as well.
class CrossSiteDocumentBlockingIsolatedOriginTest
- : public CrossSiteDocumentBlockingBaseTest {
+ : public CrossSiteDocumentBlockingTest {
public:
CrossSiteDocumentBlockingIsolatedOriginTest() {}
~CrossSiteDocumentBlockingIsolatedOriginTest() override {}
@@ -918,7 +1056,7 @@ class CrossSiteDocumentBlockingIsolatedOriginTest
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(switches::kIsolateOrigins,
"http://bar.com");
- CrossSiteDocumentBlockingBaseTest::SetUpCommandLine(command_line);
+ CrossSiteDocumentBlockingTest::SetUpCommandLine(command_line);
}
private:
@@ -927,6 +1065,7 @@ class CrossSiteDocumentBlockingIsolatedOriginTest
IN_PROC_BROWSER_TEST_F(CrossSiteDocumentBlockingIsolatedOriginTest,
BlockDocumentsFromIsolatedOrigin) {
+ embedded_test_server()->StartAcceptingConnections();
if (AreAllSitesIsolatedForTesting())
return;
diff --git a/chromium/content/browser/loader/cross_site_document_resource_handler.cc b/chromium/content/browser/loader/cross_site_document_resource_handler.cc
index 9924a53b147..90792270128 100644
--- a/chromium/content/browser/loader/cross_site_document_resource_handler.cc
+++ b/chromium/content/browser/loader/cross_site_document_resource_handler.cc
@@ -20,6 +20,7 @@
#include "content/browser/loader/detachable_resource_handler.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/site_instance_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/resource_context.h"
@@ -66,16 +67,15 @@ void CrossSiteDocumentResourceHandler::LogBlockedResponseOnUIThread(
if (!web_contents)
return;
- ukm::UkmRecorder* recorder = ukm::UkmRecorder::Get();
- ukm::SourceId source_id = ukm::UkmRecorder::GetNewSourceID();
- recorder->UpdateSourceURL(source_id, web_contents->GetLastCommittedURL());
+ ukm::SourceId source_id = static_cast<WebContentsImpl*>(web_contents)
+ ->GetUkmSourceIdForLastCommittedSource();
ukm::builders::SiteIsolation_XSD_Browser_Blocked(source_id)
.SetCanonicalMimeType(static_cast<int64_t>(canonical_mime_type))
.SetContentLengthWasZero(content_length == 0)
.SetContentResourceType(resource_type)
.SetHttpResponseCode(http_response_code)
.SetNeededSniffing(needed_sniffing)
- .Record(recorder);
+ .Record(ukm::UkmRecorder::Get());
}
void CrossSiteDocumentResourceHandler::LogBlockedResponse(
@@ -166,6 +166,14 @@ class CrossSiteDocumentResourceHandler::Controller : public ResourceController {
}
}
+ void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) override {
+ DCHECK(!modified_request_headers.has_value())
+ << "Redirect with modified headers was not supported yet. "
+ "crbug.com/845683";
+ Resume();
+ }
+
void Cancel() override {
MarkAsUsed();
document_handler_->Cancel();
@@ -212,8 +220,6 @@ void CrossSiteDocumentResourceHandler::OnResponseStarted(
network::ResourceResponse* response,
std::unique_ptr<ResourceController> controller) {
has_response_started_ = true;
- http_response_code_ =
- response->head.headers ? response->head.headers->response_code() : 0;
network::CrossOriginReadBlocking::LogAction(
network::CrossOriginReadBlocking::Action::kResponseStarted);
@@ -388,8 +394,8 @@ void CrossSiteDocumentResourceHandler::OnReadCompleted(
// If we have some new data, ask the |analyzer_| to sniff it.
analyzer_->SniffResponseBody(data, new_data_offset);
- const bool confirmed_allowed = analyzer_->should_allow();
- confirmed_blockable = analyzer_->should_block();
+ const bool confirmed_allowed = analyzer_->ShouldAllow();
+ confirmed_blockable = analyzer_->ShouldBlock();
DCHECK(!(confirmed_blockable && confirmed_allowed));
// If sniffing didn't yield a conclusive response, and we haven't read too
@@ -425,11 +431,13 @@ void CrossSiteDocumentResourceHandler::OnReadCompleted(
: "null",
"url", request()->url().spec());
- LogBlockedResponse(info, http_response_code_);
+ LogBlockedResponse(info, analyzer_->http_response_code());
// Block the response and throw away the data. Report zero bytes read.
blocked_read_completed_ = true;
- info->set_blocked_cross_site_document(true);
+ info->set_blocked_response_from_reaching_renderer(true);
+ if (analyzer_->ShouldReportBlockedResponse())
+ info->set_should_report_corb_blocking(true);
network::CrossOriginReadBlocking::SanitizeBlockedResponse(
pending_response_start_);
@@ -535,10 +543,17 @@ void CrossSiteDocumentResourceHandler::OnResponseCompleted(
bool CrossSiteDocumentResourceHandler::ShouldBlockBasedOnHeaders(
const network::ResourceResponse& response) {
+ // Give embedder a chance to skip document blocking for this response.
+ const char* initiator_scheme_exception =
+ GetContentClient()
+ ->browser()
+ ->GetInitatorSchemeBypassingDocumentBlocking();
+
+ // Delegate most decisions to CrossOriginReadBlocking::ResponseAnalyzer.
analyzer_ =
std::make_unique<network::CrossOriginReadBlocking::ResponseAnalyzer>(
- *request(), response);
- if (analyzer_->should_allow())
+ *request(), response, initiator_scheme_exception);
+ if (analyzer_->ShouldAllow())
return false;
// Check if the response's site needs to have its documents protected. By
@@ -567,21 +582,12 @@ bool CrossSiteDocumentResourceHandler::ShouldBlockBasedOnHeaders(
if (!info || info->GetChildID() == -1)
return false;
- // Give embedder a chance to skip document blocking for this response.
- const char* initiator_scheme_exception =
- GetContentClient()
- ->browser()
- ->GetInitatorSchemeBypassingDocumentBlocking();
- if (initiator_scheme_exception && request()->initiator().has_value() &&
- request()->initiator()->scheme() == initiator_scheme_exception) {
- return false;
- }
-
- // Don't block plugin requests with universal access (e.g., Flash). Such
- // requests are made without CORS, and thus dont have an Origin request
- // header. Other plugin requests (e.g., NaCl) are made using CORS and have an
- // Origin request header. If they fail the CORS check above, they should be
- // blocked.
+ // Don't block plugin requests.
+ // TODO(lukasza): Only disable CORB for plugins with universal access (see
+ // PepperURLLoaderHost::has_universal_access_), because only such plugins may
+ // have their own CORS-like mechanisms - e.g. crossdomain.xml in Flash). We
+ // should still enforce CORB for other kinds of plugins (i.e. ones without
+ // universal access).
if (info->GetResourceType() == RESOURCE_TYPE_PLUGIN_RESOURCE &&
is_nocors_plugin_request_) {
return false;
diff --git a/chromium/content/browser/loader/cross_site_document_resource_handler.h b/chromium/content/browser/loader/cross_site_document_resource_handler.h
index 447c6ed2699..1598fb024bd 100644
--- a/chromium/content/browser/loader/cross_site_document_resource_handler.h
+++ b/chromium/content/browser/loader/cross_site_document_resource_handler.h
@@ -164,10 +164,6 @@ class CONTENT_EXPORT CrossSiteDocumentResourceHandler
// completed, and thus it is safe to cancel or detach on the next read.
bool blocked_read_completed_ = false;
- // The HTTP response code (e.g. 200 or 404) received in response to this
- // resource request.
- int http_response_code_ = 0;
-
base::WeakPtrFactory<CrossSiteDocumentResourceHandler> weak_this_;
DISALLOW_COPY_AND_ASSIGN(CrossSiteDocumentResourceHandler);
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 7f66b566c8b..99405d1b48e 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
@@ -20,7 +20,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/loader/intercepting_resource_handler.h"
#include "content/browser/loader/mime_sniffing_resource_handler.h"
diff --git a/chromium/content/browser/loader/data_pipe_to_source_stream.cc b/chromium/content/browser/loader/data_pipe_to_source_stream.cc
index 8a5c372798f..4a3694f5b01 100644
--- a/chromium/content/browser/loader/data_pipe_to_source_stream.cc
+++ b/chromium/content/browser/loader/data_pipe_to_source_stream.cc
@@ -4,6 +4,8 @@
#include "content/browser/loader/data_pipe_to_source_stream.h"
+#include <utility>
+
#include "base/auto_reset.h"
#include "net/base/io_buffer.h"
@@ -30,7 +32,7 @@ std::string DataPipeToSourceStream::Description() const {
int DataPipeToSourceStream::Read(net::IOBuffer* buf,
int buf_size,
- const net::CompletionCallback& callback) {
+ net::CompletionOnceCallback callback) {
base::AutoReset<bool>(&inside_read_, true);
if (!body_.get()) {
@@ -56,7 +58,7 @@ int DataPipeToSourceStream::Read(net::IOBuffer* buf,
return 0;
case MOJO_RESULT_SHOULD_WAIT:
// Data is not available yet.
- pending_callback_ = callback;
+ pending_callback_ = std::move(callback);
output_buf_ = buf;
output_buf_size_ = buf_size;
handle_watcher_.ArmOrNotify();
diff --git a/chromium/content/browser/loader/data_pipe_to_source_stream.h b/chromium/content/browser/loader/data_pipe_to_source_stream.h
index e45d2482e87..f77287f0611 100644
--- a/chromium/content/browser/loader/data_pipe_to_source_stream.h
+++ b/chromium/content/browser/loader/data_pipe_to_source_stream.h
@@ -8,6 +8,7 @@
#include "content/common/content_export.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/simple_watcher.h"
+#include "net/base/completion_once_callback.h"
#include "net/filter/source_stream.h"
namespace content {
@@ -19,7 +20,7 @@ class CONTENT_EXPORT DataPipeToSourceStream final : public net::SourceStream {
int Read(net::IOBuffer* buf,
int buf_size,
- const net::CompletionCallback& callback) override;
+ net::CompletionOnceCallback callback) override;
std::string Description() const override;
private:
@@ -33,7 +34,7 @@ class CONTENT_EXPORT DataPipeToSourceStream final : public net::SourceStream {
scoped_refptr<net::IOBuffer> output_buf_;
int output_buf_size_ = 0;
- net::CompletionCallback pending_callback_;
+ net::CompletionOnceCallback pending_callback_;
DISALLOW_COPY_AND_ASSIGN(DataPipeToSourceStream);
};
diff --git a/chromium/content/browser/loader/detachable_resource_handler.cc b/chromium/content/browser/loader/detachable_resource_handler.cc
index b8222d203d1..26593e97ec0 100644
--- a/chromium/content/browser/loader/detachable_resource_handler.cc
+++ b/chromium/content/browser/loader/detachable_resource_handler.cc
@@ -38,6 +38,14 @@ class DetachableResourceHandler::Controller : public ResourceController {
detachable_handler_->ResumeInternal();
}
+ void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) override {
+ DCHECK(!modified_request_headers.has_value())
+ << "Redirect with modified headers was not supported yet. "
+ "crbug.com/845683";
+ Resume();
+ }
+
void Cancel() override {
MarkAsUsed();
detachable_handler_->Cancel();
@@ -249,13 +257,6 @@ void DetachableResourceHandler::OnResponseCompleted(
std::make_unique<Controller>(this));
}
-void DetachableResourceHandler::OnDataDownloaded(int bytes_downloaded) {
- if (!next_handler_)
- return;
-
- next_handler_->OnDataDownloaded(bytes_downloaded);
-}
-
void DetachableResourceHandler::ResumeInternal() {
parent_read_buffer_ = nullptr;
parent_read_buffer_size_ = nullptr;
diff --git a/chromium/content/browser/loader/detachable_resource_handler.h b/chromium/content/browser/loader/detachable_resource_handler.h
index 972ffd13523..9e7e418a2f2 100644
--- a/chromium/content/browser/loader/detachable_resource_handler.h
+++ b/chromium/content/browser/loader/detachable_resource_handler.h
@@ -69,7 +69,6 @@ class CONTENT_EXPORT DetachableResourceHandler : public ResourceHandler {
void OnResponseCompleted(
const net::URLRequestStatus& status,
std::unique_ptr<ResourceController> controller) override;
- void OnDataDownloaded(int bytes_downloaded) override;
private:
class Controller;
diff --git a/chromium/content/browser/loader/navigation_loader_util.cc b/chromium/content/browser/loader/download_utils_impl.cc
index 96a7879b520..4af0a41e592 100644
--- a/chromium/content/browser/loader/navigation_loader_util.cc
+++ b/chromium/content/browser/loader/download_utils_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/browser/loader/navigation_loader_util.h"
+#include "content/browser/loader/download_utils_impl.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
@@ -10,13 +10,12 @@
#include "net/http/http_response_headers.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
#include "url/gurl.h"
-#include "url/origin.h"
namespace content {
-namespace navigation_loader_util {
+namespace download_utils {
bool MustDownload(const GURL& url,
- net::HttpResponseHeaders* headers,
+ const net::HttpResponseHeaders* headers,
const std::string& mime_type) {
if (headers) {
std::string disposition;
@@ -43,7 +42,7 @@ bool MustDownload(const GURL& url,
}
bool IsDownload(const GURL& url,
- net::HttpResponseHeaders* headers,
+ const net::HttpResponseHeaders* headers,
const std::string& mime_type) {
if (MustDownload(url, headers, mime_type))
return true;
@@ -54,5 +53,5 @@ bool IsDownload(const GURL& url,
return !headers || headers->response_code() / 100 == 2;
}
-} // namespace navigation_loader_util
+} // namespace download_utils
} // namespace content
diff --git a/chromium/content/browser/loader/download_utils_impl.h b/chromium/content/browser/loader/download_utils_impl.h
new file mode 100644
index 00000000000..724e45ba529
--- /dev/null
+++ b/chromium/content/browser/loader/download_utils_impl.h
@@ -0,0 +1,22 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_LOADER_DOWNLOAD_UTILS_IMPL_H_
+#define CONTENT_BROWSER_LOADER_DOWNLOAD_UTILS_IMPL_H_
+
+#include "content/public/browser/download_utils.h"
+
+namespace content {
+namespace download_utils {
+
+// Determines whether given response would result in a download.
+// Note this doesn't handle the case when a plugin exists for the |mime_type|.
+bool IsDownload(const GURL& url,
+ const net::HttpResponseHeaders* headers,
+ const std::string& mime_type);
+
+} // namespace download_utils
+} // namespace content
+
+#endif // CONTENT_BROWSER_LOADER_DOWNLOAD_UTILS_IMPL_H_
diff --git a/chromium/content/browser/loader/downloaded_temp_file_impl.cc b/chromium/content/browser/loader/downloaded_temp_file_impl.cc
deleted file mode 100644
index f699d84df04..00000000000
--- a/chromium/content/browser/loader/downloaded_temp_file_impl.cc
+++ /dev/null
@@ -1,30 +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/loader/downloaded_temp_file_impl.h"
-
-#include "content/browser/loader/resource_dispatcher_host_impl.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-
-namespace content {
-
-// static
-network::mojom::DownloadedTempFilePtr DownloadedTempFileImpl::Create(
- int child_id,
- int request_id) {
- mojo::InterfacePtr<network::mojom::DownloadedTempFile> ptr;
- mojo::MakeStrongBinding(
- std::make_unique<DownloadedTempFileImpl>(child_id, request_id),
- mojo::MakeRequest(&ptr));
- return ptr;
-}
-
-DownloadedTempFileImpl::~DownloadedTempFileImpl() {
- ResourceDispatcherHostImpl::Get()->UnregisterDownloadedTempFile(child_id_,
- request_id_);
-}
-DownloadedTempFileImpl::DownloadedTempFileImpl(int child_id, int request_id)
- : child_id_(child_id), request_id_(request_id) {}
-
-} // namespace content
diff --git a/chromium/content/browser/loader/downloaded_temp_file_impl.h b/chromium/content/browser/loader/downloaded_temp_file_impl.h
deleted file mode 100644
index 07deff40610..00000000000
--- a/chromium/content/browser/loader/downloaded_temp_file_impl.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_LOADER_DOWNLOADED_TEMP_FILE_IMPL_H_
-#define CONTENT_BROWSER_LOADER_DOWNLOADED_TEMP_FILE_IMPL_H_
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "services/network/public/mojom/url_loader_factory.mojom.h"
-
-namespace content {
-
-// DownloadedTempFileImpl is created on the download_to_file mode of resource
-// loading. The instance is held by the client and lives until the client
-// destroys the interface, slightly after the URLLoader is destroyed.
-class CONTENT_EXPORT DownloadedTempFileImpl final
- : public network::mojom::DownloadedTempFile {
- public:
- // Creates a DownloadedTempFileImpl, binds it as a strong interface, and
- // returns the interface ptr to be passed to the client.
- // That means:
- // * The DownloadedTempFile object created here is essentially owned by the
- // client. It keeps alive until the client destroys the other endpoint.
- static network::mojom::DownloadedTempFilePtr Create(int child_id,
- int request_id);
-
- DownloadedTempFileImpl(int child_id, int request_id);
- ~DownloadedTempFileImpl() override;
-
- private:
- const int child_id_;
- const int request_id_;
-
- DISALLOW_COPY_AND_ASSIGN(DownloadedTempFileImpl);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_LOADER_DOWNLOADED_TEMP_FILE_IMPL_H_
diff --git a/chromium/content/browser/loader/intercepting_resource_handler.cc b/chromium/content/browser/loader/intercepting_resource_handler.cc
index 0b038d238a1..a7c3a1010ea 100644
--- a/chromium/content/browser/loader/intercepting_resource_handler.cc
+++ b/chromium/content/browser/loader/intercepting_resource_handler.cc
@@ -29,6 +29,14 @@ class InterceptingResourceHandler::Controller : public ResourceController {
intercepting_handler_->ResumeInternal();
}
+ void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) override {
+ DCHECK(!modified_request_headers.has_value())
+ << "Redirect with modified headers was not supported yet. "
+ "crbug.com/845683";
+ Resume();
+ }
+
void Cancel() override {
MarkAsUsed();
intercepting_handler_->Cancel();
diff --git a/chromium/content/browser/loader/layered_resource_handler.cc b/chromium/content/browser/loader/layered_resource_handler.cc
index 340025a4b70..9a163e7d18b 100644
--- a/chromium/content/browser/loader/layered_resource_handler.cc
+++ b/chromium/content/browser/loader/layered_resource_handler.cc
@@ -69,9 +69,4 @@ void LayeredResourceHandler::OnResponseCompleted(
next_handler_->OnResponseCompleted(status, std::move(controller));
}
-void LayeredResourceHandler::OnDataDownloaded(int bytes_downloaded) {
- DCHECK(next_handler_.get());
- next_handler_->OnDataDownloaded(bytes_downloaded);
-}
-
} // namespace content
diff --git a/chromium/content/browser/loader/layered_resource_handler.h b/chromium/content/browser/loader/layered_resource_handler.h
index 47d37bca55f..2aa0e245127 100644
--- a/chromium/content/browser/loader/layered_resource_handler.h
+++ b/chromium/content/browser/loader/layered_resource_handler.h
@@ -45,7 +45,6 @@ class CONTENT_EXPORT LayeredResourceHandler : public ResourceHandler {
void OnResponseCompleted(
const net::URLRequestStatus& status,
std::unique_ptr<ResourceController> controller) override;
- void OnDataDownloaded(int bytes_downloaded) override;
std::unique_ptr<ResourceHandler> next_handler_;
};
diff --git a/chromium/content/browser/loader/loader_browsertest.cc b/chromium/content/browser/loader/loader_browsertest.cc
index 450919d3c3b..024fadee921 100644
--- a/chromium/content/browser/loader/loader_browsertest.cc
+++ b/chromium/content/browser/loader/loader_browsertest.cc
@@ -273,17 +273,20 @@ namespace {
// Responds with a HungResponse for the specified URL to hang on the request.
// If the network service is enabled, crashes the process. If it's disabled,
// cancels all requests from specifield |child_id|.
+//
+// |crash_network_service_callback| crashes the network service when invoked,
+// and must be called on the UI thread.
std::unique_ptr<net::test_server::HttpResponse> CancelOnRequest(
const std::string& relative_url,
int child_id,
+ base::RepeatingClosure crash_network_service_callback,
const net::test_server::HttpRequest& request) {
if (request.relative_url != relative_url)
return nullptr;
if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::BindOnce(SimulateNetworkServiceCrash));
+ content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
+ crash_network_service_callback);
} else {
content::BrowserThread::PostTask(
content::BrowserThread::IO, FROM_HERE,
@@ -303,7 +306,9 @@ std::unique_ptr<net::test_server::HttpResponse> CancelOnRequest(
IN_PROC_BROWSER_TEST_F(LoaderBrowserTest, SyncXMLHttpRequest_Cancelled) {
embedded_test_server()->RegisterRequestHandler(base::Bind(
&CancelOnRequest, "/hung",
- shell()->web_contents()->GetMainFrame()->GetProcess()->GetID()));
+ shell()->web_contents()->GetMainFrame()->GetProcess()->GetID(),
+ base::BindRepeating(&BrowserTestBase::SimulateNetworkServiceCrash,
+ base::Unretained(this))));
ASSERT_TRUE(embedded_test_server()->Start());
WaitForLoadStop(shell()->web_contents());
@@ -813,25 +818,6 @@ IN_PROC_BROWSER_TEST_F(PreviewsStateBrowserTest,
CheckResourcesRequested(true);
}
-// Test that reloading with Lo-Fi disabled doesn't call ShouldEnableLoFiMode and
-// already has LOFI_OFF.
-IN_PROC_BROWSER_TEST_F(PreviewsStateBrowserTest,
- ShouldEnableLoFiModeReloadDisableLoFi) {
- // Navigate with GetPreviewsState returning SERVER_LOFI_ON.
- Reset(SERVER_LOFI_ON);
- NavigateToURLBlockUntilNavigationsComplete(
- shell(), embedded_test_server()->GetURL("/page_with_iframe.html"), 1);
- CheckResourcesRequested(true);
-
- // Reload with Lo-Fi disabled.
- Reset(PREVIEWS_NO_TRANSFORM);
- TestNavigationObserver tab_observer(shell()->web_contents(), 1);
- shell()->web_contents()->GetController().Reload(ReloadType::DISABLE_PREVIEWS,
- true);
- tab_observer.Wait();
- CheckResourcesRequested(false);
-}
-
namespace {
struct RequestData {
@@ -871,6 +857,19 @@ class RequestDataBrowserTest : public ContentBrowserTest {
return copy;
}
+ void WaitForRequests(size_t count) {
+ while (true) {
+ base::RunLoop run_loop;
+ {
+ base::AutoLock auto_lock(requests_lock_);
+ if (requests_.size() == count)
+ return;
+ requests_closure_ = run_loop.QuitClosure();
+ }
+ run_loop.Run();
+ }
+ }
+
private:
void SetUpOnMainThread() override {
ContentBrowserTest::SetUpOnMainThread();
@@ -893,10 +892,13 @@ class RequestDataBrowserTest : public ContentBrowserTest {
void RequestCreated(RequestData data) {
base::AutoLock auto_lock(requests_lock_);
requests_.push_back(data);
+ if (requests_closure_)
+ requests_closure_.Run();
}
base::Lock requests_lock_;
std::vector<RequestData> requests_;
+ base::Closure requests_closure_;
std::unique_ptr<URLLoaderInterceptor> interceptor_;
};
@@ -928,6 +930,7 @@ IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, LinkRelPrefetch) {
url::Origin top_origin = url::Origin::Create(top_url);
NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
+ WaitForRequests(2u);
auto requests = data();
EXPECT_EQ(2u, requests.size());
@@ -944,6 +947,7 @@ IN_PROC_BROWSER_TEST_F(RequestDataBrowserTest, LinkRelPrefetchReferrerPolicy) {
url::Origin top_origin = url::Origin::Create(top_url);
NavigateToURLBlockUntilNavigationsComplete(shell(), top_url, 1);
+ WaitForRequests(2u);
auto requests = data();
EXPECT_EQ(2u, requests.size());
diff --git a/chromium/content/browser/loader/merkle_integrity_source_stream.cc b/chromium/content/browser/loader/merkle_integrity_source_stream.cc
index 4643113b761..94c532f18e2 100644
--- a/chromium/content/browser/loader/merkle_integrity_source_stream.cc
+++ b/chromium/content/browser/loader/merkle_integrity_source_stream.cc
@@ -19,7 +19,7 @@ namespace {
// maximum record size in TLS and the default maximum frame size in HTTP/2.
constexpr uint64_t kMaxRecordSize = 16 * 1024;
-constexpr char kMiSha256Header[] = "mi-sha256=";
+constexpr char kMiSha256Header[] = "mi-sha256-draft2=";
constexpr size_t kMiSha256HeaderLength = sizeof(kMiSha256Header) - 1;
// Copies as many bytes from |input| as will fit in |output| and advances both.
diff --git a/chromium/content/browser/loader/merkle_integrity_source_stream_unittest.cc b/chromium/content/browser/loader/merkle_integrity_source_stream_unittest.cc
index dc1d802e457..61c61692ec5 100644
--- a/chromium/content/browser/loader/merkle_integrity_source_stream_unittest.cc
+++ b/chromium/content/browser/loader/merkle_integrity_source_stream_unittest.cc
@@ -17,13 +17,13 @@ const int kBigBufferSize = 4096;
const int kSmallBufferSize = 1;
const char kMIEmptyBody[] =
- "mi-sha256=bjQLnP-zepicpUTmu3gKLHiQHT-zNzh2hRGjBhevoB0";
+ "mi-sha256-draft2=bjQLnP-zepicpUTmu3gKLHiQHT-zNzh2hRGjBhevoB0";
const char kMISingleRecord[] =
- "mi-sha256=dcRDgR2GM35DluAV13PzgnG6-pvQwPywfFvAu1UeFrs";
+ "mi-sha256-draft2=dcRDgR2GM35DluAV13PzgnG6-pvQwPywfFvAu1UeFrs";
const char kMIMultipleRecords[] =
- "mi-sha256=IVa9shfs0nyKEhHqtB3WVNANJ2Njm5KjQLjRtnbkYJ4";
+ "mi-sha256-draft2=IVa9shfs0nyKEhHqtB3WVNANJ2Njm5KjQLjRtnbkYJ4";
const char kMIWholeNumberOfRecords[] =
- "mi-sha256=L2vdwBplKvIr0ZPkcuskWZfEVDgVdHa6aD363UpKuZs";
+ "mi-sha256-draft2=L2vdwBplKvIr0ZPkcuskWZfEVDgVdHa6aD363UpKuZs";
enum class ReadResultType {
// Each call to AddReadResult is a separate read from the lower layer
@@ -180,7 +180,7 @@ TEST_P(MerkleIntegritySourceStreamTest, MalformedMIHeader) {
}
TEST_P(MerkleIntegritySourceStreamTest, WrongMIAttributeName) {
- Init("mi-sha255=bjQLnP-zepicpUTmu3gKLHiQHT-zNzh2hRGjBhevoB0");
+ Init("mi-sha256-draft1=bjQLnP-zepicpUTmu3gKLHiQHT-zNzh2hRGjBhevoB0");
source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
std::string actual_output;
int result = ReadStream(&actual_output);
@@ -188,7 +188,7 @@ TEST_P(MerkleIntegritySourceStreamTest, WrongMIAttributeName) {
}
TEST_P(MerkleIntegritySourceStreamTest, HashTooShort) {
- Init("mi-sha256=bjQLnP-zepicpUTmu3gKLHiQHT-zNzh2hRGjBhevoA");
+ Init("mi-sha256-draft2=bjQLnP-zepicpUTmu3gKLHiQHT-zNzh2hRGjBhevoA");
source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
std::string actual_output;
int result = ReadStream(&actual_output);
@@ -196,7 +196,7 @@ TEST_P(MerkleIntegritySourceStreamTest, HashTooShort) {
}
TEST_P(MerkleIntegritySourceStreamTest, HashTooLong) {
- Init("mi-sha256=bjQLnP-zepicpUTmu3gKLHiQHT-zNzh2hRGjBhevoB0A");
+ Init("mi-sha256-draft2=bjQLnP-zepicpUTmu3gKLHiQHT-zNzh2hRGjBhevoB0A");
source()->AddReadResult(nullptr, 0, net::OK, GetParam().mode);
std::string actual_output;
int result = ReadStream(&actual_output);
@@ -470,7 +470,7 @@ TEST_P(MerkleIntegritySourceStreamTest, Truncated) {
// represent the empty string. Update the code and possibly this test depending
// on how https://github.com/martinthomson/http-mice/issues/3 is resolved.
TEST_P(MerkleIntegritySourceStreamTest, EmptyFinalRecord) {
- Init("mi-sha256=JJnIuaOEc2247K9V88VQAQy1GJuQ6ylaVM7mG69QkE4");
+ Init("mi-sha256-draft2=JJnIuaOEc2247K9V88VQAQy1GJuQ6ylaVM7mG69QkE4");
const uint8_t kRecordSize[] = {0, 0, 0, 0, 0, 0, 0, 16};
const std::string kMessage(
"When I grow up, I want to be a watermelon!! \xf0\x9f\x8d\x89");
diff --git a/chromium/content/browser/loader/mime_sniffing_resource_handler.cc b/chromium/content/browser/loader/mime_sniffing_resource_handler.cc
index bed70acf54d..89e2c5351c4 100644
--- a/chromium/content/browser/loader/mime_sniffing_resource_handler.cc
+++ b/chromium/content/browser/loader/mime_sniffing_resource_handler.cc
@@ -24,7 +24,6 @@
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/loader/stream_resource_handler.h"
#include "content/browser/web_package/signed_exchange_utils.h"
-#include "content/browser/web_package/web_package_request_handler.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/resource_context.h"
@@ -75,6 +74,14 @@ class MimeSniffingResourceHandler::Controller : public ResourceController {
mime_handler_->ResumeInternal();
}
+ void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) override {
+ DCHECK(!modified_request_headers.has_value())
+ << "Redirect with modified headers was not supported yet. "
+ "crbug.com/845683";
+ Resume();
+ }
+
void Cancel() override {
MarkAsUsed();
mime_handler_->Cancel();
diff --git a/chromium/content/browser/loader/mock_resource_loader.cc b/chromium/content/browser/loader/mock_resource_loader.cc
index 7444b0ad792..e43c857841a 100644
--- a/chromium/content/browser/loader/mock_resource_loader.cc
+++ b/chromium/content/browser/loader/mock_resource_loader.cc
@@ -10,6 +10,7 @@
#include "content/browser/loader/resource_controller.h"
#include "content/browser/loader/resource_handler.h"
#include "net/base/io_buffer.h"
+#include "net/http/http_request_headers.h"
#include "net/url_request/url_request_status.h"
#include "services/network/public/cpp/resource_response.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -24,6 +25,14 @@ class MockResourceLoader::TestResourceController : public ResourceController {
void Resume() override { mock_loader_->OnResume(); }
+ void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) override {
+ DCHECK(!modified_request_headers.has_value())
+ << "Redirect with modified headers was not supported yet. "
+ "crbug.com/845683";
+ Resume();
+ }
+
void Cancel() override { CancelWithError(net::ERR_ABORTED); }
void CancelWithError(int error_code) override {
diff --git a/chromium/content/browser/loader/mojo_async_resource_handler.cc b/chromium/content/browser/loader/mojo_async_resource_handler.cc
index 08d0708f93c..4910201a2d1 100644
--- a/chromium/content/browser/loader/mojo_async_resource_handler.cc
+++ b/chromium/content/browser/loader/mojo_async_resource_handler.cc
@@ -12,9 +12,7 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
-#include "base/metrics/histogram_macros.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"
@@ -40,24 +38,19 @@ constexpr size_t kMinAllocationSize = 2 * net::kMaxBytesToSniff;
constexpr size_t kMaxChunkSize = 32 * 1024;
-// Records histograms for the time spent between several events in the
-// MojoAsyncResourceHandler for a navigation.
-// - |response_started| is when the response's headers and metadata are
-// available. Loading is paused at this time.
-// - |proceed_with_response| is when loading is resumed.
-// - |first_read_completed| is when the first part of the body has been read.
-void RecordNavigationResourceHandlerMetrics(
- base::TimeTicks response_started,
- base::TimeTicks proceed_with_response,
- base::TimeTicks first_read_completed) {
- UMA_HISTOGRAM_TIMES(
- "Navigation.ResourceHandler."
- "ResponseStartedUntilProceedWithResponse",
- proceed_with_response - response_started);
- UMA_HISTOGRAM_TIMES(
- "Navigation.ResourceHandler."
- "ProceedWithResponseUntilFirstReadCompleted",
- first_read_completed - proceed_with_response);
+// Time between sending the transfer size updates to renderer. This threshold is
+// chosen as a compromise between sending too frequent updates and the limit its
+// consumers (DevTools and page load metrics) expect.
+constexpr base::TimeDelta kTransferSizeReportInterval =
+ base::TimeDelta::FromMilliseconds(500);
+
+bool ShouldReportTransferSize(
+ const ResourceRequestInfoImpl* resource_request_info) {
+ // Transfer size is reported only when report_raw_headers is set or the
+ // renderer is allowed to receive the resource response metadata (e.g. by
+ // Cross-Origin Read Blocking).
+ return resource_request_info->ShouldReportRawHeaders() ||
+ !resource_request_info->blocked_response_from_reaching_renderer();
}
} // namespace
@@ -124,6 +117,7 @@ MojoAsyncResourceHandler::MojoAsyncResourceHandler(
url_loader_client_(std::move(url_loader_client)),
weak_factory_(this) {
DCHECK(IsResourceTypeFrame(resource_type) ||
+ resource_type == RESOURCE_TYPE_SERVICE_WORKER ||
!(url_loader_options_ &
network::mojom::kURLLoadOptionSendSSLInfoWithResponse));
DCHECK(resource_type == RESOURCE_TYPE_MAIN_FRAME ||
@@ -178,37 +172,26 @@ void MojoAsyncResourceHandler::OnResponseStarted(
network::ResourceResponse* response,
std::unique_ptr<ResourceController> controller) {
DCHECK(!has_controller());
- time_response_started_ = base::TimeTicks::Now();
if (upload_progress_tracker_) {
upload_progress_tracker_->OnUploadCompleted();
upload_progress_tracker_ = nullptr;
}
- const ResourceRequestInfoImpl* info = GetRequestInfo();
response->head.encoded_data_length = request()->raw_header_size();
reported_total_received_bytes_ = response->head.encoded_data_length;
response->head.request_start = request()->creation_time();
- response->head.response_start = time_response_started_;
+ response->head.response_start = base::TimeTicks::Now();
sent_received_response_message_ = true;
- network::mojom::DownloadedTempFilePtr downloaded_file_ptr;
- if (!response->head.download_file_path.empty()) {
- downloaded_file_ptr = DownloadedTempFileImpl::Create(info->GetChildID(),
- info->GetRequestID());
- rdh_->RegisterDownloadedTempFile(info->GetChildID(), info->GetRequestID(),
- response->head.download_file_path);
- }
-
if ((url_loader_options_ &
network::mojom::kURLLoadOptionSendSSLInfoWithResponse) &&
request()->ssl_info().cert) {
response->head.ssl_info = request()->ssl_info();
}
- url_loader_client_->OnReceiveResponse(response->head,
- std::move(downloaded_file_ptr));
+ url_loader_client_->OnReceiveResponse(response->head);
net::IOBufferWithSize* metadata = GetResponseMetadata(request());
if (metadata) {
@@ -335,21 +318,18 @@ void MojoAsyncResourceHandler::OnReadCompleted(
return;
}
- const ResourceRequestInfoImpl* info = GetRequestInfo();
- if (info->ShouldReportRawHeaders()) {
+ if (ShouldReportTransferSize(GetRequestInfo()) &&
+ (time_transfer_size_next_report_.is_null() ||
+ time_transfer_size_next_report_ <= base::TimeTicks::Now())) {
auto transfer_size_diff = CalculateRecentlyReceivedBytes();
- if (transfer_size_diff > 0)
+ if (transfer_size_diff > 0) {
url_loader_client_->OnTransferSizeUpdated(transfer_size_diff);
+ time_transfer_size_next_report_ =
+ base::TimeTicks::Now() + kTransferSizeReportInterval;
+ }
}
if (response_body_consumer_handle_.is_valid()) {
- if (url_loader_options_ &
- network::mojom::kURLLoadOptionPauseOnResponseStarted) {
- base::TimeTicks time_first_read_completed = base::TimeTicks::Now();
- RecordNavigationResourceHandlerMetrics(time_response_started_,
- time_proceed_with_response_,
- time_first_read_completed);
- }
// Send the data pipe on the first OnReadCompleted call.
url_loader_client_->OnStartLoadingResponseBody(
std::move(response_body_consumer_handle_));
@@ -384,16 +364,10 @@ void MojoAsyncResourceHandler::OnReadCompleted(
controller->Resume();
}
-void MojoAsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) {
- url_loader_client_->OnDataDownloaded(bytes_downloaded,
- CalculateRecentlyReceivedBytes());
-}
-
void MojoAsyncResourceHandler::FollowRedirect(
+ const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
- DCHECK(!modified_request_headers.has_value()) << "Redirect with modified "
- "headers was not supported "
- "yet. crbug.com/845683";
if (!request()->status().is_success()) {
DVLOG(1) << "FollowRedirect for invalid request";
return;
@@ -408,14 +382,12 @@ void MojoAsyncResourceHandler::FollowRedirect(
DCHECK(!did_defer_on_writing_);
did_defer_on_redirect_ = false;
request()->LogUnblocked();
- Resume();
+ ResumeForRedirect(modified_request_headers);
}
void MojoAsyncResourceHandler::ProceedWithResponse() {
DCHECK(did_defer_on_response_started_);
- time_proceed_with_response_ = base::TimeTicks::Now();
-
request()->LogUnblocked();
Resume();
}
@@ -524,8 +496,8 @@ void MojoAsyncResourceHandler::OnResponseCompleted(
loader_status.encoded_data_length = request()->GetTotalReceivedBytes();
loader_status.encoded_body_length = request()->GetRawBodyBytes();
loader_status.decoded_body_length = total_written_bytes_;
- loader_status.blocked_cross_site_document =
- GetRequestInfo()->blocked_cross_site_document();
+ loader_status.should_report_corb_blocking =
+ GetRequestInfo()->should_report_corb_blocking();
if ((url_loader_options_ &
network::mojom::kURLLoadOptionSendSSLInfoForCertificateError) &&
@@ -534,6 +506,12 @@ void MojoAsyncResourceHandler::OnResponseCompleted(
loader_status.ssl_info = request()->ssl_info();
}
+ if (ShouldReportTransferSize(GetRequestInfo())) {
+ auto transfer_size_diff = CalculateRecentlyReceivedBytes();
+ if (transfer_size_diff > 0)
+ url_loader_client_->OnTransferSizeUpdated(transfer_size_diff);
+ }
+
url_loader_client_->OnComplete(loader_status);
controller->Resume();
}
diff --git a/chromium/content/browser/loader/mojo_async_resource_handler.h b/chromium/content/browser/loader/mojo_async_resource_handler.h
index c612b2f72e2..ad87065771e 100644
--- a/chromium/content/browser/loader/mojo_async_resource_handler.h
+++ b/chromium/content/browser/loader/mojo_async_resource_handler.h
@@ -13,7 +13,6 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
#include "content/browser/loader/resource_handler.h"
#include "content/common/content_export.h"
#include "content/public/common/resource_type.h"
@@ -82,10 +81,11 @@ class CONTENT_EXPORT MojoAsyncResourceHandler
void OnResponseCompleted(
const net::URLRequestStatus& status,
std::unique_ptr<ResourceController> controller) override;
- void OnDataDownloaded(int bytes_downloaded) override;
// network::mojom::URLLoader implementation:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
@@ -149,13 +149,12 @@ class CONTENT_EXPORT MojoAsyncResourceHandler
bool did_defer_on_writing_ = false;
bool did_defer_on_redirect_ = false;
bool did_defer_on_response_started_ = false;
+
+ // The time transfer size should be reported next.
+ base::TimeTicks time_transfer_size_next_report_;
int64_t reported_total_received_bytes_ = 0;
int64_t total_written_bytes_ = 0;
- // Used for UMA histograms.
- base::TimeTicks time_response_started_;
- base::TimeTicks time_proceed_with_response_;
-
// Pointer to parent's information about the read buffer. Only non-null while
// OnWillRead is deferred.
scoped_refptr<net::IOBuffer>* parent_buffer_ = nullptr;
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 f6ca9da8125..a4170df9f58 100644
--- a/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc
+++ b/chromium/content/browser/loader/mojo_async_resource_handler_unittest.cc
@@ -10,6 +10,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/logging.h"
@@ -49,7 +50,9 @@
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_status.h"
+#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
@@ -304,9 +307,9 @@ class MojoAsyncResourceHandlerTestBase {
// Create and initialize |request_|. None of this matters, for these tests,
// just need something non-NULL.
- net::URLRequestContext* request_context =
+ request_context_ =
browser_context_->GetResourceContext()->GetRequestContext();
- request_ = request_context->CreateRequest(
+ request_ = request_context_->CreateRequest(
GURL("http://foo/"), net::DEFAULT_PRIORITY, &url_request_delegate_,
TRAFFIC_ANNOTATION_FOR_TESTS);
request_->set_upload(std::move(upload_stream));
@@ -403,6 +406,7 @@ class MojoAsyncResourceHandlerTestBase {
network::TestURLLoaderClient url_loader_client_;
std::unique_ptr<TestBrowserContext> browser_context_;
net::TestDelegate url_request_delegate_;
+ net::URLRequestContext* request_context_;
std::unique_ptr<net::URLRequest> request_;
std::unique_ptr<MojoAsyncResourceHandlerWithStubOperations> handler_;
std::unique_ptr<MockResourceLoader> mock_loader_;
@@ -1211,7 +1215,7 @@ TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, RedirectHandling) {
ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
mock_loader_->status());
- handler_->FollowRedirect(base::nullopt);
+ handler_->FollowRedirect(base::nullopt, base::nullopt);
ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
url_loader_client_.ClearHasReceivedRedirect();
@@ -1232,7 +1236,7 @@ TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, RedirectHandling) {
ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
mock_loader_->status());
- handler_->FollowRedirect(base::nullopt);
+ handler_->FollowRedirect(base::nullopt, base::nullopt);
ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
// Give the final response.
@@ -1256,7 +1260,7 @@ TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, RedirectHandling) {
// redirect, despite the fact that no redirect has been received yet.
TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest,
MalformedFollowRedirectRequest) {
- handler_->FollowRedirect(base::nullopt);
+ handler_->FollowRedirect(base::nullopt, base::nullopt);
EXPECT_TRUE(handler_->has_received_bad_message());
}
@@ -1459,6 +1463,66 @@ TEST_F(MojoAsyncResourceHandlerSendSSLInfoForCertificateError,
EXPECT_FALSE(url_loader_client_.completion_status().ssl_info);
};
+TEST_F(MojoAsyncResourceHandlerTest,
+ TransferSizeUpdateCalledForNonBlockedResponse) {
+ net::URLRequestJobFactoryImpl test_job_factory_;
+ auto test_job = std::make_unique<net::URLRequestTestJob>(
+ request_.get(), request_context_->network_delegate(), "response headers",
+ "response body", true);
+ auto test_job_interceptor = std::make_unique<net::TestJobInterceptor>();
+ net::TestJobInterceptor* raw_test_job_interceptor =
+ test_job_interceptor.get();
+ EXPECT_TRUE(test_job_factory_.SetProtocolHandler(
+ url::kHttpScheme, std::move(test_job_interceptor)));
+
+ request_context_->set_job_factory(&test_job_factory_);
+ raw_test_job_interceptor->set_main_intercept_job(std::move(test_job));
+ request_->Start();
+
+ ASSERT_TRUE(CallOnWillStartAndOnResponseStarted());
+ url_request_delegate_.RunUntilComplete();
+
+ net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK);
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(status));
+ url_loader_client_.RunUntilComplete();
+ EXPECT_LT(0, url_loader_client_.body_transfer_size());
+ EXPECT_EQ(request_->GetTotalReceivedBytes(),
+ url_loader_client_.body_transfer_size());
+}
+
+TEST_F(MojoAsyncResourceHandlerTest,
+ TransferSizeUpdateNotCalledForBlockedResponse) {
+ net::URLRequestJobFactoryImpl test_job_factory_;
+ auto test_job = std::make_unique<net::URLRequestTestJob>(
+ request_.get(), request_context_->network_delegate(), "response headers",
+ "response body", true);
+ auto test_job_interceptor = std::make_unique<net::TestJobInterceptor>();
+ net::TestJobInterceptor* raw_test_job_interceptor =
+ test_job_interceptor.get();
+ EXPECT_TRUE(test_job_factory_.SetProtocolHandler(
+ url::kHttpScheme, std::move(test_job_interceptor)));
+
+ request_context_->set_job_factory(&test_job_factory_);
+ raw_test_job_interceptor->set_main_intercept_job(std::move(test_job));
+ request_->Start();
+
+ // Block the response to reach renderer.
+ ResourceRequestInfoImpl::ForRequest(request_.get())
+ ->set_blocked_response_from_reaching_renderer(true);
+
+ ASSERT_TRUE(CallOnWillStartAndOnResponseStarted());
+
+ net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK);
+ ASSERT_EQ(MockResourceLoader::Status::IDLE,
+ mock_loader_->OnResponseCompleted(status));
+ url_request_delegate_.RunUntilComplete();
+ EXPECT_TRUE(ResourceRequestInfoImpl::ForRequest(request_.get())
+ ->blocked_response_from_reaching_renderer());
+ EXPECT_EQ(0, url_loader_client_.body_transfer_size());
+ EXPECT_LT(0, request_->GetTotalReceivedBytes());
+}
+
INSTANTIATE_TEST_CASE_P(MojoAsyncResourceHandlerWithAllocationSizeTest,
MojoAsyncResourceHandlerWithAllocationSizeTest,
::testing::Values(8, 32 * 2014));
diff --git a/chromium/content/browser/loader/navigation_loader_util.h b/chromium/content/browser/loader/navigation_loader_util.h
deleted file mode 100644
index d5741554aff..00000000000
--- a/chromium/content/browser/loader/navigation_loader_util.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_LOADER_NAVIGATION_LOADER_UTIL_H_
-#define CONTENT_BROWSER_LOADER_NAVIGATION_LOADER_UTIL_H_
-
-#include "base/optional.h"
-
-#include <string>
-
-class GURL;
-namespace net {
-class HttpResponseHeaders;
-}
-
-namespace content {
-namespace navigation_loader_util {
-
-// Returns true if the given response must be downloaded because of the headers.
-bool MustDownload(const GURL& url,
- net::HttpResponseHeaders* headers,
- const std::string& mime_type);
-
-// Determines whether given response would result in a download.
-// Note this doesn't handle the case when a plugin exists for the |mime_type|.
-bool IsDownload(const GURL& url,
- net::HttpResponseHeaders* headers,
- const std::string& mime_type);
-
-} // namespace navigation_loader_util
-} // namespace content
-
-#endif // CONTENT_BROWSER_LOADER_NAVIGATION_LOADER_UTIL_H_
diff --git a/chromium/content/browser/loader/navigation_url_loader.h b/chromium/content/browser/loader/navigation_url_loader.h
index e0151260cfc..e2b961d6715 100644
--- a/chromium/content/browser/loader/navigation_url_loader.h
+++ b/chromium/content/browser/loader/navigation_url_loader.h
@@ -8,8 +8,13 @@
#include <memory>
#include "base/macros.h"
+#include "base/optional.h"
#include "content/common/content_export.h"
+namespace net {
+class HttpRequestHeaders;
+}
+
namespace content {
class AppCacheNavigationHandle;
@@ -51,7 +56,10 @@ class CONTENT_EXPORT NavigationURLLoader {
// Called in response to OnRequestRedirected to continue processing the
// request.
- virtual void FollowRedirect() = 0;
+ virtual void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) = 0;
// Called in response to OnResponseStarted to process the response.
virtual void ProceedWithResponse() = 0;
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl.cc b/chromium/content/browser/loader/navigation_url_loader_impl.cc
index 3dc15070498..0fb15c7c1be 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_impl.cc
@@ -10,6 +10,7 @@
#include "base/bind_helpers.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
+#include "base/stl_util.h"
#include "base/task_scheduler/post_task.h"
#include "base/trace_event/trace_event.h"
#include "components/download/public/common/download_stats.h"
@@ -22,7 +23,6 @@
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/loader/navigation_loader_interceptor.h"
-#include "content/browser/loader/navigation_loader_util.h"
#include "content/browser/loader/navigation_url_loader_delegate.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_request_info_impl.h"
@@ -34,17 +34,18 @@
#include "content/browser/url_loader_factory_getter.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_package/signed_exchange_consts.h"
+#include "content/browser/web_package/signed_exchange_request_handler.h"
#include "content/browser/web_package/signed_exchange_url_loader_factory_for_non_network_service.h"
#include "content/browser/web_package/signed_exchange_utils.h"
-#include "content/browser/web_package/web_package_request_handler.h"
#include "content/browser/webui/url_data_manager_backend.h"
#include "content/browser/webui/web_ui_url_loader_factory_internal.h"
#include "content/common/navigation_subresource_loader_params.h"
-#include "content/common/service_worker/service_worker_utils.h"
+#include "content/common/net/record_load_histograms.h"
#include "content/common/throttling_url_loader.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/download_utils.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/navigation_data.h"
#include "content/public/browser/navigation_ui_data.h"
@@ -59,6 +60,7 @@
#include "content/public/common/webplugininfo.h"
#include "net/base/load_flags.h"
#include "net/http/http_content_disposition.h"
+#include "net/http/http_request_headers.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_util.h"
#include "net/url_request/url_request.h"
@@ -73,6 +75,7 @@
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
@@ -108,7 +111,7 @@ base::LazyInstance<NavigationURLLoaderImpl::BeginNavigationInterceptor>::Leaky
// of them is enabled.
bool IsLoaderInterceptionEnabled() {
return base::FeatureList::IsEnabled(network::features::kNetworkService) ||
- ServiceWorkerUtils::IsServicificationEnabled() ||
+ blink::ServiceWorkerUtils::IsServicificationEnabled() ||
signed_exchange_utils::IsSignedExchangeHandlingEnabled();
}
@@ -243,6 +246,8 @@ std::unique_ptr<network::ResourceRequest> CreateResourceRequest(
new_request->fetch_redirect_mode = network::mojom::FetchRedirectMode::kManual;
new_request->fetch_request_context_type =
request_info->begin_params->request_context_type;
+ new_request->upgrade_if_insecure = request_info->upgrade_if_insecure;
+ new_request->throttling_profile_id = request_info->devtools_frame_token;
return new_request;
}
@@ -258,12 +263,11 @@ std::unique_ptr<NavigationRequestInfo> CreateNavigationRequestInfoForRedirect(
previous_request_info.common_params;
new_common_params.url = updated_resource_request.url;
new_common_params.referrer =
- Referrer(updated_resource_request.url,
+ Referrer(updated_resource_request.referrer,
Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
updated_resource_request.referrer_policy));
new_common_params.method = updated_resource_request.method;
new_common_params.post_data = updated_resource_request.request_body;
- // TODO(shimazu): Set correct base url and history url for a data URL.
mojom::BeginNavigationParamsPtr new_begin_params =
previous_request_info.begin_params.Clone();
@@ -279,8 +283,10 @@ std::unique_ptr<NavigationRequestInfo> CreateNavigationRequestInfoForRedirect(
previous_request_info.is_for_guests_only,
previous_request_info.report_raw_headers,
previous_request_info.is_prerendering,
+ previous_request_info.upgrade_if_insecure,
nullptr /* blob_url_loader_factory */,
- previous_request_info.devtools_navigation_token);
+ previous_request_info.devtools_navigation_token,
+ previous_request_info.devtools_frame_token);
}
// Called for requests that we don't have a URLLoaderFactory for.
@@ -308,7 +314,6 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
initial_interceptors,
std::unique_ptr<network::ResourceRequest> resource_request,
ResourceContext* resource_context,
- scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter,
const GURL& url,
network::mojom::URLLoaderFactoryRequest proxied_factory_request,
network::mojom::URLLoaderFactoryPtrInfo proxied_factory_info,
@@ -317,7 +322,6 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
: interceptors_(std::move(initial_interceptors)),
resource_request_(std::move(resource_request)),
resource_context_(resource_context),
- default_url_loader_factory_getter_(default_url_loader_factory_getter),
url_(url),
owner_(owner),
response_loader_binding_(this),
@@ -328,6 +332,18 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
~URLLoaderRequestController() override {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // If neither OnCompleted nor OnReceivedResponse has been invoked, the
+ // request was canceled before receiving a response, so log a cancellation.
+ // Results after receiving a non-error response are logged in the renderer,
+ // if the request is passed to one. If it's a download, or not passed to a
+ // renderer for some other reason, results will not be logged for the
+ // request. The net::OK check may not be necessary - the case where OK is
+ // received without receiving any headers looks broken, anyways.
+ if (!received_response_ && (!status_ || status_->error_code != net::OK)) {
+ RecordLoadHistograms(url_, resource_request_->resource_type,
+ status_ ? status_->error_code : net::ERR_ABORTED);
+ }
}
static uint32_t GetURLLoaderOptions(bool is_main_frame) {
@@ -352,15 +368,30 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
net::URLRequestContextGetter* url_request_context_getter,
storage::FileSystemContext* upload_file_system_context,
ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
- AppCacheNavigationHandleCore* appcache_handle_core) const {
+ AppCacheNavigationHandleCore* appcache_handle_core,
+ bool was_request_intercepted) const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
+ DCHECK(started_);
+
return base::BindOnce(
&URLLoaderRequestController::CreateNonNetworkServiceURLLoader,
weak_factory_.GetWeakPtr(),
base::Unretained(url_request_context_getter),
base::Unretained(upload_file_system_context),
std::make_unique<NavigationRequestInfo>(*request_info_),
- base::Unretained(service_worker_navigation_handle_core),
- base::Unretained(appcache_handle_core));
+ // If the request has already been intercepted, the request should not
+ // be intercepted again.
+ // S13nServiceWorker: Requests are intercepted by S13nServiceWorker
+ // before the default request handler when needed, so we never need to
+ // pass |service_worker_navigation_handle_core| here.
+ base::Unretained(
+ blink::ServiceWorkerUtils::IsServicificationEnabled() ||
+ was_request_intercepted
+ ? nullptr
+ : service_worker_navigation_handle_core),
+ base::Unretained(was_request_intercepted ? nullptr
+ : appcache_handle_core));
}
void CreateNonNetworkServiceURLLoader(
@@ -371,23 +402,25 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
AppCacheNavigationHandleCore* appcache_handle_core,
network::mojom::URLLoaderRequest url_loader,
network::mojom::URLLoaderClientPtr url_loader_client) {
- DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
+ DCHECK(started_);
default_loader_used_ = true;
if (signed_exchange_utils::IsSignedExchangeHandlingEnabled()) {
- DCHECK(!default_url_loader_factory_getter_);
+ DCHECK(!network_loader_factory_);
// It is safe to pass the callback of CreateURLLoaderThrottles with the
// unretained |this|, because the passed callback will be used by a
// SignedExchangeHandler which is indirectly owned by |this| until its
// header is verified and parsed, that's where the getter is used.
- interceptors_.push_back(std::make_unique<WebPackageRequestHandler>(
+ interceptors_.push_back(std::make_unique<SignedExchangeRequestHandler>(
url::Origin::Create(request_info->common_params.url),
request_info->common_params.url,
GetURLLoaderOptions(request_info->is_main_frame),
request_info->frame_tree_node_id,
request_info->devtools_navigation_token,
- request_info->report_raw_headers,
+ request_info->devtools_frame_token, request_info->report_raw_headers,
+ request_info->begin_params->load_flags,
base::MakeRefCounted<
SignedExchangeURLLoaderFactoryForNonNetworkService>(
resource_context_, url_request_context_getter),
@@ -415,7 +448,7 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
upload_file_system_context, *request_info,
std::move(navigation_ui_data_), std::move(url_loader_client),
std::move(url_loader), service_worker_navigation_handle_core,
- appcache_handle_core, options, &global_request_id_);
+ appcache_handle_core, options, global_request_id_);
}
// TODO(arthursonzogni): Detect when the ResourceDispatcherHost didn't
@@ -434,8 +467,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
AppCacheNavigationHandleCore* appcache_handle_core,
std::unique_ptr<NavigationRequestInfo> request_info,
std::unique_ptr<NavigationUIData> navigation_ui_data) {
- DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
DCHECK(!started_);
started_ = true;
request_info_ = std::move(request_info);
@@ -443,6 +476,11 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
web_contents_getter_ = base::BindRepeating(
&GetWebContentsFromFrameTreeNodeID, frame_tree_node_id_);
navigation_ui_data_ = std::move(navigation_ui_data);
+ // The ResourceDispatcherHostImpl can be null in unit tests.
+ ResourceDispatcherHostImpl* rph = ResourceDispatcherHostImpl::Get();
+ if (rph)
+ global_request_id_ = rph->MakeGlobalRequestID();
+
default_request_handler_factory_ = base::BindRepeating(
&URLLoaderRequestController::
CreateDefaultRequestHandlerForNonNetworkService,
@@ -453,16 +491,31 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
base::Unretained(service_worker_navigation_handle_core),
base::Unretained(appcache_handle_core));
+ // Requests to Blob scheme won't get redirected to/from other schemes
+ // or be intercepted, so we just let it go here.
+ if (request_info_->common_params.url.SchemeIsBlob() &&
+ request_info_->blob_url_loader_factory) {
+ url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
+ network::SharedURLLoaderFactory::Create(
+ std::move(request_info_->blob_url_loader_factory)),
+ CreateURLLoaderThrottles(), -1 /* routing_id */, 0 /* request_id? */,
+ network::mojom::kURLLoadOptionNone, resource_request_.get(), this,
+ kNavigationUrlLoaderTrafficAnnotation,
+ base::ThreadTaskRunnerHandle::Get());
+ return;
+ }
+
// If S13nServiceWorker is disabled, just use
// |default_request_handler_factory_| and return. The non network service
// request handling goes through ResourceDispatcherHost which has legacy
// hooks for service worker (ServiceWorkerRequestInterceptor), so no service
// worker interception is needed here.
- if (!ServiceWorkerUtils::IsServicificationEnabled() ||
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled() ||
!service_worker_navigation_handle_core) {
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
base::MakeRefCounted<SingleRequestURLLoaderFactory>(
- default_request_handler_factory_.Run()),
+ default_request_handler_factory_.Run(
+ false /* was_request_intercepted */)),
CreateURLLoaderThrottles(), -1 /* routing_id */, 0 /* request_id */,
network::mojom::kURLLoadOptionNone, resource_request_.get(),
this /* client */, kNavigationUrlLoaderTrafficAnnotation,
@@ -481,7 +534,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
if (!service_worker_interceptor) {
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
base::MakeRefCounted<SingleRequestURLLoaderFactory>(
- default_request_handler_factory_.Run()),
+ default_request_handler_factory_.Run(
+ false /* was_request_intercepted */)),
CreateURLLoaderThrottles(), -1 /* routing_id */, 0 /* request_id */,
network::mojom::kURLLoadOptionNone, resource_request_.get(),
this /* client */, kNavigationUrlLoaderTrafficAnnotation,
@@ -491,14 +545,13 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
interceptors_.push_back(std::move(service_worker_interceptor));
- // TODO(shimazu): Make sure we have a consistent global id for the
- // navigation request.
- global_request_id_ = MakeGlobalRequestID();
Restart();
}
void Start(
net::URLRequestContextGetter* url_request_context_getter,
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ network_loader_factory_info,
ServiceWorkerNavigationHandleCore* service_worker_navigation_handle_core,
AppCacheNavigationHandleCore* appcache_handle_core,
std::unique_ptr<NavigationRequestInfo> request_info,
@@ -506,8 +559,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
network::mojom::URLLoaderFactoryPtrInfo factory_for_webui,
int frame_tree_node_id,
std::unique_ptr<service_manager::Connector> connector) {
- DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
DCHECK(!started_);
global_request_id_ = MakeGlobalRequestID();
frame_tree_node_id_ = frame_tree_node_id;
@@ -516,6 +569,10 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
base::Bind(&GetWebContentsFromFrameTreeNodeID, frame_tree_node_id);
navigation_ui_data_ = std::move(navigation_ui_data);
+ DCHECK(network_loader_factory_info);
+ network_loader_factory_ = network::SharedURLLoaderFactory::Create(
+ std::move(network_loader_factory_info));
+
if (resource_request_->request_body) {
GetBodyBlobDataHandles(resource_request_->request_body.get(),
resource_context_, &blob_handles_);
@@ -527,9 +584,9 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
std::move(factory_for_webui)),
- CreateURLLoaderThrottles(), 0 /* routing_id */, 0 /* request_id? */,
- network::mojom::kURLLoadOptionNone, resource_request_.get(), this,
- kNavigationUrlLoaderTrafficAnnotation,
+ CreateURLLoaderThrottles(), 0 /* routing_id */,
+ global_request_id_.request_id, network::mojom::kURLLoadOptionNone,
+ resource_request_.get(), this, kNavigationUrlLoaderTrafficAnnotation,
base::ThreadTaskRunnerHandle::Get());
return;
}
@@ -541,9 +598,9 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
network::SharedURLLoaderFactory::Create(
std::move(request_info->blob_url_loader_factory)),
- CreateURLLoaderThrottles(), 0 /* routing_id */, 0 /* request_id? */,
- network::mojom::kURLLoadOptionNone, resource_request_.get(), this,
- kNavigationUrlLoaderTrafficAnnotation,
+ CreateURLLoaderThrottles(), 0 /* routing_id */,
+ global_request_id_.request_id, network::mojom::kURLLoadOptionNone,
+ resource_request_.get(), this, kNavigationUrlLoaderTrafficAnnotation,
base::ThreadTaskRunnerHandle::Get());
return;
}
@@ -560,24 +617,29 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
std::unique_ptr<NavigationLoaderInterceptor> appcache_interceptor =
AppCacheRequestHandler::InitializeForNavigationNetworkService(
*resource_request_, appcache_handle_core,
- default_url_loader_factory_getter_.get());
+ network_loader_factory_);
if (appcache_interceptor)
interceptors_.push_back(std::move(appcache_interceptor));
}
if (signed_exchange_utils::IsSignedExchangeHandlingEnabled()) {
+ // Signed Exchange is currently disabled when Network Service is enabled
+ // (https://crbug.com/849935), but still create
+ // SignedExchangeRequestHandler in order to show error message (and
+ // devtools warning) to users.
+
// It is safe to pass the callback of CreateURLLoaderThrottles with the
// unretained |this|, because the passed callback will be used by a
// SignedExchangeHandler which is indirectly owned by |this| until its
// header is verified and parsed, that's where the getter is used.
- interceptors_.push_back(std::make_unique<WebPackageRequestHandler>(
+ interceptors_.push_back(std::make_unique<SignedExchangeRequestHandler>(
url::Origin::Create(request_info->common_params.url),
request_info->common_params.url,
GetURLLoaderOptions(request_info->is_main_frame),
request_info->frame_tree_node_id,
request_info->devtools_navigation_token,
- request_info->report_raw_headers,
- default_url_loader_factory_getter_->GetNetworkFactory(),
+ request_info->devtools_frame_token, request_info->report_raw_headers,
+ request_info->begin_params->load_flags, network_loader_factory_,
base::BindRepeating(
&URLLoaderRequestController::CreateURLLoaderThrottles,
base::Unretained(this)),
@@ -624,7 +686,10 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
void MaybeStartLoader(
NavigationLoaderInterceptor* interceptor,
SingleRequestURLLoaderFactory::RequestHandler single_request_handler) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(IsLoaderInterceptionEnabled());
+ DCHECK(started_);
+
if (single_request_handler) {
// |interceptor| wants to handle the request with
// |single_request_handler|.
@@ -633,9 +698,9 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
base::MakeRefCounted<SingleRequestURLLoaderFactory>(
std::move(single_request_handler)),
- CreateURLLoaderThrottles(), frame_tree_node_id_, 0 /* request_id? */,
- network::mojom::kURLLoadOptionNone, resource_request_.get(), this,
- kNavigationUrlLoaderTrafficAnnotation,
+ CreateURLLoaderThrottles(), frame_tree_node_id_,
+ global_request_id_.request_id, network::mojom::kURLLoadOptionNone,
+ resource_request_.get(), this, kNavigationUrlLoaderTrafficAnnotation,
base::ThreadTaskRunnerHandle::Get());
subresource_loader_params_ =
@@ -677,7 +742,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// so let it just follow the redirect.
if (url_loader_) {
DCHECK(!redirect_info_.new_url.is_empty());
- url_loader_->FollowRedirect();
+ url_loader_->FollowRedirect(
+ std::move(url_loader_modified_request_headers_));
return;
}
@@ -693,28 +759,36 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
DCHECK(!interceptors_.empty());
DCHECK(default_request_handler_factory_);
+ // The only way to come here is to enable ServiceWorkerServicification
+ // without NetworkService. We know that the service worker's request
+ // interceptor has already intercepted and decided not to handle the
+ // request.
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
default_loader_used_ = true;
// Update |request_info_| when following a redirect.
if (url_chain_.size() > 0) {
request_info_ = CreateNavigationRequestInfoForRedirect(
*request_info_, *resource_request_);
}
+ // When |subresource_loader_params_| has its value, the request should not
+ // be intercepted by any other interceptors since it means that a request
+ // interceptor already intercepted the request and it attached its info to
+ // the request.
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
base::MakeRefCounted<SingleRequestURLLoaderFactory>(
- default_request_handler_factory_.Run()),
- CreateURLLoaderThrottles(), frame_tree_node_id_, 0 /* request_id */,
- network::mojom::kURLLoadOptionNone, resource_request_.get(),
- this /* client */, kNavigationUrlLoaderTrafficAnnotation,
+ default_request_handler_factory_.Run(
+ subresource_loader_params_.has_value()
+ /* was_request_intercepted */)),
+ CreateURLLoaderThrottles(), frame_tree_node_id_,
+ global_request_id_.request_id, network::mojom::kURLLoadOptionNone,
+ resource_request_.get(), this /* client */,
+ kNavigationUrlLoaderTrafficAnnotation,
base::ThreadTaskRunnerHandle::Get());
return;
}
- if (resource_request_->url.SchemeIs(url::kBlobScheme)) {
- factory =
- base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
- default_url_loader_factory_getter_->GetBlobFactory());
- } else if (!IsURLHandledByNetworkService(resource_request_->url) &&
- !resource_request_->url.SchemeIs(url::kDataScheme)) {
+ if (!IsURLHandledByNetworkService(resource_request_->url) &&
+ !resource_request_->url.SchemeIs(url::kDataScheme)) {
if (known_schemes_.find(resource_request_->url.scheme()) ==
known_schemes_.end()) {
bool handled = GetContentClient()->browser()->HandleExternalProtocol(
@@ -754,12 +828,11 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
!resource_request_->url.SchemeIs(url::kDataScheme)) {
DCHECK(proxied_factory_info_.is_valid());
// We don't worry about reconnection since it's a single navigation.
- default_url_loader_factory_getter_->CloneNetworkFactory(
- std::move(proxied_factory_request_));
+ network_loader_factory_->Clone(std::move(proxied_factory_request_));
factory = base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
std::move(proxied_factory_info_));
} else {
- factory = default_url_loader_factory_getter_->GetNetworkFactory();
+ factory = network_loader_factory_;
}
}
url_chain_.push_back(resource_request_->url);
@@ -767,17 +840,18 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
RESOURCE_TYPE_MAIN_FRAME);
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
factory, CreateURLLoaderThrottles(), frame_tree_node_id_,
- 0 /* request_id? */, options, resource_request_.get(), this,
+ global_request_id_.request_id, options, resource_request_.get(), this,
kNavigationUrlLoaderTrafficAnnotation,
base::ThreadTaskRunnerHandle::Get());
}
- void FollowRedirect() {
+ void FollowRedirect(
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(!redirect_info_.new_url.is_empty());
if (!IsLoaderInterceptionEnabled()) {
- url_loader_->FollowRedirect();
+ url_loader_->FollowRedirect(modified_request_headers);
return;
}
@@ -794,7 +868,8 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
bool should_clear_upload = false;
net::RedirectUtil::UpdateHttpRequest(
resource_request_->url, resource_request_->method, redirect_info_,
- &resource_request_->headers, &should_clear_upload);
+ modified_request_headers, &resource_request_->headers,
+ &should_clear_upload);
if (should_clear_upload) {
// The request body is no longer applicable.
resource_request_->request_body = nullptr;
@@ -808,6 +883,10 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
resource_request_->referrer_policy = redirect_info_.new_referrer_policy;
url_chain_.push_back(redirect_info_.new_url);
+ // Need to cache modified headers for |url_loader_| since it doesn't use
+ // |resource_request_| during redirect.
+ url_loader_modified_request_headers_ = modified_request_headers;
+
Restart();
}
@@ -817,9 +896,7 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
private:
// network::mojom::URLLoaderClient implementation:
- void OnReceiveResponse(
- const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override {
+ void OnReceiveResponse(const network::ResourceResponseHead& head) override {
received_response_ = true;
// If the default loader (network) was used to handle the URL load request
@@ -847,15 +924,14 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
bool is_stream;
std::unique_ptr<NavigationData> cloned_navigation_data;
if (IsLoaderInterceptionEnabled()) {
- bool must_download = navigation_loader_util::MustDownload(
+ bool must_download = download_utils::MustDownload(
url_, head.headers.get(), head.mime_type);
bool known_mime_type = blink::IsSupportedMimeType(head.mime_type);
#if BUILDFLAG(ENABLE_PLUGINS)
if (!response_intercepted && !must_download && !known_mime_type) {
CheckPluginAndContinueOnReceiveResponse(
- head, std::move(downloaded_file),
- std::move(url_loader_client_endpoints),
+ head, std::move(url_loader_client_endpoints),
std::vector<WebPluginInfo>());
return;
}
@@ -900,14 +976,16 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
subresource_loader_params_ = SubresourceLoaderParams();
subresource_loader_params_->controller_service_worker_info =
mojom::ControllerServiceWorkerInfo::New();
- base::WeakPtr<ServiceWorkerHandle> sw_handle =
- sw_provider_host->GetOrCreateServiceWorkerHandle(
+ subresource_loader_params_->controller_service_worker_info->mode =
+ sw_provider_host->GetControllerMode();
+ base::WeakPtr<ServiceWorkerObjectHost> sw_object_host =
+ sw_provider_host->GetOrCreateServiceWorkerObjectHost(
sw_provider_host->controller());
- if (sw_handle) {
- subresource_loader_params_->controller_service_worker_handle =
- sw_handle;
+ if (sw_object_host) {
+ subresource_loader_params_->controller_service_worker_object_host =
+ sw_object_host;
subresource_loader_params_->controller_service_worker_info
- ->object_info = sw_handle->CreateIncompleteObjectInfo();
+ ->object_info = sw_object_host->CreateIncompleteObjectInfo();
}
}
} else {
@@ -915,8 +993,7 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
}
}
- CallOnReceivedResponse(head, std::move(downloaded_file),
- std::move(url_loader_client_endpoints),
+ CallOnReceivedResponse(head, std::move(url_loader_client_endpoints),
std::move(cloned_navigation_data), is_download,
is_stream);
}
@@ -924,7 +1001,6 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
#if BUILDFLAG(ENABLE_PLUGINS)
void CheckPluginAndContinueOnReceiveResponse(
const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file,
network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
const std::vector<WebPluginInfo>& plugins) {
bool stale;
@@ -943,7 +1019,7 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// Refresh the plugins asynchronously.
PluginService::GetInstance()->GetPlugins(base::BindOnce(
&URLLoaderRequestController::CheckPluginAndContinueOnReceiveResponse,
- weak_factory_.GetWeakPtr(), head, std::move(downloaded_file),
+ weak_factory_.GetWeakPtr(), head,
std::move(url_loader_client_endpoints)));
return;
}
@@ -952,15 +1028,13 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
!has_plugin &&
(!head.headers || head.headers->response_code() / 100 == 2);
- CallOnReceivedResponse(head, std::move(downloaded_file),
- std::move(url_loader_client_endpoints), nullptr,
- is_download, false /* is_stream */);
+ CallOnReceivedResponse(head, std::move(url_loader_client_endpoints),
+ nullptr, is_download, false /* is_stream */);
}
#endif
void CallOnReceivedResponse(
const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file,
network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
std::unique_ptr<NavigationData> cloned_navigation_data,
bool is_download,
@@ -981,7 +1055,7 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
response->DeepCopy(),
std::move(url_loader_client_endpoints),
std::move(cloned_navigation_data), global_request_id_,
- is_download, is_stream, std::move(downloaded_file)));
+ is_download, is_stream));
}
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
@@ -1013,7 +1087,6 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
redirect_info, response->DeepCopy()));
}
- void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {}
void OnUploadProgress(int64_t current_position,
int64_t total_size,
OnUploadProgressCallback callback) override {}
@@ -1117,10 +1190,14 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
ResourceContext* resource_context_;
base::Callback<WebContents*()> web_contents_getter_;
std::unique_ptr<NavigationUIData> navigation_ui_data_;
- scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter_;
+ scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory_;
std::unique_ptr<ThrottlingURLLoader> url_loader_;
+ // Caches the modified request headers provided by clients during redirect,
+ // will be consumed by next |url_loader_->FollowRedirect()|.
+ base::Optional<net::HttpRequestHeaders> url_loader_modified_request_headers_;
+
BlobHandles blob_handles_;
std::vector<GURL> url_chain_;
@@ -1162,7 +1239,11 @@ class NavigationURLLoaderImpl::URLLoaderRequestController
// captures all of parameters to create a
// SingleRequestURLLoaderFactory::RequestHandler. Used only when
// NetworkService is disabled but IsLoaderInterceptionEnabled() is true.
- base::RepeatingCallback<SingleRequestURLLoaderFactory::RequestHandler()>
+ // Set |was_request_intercepted| to true if the request was intercepted by an
+ // interceptor and the request is falling back to the network. In that case,
+ // any interceptors won't intercept the request.
+ base::RepeatingCallback<SingleRequestURLLoaderFactory::RequestHandler(
+ bool /* was_request_intercepted */)>
default_request_handler_factory_;
// The completion status if it has been received. This is needed to handle
@@ -1223,6 +1304,7 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
std::unique_ptr<network::ResourceRequest> new_request = CreateResourceRequest(
request_info.get(), frame_tree_node_id, allow_download_);
+ new_request->transition_type = request_info->common_params.transition;
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
DCHECK(!request_controller_);
@@ -1230,7 +1312,6 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
/* initial_interceptors = */
std::vector<std::unique_ptr<NavigationLoaderInterceptor>>(),
std::move(new_request), resource_context,
- /* default_url_factory_getter = */ nullptr,
request_info->common_params.url,
/* proxied_url_loader_factory_request */ nullptr,
/* proxied_url_loader_factory_info */ nullptr, std::set<std::string>(),
@@ -1255,7 +1336,7 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
network::mojom::URLLoaderFactoryPtrInfo factory_for_webui;
const auto& schemes = URLDataManagerBackend::GetWebUISchemes();
std::string scheme = new_request->url.scheme();
- if (std::find(schemes.begin(), schemes.end(), scheme) != schemes.end()) {
+ if (base::ContainsValue(schemes, scheme)) {
factory_for_webui = CreateWebUIURLLoaderBinding(
frame_tree_node->current_frame_host(), scheme)
.PassInterface();
@@ -1278,8 +1359,8 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
network::mojom::URLLoaderFactoryPtrInfo factory_info;
auto factory_request = mojo::MakeRequest(&factory_info);
bool use_proxy = GetContentClient()->browser()->WillCreateURLLoaderFactory(
- frame_tree_node->current_frame_host(), true /* is_navigation */,
- &factory_request);
+ partition->browser_context(), frame_tree_node->current_frame_host(),
+ true /* is_navigation */, &factory_request);
if (RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory(
frame_tree_node->current_frame_host(), true, false,
&factory_request)) {
@@ -1311,15 +1392,16 @@ NavigationURLLoaderImpl::NavigationURLLoaderImpl(
DCHECK(!request_controller_);
request_controller_ = std::make_unique<URLLoaderRequestController>(
std::move(initial_interceptors), std::move(new_request), resource_context,
- partition->url_loader_factory_getter(), request_info->common_params.url,
- std::move(proxied_factory_request), std::move(proxied_factory_info),
- std::move(known_schemes), weak_factory_.GetWeakPtr());
+ request_info->common_params.url, std::move(proxied_factory_request),
+ std::move(proxied_factory_info), std::move(known_schemes),
+ weak_factory_.GetWeakPtr());
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
&URLLoaderRequestController::Start,
base::Unretained(request_controller_.get()),
base::RetainedRef(storage_partition->GetURLRequestContext()),
+ partition->url_loader_factory_getter()->GetNetworkFactoryInfo(),
service_worker_navigation_handle_core, appcache_handle_core,
std::move(request_info), std::move(navigation_ui_data),
std::move(factory_for_webui), frame_tree_node_id,
@@ -1331,11 +1413,15 @@ NavigationURLLoaderImpl::~NavigationURLLoaderImpl() {
request_controller_.release());
}
-void NavigationURLLoaderImpl::FollowRedirect() {
+void NavigationURLLoaderImpl::FollowRedirect(
+ const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&URLLoaderRequestController::FollowRedirect,
- base::Unretained(request_controller_.get())));
+ base::Unretained(request_controller_.get()),
+ modified_request_headers));
}
void NavigationURLLoaderImpl::ProceedWithResponse() {}
@@ -1346,8 +1432,7 @@ void NavigationURLLoaderImpl::OnReceiveResponse(
std::unique_ptr<NavigationData> navigation_data,
const GlobalRequestID& global_request_id,
bool is_download,
- bool is_stream,
- network::mojom::DownloadedTempFilePtr downloaded_file) {
+ bool is_stream) {
TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this,
"&NavigationURLLoaderImpl", this, "success", true);
@@ -1403,9 +1488,10 @@ void NavigationURLLoaderImpl::BindNonNetworkURLLoaderFactoryRequest(
}
FrameTreeNode* frame_tree_node =
FrameTreeNode::GloballyFindByID(frame_tree_node_id);
+ auto* frame = frame_tree_node->current_frame_host();
GetContentClient()->browser()->WillCreateURLLoaderFactory(
- frame_tree_node->current_frame_host(), true /* is_navigation */,
- &factory);
+ frame->GetSiteInstance()->GetBrowserContext(), frame,
+ true /* is_navigation */, &factory);
it->second->Clone(std::move(factory));
}
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl.h b/chromium/content/browser/loader/navigation_url_loader_impl.h
index 67c1d5bb8f7..ac5e384a04d 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl.h
+++ b/chromium/content/browser/loader/navigation_url_loader_impl.h
@@ -44,7 +44,10 @@ class CONTENT_EXPORT NavigationURLLoaderImpl : public NavigationURLLoader {
~NavigationURLLoaderImpl() override;
// NavigationURLLoader implementation:
- void FollowRedirect() override;
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) override;
void ProceedWithResponse() override;
void OnReceiveResponse(
@@ -53,8 +56,7 @@ class CONTENT_EXPORT NavigationURLLoaderImpl : public NavigationURLLoader {
std::unique_ptr<NavigationData> navigation_data,
const GlobalRequestID& global_request_id,
bool is_download,
- bool is_stream,
- network::mojom::DownloadedTempFilePtr downloaded_file);
+ bool is_stream);
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
scoped_refptr<network::ResourceResponse> response);
void OnComplete(const network::URLLoaderCompletionStatus& status);
diff --git a/chromium/content/browser/loader/navigation_url_loader_impl_unittest.cc b/chromium/content/browser/loader/navigation_url_loader_impl_unittest.cc
index 4cafe900bb2..538274d42a9 100644
--- a/chromium/content/browser/loader/navigation_url_loader_impl_unittest.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_impl_unittest.cc
@@ -104,7 +104,7 @@ class TestNavigationLoaderInterceptor : public NavigationLoaderInterceptor {
}
private:
- void DeleteURLLoader(network::URLLoader* url_loader) {
+ void DeleteURLLoader(network::mojom::URLLoader* url_loader) {
DCHECK_EQ(url_loader_.get(), url_loader);
url_loader_.reset();
}
@@ -154,7 +154,8 @@ class NavigationURLLoaderImplTest : public testing::Test {
const std::string& method,
NavigationURLLoaderDelegate* delegate,
bool allow_download = false,
- bool is_main_frame = true) {
+ bool is_main_frame = true,
+ bool upgrade_if_insecure = false) {
mojom::BeginNavigationParamsPtr begin_params =
mojom::BeginNavigationParams::New(
headers, net::LOAD_NORMAL, false /* skip_service_worker */,
@@ -176,8 +177,10 @@ class NavigationURLLoaderImplTest : 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 */, false /* is_prerenering */,
+ upgrade_if_insecure /* upgrade_if_insecure */,
nullptr /* blob_url_loader_factory */,
- base::UnguessableToken::Create() /* devtools_navigation_token */));
+ base::UnguessableToken::Create() /* devtools_navigation_token */,
+ base::UnguessableToken::Create() /* devtools_frame_token */));
std::vector<std::unique_ptr<NavigationLoaderInterceptor>> interceptors;
most_recent_resource_request_ = base::nullopt;
interceptors.push_back(std::make_unique<TestNavigationLoaderInterceptor>(
@@ -210,7 +213,7 @@ class NavigationURLLoaderImplTest : public testing::Test {
redirect_url.GetOrigin().spec().c_str()),
request_method, &delegate);
delegate.WaitForRequestRedirected();
- loader->FollowRedirect();
+ loader->FollowRedirect(base::nullopt, base::nullopt);
EXPECT_EQ(expected_redirect_method, delegate.redirect_info().new_method);
@@ -251,12 +254,32 @@ class NavigationURLLoaderImplTest : public testing::Test {
url.GetOrigin().spec().c_str()),
"GET", &delegate, false /* allow_download */, is_main_frame);
delegate.WaitForRequestRedirected();
- loader->FollowRedirect();
+ loader->FollowRedirect(base::nullopt, base::nullopt);
delegate.WaitForResponseStarted();
return most_recent_resource_request_.value().priority;
}
+ net::RedirectInfo NavigateAndReturnRedirectInfo(const GURL& url,
+ bool upgrade_if_insecure,
+ bool expect_request_fail) {
+ TestNavigationURLLoaderDelegate delegate;
+ std::unique_ptr<NavigationURLLoader> loader = CreateTestLoader(
+ url,
+ base::StringPrintf("%s: %s", net::HttpRequestHeaders::kOrigin,
+ url.GetOrigin().spec().c_str()),
+ "GET", &delegate, false /* allow_download */, true /*is_main_frame*/,
+ upgrade_if_insecure);
+ delegate.WaitForRequestRedirected();
+ loader->FollowRedirect(base::nullopt, base::nullopt);
+ if (expect_request_fail) {
+ delegate.WaitForRequestFailed();
+ } else {
+ delegate.WaitForResponseStarted();
+ }
+ return delegate.redirect_info();
+ }
+
protected:
base::test::ScopedFeatureList feature_list_;
TestBrowserThreadBundle thread_bundle_;
@@ -345,4 +368,68 @@ TEST_F(NavigationURLLoaderImplTest, Redirect308Tests) {
true);
}
+TEST_F(NavigationURLLoaderImplTest, RedirectModifiedHeaders) {
+ ASSERT_TRUE(http_test_server_.Start());
+
+ const GURL redirect_url = http_test_server_.GetURL("/redirect301-to-echo");
+
+ TestNavigationURLLoaderDelegate delegate;
+ std::unique_ptr<NavigationURLLoader> loader = CreateTestLoader(
+ redirect_url, "Header1: Value1\r\nHeader2: Value2", "GET", &delegate);
+ delegate.WaitForRequestRedirected();
+
+ ASSERT_TRUE(most_recent_resource_request_);
+
+ // Initial request should only have initial headers.
+ std::string header1, header2;
+ EXPECT_TRUE(
+ most_recent_resource_request_->headers.GetHeader("Header1", &header1));
+ EXPECT_EQ("Value1", header1);
+ EXPECT_TRUE(
+ most_recent_resource_request_->headers.GetHeader("Header2", &header2));
+ EXPECT_EQ("Value2", header2);
+ EXPECT_FALSE(most_recent_resource_request_->headers.HasHeader("Header3"));
+
+ // Overwrite Header2 and add Header3.
+ net::HttpRequestHeaders redirect_headers;
+ redirect_headers.SetHeader("Header2", "");
+ redirect_headers.SetHeader("Header3", "Value3");
+ loader->FollowRedirect(base::nullopt, redirect_headers);
+ delegate.WaitForResponseStarted();
+
+ // Redirected request should also have modified headers.
+ EXPECT_TRUE(
+ most_recent_resource_request_->headers.GetHeader("Header1", &header1));
+ EXPECT_EQ("Value1", header1);
+ EXPECT_TRUE(
+ most_recent_resource_request_->headers.GetHeader("Header2", &header2));
+ EXPECT_EQ("", header2);
+ std::string header3;
+ EXPECT_TRUE(
+ most_recent_resource_request_->headers.GetHeader("Header3", &header3));
+ EXPECT_EQ("Value3", header3);
+}
+
+// Tests that the Upgrade If Insecure flag is obeyed.
+TEST_F(NavigationURLLoaderImplTest, UpgradeIfInsecureTest) {
+ ASSERT_TRUE(http_test_server_.Start());
+ const GURL url = http_test_server_.GetURL("/redirect301-to-http");
+ GURL expected_url = GURL("http://test.test/test");
+ // We expect the request to fail since there is no server listening at
+ // test.test, but for the purpose of this test we only need to validate the
+ // redirect URL was not changed.
+ net::RedirectInfo redirect_info = NavigateAndReturnRedirectInfo(
+ url, false /* upgrade_if_insecure */, true /* expect_request_fail */);
+ EXPECT_FALSE(redirect_info.insecure_scheme_was_upgraded);
+ EXPECT_EQ(expected_url, redirect_info.new_url);
+ GURL::Replacements replacements;
+ replacements.SetSchemeStr("https");
+ expected_url = expected_url.ReplaceComponents(replacements);
+ redirect_info = NavigateAndReturnRedirectInfo(
+ url, true /* upgrade_if_insecure */, true /* expect_request_fail */);
+ // Same as above, but validating the URL is upgraded to https.
+ EXPECT_TRUE(redirect_info.insecure_scheme_was_upgraded);
+ EXPECT_EQ(expected_url, redirect_info.new_url);
+}
+
} // namespace content
diff --git a/chromium/content/browser/loader/navigation_url_loader_unittest.cc b/chromium/content/browser/loader/navigation_url_loader_unittest.cc
index ea806d87222..75f70ba50a4 100644
--- a/chromium/content/browser/loader/navigation_url_loader_unittest.cc
+++ b/chromium/content/browser/loader/navigation_url_loader_unittest.cc
@@ -95,7 +95,9 @@ class NavigationURLLoaderTest : public testing::Test {
std::unique_ptr<NavigationRequestInfo> request_info(
new NavigationRequestInfo(common_params, std::move(begin_params), url,
true, false, false, -1, false, false, false,
- nullptr, base::UnguessableToken::Create()));
+ false, nullptr,
+ base::UnguessableToken::Create(),
+ base::UnguessableToken::Create()));
return NavigationURLLoader::Create(
browser_context_->GetResourceContext(),
BrowserContext::GetDefaultStoragePartition(browser_context_.get()),
@@ -226,7 +228,7 @@ TEST_F(NavigationURLLoaderTest, CancelResponseRace) {
// In the same event loop iteration, follow the redirect (allowing the
// response to go through) and destroy the loader.
- loader->FollowRedirect();
+ loader->FollowRedirect(base::nullopt, base::nullopt);
loader.reset();
// Verify the URLRequestTestJob no longer has anything paused and that no
diff --git a/chromium/content/browser/loader/null_resource_controller.cc b/chromium/content/browser/loader/null_resource_controller.cc
index da79bb5843e..8ac719d3a6a 100644
--- a/chromium/content/browser/loader/null_resource_controller.cc
+++ b/chromium/content/browser/loader/null_resource_controller.cc
@@ -5,6 +5,7 @@
#include "content/browser/loader/null_resource_controller.h"
#include "base/logging.h"
+#include "net/http/http_request_headers.h"
namespace content {
@@ -27,4 +28,12 @@ void NullResourceController::Resume() {
*was_resumed_ = true;
}
+void NullResourceController::ResumeForRedirect(
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
+ DCHECK(!modified_request_headers.has_value()) << "Redirect with modified "
+ "headers was not supported "
+ "yet. crbug.com/845683";
+ Resume();
+}
+
} // namespace content
diff --git a/chromium/content/browser/loader/null_resource_controller.h b/chromium/content/browser/loader/null_resource_controller.h
index 8dd10f7102a..66c9e039467 100644
--- a/chromium/content/browser/loader/null_resource_controller.h
+++ b/chromium/content/browser/loader/null_resource_controller.h
@@ -23,6 +23,8 @@ class NullResourceController : public ResourceController {
void Cancel() override;
void CancelWithError(int error_code) override;
void Resume() override;
+ void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) override;
private:
bool* was_resumed_;
diff --git a/chromium/content/browser/loader/prefetch_browsertest.cc b/chromium/content/browser/loader/prefetch_browsertest.cc
index da0ea6f9f64..fb0726ef37c 100644
--- a/chromium/content/browser/loader/prefetch_browsertest.cc
+++ b/chromium/content/browser/loader/prefetch_browsertest.cc
@@ -14,7 +14,7 @@
#include "content/browser/loader/prefetch_url_loader_service.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/web_package/mock_signed_exchange_handler.h"
-#include "content/browser/web_package/web_package_loader.h"
+#include "content/browser/web_package/signed_exchange_loader.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
@@ -40,10 +40,10 @@ struct PrefetchBrowserTestParam {
struct ScopedSignedExchangeHandlerFactory {
explicit ScopedSignedExchangeHandlerFactory(
SignedExchangeHandlerFactory* factory) {
- WebPackageLoader::SetSignedExchangeHandlerFactoryForTest(factory);
+ SignedExchangeLoader::SetSignedExchangeHandlerFactoryForTest(factory);
}
~ScopedSignedExchangeHandlerFactory() {
- WebPackageLoader::SetSignedExchangeHandlerFactoryForTest(nullptr);
+ SignedExchangeLoader::SetSignedExchangeHandlerFactoryForTest(nullptr);
}
};
@@ -333,31 +333,31 @@ IN_PROC_BROWSER_TEST_P(PrefetchBrowserTest, WebPackageWithPreload) {
int target_fetch_count = 0;
int preload_fetch_count = 0;
const char* prefetch_url = "/prefetch.html";
- const char* target_htxg = "/target.htxg";
+ const char* target_sxg = "/target.sxg";
const char* target_url = "/target.html";
- const char* preload_url_in_htxg = "/preload.js";
+ const char* preload_url_in_sxg = "/preload.js";
RegisterResponse(
prefetch_url,
ResponseEntry(base::StringPrintf(
- "<body><link rel='prefetch' href='%s'></body>", target_htxg)));
+ "<body><link rel='prefetch' href='%s'></body>", target_sxg)));
RegisterResponse(
- target_htxg,
+ target_sxg,
// We mock the SignedExchangeHandler, so just return a HTML content
// as "application/signed-exchange;v=b0".
- ResponseEntry("<head><title>Prefetch Target (HTXG)</title></head>",
+ ResponseEntry("<head><title>Prefetch Target (SXG)</title></head>",
"application/signed-exchange;v=b0"));
- RegisterResponse(preload_url_in_htxg,
+ RegisterResponse(preload_url_in_sxg,
ResponseEntry("function foo() {}", "text/javascript"));
base::RunLoop preload_waiter;
base::RunLoop prefetch_waiter;
embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
&PrefetchBrowserTest::WatchURLAndRunClosure, base::Unretained(this),
- target_htxg, &target_fetch_count, prefetch_waiter.QuitClosure()));
+ target_sxg, &target_fetch_count, prefetch_waiter.QuitClosure()));
embedded_test_server()->RegisterRequestMonitor(base::BindRepeating(
&PrefetchBrowserTest::WatchURLAndRunClosure, base::Unretained(this),
- preload_url_in_htxg, &preload_fetch_count, preload_waiter.QuitClosure()));
+ preload_url_in_sxg, &preload_fetch_count, preload_waiter.QuitClosure()));
embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
&PrefetchBrowserTest::ServeResponses, base::Unretained(this)));
ASSERT_TRUE(embedded_test_server()->Start());
@@ -367,7 +367,7 @@ IN_PROC_BROWSER_TEST_P(PrefetchBrowserTest, WebPackageWithPreload) {
net::OK, GURL(target_url), "text/html",
{base::StringPrintf(
"Link: <%s>;rel=\"preload\";as=\"script\"",
- embedded_test_server()->GetURL(preload_url_in_htxg).spec().c_str())});
+ embedded_test_server()->GetURL(preload_url_in_sxg).spec().c_str())});
ScopedSignedExchangeHandlerFactory scoped_factory(&factory);
// Loading a page that prefetches the target URL would increment both
@@ -377,11 +377,15 @@ IN_PROC_BROWSER_TEST_P(PrefetchBrowserTest, WebPackageWithPreload) {
EXPECT_EQ(1, target_fetch_count);
EXPECT_TRUE(CheckPrefetchURLLoaderCountIfSupported(1));
- // Test after this point requires SignedHTTPExchange support.
- if (!base::FeatureList::IsEnabled(features::kSignedHTTPExchange))
+ // Test after this point requires SignedHTTPExchange support, which is now
+ // disabled when Network Service is enabled.
+ // TODO(https://crbug.com/849935): Remove the second condition once we
+ // re-enable Signed Exchange with Network Service.
+ if (!base::FeatureList::IsEnabled(features::kSignedHTTPExchange) ||
+ base::FeatureList::IsEnabled(network::features::kNetworkService))
return;
- // If the header in the .htxg file is correctly extracted, we should
+ // If the header in the .sxg file is correctly extracted, we should
// be able to also see the preload.
preload_waiter.Run();
EXPECT_EQ(1, preload_fetch_count);
diff --git a/chromium/content/browser/loader/prefetch_url_loader.cc b/chromium/content/browser/loader/prefetch_url_loader.cc
index c0d59319dd0..bbfd85fcc3c 100644
--- a/chromium/content/browser/loader/prefetch_url_loader.cc
+++ b/chromium/content/browser/loader/prefetch_url_loader.cc
@@ -5,8 +5,8 @@
#include "content/browser/loader/prefetch_url_loader.h"
#include "base/feature_list.h"
+#include "content/browser/web_package/signed_exchange_prefetch_handler.h"
#include "content/browser/web_package/signed_exchange_utils.h"
-#include "content/browser/web_package/web_package_prefetch_handler.h"
#include "content/public/common/content_features.h"
#include "net/url_request/url_request_context_getter.h"
#include "services/network/public/cpp/features.h"
@@ -29,6 +29,8 @@ PrefetchURLLoader::PrefetchURLLoader(
: frame_tree_node_id_getter_(frame_tree_node_id_getter),
url_(resource_request.url),
report_raw_headers_(resource_request.report_raw_headers),
+ load_flags_(resource_request.load_flags),
+ throttling_profile_id_(resource_request.throttling_profile_id),
network_loader_factory_(std::move(network_loader_factory)),
client_binding_(this),
forwarding_client_(std::move(client)),
@@ -52,18 +54,20 @@ PrefetchURLLoader::PrefetchURLLoader(
PrefetchURLLoader::~PrefetchURLLoader() = default;
void PrefetchURLLoader::FollowRedirect(
+ const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
DCHECK(!modified_request_headers.has_value()) << "Redirect with modified "
"headers was not supported "
"yet. crbug.com/845683";
- if (web_package_prefetch_handler_) {
+ if (signed_exchange_prefetch_handler_) {
// Rebind |client_binding_| and |loader_|.
- client_binding_.Bind(web_package_prefetch_handler_->FollowRedirect(
+ client_binding_.Bind(signed_exchange_prefetch_handler_->FollowRedirect(
mojo::MakeRequest(&loader_)));
return;
}
- loader_->FollowRedirect(base::nullopt);
+ loader_->FollowRedirect(base::nullopt, base::nullopt);
}
void PrefetchURLLoader::ProceedWithResponse() {
@@ -84,21 +88,22 @@ void PrefetchURLLoader::ResumeReadingBodyFromNet() {
}
void PrefetchURLLoader::OnReceiveResponse(
- const network::ResourceResponseHead& response,
- network::mojom::DownloadedTempFilePtr downloaded_file) {
+ const network::ResourceResponseHead& response) {
if (signed_exchange_utils::ShouldHandleAsSignedHTTPExchange(url_, response)) {
- DCHECK(!web_package_prefetch_handler_);
+ DCHECK(!signed_exchange_prefetch_handler_);
// Note that after this point this doesn't directly get upcalls from the
// network. (Until |this| calls the handler's FollowRedirect.)
- web_package_prefetch_handler_ = std::make_unique<WebPackagePrefetchHandler>(
- frame_tree_node_id_getter_, report_raw_headers_, response,
- std::move(loader_), client_binding_.Unbind(), network_loader_factory_,
- request_initiator_, url_, url_loader_throttles_getter_,
- resource_context_, request_context_getter_, this);
+ signed_exchange_prefetch_handler_ =
+ std::make_unique<SignedExchangePrefetchHandler>(
+ frame_tree_node_id_getter_, report_raw_headers_, load_flags_,
+ throttling_profile_id_, response, std::move(loader_),
+ client_binding_.Unbind(), network_loader_factory_,
+ request_initiator_, url_, url_loader_throttles_getter_,
+ resource_context_, request_context_getter_, this);
return;
}
- forwarding_client_->OnReceiveResponse(response, std::move(downloaded_file));
+ forwarding_client_->OnReceiveResponse(response);
}
void PrefetchURLLoader::OnReceiveRedirect(
@@ -107,11 +112,6 @@ void PrefetchURLLoader::OnReceiveRedirect(
forwarding_client_->OnReceiveRedirect(redirect_info, head);
}
-void PrefetchURLLoader::OnDataDownloaded(int64_t data_length,
- int64_t encoded_length) {
- forwarding_client_->OnDataDownloaded(data_length, encoded_length);
-}
-
void PrefetchURLLoader::OnUploadProgress(int64_t current_position,
int64_t total_size,
base::OnceCallback<void()> callback) {
diff --git a/chromium/content/browser/loader/prefetch_url_loader.h b/chromium/content/browser/loader/prefetch_url_loader.h
index 3a63bb0c4cc..ef4ff33677d 100644
--- a/chromium/content/browser/loader/prefetch_url_loader.h
+++ b/chromium/content/browser/loader/prefetch_url_loader.h
@@ -9,6 +9,8 @@
#include "base/callback.h"
#include "base/macros.h"
+#include "base/optional.h"
+#include "base/unguessable_token.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/data_pipe_drainer.h"
@@ -28,7 +30,7 @@ namespace content {
class ResourceContext;
class URLLoaderThrottle;
-class WebPackagePrefetchHandler;
+class SignedExchangePrefetchHandler;
// PrefetchURLLoader which basically just keeps draining the data.
class CONTENT_EXPORT PrefetchURLLoader : public network::mojom::URLLoader,
@@ -60,7 +62,9 @@ class CONTENT_EXPORT PrefetchURLLoader : public network::mojom::URLLoader,
private:
// network::mojom::URLLoader overrides:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
@@ -69,12 +73,9 @@ class CONTENT_EXPORT PrefetchURLLoader : public network::mojom::URLLoader,
void ResumeReadingBodyFromNet() override;
// network::mojom::URLLoaderClient overrides:
- void OnReceiveResponse(
- const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override;
+ void OnReceiveResponse(const network::ResourceResponseHead& head) override;
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& head) override;
- void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override;
void OnUploadProgress(int64_t current_position,
int64_t total_size,
base::OnceCallback<void()> callback) override;
@@ -94,6 +95,8 @@ class CONTENT_EXPORT PrefetchURLLoader : public network::mojom::URLLoader,
const base::RepeatingCallback<int(void)> frame_tree_node_id_getter_;
const GURL url_;
const bool report_raw_headers_;
+ const int load_flags_;
+ const base::Optional<base::UnguessableToken> throttling_profile_id_;
scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory_;
@@ -114,7 +117,8 @@ class CONTENT_EXPORT PrefetchURLLoader : public network::mojom::URLLoader,
std::unique_ptr<mojo::DataPipeDrainer> pipe_drainer_;
- std::unique_ptr<WebPackagePrefetchHandler> web_package_prefetch_handler_;
+ std::unique_ptr<SignedExchangePrefetchHandler>
+ signed_exchange_prefetch_handler_;
DISALLOW_COPY_AND_ASSIGN(PrefetchURLLoader);
};
diff --git a/chromium/content/browser/loader/prefetch_url_loader_service.cc b/chromium/content/browser/loader/prefetch_url_loader_service.cc
index a8c1638bf9e..b7baa69c5cf 100644
--- a/chromium/content/browser/loader/prefetch_url_loader_service.cc
+++ b/chromium/content/browser/loader/prefetch_url_loader_service.cc
@@ -20,9 +20,22 @@
namespace content {
-PrefetchURLLoaderService::PrefetchURLLoaderService(
- scoped_refptr<URLLoaderFactoryGetter> factory_getter)
- : loader_factory_getter_(std::move(factory_getter)) {}
+struct PrefetchURLLoaderService::BindContext {
+ BindContext(int frame_tree_node_id,
+ scoped_refptr<URLLoaderFactoryBundle> factory)
+ : frame_tree_node_id(frame_tree_node_id), factory(factory) {}
+
+ explicit BindContext(const std::unique_ptr<BindContext>& other)
+ : frame_tree_node_id(other->frame_tree_node_id),
+ factory(other->factory) {}
+
+ ~BindContext() = default;
+
+ const int frame_tree_node_id;
+ scoped_refptr<URLLoaderFactoryBundle> factory;
+};
+
+PrefetchURLLoaderService::PrefetchURLLoaderService() = default;
void PrefetchURLLoaderService::InitializeResourceContext(
ResourceContext* resource_context,
@@ -34,17 +47,16 @@ void PrefetchURLLoaderService::InitializeResourceContext(
request_context_getter_ = request_context_getter;
}
-void PrefetchURLLoaderService::ConnectToService(
+void PrefetchURLLoaderService::GetFactory(
+ network::mojom::URLLoaderFactoryRequest request,
int frame_tree_node_id,
- blink::mojom::PrefetchURLLoaderServiceRequest request) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&PrefetchURLLoaderService::ConnectToService, this,
- frame_tree_node_id, std::move(request)));
- return;
- }
- service_bindings_.AddBinding(this, std::move(request), frame_tree_node_id);
+ std::unique_ptr<URLLoaderFactoryBundleInfo> factories) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ auto factory_bundle =
+ base::MakeRefCounted<URLLoaderFactoryBundle>(std::move(factories));
+ loader_factory_bindings_.AddBinding(
+ this, std::move(request),
+ std::make_unique<BindContext>(frame_tree_node_id, factory_bundle));
}
void PrefetchURLLoaderService::CreateLoaderAndStart(
@@ -82,13 +94,6 @@ void PrefetchURLLoaderService::CreateLoaderAndStart(
PrefetchURLLoaderService::~PrefetchURLLoaderService() = default;
-void PrefetchURLLoaderService::GetFactory(
- network::mojom::URLLoaderFactoryRequest request) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- loader_factory_bindings_.AddBinding(this, std::move(request),
- service_bindings_.dispatch_context());
-}
-
void PrefetchURLLoaderService::CreateLoaderAndStart(
network::mojom::URLLoaderRequest request,
int32_t routing_id,
@@ -99,11 +104,11 @@ void PrefetchURLLoaderService::CreateLoaderAndStart(
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
- int frame_tree_node_id = loader_factory_bindings_.dispatch_context();
+ const auto& dispatch_context = *loader_factory_bindings_.dispatch_context();
+ int frame_tree_node_id = dispatch_context.frame_tree_node_id;
CreateLoaderAndStart(
std::move(request), routing_id, request_id, options, resource_request,
- std::move(client), traffic_annotation,
- loader_factory_getter_->GetNetworkFactory(),
+ std::move(client), traffic_annotation, dispatch_context.factory,
base::BindRepeating([](int id) { return id; }, frame_tree_node_id));
}
@@ -111,7 +116,9 @@ void PrefetchURLLoaderService::Clone(
network::mojom::URLLoaderFactoryRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
loader_factory_bindings_.AddBinding(
- this, std::move(request), loader_factory_bindings_.dispatch_context());
+ this, std::move(request),
+ std::make_unique<BindContext>(
+ loader_factory_bindings_.dispatch_context()));
}
std::vector<std::unique_ptr<content::URLLoaderThrottle>>
diff --git a/chromium/content/browser/loader/prefetch_url_loader_service.h b/chromium/content/browser/loader/prefetch_url_loader_service.h
index 6573ee69d52..69c241394f2 100644
--- a/chromium/content/browser/loader/prefetch_url_loader_service.h
+++ b/chromium/content/browser/loader/prefetch_url_loader_service.h
@@ -9,10 +9,10 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
+#include "content/common/url_loader_factory_bundle.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/strong_binding_set.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
-#include "third_party/blink/public/mojom/loader/prefetch_url_loader_service.mojom.h"
namespace net {
class URLRequestContextGetter;
@@ -20,6 +20,7 @@ class URLRequestContextGetter;
namespace network {
class SharedURLLoaderFactory;
+class URLLoaderFactoryBundleInfo;
}
namespace content {
@@ -31,13 +32,9 @@ class URLLoaderThrottle;
class CONTENT_EXPORT PrefetchURLLoaderService final
: public base::RefCountedThreadSafe<PrefetchURLLoaderService,
BrowserThread::DeleteOnIOThread>,
- public network::mojom::URLLoaderFactory,
- public blink::mojom::PrefetchURLLoaderService {
+ public network::mojom::URLLoaderFactory {
public:
- // |factory_getter| could be null in non-NetworkService case.
- // Created on the UI thread.
- PrefetchURLLoaderService(
- scoped_refptr<URLLoaderFactoryGetter> network_loader_factory);
+ PrefetchURLLoaderService();
// Must be called on the IO thread. The given |resource_context| will
// be valid as far as request_context_getter returns non-null context.
@@ -45,8 +42,9 @@ class CONTENT_EXPORT PrefetchURLLoaderService final
ResourceContext* resource_context,
scoped_refptr<net::URLRequestContextGetter> request_context_getter);
- void ConnectToService(int frame_tree_node_id,
- blink::mojom::PrefetchURLLoaderServiceRequest request);
+ void GetFactory(network::mojom::URLLoaderFactoryRequest request,
+ int frame_tree_node_id,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> factory_info);
// Used only when NetworkService is not enabled (or indirectly via the
// other CreateLoaderAndStart when NetworkService is enabled).
@@ -75,10 +73,9 @@ class CONTENT_EXPORT PrefetchURLLoaderService final
private:
friend class base::DeleteHelper<content::PrefetchURLLoaderService>;
friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
- ~PrefetchURLLoaderService() override;
+ struct BindContext;
- // blink::mojom::PrefetchURLLoaderService:
- void GetFactory(network::mojom::URLLoaderFactoryRequest request) override;
+ ~PrefetchURLLoaderService() override;
// network::mojom::URLLoaderFactory:
void CreateLoaderAndStart(network::mojom::URLLoaderRequest request,
@@ -97,16 +94,12 @@ class CONTENT_EXPORT PrefetchURLLoaderService final
const network::ResourceRequest& request,
base::RepeatingCallback<int(void)> frame_tree_node_id_getter);
- mojo::BindingSet<blink::mojom::PrefetchURLLoaderService,
- int /* frame_tree_node_id */>
- service_bindings_;
-
scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter_;
ResourceContext* resource_context_ = nullptr;
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
mojo::BindingSet<network::mojom::URLLoaderFactory,
- int /* frame_tree_node_id */>
+ std::unique_ptr<BindContext>>
loader_factory_bindings_;
base::RepeatingClosure prefetch_load_callback_for_testing_;
diff --git a/chromium/content/browser/loader/redirect_to_file_resource_handler.cc b/chromium/content/browser/loader/redirect_to_file_resource_handler.cc
deleted file mode 100644
index a6ce3d0b48f..00000000000
--- a/chromium/content/browser/loader/redirect_to_file_resource_handler.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/browser/loader/redirect_to_file_resource_handler.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/threading/thread_restrictions.h"
-#include "content/browser/loader/resource_controller.h"
-#include "content/browser/loader/resource_request_info_impl.h"
-#include "content/browser/loader/temporary_file_stream.h"
-#include "net/base/file_stream.h"
-#include "net/base/io_buffer.h"
-#include "net/base/mime_sniffer.h"
-#include "net/base/net_errors.h"
-#include "services/network/public/cpp/resource_response.h"
-#include "storage/browser/blob/shareable_file_reference.h"
-
-using storage::ShareableFileReference;
-
-namespace {
-
-// This class is similar to identically named classes in AsyncResourceHandler
-// and MimeTypeResourceHandler, but not quite.
-// TODO(ncbray): generalize and unify these cases?
-// In general, it's a bad idea to point to a subbuffer (particularly with
-// GrowableIOBuffer) because the backing IOBuffer may realloc its data. In this
-// particular case we know RedirectToFileResourceHandler will not realloc its
-// buffer while a write is occurring, so we should be safe. This property is
-// 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 DependentIOBufferForRedirectToFile : public net::WrappedIOBuffer {
- public:
- DependentIOBufferForRedirectToFile(net::IOBuffer* backing, char* memory)
- : net::WrappedIOBuffer(memory), backing_(backing) {}
-
- private:
- ~DependentIOBufferForRedirectToFile() override {}
-
- scoped_refptr<net::IOBuffer> backing_;
-};
-
-} // namespace
-
-namespace content {
-
-const int RedirectToFileResourceHandler::kInitialReadBufSize = 32768;
-const int RedirectToFileResourceHandler::kMaxReadBufSize = 524288;
-
-// A separate IO thread object to manage the lifetime of the net::FileStream and
-// the ShareableFileReference. When the handler is destroyed, it asynchronously
-// closes net::FileStream after all pending writes complete. Only after the
-// stream is closed is the ShareableFileReference released, to ensure the
-// temporary is not deleted before it is closed.
-class RedirectToFileResourceHandler::Writer {
- public:
- Writer(RedirectToFileResourceHandler* handler,
- std::unique_ptr<net::FileStream> file_stream,
- ShareableFileReference* deletable_file)
- : handler_(handler),
- file_stream_(std::move(file_stream)),
- is_writing_(false),
- deletable_file_(deletable_file) {
- DCHECK(!deletable_file_->path().empty());
- }
-
- bool is_writing() const { return is_writing_; }
- const base::FilePath& path() const { return deletable_file_->path(); }
-
- int Write(net::IOBuffer* buf, int buf_len) {
- DCHECK(!is_writing_);
- DCHECK(handler_);
- int result = file_stream_->Write(
- buf, buf_len,
- base::BindOnce(&Writer::DidWriteToFile, base::Unretained(this)));
- if (result == net::ERR_IO_PENDING)
- is_writing_ = true;
- return result;
- }
-
- void Close() {
- handler_ = nullptr;
- if (!is_writing_)
- CloseAndDelete();
- }
-
- private:
- // Only DidClose can delete this.
- ~Writer() {
- }
-
- void DidWriteToFile(int result) {
- DCHECK(is_writing_);
- is_writing_ = false;
- if (handler_) {
- handler_->DidWriteToFile(result);
- } else {
- CloseAndDelete();
- }
- }
-
- void CloseAndDelete() {
- DCHECK(!is_writing_);
- int result = file_stream_->Close(
- base::BindOnce(&Writer::DidClose, base::Unretained(this)));
- if (result != net::ERR_IO_PENDING)
- DidClose(result);
- }
-
- void DidClose(int result) {
- delete this;
- }
-
- RedirectToFileResourceHandler* handler_;
-
- std::unique_ptr<net::FileStream> file_stream_;
- bool is_writing_;
-
- // We create a ShareableFileReference that's deletable for the temp file
- // created as a result of the download.
- scoped_refptr<storage::ShareableFileReference> deletable_file_;
-
- DISALLOW_COPY_AND_ASSIGN(Writer);
-};
-
-RedirectToFileResourceHandler::RedirectToFileResourceHandler(
- std::unique_ptr<ResourceHandler> next_handler,
- net::URLRequest* request)
- : LayeredResourceHandler(request, std::move(next_handler)),
- buf_(new net::GrowableIOBuffer()),
- weak_factory_(this) {}
-
-RedirectToFileResourceHandler::~RedirectToFileResourceHandler() {
- // Orphan the writer to asynchronously close and release the temporary file.
- if (writer_) {
- writer_->Close();
- writer_ = nullptr;
- }
-}
-
-void RedirectToFileResourceHandler::
- SetCreateTemporaryFileStreamFunctionForTesting(
- const CreateTemporaryFileStreamFunction& create_temporary_file_stream) {
- create_temporary_file_stream_ = create_temporary_file_stream;
-}
-
-void RedirectToFileResourceHandler::OnResponseStarted(
- network::ResourceResponse* response,
- std::unique_ptr<ResourceController> controller) {
- if (!writer_) {
- response_pending_file_creation_ = response;
- HoldController(std::move(controller));
- request()->LogBlockedBy("RedirectToFileResourceHandler");
- return;
- }
- response->head.download_file_path = writer_->path();
- next_handler_->OnResponseStarted(response, std::move(controller));
-}
-
-void RedirectToFileResourceHandler::OnWillStart(
- const GURL& url,
- std::unique_ptr<ResourceController> controller) {
- DCHECK(!writer_);
-
- // Create the file ASAP but don't block.
- if (create_temporary_file_stream_.is_null()) {
- CreateTemporaryFileStream(
- base::Bind(&RedirectToFileResourceHandler::DidCreateTemporaryFile,
- weak_factory_.GetWeakPtr()));
- } else {
- create_temporary_file_stream_.Run(
- base::Bind(&RedirectToFileResourceHandler::DidCreateTemporaryFile,
- weak_factory_.GetWeakPtr()));
- }
- next_handler_->OnWillStart(url, std::move(controller));
-}
-
-void RedirectToFileResourceHandler::OnWillRead(
- scoped_refptr<net::IOBuffer>* buf,
- int* buf_size,
- std::unique_ptr<ResourceController> controller) {
- if (buf_->capacity() < next_buffer_size_)
- buf_->SetCapacity(next_buffer_size_);
-
- // We should have paused this network request already if the buffer is full.
- DCHECK(!BufIsFull());
-
- *buf = buf_.get();
- *buf_size = buf_->RemainingCapacity();
-
- buf_write_pending_ = true;
- controller->Resume();
-}
-
-void RedirectToFileResourceHandler::OnReadCompleted(
- int bytes_read,
- std::unique_ptr<ResourceController> controller) {
- DCHECK(buf_write_pending_);
- buf_write_pending_ = false;
-
- // We use the buffer's offset field to record the end of the buffer.
- int new_offset = buf_->offset() + bytes_read;
- DCHECK(new_offset <= buf_->capacity());
- buf_->set_offset(new_offset);
-
- if (buf_->capacity() == bytes_read) {
- // The network layer has saturated our buffer in one read. Next time, we
- // should give it a bigger buffer for it to fill.
- next_buffer_size_ = std::min(next_buffer_size_ * 2, kMaxReadBufSize);
- }
-
- HoldController(std::move(controller));
- // WriteMore will resume the request if there's more buffer space.
- if (!WriteMore()) {
- CancelWithError(net::ERR_FAILED);
- return;
- }
-
- if (has_controller())
- request()->LogBlockedBy("RedirectToFileResourceHandler");
-}
-
-void RedirectToFileResourceHandler::OnResponseCompleted(
- const net::URLRequestStatus& status,
- std::unique_ptr<ResourceController> controller) {
- if (writer_ && writer_->is_writing()) {
- completed_during_write_ = true;
- completed_status_ = status;
- HoldController(std::move(controller));
- request()->LogBlockedBy("RedirectToFileResourceHandler");
- return;
- }
- next_handler_->OnResponseCompleted(status, std::move(controller));
-}
-
-int RedirectToFileResourceHandler::GetBufferSizeForTesting() const {
- return buf_->capacity();
-}
-
-void RedirectToFileResourceHandler::DidCreateTemporaryFile(
- base::File::Error error_code,
- std::unique_ptr<net::FileStream> file_stream,
- ShareableFileReference* deletable_file) {
- DCHECK(!writer_);
- if (error_code != base::File::FILE_OK) {
- if (has_controller()) {
- CancelWithError(net::FileErrorToNetError(error_code));
- } else {
- OutOfBandCancel(net::FileErrorToNetError(error_code),
- true /* tell_renderer */);
- }
- return;
- }
-
- writer_ = new Writer(this, std::move(file_stream), deletable_file);
-
- if (response_pending_file_creation_) {
- scoped_refptr<network::ResourceResponse> response =
- std::move(response_pending_file_creation_);
- request()->LogUnblocked();
- OnResponseStarted(response.get(), ReleaseController());
- }
-}
-
-void RedirectToFileResourceHandler::DidWriteToFile(int result) {
- bool failed = false;
- if (result > 0) {
- OnDataDownloaded(result);
- write_cursor_ += result;
- // WriteMore will resume the request if the request hasn't completed and
- // there's more buffer space.
- failed = !WriteMore();
- } else {
- failed = true;
- }
-
- if (failed) {
- DCHECK(!writer_->is_writing());
- // TODO(davidben): Recover the error code from WriteMore or |result|, as
- // appropriate.
- if (completed_during_write_ && completed_status_.is_success()) {
- // If the request successfully completed mid-write, but the write failed,
- // convert the status to a failure for downstream.
- completed_status_ = net::URLRequestStatus(net::URLRequestStatus::CANCELED,
- net::ERR_FAILED);
- }
- if (!completed_during_write_) {
- if (has_controller()) {
- // If the write buffer is full, |this| has deferred the request, and
- // can do an in-band cancel.
- CancelWithError(net::ERR_FAILED);
- } else {
- OutOfBandCancel(net::ERR_FAILED, true /* tell_renderer */);
- }
- return;
- }
- }
-
- if (completed_during_write_ && !writer_->is_writing()) {
- // Resume shutdown now that all data has been written to disk. Note that
- // this should run even in the |failed| case above, otherwise a failed write
- // leaves the handler stuck.
- DCHECK(has_controller());
- request()->LogUnblocked();
- next_handler_->OnResponseCompleted(completed_status_, ReleaseController());
- }
-}
-
-bool RedirectToFileResourceHandler::WriteMore() {
- DCHECK(writer_);
-
- for (;;) {
- if (write_cursor_ == buf_->offset()) {
- // We've caught up to the network load, but it may be in the process of
- // appending more data to the buffer.
- if (!buf_write_pending_) {
- buf_->set_offset(0);
- write_cursor_ = 0;
- }
- break;
- }
- if (writer_->is_writing())
- break;
- DCHECK(write_cursor_ < buf_->offset());
-
- // Create a temporary buffer pointing to a subsection of the data buffer so
- // that it can be passed to Write. This code makes some crazy scary
- // assumptions about object lifetimes, thread sharing, and that buf_ will
- // not realloc durring the write due to how the state machine in this class
- // works.
- // Note that buf_ is also shared with the code that writes data into the
- // cache, so modifying it can cause some pretty subtle race conditions:
- // https://code.google.com/p/chromium/issues/detail?id=152076
- // We're using DependentIOBuffer instead of DrainableIOBuffer to dodge some
- // of these issues, for the moment.
- // TODO(ncbray) make this code less crazy scary.
- // 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<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);
- if (rv == net::ERR_IO_PENDING)
- break;
- if (rv <= 0)
- return false;
- OnDataDownloaded(rv);
- write_cursor_ += rv;
- }
-
- // If the request was defered for a reason other than having been completed,
- // and the buffer has space, resume the request.
- if (has_controller() && !completed_during_write_ && !BufIsFull()) {
- request()->LogUnblocked();
- Resume();
- }
- return true;
-}
-
-bool RedirectToFileResourceHandler::BufIsFull() const {
- // This is a hack to workaround MimeTypeResourceHandler's inability to
- // deal with a ResourceHandler that returns a buffer size of less than
- // 2 * net::kMaxBytesToSniff from its OnWillRead method.
- // TODO(darin): Fix this retardation!
- return buf_->RemainingCapacity() <= (2 * net::kMaxBytesToSniff);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/loader/redirect_to_file_resource_handler.h b/chromium/content/browser/loader/redirect_to_file_resource_handler.h
deleted file mode 100644
index 41fb23c1301..00000000000
--- a/chromium/content/browser/loader/redirect_to_file_resource_handler.h
+++ /dev/null
@@ -1,138 +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_LOADER_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_
-#define CONTENT_BROWSER_LOADER_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_
-
-#include <memory>
-
-#include "base/callback.h"
-#include "base/compiler_specific.h"
-#include "base/files/file.h"
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "content/browser/loader/layered_resource_handler.h"
-#include "content/browser/loader/temporary_file_stream.h"
-#include "content/common/content_export.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_status.h"
-#include "url/gurl.h"
-
-namespace net {
-class FileStream;
-class GrowableIOBuffer;
-}
-
-namespace storage {
-class ShareableFileReference;
-}
-
-namespace content {
-
-class ResourceController;
-
-// Redirects network data to a file. This is intended to be layered in front of
-// either the AsyncResourceHandler or the SyncResourceHandler. The downstream
-// resource handler does not see OnWillRead or OnReadCompleted calls. Instead,
-// the ResourceResponse contains the path to a temporary file and
-// OnDataDownloaded is called as the file downloads.
-class CONTENT_EXPORT RedirectToFileResourceHandler
- : public LayeredResourceHandler {
- public:
- // Exposed for testing.
- static const int kInitialReadBufSize;
- static const int kMaxReadBufSize;
-
- typedef base::Callback<void(const CreateTemporaryFileStreamCallback&)>
- CreateTemporaryFileStreamFunction;
-
- // Create a RedirectToFileResourceHandler for |request| which wraps
- // |next_handler|.
- RedirectToFileResourceHandler(std::unique_ptr<ResourceHandler> next_handler,
- net::URLRequest* request);
- ~RedirectToFileResourceHandler() override;
-
- // Replace the CreateTemporaryFileStream implementation with a mocked one for
- // testing purposes. The function should create a net::FileStream and a
- // ShareableFileReference and then asynchronously pass them to the
- // CreateTemporaryFileStreamCallback.
- void SetCreateTemporaryFileStreamFunctionForTesting(
- const CreateTemporaryFileStreamFunction& create_temporary_file_stream);
-
- // LayeredResourceHandler implementation:
- void OnResponseStarted(
- network::ResourceResponse* response,
- std::unique_ptr<ResourceController> controller) override;
- void OnWillStart(const GURL& url,
- std::unique_ptr<ResourceController> controller) override;
- void OnWillRead(scoped_refptr<net::IOBuffer>* buf,
- int* buf_size,
- std::unique_ptr<ResourceController> controller) override;
- void OnReadCompleted(int bytes_read,
- std::unique_ptr<ResourceController> controller) override;
- void OnResponseCompleted(
- const net::URLRequestStatus& status,
- std::unique_ptr<ResourceController> controller) override;
-
- // Returns the size of |buf_|, to make sure it's being increased as expected.
- int GetBufferSizeForTesting() const;
-
- private:
- void DidCreateTemporaryFile(base::File::Error error_code,
- std::unique_ptr<net::FileStream> file_stream,
- storage::ShareableFileReference* deletable_file);
-
- // Called by RedirectToFileResourceHandler::Writer.
- void DidWriteToFile(int result);
-
- // Attempts to write more data to the file, if possible. Returns false on
- // error. Returns true if there's already a write in progress, all data was
- // written successfully, or a new write was started that will complete
- // asynchronously. Resumes the request if there's more data to read and more
- // buffer space available.
- bool WriteMore();
-
- bool BufIsFull() const;
-
- // If populated, OnResponseStarted completion is pending on file creation.
- scoped_refptr<network::ResourceResponse> response_pending_file_creation_;
- CreateTemporaryFileStreamFunction create_temporary_file_stream_;
-
- // We allocate a single, fixed-size IO buffer (buf_) used to read from the
- // network (buf_write_pending_ is true while the system is copying data into
- // buf_), and then write this buffer out to disk (write_callback_pending_ is
- // true while writing to disk). Reading from the network is suspended while
- // the buffer is full (BufIsFull returns true). The write_cursor_ member
- // tracks the offset into buf_ that we are writing to disk.
-
- scoped_refptr<net::GrowableIOBuffer> buf_;
- bool buf_write_pending_ = false;
- int write_cursor_ = 0;
-
- // Helper writer object which maintains references to the net::FileStream and
- // storage::ShareableFileReference. This is maintained separately so that,
- // on Windows, the temporary file isn't deleted until after it is closed.
- class Writer;
- Writer* writer_ = nullptr;
-
- // |next_buffer_size_| is the size of the buffer to be allocated on the next
- // OnWillRead() call. We exponentially grow the size of the buffer allocated
- // when our owner fills our buffers. On the first OnWillRead() call, we
- // allocate a buffer of 32k and double it in OnReadCompleted() if the buffer
- // was filled, up to a maximum size of 512k.
- int next_buffer_size_ = kInitialReadBufSize;
-
- bool completed_during_write_ = false;
- net::URLRequestStatus completed_status_;
-
- base::WeakPtrFactory<RedirectToFileResourceHandler> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(RedirectToFileResourceHandler);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_LOADER_REDIRECT_TO_FILE_RESOURCE_HANDLER_H_
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
deleted file mode 100644
index ac012a09e0e..00000000000
--- a/chromium/content/browser/loader/redirect_to_file_resource_handler_unittest.cc
+++ /dev/null
@@ -1,925 +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/loader/redirect_to_file_resource_handler.h"
-
-#include <algorithm>
-#include <limits>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/run_loop.h"
-#include "base/strings/string_piece.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/browser/loader/mock_resource_loader.h"
-#include "content/browser/loader/temporary_file_stream.h"
-#include "content/browser/loader/test_resource_handler.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "net/base/completion_callback.h"
-#include "net/base/completion_once_callback.h"
-#include "net/base/file_stream.h"
-#include "net/base/io_buffer.h"
-#include "net/base/mime_sniffer.h"
-#include "net/base/net_errors.h"
-#include "net/base/request_priority.h"
-#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_status.h"
-#include "net/url_request/url_request_test_util.h"
-#include "services/network/public/cpp/resource_response.h"
-#include "storage/browser/blob/shareable_file_reference.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace content {
-namespace {
-
-// The maximum size for which the initial read will always be sync, even when
-// the wrote completes asynchronously. See
-// RedirectToFileResourceHandler::BufIsFull().
-const int kMaxInitialSyncReadSize =
- RedirectToFileResourceHandler::kInitialReadBufSize -
- 2 * net::kMaxBytesToSniff - 1;
-
-// Used to indicate whether FileStream operations and the lower-layer
-// TestResourceHandler operations should complete immediately or by
-// asynchronously invoking a callback. Each test is run with all operations set
-// by default to each mode, though some tests override the mode of some
-// operations.
-enum class CompletionMode {
- SYNC,
- ASYNC,
-};
-
-// Mock in-memory net::FileStream implementation that can be configured to
-// return errors and complete operations synchronously or asynchronously.
-class MockFileStream : public net::FileStream {
- public:
- struct OperationResult {
- OperationResult(int result, CompletionMode completion_mode)
- : result(result), completion_mode(completion_mode) {}
-
- OperationResult()
- : OperationResult(net::ERR_UNEXPECTED, CompletionMode::SYNC) {}
-
- int result;
- CompletionMode completion_mode;
- };
-
- MockFileStream() : FileStream(base::ThreadTaskRunnerHandle::Get()) {}
-
- ~MockFileStream() override {
- EXPECT_EQ(expect_closed_, closed_);
- // Most of these tests write 32k or more, which is a bit much for the
- // command line.
- EXPECT_TRUE(expected_written_data_ == written_data_);
- }
-
- // net::FileStream implementation:
-
- int Open(const base::FilePath& path,
- int open_flags,
- net::CompletionOnceCallback callback) override {
- return ReturnResult(open_result_, std::move(callback));
- }
-
- int Close(net::CompletionOnceCallback callback) override {
- EXPECT_FALSE(closed_);
- int result = ReturnResult(
- close_result_,
- base::BindOnce(&MockFileStream::SetClosedAndRunCallback,
- base::Unretained(this), std::move(callback)));
- if (result != net::ERR_IO_PENDING)
- closed_ = true;
- return result;
- }
-
- bool IsOpen() const override {
- NOTREACHED();
- return false;
- }
-
- int Seek(int64_t offset, net::Int64CompletionOnceCallback callback) override {
- NOTREACHED();
- return net::ERR_UNEXPECTED;
- }
-
- int Read(net::IOBuffer* buf,
- int buf_len,
- net::CompletionOnceCallback callback) override {
- NOTREACHED();
- return net::ERR_UNEXPECTED;
- }
-
- int Write(net::IOBuffer* buf,
- int buf_len,
- net::CompletionOnceCallback callback) override {
- // 0-byte writes aren't allowed.
- EXPECT_GT(buf_len, 0);
-
- OperationResult write_result = next_write_result_;
- next_write_result_ = all_write_results_;
- if (write_result.result > buf_len)
- write_result.result = buf_len;
- if (write_result.result > 0)
- written_data_ += std::string(buf->data(), write_result.result);
-
- return ReturnResult(write_result, std::move(callback));
- }
-
- int Flush(net::CompletionOnceCallback callback) override {
- NOTREACHED();
- return net::ERR_UNEXPECTED;
- }
-
- void set_open_result(OperationResult open_result) {
- open_result_ = open_result;
- }
- void set_close_result(OperationResult close_result) {
- close_result_ = close_result;
- }
-
- // Sets the result for all write operations. Returned result is capped at
- // number of bytes the consumer actually tried to write. Overrides
- // |next_write_result_|.
- void set_all_write_results(OperationResult all_write_results) {
- next_write_result_ = all_write_results_ = all_write_results;
- }
-
- // Sets the result of only the next write operation.
- void set_next_write_result(OperationResult next_write_result) {
- next_write_result_ = next_write_result;
- }
-
- void set_expected_written_data(const std::string& expected_written_data) {
- expected_written_data_ = expected_written_data;
- }
-
- // Sets whether the file should expect to be closed.
- void set_expect_closed(bool expect_closed) { expect_closed_ = expect_closed; }
-
- private:
- void SetClosedAndRunCallback(net::CompletionOnceCallback callback,
- int result) {
- EXPECT_FALSE(closed_);
- closed_ = true;
- std::move(callback).Run(result);
- }
-
- int ReturnResult(OperationResult result,
- net::CompletionOnceCallback callback) {
- if (result.completion_mode == CompletionMode::SYNC)
- return result.result;
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), result.result));
- return net::ERR_IO_PENDING;
- }
-
- OperationResult open_result_;
- OperationResult close_result_;
- OperationResult next_write_result_;
- OperationResult all_write_results_;
-
- std::string expected_written_data_;
- std::string written_data_;
-
- bool expect_closed_ = false;
- bool closed_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(MockFileStream);
-};
-
-class RedirectToFileResourceHandlerTest
- : public testing::TestWithParam<CompletionMode> {
- public:
- RedirectToFileResourceHandlerTest()
- : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
- url_request_(
- url_request_context_.CreateRequest(GURL("foo://bar/"),
- net::DEFAULT_PRIORITY,
- &url_request_delegate_,
- TRAFFIC_ANNOTATION_FOR_TESTS)) {
- base::CreateTemporaryFile(&temp_file_path_);
- std::unique_ptr<TestResourceHandler> test_handler =
- 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
- // unusual.
- test_handler->set_defer_on_response_started(true);
- test_handler->set_defer_on_will_start(true);
- }
- test_handler_ = test_handler->GetWeakPtr();
-
- redirect_to_file_handler_ = std::make_unique<RedirectToFileResourceHandler>(
- std::move(test_handler), url_request_.get());
- mock_loader_ =
- std::make_unique<MockResourceLoader>(redirect_to_file_handler_.get());
- redirect_to_file_handler_->SetCreateTemporaryFileStreamFunctionForTesting(
- base::Bind(&RedirectToFileResourceHandlerTest::
- SetCreateTemporaryFileStreamCallback,
- base::Unretained(this)));
-
- file_stream_ = std::make_unique<MockFileStream>();
- file_stream_->set_open_result(
- MockFileStream::OperationResult(net::OK, GetParam()));
- file_stream_->set_all_write_results(MockFileStream::OperationResult(
- std::numeric_limits<int>::max(), GetParam()));
- file_stream_->set_close_result(
- MockFileStream::OperationResult(net::OK, GetParam()));
- }
-
- ~RedirectToFileResourceHandlerTest() override {
- EXPECT_FALSE(test_handler_->on_read_completed_called());
-
- // This should post a task to delete the temporary file.
- redirect_to_file_handler_.reset();
- mock_loader_.reset();
- url_request_.reset();
- // This should delete the temporary file, and ensure
- // MockFileStream::Cancel() is called.
- base::RunLoop().RunUntilIdle();
-
- EXPECT_FALSE(base::PathExists(temp_file_path_));
- }
-
- // Creates a test string of the specified length, and sets that as the
- // expected data written to |file_stream_|.
- std::string CreateTestData(size_t length) {
- std::string test_data;
- test_data.reserve(length);
- for (size_t i = 0; i < length; ++i)
- test_data.push_back(static_cast<char>(i % 256));
- file_stream_->set_expected_written_data(test_data);
- return test_data;
- }
-
- // The "CreateTemporaryFileStream" method invoked by the
- // RedirectToFileResourceHandler. Just sets a callback that will be invoked
- // directly.
- void SetCreateTemporaryFileStreamCallback(
- const CreateTemporaryFileStreamCallback& create_file_stream_callback) {
- create_file_stream_callback_ = create_file_stream_callback;
- }
-
- void PerformOnWillStart() {
- MockResourceLoader::Status expected_status;
- if (GetParam() == CompletionMode::ASYNC) {
- expected_status = MockResourceLoader::Status::CALLBACK_PENDING;
- } else {
- expected_status = MockResourceLoader::Status::IDLE;
- }
- EXPECT_EQ(expected_status, mock_loader_->OnWillStart(url_request_->url()));
- }
-
- // Sets up the file stream or error, and performs the file callback.
- void PerformCreateFile(base::File::Error file_error) {
- DCHECK(file_stream_);
-
- file_stream_->set_expect_closed(file_error == base::File::FILE_OK);
- if (file_error != base::File::FILE_OK)
- file_stream_ = nullptr;
-
- base::ResetAndReturn(&create_file_stream_callback_)
- .Run(file_error, std::move(file_stream_),
- // Not really used by the test, but the ResourceHandler expects it
- // to be non-null.
- storage::ShareableFileReference::GetOrCreate(
- temp_file_path_,
- storage::ShareableFileReference::DELETE_ON_FINAL_RELEASE,
- base::ThreadTaskRunnerHandle::Get().get())
- .get());
- }
-
- // Simulates starting the request, the response starting, and stream creation
- // completing with the specified error code. Has |test_handler_| resume the
- // request, if needed. Returns final status of |mock_loader_|.
- MockResourceLoader::Status StartAndCreateStream(base::File::Error file_error)
- WARN_UNUSED_RESULT {
- PerformOnWillStart();
-
- // Create the file right away.
- PerformCreateFile(file_error);
-
- // If this is an async test, |test_handler_| will defer the OnWillStart
- // event on success (On error, its OnWillStart method is not called).
- if (file_error == base::File::FILE_OK &&
- GetParam() == CompletionMode::ASYNC) {
- EXPECT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->status());
- test_handler_->Resume();
- mock_loader_->WaitUntilIdleOrCanceled();
- }
- EXPECT_NE(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->status());
- return mock_loader_->status();
- }
-
- // Convenience wrapper for MockLoader methods that will Resume |test_handler_|
- // and wait for it to resume the request if running an async test.
- MockResourceLoader::Status OnResponseStartedAndWaitForResult()
- WARN_UNUSED_RESULT {
- mock_loader_->OnResponseStarted(
- base::MakeRefCounted<network::ResourceResponse>());
- if (GetParam() == CompletionMode::ASYNC) {
- EXPECT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->status());
- test_handler_->Resume();
- mock_loader_->WaitUntilIdleOrCanceled();
- }
- EXPECT_NE(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->status());
- return mock_loader_->status();
- }
-
- // Utility method that simulates a final 0-byte read and response completed
- // events, and checks that completion is handled correctly. Expects all data
- // to already have been written to the file.
- void CompleteRequestSuccessfully(int expected_total_bytes_downloaded) {
- // The loader should be idle and all the data should have already been
- // processed.
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
- EXPECT_EQ(expected_total_bytes_downloaded,
- test_handler_->total_bytes_downloaded());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(""));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnResponseCompleted(
- net::URLRequestStatus::FromError(net::OK)));
- EXPECT_EQ(expected_total_bytes_downloaded,
- test_handler_->total_bytes_downloaded());
- EXPECT_EQ(net::URLRequestStatus::SUCCESS,
- test_handler_->final_status().status());
- }
-
- protected:
- TestBrowserThreadBundle thread_bundle_;
- base::FilePath temp_file_path_;
- net::TestURLRequestContext url_request_context_;
- net::TestDelegate url_request_delegate_;
- base::WeakPtr<TestResourceHandler> test_handler_;
- std::unique_ptr<net::URLRequest> url_request_;
- std::unique_ptr<MockResourceLoader> mock_loader_;
- std::unique_ptr<RedirectToFileResourceHandler> redirect_to_file_handler_;
- std::unique_ptr<MockFileStream> file_stream_;
-
- CreateTemporaryFileStreamCallback create_file_stream_callback_;
-};
-
-TEST_P(RedirectToFileResourceHandlerTest, EmptyBody) {
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- CompleteRequestSuccessfully(0);
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, SingleBodyRead) {
- std::string test_data = CreateTestData(kMaxInitialSyncReadSize);
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data));
- // Wait for the write to complete, in the async case.
- base::RunLoop().RunUntilIdle();
-
- CompleteRequestSuccessfully(test_data.size());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, SingleBodyReadDelayedFileOnResponse) {
- std::string test_data = CreateTestData(kMaxInitialSyncReadSize);
-
- PerformOnWillStart();
- if (GetParam() == CompletionMode::ASYNC) {
- EXPECT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->status());
- test_handler_->Resume();
- mock_loader_->WaitUntilIdleOrCanceled();
- }
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
- mock_loader_->OnResponseStarted(
- base::MakeRefCounted<network::ResourceResponse>());
- ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->status());
-
- PerformCreateFile(base::File::FILE_OK);
-
- if (GetParam() == CompletionMode::ASYNC) {
- EXPECT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->status());
- test_handler_->Resume();
- mock_loader_->WaitUntilIdleOrCanceled();
- }
- EXPECT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data));
- // Wait for the write to complete, in the async case.
- base::RunLoop().RunUntilIdle();
-
- CompleteRequestSuccessfully(test_data.size());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, SingleBodyReadDelayedFileError) {
- std::string test_data = CreateTestData(0);
-
- PerformOnWillStart();
- if (GetParam() == CompletionMode::ASYNC) {
- EXPECT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->status());
- test_handler_->Resume();
- mock_loader_->WaitUntilIdleOrCanceled();
- }
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
- mock_loader_->OnResponseStarted(
- base::MakeRefCounted<network::ResourceResponse>());
- ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->status());
-
- PerformCreateFile(base::File::FILE_ERROR_FAILED);
-
- EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
- EXPECT_EQ(0, test_handler_->on_response_completed_called());
- EXPECT_EQ(net::ERR_FAILED, mock_loader_->error_code());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnResponseCompleted(
- net::URLRequestStatus::FromError(net::ERR_FAILED)));
- EXPECT_FALSE(test_handler_->final_status().is_success());
- EXPECT_EQ(net::ERR_FAILED, test_handler_->final_status().error());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, ManySequentialBodyReads) {
- const size_t kBytesPerRead = 128;
- std::string test_data =
- CreateTestData(RedirectToFileResourceHandler::kInitialReadBufSize);
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- for (size_t offset = 0; offset < test_data.length();
- offset += kBytesPerRead) {
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- size_t length = std::min(kBytesPerRead, test_data.length() - offset);
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(
- base::StringPiece(test_data.data() + offset, length)));
- // Spin the message loop, to allow async writes to complete.
- base::RunLoop().RunUntilIdle();
- }
-
- CompleteRequestSuccessfully(test_data.size());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, PartialWrites) {
- std::string test_data = CreateTestData(kMaxInitialSyncReadSize);
- file_stream_->set_all_write_results(MockFileStream::OperationResult(
- RedirectToFileResourceHandler::kInitialReadBufSize / 50, GetParam()));
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data));
- // Wait for the writes to complete, in the async case.
- base::RunLoop().RunUntilIdle();
-
- CompleteRequestSuccessfully(test_data.size());
-}
-
-// Same as above, but read enough data to defer reading the body.
-TEST_P(RedirectToFileResourceHandlerTest, PartialWrites2) {
- std::string test_data =
- CreateTestData(RedirectToFileResourceHandler::kInitialReadBufSize);
- // Async reads, as otherwise reading won't be defered.
- file_stream_->set_all_write_results(MockFileStream::OperationResult(
- RedirectToFileResourceHandler::kInitialReadBufSize / 50,
- CompletionMode::ASYNC));
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->OnReadCompleted(test_data));
- // Wait for the writes to complete.
- base::RunLoop().RunUntilIdle();
-
- CompleteRequestSuccessfully(test_data.size());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, ReceiveDataWhileWritingBody) {
- const int kFirstWriteSize = 100;
-
- // This test only makes sense when reads are async.
- file_stream_->set_all_write_results(MockFileStream::OperationResult(
- std::numeric_limits<int>::max(), CompletionMode::ASYNC));
-
- // Will use multiple writes, with a combined size such that they don't
- // saturate the buffer.
- std::string test_data = CreateTestData(kMaxInitialSyncReadSize);
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(
- MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data.substr(0, kFirstWriteSize)));
- // Next read completes before first write succeeds.
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data.substr(
- kFirstWriteSize, sizeof(test_data) - kFirstWriteSize)));
- EXPECT_EQ(0, test_handler_->total_bytes_downloaded());
-
- // Wait for both writes to succeed.
- base::RunLoop().RunUntilIdle();
-
- CompleteRequestSuccessfully(test_data.size());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, ReceiveDataAndDeferWhileWritingBody) {
- const int kFirstWriteSize = 100;
-
- // This test only makes sense when reads are async.
- file_stream_->set_all_write_results(MockFileStream::OperationResult(
- std::numeric_limits<int>::max(), CompletionMode::ASYNC));
-
- // Will use multiple writes, with a combined size such that they saturate the
- // buffer.
- std::string test_data =
- CreateTestData(RedirectToFileResourceHandler::kInitialReadBufSize);
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(
- MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data.substr(0, kFirstWriteSize)));
- // Next read completes before first write succeeds.
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->OnReadCompleted(test_data.substr(
- kFirstWriteSize, sizeof(test_data) - kFirstWriteSize)));
- EXPECT_EQ(0, test_handler_->total_bytes_downloaded());
-
- // Wait for both writes to succeed.
- base::RunLoop().RunUntilIdle();
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
-
- CompleteRequestSuccessfully(test_data.size());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest,
- ExpandBufferCapacityManySequentialBodyReads) {
- // The buffer is only resized when reads are async.
- file_stream_->set_all_write_results(MockFileStream::OperationResult(
- std::numeric_limits<int>::max(), CompletionMode::ASYNC));
-
- const int kInitialReadSize =
- RedirectToFileResourceHandler::kInitialReadBufSize;
- const int kMaxReadSize = RedirectToFileResourceHandler::kMaxReadBufSize;
- int next_read_size = kInitialReadSize;
- int total_read_bytes = 0;
- // Populate |read_sizes| with expected buffer sizes if each previous read
- // filled the entire buffer.
- std::vector<size_t> read_sizes;
- while (true) {
- total_read_bytes += next_read_size;
- read_sizes.push_back(next_read_size);
- if (next_read_size == kMaxReadSize)
- break;
- next_read_size = std::min(2 * next_read_size, kMaxReadSize);
- }
- // Once the max is reached, do another round to make sure it isn't increased.
- total_read_bytes += kMaxReadSize;
- read_sizes.push_back(kMaxReadSize);
-
- std::string test_data = CreateTestData(total_read_bytes);
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- int offset = 0;
- for (int read_size : read_sizes) {
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->OnReadCompleted(
- base::StringPiece(test_data.data() + offset, read_size)));
- offset += read_size;
-
- EXPECT_EQ(read_size, redirect_to_file_handler_->GetBufferSizeForTesting());
-
- base::RunLoop().RunUntilIdle();
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->status());
- }
-
- CompleteRequestSuccessfully(test_data.size());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, CompletedWhileWritingBody) {
- // This test only makes sense when reads are async.
- file_stream_->set_all_write_results(MockFileStream::OperationResult(
- std::numeric_limits<int>::max(), CompletionMode::ASYNC));
-
- std::string test_data = CreateTestData(kMaxInitialSyncReadSize);
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data));
- EXPECT_EQ(0, test_handler_->total_bytes_downloaded());
-
- // While data is being written to the disk, the request completes.
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(""));
- ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->OnResponseCompleted(
- net::URLRequestStatus::FromError(net::OK)));
-
- // Wait for the write to complete and the final status sent to the
- // TestHandler.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(static_cast<int>(test_data.size()),
- test_handler_->total_bytes_downloaded());
- EXPECT_EQ(net::URLRequestStatus::SUCCESS,
- test_handler_->final_status().status());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest,
- CompletedWhileWritingBodyAndWritePending) {
- const int kFirstWriteSize = 100;
-
- // This test only makes sense when reads are async.
- file_stream_->set_all_write_results(MockFileStream::OperationResult(
- std::numeric_limits<int>::max(), CompletionMode::ASYNC));
-
- // Will use multiple writes, with a combined size such that they don't
- // saturate the buffer.
- std::string test_data = CreateTestData(kMaxInitialSyncReadSize);
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(
- MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data.substr(0, kFirstWriteSize)));
- // Next read completes before first write succeeds.
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data.substr(
- kFirstWriteSize, sizeof(test_data) - kFirstWriteSize)));
- EXPECT_EQ(0, test_handler_->total_bytes_downloaded());
-
- // While the first write is still going on, the request completes.
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(""));
- ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->OnResponseCompleted(
- net::URLRequestStatus::FromError(net::OK)));
-
- // Wait for both writes to complete and the final status to be sent to the
- // TestHandler.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(static_cast<int>(test_data.size()),
- test_handler_->total_bytes_downloaded());
- EXPECT_EQ(net::URLRequestStatus::SUCCESS,
- test_handler_->final_status().status());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, SingleBodyReadAndFail) {
- std::string test_data = CreateTestData(kMaxInitialSyncReadSize);
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data));
-
- // Wait for the write to complete.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(static_cast<int>(test_data.size()),
- test_handler_->total_bytes_downloaded());
-
- // Next read fails and request is torn down synchronously.
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnResponseCompleted(
- net::URLRequestStatus::FromError(net::ERR_FAILED)));
-
- EXPECT_FALSE(test_handler_->final_status().is_success());
- EXPECT_EQ(net::ERR_FAILED, test_handler_->final_status().error());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, FailedWhileWritingBody) {
- // This test only makes sense when reads are async.
- file_stream_->set_all_write_results(MockFileStream::OperationResult(
- std::numeric_limits<int>::max(), CompletionMode::ASYNC));
-
- std::string test_data = CreateTestData(kMaxInitialSyncReadSize);
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data));
- EXPECT_EQ(0, test_handler_->total_bytes_downloaded());
-
- // While data is being written to the disk, the request fails.
- ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->OnResponseCompleted(
- net::URLRequestStatus::FromError(net::ERR_FAILED)));
-
- // Wait for the write to complete and the final status sent to the
- // TestHandler.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(static_cast<int>(test_data.size()),
- test_handler_->total_bytes_downloaded());
- EXPECT_FALSE(test_handler_->final_status().is_success());
- EXPECT_EQ(net::ERR_FAILED, test_handler_->final_status().error());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest,
- FailededWhileWritingBodyAndWritePending) {
- const int kFirstWriteSize = 100;
-
- // This test only makes sense when reads are async.
- file_stream_->set_all_write_results(MockFileStream::OperationResult(
- std::numeric_limits<int>::max(), CompletionMode::ASYNC));
-
- // Will use multiple writes, with a combined size such that they don't
- // saturate the buffer.
- std::string test_data = CreateTestData(kMaxInitialSyncReadSize);
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(
- MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data.substr(0, kFirstWriteSize)));
- // Next read completes before first write succeeds.
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(test_data.substr(
- kFirstWriteSize, sizeof(test_data) - kFirstWriteSize)));
-
- // While the first write is still going on, the request fails.
- ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader_->OnResponseCompleted(
- net::URLRequestStatus::FromError(net::ERR_FAILED)));
- EXPECT_EQ(0, test_handler_->total_bytes_downloaded());
-
- // Wait for both writes to complete and the final status to be sent to the
- // TestHandler.
- base::RunLoop().RunUntilIdle();
- EXPECT_EQ(static_cast<int>(test_data.size()),
- test_handler_->total_bytes_downloaded());
- EXPECT_FALSE(test_handler_->final_status().is_success());
- EXPECT_EQ(net::ERR_FAILED, test_handler_->final_status().error());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, CreateFileFails) {
- ASSERT_EQ(MockResourceLoader::Status::CANCELED,
- StartAndCreateStream(base::File::FILE_ERROR_FAILED));
-
- EXPECT_EQ(0, test_handler_->on_response_completed_called());
- EXPECT_EQ(net::ERR_FAILED, mock_loader_->error_code());
- if (GetParam() == CompletionMode::ASYNC) {
- EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnResponseCompletedFromExternalOutOfBandCancel(
- net::URLRequestStatus::FromError(net::ERR_FAILED)));
- } else {
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnResponseCompleted(
- net::URLRequestStatus::FromError(net::ERR_FAILED)));
- }
-
- EXPECT_EQ(0, test_handler_->total_bytes_downloaded());
- EXPECT_FALSE(test_handler_->final_status().is_success());
- EXPECT_EQ(net::ERR_FAILED, test_handler_->final_status().error());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, FirstWriteFails) {
- std::string test_data = CreateTestData(kMaxInitialSyncReadSize);
- file_stream_->set_expected_written_data("");
- file_stream_->set_next_write_result(
- MockFileStream::OperationResult(net::ERR_FAILED, GetParam()));
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- mock_loader_->OnReadCompleted(test_data);
- // Wait for the write to complete, in the async case.
- base::RunLoop().RunUntilIdle();
- ASSERT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
-
- EXPECT_EQ(net::ERR_FAILED, mock_loader_->error_code());
- EXPECT_EQ(0, test_handler_->on_response_completed_called());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnResponseCompleted(
- net::URLRequestStatus::FromError(net::ERR_FAILED)));
- EXPECT_EQ(0, test_handler_->total_bytes_downloaded());
- EXPECT_FALSE(test_handler_->final_status().is_success());
- EXPECT_EQ(net::ERR_FAILED, test_handler_->final_status().error());
-}
-
-TEST_P(RedirectToFileResourceHandlerTest, SecondWriteFails) {
- const int kFirstWriteSize = kMaxInitialSyncReadSize;
- std::string test_data =
- CreateTestData(RedirectToFileResourceHandler::kInitialReadBufSize);
- file_stream_->set_expected_written_data(test_data.substr(0, kFirstWriteSize));
- file_stream_->set_all_write_results(
- MockFileStream::OperationResult(net::ERR_FAILED, GetParam()));
- file_stream_->set_next_write_result(MockFileStream::OperationResult(
- std::numeric_limits<int>::max(), GetParam()));
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- StartAndCreateStream(base::File::FILE_OK));
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- OnResponseStartedAndWaitForResult());
-
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnReadCompleted(
- base::StringPiece(test_data.data(), kFirstWriteSize)));
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader_->OnWillRead());
- mock_loader_->OnReadCompleted(base::StringPiece(
- test_data.data() + kFirstWriteSize, test_data.size() - kFirstWriteSize));
- // Wait for the write to complete, in the async case.
- base::RunLoop().RunUntilIdle();
- ASSERT_EQ(MockResourceLoader::Status::CANCELED, mock_loader_->status());
-
- EXPECT_EQ(net::ERR_FAILED, mock_loader_->error_code());
- EXPECT_EQ(0, test_handler_->on_response_completed_called());
- ASSERT_EQ(MockResourceLoader::Status::IDLE,
- mock_loader_->OnResponseCompleted(
- net::URLRequestStatus::FromError(net::ERR_FAILED)));
- EXPECT_EQ(kFirstWriteSize, test_handler_->total_bytes_downloaded());
- EXPECT_FALSE(test_handler_->final_status().is_success());
- EXPECT_EQ(net::ERR_FAILED, test_handler_->final_status().error());
-}
-
-INSTANTIATE_TEST_CASE_P(/* No prefix needed */,
- RedirectToFileResourceHandlerTest,
- testing::Values(CompletionMode::SYNC,
- CompletionMode::ASYNC));
-
-} // namespace
-} // namespace content
diff --git a/chromium/content/browser/loader/resource_buffer.cc b/chromium/content/browser/loader/resource_buffer.cc
deleted file mode 100644
index 5e34dd24f15..00000000000
--- a/chromium/content/browser/loader/resource_buffer.cc
+++ /dev/null
@@ -1,173 +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/loader/resource_buffer.h"
-
-#include <math.h>
-
-#include "base/logging.h"
-
-namespace content {
-
-// A circular buffer allocator.
-//
-// We keep track of the starting offset (alloc_start_) and the ending offset
-// (alloc_end_). There are two layouts to keep in mind:
-//
-// #1:
-// ------------[XXXXXXXXXXXXXXXXXXXXXXX]----
-// ^ ^
-// start end
-//
-// #2:
-// XXXXXXXXXX]---------------------[XXXXXXXX
-// ^ ^
-// end start
-//
-// If end <= start, then we have the buffer wraparound case (depicted second).
-// If the buffer is empty, then start and end will be set to -1.
-//
-// Allocations are always contiguous.
-
-ResourceBuffer::ResourceBuffer()
- : buf_size_(0),
- min_alloc_size_(0),
- max_alloc_size_(0),
- alloc_start_(-1),
- alloc_end_(-1) {
-}
-
-ResourceBuffer::~ResourceBuffer() {
-}
-
-bool ResourceBuffer::Initialize(int buffer_size,
- int min_allocation_size,
- int max_allocation_size) {
- CHECK(!IsInitialized());
-
- // It would be wasteful if these are not multiples of min_allocation_size.
- CHECK_EQ(0, buffer_size % min_allocation_size);
- CHECK_EQ(0, max_allocation_size % min_allocation_size);
-
- buf_size_ = buffer_size;
- min_alloc_size_ = min_allocation_size;
- max_alloc_size_ = max_allocation_size;
-
- return shared_mem_.CreateAndMapAnonymous(buf_size_);
-}
-
-bool ResourceBuffer::IsInitialized() const {
- return shared_mem_.memory() != nullptr;
-}
-
-base::SharedMemory& ResourceBuffer::GetSharedMemory() {
- CHECK(IsInitialized());
- return shared_mem_;
-}
-
-bool ResourceBuffer::CanAllocate() const {
- CHECK(IsInitialized());
-
- if (alloc_start_ == -1)
- return true;
-
- int diff = alloc_end_ - alloc_start_;
- if (diff > 0)
- return (buf_size_ - diff) >= min_alloc_size_;
-
- return -diff >= min_alloc_size_;
-}
-
-char* ResourceBuffer::Allocate(int* size) {
- CHECK(CanAllocate());
-
- int alloc_offset = 0;
- int alloc_size;
-
- if (alloc_start_ == -1) {
- // This is the first allocation.
- alloc_start_ = 0;
- alloc_end_ = buf_size_;
- alloc_size = buf_size_;
- } else if (alloc_start_ < alloc_end_) {
- // Append the next allocation if it fits. Otherwise, wraparound.
- //
- // NOTE: We could look to see if a larger allocation is possible by
- // wrapping around sooner, but instead we just look to fill the space at
- // the end of the buffer provided that meets the min_alloc_size_
- // requirement.
- //
- if ((buf_size_ - alloc_end_) >= min_alloc_size_) {
- alloc_offset = alloc_end_;
- alloc_size = buf_size_ - alloc_end_;
- alloc_end_ = buf_size_;
- } else {
- // It must be possible to allocate a least min_alloc_size_.
- CHECK(alloc_start_ >= min_alloc_size_);
- alloc_size = alloc_start_;
- alloc_end_ = alloc_start_;
- }
- } else {
- // This is the wraparound case.
- CHECK(alloc_end_ < alloc_start_);
- alloc_offset = alloc_end_;
- alloc_size = alloc_start_ - alloc_end_;
- alloc_end_ = alloc_start_;
- }
-
- // Make sure alloc_size does not exceed max_alloc_size_. We store the
- // current value of alloc_size, so that we can use ShrinkLastAllocation to
- // trim it back. This allows us to reuse the alloc_end_ adjustment logic.
-
- alloc_sizes_.push(alloc_size);
-
- if (alloc_size > max_alloc_size_) {
- alloc_size = max_alloc_size_;
- ShrinkLastAllocation(alloc_size);
- }
-
- *size = alloc_size;
- return static_cast<char*>(shared_mem_.memory()) + alloc_offset;
-}
-
-int ResourceBuffer::GetLastAllocationOffset() const {
- CHECK(!alloc_sizes_.empty());
- CHECK(alloc_end_ >= alloc_sizes_.back());
- return alloc_end_ - alloc_sizes_.back();
-}
-
-void ResourceBuffer::ShrinkLastAllocation(int new_size) {
- CHECK(!alloc_sizes_.empty());
-
- int aligned_size = (new_size / min_alloc_size_) * min_alloc_size_;
- if (aligned_size < new_size)
- aligned_size += min_alloc_size_;
-
- CHECK_LE(new_size, aligned_size);
- CHECK_GE(alloc_sizes_.back(), aligned_size);
-
- int* last_allocation_size = &alloc_sizes_.back();
- alloc_end_ -= (*last_allocation_size - aligned_size);
- *last_allocation_size = aligned_size;
-}
-
-void ResourceBuffer::RecycleLeastRecentlyAllocated() {
- CHECK(!alloc_sizes_.empty());
- int allocation_size = alloc_sizes_.front();
- alloc_sizes_.pop();
-
- alloc_start_ += allocation_size;
- CHECK(alloc_start_ <= buf_size_);
-
- if (alloc_start_ == alloc_end_) {
- CHECK(alloc_sizes_.empty());
- alloc_start_ = -1;
- alloc_end_ = -1;
- } else if (alloc_start_ == buf_size_) {
- CHECK(!alloc_sizes_.empty());
- alloc_start_ = 0;
- }
-}
-
-} // namespace content
diff --git a/chromium/content/browser/loader/resource_buffer.h b/chromium/content/browser/loader/resource_buffer.h
deleted file mode 100644
index 85354c4a1c7..00000000000
--- a/chromium/content/browser/loader/resource_buffer.h
+++ /dev/null
@@ -1,122 +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_LOADER_RESOURCE_BUFFER_H_
-#define CONTENT_BROWSER_LOADER_RESOURCE_BUFFER_H_
-
-#include "base/containers/queue.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/shared_memory.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-// ResourceBuffer implements a simple "circular buffer" allocation strategy.
-// Allocations are recycled in FIFO order.
-//
-// You can think of the ResourceBuffer as a FIFO. The Allocate method reserves
-// space in the buffer. Allocate may be called multiple times until the buffer
-// is fully reserved (at which point CanAllocate returns false). Allocations
-// are freed in FIFO order via a call to RecycleLeastRecentlyAllocated.
-//
-// ResourceBuffer is reference-counted for the benefit of consumers, who need
-// to ensure that ResourceBuffer stays alive while they are using its memory.
-//
-// EXAMPLE USAGE:
-//
-// // Writes data into the ResourceBuffer, and returns the location (byte
-// // offset and count) of the bytes written into the ResourceBuffer's shared
-// // memory buffer.
-// void WriteToBuffer(ResourceBuffer* buf, int* offset, int* count) {
-// DCHECK(buf->CanAllocate());
-//
-// *offset = -1;
-// *count = 0;
-//
-// int size;
-// char* ptr = buf->Allocate(&size);
-// if (!ptr) { /* handle error */ }
-//
-// int bytes_read = static_cast<int>(fread(ptr, 1, size, file_pointer_));
-// if (!bytes_read) { /* handle error */ }
-//
-// if (bytes_read < size)
-// buf->ShrinkLastAllocation(bytes_read);
-//
-// *offset = buf->GetLastAllocationOffset();
-// *count = bytes_read;
-// }
-//
-// NOTE: As the above example illustrates, the ResourceBuffer keeps track of
-// the last allocation made. Calling ShrinkLastAllocation is optional, as it
-// just helps the ResourceBuffer optimize storage and be more aggressive about
-// returning larger allocations from the Allocate method.
-//
-class CONTENT_EXPORT ResourceBuffer
- : public base::RefCountedThreadSafe<ResourceBuffer> {
- public:
- ResourceBuffer();
-
- // Initialize the shared memory buffer. It will be buffer_size bytes in
- // length. The min/max_allocation_size parameters control the behavior of
- // the Allocate method. It will prefer to return segments that are
- // max_allocation_size in length, but will return segments less than that if
- // space is limited. It will not return allocations smaller than
- // min_allocation_size.
- bool Initialize(int buffer_size,
- int min_allocation_size,
- int max_allocation_size);
- bool IsInitialized() const;
-
- // Returns a reference to the underlying shared memory.
- base::SharedMemory& GetSharedMemory();
-
- // Returns true if Allocate will succeed.
- bool CanAllocate() const;
-
- // Returns a pointer into the shared memory buffer or NULL if the buffer is
- // already fully allocated. The returned size will be max_allocation_size
- // unless the buffer is close to being full.
- char* Allocate(int* size);
-
- // Returns the offset into the shared memory buffer where the last allocation
- // returned by Allocate can be found.
- int GetLastAllocationOffset() const;
-
- // Called to reduce the size of the last allocation returned by Allocate. It
- // is OK for new_size to match the current size of the last allocation.
- void ShrinkLastAllocation(int new_size);
-
- // Called to allow reuse of memory that was previously allocated. See notes
- // above the class for more details about this method.
- void RecycleLeastRecentlyAllocated();
-
- private:
- friend class base::RefCountedThreadSafe<ResourceBuffer>;
- ~ResourceBuffer();
-
- base::SharedMemory shared_mem_;
-
- int buf_size_;
- int min_alloc_size_;
- int max_alloc_size_;
-
- // These point to the range of the shared memory that is currently allocated.
- // If alloc_start_ is -1, then the range is empty and nothing is allocated.
- // Otherwise, alloc_start_ points to the start of the allocated range, and
- // alloc_end_ points just beyond the end of the previous allocation. In the
- // wraparound case, alloc_end_ <= alloc_start_. See resource_buffer.cc for
- // more details about these members.
- int alloc_start_;
- int alloc_end_;
-
- base::queue<int> alloc_sizes_;
-
- DISALLOW_COPY_AND_ASSIGN(ResourceBuffer);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_LOADER_RESOURCE_BUFFER_H_
diff --git a/chromium/content/browser/loader/resource_buffer_unittest.cc b/chromium/content/browser/loader/resource_buffer_unittest.cc
deleted file mode 100644
index a9e90431544..00000000000
--- a/chromium/content/browser/loader/resource_buffer_unittest.cc
+++ /dev/null
@@ -1,137 +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/loader/resource_buffer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-TEST(ResourceBufferTest, BasicAllocations) {
- scoped_refptr<ResourceBuffer> buf = new ResourceBuffer();
- EXPECT_TRUE(buf->Initialize(100, 5, 10));
- EXPECT_TRUE(buf->CanAllocate());
-
- // First allocation
- {
- int size;
- char* ptr = buf->Allocate(&size);
- EXPECT_TRUE(ptr);
- EXPECT_EQ(10, size);
- EXPECT_TRUE(buf->CanAllocate());
-
- EXPECT_EQ(0, buf->GetLastAllocationOffset());
-
- buf->ShrinkLastAllocation(2); // Less than our min allocation size.
- EXPECT_EQ(0, buf->GetLastAllocationOffset());
- EXPECT_TRUE(buf->CanAllocate());
- }
-
- // Second allocation
- {
- int size;
- char* ptr = buf->Allocate(&size);
- EXPECT_TRUE(ptr);
- EXPECT_EQ(10, size);
- EXPECT_TRUE(buf->CanAllocate());
-
- EXPECT_EQ(5, buf->GetLastAllocationOffset());
-
- buf->ShrinkLastAllocation(4);
- EXPECT_EQ(5, buf->GetLastAllocationOffset());
-
- EXPECT_TRUE(buf->CanAllocate());
- }
-}
-
-TEST(ResourceBufferTest, AllocateAndRecycle) {
- scoped_refptr<ResourceBuffer> buf = new ResourceBuffer();
- EXPECT_TRUE(buf->Initialize(100, 5, 10));
-
- int size;
-
- buf->Allocate(&size);
- EXPECT_EQ(0, buf->GetLastAllocationOffset());
-
- buf->RecycleLeastRecentlyAllocated();
-
- // Offset should again be 0.
- buf->Allocate(&size);
- EXPECT_EQ(0, buf->GetLastAllocationOffset());
-}
-
-TEST(ResourceBufferTest, WrapAround) {
- scoped_refptr<ResourceBuffer> buf = new ResourceBuffer();
- EXPECT_TRUE(buf->Initialize(20, 10, 10));
-
- int size;
-
- buf->Allocate(&size);
- EXPECT_EQ(10, size);
-
- buf->Allocate(&size);
- EXPECT_EQ(10, size);
-
- // Create hole at the beginnning. Next allocation should go there.
- buf->RecycleLeastRecentlyAllocated();
-
- buf->Allocate(&size);
- EXPECT_EQ(10, size);
-
- EXPECT_EQ(0, buf->GetLastAllocationOffset());
-}
-
-TEST(ResourceBufferTest, WrapAround2) {
- scoped_refptr<ResourceBuffer> buf = new ResourceBuffer();
- EXPECT_TRUE(buf->Initialize(30, 10, 10));
-
- int size;
-
- buf->Allocate(&size);
- EXPECT_EQ(10, size);
-
- buf->Allocate(&size);
- EXPECT_EQ(10, size);
-
- buf->Allocate(&size);
- EXPECT_EQ(10, size);
-
- EXPECT_FALSE(buf->CanAllocate());
-
- // Create holes at first and second slots.
- buf->RecycleLeastRecentlyAllocated();
- buf->RecycleLeastRecentlyAllocated();
-
- EXPECT_TRUE(buf->CanAllocate());
-
- buf->Allocate(&size);
- EXPECT_EQ(10, size);
- EXPECT_EQ(0, buf->GetLastAllocationOffset());
-
- buf->Allocate(&size);
- EXPECT_EQ(10, size);
- EXPECT_EQ(10, buf->GetLastAllocationOffset());
-
- EXPECT_FALSE(buf->CanAllocate());
-}
-
-TEST(ResourceBufferTest, Full) {
- scoped_refptr<ResourceBuffer> buf = new ResourceBuffer();
- EXPECT_TRUE(buf->Initialize(20, 10, 10));
-
- int size;
- buf->Allocate(&size);
- EXPECT_EQ(10, size);
-
- buf->Allocate(&size);
- EXPECT_EQ(10, size);
-
- // Full.
- EXPECT_FALSE(buf->CanAllocate());
-
- // Still full, even if there is a small hole at the end.
- buf->ShrinkLastAllocation(5);
- EXPECT_FALSE(buf->CanAllocate());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/loader/resource_controller.h b/chromium/content/browser/loader/resource_controller.h
index 82785346fef..55ecd8c28a5 100644
--- a/chromium/content/browser/loader/resource_controller.h
+++ b/chromium/content/browser/loader/resource_controller.h
@@ -5,8 +5,13 @@
#ifndef CONTENT_BROWSER_LOADER_RESOURCE_CONTROLLER_H_
#define CONTENT_BROWSER_LOADER_RESOURCE_CONTROLLER_H_
+#include "base/optional.h"
#include "content/common/content_export.h"
+namespace net {
+class HttpRequestHeaders;
+};
+
namespace content {
// Used to either resume a deferred resource load or cancel a resource load at
@@ -25,6 +30,12 @@ class CONTENT_EXPORT ResourceController {
// deferred. Guaranteed not to call back into the ResourceHandler, or destroy
// it, synchronously.
virtual void Resume() = 0;
+
+ // Similar to |Resume()| but can only be called if the request was previously
+ // redirected. |modified_request_headers| are changes applied to the request
+ // headers after updating them for the redirect.
+ virtual void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) = 0;
};
} // namespace content
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
index 1c1fb59e02c..061ad189c46 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/chromium/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -47,7 +47,6 @@
#include "content/browser/loader/mime_sniffing_resource_handler.h"
#include "content/browser/loader/mojo_async_resource_handler.h"
#include "content/browser/loader/null_resource_controller.h"
-#include "content/browser/loader/redirect_to_file_resource_handler.h"
#include "content/browser/loader/resource_loader.h"
#include "content/browser/loader/resource_message_filter.h"
#include "content/browser/loader/resource_request_info_impl.h"
@@ -55,7 +54,6 @@
#include "content/browser/loader/stream_resource_handler.h"
#include "content/browser/loader/throttling_resource_handler.h"
#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/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
@@ -112,11 +110,11 @@
#include "services/network/public/cpp/url_loader_completion_status.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "services/network/resource_scheduler.h"
+#include "services/network/throttling/scoped_throttling_token.h"
#include "services/network/url_loader_factory.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 "url/third_party/mozilla/url_parse.h"
@@ -171,12 +169,6 @@ void AbortRequestBeforeItStarts(
url_loader_client->OnComplete(status);
}
-void RemoveDownloadFileFromChildSecurityPolicy(int child_id,
- const base::FilePath& path) {
- ChildProcessSecurityPolicyImpl::GetInstance()->RevokeAllPermissionsForFile(
- child_id, path);
-}
-
bool IsValidatedSCT(
const net::SignedCertificateTimestampAndStatus& sct_status) {
return sct_status.status == net::ct::SCT_STATUS_OK;
@@ -193,6 +185,7 @@ PreviewsState DetermineEnabledPreviews(PreviewsState previews_to_allow,
net::URLRequest* request,
ResourceContext* resource_context,
bool is_main_frame) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
// 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 ||
@@ -324,8 +317,6 @@ ResourceDispatcherHostImpl::ResourceDispatcherHostImpl(
max_num_in_flight_requests_ * kMaxRequestsPerProcessRatio)),
max_outstanding_requests_cost_per_process_(
kMaxOutstandingRequestsCostPerProcess),
- largest_outstanding_request_count_seen_(0),
- largest_outstanding_request_per_process_count_seen_(0),
delegate_(nullptr),
loader_delegate_(nullptr),
allow_cross_origin_auth_prompt_(false),
@@ -557,7 +548,8 @@ scoped_refptr<LoginDelegate> ResourceDispatcherHostImpl::CreateLoginDelegate(
scoped_refptr<LoginDelegate> login_delegate =
GetContentClient()->browser()->CreateLoginDelegate(
auth_info, resource_request_info->GetWebContentsGetterForRequest(),
- is_request_for_main_frame, url,
+ request_id, is_request_for_main_frame, url,
+ request->response_headers(),
resource_request_info->first_auth_attempt(),
base::BindOnce(&ResourceDispatcherHostImpl::RunAuthRequiredCallback,
base::Unretained(this), request_id));
@@ -606,13 +598,6 @@ void ResourceDispatcherHostImpl::DidReceiveResponse(
network::ResourceResponse* response) {
ResourceRequestInfoImpl* info = loader->GetRequestInfo();
net::URLRequest* request = loader->request();
- if (request->was_fetched_via_proxy() &&
- request->was_fetched_via_spdy() &&
- request->url().SchemeIs(url::kHttpScheme)) {
- scheduler_->OnReceivedSpdyProxiedHttpResponse(
- info->GetChildID(), info->GetRouteID());
- }
-
if (delegate_)
delegate_->OnResponseStarted(request, info->GetContext(), response);
}
@@ -620,39 +605,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
- // older versions.
- base::UmaHistogramSparse("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,
- 50000000, 50);
- UMA_HISTOGRAM_CUSTOM_COUNTS("Net.ErrAborted.ReceivedBytes",
- loader->request()->GetTotalReceivedBytes(), 1,
- 50000000, 50);
- }
-
if (loader->request()->url().SchemeIsCryptographic()) {
- if (loader->request()->url().host_piece() == "www.google.com") {
- base::UmaHistogramSparse("Net.ErrorCodesForHTTPSGoogleMainFrame2",
- -loader->request()->status().error());
- }
-
- if (net::IsTLS13ExperimentHost(loader->request()->url().host_piece())) {
- base::UmaHistogramSparse("Net.ErrorCodesForTLS13ExperimentMainFrame",
- -loader->request()->status().error());
- }
-
int num_valid_scts = std::count_if(
loader->request()->ssl_info().signed_certificate_timestamps.begin(),
loader->request()->ssl_info().signed_certificate_timestamps.end(),
@@ -660,18 +615,6 @@ void ResourceDispatcherHostImpl::DidFinishLoading(ResourceLoader* loader) {
UMA_HISTOGRAM_COUNTS_100(
"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) {
- base::UmaHistogramSparse("Net.ErrorCodesForImages",
- -loader->request()->status().error());
- }
- // This enumeration has "2" appended to distinguish it from older versions.
- base::UmaHistogramSparse("Net.ErrorCodesForSubresources2",
- -loader->request()->status().error());
}
if (delegate_)
@@ -725,6 +668,7 @@ void ResourceDispatcherHostImpl::OnRequestResourceInternal(
int request_id,
bool is_sync_load,
const network::ResourceRequest& request_data,
+ uint32_t url_loader_options,
network::mojom::URLLoaderRequest mojo_request,
network::mojom::URLLoaderClientPtr url_loader_client,
const net::NetworkTrafficAnnotationTag& traffic_annotation) {
@@ -732,7 +676,7 @@ void ResourceDispatcherHostImpl::OnRequestResourceInternal(
requester_info->IsNavigationPreload() ||
requester_info->IsCertificateFetcherForSignedExchange());
BeginRequest(requester_info, request_id, request_data, is_sync_load,
- routing_id, std::move(mojo_request),
+ routing_id, url_loader_options, std::move(mojo_request),
std::move(url_loader_client), traffic_annotation);
}
@@ -756,6 +700,7 @@ void ResourceDispatcherHostImpl::BeginRequest(
const network::ResourceRequest& request_data,
bool is_sync_load,
int route_id,
+ uint32_t url_loader_options,
network::mojom::URLLoaderRequest mojo_request,
network::mojom::URLLoaderClientPtr url_loader_client,
const net::NetworkTrafficAnnotationTag& traffic_annotation) {
@@ -862,7 +807,8 @@ void ResourceDispatcherHostImpl::BeginRequest(
&ResourceDispatcherHostImpl::ContinuePendingBeginRequest,
base::Unretained(this), base::WrapRefCounted(requester_info),
request_id, request_data, is_sync_load, route_id,
- request_data.headers, base::Passed(std::move(mojo_request)),
+ request_data.headers, url_loader_options,
+ base::Passed(std::move(mojo_request)),
base::Passed(std::move(url_loader_client)),
base::Passed(std::move(blob_handles)), traffic_annotation));
return;
@@ -871,7 +817,7 @@ void ResourceDispatcherHostImpl::BeginRequest(
}
ContinuePendingBeginRequest(
requester_info, request_id, request_data, is_sync_load, route_id,
- request_data.headers, std::move(mojo_request),
+ request_data.headers, url_loader_options, std::move(mojo_request),
std::move(url_loader_client), std::move(blob_handles), traffic_annotation,
HeaderInterceptorResult::CONTINUE);
}
@@ -883,6 +829,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
bool is_sync_load,
int route_id,
const net::HttpRequestHeaders& headers,
+ uint32_t url_loader_options,
network::mojom::URLLoaderRequest mojo_request,
network::mojom::URLLoaderClientPtr url_loader_client,
BlobHandles blob_handles,
@@ -948,6 +895,7 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
new_request->set_site_for_cookies(request_data.site_for_cookies);
new_request->set_attach_same_site_cookies(
request_data.attach_same_site_cookies);
+ new_request->set_upgrade_if_insecure(request_data.upgrade_if_insecure);
// The initiator should normally be present, unless this is a navigation.
// Browser-initiated navigations don't have an initiator document, the
@@ -967,6 +915,11 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
new_request->SetExtraRequestHeaders(headers);
+ std::unique_ptr<network::ScopedThrottlingToken> throttling_token =
+ network::ScopedThrottlingToken::MaybeCreate(
+ new_request->net_log().source().id,
+ request_data.throttling_profile_id);
+
blob_context = GetBlobStorageContext(requester_info->blob_storage_context());
// Resolve elements from request_body and prepare upload data.
if (request_data.request_body.get()) {
@@ -1096,7 +1049,8 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
std::unique_ptr<ResourceHandler> handler = CreateResourceHandler(
requester_info.get(), new_request.get(), request_data, route_id, child_id,
- resource_context, std::move(mojo_request), std::move(url_loader_client));
+ resource_context, url_loader_options, std::move(mojo_request),
+ std::move(url_loader_client));
if (handler) {
RecordFetchRequestMode(request_data.url, request_data.method,
@@ -1104,7 +1058,8 @@ void ResourceDispatcherHostImpl::ContinuePendingBeginRequest(
const bool is_initiated_by_fetch_api =
request_data.fetch_request_context_type == REQUEST_CONTEXT_TYPE_FETCH;
BeginRequestInternal(std::move(new_request), std::move(handler),
- is_initiated_by_fetch_api);
+ is_initiated_by_fetch_api,
+ std::move(throttling_token));
}
}
@@ -1116,6 +1071,7 @@ ResourceDispatcherHostImpl::CreateResourceHandler(
int route_id,
int child_id,
ResourceContext* resource_context,
+ uint32_t url_loader_options,
network::mojom::URLLoaderRequest mojo_request,
network::mojom::URLLoaderClientPtr url_loader_client) {
DCHECK(requester_info->IsRenderer() ||
@@ -1124,15 +1080,10 @@ ResourceDispatcherHostImpl::CreateResourceHandler(
// Construct the IPC resource handler.
std::unique_ptr<ResourceHandler> handler;
handler = CreateBaseResourceHandler(
- request, std::move(mojo_request), std::move(url_loader_client),
+ request, url_loader_options, std::move(mojo_request),
+ std::move(url_loader_client),
static_cast<ResourceType>(request_data.resource_type));
- // The RedirectToFileResourceHandler depends on being next in the chain.
- if (request_data.download_to_file) {
- handler.reset(
- new RedirectToFileResourceHandler(std::move(handler), request));
- }
-
// Prefetches outlive their child process.
if (request_data.resource_type == RESOURCE_TYPE_PREFETCH) {
auto detachable_handler = std::make_unique<DetachableResourceHandler>(
@@ -1153,13 +1104,14 @@ ResourceDispatcherHostImpl::CreateResourceHandler(
std::unique_ptr<ResourceHandler>
ResourceDispatcherHostImpl::CreateBaseResourceHandler(
net::URLRequest* request,
+ uint32_t url_loader_options,
network::mojom::URLLoaderRequest mojo_request,
network::mojom::URLLoaderClientPtr url_loader_client,
ResourceType resource_type) {
std::unique_ptr<ResourceHandler> handler;
handler.reset(new MojoAsyncResourceHandler(
request, this, std::move(mojo_request), std::move(url_loader_client),
- resource_type, network::mojom::kURLLoadOptionNone));
+ resource_type, url_loader_options));
return handler;
}
@@ -1191,12 +1143,6 @@ ResourceDispatcherHostImpl::AddStandardHandlers(
&throttles);
}
- if (request->has_upload()) {
- // Request wake lock while uploading data.
- throttles.push_back(
- std::make_unique<WakeLockResourceThrottle>(request->url().host()));
- }
-
// The Clear-Site-Data throttle.
std::unique_ptr<ResourceThrottle> clear_site_data_throttle =
ClearSiteDataThrottle::MaybeCreateThrottleForRequest(request);
@@ -1255,41 +1201,6 @@ ResourceDispatcherHostImpl::AddStandardHandlers(
return handler;
}
-void ResourceDispatcherHostImpl::RegisterDownloadedTempFile(
- int child_id, int request_id, const base::FilePath& file_path) {
- scoped_refptr<ShareableFileReference> reference =
- ShareableFileReference::Get(file_path);
- DCHECK(reference.get());
-
- registered_temp_files_[child_id][request_id] = reference;
- ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
- child_id, reference->path());
-
- // When the temp file is deleted, revoke permissions that the renderer has
- // to that file. This covers an edge case where the file is deleted and then
- // the same name is re-used for some other purpose, we don't want the old
- // renderer to still have access to it.
- //
- // We do this when the file is deleted because the renderer can take a blob
- // reference to the temp file that outlives the url loaded that it was
- // loaded with to keep the file (and permissions) alive.
- reference->AddFinalReleaseCallback(
- base::BindOnce(&RemoveDownloadFileFromChildSecurityPolicy, child_id));
-}
-
-void ResourceDispatcherHostImpl::UnregisterDownloadedTempFile(
- int child_id, int request_id) {
- DeletableFilesMap& map = registered_temp_files_[child_id];
- DeletableFilesMap::iterator found = map.find(request_id);
- if (found == map.end())
- return;
-
- map.erase(found);
-
- // Note that we don't remove the security bits here. This will be done
- // when all file refs are deleted (see RegisterDownloadedTempFile).
-}
-
ResourceRequestInfoImpl* ResourceDispatcherHostImpl::CreateRequestInfo(
int child_id,
int render_view_route_id,
@@ -1353,7 +1264,6 @@ void ResourceDispatcherHostImpl::CancelRequestsForProcess(int child_id) {
const auto& map = keepalive_statistics_recorder_.per_process_records();
if (map.find(child_id) != map.end())
keepalive_statistics_recorder_.Unregister(child_id);
- registered_temp_files_.erase(child_id);
}
void ResourceDispatcherHostImpl::CancelRequestsForRoute(
@@ -1523,21 +1433,6 @@ ResourceDispatcherHostImpl::IncrementOutstandingRequestsCount(
DCHECK_GE(stats.num_requests, 0);
UpdateOutstandingRequestsStats(*info, stats);
- if (num_in_flight_requests_ > largest_outstanding_request_count_seen_) {
- largest_outstanding_request_count_seen_ = num_in_flight_requests_;
- UMA_HISTOGRAM_COUNTS_1M(
- "Net.ResourceDispatcherHost.OutstandingRequests.Total",
- largest_outstanding_request_count_seen_);
- }
-
- if (stats.num_requests >
- largest_outstanding_request_per_process_count_seen_) {
- largest_outstanding_request_per_process_count_seen_ = stats.num_requests;
- UMA_HISTOGRAM_COUNTS_1M(
- "Net.ResourceDispatcherHost.OutstandingRequests.PerProcess",
- largest_outstanding_request_per_process_count_seen_);
- }
-
return stats;
}
@@ -1571,11 +1466,7 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
ServiceWorkerNavigationHandleCore* service_worker_handle_core,
AppCacheNavigationHandleCore* appcache_handle_core,
uint32_t url_loader_options,
- GlobalRequestID* global_request_id) {
- // PlzNavigate: BeginNavigationRequest currently should only be used for the
- // browser-side navigations project.
- CHECK(IsBrowserSideNavigationEnabled());
-
+ const GlobalRequestID& global_request_id) {
DCHECK(url_loader_client.is_bound());
DCHECK(url_loader_request.is_pending());
@@ -1623,11 +1514,16 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
new_request->set_method(info.common_params.method);
new_request->set_site_for_cookies(info.site_for_cookies);
new_request->set_initiator(info.begin_params->initiator_origin);
+ new_request->set_upgrade_if_insecure(info.upgrade_if_insecure);
if (info.is_main_frame) {
new_request->set_first_party_url_policy(
net::URLRequest::UPDATE_FIRST_PARTY_URL_ON_REDIRECT);
}
+ std::unique_ptr<network::ScopedThrottlingToken> throttling_token =
+ network::ScopedThrottlingToken::MaybeCreate(
+ new_request->net_log().source().id, info.devtools_frame_token);
+
Referrer::SetReferrerForRequest(new_request.get(),
info.common_params.referrer);
@@ -1684,7 +1580,7 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
-1, // route_id
info.frame_tree_node_id,
ChildProcessHost::kInvalidUniqueID, // plugin_child_id
- MakeRequestID(),
+ global_request_id.request_id,
-1, // request_data.render_frame_id,
info.is_main_frame, resource_type, info.common_params.transition,
false, // is download
@@ -1713,8 +1609,6 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
// Request takes ownership.
extra_info->AssociateWithRequest(new_request.get());
- *global_request_id = extra_info->GetGlobalRequestID();
-
if (new_request->url().SchemeIs(url::kBlobScheme)) {
// Hang on to a reference to ensure the blob is not released prior
// to the job being started.
@@ -1760,7 +1654,8 @@ void ResourceDispatcherHostImpl::BeginNavigationRequest(
RecordFetchRequestMode(new_request->url(), new_request->method(),
network::mojom::FetchRequestMode::kNavigate);
BeginRequestInternal(std::move(new_request), std::move(handler),
- false /* is_initiated_by_fetch_api */);
+ false /* is_initiated_by_fetch_api */,
+ std::move(throttling_token));
}
void ResourceDispatcherHostImpl::SetLoaderDelegate(
@@ -1782,8 +1677,6 @@ void ResourceDispatcherHostImpl::OnRequestResourceWithMojo(
network::mojom::URLLoaderRequest mojo_request,
network::mojom::URLLoaderClientPtr url_loader_client,
const net::NetworkTrafficAnnotationTag& traffic_annotation) {
- DCHECK_EQ(network::mojom::kURLLoadOptionNone,
- options & ~network::mojom::kURLLoadOptionSynchronous);
if (!url_loader_client) {
VLOG(1) << "Killed renderer for null client";
bad_message::ReceivedBadMessage(requester_info->filter(),
@@ -1792,7 +1685,8 @@ void ResourceDispatcherHostImpl::OnRequestResourceWithMojo(
}
bool is_sync_load = options & network::mojom::kURLLoadOptionSynchronous;
OnRequestResourceInternal(requester_info, routing_id, request_id,
- is_sync_load, request, std::move(mojo_request),
+ is_sync_load, request, options,
+ std::move(mojo_request),
std::move(url_loader_client), traffic_annotation);
}
@@ -1819,7 +1713,8 @@ int ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(
void ResourceDispatcherHostImpl::BeginRequestInternal(
std::unique_ptr<net::URLRequest> request,
std::unique_ptr<ResourceHandler> handler,
- bool is_initiated_by_fetch_api) {
+ bool is_initiated_by_fetch_api,
+ std::unique_ptr<network::ScopedThrottlingToken> throttling_token) {
DCHECK(!request->is_pending());
ResourceRequestInfoImpl* info =
ResourceRequestInfoImpl::ForRequest(request.get());
@@ -1895,8 +1790,9 @@ void ResourceDispatcherHostImpl::BeginRequestInternal(
}
ResourceContext* resource_context = info->GetContext();
- std::unique_ptr<ResourceLoader> loader(new ResourceLoader(
- std::move(request), std::move(handler), this, resource_context));
+ std::unique_ptr<ResourceLoader> loader(
+ new ResourceLoader(std::move(request), std::move(handler), this,
+ resource_context, std::move(throttling_token)));
GlobalFrameRoutingId id(info->GetChildID(), info->GetRenderFrameID());
BlockedLoadersMap::const_iterator iter = blocked_loaders_map_.find(id);
@@ -1966,7 +1862,8 @@ void ResourceDispatcherHostImpl::BeginURLRequest(
true /* force_download */, true /* is_new_request */);
}
BeginRequestInternal(std::move(request), std::move(handler),
- false /* is_initiated_by_fetch_api */);
+ false /* is_initiated_by_fetch_api */,
+ nullptr /* throttling_token */);
}
int ResourceDispatcherHostImpl::MakeRequestID() {
@@ -1974,6 +1871,10 @@ int ResourceDispatcherHostImpl::MakeRequestID() {
return --request_id_;
}
+GlobalRequestID ResourceDispatcherHostImpl::MakeGlobalRequestID() {
+ return GlobalRequestID(ChildProcessHost::kInvalidUniqueID, MakeRequestID());
+}
+
void ResourceDispatcherHostImpl::CancelRequestFromRenderer(
GlobalRequestID request_id) {
ResourceLoader* loader = GetLoader(request_id);
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_impl.h b/chromium/content/browser/loader/resource_dispatcher_host_impl.h
index 388f7f84a00..b8a81809fff 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_impl.h
+++ b/chromium/content/browser/loader/resource_dispatcher_host_impl.h
@@ -47,7 +47,6 @@
#include "url/gurl.h"
namespace base {
-class FilePath;
class OneShotTimer;
}
@@ -59,11 +58,11 @@ class URLRequestContextGetter;
namespace network {
class ResourceScheduler;
+class ScopedThrottlingToken;
} // namespace network
namespace storage {
class FileSystemContext;
-class ShareableFileReference;
}
namespace content {
@@ -182,15 +181,6 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
void CancelBlockedRequestsForRoute(
const GlobalFrameRoutingId& global_routing_id);
- // Maintains a collection of temp files created in support of
- // the download_to_file capability. Used to grant access to the
- // child process and to defer deletion of the file until it's
- // no longer needed.
- void RegisterDownloadedTempFile(
- int child_id, int request_id,
- const base::FilePath& file_path);
- void UnregisterDownloadedTempFile(int child_id, int request_id);
-
// Indicates whether third-party sub-content can pop-up HTTP basic auth
// dialog boxes.
bool allow_cross_origin_auth_prompt();
@@ -240,9 +230,8 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
void FinishedWithResourcesForRequest(net::URLRequest* request);
// PlzNavigate: Begins a request for NavigationURLLoader. |loader| is the
- // loader to attach to the leaf resource handler.
- // After calling this function, |global_request_id| will contains the
- // request's global id.
+ // loader to attach to the leaf resource handler. |global_request_id| needs to
+ // be created by MakeGlobalRequestID() before calling this method.
void BeginNavigationRequest(
ResourceContext* resource_context,
net::URLRequestContext* request_context,
@@ -254,7 +243,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
ServiceWorkerNavigationHandleCore* service_worker_handle_core,
AppCacheNavigationHandleCore* appcache_handle_core,
uint32_t url_loader_options,
- GlobalRequestID* global_request_id);
+ const GlobalRequestID& global_request_id);
int num_in_flight_requests_for_testing() const {
return num_in_flight_requests_;
@@ -311,6 +300,11 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
// of |request_id_| for the details. Must be called on the IO thread.
int MakeRequestID();
+ // Creates a new global request ID for browser initiated requests. The ID
+ // is consistent with the request id created by MakeRequestID(). Must be
+ // called on the IO thread.
+ GlobalRequestID MakeGlobalRequestID();
+
// Cancels a request as requested by a renderer. This function is called when
// a mojo connection is lost.
// Note that this cancel is subtly different from the other CancelRequest
@@ -420,9 +414,11 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
void OnShutdown();
// Helper function for URL requests.
- void BeginRequestInternal(std::unique_ptr<net::URLRequest> request,
- std::unique_ptr<ResourceHandler> handler,
- bool is_initiated_by_fetch_api);
+ void BeginRequestInternal(
+ std::unique_ptr<net::URLRequest> request,
+ std::unique_ptr<ResourceHandler> handler,
+ bool is_initiated_by_fetch_api,
+ std::unique_ptr<network::ScopedThrottlingToken> throttling_token);
void StartLoading(ResourceRequestInfoImpl* info,
std::unique_ptr<ResourceLoader> loader);
@@ -539,6 +535,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
int request_id,
bool is_sync_load,
const network::ResourceRequest& request_data,
+ uint32_t url_loader_options,
network::mojom::URLLoaderRequest mojo_request,
network::mojom::URLLoaderClientPtr url_loader_client,
const net::NetworkTrafficAnnotationTag& traffic_annotation);
@@ -550,6 +547,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
const network::ResourceRequest& request_data,
bool is_sync_load,
int route_id,
+ uint32_t url_loader_options,
network::mojom::URLLoaderRequest mojo_request,
network::mojom::URLLoaderClientPtr url_loader_client,
const net::NetworkTrafficAnnotationTag& traffic_annotation);
@@ -569,6 +567,7 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
bool is_sync_load,
int route_id,
const net::HttpRequestHeaders& headers,
+ uint32_t url_loader_options,
network::mojom::URLLoaderRequest mojo_request,
network::mojom::URLLoaderClientPtr url_loader_client,
BlobHandles blob_handles,
@@ -584,12 +583,14 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
int route_id,
int child_id,
ResourceContext* resource_context,
+ uint32_t url_loader_options,
network::mojom::URLLoaderRequest mojo_request,
network::mojom::URLLoaderClientPtr url_loader_client);
// Creates either MojoAsyncResourceHandler or AsyncResourceHandler.
std::unique_ptr<ResourceHandler> CreateBaseResourceHandler(
net::URLRequest* request,
+ uint32_t url_loader_options,
network::mojom::URLLoaderRequest mojo_request,
network::mojom::URLLoaderClientPtr url_loader_client,
ResourceType resource_type);
@@ -667,15 +668,6 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
LoaderMap pending_loaders_;
- // Collection of temp files downloaded for child processes via
- // the download_to_file mechanism. We avoid deleting them until
- // the client no longer needs them.
- typedef std::map<int, scoped_refptr<storage::ShareableFileReference> >
- DeletableFilesMap; // key is request id
- typedef std::map<int, DeletableFilesMap>
- RegisteredTempFiles; // key is child process id
- RegisteredTempFiles registered_temp_files_;
-
// A timer that periodically calls UpdateLoadInfo while |pending_loaders_| is
// not empty, at least one RenderViewHost is loading, and not waiting on an
// ACK from the UI thread for the last sent LoadInfoList.
@@ -733,12 +725,6 @@ class CONTENT_EXPORT ResourceDispatcherHostImpl
// kAvgBytesPerOutstandingRequest)
int max_outstanding_requests_cost_per_process_;
- // Largest number of outstanding requests seen so far across all processes.
- int largest_outstanding_request_count_seen_;
-
- // Largest number of outstanding requests seen so far in any single process.
- int largest_outstanding_request_per_process_count_seen_;
-
// Time of the last user gesture. Stored so that we can add a load
// flag to requests occurring soon after a gesture to indicate they
// may be because of explicit user action.
diff --git a/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc b/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
index e576ad75157..d8d744e64ff 100644
--- a/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/chromium/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -27,7 +27,6 @@
#include "content/browser/download/download_resource_handler.h"
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/loader/detachable_resource_handler.h"
-#include "content/browser/loader/downloaded_temp_file_impl.h"
#include "content/browser/loader/navigation_url_loader.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/loader/resource_loader.h"
@@ -78,6 +77,8 @@
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/public/cpp/resource_request.h"
+#include "services/network/resource_scheduler.h"
+#include "services/network/resource_scheduler_params_manager.h"
#include "services/network/test/test_url_loader_client.h"
#include "storage/browser/blob/shareable_file_reference.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -104,7 +105,6 @@ static network::ResourceRequest CreateResourceRequest(const char* method,
request.plugin_child_id = -1;
request.resource_type = type;
request.appcache_host_id = kAppCacheNoHostId;
- request.download_to_file = false;
request.should_reset_appcache = false;
request.is_main_frame = true;
request.transition_type = ui::PAGE_TRANSITION_LINK;
@@ -818,7 +818,9 @@ class ResourceDispatcherHostTest : public testing::Test {
std::unique_ptr<NavigationRequestInfo> request_info(
new NavigationRequestInfo(common_params, std::move(begin_params), url,
true, false, false, -1, false, false, false,
- nullptr, base::UnguessableToken::Create()));
+ false, nullptr,
+ base::UnguessableToken::Create(),
+ base::UnguessableToken::Create()));
std::unique_ptr<NavigationURLLoader> test_loader =
NavigationURLLoader::Create(
browser_context_->GetResourceContext(),
@@ -838,6 +840,18 @@ class ResourceDispatcherHostTest : public testing::Test {
request_info->detachable_handler()->is_detached();
}
+ void SetMaxDelayableRequests(size_t max_delayable_requests) {
+ network::ResourceSchedulerParamsManager::ParamsForNetworkQualityContainer c;
+ for (int i = 0; i != net::EFFECTIVE_CONNECTION_TYPE_LAST; ++i) {
+ auto type = static_cast<net::EffectiveConnectionType>(i);
+ c[type] =
+ network::ResourceSchedulerParamsManager::ParamsForNetworkQuality(
+ max_delayable_requests, 0.0, false);
+ }
+ host_.scheduler()->SetResourceSchedulerParamsManagerForTests(
+ network::ResourceSchedulerParamsManager(c));
+ }
+
content::TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<TestBrowserContext> browser_context_;
std::unique_ptr<TestURLRequestJobFactory> job_factory_;
@@ -1467,6 +1481,7 @@ TEST_F(ResourceDispatcherHostTest, CancelRequestsOnRenderFrameDeleted) {
host_.SetDelegate(&delegate);
host_.OnRenderViewHostCreated(filter_->child_id(), 0,
request_context_getter_.get());
+ SetMaxDelayableRequests(1);
// One RenderView issues a high priority request and a low priority one. Both
// should be started.
@@ -2208,138 +2223,6 @@ TEST_F(ResourceDispatcherHostTest, DataSentBeforeDetach) {
EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code);
}
-// Tests the dispatcher host's temporary file management in the mojo-enabled
-// loading.
-TEST_F(ResourceDispatcherHostTest, RegisterDownloadedTempFileWithMojo) {
- const int kRequestID = 1;
-
- // Create a temporary file.
- base::FilePath file_path;
- ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
- EXPECT_TRUE(base::PathExists(file_path));
- scoped_refptr<ShareableFileReference> deletable_file =
- ShareableFileReference::GetOrCreate(
- file_path, ShareableFileReference::DELETE_ON_FINAL_RELEASE,
- base::CreateSingleThreadTaskRunnerWithTraits({base::MayBlock()})
- .get());
-
- // Not readable.
- EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
- filter_->child_id(), file_path));
-
- // Register it for a resource request.
- auto downloaded_file =
- DownloadedTempFileImpl::Create(filter_->child_id(), kRequestID);
- network::mojom::DownloadedTempFilePtr downloaded_file_ptr =
- DownloadedTempFileImpl::Create(filter_->child_id(), kRequestID);
- host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
-
- // Should be readable now.
- EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
- filter_->child_id(), file_path));
-
- // The child releases from the request.
- downloaded_file_ptr = nullptr;
- content::RunAllTasksUntilIdle();
-
- // Still readable because there is another reference to the file. (The child
- // may take additional blob references.)
- EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
- filter_->child_id(), file_path));
-
- // Release extra references and wait for the file to be deleted. (This relies
- // on the delete happening on the FILE thread which is mapped to main thread
- // in this test.)
- deletable_file = nullptr;
- content::RunAllTasksUntilIdle();
-
- // The file is no longer readable to the child and has been deleted.
- EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
- filter_->child_id(), file_path));
- EXPECT_FALSE(base::PathExists(file_path));
-}
-
-// Tests that temporary files held on behalf of child processes are released
-// when the child process dies.
-TEST_F(ResourceDispatcherHostTest, ReleaseTemporiesOnProcessExit) {
- const int kRequestID = 1;
-
- // Create a temporary file.
- base::FilePath file_path;
- ASSERT_TRUE(base::CreateTemporaryFile(&file_path));
- scoped_refptr<ShareableFileReference> deletable_file =
- ShareableFileReference::GetOrCreate(
- file_path, ShareableFileReference::DELETE_ON_FINAL_RELEASE,
- base::CreateSingleThreadTaskRunnerWithTraits({base::MayBlock()})
- .get());
-
- // Register it for a resource request.
- host_.RegisterDownloadedTempFile(filter_->child_id(), kRequestID, file_path);
- deletable_file = nullptr;
-
- // Should be readable now.
- EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
- filter_->child_id(), file_path));
-
- // Let the process die.
- filter_->OnChannelClosing();
- content::RunAllTasksUntilIdle();
-
- // The file is no longer readable to the child and has been deleted.
- EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
- filter_->child_id(), file_path));
- EXPECT_FALSE(base::PathExists(file_path));
-}
-
-TEST_F(ResourceDispatcherHostTest, DownloadToFile) {
- // Make a request which downloads to file.
- network::mojom::URLLoaderPtr loader;
- network::TestURLLoaderClient client;
- network::ResourceRequest request = CreateResourceRequest(
- "GET", RESOURCE_TYPE_SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
- request.download_to_file = true;
- filter_->CreateLoaderAndStart(
- mojo::MakeRequest(&loader), 0, 1, network::mojom::kURLLoadOptionNone,
- request, client.CreateInterfacePtr(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- content::RunAllTasksUntilIdle();
-
- // The request should contain the following messages:
- // ReceivedResponse (indicates headers received and filename)
- // DataDownloaded* (bytes downloaded and total length)
- // RequestComplete (request is done)
- client.RunUntilComplete();
- EXPECT_FALSE(client.response_head().download_file_path.empty());
- EXPECT_EQ(net::URLRequestTestJob::test_data_1().size(),
- static_cast<size_t>(client.download_data_length()));
- EXPECT_EQ(net::OK, client.completion_status().error_code);
-
- // Verify that the data ended up in the temporary file.
- std::string contents;
- ASSERT_TRUE(base::ReadFileToString(client.response_head().download_file_path,
- &contents));
- EXPECT_EQ(net::URLRequestTestJob::test_data_1(), contents);
-
- // The file should be readable by the child.
- EXPECT_TRUE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
- filter_->child_id(), client.response_head().download_file_path));
-
- // When the renderer releases the file, it should be deleted.
- // RunUntilIdle doesn't work because base::WorkerPool is involved.
- ShareableFileReleaseWaiter waiter(client.response_head().download_file_path);
- client.TakeDownloadedTempFile();
- content::RunAllTasksUntilIdle();
- waiter.Wait();
- // The release callback runs before the delete is scheduled, so pump the
- // message loop for the delete itself. (This relies on the delete happening on
- // the FILE thread which is mapped to main thread in this test.)
- content::RunAllTasksUntilIdle();
-
- EXPECT_FALSE(base::PathExists(client.response_head().download_file_path));
- EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
- filter_->child_id(), client.response_head().download_file_path));
-}
-
WebContents* WebContentsBinder(WebContents* rv) { return rv; }
// Tests GetLoadInfoForAllRoutes when there are 3 requests from the same
diff --git a/chromium/content/browser/loader/resource_handler.cc b/chromium/content/browser/loader/resource_handler.cc
index a507567e950..c58d7641e4d 100644
--- a/chromium/content/browser/loader/resource_handler.cc
+++ b/chromium/content/browser/loader/resource_handler.cc
@@ -44,6 +44,11 @@ void ResourceHandler::Resume() {
ReleaseController()->Resume();
}
+void ResourceHandler::ResumeForRedirect(
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
+ ReleaseController()->ResumeForRedirect(modified_request_headers);
+}
+
void ResourceHandler::Cancel() {
ReleaseController()->Cancel();
}
diff --git a/chromium/content/browser/loader/resource_handler.h b/chromium/content/browser/loader/resource_handler.h
index b9b6ebf554d..bb60dbe0d97 100644
--- a/chromium/content/browser/loader/resource_handler.h
+++ b/chromium/content/browser/loader/resource_handler.h
@@ -138,12 +138,6 @@ class CONTENT_EXPORT ResourceHandler {
const net::URLRequestStatus& status,
std::unique_ptr<ResourceController> controller) = 0;
- // This notification is synthesized by the RedirectToFileResourceHandler
- // to indicate progress of 'download_to_file' requests. OnReadCompleted
- // calls are consumed by the RedirectToFileResourceHandler and replaced
- // with OnDataDownloaded calls.
- virtual void OnDataDownloaded(int bytes_downloaded) = 0;
-
protected:
explicit ResourceHandler(net::URLRequest* request);
@@ -165,6 +159,8 @@ class CONTENT_EXPORT ResourceHandler {
// These call the corresponding methods on the ResourceController previously
// passed to HoldController and then destroy it.
void Resume();
+ void ResumeForRedirect(
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers);
void Cancel();
void CancelWithError(int error_code);
diff --git a/chromium/content/browser/loader/resource_hints_impl.cc b/chromium/content/browser/loader/resource_hints_impl.cc
index 6365bc19995..3ebe0570196 100644
--- a/chromium/content/browser/loader/resource_hints_impl.cc
+++ b/chromium/content/browser/loader/resource_hints_impl.cc
@@ -6,11 +6,10 @@
#include "base/memory/ref_counted.h"
#include "base/trace_event/trace_event.h"
-#include "content/browser/loader/resource_dispatcher_host_impl.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_hints.h"
#include "net/base/address_list.h"
#include "net/base/load_flags.h"
-#include "net/dns/host_resolver.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_info.h"
#include "net/http/http_stream_factory.h"
@@ -24,18 +23,7 @@ namespace content {
namespace {
-class RequestHolder {
- public:
- std::unique_ptr<net::HostResolver::Request>* GetRequest() {
- return &request_;
- }
-
- private:
- std::unique_ptr<net::HostResolver::Request> request_;
-};
-
-void OnResolveComplete(std::unique_ptr<RequestHolder> request_holder,
- std::unique_ptr<net::AddressList> addresses,
+void OnResolveComplete(std::unique_ptr<net::AddressList> addresses,
const net::CompletionCallback& callback,
int result) {
// Plumb the resolution result into the callback if future consumers want
@@ -50,9 +38,7 @@ void PreconnectUrl(net::URLRequestContextGetter* getter,
const GURL& site_for_cookies,
int count,
bool allow_credentials) {
- DCHECK(ResourceDispatcherHostImpl::Get()
- ->io_thread_task_runner()
- ->BelongsToCurrentThread());
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(getter);
TRACE_EVENT2("net", "PreconnectUrl", "url", url.spec(), "count", count);
@@ -74,6 +60,9 @@ void PreconnectUrl(net::URLRequestContextGetter* getter,
user_agent);
net::NetworkDelegate* delegate = request_context->network_delegate();
+ // NetworkDelegate is not set in tests.
+ if (!delegate)
+ return;
if (delegate->CanEnablePrivacyMode(url, site_for_cookies))
request_info.privacy_mode = net::PRIVACY_MODE_ENABLED;
@@ -93,10 +82,9 @@ void PreconnectUrl(net::URLRequestContextGetter* getter,
int PreresolveUrl(net::URLRequestContextGetter* getter,
const GURL& url,
- const net::CompletionCallback& callback) {
- DCHECK(ResourceDispatcherHostImpl::Get()
- ->io_thread_task_runner()
- ->BelongsToCurrentThread());
+ const net::CompletionCallback& callback,
+ std::unique_ptr<net::HostResolver::Request>* out_request) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(getter);
TRACE_EVENT1("net", "PreresolveUrl", "url", url.spec());
@@ -104,21 +92,17 @@ int PreresolveUrl(net::URLRequestContextGetter* getter,
if (!request_context)
return net::ERR_CONTEXT_SHUT_DOWN;
- 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.
+ // Save raw pointers before the unique_ptr is invalidated by base::Passed().
net::AddressList* raw_addresses = addresses.get();
- std::unique_ptr<net::HostResolver::Request>* out_request =
- request_holder->GetRequest();
net::HostResolver* resolver = request_context->host_resolver();
net::HostResolver::RequestInfo resolve_info(net::HostPortPair::FromURL(url));
resolve_info.set_is_speculative(true);
return resolver->Resolve(
resolve_info, net::IDLE, raw_addresses,
- base::Bind(&OnResolveComplete, base::Passed(&request_holder),
- base::Passed(&addresses), callback),
+ base::Bind(&OnResolveComplete, base::Passed(&addresses), callback),
out_request, net::NetLogWithSource());
}
diff --git a/chromium/content/browser/loader/resource_loader.cc b/chromium/content/browser/loader/resource_loader.cc
index c06232582ab..2435233851b 100644
--- a/chromium/content/browser/loader/resource_loader.cc
+++ b/chromium/content/browser/loader/resource_loader.cc
@@ -43,6 +43,7 @@
#include "net/url_request/url_request_status.h"
#include "services/network/loader_util.h"
#include "services/network/public/cpp/resource_response.h"
+#include "services/network/throttling/scoped_throttling_token.h"
#include "url/url_constants.h"
using base::TimeDelta;
@@ -84,6 +85,8 @@ void PopulateResourceResponse(
response->head.socket_address = response_info.socket_address;
response->head.was_fetched_via_proxy = request->was_fetched_via_proxy();
response->head.network_accessed = response_info.network_accessed;
+ response->head.async_revalidation_requested =
+ response_info.async_revalidation_requested;
const content::ResourceRequestInfo* request_info =
content::ResourceRequestInfo::ForRequest(request);
if (request_info) {
@@ -152,7 +155,15 @@ class ResourceLoader::Controller : public ResourceController {
// ResourceController implementation:
void Resume() override {
MarkAsUsed();
- resource_loader_->Resume(true /* called_from_resource_controller */);
+ resource_loader_->Resume(true /* called_from_resource_controller */,
+ base::nullopt);
+ }
+
+ void ResumeForRedirect(const base::Optional<net::HttpRequestHeaders>&
+ modified_request_headers) override {
+ MarkAsUsed();
+ resource_loader_->Resume(true /* called_from_resource_controller */,
+ modified_request_headers);
}
void Cancel() override {
@@ -209,7 +220,8 @@ class ResourceLoader::ScopedDeferral {
// If Resume() was called, it just advanced the state without doing
// anything. Go ahead and resume the request now.
if (old_deferred_stage == DEFERRED_NONE)
- resource_loader_->Resume(false /* called_from_resource_controller */);
+ resource_loader_->Resume(false /* called_from_resource_controller */,
+ base::nullopt);
}
private:
@@ -219,10 +231,12 @@ class ResourceLoader::ScopedDeferral {
DISALLOW_COPY_AND_ASSIGN(ScopedDeferral);
};
-ResourceLoader::ResourceLoader(std::unique_ptr<net::URLRequest> request,
- std::unique_ptr<ResourceHandler> handler,
- ResourceLoaderDelegate* delegate,
- ResourceContext* resource_context)
+ResourceLoader::ResourceLoader(
+ std::unique_ptr<net::URLRequest> request,
+ std::unique_ptr<ResourceHandler> handler,
+ ResourceLoaderDelegate* delegate,
+ ResourceContext* resource_context,
+ std::unique_ptr<network::ScopedThrottlingToken> throttling_token)
: deferred_stage_(DEFERRED_NONE),
request_(std::move(request)),
handler_(std::move(handler)),
@@ -231,6 +245,7 @@ ResourceLoader::ResourceLoader(std::unique_ptr<net::URLRequest> request,
started_request_(false),
times_cancelled_after_request_start_(0),
resource_context_(resource_context),
+ throttling_token_(std::move(throttling_token)),
weak_ptr_factory_(this) {
request_->set_delegate(this);
handler_->SetDelegate(this);
@@ -515,9 +530,13 @@ void ResourceLoader::CancelCertificateSelection() {
request_->CancelWithError(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
}
-void ResourceLoader::Resume(bool called_from_resource_controller) {
+void ResourceLoader::Resume(
+ bool called_from_resource_controller,
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
DeferredStage stage = deferred_stage_;
deferred_stage_ = DEFERRED_NONE;
+ DCHECK(!modified_request_headers.has_value() || stage == DEFERRED_REDIRECT)
+ << "modified_request_headers can only be used with redirects";
switch (stage) {
case DEFERRED_NONE:
NOTREACHED();
@@ -536,7 +555,7 @@ void ResourceLoader::Resume(bool called_from_resource_controller) {
// URLRequest::Start completes asynchronously, so starting the request now
// won't result in synchronously calling into a ResourceHandler, if this
// was called from Resume().
- FollowDeferredRedirectInternal();
+ FollowDeferredRedirectInternal(modified_request_headers);
break;
case DEFERRED_ON_WILL_READ:
// Always post a task, as synchronous resumes don't go through this
@@ -611,8 +630,6 @@ 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);
@@ -664,14 +681,18 @@ void ResourceLoader::CancelRequestInternal(int error, bool from_renderer) {
}
}
-void ResourceLoader::FollowDeferredRedirectInternal() {
+void ResourceLoader::FollowDeferredRedirectInternal(
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
DCHECK(!deferred_redirect_url_.is_empty());
GURL redirect_url = deferred_redirect_url_;
deferred_redirect_url_ = GURL();
if (delegate_->HandleExternalProtocol(this, redirect_url)) {
+ DCHECK(!modified_request_headers.has_value())
+ << "ResourceLoaderDelegate::HandleExternalProtocol() with modified "
+ "headers was not supported yet. crbug.com/845683";
Cancel();
} else {
- request_->FollowDeferredRedirect();
+ request_->FollowDeferredRedirect(modified_request_headers);
}
}
@@ -797,7 +818,6 @@ void ResourceLoader::ResponseCompleted() {
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
DVLOG(1) << "ResponseCompleted: " << request_->url().spec();
- RecordHistograms();
ScopedDeferral scoped_deferral(this, DEFERRED_FINISH);
handler_->OnResponseCompleted(request_->status(),
@@ -810,71 +830,6 @@ void ResourceLoader::CallDidFinishLoading() {
delegate_->DidFinishLoading(this);
}
-void ResourceLoader::RecordHistograms() {
- ResourceRequestInfoImpl* info = GetRequestInfo();
- if (request_->response_info().network_accessed) {
- if (info->GetResourceType() == RESOURCE_TYPE_MAIN_FRAME) {
- UMA_HISTOGRAM_ENUMERATION("Net.HttpResponseInfo.ConnectionInfo.MainFrame",
- request_->response_info().connection_info,
- net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS);
- } else {
- UMA_HISTOGRAM_ENUMERATION(
- "Net.HttpResponseInfo.ConnectionInfo.SubResource",
- request_->response_info().connection_info,
- net::HttpResponseInfo::NUM_OF_CONNECTION_INFOS);
- }
- }
-
- if (request_->load_flags() & net::LOAD_PREFETCH) {
- // Note that RESOURCE_TYPE_PREFETCH requests are a subset of
- // net::LOAD_PREFETCH requests. In the histograms below, "Prefetch" means
- // RESOURCE_TYPE_PREFETCH and "LoadPrefetch" means net::LOAD_PREFETCH.
- bool is_resource_type_prefetch =
- info->GetResourceType() == RESOURCE_TYPE_PREFETCH;
- PrefetchStatus prefetch_status = STATUS_UNDEFINED;
- TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time();
-
- switch (request_->status().status()) {
- case net::URLRequestStatus::SUCCESS:
- if (request_->was_cached()) {
- prefetch_status = request_->response_info().unused_since_prefetch
- ? STATUS_SUCCESS_ALREADY_PREFETCHED
- : STATUS_SUCCESS_FROM_CACHE;
- if (is_resource_type_prefetch) {
- UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentPrefetchingFromCache",
- total_time);
- }
- } else {
- prefetch_status = STATUS_SUCCESS_FROM_NETWORK;
- if (is_resource_type_prefetch) {
- UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentPrefetchingFromNetwork",
- total_time);
- }
- }
- break;
- case net::URLRequestStatus::CANCELED:
- prefetch_status = STATUS_CANCELED;
- if (is_resource_type_prefetch)
- UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeBeforeCancel", total_time);
- break;
- case net::URLRequestStatus::IO_PENDING:
- case net::URLRequestStatus::FAILED:
- prefetch_status = STATUS_UNDEFINED;
- break;
- }
-
- UMA_HISTOGRAM_ENUMERATION("Net.LoadPrefetch.Pattern", prefetch_status,
- STATUS_MAX);
- if (is_resource_type_prefetch) {
- UMA_HISTOGRAM_ENUMERATION("Net.Prefetch.Pattern", prefetch_status,
- STATUS_MAX);
- }
- } else if (request_->response_info().unused_since_prefetch) {
- TimeDelta total_time = base::TimeTicks::Now() - request_->creation_time();
- UMA_HISTOGRAM_TIMES("Net.Prefetch.TimeSpentOnPrefetchHit", total_time);
- }
-}
-
void ResourceLoader::SetRawResponseHeaders(
scoped_refptr<const net::HttpResponseHeaders> headers) {
raw_response_headers_ = headers;
diff --git a/chromium/content/browser/loader/resource_loader.h b/chromium/content/browser/loader/resource_loader.h
index 93ea0021af1..bbd241e28ed 100644
--- a/chromium/content/browser/loader/resource_loader.h
+++ b/chromium/content/browser/loader/resource_loader.h
@@ -25,6 +25,10 @@ class HttpResponseHeaders;
class X509Certificate;
}
+namespace network {
+class ScopedThrottlingToken;
+}
+
namespace content {
class LoginDelegate;
class ResourceHandler;
@@ -39,10 +43,12 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate,
public SSLClientAuthHandler::Delegate,
public ResourceHandler::Delegate {
public:
- ResourceLoader(std::unique_ptr<net::URLRequest> request,
- std::unique_ptr<ResourceHandler> handler,
- ResourceLoaderDelegate* delegate,
- ResourceContext* resource_context);
+ ResourceLoader(
+ std::unique_ptr<net::URLRequest> request,
+ std::unique_ptr<ResourceHandler> handler,
+ ResourceLoaderDelegate* delegate,
+ ResourceContext* resource_context,
+ std::unique_ptr<network::ScopedThrottlingToken> throttling_token);
~ResourceLoader() override;
void StartRequest();
@@ -92,14 +98,17 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate,
// |called_from_resource_controller| is true if called directly from a
// ResourceController, in which case |resource_handler_| must not be invoked
// or destroyed synchronously to avoid re-entrancy issues, and false
- // otherwise.
- void Resume(bool called_from_resource_controller);
+ // otherwise. |modified_request_headers| is used for redirects only.
+ void Resume(
+ bool called_from_resource_controller,
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers);
void Cancel();
void CancelWithError(int error_code);
void StartRequestInternal();
void CancelRequestInternal(int error, bool from_renderer);
- void FollowDeferredRedirectInternal();
+ void FollowDeferredRedirectInternal(
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers);
void CompleteResponseStarted();
// If |handle_result_async| is true, the result of the following read will be
// handled asynchronously if it completes synchronously, unless it's EOF or an
@@ -112,7 +121,6 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate,
void CompleteRead(int bytes_read);
void ResponseCompleted();
void CallDidFinishLoading();
- void RecordHistograms();
void SetRawResponseHeaders(
scoped_refptr<const net::HttpResponseHeaders> headers);
@@ -177,6 +185,8 @@ class CONTENT_EXPORT ResourceLoader : public net::URLRequest::Delegate,
ResourceContext* resource_context_;
+ std::unique_ptr<network::ScopedThrottlingToken> throttling_token_;
+
bool should_pause_reading_body_ = false;
// The request is not deferred (i.e., DEFERRED_NONE) and is ready to read more
// response body data. However, reading is paused because of
diff --git a/chromium/content/browser/loader/resource_loader_unittest.cc b/chromium/content/browser/loader/resource_loader_unittest.cc
index 469e35d26be..aeae17a85e5 100644
--- a/chromium/content/browser/loader/resource_loader_unittest.cc
+++ b/chromium/content/browser/loader/resource_loader_unittest.cc
@@ -59,6 +59,7 @@
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/public/cpp/resource_response.h"
+#include "services/network/throttling/scoped_throttling_token.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
@@ -453,7 +454,7 @@ class ResourceLoaderTest : public testing::Test,
loader_.reset(new ResourceLoader(
std::move(request),
WrapResourceHandler(std::move(resource_handler), raw_ptr_to_request_),
- this, &resource_context_));
+ this, &resource_context_, nullptr /* throttling_token */));
}
void SetUpResourceLoaderForUrl(const GURL& test_url) {
diff --git a/chromium/content/browser/loader/resource_message_filter.cc b/chromium/content/browser/loader/resource_message_filter.cc
index 4a82566e296..2f531f5ae08 100644
--- a/chromium/content/browser/loader/resource_message_filter.cc
+++ b/chromium/content/browser/loader/resource_message_filter.cc
@@ -4,7 +4,7 @@
#include "content/browser/loader/resource_message_filter.h"
-#include "base/feature_list.h"
+#include "base/command_line.h"
#include "base/logging.h"
#include "content/browser/appcache/chrome_appcache_service.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
@@ -18,9 +18,8 @@
#include "content/common/resource_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/resource_context.h"
-#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
#include "services/network/cors/cors_url_loader_factory.h"
-#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "storage/browser/fileapi/file_system_context.h"
@@ -146,6 +145,10 @@ void ResourceMessageFilter::CreateLoaderAndStart(
void ResourceMessageFilter::Clone(
network::mojom::URLLoaderFactoryRequest request) {
+ if (!url_loader_factory_) {
+ queued_clone_requests_.emplace_back(std::move(request));
+ return;
+ }
url_loader_factory_->Clone(std::move(request));
}
@@ -175,15 +178,19 @@ void ResourceMessageFilter::InitializeOnIOThread() {
// The WeakPtr of the filter must be created on the IO thread. So sets the
// WeakPtr of |requester_info_| now.
requester_info_->set_filter(GetWeakPtr());
- url_loader_factory_ = std::make_unique<URLLoaderFactoryImpl>(requester_info_);
-
- if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCORS)) {
- url_loader_factory_ = std::make_unique<network::cors::CORSURLLoaderFactory>(
- std::move(url_loader_factory_),
- base::BindRepeating(&ResourceDispatcherHostImpl::CancelRequest,
- base::Unretained(ResourceDispatcherHostImpl::Get()),
- requester_info_->child_id()));
- }
+ url_loader_factory_ = std::make_unique<network::cors::CORSURLLoaderFactory>(
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableWebSecurity),
+ std::make_unique<URLLoaderFactoryImpl>(requester_info_),
+ base::BindRepeating(&ResourceDispatcherHostImpl::CancelRequest,
+ base::Unretained(ResourceDispatcherHostImpl::Get()),
+ requester_info_->child_id()));
+
+ std::vector<network::mojom::URLLoaderFactoryRequest> requests =
+ std::move(queued_clone_requests_);
+ for (auto& request : requests)
+ Clone(std::move(request));
+ queued_clone_requests_.clear();
}
} // namespace content
diff --git a/chromium/content/browser/loader/resource_message_filter.h b/chromium/content/browser/loader/resource_message_filter.h
index c8f2748aa4c..a0a5a0dc3cb 100644
--- a/chromium/content/browser/loader/resource_message_filter.h
+++ b/chromium/content/browser/loader/resource_message_filter.h
@@ -81,6 +81,7 @@ class CONTENT_EXPORT ResourceMessageFilter
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag&
traffic_annotation) override;
+ // |request| could be queued when the channel has not been connected yet.
void Clone(network::mojom::URLLoaderFactoryRequest request) override;
int child_id() const;
@@ -116,6 +117,7 @@ class CONTENT_EXPORT ResourceMessageFilter
scoped_refptr<ResourceRequesterInfo> requester_info_;
std::unique_ptr<network::mojom::URLLoaderFactory> url_loader_factory_;
+ std::vector<network::mojom::URLLoaderFactoryRequest> queued_clone_requests_;
scoped_refptr<PrefetchURLLoaderService> prefetch_url_loader_service_;
diff --git a/chromium/content/browser/loader/resource_request_info_impl.cc b/chromium/content/browser/loader/resource_request_info_impl.cc
index 651bf20c2c3..3db8fd33813 100644
--- a/chromium/content/browser/loader/resource_request_info_impl.cc
+++ b/chromium/content/browser/loader/resource_request_info_impl.cc
@@ -36,6 +36,11 @@ const void* const kResourceRequestInfoImplKey = &kResourceRequestInfoImplKey;
// ResourceRequestInfo
// static
+ResourceRequestInfo* ResourceRequestInfo::ForRequest(net::URLRequest* request) {
+ return ResourceRequestInfoImpl::ForRequest(request);
+}
+
+// static
const ResourceRequestInfo* ResourceRequestInfo::ForRequest(
const net::URLRequest* request) {
return ResourceRequestInfoImpl::ForRequest(request);
@@ -184,7 +189,8 @@ ResourceRequestInfoImpl::ResourceRequestInfoImpl(
previews_state_(previews_state),
body_(body),
initiated_in_secure_context_(initiated_in_secure_context),
- blocked_cross_site_document_(false),
+ blocked_response_from_reaching_renderer_(false),
+ should_report_corb_blocking_(false),
first_auth_attempt_(true) {}
ResourceRequestInfoImpl::~ResourceRequestInfoImpl() {
@@ -308,14 +314,6 @@ PreviewsState ResourceRequestInfoImpl::GetPreviewsState() const {
return previews_state_;
}
-bool ResourceRequestInfoImpl::ShouldReportRawHeaders() const {
- return report_raw_headers_;
-}
-
-bool ResourceRequestInfoImpl::ShouldReportSecurityInfo() const {
- return report_security_info_;
-}
-
NavigationUIData* ResourceRequestInfoImpl::GetNavigationUIData() const {
return navigation_ui_data_.get();
}
@@ -325,6 +323,11 @@ ResourceRequestInfo::DevToolsStatus ResourceRequestInfoImpl::GetDevToolsStatus()
return devtools_status_;
}
+void ResourceRequestInfoImpl::SetResourceRequestBlockedReason(
+ blink::ResourceRequestBlockedReason reason) {
+ resource_request_blocked_reason_ = reason;
+}
+
base::Optional<blink::ResourceRequestBlockedReason>
ResourceRequestInfoImpl::GetResourceRequestBlockedReason() const {
return resource_request_blocked_reason_;
@@ -353,6 +356,14 @@ GlobalRoutingID ResourceRequestInfoImpl::GetGlobalRoutingID() const {
return GlobalRoutingID(GetChildID(), route_id_);
}
+bool ResourceRequestInfoImpl::ShouldReportRawHeaders() const {
+ return report_raw_headers_;
+}
+
+bool ResourceRequestInfoImpl::ShouldReportSecurityInfo() const {
+ return report_security_info_;
+}
+
void ResourceRequestInfoImpl::ResetBody() {
body_ = nullptr;
}
diff --git a/chromium/content/browser/loader/resource_request_info_impl.h b/chromium/content/browser/loader/resource_request_info_impl.h
index 0b65d8c115b..0bc8ea93804 100644
--- a/chromium/content/browser/loader/resource_request_info_impl.h
+++ b/chromium/content/browser/loader/resource_request_info_impl.h
@@ -96,14 +96,12 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
bool IsDownload() const override;
// Returns a bitmask of potentially several Previews optimizations.
PreviewsState GetPreviewsState() const override;
- bool ShouldReportRawHeaders() const;
- bool ShouldReportSecurityInfo() const;
NavigationUIData* GetNavigationUIData() const override;
DevToolsStatus GetDevToolsStatus() const override;
-
+ void SetResourceRequestBlockedReason(
+ blink::ResourceRequestBlockedReason reason) override;
base::Optional<blink::ResourceRequestBlockedReason>
GetResourceRequestBlockedReason() const override;
-
base::StringPiece GetCustomCancelReason() const override;
CONTENT_EXPORT void AssociateWithRequest(net::URLRequest* request);
@@ -111,6 +109,14 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
CONTENT_EXPORT int GetRequestID() const;
GlobalRoutingID GetGlobalRoutingID() const;
+ // Returns true if raw response headers (including sensitive data such as
+ // cookies) should be included with the response.
+ bool ShouldReportRawHeaders() const;
+
+ // Returns true if security details (SSL/TLS connection parameters and
+ // certificate chain) should be included with the response.
+ bool ShouldReportSecurityInfo() const;
+
// PlzNavigate
// The id of the FrameTreeNode that initiated this request (for a navigation
// request).
@@ -184,18 +190,19 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
devtools_status_ = devtools_status;
}
- void set_resource_request_blocked_reason(
- base::Optional<blink::ResourceRequestBlockedReason> reason) {
- resource_request_blocked_reason_ = reason;
- }
-
void SetBlobHandles(BlobHandles blob_handles);
- bool blocked_cross_site_document() const {
- return blocked_cross_site_document_;
+ bool blocked_response_from_reaching_renderer() const {
+ return blocked_response_from_reaching_renderer_;
+ }
+ void set_blocked_response_from_reaching_renderer(bool value) {
+ blocked_response_from_reaching_renderer_ = value;
}
- void set_blocked_cross_site_document(bool value) {
- blocked_cross_site_document_ = value;
+ bool should_report_corb_blocking() const {
+ return should_report_corb_blocking_;
+ }
+ void set_should_report_corb_blocking(bool value) {
+ should_report_corb_blocking_ = value;
}
void set_custom_cancel_reason(base::StringPiece reason) {
@@ -248,7 +255,13 @@ class ResourceRequestInfoImpl : public ResourceRequestInfo,
scoped_refptr<network::ResourceRequestBody> body_;
bool initiated_in_secure_context_;
std::unique_ptr<NavigationUIData> navigation_ui_data_;
- bool blocked_cross_site_document_;
+
+ // Whether response details (response headers, timing information, metadata)
+ // have been blocked from reaching the renderer process (e.g. by Cross-Origin
+ // Read Blocking).
+ bool blocked_response_from_reaching_renderer_;
+
+ bool should_report_corb_blocking_;
bool first_auth_attempt_;
// Keeps upload body blobs alive for the duration of the request.
diff --git a/chromium/content/browser/loader/resource_scheduler_filter.cc b/chromium/content/browser/loader/resource_scheduler_filter.cc
index 3b3da1ed38c..0667df77d25 100644
--- a/chromium/content/browser/loader/resource_scheduler_filter.cc
+++ b/chromium/content/browser/loader/resource_scheduler_filter.cc
@@ -5,8 +5,6 @@
#include "content/browser/loader/resource_scheduler_filter.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
-#include "content/common/frame_messages.h"
-#include "ipc/ipc_message_macros.h"
#include "services/network/resource_scheduler.h"
namespace content {
@@ -18,18 +16,6 @@ network::ResourceScheduler* GetResourceSchedulerOrNullptr() {
return ResourceDispatcherHostImpl::Get()->scheduler();
}
-ResourceSchedulerFilter::ResourceSchedulerFilter(int child_id)
- : BrowserMessageFilter(FrameMsgStart), child_id_(child_id) {}
-
-ResourceSchedulerFilter::~ResourceSchedulerFilter() {}
-
-bool ResourceSchedulerFilter::OnMessageReceived(const IPC::Message& message) {
- IPC_BEGIN_MESSAGE_MAP(ResourceSchedulerFilter, message)
- IPC_MESSAGE_HANDLER(FrameHostMsg_WillInsertBody, OnWillInsertBody)
- IPC_END_MESSAGE_MAP()
- return false;
-}
-
// static
void ResourceSchedulerFilter::OnDidCommitMainframeNavigation(
int render_process_id,
@@ -39,10 +25,4 @@ void ResourceSchedulerFilter::OnDidCommitMainframeNavigation(
scheduler->DeprecatedOnNavigate(render_process_id, render_view_routing_id);
}
-void ResourceSchedulerFilter::OnWillInsertBody(int render_view_routing_id) {
- auto* scheduler = GetResourceSchedulerOrNullptr();
- if (scheduler)
- scheduler->DeprecatedOnWillInsertBody(child_id_, render_view_routing_id);
-}
-
} // namespace content
diff --git a/chromium/content/browser/loader/resource_scheduler_filter.h b/chromium/content/browser/loader/resource_scheduler_filter.h
index 71a7b009809..573d27acd09 100644
--- a/chromium/content/browser/loader/resource_scheduler_filter.h
+++ b/chromium/content/browser/loader/resource_scheduler_filter.h
@@ -6,33 +6,20 @@
#define CONTENT_BROWSER_LOADER_RESOURCE_SCHEDULER_FILTER_H_
#include "base/macros.h"
-#include "content/public/browser/browser_message_filter.h"
namespace content {
-// This class listens for incoming ViewHostMsgs that are applicable to the
-// ResourceScheduler and invokes the appropriate notifications. It must be
-// inserted before the RenderMessageFilter, because the ResourceScheduler runs
-// on the IO thread and we want to see the messages before the view messages are
-// bounced to the UI thread.
-class ResourceSchedulerFilter : public BrowserMessageFilter {
+// This class is used to send a signal to ResourceScheduler. This class used
+// to be a ResourceMessageFilter, but is not any more.
+class ResourceSchedulerFilter {
public:
- explicit ResourceSchedulerFilter(int child_id);
-
// Informs the ResourceScheduler that a main-frame, non-same-document
// navigation has just committed.
static void OnDidCommitMainframeNavigation(int render_process_id,
int render_view_routing_id);
-
- // BrowserMessageFilter:
- bool OnMessageReceived(const IPC::Message& message) override;
-
private:
- ~ResourceSchedulerFilter() override;
-
- void OnWillInsertBody(int render_view_routing_id);
-
- int child_id_;
+ ResourceSchedulerFilter() = delete;
+ ~ResourceSchedulerFilter() = delete;
DISALLOW_COPY_AND_ASSIGN(ResourceSchedulerFilter);
};
diff --git a/chromium/content/browser/loader/stream_resource_handler.cc b/chromium/content/browser/loader/stream_resource_handler.cc
index b1337ca2e17..9a487904ac1 100644
--- a/chromium/content/browser/loader/stream_resource_handler.cc
+++ b/chromium/content/browser/loader/stream_resource_handler.cc
@@ -73,8 +73,4 @@ void StreamResourceHandler::OnResponseCompleted(
controller->Resume();
}
-void StreamResourceHandler::OnDataDownloaded(int bytes_downloaded) {
- NOTREACHED();
-}
-
} // namespace content
diff --git a/chromium/content/browser/loader/stream_resource_handler.h b/chromium/content/browser/loader/stream_resource_handler.h
index cb8a2d58d6b..b6f51bba48c 100644
--- a/chromium/content/browser/loader/stream_resource_handler.h
+++ b/chromium/content/browser/loader/stream_resource_handler.h
@@ -59,8 +59,6 @@ class StreamResourceHandler : public ResourceHandler {
const net::URLRequestStatus& status,
std::unique_ptr<ResourceController> controller) override;
- void OnDataDownloaded(int bytes_downloaded) override;
-
Stream* stream() { return writer_.stream(); }
private:
diff --git a/chromium/content/browser/loader/temporary_file_stream.cc b/chromium/content/browser/loader/temporary_file_stream.cc
deleted file mode 100644
index 2f1c784f5e0..00000000000
--- a/chromium/content/browser/loader/temporary_file_stream.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/loader/temporary_file_stream.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/files/file_proxy.h"
-#include "base/memory/ref_counted.h"
-#include "base/sequenced_task_runner.h"
-#include "base/task_scheduler/post_task.h"
-#include "content/public/browser/browser_thread.h"
-#include "net/base/file_stream.h"
-#include "storage/browser/blob/shareable_file_reference.h"
-
-using storage::ShareableFileReference;
-
-namespace content {
-
-namespace {
-
-void DidCreateTemporaryFile(
- const CreateTemporaryFileStreamCallback& callback,
- std::unique_ptr<base::FileProxy> file_proxy,
- scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::File::Error error_code,
- const base::FilePath& file_path) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (!file_proxy->IsValid()) {
- callback.Run(error_code, std::unique_ptr<net::FileStream>(), NULL);
- return;
- }
-
- // Cancelled or not, create the deletable_file so the temporary is cleaned up.
- scoped_refptr<ShareableFileReference> deletable_file =
- ShareableFileReference::GetOrCreate(
- file_path,
- ShareableFileReference::DELETE_ON_FINAL_RELEASE,
- task_runner.get());
-
- std::unique_ptr<net::FileStream> file_stream(
- new net::FileStream(file_proxy->TakeFile(), task_runner));
-
- callback.Run(error_code, std::move(file_stream), deletable_file.get());
-}
-
-} // namespace
-
-void CreateTemporaryFileStream(
- const CreateTemporaryFileStreamCallback& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- scoped_refptr<base::SequencedTaskRunner> task_runner =
- base::CreateSequencedTaskRunnerWithTraits(
- {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
- base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
-
- std::unique_ptr<base::FileProxy> file_proxy(
- new base::FileProxy(task_runner.get()));
- base::FileProxy* proxy = file_proxy.get();
- proxy->CreateTemporary(
- base::File::FLAG_ASYNC,
- base::BindOnce(&DidCreateTemporaryFile, callback, std::move(file_proxy),
- std::move(task_runner)));
-}
-
-} // namespace content
diff --git a/chromium/content/browser/loader/temporary_file_stream.h b/chromium/content/browser/loader/temporary_file_stream.h
deleted file mode 100644
index 406fcc445ee..00000000000
--- a/chromium/content/browser/loader/temporary_file_stream.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_BROWSER_LOADER_TEMPORARY_FILE_STREAM_H_
-#define CONTENT_BROWSER_LOADER_TEMPORARY_FILE_STREAM_H_
-
-#include <memory>
-
-#include "base/callback_forward.h"
-#include "base/files/file.h"
-#include "content/common/content_export.h"
-
-namespace net {
-class FileStream;
-}
-
-namespace storage {
-class ShareableFileReference;
-}
-
-namespace content {
-
-typedef base::Callback<void(base::File::Error,
- std::unique_ptr<net::FileStream>,
- storage::ShareableFileReference*)>
- CreateTemporaryFileStreamCallback;
-
-// Creates a temporary file and asynchronously calls |callback| with a
-// net::FileStream and storage::ShareableFileReference. The file is deleted
-// when the storage::ShareableFileReference is deleted. Note it is the
-// consumer's responsibility to ensure the storage::ShareableFileReference
-// stays in scope until net::FileStream has finished closing the file. On error,
-// |callback| is called with an error in the first parameter.
-//
-// This function may only be called on the IO thread.
-//
-// TODO(davidben): Juggling the net::FileStream and
-// storage::ShareableFileReference lifetimes is a nuisance. The two should
-// be tied together so the consumer need not deal with it.
-CONTENT_EXPORT void CreateTemporaryFileStream(
- const CreateTemporaryFileStreamCallback& callback);
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_LOADER_TEMPORARY_FILE_STREAM_H_
diff --git a/chromium/content/browser/loader/temporary_file_stream_unittest.cc b/chromium/content/browser/loader/temporary_file_stream_unittest.cc
deleted file mode 100644
index e32ae5b2a6b..00000000000
--- a/chromium/content/browser/loader/temporary_file_stream_unittest.cc
+++ /dev/null
@@ -1,121 +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/loader/temporary_file_stream.h"
-
-#include <string.h>
-#include <string>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/macros.h"
-#include "base/run_loop.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "content/public/test/test_utils.h"
-#include "net/base/file_stream.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
-#include "net/base/test_completion_callback.h"
-#include "storage/browser/blob/shareable_file_reference.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using storage::ShareableFileReference;
-
-namespace content {
-
-namespace {
-
-const char kTestData[] = "0123456789";
-const int kTestDataSize = arraysize(kTestData) - 1;
-
-class WaitForFileStream {
- public:
- base::File::Error error() const { return error_; }
- net::FileStream* file_stream() const { return file_stream_.get(); }
- ShareableFileReference* deletable_file() const {
- return deletable_file_.get();
- }
-
- void OnFileStreamCreated(base::File::Error error,
- std::unique_ptr<net::FileStream> file_stream,
- ShareableFileReference* deletable_file) {
- error_ = error;
- file_stream_ = std::move(file_stream);
- deletable_file_ = deletable_file;
- loop_.Quit();
- }
-
- void Wait() {
- loop_.Run();
- }
-
- void Release() {
- file_stream_.reset(nullptr);
- deletable_file_ = nullptr;
- }
- private:
- base::RunLoop loop_;
- base::File::Error error_;
- std::unique_ptr<net::FileStream> file_stream_;
- scoped_refptr<ShareableFileReference> deletable_file_;
-};
-
-} // namespace
-
-TEST(TemporaryFileStreamTest, Basic) {
- TestBrowserThreadBundle thread_bundle(TestBrowserThreadBundle::IO_MAINLOOP);
-
- // Create a temporary.
- WaitForFileStream file_stream_waiter;
- CreateTemporaryFileStream(base::Bind(&WaitForFileStream::OnFileStreamCreated,
- base::Unretained(&file_stream_waiter)));
- file_stream_waiter.Wait();
-
- // The temporary should exist.
- EXPECT_EQ(base::File::FILE_OK, file_stream_waiter.error());
- base::FilePath file_path = file_stream_waiter.deletable_file()->path();
- EXPECT_TRUE(base::PathExists(file_path));
-
- // Write some data to the temporary.
- int bytes_written = 0;
- scoped_refptr<net::IOBufferWithSize> buf =
- new net::IOBufferWithSize(kTestDataSize);
- memcpy(buf->data(), kTestData, kTestDataSize);
- scoped_refptr<net::DrainableIOBuffer> drainable =
- new net::DrainableIOBuffer(buf.get(), buf->size());
- while (bytes_written != kTestDataSize) {
- net::TestCompletionCallback write_callback;
- int rv = file_stream_waiter.file_stream()->Write(
- drainable.get(), drainable->BytesRemaining(),
- write_callback.callback());
- if (rv == net::ERR_IO_PENDING)
- rv = write_callback.WaitForResult();
- ASSERT_LT(0, rv);
- drainable->DidConsume(rv);
- bytes_written += rv;
- }
-
- // Verify the data matches.
- std::string contents;
- ASSERT_TRUE(base::ReadFileToString(file_path, &contents));
- EXPECT_EQ(kTestData, contents);
-
- // Close the file.
- net::TestCompletionCallback close_callback;
- int rv = file_stream_waiter.file_stream()->Close(close_callback.callback());
- if (rv == net::ERR_IO_PENDING)
- rv = close_callback.WaitForResult();
- EXPECT_EQ(net::OK, rv);
-
- // Release everything. The file should be gone now.
- file_stream_waiter.Release();
- content::RunAllTasksUntilIdle();
-
- // The temporary should be gone now.
- EXPECT_FALSE(base::PathExists(file_path));
-}
-
-} // content
diff --git a/chromium/content/browser/loader/test_resource_handler.cc b/chromium/content/browser/loader/test_resource_handler.cc
index b4c9f869b52..0fbeb2706a9 100644
--- a/chromium/content/browser/loader/test_resource_handler.cc
+++ b/chromium/content/browser/loader/test_resource_handler.cc
@@ -147,7 +147,6 @@ void TestResourceHandler::OnWillRead(
int* buf_size,
std::unique_ptr<ResourceController> controller) {
EXPECT_FALSE(canceled_);
- EXPECT_FALSE(expect_on_data_downloaded_);
EXPECT_EQ(0, on_response_completed_called_);
// Only create a ScopedCallDepthTracker if not called re-entrantly, as
// OnWillRead may be called synchronously in response to a Resume(), but
@@ -182,7 +181,6 @@ void TestResourceHandler::OnReadCompleted(
int bytes_read,
std::unique_ptr<ResourceController> controller) {
EXPECT_FALSE(canceled_);
- EXPECT_FALSE(expect_on_data_downloaded_);
EXPECT_EQ(1, on_will_start_called_);
EXPECT_EQ(1, on_response_started_called_);
EXPECT_EQ(0, on_response_completed_called_);
@@ -225,7 +223,7 @@ void TestResourceHandler::OnResponseCompleted(
parent_read_buffer_size_ = nullptr;
EXPECT_EQ(0, on_response_completed_called_);
- if (status.is_success() && !expect_on_data_downloaded_ && expect_eof_read_)
+ if (status.is_success() && expect_eof_read_)
EXPECT_EQ(1, on_read_eof_called_);
++on_response_completed_called_;
@@ -248,15 +246,6 @@ void TestResourceHandler::OnResponseCompleted(
controller->Resume();
}
-void TestResourceHandler::OnDataDownloaded(int bytes_downloaded) {
- EXPECT_TRUE(expect_on_data_downloaded_);
- EXPECT_EQ(1, on_will_start_called_);
- EXPECT_EQ(1, on_response_started_called_);
- EXPECT_EQ(0, on_response_completed_called_);
-
- total_bytes_downloaded_ += bytes_downloaded;
-}
-
void TestResourceHandler::Resume() {
ScopedCallDepthTracker call_depth_tracker(&call_depth_);
diff --git a/chromium/content/browser/loader/test_resource_handler.h b/chromium/content/browser/loader/test_resource_handler.h
index f109fce1a6d..d99196a1128 100644
--- a/chromium/content/browser/loader/test_resource_handler.h
+++ b/chromium/content/browser/loader/test_resource_handler.h
@@ -63,7 +63,6 @@ class TestResourceHandler : public ResourceHandler {
void OnResponseCompleted(
const net::URLRequestStatus& status,
std::unique_ptr<ResourceController> controller) override;
- void OnDataDownloaded(int bytes_downloaded) override;
void Resume();
void CancelWithError(net::Error error_code);
@@ -122,12 +121,6 @@ class TestResourceHandler : public ResourceHandler {
defer_on_response_completed_ = defer_on_response_completed;
}
- // Set if OnDataDownloaded calls are expected instead of
- // OnWillRead/OnReadCompleted.
- void set_expect_on_data_downloaded(bool expect_on_data_downloaded) {
- expect_on_data_downloaded_ = expect_on_data_downloaded;
- }
-
// Sets whether to expect a final 0-byte read on success. Defaults to true.
void set_expect_eof_read(bool expect_eof_read) {
expect_eof_read_ = expect_eof_read;
@@ -154,8 +147,6 @@ class TestResourceHandler : public ResourceHandler {
return resource_response_.get();
};
- int total_bytes_downloaded() const { return total_bytes_downloaded_; }
-
const std::string& body() const { return body_; }
net::URLRequestStatus final_status() const { return final_status_; }
@@ -197,8 +188,6 @@ class TestResourceHandler : public ResourceHandler {
bool defer_on_read_eof_ = false;
bool defer_on_response_completed_ = false;
- bool expect_on_data_downloaded_ = false;
-
bool expect_eof_read_ = true;
int on_will_start_called_ = 0;
@@ -211,7 +200,6 @@ class TestResourceHandler : public ResourceHandler {
GURL start_url_;
scoped_refptr<network::ResourceResponse> resource_response_;
- int total_bytes_downloaded_ = 0;
std::string body_;
net::URLRequestStatus final_status_ =
net::URLRequestStatus::FromError(net::ERR_UNEXPECTED);
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 e6ede61511d..9385955b5c5 100644
--- a/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc
+++ b/chromium/content/browser/loader/url_loader_factory_impl_unittest.cc
@@ -203,8 +203,8 @@ TEST_P(URLLoaderFactoryImplTest, GetResponse) {
client.completion_status().encoded_data_length);
EXPECT_EQ(static_cast<int64_t>(expected.size()),
client.completion_status().encoded_body_length);
- // OnTransferSizeUpdated is not dispatched as report_raw_headers is not set.
- EXPECT_EQ(0, client.body_transfer_size());
+ EXPECT_EQ(static_cast<int64_t>(expected.size()), client.body_transfer_size());
+ EXPECT_GT(client.body_transfer_size(), 0);
EXPECT_GT(client.response_head().encoded_data_length, 0);
EXPECT_GT(client.completion_status().encoded_data_length, 0);
}
@@ -322,133 +322,6 @@ TEST_P(URLLoaderFactoryImplTest, ShouldNotRequestURL) {
EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code);
}
-TEST_P(URLLoaderFactoryImplTest, DownloadToFile) {
- constexpr int32_t kRoutingId = 1;
- constexpr int32_t kRequestId = 2;
-
- network::mojom::URLLoaderPtr loader;
- base::FilePath root;
- base::PathService::Get(DIR_TEST_DATA, &root);
- net::URLRequestMockHTTPJob::AddUrlHandlers(root);
-
- network::ResourceRequest request;
- network::TestURLLoaderClient client;
- request.url = net::URLRequestMockHTTPJob::GetMockUrl("hello.html");
- request.method = "GET";
- request.resource_type = RESOURCE_TYPE_XHR;
- request.download_to_file = true;
- request.request_initiator = url::Origin::Create(request.url);
- factory_->CreateLoaderAndStart(
- mojo::MakeRequest(&loader), kRoutingId, kRequestId, 0, request,
- client.CreateInterfacePtr(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- ASSERT_FALSE(client.has_received_response());
- ASSERT_FALSE(client.has_data_downloaded());
- ASSERT_FALSE(client.has_received_completion());
-
- client.RunUntilResponseReceived();
-
- net::URLRequest* url_request =
- rdh_.GetURLRequest(GlobalRequestID(kChildId, kRequestId));
- ASSERT_TRUE(url_request);
- ResourceRequestInfoImpl* request_info =
- ResourceRequestInfoImpl::ForRequest(url_request);
- ASSERT_TRUE(request_info);
- EXPECT_EQ(kChildId, request_info->GetChildID());
- EXPECT_EQ(kRoutingId, request_info->GetRouteID());
- EXPECT_EQ(kRequestId, request_info->GetRequestID());
-
- ASSERT_FALSE(client.has_received_completion());
-
- client.RunUntilComplete();
- ASSERT_TRUE(client.has_data_downloaded());
- ASSERT_TRUE(client.has_received_completion());
-
- EXPECT_EQ(200, client.response_head().headers->response_code());
- std::string content_type;
- client.response_head().headers->GetNormalizedHeader("content-type",
- &content_type);
- EXPECT_EQ("text/html", content_type);
- EXPECT_EQ(0, client.completion_status().error_code);
-
- std::string contents;
- base::ReadFileToString(client.response_head().download_file_path, &contents);
-
- EXPECT_EQ(static_cast<int64_t>(contents.size()),
- client.download_data_length());
- EXPECT_EQ(static_cast<int64_t>(contents.size()),
- client.encoded_download_data_length());
-
- std::string expected;
- base::ReadFileToString(
- root.Append(base::FilePath(FILE_PATH_LITERAL("hello.html"))), &expected);
- EXPECT_EQ(expected, contents);
- EXPECT_EQ(static_cast<int64_t>(expected.size()) +
- client.response_head().encoded_data_length,
- client.completion_status().encoded_data_length);
- EXPECT_EQ(static_cast<int64_t>(expected.size()),
- client.completion_status().encoded_body_length);
-}
-
-TEST_P(URLLoaderFactoryImplTest, DownloadToFileFailure) {
- constexpr int32_t kRoutingId = 1;
- constexpr int32_t kRequestId = 2;
-
- network::mojom::URLLoaderPtr loader;
- base::FilePath root;
- base::PathService::Get(DIR_TEST_DATA, &root);
- net::URLRequestSlowDownloadJob::AddUrlHandler();
-
- network::ResourceRequest request;
- network::TestURLLoaderClient client;
- request.url = GURL(net::URLRequestSlowDownloadJob::kKnownSizeUrl);
- request.method = "GET";
- request.resource_type = RESOURCE_TYPE_XHR;
- request.download_to_file = true;
- request.request_initiator = url::Origin::Create(request.url);
- factory_->CreateLoaderAndStart(
- mojo::MakeRequest(&loader), kRoutingId, kRequestId, 0, request,
- client.CreateInterfacePtr(),
- net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- ASSERT_FALSE(client.has_received_response());
- ASSERT_FALSE(client.has_data_downloaded());
- ASSERT_FALSE(client.has_received_completion());
-
- client.RunUntilResponseReceived();
-
- net::URLRequest* url_request =
- rdh_.GetURLRequest(GlobalRequestID(kChildId, kRequestId));
- ASSERT_TRUE(url_request);
- ResourceRequestInfoImpl* request_info =
- ResourceRequestInfoImpl::ForRequest(url_request);
- ASSERT_TRUE(request_info);
- EXPECT_EQ(kChildId, request_info->GetChildID());
- EXPECT_EQ(kRoutingId, request_info->GetRouteID());
- EXPECT_EQ(kRequestId, request_info->GetRequestID());
-
- ASSERT_FALSE(client.has_received_completion());
-
- client.RunUntilDataDownloaded();
- ASSERT_TRUE(client.has_data_downloaded());
- ASSERT_FALSE(client.has_received_completion());
- EXPECT_LT(0, client.download_data_length());
- EXPECT_GE(
- static_cast<int64_t>(net::URLRequestSlowDownloadJob::kFirstDownloadSize),
- client.download_data_length());
- EXPECT_LT(0, client.encoded_download_data_length());
- EXPECT_GE(
- static_cast<int64_t>(net::URLRequestSlowDownloadJob::kFirstDownloadSize),
- client.encoded_download_data_length());
-
- url_request->Cancel();
- client.RunUntilComplete();
-
- ASSERT_TRUE(client.has_received_completion());
-
- EXPECT_EQ(200, client.response_head().headers->response_code());
- EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code);
-}
-
TEST_P(URLLoaderFactoryImplTest, OnTransferSizeUpdated) {
constexpr int32_t kRoutingId = 81;
constexpr int32_t kRequestId = 28;
diff --git a/chromium/content/browser/loader/wake_lock_resource_throttle.cc b/chromium/content/browser/loader/wake_lock_resource_throttle.cc
deleted file mode 100644
index 9ba1bd0da64..00000000000
--- a/chromium/content/browser/loader/wake_lock_resource_throttle.cc
+++ /dev/null
@@ -1,70 +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/browser/loader/wake_lock_resource_throttle.h"
-
-#include "content/browser/service_manager/service_manager_context.h"
-#include "content/public/browser/browser_thread.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
-#include "services/device/public/mojom/constants.mojom.h"
-#include "services/device/public/mojom/wake_lock_provider.mojom.h"
-#include "services/service_manager/public/cpp/connector.h"
-
-namespace content {
-
-namespace {
-
-const int kWakeLockDelaySeconds = 30;
-
-} // namespace
-
-WakeLockResourceThrottle::WakeLockResourceThrottle(const std::string& host)
- : host_(host) {}
-
-WakeLockResourceThrottle::~WakeLockResourceThrottle() {}
-
-void WakeLockResourceThrottle::WillStartRequest(bool* defer) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- // Delay wake lock request to dismiss small requests.
- timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kWakeLockDelaySeconds),
- this, &WakeLockResourceThrottle::RequestWakeLock);
-}
-
-void WakeLockResourceThrottle::WillProcessResponse(bool* defer) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- // Cancel wake lock after request finishes.
- if (wake_lock_)
- wake_lock_->CancelWakeLock();
-
- timer_.Stop();
-}
-
-const char* WakeLockResourceThrottle::GetNameForLogging() const {
- return "WakeLockResourceThrottle";
-}
-
-void WakeLockResourceThrottle::RequestWakeLock() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(!wake_lock_);
-
- service_manager::Connector* connector =
- ServiceManagerContext::GetConnectorForIOThread();
- // |connector| might be nullptr in some testing contexts, in which the
- // service manager connection isn't initialized.
- if (connector) {
- device::mojom::WakeLockProviderPtr wake_lock_provider;
- connector->BindInterface(device::mojom::kServiceName,
- mojo::MakeRequest(&wake_lock_provider));
- wake_lock_provider->GetWakeLockWithoutContext(
- device::mojom::WakeLockType::kPreventAppSuspension,
- device::mojom::WakeLockReason::kOther, "Uploading data to " + host_,
- mojo::MakeRequest(&wake_lock_));
-
- wake_lock_->RequestWakeLock();
- }
-}
-
-} // namespace content
diff --git a/chromium/content/browser/loader/wake_lock_resource_throttle.h b/chromium/content/browser/loader/wake_lock_resource_throttle.h
deleted file mode 100644
index 986b566aa86..00000000000
--- a/chromium/content/browser/loader/wake_lock_resource_throttle.h
+++ /dev/null
@@ -1,46 +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_LOADER_WAKE_LOCK_RESOURCE_THROTTLE_H_
-#define CONTENT_BROWSER_LOADER_WAKE_LOCK_RESOURCE_THROTTLE_H_
-
-#include <memory>
-#include <string>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/timer/timer.h"
-#include "content/public/browser/resource_throttle.h"
-#include "services/device/public/mojom/wake_lock.mojom.h"
-
-namespace content {
-
-// This ResourceThrottle holds wake lock until large upload request finishes.
-class WakeLockResourceThrottle : public ResourceThrottle {
- public:
- WakeLockResourceThrottle(const std::string& host);
- ~WakeLockResourceThrottle() override;
-
- // ResourceThrottle overrides:
- void WillStartRequest(bool* defer) override;
- void WillProcessResponse(bool* defer) override;
- const char* GetNameForLogging() const override;
-
- private:
- void RequestWakeLock();
-
- const std::string host_;
- base::OneShotTimer timer_;
-
- // Destruction of wake_lock_ will trigger
- // WakeLock::OnConnectionError on the service side, so there is no
- // need to call CancelWakeLock() in the destructor.
- device::mojom::WakeLockPtr wake_lock_;
-
- DISALLOW_COPY_AND_ASSIGN(WakeLockResourceThrottle);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_LOADER_WAKE_LOCK_RESOURCE_THROTTLE_H_
diff --git a/chromium/content/browser/manifest/manifest_icon_downloader.cc b/chromium/content/browser/manifest/manifest_icon_downloader.cc
index 903eca621bb..ac40d4cefb5 100644
--- a/chromium/content/browser/manifest/manifest_icon_downloader.cc
+++ b/chromium/content/browser/manifest/manifest_icon_downloader.cc
@@ -9,7 +9,6 @@
#include <limits>
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/manifest_icon_selector.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
diff --git a/chromium/content/browser/manifest/manifest_icon_selector.cc b/chromium/content/browser/manifest/manifest_icon_selector.cc
deleted file mode 100644
index 02afadb3709..00000000000
--- a/chromium/content/browser/manifest/manifest_icon_selector.cc
+++ /dev/null
@@ -1,86 +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/public/browser/manifest_icon_selector.h"
-
-#include <limits>
-
-#include "base/stl_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "third_party/blink/public/common/mime_util/mime_util.h"
-
-namespace content {
-
-// static
-GURL ManifestIconSelector::FindBestMatchingIcon(
- const std::vector<blink::Manifest::Icon>& icons,
- int ideal_icon_size_in_px,
- int minimum_icon_size_in_px,
- blink::Manifest::Icon::IconPurpose purpose) {
- DCHECK(minimum_icon_size_in_px <= ideal_icon_size_in_px);
-
- // Icon with exact matching size has priority over icon with size "any", which
- // has priority over icon with closest matching size.
- int latest_size_any_index = -1;
- int closest_size_match_index = -1;
- int best_delta_in_size = std::numeric_limits<int>::min();
-
- for (size_t i = 0; i < icons.size(); ++i) {
- const auto& icon = icons[i];
-
- // Check for supported image MIME types.
- if (!icon.type.empty() &&
- !blink::IsSupportedImageMimeType(base::UTF16ToUTF8(icon.type))) {
- continue;
- }
-
- // Check for icon purpose.
- if (!base::ContainsValue(icon.purpose, purpose))
- continue;
-
- // Check for size constraints.
- for (const gfx::Size& size : icon.sizes) {
- // Check for size "any". Return this icon if no better one is found.
- if (size.IsEmpty()) {
- latest_size_any_index = i;
- continue;
- }
-
- // Check for squareness.
- if (size.width() != size.height())
- continue;
-
- // Check for minimum size.
- if (size.width() < minimum_icon_size_in_px)
- continue;
-
- // Check for ideal size. Return this icon immediately.
- if (size.width() == ideal_icon_size_in_px)
- return icon.src;
-
- // Check for closest match.
- int delta = size.width() - ideal_icon_size_in_px;
-
- // Smallest icon larger than ideal size has priority over largest icon
- // smaller than ideal size.
- if (best_delta_in_size > 0 && delta < 0)
- continue;
-
- if ((best_delta_in_size > 0 && delta < best_delta_in_size) ||
- (best_delta_in_size < 0 && delta > best_delta_in_size)) {
- closest_size_match_index = i;
- best_delta_in_size = delta;
- }
- }
- }
-
- if (latest_size_any_index != -1)
- return icons[latest_size_any_index].src;
- else if (closest_size_match_index != -1)
- return icons[closest_size_match_index].src;
- else
- return GURL();
-}
-
-} // namespace content
diff --git a/chromium/content/browser/manifest/manifest_icon_selector_unittest.cc b/chromium/content/browser/manifest/manifest_icon_selector_unittest.cc
deleted file mode 100644
index 467a91a0864..00000000000
--- a/chromium/content/browser/manifest/manifest_icon_selector_unittest.cc
+++ /dev/null
@@ -1,499 +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/public/browser/manifest_icon_selector.h"
-
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/strings/utf_string_conversions.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-using IconPurpose = blink::Manifest::Icon::IconPurpose;
-
-namespace {
-
-const int kIdealIconSize = 144;
-const int kMinimumIconSize = 0;
-
-static blink::Manifest::Icon CreateIcon(const std::string& url,
- const std::string& type,
- const std::vector<gfx::Size> sizes,
- IconPurpose purpose) {
- blink::Manifest::Icon icon;
- icon.src = GURL(url);
- icon.type = base::UTF8ToUTF16(type);
- icon.sizes = sizes;
- icon.purpose.push_back(purpose);
-
- return icon;
-}
-
-} // anonymous namespace
-
-TEST(ManifestIconSelector, NoIcons) {
- // No icons should return the empty URL.
- std::vector<blink::Manifest::Icon> icons;
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_TRUE(url.is_empty());
-}
-
-TEST(ManifestIconSelector, NoSizes) {
- // Icon with no sizes are ignored.
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(CreateIcon("http://foo.com/icon.png", "",
- std::vector<gfx::Size>(), IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_TRUE(url.is_empty());
-}
-
-TEST(ManifestIconSelector, MIMETypeFiltering) {
- // Icons with type specified to a MIME type that isn't a valid image MIME type
- // are ignored.
- std::vector<gfx::Size> sizes;
- sizes.push_back(gfx::Size(1024, 1024));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(CreateIcon("http://foo.com/icon.png", "image/foo_bar", sizes,
- IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "image/", sizes, IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "image/", sizes, IconPurpose::ANY));
- icons.push_back(CreateIcon("http://foo.com/icon.png", "video/mp4", sizes,
- IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_TRUE(url.is_empty());
-
- icons.clear();
- icons.push_back(CreateIcon("http://foo.com/icon.png", "image/png", sizes,
- IconPurpose::ANY));
- url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
-
- icons.clear();
- icons.push_back(CreateIcon("http://foo.com/icon.png", "image/gif", sizes,
- IconPurpose::ANY));
- url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
-
- icons.clear();
- icons.push_back(CreateIcon("http://foo.com/icon.png", "image/jpeg", sizes,
- IconPurpose::ANY));
- url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
-}
-
-TEST(ManifestIconSelector, PurposeFiltering) {
- // Icons with purpose specified to non-matching purpose are ignored.
- std::vector<gfx::Size> sizes_48;
- sizes_48.push_back(gfx::Size(48, 48));
-
- std::vector<gfx::Size> sizes_96;
- sizes_96.push_back(gfx::Size(96, 96));
-
- std::vector<gfx::Size> sizes_144;
- sizes_144.push_back(gfx::Size(144, 144));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(CreateIcon("http://foo.com/icon_48.png", "", sizes_48,
- IconPurpose::BADGE));
- icons.push_back(
- CreateIcon("http://foo.com/icon_96.png", "", sizes_96, IconPurpose::ANY));
- icons.push_back(CreateIcon("http://foo.com/icon_144.png", "", sizes_144,
- IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, 48, kMinimumIconSize, IconPurpose::BADGE);
- EXPECT_EQ("http://foo.com/icon_48.png", url.spec());
-
- url = ManifestIconSelector::FindBestMatchingIcon(icons, 48, kMinimumIconSize,
- IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_96.png", url.spec());
-
- url = ManifestIconSelector::FindBestMatchingIcon(icons, 96, kMinimumIconSize,
- IconPurpose::BADGE);
- EXPECT_EQ("http://foo.com/icon_48.png", url.spec());
-
- url = ManifestIconSelector::FindBestMatchingIcon(icons, 96, 96,
- IconPurpose::BADGE);
- EXPECT_TRUE(url.is_empty());
-
- url = ManifestIconSelector::FindBestMatchingIcon(icons, 144, kMinimumIconSize,
- IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_144.png", url.spec());
-}
-
-TEST(ManifestIconSelector, IdealSizeIsUsedFirst) {
- // Each icon is marked with sizes that match the ideal icon size.
- std::vector<gfx::Size> sizes_48;
- sizes_48.push_back(gfx::Size(48, 48));
-
- std::vector<gfx::Size> sizes_96;
- sizes_96.push_back(gfx::Size(96, 96));
-
- std::vector<gfx::Size> sizes_144;
- sizes_144.push_back(gfx::Size(144, 144));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(
- CreateIcon("http://foo.com/icon_48.png", "", sizes_48, IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon_96.png", "", sizes_96, IconPurpose::ANY));
- icons.push_back(CreateIcon("http://foo.com/icon_144.png", "", sizes_144,
- IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, 48, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_48.png", url.spec());
-
- url = ManifestIconSelector::FindBestMatchingIcon(icons, 96, kMinimumIconSize,
- IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_96.png", url.spec());
-
- url = ManifestIconSelector::FindBestMatchingIcon(icons, 144, kMinimumIconSize,
- IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_144.png", url.spec());
-}
-
-TEST(ManifestIconSelector, FirstIconWithIdealSizeIsUsedFirst) {
- // This test has three icons. The first icon is going to be used because it
- // contains the ideal size.
- std::vector<gfx::Size> sizes_1;
- sizes_1.push_back(gfx::Size(kIdealIconSize, kIdealIconSize));
- sizes_1.push_back(gfx::Size(kIdealIconSize * 2, kIdealIconSize * 2));
- sizes_1.push_back(gfx::Size(kIdealIconSize * 3, kIdealIconSize * 3));
-
- std::vector<gfx::Size> sizes_2;
- sizes_2.push_back(gfx::Size(1024, 1024));
-
- std::vector<gfx::Size> sizes_3;
- sizes_3.push_back(gfx::Size(1024, 1024));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(
- CreateIcon("http://foo.com/icon_x1.png", "", sizes_1, IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon_x2.png", "", sizes_2, IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon_x3.png", "", sizes_3, IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
-
- url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize * 2, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
-
- url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize * 3, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
-}
-
-TEST(ManifestIconSelector, FallbackToSmallestLargerIcon) {
- // If there is no perfect icon, the smallest larger icon will be chosen.
- std::vector<gfx::Size> sizes_1;
- sizes_1.push_back(gfx::Size(90, 90));
-
- std::vector<gfx::Size> sizes_2;
- sizes_2.push_back(gfx::Size(128, 128));
-
- std::vector<gfx::Size> sizes_3;
- sizes_3.push_back(gfx::Size(192, 192));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(
- CreateIcon("http://foo.com/icon_x1.png", "", sizes_1, IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon_x2.png", "", sizes_2, IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon_x3.png", "", sizes_3, IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, 48, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
-
- url = ManifestIconSelector::FindBestMatchingIcon(icons, 96, kMinimumIconSize,
- IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_x2.png", url.spec());
-
- url = ManifestIconSelector::FindBestMatchingIcon(icons, 144, kMinimumIconSize,
- IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_x3.png", url.spec());
-}
-
-TEST(ManifestIconSelector, FallbackToLargestIconLargerThanMinimum) {
- // When an icon of the correct size has not been found, we fall back to the
- // closest non-matching sizes. Make sure that the minimum passed is enforced.
- std::vector<gfx::Size> sizes_1_2;
- std::vector<gfx::Size> sizes_3;
-
- sizes_1_2.push_back(gfx::Size(47, 47));
- sizes_3.push_back(gfx::Size(95, 95));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(CreateIcon("http://foo.com/icon_x1.png", "", sizes_1_2,
- IconPurpose::ANY));
- icons.push_back(CreateIcon("http://foo.com/icon_x2.png", "", sizes_1_2,
- IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon_x3.png", "", sizes_3, IconPurpose::ANY));
-
- // Icon 3 should match.
- GURL url = ManifestIconSelector::FindBestMatchingIcon(icons, 1024, 48,
- IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_x3.png", url.spec());
-
- // Nothing matches here as the minimum is 96.
- url = ManifestIconSelector::FindBestMatchingIcon(icons, 1024, 96,
- IconPurpose::ANY);
- EXPECT_TRUE(url.is_empty());
-}
-
-TEST(ManifestIconSelector, IdealVeryCloseToMinimumMatches) {
- std::vector<gfx::Size> sizes;
- sizes.push_back(gfx::Size(2, 2));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(
- CreateIcon("http://foo.com/icon_x1.png", "", sizes, IconPurpose::ANY));
-
- GURL url =
- ManifestIconSelector::FindBestMatchingIcon(icons, 2, 1, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
-}
-
-TEST(ManifestIconSelector, SizeVeryCloseToMinimumMatches) {
- std::vector<gfx::Size> sizes;
- sizes.push_back(gfx::Size(2, 2));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(
- CreateIcon("http://foo.com/icon_x1.png", "", sizes, IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(icons, 200, 1,
- IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon_x1.png", url.spec());
-}
-
-TEST(ManifestIconSelector, NotSquareIconsAreIgnored) {
- std::vector<gfx::Size> sizes;
- sizes.push_back(gfx::Size(1024, 1023));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "", sizes, IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_TRUE(url.is_empty());
-}
-
-TEST(ManifestIconSelector, ClosestIconToIdeal) {
- // Ensure ManifestIconSelector::FindBestMatchingIcon selects the closest icon
- // to the ideal size when presented with a number of options.
- int very_small = kIdealIconSize / 4;
- int small_size = kIdealIconSize / 2;
- int bit_small = kIdealIconSize - 1;
- int bit_big = kIdealIconSize + 1;
- int big = kIdealIconSize * 2;
- int very_big = kIdealIconSize * 4;
-
- // (very_small, bit_small) => bit_small
- {
- std::vector<gfx::Size> sizes_1;
- sizes_1.push_back(gfx::Size(very_small, very_small));
-
- std::vector<gfx::Size> sizes_2;
- sizes_2.push_back(gfx::Size(bit_small, bit_small));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", sizes_1,
- IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "", sizes_2, IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
- }
-
- // (very_small, bit_small, small_size) => bit_small
- {
- std::vector<gfx::Size> sizes_1;
- sizes_1.push_back(gfx::Size(very_small, very_small));
-
- std::vector<gfx::Size> sizes_2;
- sizes_2.push_back(gfx::Size(bit_small, bit_small));
-
- std::vector<gfx::Size> sizes_3;
- sizes_3.push_back(gfx::Size(small_size, small_size));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(CreateIcon("http://foo.com/icon_no_1.png", "", sizes_1,
- IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "", sizes_2, IconPurpose::ANY));
- icons.push_back(CreateIcon("http://foo.com/icon_no_2.png", "", sizes_3,
- IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
- }
-
- // (very_big, big) => big
- {
- std::vector<gfx::Size> sizes_1;
- sizes_1.push_back(gfx::Size(very_big, very_big));
-
- std::vector<gfx::Size> sizes_2;
- sizes_2.push_back(gfx::Size(big, big));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", sizes_1,
- IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "", sizes_2, IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
- }
-
- // (very_big, big, bit_big) => bit_big
- {
- std::vector<gfx::Size> sizes_1;
- sizes_1.push_back(gfx::Size(very_big, very_big));
-
- std::vector<gfx::Size> sizes_2;
- sizes_2.push_back(gfx::Size(big, big));
-
- std::vector<gfx::Size> sizes_3;
- sizes_3.push_back(gfx::Size(bit_big, bit_big));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", sizes_1,
- IconPurpose::ANY));
- icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", sizes_2,
- IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "", sizes_3, IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
- }
-
- // (bit_small, very_big) => very_big
- {
- std::vector<gfx::Size> sizes_1;
- sizes_1.push_back(gfx::Size(bit_small, bit_small));
-
- std::vector<gfx::Size> sizes_2;
- sizes_2.push_back(gfx::Size(very_big, very_big));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", sizes_1,
- IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "", sizes_2, IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
- }
-
- // (bit_small, bit_big) => bit_big
- {
- std::vector<gfx::Size> sizes_1;
- sizes_1.push_back(gfx::Size(bit_small, bit_small));
-
- std::vector<gfx::Size> sizes_2;
- sizes_2.push_back(gfx::Size(bit_big, bit_big));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", sizes_1,
- IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "", sizes_2, IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
- }
-}
-
-TEST(ManifestIconSelector, UseAnyIfNoIdealSize) {
- // 'any' (ie. gfx::Size(0,0)) should be used if there is no icon of a
- // ideal size.
-
- // Icon with 'any' and icon with ideal size => ideal size is chosen.
- {
- std::vector<gfx::Size> sizes_1;
- sizes_1.push_back(gfx::Size(kIdealIconSize, kIdealIconSize));
- std::vector<gfx::Size> sizes_2;
- sizes_2.push_back(gfx::Size(0, 0));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "", sizes_1, IconPurpose::ANY));
- icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", sizes_2,
- IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
- }
-
- // Icon with 'any' and icon larger than ideal size => any is chosen.
- {
- std::vector<gfx::Size> sizes_1;
- sizes_1.push_back(gfx::Size(kIdealIconSize + 1, kIdealIconSize + 1));
- std::vector<gfx::Size> sizes_2;
- sizes_2.push_back(gfx::Size(0, 0));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(CreateIcon("http://foo.com/icon_no.png", "", sizes_1,
- IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "", sizes_2, IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
- }
-
- // Multiple icons with 'any' => the last one is chosen.
- {
- std::vector<gfx::Size> sizes;
- sizes.push_back(gfx::Size(0, 0));
-
- std::vector<blink::Manifest::Icon> icons;
- icons.push_back(
- CreateIcon("http://foo.com/icon_no1.png", "", sizes, IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon_no2.png", "", sizes, IconPurpose::ANY));
- icons.push_back(
- CreateIcon("http://foo.com/icon.png", "", sizes, IconPurpose::ANY));
-
- GURL url = ManifestIconSelector::FindBestMatchingIcon(
- icons, kIdealIconSize * 3, kMinimumIconSize, IconPurpose::ANY);
- EXPECT_EQ("http://foo.com/icon.png", url.spec());
- }
-}
-
-} // namespace content
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 d916fcbcaad..75f94f6902d 100644
--- a/chromium/content/browser/media/android/browser_media_player_manager.cc
+++ b/chromium/content/browser/media/android/browser_media_player_manager.cc
@@ -30,7 +30,6 @@
#include "media/base/media_content_type.h"
#if !defined(USE_AURA)
-#include "content/browser/android/content_view_core.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h"
#endif
@@ -43,7 +42,6 @@ namespace content {
// Threshold on the number of media players per renderer before we start
// attempting to release inactive media players.
const int kMediaPlayerThreshold = 1;
-const int kInvalidMediaPlayerId = -1;
static BrowserMediaPlayerManager::Factory
g_browser_media_player_manager_factory = NULL;
@@ -132,8 +130,6 @@ BrowserMediaPlayerManager::CreateMediaPlayer(
BrowserMediaPlayerManager::BrowserMediaPlayerManager(
RenderFrameHost* render_frame_host)
: render_frame_host_(render_frame_host),
- fullscreen_player_id_(kInvalidMediaPlayerId),
- fullscreen_player_is_released_(false),
web_contents_(WebContents::FromRenderFrameHost(render_frame_host)),
weak_ptr_factory_(this) {
}
@@ -151,29 +147,6 @@ BrowserMediaPlayerManager::~BrowserMediaPlayerManager() {
players_.clear();
}
-void BrowserMediaPlayerManager::DidExitFullscreen(bool release_media_player) {
-#if defined(USE_AURA)
- // TODO(crbug.com/548024)
- NOTIMPLEMENTED();
-#else
- if (WebContentsDelegate* delegate = web_contents_->GetDelegate())
- delegate->ExitFullscreenModeForTab(web_contents_);
-
- Send(
- new MediaPlayerMsg_DidExitFullscreen(RoutingID(), fullscreen_player_id_));
- video_view_.reset();
- MediaPlayerAndroid* player = GetFullscreenPlayer();
- fullscreen_player_id_ = kInvalidMediaPlayerId;
- if (!player)
- return;
-
- if (release_media_player)
- ReleaseFullscreenPlayer(player);
- else
- player->SetVideoSurface(gl::ScopedJavaSurface());
-#endif // defined(USE_AURA)
-}
-
void BrowserMediaPlayerManager::OnTimeUpdate(
int player_id,
base::TimeDelta current_timestamp,
@@ -182,31 +155,11 @@ void BrowserMediaPlayerManager::OnTimeUpdate(
RoutingID(), player_id, current_timestamp, current_time_ticks));
}
-void BrowserMediaPlayerManager::SetVideoSurface(gl::ScopedJavaSurface surface) {
- MediaPlayerAndroid* player = GetFullscreenPlayer();
- if (!player)
- return;
-
- bool empty_surface = surface.IsEmpty();
- player->SetVideoSurface(std::move(surface));
- if (empty_surface)
- return;
-
- // If we already know the size, set it now. Otherwise it will be set when the
- // player gets it.
- if (player->IsPlayerReady()) {
- video_view_->OnVideoSizeChanged(player->GetVideoWidth(),
- player->GetVideoHeight());
- }
-}
-
void BrowserMediaPlayerManager::OnMediaMetadataChanged(
int player_id, base::TimeDelta duration, int width, int height,
bool success) {
Send(new MediaPlayerMsg_MediaMetadataChanged(
RoutingID(), player_id, duration, width, height, success));
- if (fullscreen_player_id_ == player_id)
- video_view_->OnVideoSizeChanged(width, height);
}
void BrowserMediaPlayerManager::OnPlaybackComplete(int player_id) {
@@ -239,18 +192,12 @@ void BrowserMediaPlayerManager::OnSeekComplete(
void BrowserMediaPlayerManager::OnError(int player_id, int error) {
Send(new MediaPlayerMsg_MediaError(RoutingID(), player_id, error));
- if (fullscreen_player_id_ == player_id &&
- error != MediaPlayerAndroid::MEDIA_ERROR_INVALID_CODE) {
- video_view_->OnMediaPlayerError(error);
- }
}
void BrowserMediaPlayerManager::OnVideoSizeChanged(
int player_id, int width, int height) {
Send(new MediaPlayerMsg_MediaVideoSizeChanged(RoutingID(), player_id,
width, height));
- if (fullscreen_player_id_ == player_id)
- video_view_->OnVideoSizeChanged(width, height);
}
media::MediaResourceGetter*
@@ -277,10 +224,6 @@ BrowserMediaPlayerManager::GetMediaUrlInterceptor() {
return media_url_interceptor_;
}
-MediaPlayerAndroid* BrowserMediaPlayerManager::GetFullscreenPlayer() {
- return GetPlayer(fullscreen_player_id_);
-}
-
MediaPlayerAndroid* BrowserMediaPlayerManager::GetPlayer(int player_id) {
for (const auto& player : players_) {
if (player->player_id() == player_id)
@@ -301,53 +244,6 @@ bool BrowserMediaPlayerManager::RequestPlay(int player_id,
media::DurationToMediaContentType(duration));
}
-void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) {
-#if defined(USE_AURA)
- // TODO(crbug.com/548024)
- NOTIMPLEMENTED();
-#else
- DCHECK_EQ(fullscreen_player_id_, kInvalidMediaPlayerId);
- if (video_view_) {
- fullscreen_player_id_ = player_id;
- video_view_->OpenVideo();
- return;
- }
-
- if (ContentVideoView::GetInstance()) {
- // In Android WebView, two ContentViewCores could both try to enter
- // fullscreen video, we just ignore the second one.
- Send(new MediaPlayerMsg_DidExitFullscreen(RoutingID(), player_id));
- return;
- }
-
- // There's no ContentVideoView instance so create one.
- // If we know the video frame size, use it.
- gfx::Size natural_video_size;
- MediaPlayerAndroid* player = GetFullscreenPlayer();
- if (player && player->IsPlayerReady()) {
- natural_video_size =
- gfx::Size(player->GetVideoWidth(), player->GetVideoHeight());
- }
-
- if (!web_contents()->GetDelegate())
- return;
-
- base::android::ScopedJavaLocalRef<jobject> embedder(
- web_contents()->GetDelegate()->GetContentVideoViewEmbedder());
- video_view_.reset(
- new ContentVideoView(this, web_contents(), embedder, natural_video_size));
-
- base::android::ScopedJavaLocalRef<jobject> j_content_video_view =
- video_view_->GetJavaObject(base::android::AttachCurrentThread());
- if (!j_content_video_view.is_null()) {
- fullscreen_player_id_ = player_id;
- } else {
- Send(new MediaPlayerMsg_DidExitFullscreen(RoutingID(), player_id));
- video_view_.reset();
- }
-#endif // defined(USE_AURA)
-}
-
void BrowserMediaPlayerManager::OnInitialize(
const MediaPlayerHostMsg_Initialize_Params& media_player_params) {
DestroyPlayer(media_player_params.player_id);
@@ -369,10 +265,6 @@ void BrowserMediaPlayerManager::OnStart(int player_id) {
RequestDecoderResources(player_id, false);
player->Start();
- if (fullscreen_player_id_ == player_id && fullscreen_player_is_released_) {
- video_view_->OpenVideo();
- fullscreen_player_is_released_ = false;
- }
}
void BrowserMediaPlayerManager::OnSeek(
@@ -407,8 +299,6 @@ void BrowserMediaPlayerManager::OnSuspendAndReleaseResources(int player_id) {
void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) {
DestroyPlayer(player_id);
- if (fullscreen_player_id_ == player_id)
- fullscreen_player_id_ = kInvalidMediaPlayerId;
}
void BrowserMediaPlayerManager::OnRequestRemotePlayback(int /* player_id */) {
@@ -453,8 +343,6 @@ void BrowserMediaPlayerManager::ReleaseResources(int player_id) {
MediaPlayerAndroid* player = GetPlayer(player_id);
if (player)
ReleasePlayer(player);
- if (player_id == fullscreen_player_id_)
- fullscreen_player_is_released_ = true;
}
std::unique_ptr<MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer(
@@ -497,8 +385,7 @@ bool BrowserMediaPlayerManager::RequestDecoderResources(
return true;
for (it = active_players_.begin(); it != active_players_.end(); ++it) {
- if (!it->second && !GetPlayer(it->first)->IsPlaying() &&
- fullscreen_player_id_ != it->first) {
+ if (!it->second && !GetPlayer(it->first)->IsPlaying()) {
ReleasePlayer(GetPlayer(it->first));
Send(new MediaPlayerMsg_MediaPlayerReleased(RoutingID(),
(it->first)));
diff --git a/chromium/content/browser/media/android/browser_media_player_manager.h b/chromium/content/browser/media/android/browser_media_player_manager.h
index dd82592843d..aaaf4ccb74f 100644
--- a/chromium/content/browser/media/android/browser_media_player_manager.h
+++ b/chromium/content/browser/media/android/browser_media_player_manager.h
@@ -12,7 +12,6 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/time/time.h"
-#include "content/browser/android/content_video_view.h"
#include "content/common/content_export.h"
#include "ipc/ipc_message.h"
#include "media/base/android/media_player_android.h"
@@ -37,8 +36,7 @@ class WebContents;
// MediaPlayerAndroid objects are converted to IPCs and then sent to the render
// process.
class CONTENT_EXPORT BrowserMediaPlayerManager
- : public media::MediaPlayerManager,
- public ContentVideoView::Client {
+ : public media::MediaPlayerManager {
public:
// Permits embedders to provide an extended version of the class.
typedef BrowserMediaPlayerManager* (*Factory)(RenderFrameHost*);
@@ -58,10 +56,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
~BrowserMediaPlayerManager() override;
- // ContentVideoView::Client implementation.
- void DidExitFullscreen(bool release_media_player) override;
- void SetVideoSurface(gl::ScopedJavaSurface surface) override;
-
// Called when browser player wants the renderer media element to seek.
// Any actual seek started by renderer will be handled by browser in OnSeek().
void OnSeekRequest(int player_id, const base::TimeDelta& time_to_seek);
@@ -87,13 +81,11 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
media::MediaResourceGetter* GetMediaResourceGetter() override;
media::MediaUrlInterceptor* GetMediaUrlInterceptor() override;
- media::MediaPlayerAndroid* GetFullscreenPlayer() override;
media::MediaPlayerAndroid* GetPlayer(int player_id) override;
bool RequestPlay(int player_id, base::TimeDelta duration,
bool has_audio) override;
// Message handlers.
- virtual void OnEnterFullscreen(int player_id);
virtual void OnInitialize(
const MediaPlayerHostMsg_Initialize_Params& media_player_params);
virtual void OnStart(int player_id);
@@ -172,10 +164,6 @@ class CONTENT_EXPORT BrowserMediaPlayerManager
// will release its resources later.
ActivePlayerMap active_players_;
- // The fullscreen video view object or NULL if video is not played in
- // fullscreen.
- std::unique_ptr<ContentVideoView> video_view_;
-
// Player ID of the fullscreen media player.
int fullscreen_player_id_;
diff --git a/chromium/content/browser/media/android/browser_surface_view_manager.cc b/chromium/content/browser/media/android/browser_surface_view_manager.cc
deleted file mode 100644
index 54a75fe8150..00000000000
--- a/chromium/content/browser/media/android/browser_surface_view_manager.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/media/android/browser_surface_view_manager.h"
-
-#include "base/android/build_info.h"
-#include "base/trace_event/trace_event.h"
-#include "content/browser/gpu/gpu_process_host.h"
-#include "content/browser/web_contents/web_contents_impl.h"
-#include "content/common/media/surface_view_manager_messages_android.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/render_frame_host.h"
-#include "content/public/browser/web_contents_delegate.h"
-#include "gpu/ipc/common/gpu_surface_tracker.h"
-#include "media/base/surface_manager.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace content {
-namespace {
-void SendDestroyingVideoSurfaceOnIO(int surface_id,
- const base::Closure& done_cb) {
- GpuProcessHost* host = GpuProcessHost::Get(
- GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, false /* force_create */);
- if (host)
- host->SendDestroyingVideoSurface(surface_id, done_cb);
- else
- done_cb.Run();
-}
-} // namespace
-
-BrowserSurfaceViewManager::BrowserSurfaceViewManager(
- RenderFrameHost* render_frame_host)
- : render_frame_host_(render_frame_host),
- surface_id_(media::SurfaceManager::kNoSurfaceID) {}
-
-BrowserSurfaceViewManager::~BrowserSurfaceViewManager() {}
-
-void BrowserSurfaceViewManager::SetVideoSurface(gl::ScopedJavaSurface surface) {
- TRACE_EVENT0("media", "BrowserSurfaceViewManager::SetVideoSurface");
- if (surface.IsEmpty()) {
- DCHECK_NE(surface_id_, media::SurfaceManager::kNoSurfaceID);
- gpu::GpuSurfaceTracker::Get()->RemoveSurface(surface_id_);
- SendDestroyingVideoSurface(surface_id_);
- surface_id_ = media::SurfaceManager::kNoSurfaceID;
- } else {
- // We just use the surface tracker to allocate a surface id for us. The
- // lookup will go through the Android specific path and get the java
- // surface directly, so there's no need to add a valid native widget here.
- surface_id_ = gpu::GpuSurfaceTracker::Get()->AddSurfaceForNativeWidget(
- gpu::GpuSurfaceTracker::SurfaceRecord(gfx::kNullAcceleratedWidget,
- surface.j_surface().obj()));
- SendSurfaceID(surface_id_);
- }
-}
-
-void BrowserSurfaceViewManager::DidExitFullscreen(bool release_media_player) {
- DVLOG(3) << __func__;
- content_video_view_.reset();
-}
-
-void BrowserSurfaceViewManager::OnCreateFullscreenSurface(
- const gfx::Size& video_natural_size) {
- // If we are in virtual reality, no surface view is needed so just return.
- // TODO(http://crbug.com/673886): Support overlay surfaces in VR using GVR
- // reprojection video surface.
- RenderWidgetHostViewBase * rwhvb =
- static_cast<RenderWidgetHostViewBase*>(render_frame_host_->GetView());
- if (rwhvb->IsInVR()) {
- SendSurfaceID(media::SurfaceManager::kNoSurfaceID);
- return;
- }
-
- // It's valid to get this call if we already own the fullscreen view. We just
- // return the existing surface id.
- if (content_video_view_) {
- // Send the surface now if we have it. Otherwise it will be returned by
- // |SetVideoSurface|.
- if (surface_id_ != media::SurfaceManager::kNoSurfaceID) {
- SendSurfaceID(surface_id_);
- OnNaturalSizeChanged(video_natural_size);
- return;
- }
- }
-
- // If we don't own the fullscreen view, but one exists, it means another
- // WebContents has it. Ignore this request and return a null surface id.
- if (ContentVideoView::GetInstance()) {
- SendSurfaceID(media::SurfaceManager::kNoSurfaceID);
- return;
- }
-
- WebContents* web_contents =
- WebContents::FromRenderFrameHost(render_frame_host_);
- if (!web_contents->GetDelegate()) {
- SendSurfaceID(media::SurfaceManager::kNoSurfaceID);
- return;
- }
- content_video_view_.reset(new ContentVideoView(
- this, web_contents,
- web_contents->GetDelegate()->GetContentVideoViewEmbedder(),
- video_natural_size));
-}
-
-void BrowserSurfaceViewManager::OnNaturalSizeChanged(const gfx::Size& size) {
- if (content_video_view_)
- content_video_view_->OnVideoSizeChanged(size.width(), size.height());
-}
-
-bool BrowserSurfaceViewManager::SendSurfaceID(int surface_id) {
- return render_frame_host_->Send(
- new SurfaceViewManagerMsg_FullscreenSurfaceCreated(
- render_frame_host_->GetRoutingID(), surface_id));
-}
-
-void BrowserSurfaceViewManager::SendDestroyingVideoSurface(int surface_id) {
- base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- // Unretained is okay because we're waiting on the callback.
- if (BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&SendDestroyingVideoSurfaceOnIO, surface_id,
- base::Bind(&base::WaitableEvent::Signal,
- base::Unretained(&waiter))))) {
- base::ThreadRestrictions::ScopedAllowWait allow_wait;
- waiter.Wait();
- }
-}
-
-} // namespace content
diff --git a/chromium/content/browser/media/android/browser_surface_view_manager.h b/chromium/content/browser/media/android/browser_surface_view_manager.h
deleted file mode 100644
index 08039efa5e9..00000000000
--- a/chromium/content/browser/media/android/browser_surface_view_manager.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_SURFACE_VIEW_MANAGER_H_
-#define CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_SURFACE_VIEW_MANAGER_H_
-
-#include <stdint.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "content/browser/android/content_video_view.h"
-#include "content/common/content_export.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace content {
-
-class RenderFrameHost;
-
-// BrowserSurfaceViewManager creates and owns a ContentVideoView on behalf of
-// a fullscreen media player. Its SurfaceView is registered so that a decoder
-// in the GPU process can look it up and render to it.
-class CONTENT_EXPORT BrowserSurfaceViewManager final
- : public ContentVideoView::Client {
- public:
- explicit BrowserSurfaceViewManager(RenderFrameHost* render_frame_host);
- ~BrowserSurfaceViewManager();
-
- // ContentVideoView::Client overrides.
- void SetVideoSurface(gl::ScopedJavaSurface surface) override;
- void DidExitFullscreen(bool release_media_player) override;
-
- void OnCreateFullscreenSurface(const gfx::Size& video_natural_size);
- void OnNaturalSizeChanged(const gfx::Size& size);
-
- private:
- // Send a message to return the surface id to the caller.
- bool SendSurfaceID(int surface_id);
-
- // Synchronously notify the decoder that the surface is being destroyed so it
- // can stop rendering to it. This sends a message to the GPU process. Without
- // this, the MediaCodec decoder will start throwing IllegalStateException, and
- // crash on some devices (http://crbug.com/598408, http://crbug.com/600454).
- void SendDestroyingVideoSurface(int surface_id);
-
- RenderFrameHost* const render_frame_host_;
-
- // The surface id of the ContentVideoView surface.
- int surface_id_;
-
- // The fullscreen view that contains a SurfaceView.
- std::unique_ptr<ContentVideoView> content_video_view_;
-
- DISALLOW_COPY_AND_ASSIGN(BrowserSurfaceViewManager);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_MEDIA_ANDROID_BROWSER_SURFACE_VIEW_MANAGER_H_
diff --git a/chromium/content/browser/media/android/media_player_renderer.cc b/chromium/content/browser/media/android/media_player_renderer.cc
index 2c5926260df..05d7c6a039d 100644
--- a/chromium/content/browser/media/android/media_player_renderer.cc
+++ b/chromium/content/browser/media/android/media_player_renderer.cc
@@ -298,11 +298,6 @@ void MediaPlayerRenderer::OnVideoSizeChanged(int player_id,
}
}
-media::MediaPlayerAndroid* MediaPlayerRenderer::GetFullscreenPlayer() {
- NOTREACHED();
- return nullptr;
-}
-
media::MediaPlayerAndroid* MediaPlayerRenderer::GetPlayer(int player_id) {
NOTREACHED();
return nullptr;
diff --git a/chromium/content/browser/media/android/media_player_renderer.h b/chromium/content/browser/media/android/media_player_renderer.h
index 44ab9e046be..ed0bd5822df 100644
--- a/chromium/content/browser/media/android/media_player_renderer.h
+++ b/chromium/content/browser/media/android/media_player_renderer.h
@@ -86,7 +86,6 @@ class CONTENT_EXPORT MediaPlayerRenderer : public media::Renderer,
const base::TimeDelta& current_time) override;
void OnError(int player_id, int error) override;
void OnVideoSizeChanged(int player_id, int width, int height) override;
- media::MediaPlayerAndroid* GetFullscreenPlayer() override;
media::MediaPlayerAndroid* GetPlayer(int player_id) override;
bool RequestPlay(int player_id,
base::TimeDelta duration,
diff --git a/chromium/content/browser/media/android/media_web_contents_observer_android.cc b/chromium/content/browser/media/android/media_web_contents_observer_android.cc
index c6ac9e5e68a..25368e310fc 100644
--- a/chromium/content/browser/media/android/media_web_contents_observer_android.cc
+++ b/chromium/content/browser/media/android/media_web_contents_observer_android.cc
@@ -8,11 +8,9 @@
#include "base/memory/ptr_util.h"
#include "content/browser/media/android/browser_media_player_manager.h"
-#include "content/browser/media/android/browser_surface_view_manager.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/media/media_player_delegate_messages.h"
#include "content/common/media/media_player_messages_android.h"
-#include "content/common/media/surface_view_manager_messages_android.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message_macros.h"
@@ -53,19 +51,6 @@ MediaWebContentsObserverAndroid::GetMediaPlayerManager(
return manager;
}
-BrowserSurfaceViewManager*
-MediaWebContentsObserverAndroid::GetSurfaceViewManager(
- RenderFrameHost* render_frame_host) {
- auto it = surface_view_managers_.find(render_frame_host);
- if (it != surface_view_managers_.end())
- return it->second.get();
-
- BrowserSurfaceViewManager* manager =
- new BrowserSurfaceViewManager(render_frame_host);
- surface_view_managers_[render_frame_host] = base::WrapUnique(manager);
- return manager;
-}
-
void MediaWebContentsObserverAndroid::SuspendAllMediaPlayers() {
web_contents()->ForEachFrame(
base::BindRepeating(&SuspendAllMediaPlayersInRenderFrame));
@@ -94,7 +79,6 @@ void MediaWebContentsObserverAndroid::RenderFrameDeleted(
MediaWebContentsObserver::RenderFrameDeleted(render_frame_host);
media_player_managers_.erase(render_frame_host);
- surface_view_managers_.erase(render_frame_host);
}
bool MediaWebContentsObserverAndroid::OnMessageReceived(
@@ -106,9 +90,6 @@ bool MediaWebContentsObserverAndroid::OnMessageReceived(
if (OnMediaPlayerMessageReceived(msg, render_frame_host))
return true;
- if (OnSurfaceViewManagerMessageReceived(msg, render_frame_host))
- return true;
-
return false;
}
@@ -130,9 +111,6 @@ bool MediaWebContentsObserverAndroid::OnMediaPlayerMessageReceived(
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserverAndroid, msg)
- IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_EnterFullscreen,
- media_player_manager,
- BrowserMediaPlayerManager::OnEnterFullscreen)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Initialize, media_player_manager,
BrowserMediaPlayerManager::OnInitialize)
IPC_MESSAGE_FORWARD(MediaPlayerHostMsg_Start, media_player_manager,
@@ -165,20 +143,4 @@ bool MediaWebContentsObserverAndroid::OnMediaPlayerMessageReceived(
return handled;
}
-bool MediaWebContentsObserverAndroid::OnSurfaceViewManagerMessageReceived(
- const IPC::Message& msg,
- RenderFrameHost* render_frame_host) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(MediaWebContentsObserverAndroid, msg)
- IPC_MESSAGE_FORWARD(SurfaceViewManagerHostMsg_CreateFullscreenSurface,
- GetSurfaceViewManager(render_frame_host),
- BrowserSurfaceViewManager::OnCreateFullscreenSurface)
- IPC_MESSAGE_FORWARD(SurfaceViewManagerHostMsg_NaturalSizeChanged,
- GetSurfaceViewManager(render_frame_host),
- BrowserSurfaceViewManager::OnNaturalSizeChanged)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
} // namespace content
diff --git a/chromium/content/browser/media/android/media_web_contents_observer_android.h b/chromium/content/browser/media/android/media_web_contents_observer_android.h
index e330e45009e..13da22f5c16 100644
--- a/chromium/content/browser/media/android/media_web_contents_observer_android.h
+++ b/chromium/content/browser/media/android/media_web_contents_observer_android.h
@@ -21,7 +21,6 @@ enum class MediaContentType;
namespace content {
class BrowserMediaPlayerManager;
-class BrowserSurfaceViewManager;
// This class adds Android specific extensions to the MediaWebContentsObserver.
class CONTENT_EXPORT MediaWebContentsObserverAndroid
@@ -39,8 +38,6 @@ class CONTENT_EXPORT MediaWebContentsObserverAndroid
// returned pointer.
BrowserMediaPlayerManager* GetMediaPlayerManager(
RenderFrameHost* render_frame_host);
- BrowserSurfaceViewManager* GetSurfaceViewManager(
- RenderFrameHost* render_frame_host);
// Called by the WebContents when a tab has been closed but may still be
// available for "undo" -- indicates that all media players (even audio only
@@ -72,20 +69,12 @@ class CONTENT_EXPORT MediaWebContentsObserverAndroid
bool OnMediaPlayerMessageReceived(const IPC::Message& message,
RenderFrameHost* render_frame_host);
- bool OnSurfaceViewManagerMessageReceived(const IPC::Message& message,
- RenderFrameHost* render_frame_host);
-
// Map from RenderFrameHost* to BrowserMediaPlayerManager.
using MediaPlayerManagerMap =
std::unordered_map<RenderFrameHost*,
std::unique_ptr<BrowserMediaPlayerManager>>;
MediaPlayerManagerMap media_player_managers_;
- using SurfaceViewManagerMap =
- std::unordered_map<RenderFrameHost*,
- std::unique_ptr<BrowserSurfaceViewManager>>;
- SurfaceViewManagerMap surface_view_managers_;
-
DISALLOW_COPY_AND_ASSIGN(MediaWebContentsObserverAndroid);
};
diff --git a/chromium/content/browser/media/audible_metrics_unittest.cc b/chromium/content/browser/media/audible_metrics_unittest.cc
index d122e3178c2..a9f1b47e483 100644
--- a/chromium/content/browser/media/audible_metrics_unittest.cc
+++ b/chromium/content/browser/media/audible_metrics_unittest.cc
@@ -5,9 +5,9 @@
#include "content/browser/media/audible_metrics.h"
#include "base/metrics/histogram_samples.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/metrics/user_action_tester.h"
#include "base/test/simple_test_tick_clock.h"
-#include "base/test/user_action_tester.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
diff --git a/chromium/content/browser/media/audio_input_stream_broker.cc b/chromium/content/browser/media/audio_input_stream_broker.cc
index e0a2f97fdda..b8cc22b65e5 100644
--- a/chromium/content/browser/media/audio_input_stream_broker.cc
+++ b/chromium/content/browser/media/audio_input_stream_broker.cc
@@ -52,8 +52,8 @@ AudioInputStreamBroker::AudioInputStreamBroker(
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("audio", "AudioInputStreamBroker", this);
// Unretained is safe because |this| owns |renderer_factory_client_|.
- renderer_factory_client_.set_connection_error_handler(
- base::BindOnce(&AudioInputStreamBroker::Cleanup, base::Unretained(this)));
+ renderer_factory_client_.set_connection_error_handler(base::BindOnce(
+ &AudioInputStreamBroker::ClientBindingLost, base::Unretained(this)));
// Notify RenderProcessHost about input stream so the renderer is not
// background.
@@ -170,7 +170,7 @@ void AudioInputStreamBroker::DidStartRecording() {
void AudioInputStreamBroker::StreamCreated(
media::mojom::AudioInputStreamPtr stream,
- media::mojom::AudioDataPipePtr data_pipe,
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
bool initially_muted,
const base::Optional<base::UnguessableToken>& stream_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -210,6 +210,12 @@ void AudioInputStreamBroker::ObserverBindingLost(
Cleanup();
}
+void AudioInputStreamBroker::ClientBindingLost() {
+ disconnect_reason_ = media::mojom::AudioInputStreamObserver::
+ DisconnectReason::kTerminatedByClient;
+ Cleanup();
+}
+
void AudioInputStreamBroker::Cleanup() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chromium/content/browser/media/audio_input_stream_broker.h b/chromium/content/browser/media/audio_input_stream_broker.h
index 524fb3408e3..910453c4977 100644
--- a/chromium/content/browser/media/audio_input_stream_broker.h
+++ b/chromium/content/browser/media/audio_input_stream_broker.h
@@ -49,12 +49,12 @@ class CONTENT_EXPORT AudioInputStreamBroker final
private:
void StreamCreated(media::mojom::AudioInputStreamPtr stream,
- media::mojom::AudioDataPipePtr data_pipe,
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
bool initially_muted,
const base::Optional<base::UnguessableToken>& stream_id);
void ObserverBindingLost(uint32_t reason, const std::string& description);
-
+ void ClientBindingLost();
void Cleanup();
const std::string device_id_;
diff --git a/chromium/content/browser/media/audio_input_stream_broker_unittest.cc b/chromium/content/browser/media/audio_input_stream_broker_unittest.cc
index 809f63f1504..4adcdff9b3c 100644
--- a/chromium/content/browser/media/audio_input_stream_broker_unittest.cc
+++ b/chromium/content/browser/media/audio_input_stream_broker_unittest.cc
@@ -56,7 +56,7 @@ class MockRendererAudioInputStreamFactoryClient
void StreamCreated(
media::mojom::AudioInputStreamPtr input_stream,
media::mojom::AudioInputStreamClientRequest client_request,
- media::mojom::AudioDataPipePtr data_pipe,
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
bool initially_muted,
const base::Optional<base::UnguessableToken>& stream_id) override {
EXPECT_TRUE(stream_id.has_value());
@@ -188,7 +188,8 @@ TEST(AudioInputStreamBrokerTest, StreamCreationSuccess_Propagates) {
base::SyncSocket socket1, socket2;
base::SyncSocket::CreatePair(&socket1, &socket2);
std::move(stream_request_data.created_callback)
- .Run({base::in_place, mojo::SharedBufferHandle::Create(shmem_size),
+ .Run({base::in_place,
+ base::ReadOnlySharedMemoryRegion::Create(shmem_size).region,
mojo::WrapPlatformFile(socket1.Release())},
kInitiallyMuted, base::UnguessableToken::Create());
diff --git a/chromium/content/browser/media/audio_log_factory.cc b/chromium/content/browser/media/audio_log_factory.cc
new file mode 100644
index 00000000000..f7ec4fef3c1
--- /dev/null
+++ b/chromium/content/browser/media/audio_log_factory.cc
@@ -0,0 +1,25 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/media/audio_log_factory.h"
+
+#include <utility>
+
+#include "content/browser/media/media_internals.h"
+
+namespace content {
+
+AudioLogFactory::AudioLogFactory() = default;
+AudioLogFactory::~AudioLogFactory() = default;
+
+void AudioLogFactory::CreateAudioLog(
+ media::mojom::AudioLogComponent component,
+ int32_t component_id,
+ media::mojom::AudioLogRequest audio_log_request) {
+ MediaInternals::GetInstance()->CreateMojoAudioLog(
+ static_cast<media::AudioLogFactory::AudioComponent>(component),
+ component_id, std::move(audio_log_request));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/audio_log_factory.h b/chromium/content/browser/media/audio_log_factory.h
new file mode 100644
index 00000000000..513d5a48a89
--- /dev/null
+++ b/chromium/content/browser/media/audio_log_factory.h
@@ -0,0 +1,28 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_MEDIA_AUDIO_LOG_FACTORY_H_
+#define CONTENT_BROWSER_MEDIA_AUDIO_LOG_FACTORY_H_
+
+#include "media/mojo/interfaces/audio_logging.mojom.h"
+
+namespace content {
+
+class AudioLogFactory : public media::mojom::AudioLogFactory {
+ public:
+ AudioLogFactory();
+ ~AudioLogFactory() override;
+
+ // media::mojom::AudioLogFactory implementation.
+ void CreateAudioLog(media::mojom::AudioLogComponent component,
+ int32_t component_id,
+ media::mojom::AudioLogRequest audio_log_request) override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AudioLogFactory);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_MEDIA_AUDIO_LOG_FACTORY_H_
diff --git a/chromium/content/browser/media/audio_loopback_stream_broker.cc b/chromium/content/browser/media/audio_loopback_stream_broker.cc
index d7cba0187ea..884508c44f3 100644
--- a/chromium/content/browser/media/audio_loopback_stream_broker.cc
+++ b/chromium/content/browser/media/audio_loopback_stream_broker.cc
@@ -141,7 +141,7 @@ void AudioLoopbackStreamBroker::DidStartRecording() {
void AudioLoopbackStreamBroker::StreamCreated(
media::mojom::AudioInputStreamPtr stream,
- media::mojom::AudioDataPipePtr data_pipe) {
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (!data_pipe) {
diff --git a/chromium/content/browser/media/audio_loopback_stream_broker.h b/chromium/content/browser/media/audio_loopback_stream_broker.h
index 71778564a65..9853b4c9768 100644
--- a/chromium/content/browser/media/audio_loopback_stream_broker.h
+++ b/chromium/content/browser/media/audio_loopback_stream_broker.h
@@ -47,7 +47,7 @@ class CONTENT_EXPORT AudioLoopbackStreamBroker final
private:
void StreamCreated(media::mojom::AudioInputStreamPtr stream,
- media::mojom::AudioDataPipePtr data_pipe);
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe);
void Cleanup();
const std::unique_ptr<AudioStreamBrokerFactory::LoopbackSource> source_;
diff --git a/chromium/content/browser/media/audio_loopback_stream_broker_unittest.cc b/chromium/content/browser/media/audio_loopback_stream_broker_unittest.cc
index cfe6cc7ccb3..14923ed61e4 100644
--- a/chromium/content/browser/media/audio_loopback_stream_broker_unittest.cc
+++ b/chromium/content/browser/media/audio_loopback_stream_broker_unittest.cc
@@ -71,7 +71,7 @@ class MockRendererAudioInputStreamFactoryClient
void StreamCreated(
media::mojom::AudioInputStreamPtr input_stream,
media::mojom::AudioInputStreamClientRequest client_request,
- media::mojom::AudioDataPipePtr data_pipe,
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
bool initially_muted,
const base::Optional<base::UnguessableToken>& stream_id) override {
// Loopback streams have no stream ids.
@@ -219,7 +219,8 @@ TEST(AudioLoopbackStreamBrokerTest, StreamCreationSuccess_Propagates) {
base::SyncSocket socket1, socket2;
base::SyncSocket::CreatePair(&socket1, &socket2);
std::move(stream_request_data.created_callback)
- .Run({base::in_place, mojo::SharedBufferHandle::Create(shmem_size),
+ .Run({base::in_place,
+ base::ReadOnlySharedMemoryRegion::Create(shmem_size).region,
mojo::WrapPlatformFile(socket1.Release())});
EXPECT_CALL(env.renderer_factory_client, OnStreamCreated());
@@ -248,7 +249,8 @@ TEST(AudioLoopbackStreamBrokerTest, MutedStreamCreation_Mutes) {
base::SyncSocket socket1, socket2;
base::SyncSocket::CreatePair(&socket1, &socket2);
std::move(stream_request_data.created_callback)
- .Run({base::in_place, mojo::SharedBufferHandle::Create(shmem_size),
+ .Run({base::in_place,
+ base::ReadOnlySharedMemoryRegion::Create(shmem_size).region,
mojo::WrapPlatformFile(socket1.Release())});
EXPECT_CALL(env.renderer_factory_client, OnStreamCreated());
@@ -277,7 +279,8 @@ TEST(AudioLoopbackStreamBrokerTest, SourceGone_CallsDeleter) {
base::SyncSocket socket1, socket2;
base::SyncSocket::CreatePair(&socket1, &socket2);
std::move(stream_request_data.created_callback)
- .Run({base::in_place, mojo::SharedBufferHandle::Create(shmem_size),
+ .Run({base::in_place,
+ base::ReadOnlySharedMemoryRegion::Create(shmem_size).region,
mojo::WrapPlatformFile(socket1.Release())});
EXPECT_CALL(env.renderer_factory_client, OnStreamCreated());
diff --git a/chromium/content/browser/media/audio_output_stream_broker.cc b/chromium/content/browser/media/audio_output_stream_broker.cc
index 21cf65ea694..0d2f3deafe2 100644
--- a/chromium/content/browser/media/audio_output_stream_broker.cc
+++ b/chromium/content/browser/media/audio_output_stream_broker.cc
@@ -48,7 +48,7 @@ AudioOutputStreamBroker::AudioOutputStreamBroker(
// Unretained is safe because |this| owns |client_|
client_.set_connection_error_handler(base::BindOnce(
- &AudioOutputStreamBroker::Cleanup, base::Unretained(this)));
+ &AudioOutputStreamBroker::ClientBindingLost, base::Unretained(this)));
}
AudioOutputStreamBroker::~AudioOutputStreamBroker() {
@@ -101,7 +101,7 @@ void AudioOutputStreamBroker::CreateStream(
void AudioOutputStreamBroker::StreamCreated(
media::mojom::AudioOutputStreamPtr stream,
- media::mojom::AudioDataPipePtr data_pipe) {
+ media::mojom::ReadWriteAudioDataPipePtr data_pipe) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
TRACE_EVENT_NESTABLE_ASYNC_END1("audio", "CreateStream", this, "success",
!!data_pipe);
@@ -149,6 +149,12 @@ void AudioOutputStreamBroker::ObserverBindingLost(
Cleanup();
}
+void AudioOutputStreamBroker::ClientBindingLost() {
+ disconnect_reason_ = media::mojom::AudioOutputStreamObserver::
+ DisconnectReason::kTerminatedByClient;
+ Cleanup();
+}
+
void AudioOutputStreamBroker::Cleanup() {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
std::move(deleter_).Run(this);
diff --git a/chromium/content/browser/media/audio_output_stream_broker.h b/chromium/content/browser/media/audio_output_stream_broker.h
index d997649ff6d..f2480aa0140 100644
--- a/chromium/content/browser/media/audio_output_stream_broker.h
+++ b/chromium/content/browser/media/audio_output_stream_broker.h
@@ -44,8 +44,9 @@ class CONTENT_EXPORT AudioOutputStreamBroker final : public AudioStreamBroker {
private:
void StreamCreated(media::mojom::AudioOutputStreamPtr stream,
- media::mojom::AudioDataPipePtr data_pipe);
+ media::mojom::ReadWriteAudioDataPipePtr data_pipe);
void ObserverBindingLost(uint32_t reason, const std::string& description);
+ void ClientBindingLost();
void Cleanup();
SEQUENCE_CHECKER(owning_sequence_);
diff --git a/chromium/content/browser/media/audio_output_stream_broker_unittest.cc b/chromium/content/browser/media/audio_output_stream_broker_unittest.cc
index 5427db631be..7a9d488e322 100644
--- a/chromium/content/browser/media/audio_output_stream_broker_unittest.cc
+++ b/chromium/content/browser/media/audio_output_stream_broker_unittest.cc
@@ -53,7 +53,7 @@ class MockAudioOutputStreamProviderClient
~MockAudioOutputStreamProviderClient() override {}
void Created(media::mojom::AudioOutputStreamPtr,
- media::mojom::AudioDataPipePtr) override {
+ media::mojom::ReadWriteAudioDataPipePtr) override {
OnCreated();
}
@@ -197,7 +197,7 @@ TEST(AudioOutputStreamBrokerTest, StreamCreationSuccess_Propagates) {
base::SyncSocket socket1, socket2;
base::SyncSocket::CreatePair(&socket1, &socket2);
std::move(stream_request_data.created_callback)
- .Run({base::in_place, mojo::SharedBufferHandle::Create(kShMemSize),
+ .Run({base::in_place, base::UnsafeSharedMemoryRegion::Create(kShMemSize),
mojo::WrapPlatformFile(socket1.Release())});
EXPECT_CALL(env.provider_client, OnCreated());
diff --git a/chromium/content/browser/media/audio_stream_monitor.cc b/chromium/content/browser/media/audio_stream_monitor.cc
index 67c0baebe0b..324f3105a21 100644
--- a/chromium/content/browser/media/audio_stream_monitor.cc
+++ b/chromium/content/browser/media/audio_stream_monitor.cc
@@ -192,7 +192,7 @@ void AudioStreamMonitor::UpdateStreams() {
if (is_audible_ != was_audible) {
MaybeToggle();
- web_contents_->OnAudioStateChanged(is_audible_);
+ web_contents_->OnAudioStateChanged();
}
}
diff --git a/chromium/content/browser/media/capture/aura_window_capture_machine.cc b/chromium/content/browser/media/capture/aura_window_capture_machine.cc
deleted file mode 100644
index 2f6caae4995..00000000000
--- a/chromium/content/browser/media/capture/aura_window_capture_machine.cc
+++ /dev/null
@@ -1,485 +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/media/capture/aura_window_capture_machine.h"
-
-#include <algorithm>
-#include <utility>
-
-#include "base/logging.h"
-#include "base/metrics/histogram_macros.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/gl_helper.h"
-#include "content/browser/compositor/image_transport_factory.h"
-#include "content/browser/media/capture/desktop_capture_device_uma_types.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/common/service_manager_connection.h"
-#include "media/base/video_util.h"
-#include "media/capture/content/thread_safe_capture_oracle.h"
-#include "media/capture/content/video_capture_oracle.h"
-#include "media/capture/video_capture_types.h"
-#include "services/device/public/mojom/constants.mojom.h"
-#include "services/device/public/mojom/wake_lock_provider.mojom.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "skia/ext/image_operations.h"
-#include "ui/aura/client/screen_position_client.h"
-#include "ui/aura/env.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_observer.h"
-#include "ui/aura/window_tree_host.h"
-#include "ui/base/cursor/cursors_aura.h"
-#include "ui/compositor/compositor.h"
-#include "ui/compositor/dip_util.h"
-#include "ui/compositor/layer.h"
-
-namespace content {
-
-AuraWindowCaptureMachine::AuraWindowCaptureMachine()
- : desktop_window_(nullptr),
- screen_capture_(false),
- frame_capture_active_(true),
- weak_factory_(this) {}
-
-AuraWindowCaptureMachine::~AuraWindowCaptureMachine() {}
-
-void AuraWindowCaptureMachine::Start(
- const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy,
- const media::VideoCaptureParams& params,
- const base::Callback<void(bool)> callback) {
- // Starts the capture machine asynchronously.
- BrowserThread::PostTaskAndReplyWithResult(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&AuraWindowCaptureMachine::InternalStart,
- base::Unretained(this),
- oracle_proxy,
- params),
- callback);
-}
-
-bool AuraWindowCaptureMachine::InternalStart(
- const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy,
- const media::VideoCaptureParams& params) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- // The window might be destroyed between SetWindow() and Start().
- if (!desktop_window_)
- return false;
-
- // If the associated layer is already destroyed then return failure.
- ui::Layer* layer = desktop_window_->layer();
- if (!layer)
- return false;
-
- DCHECK(oracle_proxy);
- oracle_proxy_ = oracle_proxy;
- capture_params_ = params;
-
- // Update capture size.
- UpdateCaptureSize();
-
- // Start observing compositor updates.
- aura::WindowTreeHost* const host = desktop_window_->GetHost();
- ui::Compositor* const compositor = host ? host->compositor() : nullptr;
- if (!compositor)
- return false;
- compositor->AddAnimationObserver(this);
-
- // Start observing for GL context losses.
- compositor->context_factory()->AddObserver(this);
-
- DCHECK(!wake_lock_);
- // Request Wake Lock. In some testing contexts, the service manager
- // connection isn't initialized.
- if (ServiceManagerConnection::GetForProcess()) {
- service_manager::Connector* connector =
- ServiceManagerConnection::GetForProcess()->GetConnector();
- DCHECK(connector);
- device::mojom::WakeLockProviderPtr wake_lock_provider;
- connector->BindInterface(device::mojom::kServiceName,
- mojo::MakeRequest(&wake_lock_provider));
- wake_lock_provider->GetWakeLockWithoutContext(
- device::mojom::WakeLockType::kPreventDisplaySleep,
- device::mojom::WakeLockReason::kOther, "Aura window or desktop capture",
- mojo::MakeRequest(&wake_lock_));
-
- wake_lock_->RequestWakeLock();
- }
-
- return true;
-}
-
-void AuraWindowCaptureMachine::Suspend() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&AuraWindowCaptureMachine::InternalSuspend,
- base::Unretained(this)));
-}
-
-void AuraWindowCaptureMachine::InternalSuspend() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DVLOG(1) << "Suspending frame capture and delivery.";
- frame_capture_active_ = false;
-}
-
-void AuraWindowCaptureMachine::Resume() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&AuraWindowCaptureMachine::InternalResume,
- base::Unretained(this)));
-}
-
-void AuraWindowCaptureMachine::InternalResume() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DVLOG(1) << "Resuming frame capture and delivery.";
- frame_capture_active_ = true;
- // Whenever capture resumes, capture a refresh frame immediately to make sure
- // no content updates are missing from the video stream.
- MaybeCaptureForRefresh();
-}
-
-void AuraWindowCaptureMachine::Stop(const base::Closure& callback) {
- // Stops the capture machine asynchronously.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&AuraWindowCaptureMachine::InternalStop,
- base::Unretained(this), callback));
-}
-
-void AuraWindowCaptureMachine::InternalStop(const base::Closure& callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- // Cancel any and all outstanding callbacks owned by external modules.
- weak_factory_.InvalidateWeakPtrs();
-
- if (wake_lock_)
- wake_lock_->CancelWakeLock();
- // Stop observing compositor and window events.
- if (desktop_window_) {
- if (aura::WindowTreeHost* host = desktop_window_->GetHost()) {
- if (ui::Compositor* compositor = host->compositor()) {
- compositor->RemoveAnimationObserver(this);
- compositor->context_factory()->RemoveObserver(this);
- }
- }
- desktop_window_->RemoveObserver(this);
- desktop_window_ = nullptr;
- cursor_renderer_.reset();
- }
-
- OnLostResources();
-
- callback.Run();
-}
-
-void AuraWindowCaptureMachine::MaybeCaptureForRefresh() {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(
- &AuraWindowCaptureMachine::Capture,
- // Use of Unretained() is safe here since this task must run
- // before InternalStop().
- base::Unretained(this), base::TimeTicks()));
-}
-
-void AuraWindowCaptureMachine::SetWindow(aura::Window* window) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- DCHECK(!desktop_window_);
- desktop_window_ = window;
- cursor_renderer_.reset(
- new CursorRendererAura(CursorRenderer::CURSOR_DISPLAYED_ALWAYS));
- cursor_renderer_->SetTargetView(window);
-
- // Start observing window events.
- desktop_window_->AddObserver(this);
-
- // We must store this for the UMA reporting in DidCopyOutput() as
- // desktop_window_ might be destroyed at that point.
- screen_capture_ = window->IsRootWindow();
- IncrementDesktopCaptureCounter(screen_capture_ ? SCREEN_CAPTURER_CREATED
- : WINDOW_CAPTURER_CREATED);
-}
-
-void AuraWindowCaptureMachine::UpdateCaptureSize() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (oracle_proxy_ && desktop_window_) {
- ui::Layer* layer = desktop_window_->layer();
- oracle_proxy_->UpdateCaptureSize(ui::ConvertSizeToPixel(
- layer, layer->bounds().size()));
- }
-}
-
-void AuraWindowCaptureMachine::Capture(base::TimeTicks event_time) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- // Do not capture if the desktop window is already destroyed.
- if (!desktop_window_)
- return;
-
- scoped_refptr<media::VideoFrame> frame;
- media::ThreadSafeCaptureOracle::CaptureFrameCallback capture_frame_cb;
-
- // TODO(miu): Need to fix this so the compositor is providing the presentation
- // timestamps and damage regions, to leverage the frame timestamp rewriting
- // logic. http://crbug.com/492839
- const base::TimeTicks start_time = base::TimeTicks::Now();
- media::VideoCaptureOracle::Event event;
- if (event_time.is_null()) {
- event = media::VideoCaptureOracle::kRefreshRequest;
- event_time = start_time;
- } else {
- event = media::VideoCaptureOracle::kCompositorUpdate;
- }
- if (oracle_proxy_->ObserveEventAndDecideCapture(
- event, gfx::Rect(), event_time, &frame, &capture_frame_cb)) {
- std::unique_ptr<viz::CopyOutputRequest> request =
- std::make_unique<viz::CopyOutputRequest>(
- viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE,
- base::BindOnce(&AuraWindowCaptureMachine::DidCopyOutput,
- weak_factory_.GetWeakPtr(), std::move(frame),
- event_time, start_time, capture_frame_cb));
- gfx::Rect window_rect = gfx::Rect(desktop_window_->bounds().width(),
- desktop_window_->bounds().height());
- request->set_area(window_rect);
- desktop_window_->layer()->RequestCopyOfOutput(std::move(request));
- }
-}
-
-void AuraWindowCaptureMachine::DidCopyOutput(
- scoped_refptr<media::VideoFrame> video_frame,
- base::TimeTicks event_time,
- base::TimeTicks start_time,
- const CaptureFrameCallback& capture_frame_cb,
- std::unique_ptr<viz::CopyOutputResult> result) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- static bool first_call = true;
-
- const bool succeeded = ProcessCopyOutputResponse(
- video_frame, event_time, capture_frame_cb, std::move(result));
-
- const base::TimeDelta capture_time = base::TimeTicks::Now() - start_time;
-
- // The two UMA_ blocks must be put in its own scope since it creates a static
- // variable which expected constant histogram name.
- if (screen_capture_) {
- UMA_HISTOGRAM_TIMES(kUmaScreenCaptureTime, capture_time);
- } else {
- UMA_HISTOGRAM_TIMES(kUmaWindowCaptureTime, capture_time);
- }
-
- if (first_call) {
- first_call = false;
- if (screen_capture_) {
- IncrementDesktopCaptureCounter(succeeded ? FIRST_SCREEN_CAPTURE_SUCCEEDED
- : FIRST_SCREEN_CAPTURE_FAILED);
- } else {
- IncrementDesktopCaptureCounter(succeeded
- ? FIRST_WINDOW_CAPTURE_SUCCEEDED
- : FIRST_WINDOW_CAPTURE_FAILED);
- }
- }
-
- // If ProcessCopyOutputResponse() failed, it will not run |capture_frame_cb|,
- // so do that now.
- if (!succeeded)
- capture_frame_cb.Run(std::move(video_frame), event_time, false);
-}
-
-bool AuraWindowCaptureMachine::ProcessCopyOutputResponse(
- scoped_refptr<media::VideoFrame> video_frame,
- base::TimeTicks event_time,
- 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.";
- return false;
- }
- if (result->IsEmpty()) {
- VLOG(1) << "CopyOutputRequest failed: Empty result.";
- return false;
- }
- DCHECK(video_frame);
-
- // Compute the dest size we want after the letterboxing resize. Make the
- // coordinates and sizes even because we letterbox in YUV space
- // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
- // line up correctly.
- // The video frame's visible_rect() and the result's size() are both physical
- // pixels.
- gfx::Rect region_in_frame = media::ComputeLetterboxRegion(
- video_frame->visible_rect(), result->size());
- region_in_frame = gfx::Rect(region_in_frame.x() & ~1,
- region_in_frame.y() & ~1,
- region_in_frame.width() & ~1,
- region_in_frame.height() & ~1);
- if (region_in_frame.IsEmpty()) {
- VLOG(1) << "Aborting capture: Computed empty letterboxed content region.";
- return false;
- }
-
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
- viz::GLHelper* gl_helper = factory->GetGLHelper();
- if (!gl_helper) {
- VLOG(1) << "Aborting capture: No GLHelper available for YUV readback.";
- 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);
- viz::GLHelper::ScalerInterface* const scaler =
- yuv_readback_pipeline_->scaler();
- const gfx::Vector2d scale_from(result->size().width(),
- result->size().height());
- const gfx::Vector2d scale_to(region_in_frame.width(),
- region_in_frame.height());
- if (scale_from == scale_to) {
- if (scaler)
- yuv_readback_pipeline_->SetScaler(nullptr);
- } else if (!scaler || !scaler->IsSameScaleRatio(scale_from, scale_to)) {
- std::unique_ptr<viz::GLHelper::ScalerInterface> fast_scaler =
- gl_helper->CreateScaler(viz::GLHelper::SCALER_QUALITY_FAST, scale_from,
- scale_to, false, false, false);
- DCHECK(
- fast_scaler); // Arguments to CreateScaler() should never be invalid.
- yuv_readback_pipeline_->SetScaler(std::move(fast_scaler));
- }
-
- yuv_readback_pipeline_->ReadbackYUV(
- 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),
- video_frame->data(media::VideoFrame::kUPlane),
- video_frame->stride(media::VideoFrame::kVPlane),
- video_frame->data(media::VideoFrame::kVPlane), region_in_frame.origin(),
- base::Bind(&CopyOutputFinishedForVideo, weak_factory_.GetWeakPtr(),
- event_time, capture_frame_cb, video_frame, region_in_frame,
- base::Passed(&release_callback)));
- media::LetterboxVideoFrame(video_frame.get(), region_in_frame);
- return true;
-}
-
-using CaptureFrameCallback =
- media::ThreadSafeCaptureOracle::CaptureFrameCallback;
-
-void AuraWindowCaptureMachine::CopyOutputFinishedForVideo(
- base::WeakPtr<AuraWindowCaptureMachine> machine,
- base::TimeTicks event_time,
- const CaptureFrameCallback& capture_frame_cb,
- scoped_refptr<media::VideoFrame> target,
- const gfx::Rect& region_in_frame,
- std::unique_ptr<viz::SingleReleaseCallback> release_callback,
- bool result) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- release_callback->Run(gpu::SyncToken(), false);
-
- // Render the cursor and deliver the captured frame if the
- // AuraWindowCaptureMachine has not been stopped (i.e., the WeakPtr is
- // still valid).
- if (machine) {
- if (machine->cursor_renderer_ && result)
- machine->cursor_renderer_->RenderOnVideoFrame(target.get(),
- region_in_frame, nullptr);
- } else {
- VLOG(1) << "Aborting capture: AuraWindowCaptureMachine has gone away.";
- result = false;
- }
-
- capture_frame_cb.Run(std::move(target), event_time, result);
-}
-
-void AuraWindowCaptureMachine::OnWindowBoundsChanged(
- aura::Window* window,
- const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds,
- ui::PropertyChangeReason reason) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(desktop_window_ && window == desktop_window_);
-
- // Post a task to update capture size after first returning to the event loop.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&AuraWindowCaptureMachine::UpdateCaptureSize,
- weak_factory_.GetWeakPtr()));
-}
-
-void AuraWindowCaptureMachine::OnWindowDestroying(aura::Window* window) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- InternalStop(base::DoNothing());
-
- oracle_proxy_->ReportError(FROM_HERE, "OnWindowDestroying()");
-}
-
-void AuraWindowCaptureMachine::OnWindowAddedToRootWindow(
- aura::Window* window) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(window == desktop_window_);
-
- if (aura::WindowTreeHost* host = window->GetHost()) {
- if (ui::Compositor* compositor = host->compositor())
- compositor->AddAnimationObserver(this);
- }
-}
-
-void AuraWindowCaptureMachine::OnWindowRemovingFromRootWindow(
- aura::Window* window,
- aura::Window* new_root) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(window == desktop_window_);
-
- if (aura::WindowTreeHost* host = window->GetHost()) {
- if (ui::Compositor* compositor = host->compositor()) {
- compositor->RemoveAnimationObserver(this);
- compositor->context_factory()->RemoveObserver(this);
- }
- }
-}
-
-void AuraWindowCaptureMachine::OnAnimationStep(base::TimeTicks timestamp) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(!timestamp.is_null());
-
- // HACK: The compositor invokes this observer method to step layer animation
- // forward. Scheduling frame capture was not the intention, and so invoking
- // this method does not actually indicate the content has changed. However,
- // this is the only reliable way to ensure all screen changes are captured, as
- // of this writing.
- // http://crbug.com/600031
- //
- // TODO(miu): Need a better observer callback interface from the compositor
- // for this use case. The solution here will always capture frames at the
- // maximum framerate, which means CPU/GPU is being wasted on redundant
- // captures and quality/smoothness of animating content will suffer
- // significantly.
- // http://crbug.com/492839
- if (frame_capture_active_)
- Capture(timestamp);
-}
-
-void AuraWindowCaptureMachine::OnCompositingShuttingDown(
- ui::Compositor* compositor) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- compositor->RemoveAnimationObserver(this);
- compositor->context_factory()->RemoveObserver(this);
-}
-
-void AuraWindowCaptureMachine::OnLostResources() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- yuv_readback_pipeline_.reset();
-}
-
-} // namespace content
diff --git a/chromium/content/browser/media/capture/aura_window_capture_machine.h b/chromium/content/browser/media/capture/aura_window_capture_machine.h
deleted file mode 100644
index d6067419741..00000000000
--- a/chromium/content/browser/media/capture/aura_window_capture_machine.h
+++ /dev/null
@@ -1,150 +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_MEDIA_CAPTURE_AURA_WINDOW_CAPTURE_MACHINE_H_
-#define CONTENT_BROWSER_MEDIA_CAPTURE_AURA_WINDOW_CAPTURE_MACHINE_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "content/browser/media/capture/cursor_renderer_aura.h"
-#include "media/capture/content/screen_capture_device_core.h"
-#include "services/device/public/mojom/wake_lock.mojom.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_observer.h"
-#include "ui/base/cursor/cursors_aura.h"
-#include "ui/compositor/compositor.h"
-#include "ui/compositor/compositor_animation_observer.h"
-
-namespace viz {
-class CopyOutputResult;
-class ReadbackYUVInterface;
-}
-
-namespace content {
-
-// AuraWindowCaptureMachine uses the compositor to capture Aura windows.
-//
-// It is used for browser window capture on platforms that use Aura (Windows,
-// Linux, and Chrome OS) and additionally for desktop capture on Chrome OS.
-class AuraWindowCaptureMachine : public media::VideoCaptureMachine,
- public aura::WindowObserver,
- public ui::ContextFactoryObserver,
- public ui::CompositorAnimationObserver {
- public:
- AuraWindowCaptureMachine();
- ~AuraWindowCaptureMachine() 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;
- void MaybeCaptureForRefresh() override;
-
- // Implements aura::WindowObserver.
- void OnWindowBoundsChanged(aura::Window* window,
- const gfx::Rect& old_bounds,
- 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,
- aura::Window* new_root) override;
-
- // ui::CompositorAnimationObserver implementation.
- void OnAnimationStep(base::TimeTicks timestamp) override;
- void OnCompositingShuttingDown(ui::Compositor* compositor) override;
-
- // Sets the window to use for capture.
- void SetWindow(aura::Window* window);
-
- private:
- bool InternalStart(
- const scoped_refptr<media::ThreadSafeCaptureOracle>& oracle_proxy,
- const media::VideoCaptureParams& params);
- void InternalSuspend();
- void InternalResume();
- void InternalStop(const base::Closure& callback);
-
- // Captures a frame. |event_time| is provided by the compositor, or is null
- // for refresh requests.
- void Capture(base::TimeTicks event_time);
-
- // Update capture size. Must be called on the UI thread.
- void UpdateCaptureSize();
-
- using CaptureFrameCallback =
- media::ThreadSafeCaptureOracle::CaptureFrameCallback;
-
- // Response callback for cc::Layer::RequestCopyOfOutput().
- void DidCopyOutput(scoped_refptr<media::VideoFrame> video_frame,
- base::TimeTicks event_time,
- base::TimeTicks start_time,
- const CaptureFrameCallback& capture_frame_cb,
- std::unique_ptr<viz::CopyOutputResult> result);
-
- // A helper which does the real work for DidCopyOutput. Returns true if
- // succeeded and |capture_frame_cb| will be run at some future point. Returns
- // false on error, and |capture_frame_cb| should be run by the caller (with
- // failure status).
- bool ProcessCopyOutputResponse(scoped_refptr<media::VideoFrame> video_frame,
- base::TimeTicks event_time,
- const CaptureFrameCallback& capture_frame_cb,
- std::unique_ptr<viz::CopyOutputResult> result);
-
- // ui::ContextFactoryObserver implementation.
- void OnLostResources() override;
-
- // Renders the cursor if needed and then delivers the captured frame.
- static void CopyOutputFinishedForVideo(
- base::WeakPtr<AuraWindowCaptureMachine> machine,
- base::TimeTicks event_time,
- const CaptureFrameCallback& capture_frame_cb,
- scoped_refptr<media::VideoFrame> target,
- const gfx::Rect& region_in_frame,
- std::unique_ptr<viz::SingleReleaseCallback> release_callback,
- bool result);
-
- // The window associated with the desktop.
- aura::Window* desktop_window_;
-
- // Whether screen capturing or window capture.
- bool screen_capture_;
-
- // Makes all the decisions about which frames to copy, and how.
- scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy_;
-
- // The capture parameters for this capture.
- media::VideoCaptureParams capture_params_;
-
- // YUV readback pipeline.
- std::unique_ptr<viz::ReadbackYUVInterface> yuv_readback_pipeline_;
-
- // Renders mouse cursor on frame.
- std::unique_ptr<content::CursorRendererAura> cursor_renderer_;
-
- // TODO(jiayl): Remove wake_lock_ when there is an API to keep the
- // screen from sleeping for the drive-by web.
- device::mojom::WakeLockPtr wake_lock_;
-
- // False while frame capture has been suspended. All other aspects of the
- // machine are maintained.
- bool frame_capture_active_;
-
- // WeakPtrs are used for the asynchronous capture callbacks passed to external
- // modules. They are only valid on the UI thread and become invalidated
- // immediately when InternalStop() is called to ensure that no more captured
- // frames will be delivered to the client.
- base::WeakPtrFactory<AuraWindowCaptureMachine> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(AuraWindowCaptureMachine);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_MEDIA_CAPTURE_AURA_WINDOW_CAPTURE_MACHINE_H_
diff --git a/chromium/content/browser/media/capture/content_capture_device_browsertest_base.cc b/chromium/content/browser/media/capture/content_capture_device_browsertest_base.cc
index 73ba0a4823f..a33ddda3ee8 100644
--- a/chromium/content/browser/media/capture/content_capture_device_browsertest_base.cc
+++ b/chromium/content/browser/media/capture/content_capture_device_browsertest_base.cc
@@ -143,8 +143,8 @@ void ContentCaptureDeviceBrowserTestBase::
void ContentCaptureDeviceBrowserTestBase::StopAndDeAllocate() {
device_->StopAndDeAllocate();
- RunUntilIdle();
device_.reset();
+ RunUntilIdle();
}
void ContentCaptureDeviceBrowserTestBase::RunUntilIdle() {
diff --git a/chromium/content/browser/media/capture/cursor_renderer.cc b/chromium/content/browser/media/capture/cursor_renderer.cc
index 66352cc8a80..6434a15a422 100644
--- a/chromium/content/browser/media/capture/cursor_renderer.cc
+++ b/chromium/content/browser/media/capture/cursor_renderer.cc
@@ -283,11 +283,11 @@ CursorRendererUndoer::CursorRendererUndoer() = default;
CursorRendererUndoer::~CursorRendererUndoer() = default;
-CursorRendererUndoer::CursorRendererUndoer(CursorRendererUndoer&& other) =
- default;
+CursorRendererUndoer::CursorRendererUndoer(
+ CursorRendererUndoer&& other) noexcept = default;
CursorRendererUndoer& CursorRendererUndoer::operator=(
- CursorRendererUndoer&& other) = default;
+ CursorRendererUndoer&& other) noexcept = default;
namespace {
diff --git a/chromium/content/browser/media/capture/cursor_renderer.h b/chromium/content/browser/media/capture/cursor_renderer.h
index b9d1acc4927..64409bd5b01 100644
--- a/chromium/content/browser/media/capture/cursor_renderer.h
+++ b/chromium/content/browser/media/capture/cursor_renderer.h
@@ -185,8 +185,8 @@ class CONTENT_EXPORT CursorRendererUndoer {
CursorRendererUndoer();
~CursorRendererUndoer();
- CursorRendererUndoer(CursorRendererUndoer&& other);
- CursorRendererUndoer& operator=(CursorRendererUndoer&& other);
+ CursorRendererUndoer(CursorRendererUndoer&& other) noexcept;
+ CursorRendererUndoer& operator=(CursorRendererUndoer&& other) noexcept;
void TakeSnapshot(const media::VideoFrame& frame, const gfx::Rect& rect);
diff --git a/chromium/content/browser/media/capture/desktop_capture_device_aura.cc b/chromium/content/browser/media/capture/desktop_capture_device_aura.cc
deleted file mode 100644
index a80e01233d3..00000000000
--- a/chromium/content/browser/media/capture/desktop_capture_device_aura.cc
+++ /dev/null
@@ -1,82 +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/media/capture/desktop_capture_device_aura.h"
-
-#include <utility>
-
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/timer/timer.h"
-#include "content/browser/media/capture/aura_window_capture_machine.h"
-#include "content/browser/media/capture/desktop_capture_device_uma_types.h"
-#include "content/public/browser/browser_thread.h"
-#include "ui/aura/window.h"
-
-namespace content {
-
-namespace {
-
-void SetCaptureSource(AuraWindowCaptureMachine* machine,
- const DesktopMediaID& source) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- aura::Window* window = DesktopMediaID::GetAuraWindowById(source);
- if (window) {
- machine->SetWindow(window);
- if (source.type == DesktopMediaID::TYPE_SCREEN) {
- if (source.audio_share)
- IncrementDesktopCaptureCounter(SCREEN_CAPTURER_CREATED_WITH_AUDIO);
- else
- IncrementDesktopCaptureCounter(SCREEN_CAPTURER_CREATED_WITHOUT_AUDIO);
- }
- }
-}
-
-} // namespace
-
-DesktopCaptureDeviceAura::DesktopCaptureDeviceAura(
- const DesktopMediaID& source) {
- AuraWindowCaptureMachine* machine = new AuraWindowCaptureMachine();
- core_.reset(new media::ScreenCaptureDeviceCore(base::WrapUnique(machine)));
- // |core_| owns |machine| and deletes it on UI thread so passing the raw
- // pointer to the UI thread is safe here.
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&SetCaptureSource, machine, source));
-}
-
-DesktopCaptureDeviceAura::~DesktopCaptureDeviceAura() {
- DVLOG(2) << "DesktopCaptureDeviceAura@" << this << " destroying.";
-}
-
-// static
-std::unique_ptr<media::VideoCaptureDevice> DesktopCaptureDeviceAura::Create(
- const DesktopMediaID& source) {
- if (source.aura_id == DesktopMediaID::kNullId)
- return nullptr;
- return std::unique_ptr<media::VideoCaptureDevice>(
- new DesktopCaptureDeviceAura(source));
-}
-
-void DesktopCaptureDeviceAura::AllocateAndStart(
- const media::VideoCaptureParams& params,
- std::unique_ptr<Client> client) {
- DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
- core_->AllocateAndStart(params, std::move(client));
-}
-
-void DesktopCaptureDeviceAura::RequestRefreshFrame() {
- core_->RequestRefreshFrame();
-}
-
-void DesktopCaptureDeviceAura::StopAndDeAllocate() {
- core_->StopAndDeAllocate();
-}
-
-void DesktopCaptureDeviceAura::OnUtilizationReport(int frame_feedback_id,
- double utilization) {
- core_->OnConsumerReportingUtilization(frame_feedback_id, utilization);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/media/capture/desktop_capture_device_aura.h b/chromium/content/browser/media/capture/desktop_capture_device_aura.h
deleted file mode 100644
index 6eee43a0edb..00000000000
--- a/chromium/content/browser/media/capture/desktop_capture_device_aura.h
+++ /dev/null
@@ -1,48 +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_MEDIA_CAPTURE_DESKTOP_CAPTURE_DEVICE_AURA_H_
-#define CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_CAPTURE_DEVICE_AURA_H_
-
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "content/public/browser/desktop_media_id.h"
-#include "media/capture/content/screen_capture_device_core.h"
-#include "media/capture/video/video_capture_device.h"
-
-namespace content {
-
-// An implementation of VideoCaptureDevice that mirrors an Aura window.
-class CONTENT_EXPORT DesktopCaptureDeviceAura
- : public media::VideoCaptureDevice {
- public:
- // Creates a VideoCaptureDevice for the Aura desktop. If |source| does not
- // reference a registered aura window, returns nullptr instead.
- static std::unique_ptr<media::VideoCaptureDevice> Create(
- const DesktopMediaID& source);
-
- ~DesktopCaptureDeviceAura() override;
-
- // VideoCaptureDevice implementation.
- void AllocateAndStart(const media::VideoCaptureParams& params,
- std::unique_ptr<Client> client) override;
- void RequestRefreshFrame() override;
- void StopAndDeAllocate() override;
- void OnUtilizationReport(int frame_feedback_id, double utilization) override;
-
- private:
- explicit DesktopCaptureDeviceAura(const DesktopMediaID& source);
-
- std::unique_ptr<media::ScreenCaptureDeviceCore> core_;
-
- DISALLOW_COPY_AND_ASSIGN(DesktopCaptureDeviceAura);
-};
-
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_MEDIA_CAPTURE_DESKTOP_CAPTURE_DEVICE_AURA_H_
diff --git a/chromium/content/browser/media/capture/desktop_capture_device_aura_unittest.cc b/chromium/content/browser/media/capture/desktop_capture_device_aura_unittest.cc
deleted file mode 100644
index 7de25f82bfa..00000000000
--- a/chromium/content/browser/media/capture/desktop_capture_device_aura_unittest.cc
+++ /dev/null
@@ -1,175 +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/media/capture/desktop_capture_device_aura.h"
-
-#include <stddef.h>
-#include <stdint.h>
-#include <utility>
-
-#include "base/location.h"
-#include "base/macros.h"
-#include "base/run_loop.h"
-#include "base/synchronization/waitable_event.h"
-#include "content/browser/compositor/test/test_image_transport_factory.h"
-#include "content/public/browser/desktop_media_id.h"
-#include "content/public/test/test_browser_thread_bundle.h"
-#include "media/capture/video_capture_types.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/aura/client/window_parenting_client.h"
-#include "ui/aura/test/aura_test_helper.h"
-#include "ui/aura/test/test_window_delegate.h"
-#include "ui/aura/window.h"
-#include "ui/wm/core/default_activation_client.h"
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::AtMost;
-using ::testing::DoAll;
-using ::testing::Expectation;
-using ::testing::InvokeWithoutArgs;
-using ::testing::SaveArg;
-
-namespace media {
-class VideoFrame;
-} // namespace media
-
-namespace content {
-namespace {
-
-const int kFrameRate = 30;
-
-class MockDeviceClient : public media::VideoCaptureDevice::Client {
- public:
- MOCK_METHOD7(OnIncomingCapturedData,
- void(const uint8_t* data,
- int length,
- const media::VideoCaptureFormat& frame_format,
- int rotation,
- base::TimeTicks reference_time,
- base::TimeDelta tiemstamp,
- int frame_feedback_id));
- MOCK_METHOD6(OnIncomingCapturedGfxBuffer,
- void(gfx::GpuMemoryBuffer* buffer,
- const media::VideoCaptureFormat& frame_format,
- int clockwise_rotation,
- base::TimeTicks reference_time,
- base::TimeDelta timestamp,
- int frame_feedback_id));
- MOCK_METHOD0(DoReserveOutputBuffer, void(void));
- MOCK_METHOD0(DoOnIncomingCapturedBuffer, void(void));
- MOCK_METHOD0(DoOnIncomingCapturedVideoFrame, void(void));
- MOCK_METHOD0(DoResurrectLastOutputBuffer, void(void));
- MOCK_METHOD2(OnError,
- void(const base::Location& from_here,
- const std::string& reason));
- MOCK_METHOD0(OnStarted, void(void));
-
- // Trampoline methods to workaround GMOCK problems with std::unique_ptr<>.
- Buffer ReserveOutputBuffer(const gfx::Size& dimensions,
- media::VideoPixelFormat format,
- int frame_feedback_id) override {
- EXPECT_EQ(media::PIXEL_FORMAT_I420, format);
- DoReserveOutputBuffer();
- return Buffer();
- }
- void OnIncomingCapturedBuffer(Buffer buffer,
- const media::VideoCaptureFormat& frame_format,
- base::TimeTicks reference_time,
- base::TimeDelta timestamp) override {
- DoOnIncomingCapturedBuffer();
- }
- void OnIncomingCapturedBufferExt(
- Buffer buffer,
- const media::VideoCaptureFormat& format,
- base::TimeTicks reference_time,
- base::TimeDelta timestamp,
- gfx::Rect visible_rect,
- const media::VideoFrameMetadata& additional_metadata) override {
- DoOnIncomingCapturedVideoFrame();
- }
- Buffer ResurrectLastOutputBuffer(const gfx::Size& dimensions,
- media::VideoPixelFormat format,
- int frame_feedback_id) override {
- EXPECT_EQ(media::PIXEL_FORMAT_I420, format);
- DoResurrectLastOutputBuffer();
- return Buffer();
- }
- double GetBufferPoolUtilization() const override { return 0.0; }
-};
-
-// Test harness that sets up a minimal environment with necessary stubs.
-class DesktopCaptureDeviceAuraTest : public testing::Test {
- public:
- DesktopCaptureDeviceAuraTest() = default;
- ~DesktopCaptureDeviceAuraTest() override = default;
-
- protected:
- void SetUp() override {
- // The ContextFactory must exist before any Compositors are created.
- ImageTransportFactory::SetFactory(
- std::make_unique<TestImageTransportFactory>());
- helper_.reset(new aura::test::AuraTestHelper());
- helper_->SetUp(
- ImageTransportFactory::GetInstance()->GetContextFactory(),
- ImageTransportFactory::GetInstance()->GetContextFactoryPrivate());
- new wm::DefaultActivationClient(helper_->root_window());
- // We need a window to cover desktop area so that DesktopCaptureDeviceAura
- // can use gfx::NativeWindow::GetWindowAtScreenPoint() to locate the
- // root window associated with the primary display.
- gfx::Rect desktop_bounds = root_window()->bounds();
- window_delegate_.reset(new aura::test::TestWindowDelegate());
- desktop_window_.reset(new aura::Window(window_delegate_.get()));
- desktop_window_->Init(ui::LAYER_TEXTURED);
- desktop_window_->SetBounds(desktop_bounds);
- aura::client::ParentWindowWithContext(
- desktop_window_.get(), root_window(), desktop_bounds);
- desktop_window_->Show();
- }
-
- void TearDown() override {
- helper_->RunAllPendingInMessageLoop();
- root_window()->RemoveChild(desktop_window_.get());
- desktop_window_.reset();
- window_delegate_.reset();
- helper_->TearDown();
- base::RunLoop().RunUntilIdle();
- ImageTransportFactory::Terminate();
- }
-
- aura::Window* root_window() { return helper_->root_window(); }
-
- private:
- TestBrowserThreadBundle thread_bundle_;
- std::unique_ptr<aura::test::AuraTestHelper> helper_;
- std::unique_ptr<aura::Window> desktop_window_;
- std::unique_ptr<aura::test::TestWindowDelegate> window_delegate_;
-
- DISALLOW_COPY_AND_ASSIGN(DesktopCaptureDeviceAuraTest);
-};
-
-TEST_F(DesktopCaptureDeviceAuraTest, StartAndStop) {
- std::unique_ptr<media::VideoCaptureDevice> capture_device =
- DesktopCaptureDeviceAura::Create(
- content::DesktopMediaID::RegisterAuraWindow(
- content::DesktopMediaID::TYPE_SCREEN, root_window()));
- ASSERT_TRUE(capture_device);
-
- std::unique_ptr<MockDeviceClient> client(new MockDeviceClient());
- EXPECT_CALL(*client, OnError(_, _)).Times(0);
- // |STARTED| is reported asynchronously, which may not be received if capture
- // is stopped immediately.
- EXPECT_CALL(*client, OnStarted()).Times(AtMost(1));
-
- media::VideoCaptureParams capture_params;
- capture_params.requested_format.frame_size.SetSize(640, 480);
- capture_params.requested_format.frame_rate = kFrameRate;
- capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
- capture_device->AllocateAndStart(capture_params, std::move(client));
- capture_device->StopAndDeAllocate();
-}
-
-} // namespace
-} // namespace content
diff --git a/chromium/content/browser/media/capture/fake_webcontent_capture_machine.cc b/chromium/content/browser/media/capture/fake_webcontent_capture_machine.cc
deleted file mode 100644
index f18b8835d6e..00000000000
--- a/chromium/content/browser/media/capture/fake_webcontent_capture_machine.cc
+++ /dev/null
@@ -1,35 +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/media/capture/fake_webcontent_capture_machine.h"
-
-#include "base/logging.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
deleted file mode 100644
index 92a5f84a3ec..00000000000
--- a/chromium/content/browser/media/capture/fake_webcontent_capture_machine.h
+++ /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.
-
-#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/frame_sink_video_capture_device.cc b/chromium/content/browser/media/capture/frame_sink_video_capture_device.cc
index 80ad28d503b..e096bf8cc5b 100644
--- a/chromium/content/browser/media/capture/frame_sink_video_capture_device.cc
+++ b/chromium/content/browser/media/capture/frame_sink_video_capture_device.cc
@@ -41,7 +41,7 @@ class ScopedFrameDoneHelper
: public base::ScopedClosureRunner,
public media::VideoCaptureDevice::Client::Buffer::ScopedAccessPermission {
public:
- ScopedFrameDoneHelper(base::OnceClosure done_callback)
+ explicit ScopedFrameDoneHelper(base::OnceClosure done_callback)
: base::ScopedClosureRunner(std::move(done_callback)) {}
~ScopedFrameDoneHelper() final = default;
};
@@ -258,12 +258,6 @@ void FrameSinkVideoCaptureDevice::OnFrameCaptured(
std::move(info));
}
-void FrameSinkVideoCaptureDevice::OnTargetLost(
- const viz::FrameSinkId& frame_sink_id) {
- // This is ignored because FrameSinkVideoCaptureDevice subclasses always call
- // OnTargetChanged() and OnTargetPermanentlyLost() to resolve lost targets.
-}
-
void FrameSinkVideoCaptureDevice::OnStopped() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -279,19 +273,19 @@ void FrameSinkVideoCaptureDevice::OnTargetChanged(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
target_ = frame_sink_id;
- // TODO(crbug.com/754872): When the frame sink is invalid, the capturer should
- // be told there is no target. This will require a mojo API change; and will
- // be addressed in a soon-upcoming CL.
- if (capturer_ && frame_sink_id.is_valid()) {
- capturer_->ChangeTarget(frame_sink_id);
+ if (capturer_) {
+ if (target_.is_valid()) {
+ capturer_->ChangeTarget(target_);
+ } else {
+ capturer_->ChangeTarget(base::nullopt);
+ }
}
}
void FrameSinkVideoCaptureDevice::OnTargetPermanentlyLost() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- target_ = viz::FrameSinkId();
-
+ OnTargetChanged(viz::FrameSinkId());
OnFatalError("Capture target has been permanently lost.");
}
@@ -376,9 +370,9 @@ void FrameSinkVideoCaptureDevice::OnFatalError(std::string message) {
FrameSinkVideoCaptureDevice::ConsumptionState::ConsumptionState() = default;
FrameSinkVideoCaptureDevice::ConsumptionState::~ConsumptionState() = default;
FrameSinkVideoCaptureDevice::ConsumptionState::ConsumptionState(
- FrameSinkVideoCaptureDevice::ConsumptionState&& other) = default;
+ FrameSinkVideoCaptureDevice::ConsumptionState&& other) noexcept = default;
FrameSinkVideoCaptureDevice::ConsumptionState&
FrameSinkVideoCaptureDevice::ConsumptionState::operator=(
- FrameSinkVideoCaptureDevice::ConsumptionState&& other) = default;
+ FrameSinkVideoCaptureDevice::ConsumptionState&& other) noexcept = default;
} // namespace content
diff --git a/chromium/content/browser/media/capture/frame_sink_video_capture_device.h b/chromium/content/browser/media/capture/frame_sink_video_capture_device.h
index fefe7b9d10c..341248435ea 100644
--- a/chromium/content/browser/media/capture/frame_sink_video_capture_device.h
+++ b/chromium/content/browser/media/capture/frame_sink_video_capture_device.h
@@ -6,6 +6,8 @@
#define CONTENT_BROWSER_MEDIA_CAPTURE_FRAME_SINK_VIDEO_CAPTURE_DEVICE_H_
#include <memory>
+#include <string>
+#include <utility>
#include <vector>
#include "base/macros.h"
@@ -76,7 +78,6 @@ class CONTENT_EXPORT FrameSinkVideoCaptureDevice
const gfx::Rect& update_rect,
const gfx::Rect& content_rect,
viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) final;
- void OnTargetLost(const viz::FrameSinkId& frame_sink_id) final;
void OnStopped() final;
// These are called to notify when the capture target has changed or was
@@ -147,8 +148,8 @@ class CONTENT_EXPORT FrameSinkVideoCaptureDevice
ConsumptionState();
~ConsumptionState();
- ConsumptionState(ConsumptionState&& other);
- ConsumptionState& operator=(ConsumptionState&& other);
+ ConsumptionState(ConsumptionState&& other) noexcept;
+ ConsumptionState& operator=(ConsumptionState&& other) noexcept;
};
std::vector<ConsumptionState> slots_;
diff --git a/chromium/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc b/chromium/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc
index b9cc7f8bad8..d8de88d4e46 100644
--- a/chromium/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc
+++ b/chromium/content/browser/media/capture/frame_sink_video_capture_device_unittest.cc
@@ -91,7 +91,12 @@ class MockFrameSinkVideoCapturer : public viz::mojom::FrameSinkVideoCapturer {
const gfx::Size& max_size,
bool use_fixed_aspect_ratio));
MOCK_METHOD1(SetAutoThrottlingEnabled, void(bool));
- MOCK_METHOD1(ChangeTarget, void(const viz::FrameSinkId& frame_sink_id));
+ void ChangeTarget(
+ const base::Optional<viz::FrameSinkId>& frame_sink_id) final {
+ DCHECK_NOT_ON_DEVICE_THREAD();
+ MockChangeTarget(frame_sink_id ? *frame_sink_id : viz::FrameSinkId());
+ }
+ MOCK_METHOD1(MockChangeTarget, void(const viz::FrameSinkId& frame_sink_id));
void Start(viz::mojom::FrameSinkVideoConsumerPtr consumer) final {
DCHECK_NOT_ON_DEVICE_THREAD();
consumer_ = std::move(consumer);
@@ -310,7 +315,7 @@ class FrameSinkVideoCaptureDeviceTest : public testing::Test {
EXPECT_CALL(capturer_,
SetResolutionConstraints(kResolution, kResolution, _));
constexpr viz::FrameSinkId frame_sink_id(1, 1);
- EXPECT_CALL(capturer_, ChangeTarget(frame_sink_id));
+ EXPECT_CALL(capturer_, MockChangeTarget(frame_sink_id));
EXPECT_CALL(capturer_, MockStart(NotNull()));
EXPECT_FALSE(capturer_.is_bound());
@@ -555,6 +560,7 @@ TEST_F(FrameSinkVideoCaptureDeviceTest, ShutsDownOnFatalError) {
// consumption, unbind the capturer, log an error with the VideoFrameReceiver,
// and destroy the VideoFrameReceiver.
{
+ EXPECT_CALL(capturer_, MockChangeTarget(viz::FrameSinkId()));
EXPECT_CALL(capturer_, MockStop());
POST_DEVICE_METHOD_CALL0(OnTargetPermanentlyLost);
WAIT_FOR_DEVICE_TASKS();
diff --git a/chromium/content/browser/media/capture/lame_window_capturer_chromeos.cc b/chromium/content/browser/media/capture/lame_window_capturer_chromeos.cc
index 95e5e769f1a..1086b27f68f 100644
--- a/chromium/content/browser/media/capture/lame_window_capturer_chromeos.cc
+++ b/chromium/content/browser/media/capture/lame_window_capturer_chromeos.cc
@@ -4,6 +4,8 @@
#include "content/browser/media/capture/lame_window_capturer_chromeos.h"
+#include <algorithm>
+
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
@@ -99,7 +101,7 @@ void LameWindowCapturerChromeOS::SetAutoThrottlingEnabled(bool enabled) {
}
void LameWindowCapturerChromeOS::ChangeTarget(
- const viz::FrameSinkId& frame_sink_id) {
+ const base::Optional<viz::FrameSinkId>& frame_sink_id) {
// The LameWindowCapturerChromeOS does not capture from compositor frame
// sinks.
}
diff --git a/chromium/content/browser/media/capture/lame_window_capturer_chromeos.h b/chromium/content/browser/media/capture/lame_window_capturer_chromeos.h
index 6978f755f07..2a467ecc20b 100644
--- a/chromium/content/browser/media/capture/lame_window_capturer_chromeos.h
+++ b/chromium/content/browser/media/capture/lame_window_capturer_chromeos.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_MEDIA_CAPTURE_LAME_WINDOW_CAPTURER_CHROMEOS_H_
#define CONTENT_BROWSER_MEDIA_CAPTURE_LAME_WINDOW_CAPTURER_CHROMEOS_H_
+#include <memory>
#include <utility>
#include <vector>
@@ -60,7 +61,8 @@ class LameWindowCapturerChromeOS : public viz::mojom::FrameSinkVideoCapturer,
const gfx::Size& max_size,
bool use_fixed_aspect_ratio) final;
void SetAutoThrottlingEnabled(bool enabled) final;
- void ChangeTarget(const viz::FrameSinkId& frame_sink_id) final;
+ void ChangeTarget(
+ const base::Optional<viz::FrameSinkId>& frame_sink_id) final;
void Start(viz::mojom::FrameSinkVideoConsumerPtr consumer) final;
void Stop() final;
void RequestRefreshFrame() final;
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 1e93e1c1ce3..9d5cf896498 100644
--- a/chromium/content/browser/media/capture/screen_capture_device_android.cc
+++ b/chromium/content/browser/media/capture/screen_capture_device_android.cc
@@ -4,36 +4,70 @@
#include "content/browser/media/capture/screen_capture_device_android.h"
+#include <utility>
+
#include "base/logging.h"
-#include "media/capture/content/android/screen_capture_machine_android.h"
+#include "media/capture/content/android/thread_safe_capture_oracle.h"
namespace content {
-ScreenCaptureDeviceAndroid::ScreenCaptureDeviceAndroid()
- : core_(std::make_unique<media::ScreenCaptureMachineAndroid>()) {}
+ScreenCaptureDeviceAndroid::ScreenCaptureDeviceAndroid() = default;
ScreenCaptureDeviceAndroid::~ScreenCaptureDeviceAndroid() {
- DVLOG(2) << "ScreenCaptureDeviceAndroid@" << this << " destroying.";
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(!oracle_proxy_);
}
void ScreenCaptureDeviceAndroid::AllocateAndStart(
const media::VideoCaptureParams& params,
std::unique_ptr<Client> client) {
- DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
- core_.AllocateAndStart(params, std::move(client));
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (params.requested_format.pixel_format != media::PIXEL_FORMAT_I420) {
+ client->OnError(
+ FROM_HERE, "unsupported format: " + media::VideoCaptureFormat::ToString(
+ params.requested_format));
+ return;
+ }
+
+ DCHECK(!oracle_proxy_);
+ oracle_proxy_ = new media::ThreadSafeCaptureOracle(std::move(client), params);
+
+ if (!capture_machine_.Start(oracle_proxy_, params)) {
+ oracle_proxy_->ReportError(FROM_HERE, "Failed to start capture machine.");
+ StopAndDeAllocate();
+ } else {
+ // The |capture_machine_| will later report to the |oracle_proxy_| whether
+ // the device started successfully.
+ }
}
void ScreenCaptureDeviceAndroid::StopAndDeAllocate() {
- core_.StopAndDeAllocate();
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (!oracle_proxy_) {
+ return; // Device is already stopped.
+ }
+
+ oracle_proxy_->Stop();
+ oracle_proxy_ = nullptr;
+ capture_machine_.Stop();
}
void ScreenCaptureDeviceAndroid::RequestRefreshFrame() {
- core_.RequestRefreshFrame();
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (!oracle_proxy_) {
+ return; // Device is stopped.
+ }
+ capture_machine_.MaybeCaptureForRefresh();
}
void ScreenCaptureDeviceAndroid::OnUtilizationReport(int frame_feedback_id,
double utilization) {
- core_.OnConsumerReportingUtilization(frame_feedback_id, utilization);
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(oracle_proxy_);
+ oracle_proxy_->OnConsumerReportingUtilization(frame_feedback_id, utilization);
}
} // namespace content
diff --git a/chromium/content/browser/media/capture/screen_capture_device_android.h b/chromium/content/browser/media/capture/screen_capture_device_android.h
index 7d2d5184435..14112269a5a 100644
--- a/chromium/content/browser/media/capture/screen_capture_device_android.h
+++ b/chromium/content/browser/media/capture/screen_capture_device_android.h
@@ -7,15 +7,17 @@
#include <memory>
+#include "base/macros.h"
+#include "base/sequence_checker.h"
#include "content/common/content_export.h"
-#include "media/capture/content/screen_capture_device_core.h"
+#include "media/capture/content/android/screen_capture_machine_android.h"
#include "media/capture/video/video_capture_device.h"
namespace content {
-// ScreenCaptureDeviceAndroid is a forwarder to media::ScreenCaptureDeviceCore
-// while keeping the Power Saving from kicking in between AllocateAndStart() and
-// StopAndDeAllocate().
+// ScreenCaptureDeviceAndroid is an adapter for using
+// media::ScreenCaptureMachineAndroid via the media::VideoCaptureDevice
+// interface.
class CONTENT_EXPORT ScreenCaptureDeviceAndroid
: public media::VideoCaptureDevice {
public:
@@ -30,7 +32,10 @@ class CONTENT_EXPORT ScreenCaptureDeviceAndroid
void OnUtilizationReport(int frame_feedback_id, double utilization) override;
private:
- media::ScreenCaptureDeviceCore core_;
+ SEQUENCE_CHECKER(sequence_checker_);
+
+ media::ScreenCaptureMachineAndroid capture_machine_;
+ scoped_refptr<media::ThreadSafeCaptureOracle> oracle_proxy_;
DISALLOW_COPY_AND_ASSIGN(ScreenCaptureDeviceAndroid);
};
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 15115a22b8b..e1593cc807e 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
@@ -177,15 +177,20 @@ bool WebContentsAudioInputStream::Impl::Open() {
tracker_->Start(
initial_render_process_id_, initial_main_render_frame_id_,
base::Bind(&Impl::OnTargetChanged, this));
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(&Impl::IncrementCapturerCount, this));
+ IncrementCapturerCount();
return true;
}
void WebContentsAudioInputStream::Impl::IncrementCapturerCount() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&Impl::IncrementCapturerCount, this));
+ return;
+ }
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (WebContents* contents = tracker_->web_contents())
contents->IncrementCapturerCount(gfx::Size());
}
@@ -237,9 +242,7 @@ void WebContentsAudioInputStream::Impl::Close() {
if (state_ == OPENED) {
state_ = CONSTRUCTED;
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&Impl::DecrementCapturerCount, this));
+ DecrementCapturerCount();
tracker_->Stop();
mixer_stream_->Close();
}
@@ -249,8 +252,14 @@ void WebContentsAudioInputStream::Impl::Close() {
}
void WebContentsAudioInputStream::Impl::DecrementCapturerCount() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&Impl::DecrementCapturerCount, this));
+ return;
+ }
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (WebContents* contents = tracker_->web_contents())
contents->DecrementCapturerCount();
}
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 c440442ca3c..e4122a24cdf 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
@@ -53,10 +53,15 @@ class WebContentsVideoCaptureDevice::FrameTracker
AsWeakPtr(), render_process_id, main_render_frame_id));
}
- ~FrameTracker() final { DCHECK_CURRENTLY_ON(BrowserThread::UI); }
+ ~FrameTracker() final {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (is_capturing_)
+ DidStopCapturingWebContents();
+ }
void WillStartCapturingWebContents(const gfx::Size& capture_size) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(!is_capturing_);
auto* contents = web_contents();
if (!contents) {
@@ -85,14 +90,18 @@ class WebContentsVideoCaptureDevice::FrameTracker
<< preferred_size.ToString() << " from a capture size of "
<< capture_size.ToString();
contents->IncrementCapturerCount(preferred_size);
+ is_capturing_ = true;
}
void DidStopCapturingWebContents() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (auto* contents = web_contents()) {
+ DCHECK(is_capturing_);
contents->DecrementCapturerCount();
+ is_capturing_ = false;
}
+ DCHECK(!is_capturing_);
}
private:
@@ -134,6 +143,7 @@ class WebContentsVideoCaptureDevice::FrameTracker
void DidDestroyFullscreenWidget() final { OnPossibleTargetChange(); }
void WebContentsDestroyed() final {
Observe(nullptr);
+ is_capturing_ = false;
OnPossibleTargetChange();
}
@@ -192,6 +202,9 @@ class WebContentsVideoCaptureDevice::FrameTracker
viz::FrameSinkId target_frame_sink_id_;
gfx::NativeView target_native_view_ = gfx::NativeView();
+ // Indicates whether the WebContents's capturer count needs to be decremented.
+ bool is_capturing_ = false;
+
DISALLOW_COPY_AND_ASSIGN(FrameTracker);
};
diff --git a/chromium/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc b/chromium/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
index 643c570b0a0..ec35ff5a5b3 100644
--- a/chromium/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
+++ b/chromium/content/browser/media/capture/web_contents_video_capture_device_browsertest.cc
@@ -195,6 +195,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsVideoCaptureDeviceBrowserTest,
capture_stack()->ExpectHasLogMessages();
device->StopAndDeAllocate();
+ device.reset();
RunUntilIdle();
}
@@ -204,6 +205,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsVideoCaptureDeviceBrowserTest,
ErrorsOutWhenWebContentsIsDestroyed) {
NavigateToInitialDocument();
AllocateAndStartAndWaitForFirstFrame();
+ EXPECT_TRUE(shell()->web_contents()->IsBeingCaptured());
// Initially, the device captures any content changes normally.
ChangePageContentColor(SK_ColorRED);
@@ -226,6 +228,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsVideoCaptureDeviceBrowserTest,
SuspendsAndResumes) {
NavigateToInitialDocument();
AllocateAndStartAndWaitForFirstFrame();
+ EXPECT_TRUE(shell()->web_contents()->IsBeingCaptured());
// Initially, the device captures any content changes normally.
ChangePageContentColor(SK_ColorRED);
@@ -252,6 +255,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsVideoCaptureDeviceBrowserTest,
WaitForFrameWithColor(SK_ColorGREEN);
StopAndDeAllocate();
+ EXPECT_FALSE(shell()->web_contents()->IsBeingCaptured());
}
// Tests that the device delivers refresh frames when asked, while the source
@@ -260,6 +264,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsVideoCaptureDeviceBrowserTest,
DeliversRefreshFramesUponRequest) {
NavigateToInitialDocument();
AllocateAndStartAndWaitForFirstFrame();
+ EXPECT_TRUE(shell()->web_contents()->IsBeingCaptured());
// Set the page content to a known color.
ChangePageContentColor(SK_ColorRED);
@@ -274,6 +279,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsVideoCaptureDeviceBrowserTest,
}
StopAndDeAllocate();
+ EXPECT_FALSE(shell()->web_contents()->IsBeingCaptured());
}
class WebContentsVideoCaptureDeviceBrowserTestP
@@ -331,6 +337,7 @@ IN_PROC_BROWSER_TEST_P(WebContentsVideoCaptureDeviceBrowserTestP,
NavigateToInitialDocument();
AllocateAndStartAndWaitForFirstFrame();
+ EXPECT_TRUE(shell()->web_contents()->IsBeingCaptured());
for (int visilibilty_case = 0; visilibilty_case < 3; ++visilibilty_case) {
switch (visilibilty_case) {
@@ -378,6 +385,7 @@ IN_PROC_BROWSER_TEST_P(WebContentsVideoCaptureDeviceBrowserTestP,
}
StopAndDeAllocate();
+ EXPECT_FALSE(shell()->web_contents()->IsBeingCaptured());
}
} // namespace
diff --git a/chromium/content/browser/media/cdm_registry_impl_unittest.cc b/chromium/content/browser/media/cdm_registry_impl_unittest.cc
index 96547c4fc7f..6f10e239e6c 100644
--- a/chromium/content/browser/media/cdm_registry_impl_unittest.cc
+++ b/chromium/content/browser/media/cdm_registry_impl_unittest.cc
@@ -21,6 +21,13 @@
namespace content {
+namespace {
+
+using VideoCodec = media::VideoCodec;
+using EncryptionMode = media::EncryptionMode;
+using CdmSessionType = media::CdmSessionType;
+using CdmProxy = media::CdmProxy;
+
const char kTestCdmName[] = "Test CDM";
const char kAlternateCdmName[] = "Alternate CDM";
const char kTestCdmGuid[] = "62FE9C4B-384E-48FD-B28A-9F6F248BC8CC";
@@ -30,6 +37,31 @@ const char kVersion2[] = "1.1.1.2";
const char kTestKeySystem[] = "com.example.somesystem";
const char kTestFileSystemId[] = "file_system_id";
+// Helper function to compare a STL container to an initializer_list.
+template <typename Container, typename T>
+bool StlEquals(const Container a, std::initializer_list<T> b) {
+ return a == Container(b);
+}
+
+#define EXPECT_STL_EQ(a, ...) \
+ do { \
+ EXPECT_TRUE(StlEquals(a, {__VA_ARGS__})); \
+ } while (false)
+
+#define EXPECT_VIDEO_CODECS(...) \
+ EXPECT_STL_EQ(cdm.capability.video_codecs, __VA_ARGS__)
+
+#define EXPECT_ENCRYPTION_SCHEMES(...) \
+ EXPECT_STL_EQ(cdm.capability.encryption_schemes, __VA_ARGS__)
+
+#define EXPECT_SESSION_TYPES(...) \
+ EXPECT_STL_EQ(cdm.capability.session_types, __VA_ARGS__)
+
+#define EXPECT_CDM_PROXY_PROTOCOLS(...) \
+ EXPECT_STL_EQ(cdm.capability.cdm_proxy_protocols, __VA_ARGS__)
+
+} // namespace
+
// For simplicity and to make failures easier to diagnose, this test uses
// std::string instead of base::FilePath and std::vector<std::string>.
class CdmRegistryImplTest : public testing::Test {
@@ -38,19 +70,19 @@ class CdmRegistryImplTest : public testing::Test {
~CdmRegistryImplTest() override {}
protected:
- void Register(const std::string& name,
- const std::string& version,
- const std::string& path,
- const std::vector<media::VideoCodec>& supported_video_codecs,
- bool supports_persistent_license,
- const base::flat_set<media::EncryptionMode>& supported_modes,
- std::string supported_key_system,
- bool supports_sub_key_systems = false) {
- cdm_registry_.RegisterCdm(CdmInfo(
- name, kTestCdmGuid, base::Version(version),
- base::FilePath::FromUTF8Unsafe(path), kTestFileSystemId,
- supported_video_codecs, supports_persistent_license, supported_modes,
- supported_key_system, supports_sub_key_systems));
+ CdmInfo GetTestCdmInfo() {
+ return CdmInfo(
+ kTestCdmName, kTestCdmGuid, base::Version(kVersion1),
+ base::FilePath::FromUTF8Unsafe(kTestPath), kTestFileSystemId,
+ CdmCapability(
+ {media::kCodecVP8, media::kCodecVP9}, {EncryptionMode::kCenc},
+ {CdmSessionType::kTemporary, CdmSessionType::kPersistentLicense},
+ {CdmProxy::Protocol::kIntel}),
+ kTestKeySystem, /*supports_sub_key_systems=*/true);
+ }
+
+ void Register(CdmInfo cdm_info) {
+ cdm_registry_.RegisterCdm(std::move(cdm_info));
}
bool IsRegistered(const std::string& name, const std::string& version) {
@@ -75,52 +107,51 @@ class CdmRegistryImplTest : public testing::Test {
};
TEST_F(CdmRegistryImplTest, Register) {
- Register(kTestCdmName, kVersion1, kTestPath,
- {media::kCodecVP8, media::kCodecVP9}, true,
- {media::EncryptionMode::kCenc}, kTestKeySystem, true);
- std::vector<CdmInfo> cdms = cdm_registry_.GetAllRegisteredCdms();
+ Register(GetTestCdmInfo());
+
+ auto cdms = cdm_registry_.GetAllRegisteredCdms();
ASSERT_EQ(1u, cdms.size());
CdmInfo cdm = cdms[0];
EXPECT_EQ(kTestCdmName, cdm.name);
EXPECT_EQ(kVersion1, cdm.version.GetString());
EXPECT_EQ(kTestPath, cdm.path.MaybeAsASCII());
EXPECT_EQ(kTestFileSystemId, cdm.file_system_id);
- EXPECT_EQ(2u, cdm.supported_video_codecs.size());
- EXPECT_EQ(media::kCodecVP8, cdm.supported_video_codecs[0]);
- EXPECT_EQ(media::kCodecVP9, cdm.supported_video_codecs[1]);
- EXPECT_TRUE(cdm.supports_persistent_license);
- EXPECT_EQ(1u, cdm.supported_encryption_schemes.size());
- EXPECT_EQ(
- 1u, cdm.supported_encryption_schemes.count(media::EncryptionMode::kCenc));
+ EXPECT_VIDEO_CODECS(VideoCodec::kCodecVP8, VideoCodec::kCodecVP9);
+ EXPECT_ENCRYPTION_SCHEMES(EncryptionMode::kCenc);
+ EXPECT_SESSION_TYPES(CdmSessionType::kTemporary,
+ CdmSessionType::kPersistentLicense);
+ EXPECT_CDM_PROXY_PROTOCOLS(CdmProxy::Protocol::kIntel);
EXPECT_EQ(kTestKeySystem, cdm.supported_key_system);
EXPECT_TRUE(cdm.supports_sub_key_systems);
}
TEST_F(CdmRegistryImplTest, ReRegister) {
- Register(kTestCdmName, kVersion1, "/bb/cc", {}, false,
- {media::EncryptionMode::kCenc}, kTestKeySystem);
+ auto cdm_info = GetTestCdmInfo();
+ Register(cdm_info);
EXPECT_TRUE(IsRegistered(kTestCdmName, kVersion1));
// Now register same key system with different values.
- Register(kTestCdmName, kVersion1, kTestPath, {}, false,
- {media::EncryptionMode::kCenc}, kTestKeySystem);
+ cdm_info.supports_sub_key_systems = false;
+ Register(cdm_info);
+
EXPECT_TRUE(IsRegistered(kTestCdmName, kVersion1));
}
TEST_F(CdmRegistryImplTest, MultipleVersions) {
- Register(kTestCdmName, kVersion1, kTestPath, {}, false,
- {media::EncryptionMode::kCenc}, kTestKeySystem);
- Register(kTestCdmName, kVersion2, "/bb/cc", {}, false,
- {media::EncryptionMode::kCenc}, kTestKeySystem);
+ auto cdm_info = GetTestCdmInfo();
+ Register(cdm_info);
+ cdm_info.version = base::Version(kVersion2);
+ Register(cdm_info);
+
EXPECT_TRUE(IsRegistered(kTestCdmName, kVersion1));
EXPECT_TRUE(IsRegistered(kTestCdmName, kVersion2));
}
TEST_F(CdmRegistryImplTest, NewVersionInsertedLast) {
- Register(kTestCdmName, kVersion1, kTestPath, {}, false,
- {media::EncryptionMode::kCenc}, kTestKeySystem);
- Register(kTestCdmName, kVersion2, "/bb/cc", {}, false,
- {media::EncryptionMode::kCenc}, kTestKeySystem);
+ auto cdm_info = GetTestCdmInfo();
+ Register(cdm_info);
+ cdm_info.version = base::Version(kVersion2);
+ Register(cdm_info);
const std::vector<std::string> versions = GetVersions(kTestCdmGuid);
EXPECT_EQ(2u, versions.size());
@@ -129,27 +160,25 @@ TEST_F(CdmRegistryImplTest, NewVersionInsertedLast) {
}
TEST_F(CdmRegistryImplTest, DifferentNames) {
- Register(kTestCdmName, kVersion1, kTestPath, {}, false,
- {media::EncryptionMode::kCenc}, kTestKeySystem);
- Register(kAlternateCdmName, kVersion1, kTestPath, {}, false,
- {media::EncryptionMode::kCbcs}, kTestKeySystem);
+ auto cdm_info = GetTestCdmInfo();
+ Register(cdm_info);
+ cdm_info.name = kAlternateCdmName;
+ Register(cdm_info);
+
EXPECT_TRUE(IsRegistered(kTestCdmName, kVersion1));
EXPECT_TRUE(IsRegistered(kAlternateCdmName, kVersion1));
}
TEST_F(CdmRegistryImplTest, SupportedEncryptionSchemes) {
- Register(kTestCdmName, kVersion1, kTestPath, {}, false,
- {media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs},
- kTestKeySystem);
+ auto cdm_info = GetTestCdmInfo();
+ cdm_info.capability.encryption_schemes = {EncryptionMode::kCenc,
+ EncryptionMode::kCbcs};
+ Register(cdm_info);
std::vector<CdmInfo> cdms = cdm_registry_.GetAllRegisteredCdms();
ASSERT_EQ(1u, cdms.size());
const CdmInfo& cdm = cdms[0];
- EXPECT_EQ(2u, cdm.supported_encryption_schemes.size());
- EXPECT_EQ(
- 1u, cdm.supported_encryption_schemes.count(media::EncryptionMode::kCenc));
- EXPECT_EQ(
- 1u, cdm.supported_encryption_schemes.count(media::EncryptionMode::kCbcs));
+ EXPECT_ENCRYPTION_SCHEMES(EncryptionMode::kCenc, EncryptionMode::kCbcs);
}
} // namespace content
diff --git a/chromium/content/browser/media/encrypted_media_browsertest.cc b/chromium/content/browser/media/encrypted_media_browsertest.cc
index 7096e1e1fe8..db7a34efd8d 100644
--- a/chromium/content/browser/media/encrypted_media_browsertest.cc
+++ b/chromium/content/browser/media/encrypted_media_browsertest.cc
@@ -56,6 +56,7 @@ const char kMp4Vp9VideoOnly[] =
"video/mp4; codecs=\"vp09.00.10.08.01.02.02.02.00\"";
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
const char kMp4Avc1VideoOnly[] = "video/mp4; codecs=\"avc1.64001E\"";
+const char kMp4AacAudioOnly[] = "audio/mp4; codecs=\"mp4a.40.2\"";
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
// EME-specific test results and errors.
@@ -63,6 +64,7 @@ const char kEmeKeyError[] = "KEYERROR";
const char kEmeNotSupportedError[] = "NOTSUPPORTEDERROR";
const char kDefaultEmePlayer[] = "eme_player.html";
+const char kDefaultMseOnlyEmePlayer[] = "mse_different_containers.html";
// The type of video src used to load media.
enum class SrcType { SRC, MSE };
@@ -92,15 +94,14 @@ class EncryptedMediaTest
void TestSimplePlayback(const std::string& encrypted_media,
const std::string& media_type) {
- RunSimpleEncryptedMediaTest(encrypted_media, media_type, CurrentKeySystem(),
- CurrentSourceType());
+ RunSimplePlaybackTest(encrypted_media, media_type, CurrentKeySystem(),
+ CurrentSourceType());
}
void TestFrameSizeChange() {
- RunEncryptedMediaTest("encrypted_frame_size_change.html",
- "frame_size_change-av_enc-v.webm",
- kWebMVorbisAudioVp8Video, CurrentKeySystem(),
- CurrentSourceType(), media::kEnded);
+ RunTest("encrypted_frame_size_change.html",
+ "frame_size_change-av_enc-v.webm", kWebMVorbisAudioVp8Video,
+ CurrentKeySystem(), CurrentSourceType(), media::kEnded);
}
void TestConfigChange(ConfigChangeType config_change_type) {
@@ -121,12 +122,12 @@ class EncryptedMediaTest
true);
}
- void RunEncryptedMediaTest(const std::string& html_page,
- const std::string& media_file,
- const std::string& media_type,
- const std::string& key_system,
- SrcType src_type,
- const std::string& expectation) {
+ void RunTest(const std::string& html_page,
+ const std::string& media_file,
+ const std::string& media_type,
+ const std::string& key_system,
+ SrcType src_type,
+ const std::string& expectation) {
base::StringPairs query_params;
query_params.emplace_back("mediaFile", media_file);
query_params.emplace_back("mediaType", media_type);
@@ -136,24 +137,40 @@ class EncryptedMediaTest
RunMediaTestPage(html_page, query_params, expectation, true);
}
- void RunSimpleEncryptedMediaTest(const std::string& media_file,
- const std::string& media_type,
- const std::string& key_system,
- SrcType src_type) {
- RunEncryptedMediaTest(kDefaultEmePlayer, media_file, media_type, key_system,
- src_type, media::kEnded);
+ void RunSimplePlaybackTest(const std::string& media_file,
+ const std::string& media_type,
+ const std::string& key_system,
+ SrcType src_type) {
+ RunTest(kDefaultEmePlayer, media_file, media_type, key_system, src_type,
+ media::kEnded);
}
- void TestMp4EncryptionPlayback(const std::string& media_file,
- const std::string& media_type,
- const std::string& expected_title) {
+ void RunMultipleFileTest(const std::string& video_file,
+ const std::string& video_type,
+ const std::string& audio_file,
+ const std::string& audio_type,
+ const std::string& expected_title) {
if (CurrentSourceType() != SrcType::MSE) {
DVLOG(0) << "Skipping test; Can only play MP4 encrypted streams by MSE.";
return;
}
- RunEncryptedMediaTest(kDefaultEmePlayer, media_file, media_type,
- CurrentKeySystem(), SrcType::MSE, expected_title);
+ base::StringPairs query_params;
+ query_params.emplace_back("keySystem", CurrentKeySystem());
+ query_params.emplace_back("runEncrypted", "1");
+ if (!video_file.empty()) {
+ DCHECK(!video_type.empty());
+ query_params.emplace_back("videoFile", video_file);
+ query_params.emplace_back("videoFormat", video_type);
+ }
+ if (!audio_file.empty()) {
+ DCHECK(!audio_type.empty());
+ query_params.emplace_back("audioFile", audio_file);
+ query_params.emplace_back("audioFormat", audio_type);
+ }
+
+ RunMediaTestPage(kDefaultMseOnlyEmePlayer, query_params, expected_title,
+ true);
}
protected:
@@ -258,8 +275,8 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoClearAudio_WebM_Opus) {
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_AudioOnly_MP4_FLAC) {
- TestMp4EncryptionPlayback("bear-flac-cenc.mp4", kMp4FlacAudioOnly,
- media::kEnded);
+ RunMultipleFileTest(std::string(), std::string(), "bear-flac-cenc.mp4",
+ kMp4FlacAudioOnly, media::kEnded);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_VideoOnly_MP4_VP9) {
@@ -302,32 +319,54 @@ IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, MAYBE_FrameSizeChangeVideo) {
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CENC) {
- TestMp4EncryptionPlayback("bear-640x360-v_frag-cenc.mp4", kMp4Avc1VideoOnly,
- media::kEnded);
+ RunMultipleFileTest("bear-640x360-v_frag-cenc.mp4", kMp4Avc1VideoOnly,
+ "bear-640x360-a_frag-cenc.mp4", kMp4AacAudioOnly,
+ media::kEnded);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CBC1) {
- TestMp4EncryptionPlayback("bear-640x360-v_frag-cbc1.mp4", kMp4Avc1VideoOnly,
- media::kError);
+ RunMultipleFileTest("bear-640x360-v_frag-cbc1.mp4", kMp4Avc1VideoOnly,
+ std::string(), std::string(), media::kError);
}
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CENS) {
- TestMp4EncryptionPlayback("bear-640x360-v_frag-cens.mp4", kMp4Avc1VideoOnly,
- media::kError);
+ RunMultipleFileTest("bear-640x360-v_frag-cens.mp4", kMp4Avc1VideoOnly,
+ std::string(), std::string(), media::kError);
}
+#if !defined(OS_ANDROID)
+// TODO(crbug.com/813845): Enable CBCS support on Chrome for Android.
IN_PROC_BROWSER_TEST_P(EncryptedMediaTest, Playback_Encryption_CBCS) {
std::string expected_result =
BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) ? media::kEnded : media::kError;
- TestMp4EncryptionPlayback("bear-640x360-v_frag-cbcs.mp4", kMp4Avc1VideoOnly,
- expected_result);
+ RunMultipleFileTest("bear-640x360-v_frag-cbcs.mp4", kMp4Avc1VideoOnly,
+ "bear-640x360-a_frag-cbcs.mp4", kMp4AacAudioOnly,
+ expected_result);
+}
+
+IN_PROC_BROWSER_TEST_P(EncryptedMediaTest,
+ Playback_Encryption_CBCS_Video_CENC_Audio) {
+ std::string expected_result =
+ BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) ? media::kEnded : media::kError;
+ RunMultipleFileTest("bear-640x360-v_frag-cbcs.mp4", kMp4Avc1VideoOnly,
+ "bear-640x360-a_frag-cenc.mp4", kMp4AacAudioOnly,
+ expected_result);
+}
+
+IN_PROC_BROWSER_TEST_P(EncryptedMediaTest,
+ Playback_Encryption_CENC_Video_CBCS_Audio) {
+ std::string expected_result =
+ BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME) ? media::kEnded : media::kError;
+ RunMultipleFileTest("bear-640x360-v_frag-cenc.mp4", kMp4Avc1VideoOnly,
+ "bear-640x360-a_frag-cbcs.mp4", kMp4AacAudioOnly,
+ expected_result);
}
+#endif // !defined(OS_ANDROID)
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
IN_PROC_BROWSER_TEST_F(EncryptedMediaTest, UnknownKeySystemThrowsException) {
- RunEncryptedMediaTest(kDefaultEmePlayer, "bear-a_enc-a.webm",
- kWebMVorbisAudioOnly, "com.example.foo", SrcType::MSE,
- kEmeNotSupportedError);
+ RunTest(kDefaultEmePlayer, "bear-a_enc-a.webm", kWebMVorbisAudioOnly,
+ "com.example.foo", SrcType::MSE, kEmeNotSupportedError);
}
} // namespace content
diff --git a/chromium/content/browser/media/flinging_renderer.cc b/chromium/content/browser/media/flinging_renderer.cc
index 8828939c4e5..b6119358422 100644
--- a/chromium/content/browser/media/flinging_renderer.cc
+++ b/chromium/content/browser/media/flinging_renderer.cc
@@ -14,7 +14,8 @@
namespace content {
-FlingingRenderer::FlingingRenderer(std::unique_ptr<MediaController> controller)
+FlingingRenderer::FlingingRenderer(
+ std::unique_ptr<media::MediaController> controller)
: controller_(std::move(controller)) {}
FlingingRenderer::~FlingingRenderer() = default;
diff --git a/chromium/content/browser/media/flinging_renderer.h b/chromium/content/browser/media/flinging_renderer.h
index 59a12b8bf07..38c411cd6d5 100644
--- a/chromium/content/browser/media/flinging_renderer.h
+++ b/chromium/content/browser/media/flinging_renderer.h
@@ -7,7 +7,7 @@
#include "base/callback.h"
#include "content/common/content_export.h"
-#include "content/public/browser/media_controller.h"
+#include "media/base/media_controller.h"
#include "media/base/media_resource.h"
#include "media/base/renderer.h"
#include "media/base/renderer_client.h"
@@ -50,9 +50,9 @@ class CONTENT_EXPORT FlingingRenderer : public media::Renderer {
private:
friend class FlingingRendererTest;
- explicit FlingingRenderer(std::unique_ptr<MediaController> controller);
+ explicit FlingingRenderer(std::unique_ptr<media::MediaController> controller);
- std::unique_ptr<MediaController> controller_;
+ std::unique_ptr<media::MediaController> controller_;
DISALLOW_COPY_AND_ASSIGN(FlingingRenderer);
};
diff --git a/chromium/content/browser/media/flinging_renderer_unittest.cc b/chromium/content/browser/media/flinging_renderer_unittest.cc
index 923415d94b8..680ac22101c 100644
--- a/chromium/content/browser/media/flinging_renderer_unittest.cc
+++ b/chromium/content/browser/media/flinging_renderer_unittest.cc
@@ -5,7 +5,7 @@
#include "content/browser/media/flinging_renderer.h"
#include "base/version.h"
-#include "content/public/browser/media_controller.h"
+#include "media/base/media_controller.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -14,7 +14,7 @@ using ::testing::StrictMock;
namespace content {
-class MockMediaController : public MediaController {
+class MockMediaController : public media::MediaController {
public:
MOCK_METHOD0(Play, void());
MOCK_METHOD0(Pause, void());
@@ -27,7 +27,7 @@ class FlingingRendererTest : public testing::Test {
public:
FlingingRendererTest()
: media_controller_(new StrictMock<MockMediaController>()),
- renderer_(std::unique_ptr<MediaController>(media_controller_)) {}
+ renderer_(std::unique_ptr<media::MediaController>(media_controller_)) {}
protected:
StrictMock<MockMediaController>* media_controller_;
diff --git a/chromium/content/browser/media/key_system_support_impl.cc b/chromium/content/browser/media/key_system_support_impl.cc
index 414da641e76..624cca51aa8 100644
--- a/chromium/content/browser/media/key_system_support_impl.cc
+++ b/chromium/content/browser/media/key_system_support_impl.cc
@@ -6,13 +6,20 @@
#include <vector>
+#include "base/command_line.h"
#include "base/containers/flat_set.h"
+#include "base/feature_list.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
+#include "base/strings/string_split.h"
#include "content/public/browser/cdm_registry.h"
+#include "content/public/browser/content_browser_client.h"
#include "content/public/common/cdm_info.h"
+#include "content/public/common/content_client.h"
+#include "content/public/common/content_switches.h"
#include "media/base/key_system_names.h"
#include "media/base/key_systems.h"
+#include "media/base/media_switches.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
namespace content {
@@ -26,6 +33,104 @@ void SendCdmAvailableUMA(const std::string& key_system, bool available) {
available);
}
+template <typename T>
+std::vector<T> SetToVector(const base::flat_set<T>& s) {
+ return std::vector<T>(s.begin(), s.end());
+}
+
+// Returns whether hardware secure codecs are enabled from command line. If
+// true, |video_codecs| are filled with codecs specified on command line, which
+// could be empty if no codecs are specified. If false, |video_codecs| will not
+// be modified.
+bool IsHardwareSecureCodecsOverriddenFromCommandLine(
+ std::vector<media::VideoCodec>* video_codecs,
+ std::vector<media::EncryptionMode>* encryption_schemes) {
+ DCHECK(video_codecs->empty());
+ DCHECK(encryption_schemes->empty());
+
+ auto* command_line = base::CommandLine::ForCurrentProcess();
+ if (!command_line || !command_line->HasSwitch(
+ switches::kOverrideHardwareSecureCodecsForTesting)) {
+ return false;
+ }
+
+ auto codecs_string = command_line->GetSwitchValueASCII(
+ switches::kOverrideHardwareSecureCodecsForTesting);
+ const auto supported_codecs = base::SplitStringPiece(
+ codecs_string, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+
+ for (const auto& codec : supported_codecs) {
+ if (codec == "vp8")
+ video_codecs->push_back(media::VideoCodec::kCodecVP8);
+ else if (codec == "vp9")
+ video_codecs->push_back(media::VideoCodec::kCodecVP9);
+ else if (codec == "avc1")
+ video_codecs->push_back(media::VideoCodec::kCodecH264);
+ else
+ DVLOG(1) << "Unsupported codec specified on command line: " << codec;
+ }
+
+ // Codecs enabled from command line assumes CENC support.
+ if (!video_codecs->empty())
+ encryption_schemes->push_back(media::EncryptionMode::kCenc);
+
+ return true;
+}
+
+void GetHardwareSecureDecryptionCaps(
+ const std::string& key_system,
+ const base::flat_set<media::CdmProxy::Protocol>& cdm_proxy_protocols,
+ std::vector<media::VideoCodec>* video_codecs,
+ std::vector<media::EncryptionMode>* encryption_schemes) {
+ DCHECK(video_codecs->empty());
+ DCHECK(encryption_schemes->empty());
+
+ if (!base::FeatureList::IsEnabled(media::kHardwareSecureDecryption)) {
+ DVLOG(1) << "Hardware secure decryption disabled";
+ return;
+ }
+
+ // Secure codecs override takes precedence over other checks.
+ if (IsHardwareSecureCodecsOverriddenFromCommandLine(video_codecs,
+ encryption_schemes)) {
+ DVLOG(1) << "Hardware secure codecs overridden from command line";
+ return;
+ }
+
+ if (cdm_proxy_protocols.empty()) {
+ DVLOG(1) << "CDM does not support any CdmProxy protocols";
+ return;
+ }
+
+ // Hardware secure video codecs need hardware video decoder support.
+ // TODO(xhwang): Make sure this check is as close as possible to the check
+ // in the render process. For example, also check check GPU features like
+ // GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE.
+ auto* command_line = base::CommandLine::ForCurrentProcess();
+ if (command_line &&
+ command_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
+ DVLOG(1) << "Hardware secure codecs not supported because accelerated "
+ "video decode disabled";
+ return;
+ }
+
+ if (!base::FeatureList::IsEnabled(media::kMojoVideoDecoder)) {
+ DVLOG(1) << "Hardware secure codecs not supported because mojo video "
+ "decode disabled";
+ return;
+ }
+
+ base::flat_set<media::VideoCodec> video_codec_set;
+ base::flat_set<media::EncryptionMode> encryption_scheme_set;
+
+ GetContentClient()->browser()->GetHardwareSecureDecryptionCaps(
+ key_system, cdm_proxy_protocols, &video_codec_set,
+ &encryption_scheme_set);
+
+ *video_codecs = SetToVector(video_codec_set);
+ *encryption_schemes = SetToVector(encryption_scheme_set);
+}
+
} // namespace
// static
@@ -59,20 +164,31 @@ KeySystemSupportImpl::~KeySystemSupportImpl() = default;
void KeySystemSupportImpl::IsKeySystemSupported(
const std::string& key_system,
IsKeySystemSupportedCallback callback) {
- DVLOG(3) << __func__;
- std::unique_ptr<CdmInfo> cdm = GetCdmInfoForKeySystem(key_system);
- if (!cdm) {
+ DVLOG(3) << __func__ << ": key_system = " << key_system;
+
+ auto cdm_info = GetCdmInfoForKeySystem(key_system);
+ if (!cdm_info) {
SendCdmAvailableUMA(key_system, false);
- std::move(callback).Run(false, {}, false, {});
+ std::move(callback).Run(false, nullptr);
return;
}
- const base::flat_set<media::EncryptionMode>& schemes =
- cdm->supported_encryption_schemes;
SendCdmAvailableUMA(key_system, true);
- std::move(callback).Run(
- true, cdm->supported_video_codecs, cdm->supports_persistent_license,
- std::vector<media::EncryptionMode>(schemes.begin(), schemes.end()));
+
+ // Supported codecs and encryption schemes.
+ auto capability = media::mojom::KeySystemCapability::New();
+ capability->video_codecs = cdm_info->capability.video_codecs;
+ capability->encryption_schemes =
+ SetToVector(cdm_info->capability.encryption_schemes);
+
+ GetHardwareSecureDecryptionCaps(key_system,
+ cdm_info->capability.cdm_proxy_protocols,
+ &capability->hw_secure_video_codecs,
+ &capability->hw_secure_encryption_schemes);
+
+ capability->session_types = SetToVector(cdm_info->capability.session_types);
+
+ std::move(callback).Run(true, std::move(capability));
}
} // namespace content
diff --git a/chromium/content/browser/media/key_system_support_impl_unittest.cc b/chromium/content/browser/media/key_system_support_impl_unittest.cc
index aa3134ae60e..8ba04e3e867 100644
--- a/chromium/content/browser/media/key_system_support_impl_unittest.cc
+++ b/chromium/content/browser/media/key_system_support_impl_unittest.cc
@@ -22,11 +22,35 @@ namespace content {
namespace {
+using VideoCodec = media::VideoCodec;
+using EncryptionMode = media::EncryptionMode;
+using CdmSessionType = media::CdmSessionType;
+
const char kTestCdmGuid[] = "62FE9C4B-384E-48FD-B28A-9F6F248BC8CC";
const char kVersion[] = "1.1.1.1";
const char kTestPath[] = "/aa/bb";
const char kTestFileSystemId[] = "file_system_id";
+// Helper function to compare a STL container to an initializer_list.
+template <typename Container, typename T>
+bool StlEquals(const Container a, std::initializer_list<T> b) {
+ return a == Container(b);
+}
+
+#define EXPECT_STL_EQ(a, ...) \
+ do { \
+ EXPECT_TRUE(StlEquals(a, {__VA_ARGS__})); \
+ } while (false)
+
+#define EXPECT_VIDEO_CODECS(...) \
+ EXPECT_STL_EQ(capability_->video_codecs, __VA_ARGS__)
+
+#define EXPECT_ENCRYPTION_SCHEMES(...) \
+ EXPECT_STL_EQ(capability_->encryption_schemes, __VA_ARGS__)
+
+#define EXPECT_SESSION_TYPES(...) \
+ EXPECT_STL_EQ(capability_->session_types, __VA_ARGS__)
+
} // namespace
class KeySystemSupportTest : public testing::Test {
@@ -36,20 +60,24 @@ class KeySystemSupportTest : public testing::Test {
KeySystemSupportImpl::Create(mojo::MakeRequest(&key_system_support_));
}
- // Registers |key_system| with |supported_video_codecs| and
- // |supports_persistent_license|. All other values for CdmInfo have some
- // default value as they're not returned by IsKeySystemSupported().
- void Register(const std::string& key_system,
- const std::vector<media::VideoCodec>& supported_video_codecs,
- bool supports_persistent_license,
- const base::flat_set<media::EncryptionMode>& supported_modes) {
+ // TODO(xhwang): Add tests for hardware secure video codecs and encryption
+ // schemes.
+ CdmCapability GetTestCdmCapability() {
+ return CdmCapability(
+ {VideoCodec::kCodecVP8, VideoCodec::kCodecVP9},
+ {EncryptionMode::kCenc, EncryptionMode::kCbcs},
+ {CdmSessionType::kTemporary, CdmSessionType::kPersistentLicense}, {});
+ }
+
+ // Registers |key_system| with |capability|. All other values for CdmInfo have
+ // some default value as they're not returned by IsKeySystemSupported().
+ void Register(const std::string& key_system, CdmCapability capability) {
DVLOG(1) << __func__;
CdmRegistry::GetInstance()->RegisterCdm(
CdmInfo(key_system, kTestCdmGuid, base::Version(kVersion),
base::FilePath::FromUTF8Unsafe(kTestPath), kTestFileSystemId,
- supported_video_codecs, supports_persistent_license,
- supported_modes, key_system, false));
+ std::move(capability), key_system, false));
}
// Determines if |key_system| is registered. If it is, updates |codecs_|
@@ -58,8 +86,7 @@ class KeySystemSupportTest : public testing::Test {
DVLOG(1) << __func__;
bool is_available = false;
key_system_support_->IsKeySystemSupported(key_system, &is_available,
- &codecs_, &persistent_,
- &encryption_schemes_);
+ &capability_);
return is_available;
}
@@ -67,9 +94,7 @@ class KeySystemSupportTest : public testing::Test {
TestBrowserThreadBundle test_browser_thread_bundle_;
// Updated by IsSupported().
- std::vector<media::VideoCodec> codecs_;
- bool persistent_;
- std::vector<media::EncryptionMode> encryption_schemes_;
+ media::mojom::KeySystemCapabilityPtr capability_;
};
// Note that as CdmRegistry::GetInstance() is a static, it is shared between
@@ -78,45 +103,32 @@ class KeySystemSupportTest : public testing::Test {
TEST_F(KeySystemSupportTest, NoKeySystems) {
EXPECT_FALSE(IsSupported("KeySystem1"));
+ EXPECT_FALSE(capability_);
}
TEST_F(KeySystemSupportTest, OneKeySystem) {
- Register("KeySystem2", {media::VideoCodec::kCodecVP8}, true,
- {media::EncryptionMode::kCenc, media::EncryptionMode::kCbcs});
+ Register("KeySystem2", GetTestCdmCapability());
+
EXPECT_TRUE(IsSupported("KeySystem2"));
- EXPECT_EQ(1u, codecs_.size());
- EXPECT_EQ(media::VideoCodec::kCodecVP8, codecs_[0]);
- EXPECT_TRUE(persistent_);
- EXPECT_EQ(2u, encryption_schemes_.size());
- EXPECT_EQ(media::EncryptionMode::kCenc, encryption_schemes_[0]);
- EXPECT_EQ(media::EncryptionMode::kCbcs, encryption_schemes_[1]);
+ EXPECT_VIDEO_CODECS(VideoCodec::kCodecVP8, VideoCodec::kCodecVP9);
+ EXPECT_ENCRYPTION_SCHEMES(EncryptionMode::kCenc, EncryptionMode::kCbcs);
+ EXPECT_SESSION_TYPES(CdmSessionType::kTemporary,
+ CdmSessionType::kPersistentLicense);
}
TEST_F(KeySystemSupportTest, MultipleKeySystems) {
- Register("KeySystem3",
- {media::VideoCodec::kCodecVP8, media::VideoCodec::kCodecVP9}, true,
- {media::EncryptionMode::kCenc});
- Register("KeySystem4", {media::VideoCodec::kCodecVP9}, false,
- {media::EncryptionMode::kCbcs});
+ Register("KeySystem3", GetTestCdmCapability());
+ Register("KeySystem4", GetTestCdmCapability());
+
EXPECT_TRUE(IsSupported("KeySystem3"));
- EXPECT_EQ(2u, codecs_.size());
- EXPECT_EQ(media::VideoCodec::kCodecVP8, codecs_[0]);
- EXPECT_EQ(media::VideoCodec::kCodecVP9, codecs_[1]);
- EXPECT_TRUE(persistent_);
- EXPECT_EQ(1u, encryption_schemes_.size());
- EXPECT_EQ(media::EncryptionMode::kCenc, encryption_schemes_[0]);
EXPECT_TRUE(IsSupported("KeySystem4"));
- EXPECT_EQ(1u, codecs_.size());
- EXPECT_EQ(media::VideoCodec::kCodecVP9, codecs_[0]);
- EXPECT_FALSE(persistent_);
- EXPECT_EQ(1u, encryption_schemes_.size());
- EXPECT_EQ(media::EncryptionMode::kCbcs, encryption_schemes_[0]);
}
TEST_F(KeySystemSupportTest, MissingKeySystem) {
- Register("KeySystem5", {media::VideoCodec::kCodecVP8}, true,
- {media::EncryptionMode::kCenc});
+ Register("KeySystem5", GetTestCdmCapability());
+
EXPECT_FALSE(IsSupported("KeySystem6"));
+ EXPECT_FALSE(capability_);
}
} // namespace content
diff --git a/chromium/content/browser/media/media_autoplay_browsertest.cc b/chromium/content/browser/media/media_autoplay_browsertest.cc
new file mode 100644
index 00000000000..bb03034fe17
--- /dev/null
+++ b/chromium/content/browser/media/media_autoplay_browsertest.cc
@@ -0,0 +1,66 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/path_service.h"
+#include "content/common/media/media_player_delegate_messages.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/common/content_paths.h"
+#include "content/public/test/browser_test.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 WaitForMediaPlaying : public WebContentsObserver {
+ public:
+ WaitForMediaPlaying(WebContents* web_contents)
+ : WebContentsObserver(web_contents) {}
+
+ // WebContentsObserver override.
+ void MediaStartedPlaying(const MediaPlayerInfo&, const MediaPlayerId&) final {
+ run_loop_.Quit();
+ }
+
+ void Wait() { run_loop_.Run(); }
+
+ private:
+ base::RunLoop run_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaitForMediaPlaying);
+};
+
+} // namespace
+
+class MediaAutoplayTest : public ContentBrowserTest {
+ public:
+ void SetUpOnMainThread() override {
+ ContentBrowserTest::SetUpOnMainThread();
+
+ base::FilePath test_data_dir;
+ ASSERT_TRUE(base::PathService::Get(content::DIR_TEST_DATA, &test_data_dir));
+ embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
+ ASSERT_TRUE(embedded_test_server()->Start());
+ }
+};
+
+// Test that playing a player from an IPC does not lead to a crash the renderer.
+// This is a regression test from a crash from autoplay_initiated_ not being set
+// in the Blink's AutoplayPolicy.
+IN_PROC_BROWSER_TEST_F(MediaAutoplayTest, Crash_AutoplayInitiated) {
+ NavigateToURL(shell(),
+ embedded_test_server()->GetURL("/media/video-player.html"));
+
+ WaitForMediaPlaying wait_for_media_playing(shell()->web_contents());
+
+ RenderFrameHost* main_frame = shell()->web_contents()->GetMainFrame();
+ main_frame->Send(
+ new MediaPlayerDelegateMsg_Play(main_frame->GetRoutingID(), 1));
+
+ wait_for_media_playing.Wait();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/media/media_canplaytype_browsertest.cc b/chromium/content/browser/media/media_canplaytype_browsertest.cc
index f6706151c8f..c517a4bf7c4 100644
--- a/chromium/content/browser/media/media_canplaytype_browsertest.cc
+++ b/chromium/content/browser/media/media_canplaytype_browsertest.cc
@@ -591,21 +591,21 @@ class AV1MediaCanPlayTypeTest : public MediaCanPlayTypeTest {
// 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(kProbably, 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
+ // Fully qualified codec strings are required. These tests are not exhaustive
+ // since codec string parsing is exhaustively tested elsewhere.
EXPECT_EQ(kNot, CanPlay("'video/webm; codecs=\"av1\"'"));
EXPECT_EQ(kNot, CanPlay("'video/mp4; codecs=\"av1\"'"));
+ EXPECT_EQ(kProbably, CanPlay("'video/webm; codecs=\"av01.0.04M.08\"'"));
+ EXPECT_EQ(kProbably, CanPlay("'video/mp4; codecs=\"av01.0.04M.08\"'"));
}
+#else
+// AV1 is enabled by default. However, on platforms where it is not built, such
+// as ARM-based devices, av1 must be unsupported.
+IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_av1_unsupported) {
+ EXPECT_EQ(kNot, CanPlay("'video/webm; codecs=\"av01.0.04M.08\"'"));
+ EXPECT_EQ(kNot, CanPlay("'video/mp4; codecs=\"av01.0.04M.08\"'"));
+}
+#endif // BUILDFLAG(ENABLE_AV1_DECODER)
IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_wav) {
EXPECT_EQ(kMaybe, CanPlay("'audio/wav'"));
diff --git a/chromium/content/browser/media/media_internals.cc b/chromium/content/browser/media/media_internals.cc
index e245a5feada..54b72c76803 100644
--- a/chromium/content/browser/media/media_internals.cc
+++ b/chromium/content/browser/media/media_internals.cc
@@ -16,7 +16,6 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
-#include "content/browser/media/mojo_audio_logging_adapter.h"
#include "content/browser/renderer_host/media/media_stream_manager.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -118,7 +117,8 @@ const char kAudioLogUpdateFunction[] = "media.updateAudioComponent";
namespace content {
-class AudioLogImpl : public media::mojom::AudioLog {
+class MediaInternals::AudioLogImpl : public media::mojom::AudioLog,
+ public media::AudioLog {
public:
AudioLogImpl(int owner_id,
media::AudioLogFactory::AudioComponent component,
@@ -164,12 +164,13 @@ class AudioLogImpl : public media::mojom::AudioLog {
DISALLOW_COPY_AND_ASSIGN(AudioLogImpl);
};
-AudioLogImpl::AudioLogImpl(int owner_id,
- media::AudioLogFactory::AudioComponent component,
- content::MediaInternals* media_internals,
- int component_id,
- int render_process_id,
- int render_frame_id)
+MediaInternals::AudioLogImpl::AudioLogImpl(
+ int owner_id,
+ media::AudioLogFactory::AudioComponent component,
+ content::MediaInternals* media_internals,
+ int component_id,
+ int render_process_id,
+ int render_frame_id)
: owner_id_(owner_id),
component_(component),
media_internals_(media_internals),
@@ -177,10 +178,16 @@ AudioLogImpl::AudioLogImpl(int owner_id,
render_process_id_(render_process_id),
render_frame_id_(render_frame_id) {}
-AudioLogImpl::~AudioLogImpl() {}
+MediaInternals::AudioLogImpl::~AudioLogImpl() {
+ // Ensure log is always closed. This covers the case of crashes in the audio
+ // service utility process, in which case the log may not be closed
+ // explicitly.
+ OnClosed();
+}
-void AudioLogImpl::OnCreated(const media::AudioParameters& params,
- const std::string& device_id) {
+void MediaInternals::AudioLogImpl::OnCreated(
+ const media::AudioParameters& params,
+ const std::string& device_id) {
base::DictionaryValue dict;
StoreComponentMetadata(&dict);
@@ -199,15 +206,15 @@ void AudioLogImpl::OnCreated(const media::AudioParameters& params,
SetWebContentsTitle();
}
-void AudioLogImpl::OnStarted() {
+void MediaInternals::AudioLogImpl::OnStarted() {
SendSingleStringUpdate(kAudioLogStatusKey, "started");
}
-void AudioLogImpl::OnStopped() {
+void MediaInternals::AudioLogImpl::OnStopped() {
SendSingleStringUpdate(kAudioLogStatusKey, "stopped");
}
-void AudioLogImpl::OnClosed() {
+void MediaInternals::AudioLogImpl::OnClosed() {
base::DictionaryValue dict;
StoreComponentMetadata(&dict);
dict.SetString(kAudioLogStatusKey, "closed");
@@ -216,11 +223,11 @@ void AudioLogImpl::OnClosed() {
&dict);
}
-void AudioLogImpl::OnError() {
+void MediaInternals::AudioLogImpl::OnError() {
SendSingleStringUpdate("error_occurred", "true");
}
-void AudioLogImpl::OnSetVolume(double volume) {
+void MediaInternals::AudioLogImpl::OnSetVolume(double volume) {
base::DictionaryValue dict;
StoreComponentMetadata(&dict);
dict.SetDouble("volume", volume);
@@ -229,11 +236,11 @@ void AudioLogImpl::OnSetVolume(double volume) {
&dict);
}
-void AudioLogImpl::OnLogMessage(const std::string& message) {
+void MediaInternals::AudioLogImpl::OnLogMessage(const std::string& message) {
MediaStreamManager::SendMessageToNativeLog(message);
}
-void AudioLogImpl::SetWebContentsTitle() {
+void MediaInternals::AudioLogImpl::SetWebContentsTitle() {
if (render_process_id_ < 0 || render_frame_id_ < 0)
return;
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
@@ -242,12 +249,12 @@ void AudioLogImpl::SetWebContentsTitle() {
render_process_id_, render_frame_id_);
}
-std::string AudioLogImpl::FormatCacheKey() {
+std::string MediaInternals::AudioLogImpl::FormatCacheKey() {
return base::StringPrintf("%d:%d:%d", owner_id_, component_, component_id_);
}
// static
-void AudioLogImpl::SendWebContentsTitleHelper(
+void MediaInternals::AudioLogImpl::SendWebContentsTitleHelper(
const std::string& cache_key,
std::unique_ptr<base::DictionaryValue> dict,
int render_process_id,
@@ -275,8 +282,9 @@ void AudioLogImpl::SendWebContentsTitleHelper(
dict.get());
}
-void AudioLogImpl::SendSingleStringUpdate(const std::string& key,
- const std::string& value) {
+void MediaInternals::AudioLogImpl::SendSingleStringUpdate(
+ const std::string& key,
+ const std::string& value) {
base::DictionaryValue dict;
StoreComponentMetadata(&dict);
dict.SetString(key, value);
@@ -285,7 +293,8 @@ void AudioLogImpl::SendSingleStringUpdate(const std::string& key,
&dict);
}
-void AudioLogImpl::StoreComponentMetadata(base::DictionaryValue* dict) {
+void MediaInternals::AudioLogImpl::StoreComponentMetadata(
+ base::DictionaryValue* dict) {
dict->SetInteger("owner_id", owner_id_);
dict->SetInteger("component_id", component_id_);
dict->SetInteger("component_type", component_);
@@ -322,6 +331,7 @@ class MediaInternals::MediaInternalsUMAHandler {
std::string audio_codec_name;
std::string video_codec_name;
std::string video_decoder;
+ bool is_platform_video_decoder = false;
GURL origin_url;
};
@@ -410,6 +420,10 @@ void MediaInternals::MediaInternalsUMAHandler::SavePlayerState(
player_info.video_decoder_changed = true;
}
}
+ if (event.params.HasKey("is_platform_video_decoder")) {
+ event.params.GetBoolean("is_platform_video_decoder",
+ &player_info.is_platform_video_decoder);
+ }
if (event.params.HasKey("video_dds")) {
event.params.GetBoolean("video_dds", &player_info.video_dds);
}
@@ -469,8 +483,10 @@ std::string MediaInternals::MediaInternalsUMAHandler::GetUMANameForAVStream(
uma_name += "DDS.";
}
- if (player_info.video_decoder == media::GpuVideoDecoder::kDecoderName ||
- player_info.video_decoder == "MojoVideoDecoder") {
+ // Note that HW essentailly means 'platform' anyway. MediaCodec has been
+ // reported as HW forever, regardless of the underlying platform
+ // implementation.
+ if (player_info.is_platform_video_decoder) {
uma_name += "HW";
} else {
uma_name += "SW";
@@ -720,8 +736,7 @@ void MediaInternals::UpdateVideoCaptureDeviceCapabilities(
std::unique_ptr<media::AudioLog> MediaInternals::CreateAudioLog(
AudioComponent component,
int component_id) {
- return std::make_unique<MojoAudioLogAdapter>(
- CreateMojoAudioLog(component, component_id));
+ return CreateAudioLogImpl(component, component_id, -1, MSG_ROUTING_NONE);
}
media::mojom::AudioLogPtr MediaInternals::CreateMojoAudioLog(
@@ -729,15 +744,36 @@ media::mojom::AudioLogPtr MediaInternals::CreateMojoAudioLog(
int component_id,
int render_process_id,
int render_frame_id) {
- base::AutoLock auto_lock(lock_);
media::mojom::AudioLogPtr audio_log_ptr;
- mojo::MakeStrongBinding(std::make_unique<AudioLogImpl>(
- owner_ids_[component]++, component, this,
- component_id, render_process_id, render_frame_id),
- mojo::MakeRequest(&audio_log_ptr));
+ CreateMojoAudioLog(component, component_id, mojo::MakeRequest(&audio_log_ptr),
+ render_process_id, render_frame_id);
return audio_log_ptr;
}
+void MediaInternals::CreateMojoAudioLog(
+ media::AudioLogFactory::AudioComponent component,
+ int component_id,
+ media::mojom::AudioLogRequest request,
+ int render_process_id,
+ int render_frame_id) {
+ mojo::MakeStrongBinding(
+ CreateAudioLogImpl(component, component_id, render_process_id,
+ render_frame_id),
+ std::move(request));
+}
+
+std::unique_ptr<MediaInternals::AudioLogImpl>
+MediaInternals::CreateAudioLogImpl(
+ media::AudioLogFactory::AudioComponent component,
+ int component_id,
+ int render_process_id,
+ int render_frame_id) {
+ base::AutoLock auto_lock(lock_);
+ return std::make_unique<AudioLogImpl>(owner_ids_[component]++, component,
+ this, component_id, render_process_id,
+ render_frame_id);
+}
+
void MediaInternals::OnProcessTerminatedForTesting(int process_id) {
uma_handler_->OnProcessTerminated(process_id);
}
diff --git a/chromium/content/browser/media/media_internals.h b/chromium/content/browser/media/media_internals.h
index 25b1085daaf..494c251ad9c 100644
--- a/chromium/content/browser/media/media_internals.h
+++ b/chromium/content/browser/media/media_internals.h
@@ -92,14 +92,21 @@ class CONTENT_EXPORT MediaInternals : public media::AudioLogFactory,
int render_process_id = -1,
int render_frame_id = MSG_ROUTING_NONE);
+ // Strongly bounds |request| to a new media::mojom::AudioLog instance. Safe to
+ // call from any thread.
+ void CreateMojoAudioLog(AudioComponent component,
+ int component_id,
+ media::mojom::AudioLogRequest request,
+ int render_process_id = -1,
+ int render_frame_id = MSG_ROUTING_NONE);
+
void OnProcessTerminatedForTesting(int process_id);
private:
+ class AudioLogImpl;
// Inner class to handle reporting pipelinestatus to UMA
class MediaInternalsUMAHandler;
- friend class AudioLogImpl;
-
MediaInternals();
// Sends |update| to each registered UpdateCallback. Safe to call from any
@@ -123,6 +130,11 @@ class CONTENT_EXPORT MediaInternals : public media::AudioLogFactory,
const std::string& function,
const base::DictionaryValue* value);
+ std::unique_ptr<AudioLogImpl> CreateAudioLogImpl(AudioComponent component,
+ int component_id,
+ int render_process_id,
+ int render_frame_id);
+
// Must only be accessed on the UI thread.
std::vector<UpdateCallback> update_callbacks_;
diff --git a/chromium/content/browser/media/media_source_browsertest.cc b/chromium/content/browser/media/media_source_browsertest.cc
index 5e3cb0006e5..a7d782ba920 100644
--- a/chromium/content/browser/media/media_source_browsertest.cc
+++ b/chromium/content/browser/media/media_source_browsertest.cc
@@ -26,10 +26,17 @@ const char kWebMVideoOnly[] = "video/webm; codecs=\"vp8\"";
const char kWebMAudioVideo[] = "video/webm; codecs=\"vorbis, vp8\"";
const char kMp4FlacAudioOnly[] = "audio/mp4; codecs=\"flac\"";
-#if BUILDFLAG(USE_PROPRIETARY_CODECS) && \
- BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
+#if BUILDFLAG(USE_PROPRIETARY_CODECS)
+const char kMp4AudioOnly[] = "audio/mp4; codecs=\"mp4a.40.2\"'";
+
+#if !defined(OS_ANDROID)
+const char kMp4VideoOnly[] = "video/mp4; codecs=\"avc1.4D4041\"'";
+#endif // !defined(OS_ANDROID)
+
+#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
const char kMp2tAudioVideo[] = "video/mp2t; codecs=\"mp4a.40.2, avc1.42E01E\"";
-#endif
+#endif // BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
+#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
namespace content {
@@ -103,8 +110,12 @@ IN_PROC_BROWSER_TEST_F(MediaSourceTest, ConfigChangeVideo) {
#if !defined(OS_ANDROID)
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"));
+ query_params.push_back(
+ std::make_pair("videoFile", "bear-640x360-v_frag.mp4"));
+ query_params.push_back(std::make_pair("videoFormat", kMp4VideoOnly));
+ query_params.push_back(
+ std::make_pair("audioFile", "bear-320x240-audio-only.webm"));
+ query_params.push_back(std::make_pair("audioFormat", kWebMAudioOnly));
RunMediaTestPage("mse_different_containers.html", query_params, media::kEnded,
true);
}
@@ -112,8 +123,12 @@ IN_PROC_BROWSER_TEST_F(MediaSourceTest, Playback_Video_MP4_Audio_WEBM) {
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"));
+ query_params.push_back(
+ std::make_pair("videoFile", "bear-320x240-video-only.webm"));
+ query_params.push_back(std::make_pair("videoFormat", kWebMVideoOnly));
+ query_params.push_back(
+ std::make_pair("audioFile", "bear-640x360-a_frag.mp4"));
+ query_params.push_back(std::make_pair("audioFormat", kMp4AudioOnly));
RunMediaTestPage("mse_different_containers.html", query_params, media::kEnded,
true);
}
diff --git a/chromium/content/browser/media/media_web_contents_observer.cc b/chromium/content/browser/media/media_web_contents_observer.cc
index b3abe26c982..1b013f92874 100644
--- a/chromium/content/browser/media/media_web_contents_observer.cc
+++ b/chromium/content/browser/media/media_web_contents_observer.cc
@@ -12,6 +12,7 @@
#include "content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/media/media_player_delegate_messages.h"
+#include "content/public/browser/picture_in_picture_window_controller.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message_macros.h"
@@ -46,11 +47,11 @@ void CheckFullscreenDetectionEnabled(WebContents* web_contents) {
bool MediaPlayerEntryExists(
const WebContentsObserver::MediaPlayerId& player_id,
const MediaWebContentsObserver::ActiveMediaPlayerMap& player_map) {
- const auto& players = player_map.find(player_id.first);
+ const auto& players = player_map.find(player_id.render_frame_host);
if (players == player_map.end())
return false;
- return players->second.find(player_id.second) != players->second.end();
+ return players->second.find(player_id.delegate_id) != players->second.end();
}
} // anonymous namespace
@@ -70,10 +71,16 @@ void MediaWebContentsObserver::RenderFrameDeleted(
ClearWakeLocks(render_frame_host);
session_controllers_manager_.RenderFrameDeleted(render_frame_host);
- if (fullscreen_player_ && fullscreen_player_->first == render_frame_host) {
+ if (fullscreen_player_ &&
+ fullscreen_player_->render_frame_host == render_frame_host) {
picture_in_picture_allowed_in_fullscreen_.reset();
fullscreen_player_.reset();
}
+
+ // Usually the frame will exit PIP before it is deleted but for OOPIF, it
+ // seems that the player never notifies the browser process.
+ if (pip_player_ && pip_player_->render_frame_host == render_frame_host)
+ ExitPictureInPictureInternal();
}
void MediaWebContentsObserver::MaybeUpdateAudibleState() {
@@ -158,10 +165,10 @@ void MediaWebContentsObserver::RequestPersistentVideo(bool value) {
// The message is sent to the renderer even though the video is already the
// fullscreen element itself. It will eventually be handled by Blink.
- RenderFrameHost* target_frame = fullscreen_player_->first;
- int delegate_id = fullscreen_player_->second;
- target_frame->Send(new MediaPlayerDelegateMsg_BecamePersistentVideo(
- target_frame->GetRoutingID(), delegate_id, value));
+ fullscreen_player_->render_frame_host->Send(
+ new MediaPlayerDelegateMsg_BecamePersistentVideo(
+ fullscreen_player_->render_frame_host->GetRoutingID(),
+ fullscreen_player_->delegate_id, value));
}
bool MediaWebContentsObserver::IsPlayerActive(
@@ -176,10 +183,10 @@ void MediaWebContentsObserver::OnPictureInPictureWindowResize(
const gfx::Size& window_size) {
DCHECK(pip_player_.has_value());
- RenderFrameHost* frame = pip_player_->first;
- int delegate_id = pip_player_->second;
- frame->Send(new MediaPlayerDelegateMsg_OnPictureInPictureWindowResize(
- frame->GetRoutingID(), delegate_id, window_size));
+ pip_player_->render_frame_host->Send(
+ new MediaPlayerDelegateMsg_OnPictureInPictureWindowResize(
+ pip_player_->render_frame_host->GetRoutingID(),
+ pip_player_->delegate_id, window_size));
}
void MediaWebContentsObserver::OnMediaDestroyed(
@@ -199,6 +206,18 @@ void MediaWebContentsObserver::OnMediaPaused(RenderFrameHost* render_frame_host,
UpdateVideoLock();
+ // TODO(872066): check for |pip_player_| fully matching paused player.
+ if (!web_contents()->IsBeingDestroyed() && pip_player_.has_value() &&
+ pip_player_->render_frame_host == render_frame_host) {
+ PictureInPictureWindowControllerImpl* pip_controller =
+ PictureInPictureWindowControllerImpl::FromWebContents(
+ web_contents_impl());
+ if (pip_controller) {
+ pip_controller->UpdatePlaybackState(false /* is not playing */,
+ reached_end_of_stream);
+ }
+ }
+
if (removed_audio || removed_video) {
// Notify observers the player has been "paused".
web_contents_impl()->MediaStoppedPlaying(
@@ -243,8 +262,19 @@ void MediaWebContentsObserver::OnMediaPlaying(
return;
}
+ // TODO(872066): check for |pip_player_| fully matching paused player.
+ if (!web_contents()->IsBeingDestroyed() && pip_player_.has_value() &&
+ pip_player_->render_frame_host == render_frame_host) {
+ PictureInPictureWindowControllerImpl* pip_controller =
+ PictureInPictureWindowControllerImpl::FromWebContents(
+ web_contents_impl());
+ if (pip_controller) {
+ pip_controller->UpdatePlaybackState(true /* is not playing */,
+ false /* reached_end_of_stream */);
+ }
+ }
+
// Notify observers of the new player.
- DCHECK(has_audio || has_video);
web_contents_impl()->MediaStartedPlaying(
WebContentsObserver::MediaPlayerInfo(has_video, has_audio), id);
}
@@ -312,17 +342,7 @@ void MediaWebContentsObserver::OnPictureInPictureModeEnded(
RenderFrameHost* render_frame_host,
int delegate_id,
int request_id) {
- // TODO(mlamouri): must be a DCHECK but can't at the moment because we do not
- // correctly notify players when switching PIP video in the same tab.
- if (pip_player_) {
- web_contents_impl()->ExitPictureInPicture();
-
- // Reset must happen after notifying the WebContents because it may interact
- // with it.
- pip_player_.reset();
-
- UpdateVideoLock();
- }
+ ExitPictureInPictureInternal();
render_frame_host->Send(
new MediaPlayerDelegateMsg_OnPictureInPictureModeEnded_ACK(
@@ -337,12 +357,16 @@ void MediaWebContentsObserver::OnPictureInPictureSurfaceChanged(
DCHECK(surface_id.is_valid());
DCHECK(pip_player_);
+ pip_player_ = MediaPlayerId(render_frame_host, delegate_id);
+
PictureInPictureWindowControllerImpl* pip_controller =
PictureInPictureWindowControllerImpl::FromWebContents(
web_contents_impl());
- DCHECK(pip_controller);
- pip_controller->EmbedSurface(surface_id, natural_size);
+ // The PictureInPictureWindowController instance may not have been created by
+ // the embedder.
+ if (pip_controller)
+ pip_controller->EmbedSurface(surface_id, natural_size);
}
void MediaWebContentsObserver::ClearWakeLocks(
@@ -448,18 +472,18 @@ void MediaWebContentsObserver::OnMediaMutedStatusChanged(
void MediaWebContentsObserver::AddMediaPlayerEntry(
const MediaPlayerId& id,
ActiveMediaPlayerMap* player_map) {
- (*player_map)[id.first].insert(id.second);
+ (*player_map)[id.render_frame_host].insert(id.delegate_id);
}
bool MediaWebContentsObserver::RemoveMediaPlayerEntry(
const MediaPlayerId& id,
ActiveMediaPlayerMap* player_map) {
- auto it = player_map->find(id.first);
+ auto it = player_map->find(id.render_frame_host);
if (it == player_map->end())
return false;
// Remove the player.
- bool did_remove = it->second.erase(id.second) == 1;
+ bool did_remove = it->second.erase(id.delegate_id) == 1;
if (!did_remove)
return false;
@@ -484,6 +508,18 @@ void MediaWebContentsObserver::RemoveAllMediaPlayerEntries(
player_map->erase(it);
}
+void MediaWebContentsObserver::ExitPictureInPictureInternal() {
+ DCHECK(pip_player_);
+
+ web_contents_impl()->ExitPictureInPicture();
+
+ // Reset must happen after notifying the WebContents because it may interact
+ // with it.
+ pip_player_.reset();
+
+ UpdateVideoLock();
+}
+
WebContentsImpl* MediaWebContentsObserver::web_contents_impl() const {
return static_cast<WebContentsImpl*>(web_contents());
}
diff --git a/chromium/content/browser/media/media_web_contents_observer.h b/chromium/content/browser/media/media_web_contents_observer.h
index 2655629a1da..67d25de6fd2 100644
--- a/chromium/content/browser/media/media_web_contents_observer.h
+++ b/chromium/content/browser/media/media_web_contents_observer.h
@@ -162,6 +162,10 @@ class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver {
ActiveMediaPlayerMap* player_map,
std::set<MediaPlayerId>* removed_players);
+ // Internal method to exit Picture-in-Picture from an event received from the
+ // renderer process.
+ void ExitPictureInPictureInternal();
+
// Convenience method that casts web_contents() to a WebContentsImpl*.
WebContentsImpl* web_contents_impl() const;
diff --git a/chromium/content/browser/media/midi_host.cc b/chromium/content/browser/media/midi_host.cc
index cc77c0a6895..712e186aab6 100644
--- a/chromium/content/browser/media/midi_host.cc
+++ b/chromium/content/browser/media/midi_host.cc
@@ -7,6 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/process/process.h"
+#include "base/stl_util.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/bad_message.h"
#include "content/browser/browser_main_loop.h"
@@ -108,8 +109,7 @@ void MidiHost::OnSendData(uint32_t port,
// Blink running in a renderer checks permission to raise a SecurityError
// in JavaScript. The actual permission check for security purposes
// happens here in the browser process.
- if (!has_sys_ex_permission_ &&
- std::find(data.begin(), data.end(), kSysExByte) != data.end()) {
+ if (!has_sys_ex_permission_ && base::ContainsValue(data, kSysExByte)) {
bad_message::ReceivedBadMessage(this, bad_message::MH_SYS_EX_PERMISSION);
return;
}
diff --git a/chromium/content/browser/media/mojo_audio_logging_adapter.cc b/chromium/content/browser/media/mojo_audio_logging_adapter.cc
deleted file mode 100644
index c3ee310692a..00000000000
--- a/chromium/content/browser/media/mojo_audio_logging_adapter.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/media/mojo_audio_logging_adapter.h"
-
-#include <utility>
-
-#include "content/browser/media/media_internals.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
-
-namespace content {
-
-MojoAudioLogAdapter::MojoAudioLogAdapter(media::mojom::AudioLogPtr audio_log)
- : audio_log_(std::move(audio_log)) {}
-
-MojoAudioLogAdapter::~MojoAudioLogAdapter() = default;
-
-void MojoAudioLogAdapter::OnCreated(const media::AudioParameters& params,
- const std::string& device_id) {
- audio_log_->OnCreated(params, device_id);
-}
-
-void MojoAudioLogAdapter::OnStarted() {
- audio_log_->OnStarted();
-}
-
-void MojoAudioLogAdapter::OnStopped() {
- audio_log_->OnStopped();
-}
-
-void MojoAudioLogAdapter::OnClosed() {
- audio_log_->OnClosed();
-}
-
-void MojoAudioLogAdapter::OnError() {
- audio_log_->OnError();
-}
-
-void MojoAudioLogAdapter::OnSetVolume(double volume) {
- audio_log_->OnSetVolume(volume);
-}
-
-void MojoAudioLogAdapter::OnLogMessage(const std::string& message) {
- audio_log_->OnLogMessage(message);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/media/mojo_audio_logging_adapter.h b/chromium/content/browser/media/mojo_audio_logging_adapter.h
deleted file mode 100644
index 020d62448e1..00000000000
--- a/chromium/content/browser/media/mojo_audio_logging_adapter.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_MEDIA_MOJO_AUDIO_LOGGING_ADAPTER_H_
-#define CONTENT_BROWSER_MEDIA_MOJO_AUDIO_LOGGING_ADAPTER_H_
-
-#include <map>
-#include <string>
-
-#include "base/macros.h"
-#include "base/sequence_checker.h"
-#include "content/common/content_export.h"
-#include "media/audio/audio_logging.h"
-#include "media/mojo/interfaces/audio_logging.mojom.h"
-
-namespace content {
-
-// This class wraps a media::mojom::AudioLogPtr into a media::AudioLog.
-// TODO(crbug.com/812557): Move this class to the audio service once the audio
-// service is in charge of creating and owning the AudioManager.
-class CONTENT_EXPORT MojoAudioLogAdapter : public media::AudioLog {
- public:
- explicit MojoAudioLogAdapter(media::mojom::AudioLogPtr audio_log);
- ~MojoAudioLogAdapter() override;
-
- // media::AudioLog implementation.
- void OnCreated(const media::AudioParameters& params,
- const std::string& device_id) override;
- void OnStarted() override;
- void OnStopped() override;
- void OnClosed() override;
- void OnError() override;
- void OnSetVolume(double volume) override;
- void OnLogMessage(const std::string& message) override;
-
- private:
- media::mojom::AudioLogPtr audio_log_;
-
- DISALLOW_COPY_AND_ASSIGN(MojoAudioLogAdapter);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_MEDIA_MOJO_AUDIO_LOGGING_ADAPTER_H_
diff --git a/chromium/content/browser/media/session/media_session_controller.cc b/chromium/content/browser/media/session/media_session_controller.cc
index 3a59f89f0a0..69df8daac0e 100644
--- a/chromium/content/browser/media/session/media_session_controller.cc
+++ b/chromium/content/browser/media/session/media_session_controller.cc
@@ -77,39 +77,40 @@ bool MediaSessionController::Initialize(
void MediaSessionController::OnSuspend(int player_id) {
DCHECK_EQ(player_id_, player_id);
- id_.first->Send(
- new MediaPlayerDelegateMsg_Pause(id_.first->GetRoutingID(), id_.second));
+ id_.render_frame_host->Send(new MediaPlayerDelegateMsg_Pause(
+ id_.render_frame_host->GetRoutingID(), id_.delegate_id));
}
void MediaSessionController::OnResume(int player_id) {
DCHECK_EQ(player_id_, player_id);
- id_.first->Send(
- new MediaPlayerDelegateMsg_Play(id_.first->GetRoutingID(), id_.second));
+ id_.render_frame_host->Send(new MediaPlayerDelegateMsg_Play(
+ id_.render_frame_host->GetRoutingID(), id_.delegate_id));
}
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));
+ id_.render_frame_host->Send(new MediaPlayerDelegateMsg_SeekForward(
+ id_.render_frame_host->GetRoutingID(), id_.delegate_id, 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));
+ id_.render_frame_host->Send(new MediaPlayerDelegateMsg_SeekBackward(
+ id_.render_frame_host->GetRoutingID(), id_.delegate_id, seek_time));
}
void MediaSessionController::OnSetVolumeMultiplier(int player_id,
double volume_multiplier) {
DCHECK_EQ(player_id_, player_id);
- id_.first->Send(new MediaPlayerDelegateMsg_UpdateVolumeMultiplier(
- id_.first->GetRoutingID(), id_.second, volume_multiplier));
+ id_.render_frame_host->Send(new MediaPlayerDelegateMsg_UpdateVolumeMultiplier(
+ id_.render_frame_host->GetRoutingID(), id_.delegate_id,
+ volume_multiplier));
}
RenderFrameHost* MediaSessionController::render_frame_host() const {
- return id_.first;
+ return id_.render_frame_host;
}
void MediaSessionController::OnPlaybackPaused() {
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 96fd8a37b00..433d2de0937 100644
--- a/chromium/content/browser/media/session/media_session_controller_unittest.cc
+++ b/chromium/content/browser/media/session/media_session_controller_unittest.cc
@@ -74,9 +74,9 @@ class MediaSessionControllerTest : public RenderViewHostImplTestHarness {
if (!T::Read(msg, &result))
return false;
- EXPECT_EQ(id_.second, std::get<0>(result));
+ EXPECT_EQ(id_.delegate_id, std::get<0>(result));
test_sink().ClearMessages();
- return id_.second == std::get<0>(result);
+ return id_.delegate_id == std::get<0>(result);
}
template <typename T>
@@ -89,8 +89,8 @@ class MediaSessionControllerTest : public RenderViewHostImplTestHarness {
if (!T::Read(msg, &result))
return false;
- EXPECT_EQ(id_.second, std::get<0>(result));
- if (id_.second != std::get<0>(result))
+ EXPECT_EQ(id_.delegate_id, std::get<0>(result));
+ if (id_.delegate_id != std::get<0>(result))
return false;
EXPECT_EQ(expected_seek_time, std::get<1>(result));
@@ -108,8 +108,8 @@ class MediaSessionControllerTest : public RenderViewHostImplTestHarness {
if (!T::Read(msg, &result))
return false;
- EXPECT_EQ(id_.second, std::get<0>(result));
- if (id_.second != std::get<0>(result))
+ EXPECT_EQ(id_.delegate_id, std::get<0>(result));
+ if (id_.delegate_id != std::get<0>(result))
return false;
EXPECT_EQ(expected_multiplier, std::get<1>(result));
@@ -117,7 +117,8 @@ class MediaSessionControllerTest : public RenderViewHostImplTestHarness {
return expected_multiplier == std::get<1>(result);
}
- WebContentsObserver::MediaPlayerId id_;
+ WebContentsObserver::MediaPlayerId id_ =
+ WebContentsObserver::MediaPlayerId::createMediaPlayerIdForTests();
std::unique_ptr<MediaSessionController> controller_;
};
diff --git a/chromium/content/browser/media/session/media_session_controllers_manager.cc b/chromium/content/browser/media/session/media_session_controllers_manager.cc
index 6eb3dd46032..33947c0d4b6 100644
--- a/chromium/content/browser/media/session/media_session_controllers_manager.cc
+++ b/chromium/content/browser/media/session/media_session_controllers_manager.cc
@@ -38,7 +38,7 @@ void MediaSessionControllersManager::RenderFrameDeleted(
return;
for (auto it = controllers_map_.begin(); it != controllers_map_.end();) {
- if (it->first.first == render_frame_host)
+ if (it->first.render_frame_host == render_frame_host)
it = controllers_map_.erase(it);
else
++it;
diff --git a/chromium/content/browser/media/session/media_session_controllers_manager_unittest.cc b/chromium/content/browser/media/session/media_session_controllers_manager_unittest.cc
index 61771490a62..e8e18e1f400 100644
--- a/chromium/content/browser/media/session/media_session_controllers_manager_unittest.cc
+++ b/chromium/content/browser/media/session/media_session_controllers_manager_unittest.cc
@@ -90,7 +90,9 @@ class MediaSessionControllersManagerTest
}
protected:
- MediaSessionControllersManager::MediaPlayerId media_player_id_;
+ MediaSessionControllersManager::MediaPlayerId media_player_id_ =
+ MediaSessionControllersManager::MediaPlayerId::
+ createMediaPlayerIdForTests();
std::unique_ptr<StrictMock<MockMediaSessionController>>
mock_media_session_controller_;
StrictMock<MockMediaSessionController>* mock_media_session_controller_ptr_ =
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 28fdcebf58d..f423db1ed37 100644
--- a/chromium/content/browser/media/session/media_session_impl_browsertest.cc
+++ b/chromium/content/browser/media/session/media_session_impl_browsertest.cc
@@ -13,7 +13,7 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_samples.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_tick_clock.h"
#include "content/browser/media/session/audio_focus_delegate.h"
#include "content/browser/media/session/media_session_service_impl.h"
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 95e428bd4c6..1efa52b4fd1 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
@@ -8,7 +8,7 @@
#include <memory>
#include "base/metrics/histogram_samples.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "content/browser/media/session/media_session_player_observer.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
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 2a11394e2b2..00717a379e4 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
@@ -139,9 +139,15 @@ class MediaSessionServiceImplBrowserTest : public ContentBrowserTest {
std::unique_ptr<MockMediaSessionPlayerObserver> player_;
};
+#if defined(LEAK_SANITIZER)
+// TODO(crbug.com/850870) Plug the leaks.
+#define MAYBE_CrashMessageOnUnload DISABLED_CrashMessageOnUnload
+#else
+#define MAYBE_CrashMessageOnUnload CrashMessageOnUnload
+#endif
// Two windows from the same BrowserContext.
IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest,
- CrashMessageOnUnload) {
+ MAYBE_CrashMessageOnUnload) {
NavigateToURL(shell(), GetTestUrl("media/session", "embedder.html"));
// Navigate to a chrome:// URL to avoid render process re-use.
NavigateToURL(shell(), GURL("chrome://flags"));
@@ -154,8 +160,15 @@ IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest,
// observers to wait for the message to be processed on the MediaSessionObserver
// side.
+#if defined(LEAK_SANITIZER)
+// TODO(crbug.com/850870) Plug the leaks.
+#define MAYBE_ResetServiceWhenNavigatingAway \
+ DISABLED_ResetServiceWhenNavigatingAway
+#else
+#define MAYBE_ResetServiceWhenNavigatingAway ResetServiceWhenNavigatingAway
+#endif
IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest,
- ResetServiceWhenNavigatingAway) {
+ MAYBE_ResetServiceWhenNavigatingAway) {
NavigateToURL(shell(), GetTestUrl(".", "title1.html"));
EnsurePlayer();
@@ -176,8 +189,16 @@ IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest,
EXPECT_EQ(0u, GetService()->actions().size());
}
+#if defined(LEAK_SANITIZER)
+// TODO(crbug.com/850870) Plug the leaks.
+#define MAYBE_DontResetServiceForSameDocumentNavigation \
+ DISABLED_DontResetServiceForSameDocumentNavigation
+#else
+#define MAYBE_DontResetServiceForSameDocumentNavigation \
+ DontResetServiceForSameDocumentNavigation
+#endif
IN_PROC_BROWSER_TEST_F(MediaSessionServiceImplBrowserTest,
- DontResetServiceForSameDocumentNavigation) {
+ MAYBE_DontResetServiceForSameDocumentNavigation) {
NavigateToURL(shell(), GetTestUrl(".", "title1.html"));
EnsurePlayer();
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 4b6fc027436..973d7650b02 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
@@ -5,7 +5,7 @@
#include "content/browser/media/session/media_session_uma_helper.h"
#include "base/metrics/histogram_samples.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_tick_clock.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/content/browser/memory/memory_coordinator_impl_browsertest.cc b/chromium/content/browser/memory/memory_coordinator_impl_browsertest.cc
index 9966aafe47a..3a84581863b 100644
--- a/chromium/content/browser/memory/memory_coordinator_impl_browsertest.cc
+++ b/chromium/content/browser/memory/memory_coordinator_impl_browsertest.cc
@@ -6,6 +6,7 @@
#include "base/test/scoped_feature_list.h"
#include "content/browser/browser_main_loop.h"
+#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/public/common/content_features.h"
#include "content/public/test/content_browser_test.h"
@@ -32,10 +33,24 @@ class MemoryCoordinatorImplBrowserTest : public ContentBrowserTest {
// implemented.
#if !defined(OS_MACOSX)
+void GetGpuProcessIDOnIO(int* gpu_process_id, base::WaitableEvent* event) {
+ *gpu_process_id = GpuProcessHost::Get()->GetIDForTesting();
+ event->Signal();
+}
+
IN_PROC_BROWSER_TEST_F(MemoryCoordinatorImplBrowserTest, HandleAdded) {
GURL url = GetTestUrl("", "simple_page.html");
NavigateToURL(shell(), url);
+ // Query the GPU process ID from the IO thread.
+ int gpu_process_id = -1;
+ base::WaitableEvent io_event;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&GetGpuProcessIDOnIO, &gpu_process_id, &io_event));
+ io_event.Wait();
+ ASSERT_NE(gpu_process_id, -1);
+
size_t num_children = 0;
for (auto const& it : MemoryCoordinatorImpl::GetInstance()->children()) {
int process_id = it.first;
@@ -46,6 +61,10 @@ IN_PROC_BROWSER_TEST_F(MemoryCoordinatorImplBrowserTest, HandleAdded) {
if (spare_process && process_id == spare_process->GetID())
continue;
+ // Ignore the GPU process.
+ if (process_id == gpu_process_id)
+ continue;
+
num_children++;
}
diff --git a/chromium/content/browser/mojo_sandbox_browsertest.cc b/chromium/content/browser/mojo_sandbox_browsertest.cc
index 8ec022566d6..89168cc96c9 100644
--- a/chromium/content/browser/mojo_sandbox_browsertest.cc
+++ b/chromium/content/browser/mojo_sandbox_browsertest.cc
@@ -52,6 +52,7 @@ class MojoSandboxTest : public ContentBrowserTest {
private:
void StartUtilityProcessOnIoThread() {
host_.reset(new UtilityProcessHost(nullptr, nullptr));
+ host_->SetMetricsName("mojo_sandbox_test_process");
ASSERT_TRUE(host_->Start());
}
diff --git a/chromium/content/browser/net/network_quality_observer_impl.cc b/chromium/content/browser/net/network_quality_observer_impl.cc
index 6dd157e8218..dafe9179271 100644
--- a/chromium/content/browser/net/network_quality_observer_impl.cc
+++ b/chromium/content/browser/net/network_quality_observer_impl.cc
@@ -91,10 +91,12 @@ class NetworkQualityObserverImpl::UiThreadObserver
// Notify all the existing renderers of the change in the network quality.
for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
!it.IsAtEnd(); it.Advance()) {
- it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
- last_notified_type_, last_notified_network_quality_.http_rtt(),
- last_notified_network_quality_.transport_rtt(),
- last_notified_network_quality_.downstream_throughput_kbps());
+ if (it.GetCurrentValue()->IsInitializedAndNotDead()) {
+ it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
+ last_notified_type_, last_notified_network_quality_.http_rtt(),
+ last_notified_network_quality_.transport_rtt(),
+ last_notified_network_quality_.downstream_throughput_kbps());
+ }
}
}
@@ -107,10 +109,12 @@ class NetworkQualityObserverImpl::UiThreadObserver
// Notify all the existing renderers of the change in the network quality.
for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
!it.IsAtEnd(); it.Advance()) {
- it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
- last_notified_type_, last_notified_network_quality_.http_rtt(),
- last_notified_network_quality_.transport_rtt(),
- last_notified_network_quality_.downstream_throughput_kbps());
+ if (it.GetCurrentValue()->IsInitializedAndNotDead()) {
+ it.GetCurrentValue()->GetRendererInterface()->OnNetworkQualityChanged(
+ last_notified_type_, last_notified_network_quality_.http_rtt(),
+ last_notified_network_quality_.transport_rtt(),
+ last_notified_network_quality_.downstream_throughput_kbps());
+ }
}
}
diff --git a/chromium/content/browser/net/network_quality_observer_impl_unittest.cc b/chromium/content/browser/net/network_quality_observer_impl_unittest.cc
index 19e9d677fe8..cd9ab62b89b 100644
--- a/chromium/content/browser/net/network_quality_observer_impl_unittest.cc
+++ b/chromium/content/browser/net/network_quality_observer_impl_unittest.cc
@@ -5,7 +5,7 @@
#include "content/browser/net/network_quality_observer_impl.h"
#include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/time/time.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/nqe/effective_connection_type.h"
diff --git a/chromium/content/browser/net/quota_policy_cookie_store.cc b/chromium/content/browser/net/quota_policy_cookie_store.cc
index 98068af557c..116ce029657 100644
--- a/chromium/content/browser/net/quota_policy_cookie_store.cc
+++ b/chromium/content/browser/net/quota_policy_cookie_store.cc
@@ -21,102 +21,23 @@
#include "net/cookies/cookie_util.h"
#include "net/extras/sqlite/cookie_crypto_delegate.h"
#include "storage/browser/quota/special_storage_policy.h"
-#include "url/gurl.h"
namespace content {
QuotaPolicyCookieStore::QuotaPolicyCookieStore(
const scoped_refptr<net::SQLitePersistentCookieStore>& cookie_store,
storage::SpecialStoragePolicy* special_storage_policy)
- : special_storage_policy_(special_storage_policy),
- persistent_store_(cookie_store) {
-}
+ : SessionCleanupCookieStore(cookie_store),
+ special_storage_policy_(special_storage_policy) {}
QuotaPolicyCookieStore::~QuotaPolicyCookieStore() {
- using CookieOrigin = net::SQLitePersistentCookieStore::CookieOrigin;
if (!special_storage_policy_.get() ||
!special_storage_policy_->HasSessionOnlyOrigins()) {
return;
}
- std::list<CookieOrigin> session_only_cookies;
- auto delete_cookie_predicate =
- special_storage_policy_->CreateDeleteCookieOnExitPredicate();
- DCHECK(delete_cookie_predicate);
-
- for (const auto& entry : cookies_per_origin_) {
- if (entry.second == 0) {
- continue;
- }
- const CookieOrigin& cookie = entry.first;
- const GURL url(
- net::cookie_util::CookieOriginToURL(cookie.first, cookie.second));
- if (!url.is_valid() ||
- !delete_cookie_predicate.Run(cookie.first, cookie.second)) {
- continue;
- }
- session_only_cookies.push_back(cookie);
- }
-
- persistent_store_->DeleteAllInList(session_only_cookies);
-}
-
-void QuotaPolicyCookieStore::Load(const LoadedCallback& loaded_callback) {
- persistent_store_->Load(
- base::Bind(&QuotaPolicyCookieStore::OnLoad, this, loaded_callback));
-}
-
-void QuotaPolicyCookieStore::LoadCookiesForKey(
- const std::string& key,
- const LoadedCallback& loaded_callback) {
- persistent_store_->LoadCookiesForKey(
- key,
- base::Bind(&QuotaPolicyCookieStore::OnLoad, this, loaded_callback));
-}
-
-void QuotaPolicyCookieStore::AddCookie(const net::CanonicalCookie& cc) {
- net::SQLitePersistentCookieStore::CookieOrigin origin(
- cc.Domain(), cc.IsSecure());
- ++cookies_per_origin_[origin];
- persistent_store_->AddCookie(cc);
-}
-
-void QuotaPolicyCookieStore::UpdateCookieAccessTime(
- const net::CanonicalCookie& cc) {
- persistent_store_->UpdateCookieAccessTime(cc);
-}
-
-void QuotaPolicyCookieStore::DeleteCookie(const net::CanonicalCookie& cc) {
- net::SQLitePersistentCookieStore::CookieOrigin origin(
- cc.Domain(), cc.IsSecure());
- DCHECK_GE(cookies_per_origin_[origin], 1U);
- --cookies_per_origin_[origin];
- persistent_store_->DeleteCookie(cc);
-}
-
-void QuotaPolicyCookieStore::SetForceKeepSessionState() {
- special_storage_policy_ = nullptr;
-}
-
-void QuotaPolicyCookieStore::SetBeforeFlushCallback(
- base::RepeatingClosure callback) {
- persistent_store_->SetBeforeFlushCallback(std::move(callback));
-}
-
-void QuotaPolicyCookieStore::Flush(base::OnceClosure callback) {
- persistent_store_->Flush(std::move(callback));
-}
-
-void QuotaPolicyCookieStore::OnLoad(
- const LoadedCallback& loaded_callback,
- std::vector<std::unique_ptr<net::CanonicalCookie>> cookies) {
- for (const auto& cookie : cookies) {
- net::SQLitePersistentCookieStore::CookieOrigin origin(
- cookie->Domain(), cookie->IsSecure());
- ++cookies_per_origin_[origin];
- }
-
- loaded_callback.Run(std::move(cookies));
+ DeleteSessionCookies(
+ special_storage_policy_->CreateDeleteCookieOnExitPredicate());
}
CookieStoreConfig::CookieStoreConfig()
diff --git a/chromium/content/browser/net/quota_policy_cookie_store.h b/chromium/content/browser/net/quota_policy_cookie_store.h
index f55b34a3a1f..e7540e599aa 100644
--- a/chromium/content/browser/net/quota_policy_cookie_store.h
+++ b/chromium/content/browser/net/quota_policy_cookie_store.h
@@ -11,16 +11,11 @@
#include <vector>
#include "base/callback_forward.h"
-#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
-#include "net/cookies/cookie_monster.h"
#include "net/extras/sqlite/sqlite_persistent_cookie_store.h"
-
-namespace net {
-class CanonicalCookie;
-} // namespace net
+#include "services/network/session_cleanup_cookie_store.h"
namespace storage {
class SpecialStoragePolicy;
@@ -34,41 +29,17 @@ namespace content {
// |SpecialStoragePolicy| is consulted when the SQLite database is closed to
// decide which cookies to keep.
class CONTENT_EXPORT QuotaPolicyCookieStore
- : public net::CookieMonster::PersistentCookieStore {
+ : public network::SessionCleanupCookieStore {
public:
// Wraps the passed-in |cookie_store|.
QuotaPolicyCookieStore(
const scoped_refptr<net::SQLitePersistentCookieStore>& cookie_store,
storage::SpecialStoragePolicy* special_storage_policy);
- // net::CookieMonster::PersistentCookieStore:
- void Load(const LoadedCallback& loaded_callback) override;
- void LoadCookiesForKey(const std::string& key,
- const LoadedCallback& callback) override;
- void AddCookie(const net::CanonicalCookie& cc) override;
- void UpdateCookieAccessTime(const net::CanonicalCookie& cc) override;
- void DeleteCookie(const net::CanonicalCookie& cc) override;
- void SetForceKeepSessionState() override;
- void SetBeforeFlushCallback(base::RepeatingClosure callback) override;
- void Flush(base::OnceClosure callback) override;
-
private:
- typedef std::map<net::SQLitePersistentCookieStore::CookieOrigin, size_t>
- CookiesPerOriginMap;
-
~QuotaPolicyCookieStore() override;
- // Called after cookies are loaded from the database. Calls |loaded_callback|
- // when done.
- void OnLoad(const LoadedCallback& loaded_callback,
- std::vector<std::unique_ptr<net::CanonicalCookie>> cookies);
-
- // Map of (domain keys(eTLD+1), is secure cookie) to number of cookies in the
- // database.
- CookiesPerOriginMap cookies_per_origin_;
-
scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
- scoped_refptr<net::SQLitePersistentCookieStore> persistent_store_;
DISALLOW_COPY_AND_ASSIGN(QuotaPolicyCookieStore);
};
diff --git a/chromium/content/browser/net/reporting_service_proxy.cc b/chromium/content/browser/net/reporting_service_proxy.cc
index a729bc91dc4..6f525514216 100644
--- a/chromium/content/browser/net/reporting_service_proxy.cc
+++ b/chromium/content/browser/net/reporting_service_proxy.cc
@@ -16,6 +16,7 @@
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/reporting/reporting_report.h"
#include "net/reporting/reporting_service.h"
+#include "net/url_request/http_user_agent_settings.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "third_party/blink/public/platform/reporting.mojom.h"
@@ -35,32 +36,38 @@ class ReportingServiceProxyImpl : public blink::mojom::ReportingServiceProxy {
void QueueInterventionReport(const GURL& url,
const std::string& message,
- const std::string& source_file,
+ const base::Optional<std::string>& source_file,
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);
+ if (source_file)
+ body->SetString("sourceFile", *source_file);
+ if (line_number)
+ body->SetInteger("lineNumber", line_number);
+ if (column_number)
+ body->SetInteger("columnNumber", column_number);
QueueReport(url, "default", "intervention", std::move(body));
}
void QueueDeprecationReport(const GURL& url,
const std::string& id,
- base::Time anticipatedRemoval,
+ base::Optional<base::Time> anticipatedRemoval,
const std::string& message,
- const std::string& source_file,
+ const base::Optional<std::string>& source_file,
int line_number,
int column_number) override {
auto body = std::make_unique<base::DictionaryValue>();
body->SetString("id", id);
- if (anticipatedRemoval.is_null())
- body->SetDouble("anticipatedRemoval", anticipatedRemoval.ToDoubleT());
+ if (anticipatedRemoval)
+ body->SetDouble("anticipatedRemoval", anticipatedRemoval->ToDoubleT());
body->SetString("message", message);
- body->SetString("sourceFile", source_file);
- body->SetInteger("lineNumber", line_number);
- body->SetInteger("columnNumber", column_number);
+ if (source_file)
+ body->SetString("sourceFile", *source_file);
+ if (line_number)
+ body->SetInteger("lineNumber", line_number);
+ if (column_number)
+ body->SetInteger("columnNumber", column_number);
QueueReport(url, "default", "deprecation", std::move(body));
}
@@ -75,7 +82,7 @@ class ReportingServiceProxyImpl : public blink::mojom::ReportingServiceProxy {
const std::string& blocked_uri,
int line_number,
int column_number,
- const std::string& source_file,
+ const base::Optional<std::string>& source_file,
int status_code,
const std::string& script_sample) override {
auto body = std::make_unique<base::DictionaryValue>();
@@ -90,7 +97,8 @@ class ReportingServiceProxyImpl : public blink::mojom::ReportingServiceProxy {
body->SetInteger("line-number", line_number);
if (column_number)
body->SetInteger("column-number", column_number);
- body->SetString("source-file", source_file);
+ if (source_file)
+ body->SetString("sourceFile", *source_file);
if (status_code)
body->SetInteger("status-code", status_code);
body->SetString("script-sample", script_sample);
@@ -118,7 +126,11 @@ class ReportingServiceProxyImpl : public blink::mojom::ReportingServiceProxy {
// Depth is only non-zero for NEL reports, and those can't come from the
// renderer.
- reporting_service->QueueReport(url, group, type, std::move(body),
+ std::string user_agent;
+ if (request_context->http_user_agent_settings() != nullptr)
+ user_agent = request_context->http_user_agent_settings()->GetUserAgent();
+ reporting_service->QueueReport(url, user_agent, group, type,
+ std::move(body),
/* depth= */ 0);
}
diff --git a/chromium/content/browser/net_info_browsertest.cc b/chromium/content/browser/net_info_browsertest.cc
index 1ef2c6511fd..e5bf126c3c4 100644
--- a/chromium/content/browser/net_info_browsertest.cc
+++ b/chromium/content/browser/net_info_browsertest.cc
@@ -9,7 +9,7 @@
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "build/build_config.h"
#include "content/browser/net/network_quality_observer_impl.h"
#include "content/public/common/content_switches.h"
diff --git a/chromium/content/browser/network_service_browsertest.cc b/chromium/content/browser/network_service_browsertest.cc
index 1e329cf5dfa..e8e70eb852f 100644
--- a/chromium/content/browser/network_service_browsertest.cc
+++ b/chromium/content/browser/network_service_browsertest.cc
@@ -56,12 +56,14 @@ class RenderProcessKilledObserver : public WebContentsObserver {
class WebUITestWebUIControllerFactory : public WebUIControllerFactory {
public:
- WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
- const GURL& url) const override {
+ std::unique_ptr<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;
+ return HasWebUIScheme(url) ? std::make_unique<WebUIController>(web_ui)
+ : nullptr;
}
WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
const GURL& url) const override {
diff --git a/chromium/content/browser/network_service_client.cc b/chromium/content/browser/network_service_client.cc
index 08fdcd44f7e..afeafe636a5 100644
--- a/chromium/content/browser/network_service_client.cc
+++ b/chromium/content/browser/network_service_client.cc
@@ -5,6 +5,7 @@
#include "content/browser/network_service_client.h"
#include "base/optional.h"
+#include "base/task_scheduler/post_task.h"
#include "content/browser/devtools/devtools_url_loader_interceptor.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/ssl/ssl_client_auth_handler.h"
@@ -14,11 +15,14 @@
#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/child_process_security_policy.h"
+#include "content/public/browser/global_request_id.h"
#include "content/public/browser/login_delegate.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/resource_type.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/ssl/client_cert_store.h"
+#include "services/network/public/mojom/network_context.mojom.h"
namespace content {
namespace {
@@ -166,11 +170,14 @@ class LoginHandlerDelegate {
uint32_t routing_id,
uint32_t request_id,
const GURL& url,
+ scoped_refptr<net::HttpResponseHeaders> response_headers,
bool first_auth_attempt)
: auth_challenge_responder_(std::move(auth_challenge_responder)),
auth_info_(auth_info),
+ request_id_(process_id, request_id),
is_request_for_main_frame_(is_request_for_main_frame),
url_(url),
+ response_headers_(std::move(response_headers)),
first_auth_attempt_(first_auth_attempt),
web_contents_getter_(web_contents_getter) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -226,8 +233,9 @@ class LoginHandlerDelegate {
void CreateLoginDelegate() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
login_delegate_ = GetContentClient()->browser()->CreateLoginDelegate(
- auth_info_.get(), web_contents_getter_, is_request_for_main_frame_,
- url_, first_auth_attempt_,
+ auth_info_.get(), web_contents_getter_, request_id_,
+ is_request_for_main_frame_, url_, response_headers_,
+ first_auth_attempt_,
base::BindOnce(&LoginHandlerDelegate::RunAuthCredentials,
base::Unretained(this)));
@@ -255,13 +263,47 @@ class LoginHandlerDelegate {
network::mojom::AuthChallengeResponderPtr auth_challenge_responder_;
scoped_refptr<net::AuthChallengeInfo> auth_info_;
+ const content::GlobalRequestID request_id_;
bool is_request_for_main_frame_;
GURL url_;
+ const scoped_refptr<net::HttpResponseHeaders> response_headers_;
bool first_auth_attempt_;
ResourceRequestInfo::WebContentsGetter web_contents_getter_;
scoped_refptr<LoginDelegate> login_delegate_;
};
+void HandleFileUploadRequest(
+ uint32_t process_id,
+ bool async,
+ const std::vector<base::FilePath>& file_paths,
+ NetworkServiceClient::OnFileUploadRequestedCallback callback,
+ scoped_refptr<base::TaskRunner> task_runner) {
+ std::vector<base::File> files;
+ uint32_t file_flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
+ (async ? base::File::FLAG_ASYNC : 0);
+ ChildProcessSecurityPolicy* cpsp = ChildProcessSecurityPolicy::GetInstance();
+ for (const auto& file_path : file_paths) {
+ if (process_id != network::mojom::kBrowserProcessId &&
+ !cpsp->CanReadFile(process_id, file_path)) {
+ task_runner->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), net::ERR_ACCESS_DENIED,
+ std::vector<base::File>()));
+ return;
+ }
+ files.emplace_back(file_path, file_flags);
+ if (!files.back().IsValid()) {
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback),
+ net::FileErrorToNetError(files.back().error_details()),
+ std::vector<base::File>()));
+ return;
+ }
+ }
+ task_runner->PostTask(FROM_HERE, base::BindOnce(std::move(callback), net::OK,
+ std::move(files)));
+}
+
} // namespace
NetworkServiceClient::NetworkServiceClient(
@@ -279,6 +321,7 @@ void NetworkServiceClient::OnAuthRequired(
bool first_auth_attempt,
const scoped_refptr<net::AuthChallengeInfo>& auth_info,
int32_t resource_type,
+ const base::Optional<network::ResourceResponseHead>& head,
network::mojom::AuthChallengeResponderPtr auth_challenge_responder) {
base::Callback<WebContents*(void)> web_contents_getter =
process_id ? base::Bind(WebContentsImpl::FromRenderFrameHostID,
@@ -302,7 +345,7 @@ void NetworkServiceClient::OnAuthRequired(
new LoginHandlerDelegate(std::move(auth_challenge_responder),
std::move(web_contents_getter), auth_info,
is_request_for_main_frame, process_id, routing_id,
- request_id, url,
+ request_id, url, head ? head->headers : nullptr,
first_auth_attempt); // deletes self
}
@@ -349,4 +392,37 @@ void NetworkServiceClient::OnSSLCertificateError(
std::move(web_contents_getter), ssl_info, fatal);
}
+void NetworkServiceClient::OnFileUploadRequested(
+ uint32_t process_id,
+ bool async,
+ const std::vector<base::FilePath>& file_paths,
+ OnFileUploadRequestedCallback callback) {
+ base::PostTaskWithTraits(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
+ base::BindOnce(&HandleFileUploadRequest, process_id, async, file_paths,
+ std::move(callback),
+ base::SequencedTaskRunnerHandle::Get()));
+}
+
+void NetworkServiceClient::OnCookiesRead(int process_id,
+ int routing_id,
+ const GURL& url,
+ const GURL& first_party_url,
+ const net::CookieList& cookie_list,
+ bool blocked_by_policy) {
+ GetContentClient()->browser()->OnCookiesRead(process_id, routing_id, url,
+ first_party_url, cookie_list,
+ blocked_by_policy);
+}
+
+void NetworkServiceClient::OnCookieChange(int process_id,
+ int routing_id,
+ const GURL& url,
+ const GURL& first_party_url,
+ const net::CanonicalCookie& cookie,
+ bool blocked_by_policy) {
+ GetContentClient()->browser()->OnCookieChange(
+ process_id, routing_id, url, first_party_url, cookie, blocked_by_policy);
+}
+
} // namespace content
diff --git a/chromium/content/browser/network_service_client.h b/chromium/content/browser/network_service_client.h
index 900cba838bc..68c0af0a499 100644
--- a/chromium/content/browser/network_service_client.h
+++ b/chromium/content/browser/network_service_client.h
@@ -6,13 +6,15 @@
#define CONTENT_BROWSER_NETWORK_SERVICE_IMPL_H_
#include "base/macros.h"
+#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "url/gurl.h"
namespace content {
-class NetworkServiceClient : public network::mojom::NetworkServiceClient {
+class CONTENT_EXPORT NetworkServiceClient
+ : public network::mojom::NetworkServiceClient {
public:
explicit NetworkServiceClient(network::mojom::NetworkServiceClientRequest
network_service_client_request);
@@ -27,6 +29,7 @@ class NetworkServiceClient : public network::mojom::NetworkServiceClient {
bool first_auth_attempt,
const scoped_refptr<net::AuthChallengeInfo>& auth_info,
int32_t resource_type,
+ const base::Optional<network::ResourceResponseHead>& head,
network::mojom::AuthChallengeResponderPtr
auth_challenge_responder) override;
void OnCertificateRequested(
@@ -44,6 +47,22 @@ class NetworkServiceClient : public network::mojom::NetworkServiceClient {
const net::SSLInfo& ssl_info,
bool fatal,
OnSSLCertificateErrorCallback response) override;
+ void OnFileUploadRequested(uint32_t process_id,
+ bool async,
+ const std::vector<base::FilePath>& file_paths,
+ OnFileUploadRequestedCallback callback) override;
+ void OnCookiesRead(int process_id,
+ int routing_id,
+ const GURL& url,
+ const GURL& first_party_url,
+ const net::CookieList& cookie_list,
+ bool blocked_by_policy) override;
+ void OnCookieChange(int process_id,
+ int routing_id,
+ const GURL& url,
+ const GURL& first_party_url,
+ const net::CanonicalCookie& cookie,
+ bool blocked_by_policy) override;
private:
mojo::Binding<network::mojom::NetworkServiceClient> binding_;
diff --git a/chromium/content/browser/network_service_client_unittest.cc b/chromium/content/browser/network_service_client_unittest.cc
new file mode 100644
index 00000000000..37bf2ef1fd6
--- /dev/null
+++ b/chromium/content/browser/network_service_client_unittest.cc
@@ -0,0 +1,192 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/network_service_client.h"
+
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/test/scoped_task_environment.h"
+#include "content/browser/child_process_security_policy_impl.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+struct UploadResponse {
+ UploadResponse()
+ : callback(base::BindOnce(&UploadResponse::OnComplete,
+ base::Unretained(this))) {}
+
+ void OnComplete(int error_code, std::vector<base::File> opened_files) {
+ this->error_code = error_code;
+ this->opened_files = std::move(opened_files);
+ }
+
+ network::mojom::NetworkServiceClient::OnFileUploadRequestedCallback callback;
+ int error_code;
+ std::vector<base::File> opened_files;
+};
+
+void GrantAccess(const base::FilePath& file, int process_id) {
+ ChildProcessSecurityPolicy::GetInstance()->GrantReadFile(process_id, file);
+}
+
+void CreateFile(const base::FilePath& path, const char* content) {
+ base::File file(path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
+ ASSERT_TRUE(file.IsValid());
+ int content_size = strlen(content);
+ int bytes_written = file.Write(0, content, content_size);
+ EXPECT_EQ(bytes_written, content_size);
+}
+
+void ValidateFileContents(base::File& file, const char* expected_content) {
+ int expected_length = strlen(expected_content);
+ ASSERT_EQ(file.GetLength(), expected_length);
+ char content[expected_length];
+ file.Read(0, content, expected_length);
+ EXPECT_EQ(0, strncmp(content, expected_content, expected_length));
+}
+
+const int kBrowserProcessId = 0;
+const int kRendererProcessId = 1;
+const char kFileContent1[] = "test file content one";
+const char kFileContent2[] = "test file content two";
+
+} // namespace
+
+class NetworkServiceClientTest : public testing::Test {
+ public:
+ NetworkServiceClientTest() : client_(mojo::MakeRequest(&client_ptr_)) {}
+
+ void SetUp() override {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ChildProcessSecurityPolicyImpl::GetInstance()->Add(kRendererProcessId);
+ }
+
+ void TearDown() override {
+ ChildProcessSecurityPolicyImpl::GetInstance()->Remove(kRendererProcessId);
+ }
+
+ protected:
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ network::mojom::NetworkServiceClientPtr client_ptr_;
+ NetworkServiceClient client_;
+ base::ScopedTempDir temp_dir_;
+};
+
+TEST_F(NetworkServiceClientTest, UploadNoFiles) {
+ UploadResponse response;
+ client_.OnFileUploadRequested(kRendererProcessId, true, {},
+ std::move(response.callback));
+ scoped_task_environment_.RunUntilIdle();
+ EXPECT_EQ(net::OK, response.error_code);
+ EXPECT_EQ(0U, response.opened_files.size());
+}
+
+TEST_F(NetworkServiceClientTest, UploadOneValidAsyncFile) {
+ base::FilePath path = temp_dir_.GetPath().AppendASCII("filename");
+ CreateFile(path, kFileContent1);
+ GrantAccess(path, kRendererProcessId);
+
+ UploadResponse response;
+ client_.OnFileUploadRequested(kRendererProcessId, true, {path},
+ std::move(response.callback));
+ scoped_task_environment_.RunUntilIdle();
+ EXPECT_EQ(net::OK, response.error_code);
+ ASSERT_EQ(1U, response.opened_files.size());
+ EXPECT_TRUE(response.opened_files[0].async());
+}
+
+TEST_F(NetworkServiceClientTest, UploadOneValidFile) {
+ base::FilePath path = temp_dir_.GetPath().AppendASCII("filename");
+ CreateFile(path, kFileContent1);
+ GrantAccess(path, kRendererProcessId);
+
+ UploadResponse response;
+ client_.OnFileUploadRequested(kRendererProcessId, false, {path},
+ std::move(response.callback));
+ scoped_task_environment_.RunUntilIdle();
+ EXPECT_EQ(net::OK, response.error_code);
+ ASSERT_EQ(1U, response.opened_files.size());
+ EXPECT_FALSE(response.opened_files[0].async());
+ ValidateFileContents(response.opened_files[0], kFileContent1);
+}
+
+TEST_F(NetworkServiceClientTest, UploadTwoValidFiles) {
+ base::FilePath path1 = temp_dir_.GetPath().AppendASCII("filename1");
+ base::FilePath path2 = temp_dir_.GetPath().AppendASCII("filename2");
+ CreateFile(path1, kFileContent1);
+ CreateFile(path2, kFileContent2);
+ GrantAccess(path1, kRendererProcessId);
+ GrantAccess(path2, kRendererProcessId);
+
+ UploadResponse response;
+ client_.OnFileUploadRequested(kRendererProcessId, false, {path1, path2},
+ std::move(response.callback));
+ scoped_task_environment_.RunUntilIdle();
+ EXPECT_EQ(net::OK, response.error_code);
+ ASSERT_EQ(2U, response.opened_files.size());
+ ValidateFileContents(response.opened_files[0], kFileContent1);
+ ValidateFileContents(response.opened_files[1], kFileContent2);
+}
+
+TEST_F(NetworkServiceClientTest, UploadOneUnauthorizedFile) {
+ base::FilePath path = temp_dir_.GetPath().AppendASCII("filename");
+ CreateFile(path, kFileContent1);
+
+ UploadResponse response;
+ client_.OnFileUploadRequested(kRendererProcessId, false, {path},
+ std::move(response.callback));
+ scoped_task_environment_.RunUntilIdle();
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, response.error_code);
+ EXPECT_EQ(0U, response.opened_files.size());
+}
+
+TEST_F(NetworkServiceClientTest, UploadOneValidFileAndOneUnauthorized) {
+ base::FilePath path1 = temp_dir_.GetPath().AppendASCII("filename1");
+ base::FilePath path2 = temp_dir_.GetPath().AppendASCII("filename2");
+ CreateFile(path1, kFileContent1);
+ CreateFile(path2, kFileContent2);
+ GrantAccess(path1, kRendererProcessId);
+
+ UploadResponse response;
+ client_.OnFileUploadRequested(kRendererProcessId, false, {path1, path2},
+ std::move(response.callback));
+ scoped_task_environment_.RunUntilIdle();
+ EXPECT_EQ(net::ERR_ACCESS_DENIED, response.error_code);
+ EXPECT_EQ(0U, response.opened_files.size());
+}
+
+TEST_F(NetworkServiceClientTest, UploadOneValidFileAndOneNotFound) {
+ base::FilePath path1 = temp_dir_.GetPath().AppendASCII("filename1");
+ base::FilePath path2 = temp_dir_.GetPath().AppendASCII("filename2");
+ CreateFile(path1, kFileContent1);
+ GrantAccess(path1, kRendererProcessId);
+ GrantAccess(path2, kRendererProcessId);
+
+ UploadResponse response;
+ client_.OnFileUploadRequested(kRendererProcessId, false, {path1, path2},
+ std::move(response.callback));
+ scoped_task_environment_.RunUntilIdle();
+ EXPECT_EQ(net::ERR_FILE_NOT_FOUND, response.error_code);
+ EXPECT_EQ(0U, response.opened_files.size());
+}
+
+TEST_F(NetworkServiceClientTest, UploadFromBrowserProcess) {
+ base::FilePath path = temp_dir_.GetPath().AppendASCII("filename");
+ CreateFile(path, kFileContent1);
+ // No grant necessary for browser process.
+
+ UploadResponse response;
+ client_.OnFileUploadRequested(kBrowserProcessId, false, {path},
+ std::move(response.callback));
+ scoped_task_environment_.RunUntilIdle();
+ EXPECT_EQ(net::OK, response.error_code);
+ ASSERT_EQ(1U, response.opened_files.size());
+ ValidateFileContents(response.opened_files[0], kFileContent1);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/network_service_instance.cc b/chromium/content/browser/network_service_instance.cc
index c62cf6403bf..374ac6da02d 100644
--- a/chromium/content/browser/network_service_instance.cc
+++ b/chromium/content/browser/network_service_instance.cc
@@ -58,6 +58,9 @@ network::mojom::NetworkService* GetNetworkService() {
delete g_client; // In case we're recreating the network service.
g_client = new NetworkServiceClient(mojo::MakeRequest(&client_ptr));
(*g_network_service_ptr)->SetClient(std::move(client_ptr));
+
+ GetContentClient()->browser()->OnNetworkServiceCreated(
+ g_network_service_ptr->get());
}
return g_network_service_ptr->get();
}
diff --git a/chromium/content/browser/notifications/blink_notification_service_impl.cc b/chromium/content/browser/notifications/blink_notification_service_impl.cc
index 53101e0342c..cbcd2b5369f 100644
--- a/chromium/content/browser/notifications/blink_notification_service_impl.cc
+++ b/chromium/content/browser/notifications/blink_notification_service_impl.cc
@@ -11,15 +11,16 @@
#include "base/strings/string16.h"
#include "content/browser/notifications/notification_event_dispatcher_impl.h"
#include "content/browser/notifications/platform_notification_context_impl.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/notification_database_data.h"
+#include "content/public/browser/permission_controller.h"
+#include "content/public/browser/permission_type.h"
#include "content/public/browser/platform_notification_service.h"
#include "content/public/common/content_client.h"
#include "content/public/common/notification_resources.h"
#include "content/public/common/platform_notification_data.h"
-#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"
namespace content {
@@ -27,32 +28,28 @@ namespace content {
namespace {
// Returns the implementation of the PlatformNotificationService. May be NULL.
-PlatformNotificationService* Service() {
+PlatformNotificationService* GetNotificationService() {
return GetContentClient()->browser()->GetPlatformNotificationService();
}
} // namespace
+using blink::mojom::PersistentNotificationError;
+
BlinkNotificationServiceImpl::BlinkNotificationServiceImpl(
PlatformNotificationContextImpl* notification_context,
BrowserContext* browser_context,
- ResourceContext* resource_context,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
- int render_process_id,
const url::Origin& origin,
mojo::InterfaceRequest<blink::mojom::NotificationService> request)
: notification_context_(notification_context),
browser_context_(browser_context),
- resource_context_(resource_context),
service_worker_context_(std::move(service_worker_context)),
- render_process_id_(render_process_id),
origin_(origin),
- binding_(this, std::move(request)),
- weak_ptr_factory_(this) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ binding_(this, std::move(request)) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(notification_context_);
DCHECK(browser_context_);
- DCHECK(resource_context_);
binding_.set_connection_error_handler(base::BindOnce(
&BlinkNotificationServiceImpl::OnConnectionError,
@@ -60,23 +57,22 @@ BlinkNotificationServiceImpl::BlinkNotificationServiceImpl(
}
BlinkNotificationServiceImpl::~BlinkNotificationServiceImpl() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
void BlinkNotificationServiceImpl::GetPermissionStatus(
GetPermissionStatusCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!Service()) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!GetNotificationService()) {
std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
return;
}
- blink::mojom::PermissionStatus permission_status = CheckPermissionStatus();
-
- std::move(callback).Run(permission_status);
+ std::move(callback).Run(CheckPermissionStatus());
}
void BlinkNotificationServiceImpl::OnConnectionError() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
notification_context_->RemoveService(this);
// |this| has now been deleted.
}
@@ -86,9 +82,10 @@ void BlinkNotificationServiceImpl::DisplayNonPersistentNotification(
const PlatformNotificationData& platform_notification_data,
const NotificationResources& notification_resources,
blink::mojom::NonPersistentNotificationListenerPtr event_listener_ptr) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!Service())
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!GetNotificationService())
return;
+
if (CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED)
return;
@@ -96,51 +93,31 @@ void BlinkNotificationServiceImpl::DisplayNonPersistentNotification(
notification_context_->notification_id_generator()
->GenerateForNonPersistentNotification(origin_, token);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&BlinkNotificationServiceImpl::
- DisplayNonPersistentNotificationOnUIThread,
- weak_ptr_factory_.GetWeakPtr(), notification_id,
- origin_.GetURL(), platform_notification_data,
- notification_resources,
- event_listener_ptr.PassInterface()));
-}
-
-void BlinkNotificationServiceImpl::DisplayNonPersistentNotificationOnUIThread(
- const std::string& notification_id,
- const GURL& origin,
- const content::PlatformNotificationData& notification_data,
- const content::NotificationResources& notification_resources,
- blink::mojom::NonPersistentNotificationListenerPtrInfo listener_ptr_info) {
NotificationEventDispatcherImpl* event_dispatcher =
NotificationEventDispatcherImpl::GetInstance();
event_dispatcher->RegisterNonPersistentNotificationListener(
- notification_id, std::move(listener_ptr_info));
+ notification_id, std::move(event_listener_ptr));
- Service()->DisplayNotification(browser_context_, notification_id, origin,
- notification_data, notification_resources);
+ GetNotificationService()->DisplayNotification(
+ browser_context_, notification_id, origin_.GetURL(),
+ platform_notification_data, notification_resources);
}
void BlinkNotificationServiceImpl::CloseNonPersistentNotification(
const std::string& token) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!Service())
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!GetNotificationService())
+ return;
+
+ if (CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED)
return;
std::string notification_id =
notification_context_->notification_id_generator()
->GenerateForNonPersistentNotification(origin_, token);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&BlinkNotificationServiceImpl::
- CloseNonPersistentNotificationOnUIThread,
- weak_ptr_factory_.GetWeakPtr(), notification_id));
-}
-
-void BlinkNotificationServiceImpl::CloseNonPersistentNotificationOnUIThread(
- const std::string& notification_id) {
- Service()->CloseNotification(browser_context_, notification_id);
+ GetNotificationService()->CloseNotification(browser_context_,
+ notification_id);
// TODO(https://crbug.com/442141): Pass a callback here to focus the tab
// which created the notification, unless the event is canceled.
@@ -150,8 +127,10 @@ void BlinkNotificationServiceImpl::CloseNonPersistentNotificationOnUIThread(
blink::mojom::PermissionStatus
BlinkNotificationServiceImpl::CheckPermissionStatus() {
- return Service()->CheckPermissionOnIOThread(
- resource_context_, origin_.GetURL(), render_process_id_);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return BrowserContext::GetPermissionController(browser_context_)
+ ->GetPermissionStatus(PermissionType::NOTIFICATIONS, origin_.GetURL(),
+ origin_.GetURL());
}
void BlinkNotificationServiceImpl::DisplayPersistentNotification(
@@ -159,18 +138,39 @@ void BlinkNotificationServiceImpl::DisplayPersistentNotification(
const PlatformNotificationData& platform_notification_data,
const NotificationResources& notification_resources,
DisplayPersistentNotificationCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!Service()) {
- std::move(callback).Run(
- blink::mojom::PersistentNotificationError::INTERNAL_ERROR);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!GetNotificationService()) {
+ std::move(callback).Run(PersistentNotificationError::INTERNAL_ERROR);
return;
}
+
if (CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED) {
- std::move(callback).Run(
- blink::mojom::PersistentNotificationError::PERMISSION_DENIED);
+ std::move(callback).Run(PersistentNotificationError::PERMISSION_DENIED);
return;
}
+ int64_t next_persistent_id =
+ GetNotificationService()->ReadNextPersistentNotificationId(
+ browser_context_);
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&BlinkNotificationServiceImpl::
+ DisplayPersistentNotificationOnIOThread,
+ weak_factory_for_io_.GetWeakPtr(),
+ service_worker_registration_id, next_persistent_id,
+ platform_notification_data, notification_resources,
+ std::move(callback)));
+}
+
+void BlinkNotificationServiceImpl::DisplayPersistentNotificationOnIOThread(
+ int64_t service_worker_registration_id,
+ int64_t next_persistent_notification_id,
+ const PlatformNotificationData& platform_notification_data,
+ const NotificationResources& notification_resources,
+ DisplayPersistentNotificationCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
// TODO(awdf): Necessary to validate resources here?
NotificationDatabaseData database_data;
@@ -179,100 +179,102 @@ void BlinkNotificationServiceImpl::DisplayPersistentNotification(
database_data.notification_data = platform_notification_data;
notification_context_->WriteNotificationData(
- origin_.GetURL(), database_data,
+ next_persistent_notification_id, origin_.GetURL(), database_data,
base::AdaptCallbackForRepeating(base::BindOnce(
- &BlinkNotificationServiceImpl::DisplayPersistentNotificationWithId,
- weak_ptr_factory_.GetWeakPtr(), service_worker_registration_id,
+ &BlinkNotificationServiceImpl::
+ DisplayPersistentNotificationWithIdOnIOThread,
+ weak_factory_for_io_.GetWeakPtr(), service_worker_registration_id,
platform_notification_data, notification_resources,
std::move(callback))));
}
-void BlinkNotificationServiceImpl::DisplayPersistentNotificationWithId(
- int64_t service_worker_registration_id,
- const PlatformNotificationData& platform_notification_data,
- const NotificationResources& notification_resources,
- DisplayPersistentNotificationCallback callback,
- bool success,
- const std::string& notification_id) {
+void BlinkNotificationServiceImpl::
+ DisplayPersistentNotificationWithIdOnIOThread(
+ int64_t service_worker_registration_id,
+ const PlatformNotificationData& platform_notification_data,
+ const NotificationResources& notification_resources,
+ DisplayPersistentNotificationCallback callback,
+ bool success,
+ const std::string& notification_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
if (!success) {
- std::move(callback).Run(
- blink::mojom::PersistentNotificationError::INTERNAL_ERROR);
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(std::move(callback),
+ PersistentNotificationError::INTERNAL_ERROR));
return;
}
service_worker_context_->FindReadyRegistrationForId(
service_worker_registration_id, origin_.GetURL(),
- base::BindOnce(&BlinkNotificationServiceImpl::
- DisplayPersistentNotificationWithIdForServiceWorker,
- weak_ptr_factory_.GetWeakPtr(), notification_id,
- platform_notification_data, notification_resources,
- std::move(callback)));
+ base::BindOnce(
+ &BlinkNotificationServiceImpl::
+ DisplayPersistentNotificationWithServiceWorkerOnIOThread,
+ weak_factory_for_io_.GetWeakPtr(), notification_id,
+ platform_notification_data, notification_resources,
+ std::move(callback)));
}
void BlinkNotificationServiceImpl::
- DisplayPersistentNotificationWithIdForServiceWorker(
+ DisplayPersistentNotificationWithServiceWorkerOnIOThread(
const std::string& notification_id,
const PlatformNotificationData& platform_notification_data,
const NotificationResources& notification_resources,
DisplayPersistentNotificationCallback callback,
- content::ServiceWorkerStatusCode service_worker_status,
- scoped_refptr<content::ServiceWorkerRegistration> registration) {
+ blink::ServiceWorkerStatusCode service_worker_status,
+ scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (service_worker_status != SERVICE_WORKER_OK) {
- std::move(callback).Run(
- blink::mojom::PersistentNotificationError::INTERNAL_ERROR);
- LOG(ERROR) << "Registration not found for " << origin_.GetURL().spec();
- // TODO(peter): Add UMA to track how often this occurs.
- return;
- }
-
- if (registration->pattern().GetOrigin() != origin_.GetURL()) {
- // Bail out, something's wrong.
- std::move(callback).Run(
- blink::mojom::PersistentNotificationError::INTERNAL_ERROR);
- return;
+ PersistentNotificationError error =
+ PersistentNotificationError::INTERNAL_ERROR;
+
+ // Display the notification if the Service Worker's origin matches the origin
+ // of the notification's sender.
+ if (service_worker_status == blink::ServiceWorkerStatusCode::kOk &&
+ registration->pattern().GetOrigin() == origin_.GetURL()) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(
+ &PlatformNotificationService::DisplayPersistentNotification,
+ base::Unretained(GetNotificationService()), browser_context_,
+ notification_id, registration->pattern(), origin_.GetURL(),
+ platform_notification_data, notification_resources));
+
+ error = PersistentNotificationError::NONE;
}
- // Using base::Unretained here is safe because Service() returns a singleton.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(
- &PlatformNotificationService::DisplayPersistentNotification,
- base::Unretained(Service()), browser_context_, notification_id,
- registration->pattern(), origin_.GetURL(), platform_notification_data,
- notification_resources));
-
- std::move(callback).Run(blink::mojom::PersistentNotificationError::NONE);
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::BindOnce(std::move(callback), error));
}
void BlinkNotificationServiceImpl::ClosePersistentNotification(
const std::string& notification_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!GetNotificationService())
+ return;
if (CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED)
return;
- // Using base::Unretained here is safe because Service() returns a singleton.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::BindOnce(&PlatformNotificationService::ClosePersistentNotification,
- base::Unretained(Service()), browser_context_,
- notification_id));
+ GetNotificationService()->ClosePersistentNotification(browser_context_,
+ notification_id);
- notification_context_->DeleteNotificationData(
- notification_id, origin_.GetURL(), base::DoNothing());
+ // Deleting the data associated with |notification_id| from the notification
+ // database has to be done on the IO thread, but there's no reason to postpone
+ // removing the notification from the user's display until that's done.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&PlatformNotificationContextImpl::DeleteNotificationData,
+ notification_context_, notification_id, origin_.GetURL(),
+ base::DoNothing()));
}
void BlinkNotificationServiceImpl::GetNotifications(
int64_t service_worker_registration_id,
const std::string& filter_tag,
GetNotificationsCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- if (CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!GetNotificationService() ||
+ CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED) {
// No permission has been granted for the given origin. It is harmless to
// try to get notifications without permission, so return empty vectors
// indicating that no (accessible) notifications exist at this time.
@@ -281,18 +283,27 @@ void BlinkNotificationServiceImpl::GetNotifications(
return;
}
- notification_context_->ReadAllNotificationDataForServiceWorkerRegistration(
- origin_.GetURL(), service_worker_registration_id,
- base::AdaptCallbackForRepeating(base::BindOnce(
- &BlinkNotificationServiceImpl::DidGetNotifications,
- weak_ptr_factory_.GetWeakPtr(), filter_tag, std::move(callback))));
+ auto read_notification_data_callback = base::BindOnce(
+ &BlinkNotificationServiceImpl::DidGetNotificationsOnIOThread,
+ weak_factory_for_io_.GetWeakPtr(), filter_tag, std::move(callback));
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&PlatformNotificationContextImpl::
+ ReadAllNotificationDataForServiceWorkerRegistration,
+ notification_context_, origin_.GetURL(),
+ service_worker_registration_id,
+ base::AdaptCallbackForRepeating(
+ std::move(read_notification_data_callback))));
}
-void BlinkNotificationServiceImpl::DidGetNotifications(
+void BlinkNotificationServiceImpl::DidGetNotificationsOnIOThread(
const std::string& filter_tag,
GetNotificationsCallback callback,
bool success,
const std::vector<NotificationDatabaseData>& notifications) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
std::vector<std::string> ids;
std::vector<PlatformNotificationData> datas;
@@ -305,7 +316,10 @@ void BlinkNotificationServiceImpl::DidGetNotifications(
}
}
- std::move(callback).Run(ids, datas);
+ // Make sure to invoke the |callback| on the UI thread again.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::BindOnce(std::move(callback), std::move(ids), std::move(datas)));
}
} // namespace content
diff --git a/chromium/content/browser/notifications/blink_notification_service_impl.h b/chromium/content/browser/notifications/blink_notification_service_impl.h
index 1ddd97d69ef..193f5d241c3 100644
--- a/chromium/content/browser/notifications/blink_notification_service_impl.h
+++ b/chromium/content/browser/notifications/blink_notification_service_impl.h
@@ -13,6 +13,7 @@
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom.h"
+#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
#include "url/origin.h"
namespace content {
@@ -20,20 +21,18 @@ namespace content {
struct NotificationDatabaseData;
class PlatformNotificationContextImpl;
struct PlatformNotificationData;
-class ResourceContext;
// Implementation of the NotificationService used for Web Notifications. Is
// responsible for displaying, updating and reading of both non-persistent
-// and persistent notifications. Lives on the IO thread.
+// and persistent notifications. Primarily lives on the UI thread, but jumps to
+// the IO thread when needing to interact with the PlatformNotificationContext.
class CONTENT_EXPORT BlinkNotificationServiceImpl
: public blink::mojom::NotificationService {
public:
BlinkNotificationServiceImpl(
PlatformNotificationContextImpl* notification_context,
BrowserContext* browser_context,
- ResourceContext* resource_context,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
- int render_process_id,
const url::Origin& origin,
mojo::InterfaceRequest<blink::mojom::NotificationService> request);
~BlinkNotificationServiceImpl() override;
@@ -60,14 +59,17 @@ class CONTENT_EXPORT BlinkNotificationServiceImpl
// Called when an error is detected on binding_.
void OnConnectionError();
- void DisplayNonPersistentNotificationOnUIThread(
- const std::string& notification_id,
- const GURL& origin,
- const content::PlatformNotificationData& notification_data,
- const content::NotificationResources& notification_resources,
- blink::mojom::NonPersistentNotificationListenerPtrInfo listener_ptr_info);
+ // Check the permission status for the current |origin_|.
+ blink::mojom::PermissionStatus CheckPermissionStatus();
+
+ void DisplayPersistentNotificationOnIOThread(
+ int64_t service_worker_registration_id,
+ int64_t persistent_notification_id,
+ const PlatformNotificationData& platform_notification_data,
+ const NotificationResources& notification_resources,
+ DisplayPersistentNotificationCallback callback);
- void DisplayPersistentNotificationWithId(
+ void DisplayPersistentNotificationWithIdOnIOThread(
int64_t service_worker_registration_id,
const PlatformNotificationData& platform_notification_data,
const NotificationResources& notification_resources,
@@ -75,20 +77,15 @@ class CONTENT_EXPORT BlinkNotificationServiceImpl
bool success,
const std::string& notification_id);
- void DisplayPersistentNotificationWithIdForServiceWorker(
+ void DisplayPersistentNotificationWithServiceWorkerOnIOThread(
const std::string& notification_id,
const PlatformNotificationData& platform_notification_data,
const NotificationResources& notification_resources,
DisplayPersistentNotificationCallback callback,
- content::ServiceWorkerStatusCode service_worker_status,
- scoped_refptr<content::ServiceWorkerRegistration> registration);
+ blink::ServiceWorkerStatusCode service_worker_status,
+ scoped_refptr<ServiceWorkerRegistration> registration);
- void CloseNonPersistentNotificationOnUIThread(
- const std::string& notification_id);
-
- blink::mojom::PermissionStatus CheckPermissionStatus();
-
- void DidGetNotifications(
+ void DidGetNotificationsOnIOThread(
const std::string& filter_tag,
GetNotificationsCallback callback,
bool success,
@@ -99,18 +96,15 @@ class CONTENT_EXPORT BlinkNotificationServiceImpl
BrowserContext* browser_context_;
- ResourceContext* resource_context_;
-
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
- int render_process_id_;
-
// The origin that this notification service is communicating with.
url::Origin origin_;
mojo::Binding<blink::mojom::NotificationService> binding_;
- base::WeakPtrFactory<BlinkNotificationServiceImpl> weak_ptr_factory_;
+ base::WeakPtrFactory<BlinkNotificationServiceImpl> weak_factory_for_io_{this};
+ base::WeakPtrFactory<BlinkNotificationServiceImpl> weak_factory_for_ui_{this};
DISALLOW_COPY_AND_ASSIGN(BlinkNotificationServiceImpl);
};
diff --git a/chromium/content/browser/notifications/blink_notification_service_impl_unittest.cc b/chromium/content/browser/notifications/blink_notification_service_impl_unittest.cc
index 26622dee5f7..618c7bd88cd 100644
--- a/chromium/content/browser/notifications/blink_notification_service_impl_unittest.cc
+++ b/chromium/content/browser/notifications/blink_notification_service_impl_unittest.cc
@@ -18,7 +18,8 @@
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/test/mock_resource_context.h"
+#include "content/public/browser/permission_type.h"
+#include "content/public/test/mock_permission_manager.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
@@ -26,16 +27,18 @@
#include "content/test/test_content_browser_client.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/notifications/notification_service.mojom.h"
#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
+using ::testing::Return;
+using ::testing::_;
+
namespace content {
namespace {
-const int kFakeRenderProcessId = 1;
-
const char kTestOrigin[] = "https://example.com";
const char kTestServiceWorkerUrl[] = "https://example.com/sw.js";
@@ -53,7 +56,9 @@ class MockNonPersistentNotificationListener
// NonPersistentNotificationListener interface.
void OnShow() override {}
- void OnClick() override {}
+ void OnClick(OnClickCallback completed_closure) override {
+ std::move(completed_closure).Run();
+ }
void OnClose(OnCloseCallback completed_closure) override {
std::move(completed_closure).Run();
}
@@ -107,10 +112,14 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
blink::mojom::NotificationServicePtr notification_service_ptr;
notification_service_ = std::make_unique<BlinkNotificationServiceImpl>(
- notification_context_.get(), &browser_context_, &resource_context_,
- embedded_worker_helper_->context_wrapper(), kFakeRenderProcessId,
+ notification_context_.get(), &browser_context_,
+ embedded_worker_helper_->context_wrapper(),
url::Origin::Create(GURL(kTestOrigin)),
mojo::MakeRequest(&notification_service_ptr));
+
+ // Provide a mock permission manager to the |browser_context_|.
+ browser_context_.SetPermissionControllerDelegate(
+ std::make_unique<testing::NiceMock<MockPermissionManager>>());
}
void TearDown() override {
@@ -132,10 +141,10 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
base::RunLoop run_loop;
embedded_worker_helper_->context()->RegisterServiceWorker(
GURL(kTestServiceWorkerUrl), options,
- base::AdaptCallbackForRepeating(base::BindOnce(
+ base::BindOnce(
&BlinkNotificationServiceImplTest::DidRegisterServiceWorker,
base::Unretained(this), &service_worker_registration_id,
- run_loop.QuitClosure())));
+ run_loop.QuitClosure()));
run_loop.Run();
}
@@ -166,11 +175,12 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
void DidRegisterServiceWorker(int64_t* out_service_worker_registration_id,
base::OnceClosure quit_closure,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t service_worker_registration_id) {
DCHECK(out_service_worker_registration_id);
- EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
+ << blink::ServiceWorkerStatusToString(status);
*out_service_worker_registration_id = service_worker_registration_id;
@@ -180,10 +190,11 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
void DidFindServiceWorkerRegistration(
scoped_refptr<ServiceWorkerRegistration>* out_service_worker_registration,
base::OnceClosure quit_closure,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
DCHECK(out_service_worker_registration);
- EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
+ << blink::ServiceWorkerStatusToString(status);
*out_service_worker_registration = service_worker_registration;
@@ -191,8 +202,10 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
}
void DidGetPermissionStatus(
+ base::OnceClosure quit_closure,
blink::mojom::PermissionStatus permission_status) {
permission_callback_result_ = permission_status;
+ std::move(quit_closure).Run();
}
blink::mojom::PermissionStatus GetPermissionCallbackResult() {
@@ -272,8 +285,9 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
// PlatformNotificationContext::ReadNotificationData
bool ReadNotificationData(const std::string& notification_id) {
base::RunLoop run_loop;
- notification_context_->ReadNotificationData(
+ notification_context_->ReadNotificationDataAndRecordInteraction(
notification_id, GURL(kTestOrigin),
+ PlatformNotificationContext::Interaction::NONE,
base::AdaptCallbackForRepeating(base::BindOnce(
&BlinkNotificationServiceImplTest::DidReadNotificationData,
base::Unretained(this), run_loop.QuitClosure())));
@@ -281,6 +295,18 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
return read_notification_data_callback_result_;
}
+ // Updates the permission status for the |kTestOrigin| to the given
+ // |permission_status| through the PermissionManager.
+ void SetPermissionStatus(blink::mojom::PermissionStatus permission_status) {
+ MockPermissionManager* mock_permission_manager =
+ static_cast<MockPermissionManager*>(
+ browser_context_.GetPermissionControllerDelegate());
+
+ ON_CALL(*mock_permission_manager,
+ GetPermissionStatus(PermissionType::NOTIFICATIONS, _, _))
+ .WillByDefault(Return(permission_status));
+ }
+
protected:
TestBrowserThreadBundle thread_bundle_; // Must be first member.
@@ -310,41 +336,52 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
bool read_notification_data_callback_result_ = false;
- MockResourceContext resource_context_;
-
DISALLOW_COPY_AND_ASSIGN(BlinkNotificationServiceImplTest);
};
TEST_F(BlinkNotificationServiceImplTest, GetPermissionStatus) {
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::GRANTED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
- notification_service_->GetPermissionStatus(
- base::BindOnce(&BlinkNotificationServiceImplTest::DidGetPermissionStatus,
- base::Unretained(this)));
+ {
+ base::RunLoop run_loop;
+ notification_service_->GetPermissionStatus(base::BindOnce(
+ &BlinkNotificationServiceImplTest::DidGetPermissionStatus,
+ base::Unretained(this), run_loop.QuitClosure()));
+ run_loop.Run();
+ }
EXPECT_EQ(blink::mojom::PermissionStatus::GRANTED,
GetPermissionCallbackResult());
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::DENIED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::DENIED);
- notification_service_->GetPermissionStatus(
- base::BindOnce(&BlinkNotificationServiceImplTest::DidGetPermissionStatus,
- base::Unretained(this)));
+ {
+ base::RunLoop run_loop;
+ notification_service_->GetPermissionStatus(base::BindOnce(
+ &BlinkNotificationServiceImplTest::DidGetPermissionStatus,
+ base::Unretained(this), run_loop.QuitClosure()));
+ run_loop.Run();
+ }
EXPECT_EQ(blink::mojom::PermissionStatus::DENIED,
GetPermissionCallbackResult());
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::ASK);
- notification_service_->GetPermissionStatus(
- base::BindOnce(&BlinkNotificationServiceImplTest::DidGetPermissionStatus,
- base::Unretained(this)));
+ SetPermissionStatus(blink::mojom::PermissionStatus::ASK);
+
+ {
+ base::RunLoop run_loop;
+ notification_service_->GetPermissionStatus(base::BindOnce(
+ &BlinkNotificationServiceImplTest::DidGetPermissionStatus,
+ base::Unretained(this), run_loop.QuitClosure()));
+ run_loop.Run();
+ }
EXPECT_EQ(blink::mojom::PermissionStatus::ASK, GetPermissionCallbackResult());
}
TEST_F(BlinkNotificationServiceImplTest,
DisplayNonPersistentNotificationWithPermission) {
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::GRANTED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
notification_service_->DisplayNonPersistentNotification(
"token", PlatformNotificationData(), NotificationResources(),
@@ -361,7 +398,7 @@ TEST_F(BlinkNotificationServiceImplTest,
TEST_F(BlinkNotificationServiceImplTest,
DisplayNonPersistentNotificationWithoutPermission) {
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::DENIED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::DENIED);
notification_service_->DisplayNonPersistentNotification(
"token", PlatformNotificationData(), NotificationResources(),
@@ -378,7 +415,7 @@ TEST_F(BlinkNotificationServiceImplTest,
TEST_F(BlinkNotificationServiceImplTest,
DisplayPersistentNotificationWithPermission) {
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::GRANTED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
@@ -396,7 +433,7 @@ TEST_F(BlinkNotificationServiceImplTest,
}
TEST_F(BlinkNotificationServiceImplTest, CloseDisplayedPersistentNotification) {
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::GRANTED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
@@ -423,7 +460,7 @@ TEST_F(BlinkNotificationServiceImplTest, CloseDisplayedPersistentNotification) {
TEST_F(BlinkNotificationServiceImplTest,
ClosePersistentNotificationDeletesFromDatabase) {
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::GRANTED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
@@ -456,7 +493,7 @@ TEST_F(BlinkNotificationServiceImplTest,
TEST_F(BlinkNotificationServiceImplTest,
DisplayPersistentNotificationWithoutPermission) {
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::DENIED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::DENIED);
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
@@ -475,7 +512,7 @@ TEST_F(BlinkNotificationServiceImplTest,
TEST_F(BlinkNotificationServiceImplTest,
DisplayMultiplePersistentNotifications) {
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::GRANTED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
@@ -493,7 +530,7 @@ TEST_F(BlinkNotificationServiceImplTest,
}
TEST_F(BlinkNotificationServiceImplTest, GetNotifications) {
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::GRANTED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
@@ -512,7 +549,7 @@ TEST_F(BlinkNotificationServiceImplTest, GetNotifications) {
}
TEST_F(BlinkNotificationServiceImplTest, GetNotificationsWithoutPermission) {
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::GRANTED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
@@ -523,14 +560,14 @@ TEST_F(BlinkNotificationServiceImplTest, GetNotificationsWithoutPermission) {
// Wait for service to receive all the Display calls.
RunAllTasksUntilIdle();
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::DENIED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::DENIED);
EXPECT_EQ(
0u, GetNotificationsSync(registration->id(), "" /* filter_tag */).size());
}
TEST_F(BlinkNotificationServiceImplTest, GetNotificationsWithFilter) {
- mock_platform_service_.SetPermission(blink::mojom::PermissionStatus::GRANTED);
+ SetPermissionStatus(blink::mojom::PermissionStatus::GRANTED);
scoped_refptr<ServiceWorkerRegistration> registration;
RegisterServiceWorker(&registration);
diff --git a/chromium/content/browser/notifications/notification_database.cc b/chromium/content/browser/notifications/notification_database.cc
index 87dca497209..28ff2f47881 100644
--- a/chromium/content/browser/notifications/notification_database.cc
+++ b/chromium/content/browser/notifications/notification_database.cc
@@ -7,6 +7,7 @@
#include <string>
#include "base/files/file_util.h"
+#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "content/browser/notifications/notification_database_data_conversions.h"
@@ -37,15 +38,11 @@ namespace content {
namespace {
// Keys of the fields defined in the database.
-const char kNextNotificationIdKey[] = "NEXT_NOTIFICATION_ID";
const char kDataKeyPrefix[] = "DATA:";
// Separates the components of compound keys.
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 LevelDBStatusToNotificationDatabaseStatus(
const leveldb::Status& status) {
@@ -99,6 +96,15 @@ NotificationDatabase::Status DeserializedNotificationData(
return NotificationDatabase::STATUS_ERROR_CORRUPTED;
}
+// Updates the time of the last click on the notification, and the first if
+// necessary.
+void UpdateNotificationClickTimestamps(NotificationDatabaseData* data) {
+ base::TimeDelta delta = base::Time::Now() - data->creation_time_millis;
+ if (!data->time_until_first_click_millis.has_value())
+ data->time_until_first_click_millis = delta;
+ data->time_until_last_click_millis = delta;
+}
+
} // namespace
NotificationDatabase::NotificationDatabase(const base::FilePath& path)
@@ -111,7 +117,7 @@ NotificationDatabase::~NotificationDatabase() {
NotificationDatabase::Status NotificationDatabase::Open(
bool create_if_missing) {
DCHECK(sequence_checker_.CalledOnValidSequence());
- DCHECK_EQ(STATE_UNINITIALIZED, state_);
+ DCHECK_EQ(State::UNINITIALIZED, state_);
if (!create_if_missing) {
if (IsInMemoryDatabase() || !base::PathExists(path_) ||
@@ -134,16 +140,10 @@ NotificationDatabase::Status NotificationDatabase::Open(
Status status = LevelDBStatusToNotificationDatabaseStatus(
leveldb_env::OpenDB(options, path_.AsUTF8Unsafe(), &db_));
- if (status != STATUS_OK)
- return status;
-
- state_ = STATE_INITIALIZED;
+ if (status == STATUS_OK)
+ state_ = State::INITIALIZED;
- return ReadNextPersistentNotificationId();
-}
-
-int64_t NotificationDatabase::GetNextPersistentNotificationId() {
- return next_persistent_notification_id_++;
+ return status;
}
NotificationDatabase::Status NotificationDatabase::ReadNotificationData(
@@ -151,7 +151,7 @@ NotificationDatabase::Status NotificationDatabase::ReadNotificationData(
const GURL& origin,
NotificationDatabaseData* notification_database_data) const {
DCHECK(sequence_checker_.CalledOnValidSequence());
- DCHECK_EQ(STATE_INITIALIZED, state_);
+ DCHECK_EQ(State::INITIALIZED, state_);
DCHECK(!notification_id.empty());
DCHECK(origin.is_valid());
DCHECK(notification_database_data);
@@ -168,6 +168,43 @@ NotificationDatabase::Status NotificationDatabase::ReadNotificationData(
notification_database_data);
}
+NotificationDatabase::Status
+NotificationDatabase::ReadNotificationDataAndRecordInteraction(
+ const std::string& notification_id,
+ const GURL& origin,
+ PlatformNotificationContext::Interaction interaction,
+ NotificationDatabaseData* notification_database_data) {
+ Status status =
+ ReadNotificationData(notification_id, origin, notification_database_data);
+ if (status != STATUS_OK)
+ return status;
+
+ // Update the appropriate fields for UKM logging purposes.
+ switch (interaction) {
+ case PlatformNotificationContext::Interaction::CLOSED:
+ notification_database_data->time_until_close_millis =
+ base::Time::Now() - notification_database_data->creation_time_millis;
+ break;
+ case PlatformNotificationContext::Interaction::NONE:
+ return status;
+ case PlatformNotificationContext::Interaction::ACTION_BUTTON_CLICKED:
+ notification_database_data->num_action_button_clicks += 1;
+ UpdateNotificationClickTimestamps(notification_database_data);
+ break;
+ case PlatformNotificationContext::Interaction::CLICKED:
+ notification_database_data->num_clicks += 1;
+ UpdateNotificationClickTimestamps(notification_database_data);
+ break;
+ }
+
+ // Write the changed values to the database.
+ status = WriteNotificationData(origin, *notification_database_data);
+ UMA_HISTOGRAM_ENUMERATION(
+ "Notifications.Database.ReadResultRecordInteraction", status,
+ NotificationDatabase::STATUS_COUNT);
+ return status;
+}
+
NotificationDatabase::Status NotificationDatabase::ReadAllNotificationData(
std::vector<NotificationDatabaseData>* notification_data_vector) const {
return ReadAllNotificationDataInternal(
@@ -197,7 +234,7 @@ NotificationDatabase::Status NotificationDatabase::WriteNotificationData(
const GURL& origin,
const NotificationDatabaseData& notification_data) {
DCHECK(sequence_checker_.CalledOnValidSequence());
- DCHECK_EQ(STATE_INITIALIZED, state_);
+ DCHECK_EQ(State::INITIALIZED, state_);
DCHECK(origin.is_valid());
const std::string& notification_id = notification_data.notification_id;
@@ -213,12 +250,6 @@ NotificationDatabase::Status NotificationDatabase::WriteNotificationData(
leveldb::WriteBatch batch;
batch.Put(CreateDataKey(origin, notification_id), serialized_data);
- if (written_persistent_notification_id_ != next_persistent_notification_id_) {
- written_persistent_notification_id_ = next_persistent_notification_id_;
- batch.Put(kNextNotificationIdKey,
- base::Int64ToString(next_persistent_notification_id_));
- }
-
return LevelDBStatusToNotificationDatabaseStatus(
db_->Write(leveldb::WriteOptions(), &batch));
}
@@ -227,7 +258,7 @@ NotificationDatabase::Status NotificationDatabase::DeleteNotificationData(
const std::string& notification_id,
const GURL& origin) {
DCHECK(sequence_checker_.CalledOnValidSequence());
- DCHECK_EQ(STATE_INITIALIZED, state_);
+ DCHECK_EQ(State::INITIALIZED, state_);
DCHECK(!notification_id.empty());
DCHECK(origin.is_valid());
@@ -267,7 +298,7 @@ NotificationDatabase::Status NotificationDatabase::Destroy() {
options.env = env_.get();
}
- state_ = STATE_DISABLED;
+ state_ = State::DISABLED;
db_.reset();
return LevelDBStatusToNotificationDatabaseStatus(
@@ -275,31 +306,6 @@ NotificationDatabase::Status NotificationDatabase::Destroy() {
}
NotificationDatabase::Status
-NotificationDatabase::ReadNextPersistentNotificationId() {
- std::string value;
- Status status = LevelDBStatusToNotificationDatabaseStatus(
- db_->Get(leveldb::ReadOptions(), kNextNotificationIdKey, &value));
-
- if (status == STATUS_ERROR_NOT_FOUND) {
- next_persistent_notification_id_ = kFirstPersistentNotificationId;
- written_persistent_notification_id_ = kFirstPersistentNotificationId;
- return STATUS_OK;
- }
-
- if (status != STATUS_OK)
- return status;
-
- if (!base::StringToInt64(value, &next_persistent_notification_id_) ||
- next_persistent_notification_id_ < kFirstPersistentNotificationId) {
- return STATUS_ERROR_CORRUPTED;
- }
-
- written_persistent_notification_id_ = next_persistent_notification_id_;
-
- return STATUS_OK;
-}
-
-NotificationDatabase::Status
NotificationDatabase::ReadAllNotificationDataInternal(
const GURL& origin,
int64_t service_worker_registration_id,
@@ -377,11 +383,7 @@ NotificationDatabase::DeleteAllNotificationDataInternal(
batch.Delete(iter->key());
- // Silently remove the notification if it doesn't have an ID assigned.
- // TODO(peter): Remove this clause when Chrome 55 has branched.
- if (notification_database_data.notification_id.empty())
- continue;
-
+ DCHECK(!notification_database_data.notification_id.empty());
deleted_notification_ids->insert(
notification_database_data.notification_id);
}
diff --git a/chromium/content/browser/notifications/notification_database.h b/chromium/content/browser/notifications/notification_database.h
index e85594f0ee6..5237a8e323c 100644
--- a/chromium/content/browser/notifications/notification_database.h
+++ b/chromium/content/browser/notifications/notification_database.h
@@ -14,6 +14,7 @@
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/sequence_checker.h"
+#include "content/browser/notifications/platform_notification_context_impl.h"
#include "content/common/content_export.h"
class GURL;
@@ -90,6 +91,15 @@ class CONTENT_EXPORT NotificationDatabase {
const GURL& origin,
NotificationDatabaseData* notification_data) const;
+ // This function is identical to ReadNotificationData above, but also records
+ // an interaction with that notification in the database for UKM logging
+ // purposes.
+ Status ReadNotificationDataAndRecordInteraction(
+ const std::string& notification_id,
+ const GURL& origin,
+ PlatformNotificationContext::Interaction interaction,
+ NotificationDatabaseData* notification_data);
+
// Reads all notification data for all origins from the database, and appends
// the data to |notification_data_vector|. Returns the status code.
Status ReadAllNotificationData(
@@ -147,12 +157,10 @@ class CONTENT_EXPORT NotificationDatabase {
private:
friend class NotificationDatabaseTest;
- // TODO(peter): Convert to an enum class when DCHECK_EQ supports this.
- // See https://crbug.com/463869.
- enum State {
- STATE_UNINITIALIZED,
- STATE_INITIALIZED,
- STATE_DISABLED,
+ enum class State {
+ UNINITIALIZED,
+ INITIALIZED,
+ DISABLED,
};
// Reads the next available persistent notification id from the database and
@@ -193,9 +201,6 @@ class CONTENT_EXPORT NotificationDatabase {
base::FilePath path_;
- int64_t next_persistent_notification_id_ = 0;
- int64_t written_persistent_notification_id_ = 0;
-
std::unique_ptr<const leveldb::FilterPolicy> filter_policy_;
// The declaration order for these members matters, as |db_| depends on |env_|
@@ -203,7 +208,7 @@ class CONTENT_EXPORT NotificationDatabase {
std::unique_ptr<leveldb::Env> env_;
std::unique_ptr<leveldb::DB> db_;
- State state_ = STATE_UNINITIALIZED;
+ State state_ = State::UNINITIALIZED;
base::SequenceChecker sequence_checker_;
diff --git a/chromium/content/browser/notifications/notification_database_data_conversions.cc b/chromium/content/browser/notifications/notification_database_data_conversions.cc
index 557692ae53e..656108caa62 100644
--- a/chromium/content/browser/notifications/notification_database_data_conversions.cc
+++ b/chromium/content/browser/notifications/notification_database_data_conversions.cc
@@ -83,6 +83,8 @@ bool DeserializeNotificationDatabaseData(const std::string& input,
if (payload.vibration_pattern().size() > 0) {
notification_data->vibration_pattern.assign(
payload.vibration_pattern().begin(), payload.vibration_pattern().end());
+ } else {
+ notification_data->vibration_pattern.clear();
}
notification_data->timestamp =
@@ -94,8 +96,12 @@ bool DeserializeNotificationDatabaseData(const std::string& input,
if (payload.data().length()) {
notification_data->data.assign(payload.data().begin(),
payload.data().end());
+ } else {
+ notification_data->data.clear();
}
+ notification_data->actions.clear();
+
for (const auto& payload_action : payload.actions()) {
PlatformNotificationAction action;
@@ -208,12 +214,18 @@ bool SerializeNotificationDatabaseData(const NotificationDatabaseData& input,
message.set_num_action_button_clicks(input.num_action_button_clicks);
message.set_creation_time_millis(
input.creation_time_millis.ToDeltaSinceWindowsEpoch().InMicroseconds());
- message.set_time_until_first_click_millis(
- input.time_until_first_click_millis.InMilliseconds());
- message.set_time_until_last_click_millis(
- input.time_until_last_click_millis.InMilliseconds());
- message.set_time_until_close_millis(
- input.time_until_close_millis.InMilliseconds());
+ if (input.time_until_first_click_millis.has_value()) {
+ message.set_time_until_first_click_millis(
+ input.time_until_first_click_millis.value().InMilliseconds());
+ }
+ if (input.time_until_last_click_millis.has_value()) {
+ message.set_time_until_last_click_millis(
+ input.time_until_last_click_millis.value().InMilliseconds());
+ }
+ if (input.time_until_close_millis.has_value()) {
+ message.set_time_until_close_millis(
+ input.time_until_close_millis.value().InMilliseconds());
+ }
switch (input.closed_reason) {
case NotificationDatabaseData::ClosedReason::USER:
diff --git a/chromium/content/browser/notifications/notification_database_data_unittest.cc b/chromium/content/browser/notifications/notification_database_data_unittest.cc
index 6436f409c4e..9de61d52c50 100644
--- a/chromium/content/browser/notifications/notification_database_data_unittest.cc
+++ b/chromium/content/browser/notifications/notification_database_data_unittest.cc
@@ -170,6 +170,34 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeData) {
}
}
+TEST(NotificationDatabaseDataTest, ActionDeserializationIsNotAdditive) {
+ NotificationDatabaseData database_data;
+
+ for (size_t i = 0; i < blink::kWebNotificationMaxActions; ++i)
+ database_data.notification_data.actions.emplace_back();
+
+ std::string serialized_data;
+ NotificationDatabaseData copied_database_data;
+
+ // Serialize the data in |notification_data| to the string |serialized_data|,
+ // and then deserialize it again immediately to |copied_database_data|.
+ ASSERT_TRUE(
+ SerializeNotificationDatabaseData(database_data, &serialized_data));
+ ASSERT_TRUE(DeserializeNotificationDatabaseData(serialized_data,
+ &copied_database_data));
+
+ EXPECT_EQ(copied_database_data.notification_data.actions.size(),
+ blink::kWebNotificationMaxActions);
+
+ // Deserialize it again in the same |copied_database_data|. The number of
+ // actions in the structure should not be affected.
+ ASSERT_TRUE(DeserializeNotificationDatabaseData(serialized_data,
+ &copied_database_data));
+
+ EXPECT_EQ(copied_database_data.notification_data.actions.size(),
+ blink::kWebNotificationMaxActions);
+}
+
TEST(NotificationDatabaseDataTest, SerializeAndDeserializeActionTypes) {
PlatformNotificationActionType action_types[] = {
PLATFORM_NOTIFICATION_ACTION_TYPE_BUTTON,
@@ -222,7 +250,7 @@ TEST(NotificationDatabaseDataTest, SerializeAndDeserializeDirections) {
}
}
-TEST(NotificationDatabaseDataTest, SerializeAndDeserializeclosed_reasons) {
+TEST(NotificationDatabaseDataTest, SerializeAndDeserializeClosedReasons) {
NotificationDatabaseData::ClosedReason closed_reasons[] = {
NotificationDatabaseData::ClosedReason::USER,
NotificationDatabaseData::ClosedReason::DEVELOPER,
diff --git a/chromium/content/browser/notifications/notification_database_unittest.cc b/chromium/content/browser/notifications/notification_database_unittest.cc
index b1eca237f6c..f6fdef1f358 100644
--- a/chromium/content/browser/notifications/notification_database_unittest.cc
+++ b/chromium/content/browser/notifications/notification_database_unittest.cc
@@ -188,10 +188,6 @@ TEST_F(NotificationDatabaseTest, NotificationIdIncrements) {
ASSERT_EQ(NotificationDatabase::STATUS_OK,
database->Open(true /* create_if_missing */));
- EXPECT_EQ(database->GetNextPersistentNotificationId(), 1);
- EXPECT_EQ(database->GetNextPersistentNotificationId(), 2);
- EXPECT_EQ(database->GetNextPersistentNotificationId(), 3);
-
GURL origin("https://example.com");
std::string notification_id;
@@ -202,10 +198,6 @@ TEST_F(NotificationDatabaseTest, NotificationIdIncrements) {
database.reset(CreateDatabaseOnFileSystem(database_dir.GetPath()));
ASSERT_EQ(NotificationDatabase::STATUS_OK,
database->Open(false /* create_if_missing */));
-
- // Verify that the next persistent notification id was stored in the database,
- // and continues where we expect it to be, even after closing and opening it.
- EXPECT_EQ(database->GetNextPersistentNotificationId(), 4);
}
TEST_F(NotificationDatabaseTest, NotificationIdIncrementsStorage) {
@@ -228,35 +220,6 @@ TEST_F(NotificationDatabaseTest, NotificationIdIncrementsStorage) {
EXPECT_EQ(database_data.notification_id, read_database_data.notification_id);
}
-TEST_F(NotificationDatabaseTest, NotificationIdCorruption) {
- base::ScopedTempDir database_dir;
- ASSERT_TRUE(database_dir.CreateUniqueTempDir());
-
- std::unique_ptr<NotificationDatabase> database(
- CreateDatabaseOnFileSystem(database_dir.GetPath()));
-
- ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->Open(true /* create_if_missing */));
-
- GURL origin("https://example.com");
-
- NotificationDatabaseData database_data;
- database_data.notification_id = GenerateNotificationId();
-
- ASSERT_EQ(NotificationDatabase::STATUS_OK,
- database->WriteNotificationData(origin, database_data));
-
- // Deliberately write an invalid value as the next notification id. When
- // re-opening the database, the Open() method should realize that an invalid
- // value is being read, and mark the database as corrupted.
- ASSERT_NO_FATAL_FAILURE(
- WriteLevelDBKeyValuePair(database.get(), "NEXT_NOTIFICATION_ID", "-42"));
-
- database.reset(CreateDatabaseOnFileSystem(database_dir.GetPath()));
- EXPECT_EQ(NotificationDatabase::STATUS_ERROR_CORRUPTED,
- database->Open(false /* create_if_missing */));
-}
-
TEST_F(NotificationDatabaseTest, ReadInvalidNotificationData) {
std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
ASSERT_EQ(NotificationDatabase::STATUS_OK,
@@ -394,6 +357,63 @@ TEST_F(NotificationDatabaseTest, ReadWriteMultipleNotificationData) {
}
}
+TEST_F(NotificationDatabaseTest, ReadNotificationUpdateInteraction) {
+ std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
+ ASSERT_EQ(NotificationDatabase::STATUS_OK,
+ database->Open(true /* create_if_missing */));
+
+ GURL origin("https://example.com");
+
+ NotificationDatabaseData database_data, read_database_data;
+ database_data.notification_id = GenerateNotificationId();
+ database_data.notification_data.title = base::UTF8ToUTF16("My Notification");
+
+ ASSERT_EQ(NotificationDatabase::STATUS_OK,
+ database->WriteNotificationData(origin, database_data));
+
+ // Check that the time deltas have not yet been set.
+ EXPECT_EQ(false,
+ read_database_data.time_until_first_click_millis.has_value());
+ EXPECT_EQ(false, read_database_data.time_until_last_click_millis.has_value());
+ EXPECT_EQ(false, read_database_data.time_until_close_millis.has_value());
+
+ // Check that when a notification has an interaction, the appropriate field is
+ // updated on the read.
+ ASSERT_EQ(NotificationDatabase::STATUS_OK,
+ database->ReadNotificationDataAndRecordInteraction(
+ database_data.notification_id, origin,
+ PlatformNotificationContext::Interaction::CLICKED,
+ &read_database_data));
+ EXPECT_EQ(1, read_database_data.num_clicks);
+
+ ASSERT_EQ(NotificationDatabase::STATUS_OK,
+ database->ReadNotificationDataAndRecordInteraction(
+ database_data.notification_id, origin,
+ PlatformNotificationContext::Interaction::ACTION_BUTTON_CLICKED,
+ &read_database_data));
+ EXPECT_EQ(1, read_database_data.num_action_button_clicks);
+
+ ASSERT_EQ(NotificationDatabase::STATUS_OK,
+ database->ReadNotificationDataAndRecordInteraction(
+ database_data.notification_id, origin,
+ PlatformNotificationContext::Interaction::ACTION_BUTTON_CLICKED,
+ &read_database_data));
+ EXPECT_EQ(2, read_database_data.num_action_button_clicks);
+
+ // Check that the click timestamps are correctly updated.
+ EXPECT_EQ(true, read_database_data.time_until_first_click_millis.has_value());
+ EXPECT_EQ(true, read_database_data.time_until_last_click_millis.has_value());
+
+ // Check that when a read with a CLOSED interaction occurs, the correct
+ // field is updated.
+ ASSERT_EQ(NotificationDatabase::STATUS_OK,
+ database->ReadNotificationDataAndRecordInteraction(
+ database_data.notification_id, origin,
+ PlatformNotificationContext::Interaction::CLOSED,
+ &read_database_data));
+ EXPECT_EQ(true, read_database_data.time_until_close_millis.has_value());
+}
+
TEST_F(NotificationDatabaseTest, DeleteInvalidNotificationData) {
std::unique_ptr<NotificationDatabase> database(CreateDatabaseInMemory());
ASSERT_EQ(NotificationDatabase::STATUS_OK,
diff --git a/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc b/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
index 1f00936370a..879ab76c96d 100644
--- a/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
+++ b/chromium/content/browser/notifications/notification_event_dispatcher_impl.cc
@@ -13,7 +13,7 @@
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_storage.h"
-#include "content/common/platform_notification_messages.h"
+#include "content/common/platform_notification_param_traits.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
@@ -45,44 +45,44 @@ void NotificationEventFinished(
}
// To be called when a notification event has finished with a
-// ServiceWorkerStatusCode result. Will call NotificationEventFinished with a
-// PersistentNotificationStatus derived from the service worker status.
+// blink::ServiceWorkerStatusCode result. Will call NotificationEventFinished
+// with a PersistentNotificationStatus derived from the service worker status.
void ServiceWorkerNotificationEventFinished(
const NotificationDispatchCompleteCallback& dispatch_complete_callback,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
#if defined(OS_ANDROID)
// This LOG(INFO) deliberately exists to help track down the cause of
// https://crbug.com/534537, where notifications sometimes do not react to
// the user clicking on them. It should be removed once that's fixed.
- LOG(INFO) << "The notification event has finished: " << service_worker_status;
+ LOG(INFO) << "The notification event has finished: "
+ << blink::ServiceWorkerStatusToString(service_worker_status);
#endif
PersistentNotificationStatus status = PERSISTENT_NOTIFICATION_STATUS_SUCCESS;
switch (service_worker_status) {
- case SERVICE_WORKER_OK:
+ case blink::ServiceWorkerStatusCode::kOk:
// Success status was initialized above.
break;
- case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
+ case blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected:
status = PERSISTENT_NOTIFICATION_STATUS_EVENT_WAITUNTIL_REJECTED;
break;
- case SERVICE_WORKER_ERROR_FAILED:
- case SERVICE_WORKER_ERROR_ABORT:
- case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
- case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
- case SERVICE_WORKER_ERROR_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_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:
+ case blink::ServiceWorkerStatusCode::kErrorFailed:
+ case blink::ServiceWorkerStatusCode::kErrorAbort:
+ case blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorProcessNotFound:
+ case blink::ServiceWorkerStatusCode::kErrorNotFound:
+ case blink::ServiceWorkerStatusCode::kErrorExists:
+ case blink::ServiceWorkerStatusCode::kErrorInstallWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorActivateWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorIpcFailed:
+ case blink::ServiceWorkerStatusCode::kErrorNetwork:
+ case blink::ServiceWorkerStatusCode::kErrorSecurity:
+ case blink::ServiceWorkerStatusCode::kErrorState:
+ case blink::ServiceWorkerStatusCode::kErrorTimeout:
+ case blink::ServiceWorkerStatusCode::kErrorScriptEvaluateFailed:
+ case blink::ServiceWorkerStatusCode::kErrorDiskCache:
+ case blink::ServiceWorkerStatusCode::kErrorRedundant:
+ case blink::ServiceWorkerStatusCode::kErrorDisallowed:
status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR;
break;
}
@@ -97,7 +97,7 @@ void DispatchNotificationEventOnRegistration(
const scoped_refptr<PlatformNotificationContext>& notification_context,
const NotificationOperationCallback& dispatch_event_action,
const NotificationDispatchCompleteCallback& dispatch_error_callback,
- ServiceWorkerStatusCode service_worker_status,
+ blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
#if defined(OS_ANDROID)
@@ -105,9 +105,9 @@ void DispatchNotificationEventOnRegistration(
// https://crbug.com/534537, where notifications sometimes do not react to
// the user clicking on them. It should be removed once that's fixed.
LOG(INFO) << "Trying to dispatch notification for SW with status: "
- << service_worker_status;
+ << blink::ServiceWorkerStatusToString(service_worker_status);
#endif
- if (service_worker_status == SERVICE_WORKER_OK) {
+ if (service_worker_status == blink::ServiceWorkerStatusCode::kOk) {
DCHECK(service_worker_registration->active_version());
dispatch_event_action.Run(service_worker_registration.get(),
@@ -117,30 +117,29 @@ void DispatchNotificationEventOnRegistration(
PersistentNotificationStatus status = PERSISTENT_NOTIFICATION_STATUS_SUCCESS;
switch (service_worker_status) {
- case SERVICE_WORKER_ERROR_NOT_FOUND:
+ case blink::ServiceWorkerStatusCode::kErrorNotFound:
status = PERSISTENT_NOTIFICATION_STATUS_NO_SERVICE_WORKER;
break;
- case SERVICE_WORKER_ERROR_FAILED:
- case SERVICE_WORKER_ERROR_ABORT:
- 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:
+ case blink::ServiceWorkerStatusCode::kErrorFailed:
+ case blink::ServiceWorkerStatusCode::kErrorAbort:
+ case blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorProcessNotFound:
+ case blink::ServiceWorkerStatusCode::kErrorExists:
+ case blink::ServiceWorkerStatusCode::kErrorInstallWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorActivateWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorIpcFailed:
+ case blink::ServiceWorkerStatusCode::kErrorNetwork:
+ case blink::ServiceWorkerStatusCode::kErrorSecurity:
+ case blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected:
+ case blink::ServiceWorkerStatusCode::kErrorState:
+ case blink::ServiceWorkerStatusCode::kErrorTimeout:
+ case blink::ServiceWorkerStatusCode::kErrorScriptEvaluateFailed:
+ case blink::ServiceWorkerStatusCode::kErrorDiskCache:
+ case blink::ServiceWorkerStatusCode::kErrorRedundant:
+ case blink::ServiceWorkerStatusCode::kErrorDisallowed:
status = PERSISTENT_NOTIFICATION_STATUS_SERVICE_WORKER_ERROR;
break;
- case SERVICE_WORKER_OK:
+ case blink::ServiceWorkerStatusCode::kOk:
NOTREACHED();
break;
}
@@ -187,13 +186,14 @@ void FindServiceWorkerRegistration(
void ReadNotificationDatabaseData(
const std::string& notification_id,
const GURL& origin,
+ PlatformNotificationContext::Interaction interaction,
const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context,
const scoped_refptr<PlatformNotificationContext>& notification_context,
const NotificationOperationCallback& notification_read_callback,
const NotificationDispatchCompleteCallback& dispatch_error_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- notification_context->ReadNotificationData(
- notification_id, origin,
+ notification_context->ReadNotificationDataAndRecordInteraction(
+ notification_id, origin, interaction,
base::Bind(&FindServiceWorkerRegistration, origin, service_worker_context,
notification_context, notification_read_callback,
dispatch_error_callback));
@@ -209,9 +209,9 @@ void DispatchNotificationClickEventOnWorker(
const base::Optional<int>& action_index,
const base::Optional<base::string16>& reply,
ServiceWorkerVersion::StatusCallback callback,
- ServiceWorkerStatusCode start_worker_status) {
+ blink::ServiceWorkerStatusCode start_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (start_worker_status != SERVICE_WORKER_OK) {
+ if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(start_worker_status);
return;
}
@@ -223,7 +223,7 @@ void DispatchNotificationClickEventOnWorker(
if (action_index.has_value())
action_index_int = action_index.value();
- service_worker->event_dispatcher()->DispatchNotificationClickEvent(
+ service_worker->endpoint()->DispatchNotificationClickEvent(
notification_database_data.notification_id,
notification_database_data.notification_data, action_index_int, reply,
service_worker->CreateSimpleEventCallback(request_id));
@@ -252,10 +252,10 @@ void DoDispatchNotificationClickEvent(
// Called when the notification data has been deleted to finish the notification
// close event.
void OnPersistentNotificationDataDeleted(
- ServiceWorkerStatusCode service_worker_status,
+ blink::ServiceWorkerStatusCode service_worker_status,
const NotificationDispatchCompleteCallback& dispatch_complete_callback,
bool success) {
- if (service_worker_status != SERVICE_WORKER_OK) {
+ if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
ServiceWorkerNotificationEventFinished(dispatch_complete_callback,
service_worker_status);
return;
@@ -273,7 +273,7 @@ void DeleteNotificationDataFromDatabase(
const GURL& origin,
const scoped_refptr<PlatformNotificationContext>& notification_context,
const NotificationDispatchCompleteCallback& dispatch_complete_callback,
- ServiceWorkerStatusCode status_code) {
+ blink::ServiceWorkerStatusCode status_code) {
notification_context->DeleteNotificationData(
notification_id, origin,
base::Bind(&OnPersistentNotificationDataDeleted, status_code,
@@ -286,9 +286,9 @@ void DispatchNotificationCloseEventOnWorker(
const scoped_refptr<ServiceWorkerVersion>& service_worker,
const NotificationDatabaseData& notification_database_data,
ServiceWorkerVersion::StatusCallback callback,
- ServiceWorkerStatusCode start_worker_status) {
+ blink::ServiceWorkerStatusCode start_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (start_worker_status != SERVICE_WORKER_OK) {
+ if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(start_worker_status);
return;
}
@@ -296,7 +296,7 @@ void DispatchNotificationCloseEventOnWorker(
int request_id = service_worker->StartRequest(
ServiceWorkerMetrics::EventType::NOTIFICATION_CLOSE, std::move(callback));
- service_worker->event_dispatcher()->DispatchNotificationCloseEvent(
+ service_worker->endpoint()->DispatchNotificationCloseEvent(
notification_database_data.notification_id,
notification_database_data.notification_data,
service_worker->CreateSimpleEventCallback(request_id));
@@ -324,7 +324,7 @@ void DoDispatchNotificationCloseEvent(
DeleteNotificationDataFromDatabase(
notification_id, notification_database_data.origin,
notification_context, dispatch_complete_callback,
- ServiceWorkerStatusCode::SERVICE_WORKER_OK);
+ blink::ServiceWorkerStatusCode::kOk);
}
}
@@ -334,6 +334,7 @@ void DispatchNotificationEvent(
BrowserContext* browser_context,
const std::string& notification_id,
const GURL& origin,
+ const PlatformNotificationContext::Interaction interaction,
const NotificationOperationCallbackWithContext&
notification_action_callback,
const NotificationDispatchCompleteCallback& notification_error_callback) {
@@ -353,7 +354,7 @@ void DispatchNotificationEvent(
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
- &ReadNotificationDatabaseData, notification_id, origin,
+ &ReadNotificationDatabaseData, notification_id, origin, interaction,
service_worker_context, notification_context,
base::Bind(notification_action_callback, notification_context),
notification_error_callback));
@@ -387,8 +388,13 @@ void NotificationEventDispatcherImpl::DispatchNotificationClickEvent(
auto repeating_callback =
base::AdaptCallbackForRepeating(std::move(dispatch_complete_callback));
+ PlatformNotificationContext::Interaction interaction =
+ action_index.has_value()
+ ? PlatformNotificationContext::Interaction::ACTION_BUTTON_CLICKED
+ : PlatformNotificationContext::Interaction::CLICKED;
+
DispatchNotificationEvent(
- browser_context, notification_id, origin,
+ browser_context, notification_id, origin, interaction,
base::Bind(&DoDispatchNotificationClickEvent, action_index, reply,
repeating_callback),
repeating_callback /* notification_error_callback */);
@@ -407,6 +413,7 @@ void NotificationEventDispatcherImpl::DispatchNotificationCloseEvent(
DispatchNotificationEvent(
browser_context, notification_id, origin,
+ PlatformNotificationContext::Interaction::CLOSED,
base::Bind(&DoDispatchNotificationCloseEvent, notification_id, by_user,
repeating_callback),
repeating_callback /* notification_error_callback */);
@@ -414,7 +421,7 @@ void NotificationEventDispatcherImpl::DispatchNotificationCloseEvent(
void NotificationEventDispatcherImpl::RegisterNonPersistentNotificationListener(
const std::string& notification_id,
- blink::mojom::NonPersistentNotificationListenerPtrInfo listener_ptr_info) {
+ blink::mojom::NonPersistentNotificationListenerPtr event_listener_ptr) {
if (non_persistent_notification_listeners_.count(notification_id)) {
// Dispatch the close event for any previously displayed notification with
// the same notification id. This happens whenever a non-persistent
@@ -425,19 +432,16 @@ void NotificationEventDispatcherImpl::RegisterNonPersistentNotificationListener(
DispatchNonPersistentCloseEvent(notification_id, base::DoNothing());
}
- blink::mojom::NonPersistentNotificationListenerPtr listener_ptr(
- std::move(listener_ptr_info));
-
// Observe connection errors, which occur when the JavaScript object or the
// renderer hosting them goes away. (For example through navigation.) The
// listener gets freed together with |this|, thus the Unretained is safe.
- listener_ptr.set_connection_error_handler(base::BindOnce(
+ event_listener_ptr.set_connection_error_handler(base::BindOnce(
&NotificationEventDispatcherImpl::
HandleConnectionErrorForNonPersistentNotificationListener,
base::Unretained(this), notification_id));
non_persistent_notification_listeners_.emplace(notification_id,
- std::move(listener_ptr));
+ std::move(event_listener_ptr));
}
void NotificationEventDispatcherImpl::DispatchNonPersistentShowEvent(
@@ -448,10 +452,15 @@ void NotificationEventDispatcherImpl::DispatchNonPersistentShowEvent(
}
void NotificationEventDispatcherImpl::DispatchNonPersistentClickEvent(
- const std::string& notification_id) {
- if (!non_persistent_notification_listeners_.count(notification_id))
+ const std::string& notification_id,
+ NotificationClickEventCallback callback) {
+ if (!non_persistent_notification_listeners_.count(notification_id)) {
+ std::move(callback).Run(false /* success */);
return;
- non_persistent_notification_listeners_[notification_id]->OnClick();
+ }
+
+ non_persistent_notification_listeners_[notification_id]->OnClick(
+ base::BindOnce(std::move(callback), true /* success */));
}
void NotificationEventDispatcherImpl::DispatchNonPersistentCloseEvent(
diff --git a/chromium/content/browser/notifications/notification_event_dispatcher_impl.h b/chromium/content/browser/notifications/notification_event_dispatcher_impl.h
index dff47bf1dbe..230c56df61a 100644
--- a/chromium/content/browser/notifications/notification_event_dispatcher_impl.h
+++ b/chromium/content/browser/notifications/notification_event_dispatcher_impl.h
@@ -41,7 +41,8 @@ class CONTENT_EXPORT NotificationEventDispatcherImpl
void DispatchNonPersistentShowEvent(
const std::string& notification_id) override;
void DispatchNonPersistentClickEvent(
- const std::string& notification_id) override;
+ const std::string& notification_id,
+ NotificationClickEventCallback callback) override;
void DispatchNonPersistentCloseEvent(
const std::string& notification_id,
base::OnceClosure completed_closure) override;
@@ -50,7 +51,7 @@ class CONTENT_EXPORT NotificationEventDispatcherImpl
// non-persistent notification identified by |notification_id|.
void RegisterNonPersistentNotificationListener(
const std::string& notification_id,
- blink::mojom::NonPersistentNotificationListenerPtrInfo listener_ptr_info);
+ blink::mojom::NonPersistentNotificationListenerPtr event_listener_ptr);
private:
friend class NotificationEventDispatcherImplTest;
diff --git a/chromium/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc b/chromium/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc
index a2bbe92a81e..d1bf4fe4d95 100644
--- a/chromium/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc
+++ b/chromium/content/browser/notifications/notification_event_dispatcher_impl_unittest.cc
@@ -50,7 +50,10 @@ class TestNotificationListener
// blink::mojom::NonPersistentNotificationListener implementation.
void OnShow() override { on_show_count_++; }
- void OnClick() override { on_click_count_++; }
+ void OnClick(OnClickCallback completed_closure) override {
+ on_click_count_++;
+ std::move(completed_closure).Run();
+ }
void OnClose(OnCloseCallback completed_closure) override {
on_close_count_++;
std::move(completed_closure).Run();
@@ -94,11 +97,11 @@ class NotificationEventDispatcherImplTest : public ::testing::Test {
TEST_F(NotificationEventDispatcherImplTest,
DispatchNonPersistentShowEvent_NotifiesCorrectRegisteredListener) {
auto listener = std::make_unique<TestNotificationListener>();
- dispatcher_->RegisterNonPersistentNotificationListener(
- kPrimaryUniqueId, listener->GetPtr().PassInterface());
+ dispatcher_->RegisterNonPersistentNotificationListener(kPrimaryUniqueId,
+ listener->GetPtr());
auto other_listener = std::make_unique<TestNotificationListener>();
dispatcher_->RegisterNonPersistentNotificationListener(
- kSomeOtherUniqueId, other_listener->GetPtr().PassInterface());
+ kSomeOtherUniqueId, other_listener->GetPtr());
dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
@@ -119,7 +122,7 @@ TEST_F(NotificationEventDispatcherImplTest,
RegisterReplacementNonPersistentListener_FirstListenerGetsOnClose) {
auto original_listener = std::make_unique<TestNotificationListener>();
dispatcher_->RegisterNonPersistentNotificationListener(
- kPrimaryUniqueId, original_listener->GetPtr().PassInterface());
+ kPrimaryUniqueId, original_listener->GetPtr());
dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
@@ -127,7 +130,7 @@ TEST_F(NotificationEventDispatcherImplTest,
auto replacement_listener = std::make_unique<TestNotificationListener>();
dispatcher_->RegisterNonPersistentNotificationListener(
- kPrimaryUniqueId, replacement_listener->GetPtr().PassInterface());
+ kPrimaryUniqueId, replacement_listener->GetPtr());
WaitForMojoTasksToComplete();
@@ -138,20 +141,22 @@ TEST_F(NotificationEventDispatcherImplTest,
TEST_F(NotificationEventDispatcherImplTest,
DispatchNonPersistentClickEvent_NotifiesCorrectRegisteredListener) {
auto listener = std::make_unique<TestNotificationListener>();
- dispatcher_->RegisterNonPersistentNotificationListener(
- kPrimaryUniqueId, listener->GetPtr().PassInterface());
+ dispatcher_->RegisterNonPersistentNotificationListener(kPrimaryUniqueId,
+ listener->GetPtr());
auto other_listener = std::make_unique<TestNotificationListener>();
dispatcher_->RegisterNonPersistentNotificationListener(
- kSomeOtherUniqueId, other_listener->GetPtr().PassInterface());
+ kSomeOtherUniqueId, other_listener->GetPtr());
- dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId);
+ dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId,
+ base::DoNothing());
WaitForMojoTasksToComplete();
EXPECT_EQ(listener->on_click_count(), 1);
EXPECT_EQ(other_listener->on_click_count(), 0);
- dispatcher_->DispatchNonPersistentClickEvent(kSomeOtherUniqueId);
+ dispatcher_->DispatchNonPersistentClickEvent(kSomeOtherUniqueId,
+ base::DoNothing());
WaitForMojoTasksToComplete();
@@ -162,11 +167,11 @@ TEST_F(NotificationEventDispatcherImplTest,
TEST_F(NotificationEventDispatcherImplTest,
DispatchNonPersistentCloseEvent_NotifiesCorrectRegisteredListener) {
auto listener = std::make_unique<TestNotificationListener>();
- dispatcher_->RegisterNonPersistentNotificationListener(
- kPrimaryUniqueId, listener->GetPtr().PassInterface());
+ dispatcher_->RegisterNonPersistentNotificationListener(kPrimaryUniqueId,
+ listener->GetPtr());
auto other_listener = std::make_unique<TestNotificationListener>();
dispatcher_->RegisterNonPersistentNotificationListener(
- kSomeOtherUniqueId, other_listener->GetPtr().PassInterface());
+ kSomeOtherUniqueId, other_listener->GetPtr());
dispatcher_->DispatchNonPersistentCloseEvent(kPrimaryUniqueId,
base::DoNothing());
@@ -188,11 +193,12 @@ TEST_F(NotificationEventDispatcherImplTest,
TEST_F(NotificationEventDispatcherImplTest,
DispatchMultipleNonPersistentEvents_StopsNotifyingAfterClose) {
auto listener = std::make_unique<TestNotificationListener>();
- dispatcher_->RegisterNonPersistentNotificationListener(
- kPrimaryUniqueId, listener->GetPtr().PassInterface());
+ dispatcher_->RegisterNonPersistentNotificationListener(kPrimaryUniqueId,
+ listener->GetPtr());
dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
- dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId);
+ dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId,
+ base::DoNothing());
dispatcher_->DispatchNonPersistentCloseEvent(kPrimaryUniqueId,
base::DoNothing());
@@ -203,7 +209,8 @@ TEST_F(NotificationEventDispatcherImplTest,
EXPECT_EQ(listener->on_close_count(), 1);
// Should not be counted as the notification was already closed.
- dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId);
+ dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId,
+ base::DoNothing());
WaitForMojoTasksToComplete();
diff --git a/chromium/content/browser/notifications/platform_notification_context_impl.cc b/chromium/content/browser/notifications/platform_notification_context_impl.cc
index e174998b4d5..627e8dbd251 100644
--- a/chromium/content/browser/notifications/platform_notification_context_impl.cc
+++ b/chromium/content/browser/notifications/platform_notification_context_impl.cc
@@ -105,6 +105,9 @@ void PlatformNotificationContextImpl::InitializeOnIO(
void PlatformNotificationContextImpl::Shutdown() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ services_.clear();
+
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&PlatformNotificationContextImpl::ShutdownOnIO, this));
@@ -113,40 +116,23 @@ void PlatformNotificationContextImpl::Shutdown() {
void PlatformNotificationContextImpl::ShutdownOnIO() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- services_.clear();
-
// |service_worker_context_| may be NULL in tests.
if (service_worker_context_)
service_worker_context_->RemoveObserver(this);
}
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, origin,
- browser_context_->GetResourceContext(),
- std::move(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, browser_context_, resource_context, service_worker_context_,
- render_process_id, origin, std::move(request)));
+ this, browser_context_, service_worker_context_, origin,
+ std::move(request)));
}
void PlatformNotificationContextImpl::RemoveService(
BlinkNotificationServiceImpl* service) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::EraseIf(
services_,
[service](const std::unique_ptr<BlinkNotificationServiceImpl>& ptr) {
@@ -154,27 +140,30 @@ void PlatformNotificationContextImpl::RemoveService(
});
}
-void PlatformNotificationContextImpl::ReadNotificationData(
+void PlatformNotificationContextImpl::ReadNotificationDataAndRecordInteraction(
const std::string& notification_id,
const GURL& origin,
+ const PlatformNotificationContext::Interaction interaction,
const ReadResultCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
LazyInitialize(
base::Bind(&PlatformNotificationContextImpl::DoReadNotificationData, this,
- notification_id, origin, callback),
+ notification_id, origin, interaction, callback),
base::Bind(callback, false /* success */, NotificationDatabaseData()));
}
void PlatformNotificationContextImpl::DoReadNotificationData(
const std::string& notification_id,
const GURL& origin,
+ Interaction interaction,
const ReadResultCallback& callback) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
NotificationDatabaseData database_data;
NotificationDatabase::Status status =
- database_->ReadNotificationData(notification_id, origin, &database_data);
+ database_->ReadNotificationDataAndRecordInteraction(
+ notification_id, origin, interaction, &database_data);
UMA_HISTOGRAM_ENUMERATION("Notifications.Database.ReadResult", status,
NotificationDatabase::STATUS_COUNT);
@@ -319,17 +308,20 @@ void PlatformNotificationContextImpl::
}
void PlatformNotificationContextImpl::WriteNotificationData(
+ int64_t persistent_notification_id,
const GURL& origin,
const NotificationDatabaseData& database_data,
const WriteResultCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
LazyInitialize(
base::Bind(&PlatformNotificationContextImpl::DoWriteNotificationData,
- this, origin, database_data, callback),
+ this, persistent_notification_id, origin, database_data,
+ callback),
base::Bind(callback, false /* success */, "" /* notification_id */));
}
void PlatformNotificationContextImpl::DoWriteNotificationData(
+ int64_t persistent_notification_id,
const GURL& origin,
const NotificationDatabaseData& database_data,
const WriteResultCallback& callback) {
@@ -366,7 +358,7 @@ void PlatformNotificationContextImpl::DoWriteNotificationData(
write_database_data.notification_id =
notification_id_generator_.GenerateForPersistentNotification(
origin, database_data.notification_data.tag,
- database_->GetNextPersistentNotificationId());
+ persistent_notification_id);
NotificationDatabase::Status status =
database_->WriteNotificationData(origin, write_database_data);
diff --git a/chromium/content/browser/notifications/platform_notification_context_impl.h b/chromium/content/browser/notifications/platform_notification_context_impl.h
index a780c453cca..7ea92b62620 100644
--- a/chromium/content/browser/notifications/platform_notification_context_impl.h
+++ b/chromium/content/browser/notifications/platform_notification_context_impl.h
@@ -39,7 +39,6 @@ class BlinkNotificationServiceImpl;
class BrowserContext;
class NotificationDatabase;
struct NotificationDatabaseData;
-class ResourceContext;
class ServiceWorkerContextWrapper;
// Implementation of the Web Notification storage context. The public methods
@@ -65,14 +64,12 @@ class CONTENT_EXPORT PlatformNotificationContextImpl
void Shutdown();
// Creates a BlinkNotificationServiceImpl that is owned by this context. Must
- // 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,
+ // be called on the UI thread.
+ void CreateService(const url::Origin& origin,
blink::mojom::NotificationServiceRequest request);
// Removes |service| from the list of owned services, for example because the
- // Mojo pipe disconnected. Must be called on the IO thread.
+ // Mojo pipe disconnected. Must be called on the UI thread.
void RemoveService(BlinkNotificationServiceImpl* service);
// Returns the notification Id generator owned by the context.
@@ -81,10 +78,13 @@ class CONTENT_EXPORT PlatformNotificationContextImpl
}
// PlatformNotificationContext implementation.
- void ReadNotificationData(const std::string& notification_id,
- const GURL& origin,
- const ReadResultCallback& callback) override;
- void WriteNotificationData(const GURL& origin,
+ void ReadNotificationDataAndRecordInteraction(
+ const std::string& notification_id,
+ const GURL& origin,
+ Interaction interaction,
+ const ReadResultCallback& callback) override;
+ void WriteNotificationData(int64_t persistent_notification_id,
+ const GURL& origin,
const NotificationDatabaseData& database_data,
const WriteResultCallback& callback) override;
void DeleteNotificationData(const std::string& notification_id,
@@ -112,11 +112,6 @@ class CONTENT_EXPORT PlatformNotificationContextImpl
std::unique_ptr<std::set<std::string>> displayed_notifications,
bool supports_synchronization);
void ShutdownOnIO();
- void CreateServiceOnIO(
- int render_process_id,
- const url::Origin& origin,
- ResourceContext* resource_context,
- mojo::InterfaceRequest<blink::mojom::NotificationService> request);
// Initializes the database if neccesary. Must be called on the IO thread.
// |success_closure| will be invoked on a the |task_runner_| thread when
@@ -136,6 +131,7 @@ class CONTENT_EXPORT PlatformNotificationContextImpl
// IO thread when the operation has completed.
void DoReadNotificationData(const std::string& notification_id,
const GURL& origin,
+ Interaction interaction,
const ReadResultCallback& callback);
// Updates the database (and the result callback) based on
@@ -169,7 +165,8 @@ class CONTENT_EXPORT PlatformNotificationContextImpl
// Actually writes the notification database to the database. Must only be
// called on the |task_runner_| thread. |callback| will be invoked on the
// IO thread when the operation has completed.
- void DoWriteNotificationData(const GURL& origin,
+ void DoWriteNotificationData(int64_t persistent_notification_id,
+ const GURL& origin,
const NotificationDatabaseData& database_data,
const WriteResultCallback& callback);
diff --git a/chromium/content/browser/notifications/platform_notification_context_unittest.cc b/chromium/content/browser/notifications/platform_notification_context_unittest.cc
index d661a252d6f..ffe0ebb1681 100644
--- a/chromium/content/browser/notifications/platform_notification_context_unittest.cc
+++ b/chromium/content/browser/notifications/platform_notification_context_unittest.cc
@@ -68,19 +68,19 @@ class PlatformNotificationContextTest : public ::testing::Test {
// Callback to provide when registering a Service Worker with a Service
// Worker Context. Will write the registration id to |store_registration_id|.
void DidRegisterServiceWorker(int64_t* store_registration_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t service_worker_registration_id) {
DCHECK(store_registration_id);
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
*store_registration_id = service_worker_registration_id;
}
// Callback to provide when unregistering a Service Worker. Will write the
// resulting status code to |store_status|.
- void DidUnregisterServiceWorker(ServiceWorkerStatusCode* store_status,
- ServiceWorkerStatusCode status) {
+ void DidUnregisterServiceWorker(blink::ServiceWorkerStatusCode* store_status,
+ blink::ServiceWorkerStatusCode status) {
DCHECK(store_status);
*store_status = status;
}
@@ -123,6 +123,11 @@ class PlatformNotificationContextTest : public ::testing::Test {
// Returns whether the last invoked callback finished successfully.
bool success() const { return success_; }
+ // Returns the next persistent notification id for tests.
+ int64_t next_persistent_notification_id() {
+ return next_persistent_notification_id_++;
+ }
+
// Returns the NotificationDatabaseData associated with the last invoked
// ReadNotificationData callback.
const NotificationDatabaseData& database_data() const {
@@ -133,20 +138,22 @@ class PlatformNotificationContextTest : public ::testing::Test {
const std::string& notification_id() const { return notification_id_; }
private:
- TestBrowserThreadBundle thread_bundle_;
+ TestBrowserThreadBundle thread_bundle_; // Must be first member
TestBrowserContext browser_context_;
bool success_;
NotificationDatabaseData database_data_;
std::string notification_id_;
+ int64_t next_persistent_notification_id_ = 1;
};
TEST_F(PlatformNotificationContextTest, ReadNonExistentNotification) {
scoped_refptr<PlatformNotificationContextImpl> context =
CreatePlatformNotificationContext();
- context->ReadNotificationData(
+ context->ReadNotificationDataAndRecordInteraction(
"invalid-notification-id", GURL("https://example.com"),
+ PlatformNotificationContext::Interaction::NONE,
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -165,7 +172,7 @@ TEST_F(PlatformNotificationContextTest, WriteReadNotification) {
notification_database_data.origin = origin;
context->WriteNotificationData(
- origin, notification_database_data,
+ next_persistent_notification_id(), origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -175,8 +182,8 @@ TEST_F(PlatformNotificationContextTest, WriteReadNotification) {
ASSERT_TRUE(success());
EXPECT_FALSE(notification_id().empty());
- context->ReadNotificationData(
- notification_id(), origin,
+ context->ReadNotificationDataAndRecordInteraction(
+ notification_id(), origin, PlatformNotificationContext::Interaction::NONE,
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -206,10 +213,9 @@ TEST_F(PlatformNotificationContextTest, WriteReadReplacedNotification) {
// Write the first notification with the given |tag|.
context->WriteNotificationData(
- origin, notification_database_data,
+ next_persistent_notification_id(), origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
-
base::RunLoop().RunUntilIdle();
std::string read_notification_id = notification_id();
@@ -223,7 +229,7 @@ TEST_F(PlatformNotificationContextTest, WriteReadReplacedNotification) {
// Write the second notification with the given |tag|.
context->WriteNotificationData(
- origin, notification_database_data,
+ next_persistent_notification_id(), origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -277,7 +283,7 @@ TEST_F(PlatformNotificationContextTest, DeleteNotification) {
NotificationDatabaseData notification_database_data;
context->WriteNotificationData(
- origin, notification_database_data,
+ next_persistent_notification_id(), origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -297,8 +303,8 @@ TEST_F(PlatformNotificationContextTest, DeleteNotification) {
// The notification existed, so it should have been removed successfully.
ASSERT_TRUE(success());
- context->ReadNotificationData(
- notification_id(), origin,
+ context->ReadNotificationDataAndRecordInteraction(
+ notification_id(), origin, PlatformNotificationContext::Interaction::NONE,
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -345,7 +351,7 @@ TEST_F(PlatformNotificationContextTest, ServiceWorkerUnregistered) {
// Create a notification for that Service Worker registration.
notification_context->WriteNotificationData(
- origin, notification_database_data,
+ next_persistent_notification_id(), origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -354,7 +360,7 @@ TEST_F(PlatformNotificationContextTest, ServiceWorkerUnregistered) {
ASSERT_TRUE(success());
EXPECT_FALSE(notification_id().empty());
- ServiceWorkerStatusCode unregister_status;
+ blink::ServiceWorkerStatusCode unregister_status;
// Now drop the Service Worker registration which owns that notification.
embedded_worker_test_helper->context()->UnregisterServiceWorker(
@@ -363,11 +369,11 @@ TEST_F(PlatformNotificationContextTest, ServiceWorkerUnregistered) {
base::Unretained(this), &unregister_status));
base::RunLoop().RunUntilIdle();
- ASSERT_EQ(SERVICE_WORKER_OK, unregister_status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, unregister_status);
// And verify that the associated notification has indeed been dropped.
- notification_context->ReadNotificationData(
- notification_id(), origin,
+ notification_context->ReadNotificationDataAndRecordInteraction(
+ notification_id(), origin, PlatformNotificationContext::Interaction::NONE,
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -384,7 +390,7 @@ TEST_F(PlatformNotificationContextTest, DestroyDatabaseOnStorageWiped) {
NotificationDatabaseData notification_database_data;
context->WriteNotificationData(
- origin, notification_database_data,
+ next_persistent_notification_id(), origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -401,8 +407,8 @@ TEST_F(PlatformNotificationContextTest, DestroyDatabaseOnStorageWiped) {
// Verify that reading notification data fails because the data does not
// exist anymore. Deliberately omit RunUntilIdle(), since this is unlikely to
// be the case when OnStorageWiped gets called in production.
- context->ReadNotificationData(
- notification_id(), origin,
+ context->ReadNotificationDataAndRecordInteraction(
+ notification_id(), origin, PlatformNotificationContext::Interaction::NONE,
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -424,8 +430,9 @@ TEST_F(PlatformNotificationContextTest, DestroyOnDiskDatabase) {
OverrideTaskRunnerForTesting(context.get());
// Trigger a read-operation to force creating the database.
- context->ReadNotificationData(
+ context->ReadNotificationDataAndRecordInteraction(
"invalid-notification-id", GURL("https://example.com"),
+ PlatformNotificationContext::Interaction::NONE,
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
@@ -476,7 +483,7 @@ TEST_F(PlatformNotificationContextTest, ReadAllServiceWorkerDataFilled) {
// test Service Worker Registration id.
for (int i = 0; i < 10; ++i) {
context->WriteNotificationData(
- origin, notification_database_data,
+ next_persistent_notification_id(), origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -520,7 +527,7 @@ TEST_F(PlatformNotificationContextTest, SynchronizeNotifications) {
content::NotificationResources notification_resources;
context->WriteNotificationData(
- origin, notification_database_data,
+ next_persistent_notification_id(), origin, notification_database_data,
base::Bind(&PlatformNotificationContextTest::DidWriteNotificationData,
base::Unretained(this)));
@@ -558,8 +565,9 @@ TEST_F(PlatformNotificationContextTest, SynchronizeNotifications) {
ASSERT_TRUE(success());
ASSERT_EQ(0u, notification_database_datas.size());
- context->ReadNotificationData(
+ context->ReadNotificationDataAndRecordInteraction(
notification_id(), origin,
+ PlatformNotificationContext::Interaction::CLOSED,
base::Bind(&PlatformNotificationContextTest::DidReadNotificationData,
base::Unretained(this)));
diff --git a/chromium/content/browser/oop_browsertest.cc b/chromium/content/browser/oop_browsertest.cc
index e6e00b92256..390c73409e9 100644
--- a/chromium/content/browser/oop_browsertest.cc
+++ b/chromium/content/browser/oop_browsertest.cc
@@ -7,11 +7,14 @@
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "build/build_config.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
-#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.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_utils.h"
@@ -33,9 +36,9 @@ class OOPBrowserTest : public ContentBrowserTest {
ContentBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kEnableGpuRasterization);
command_line->AppendSwitch(switches::kEnablePixelOutputInTests);
- command_line->AppendSwitch(switches::kEnableOOPRasterization);
+ command_line->AppendSwitch(switches::kEnableOopRasterization);
- const bool use_gpu_in_tests = !features::IsMashEnabled();
+ const bool use_gpu_in_tests = features::IsAshInBrowserProcess();
if (use_gpu_in_tests)
command_line->AppendSwitch(switches::kUseGpuInTests);
}
@@ -58,10 +61,13 @@ IN_PROC_BROWSER_TEST_F(OOPBrowserTest, Basic) {
"<style>div{background-color:blue; width:100; height:100;}</style>"
"<body bgcolor=blue><div></div></body>");
NavigateToURLBlockUntilNavigationsComplete(shell(), url, 1);
- shell()->web_contents()->GetMainFrame()->InsertVisualStateCallback(base::Bind(
- &OOPBrowserTest::VerifyVisualStateUpdated, base::Unretained(this),
- base::RunLoop::QuitCurrentWhenIdleClosureDeprecated()));
- content::RunMessageLoop();
+
+ // Wait for the renderer to submit a frame.
+ RenderFrameSubmissionObserver frame_observer(
+ RenderWidgetHostImpl::From(
+ shell()->web_contents()->GetRenderViewHost()->GetWidget())
+ ->render_frame_metadata_provider());
+ frame_observer.WaitForAnyFrameSubmission();
auto* rwh = shell()->web_contents()->GetRenderViewHost()->GetWidget();
ASSERT_TRUE(rwh->GetView()->IsSurfaceAvailableForCopy());
@@ -78,7 +84,7 @@ IN_PROC_BROWSER_TEST_F(OOPBrowserTest, Basic) {
&snapshot, run_loop.QuitWhenIdleClosure()));
run_loop.Run();
- EXPECT_FALSE(snapshot.drawsNothing());
+ ASSERT_FALSE(snapshot.drawsNothing());
for (int i = 0; i < snapshot.width(); ++i) {
for (int j = 0; j < snapshot.height(); ++j) {
ASSERT_EQ(snapshot.getColor(i, j), SK_ColorBLUE);
diff --git a/chromium/content/browser/origin_manifest/origin_manifest_parser.cc b/chromium/content/browser/origin_manifest/origin_manifest_parser.cc
deleted file mode 100644
index 1b6a3db52d2..00000000000
--- a/chromium/content/browser/origin_manifest/origin_manifest_parser.cc
+++ /dev/null
@@ -1,105 +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/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
deleted file mode 100644
index fa3ef6ba71f..00000000000
--- a/chromium/content/browser/origin_manifest/origin_manifest_parser.h
+++ /dev/null
@@ -1,54 +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_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/blink/public/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
deleted file mode 100644
index 5f12ec7bac8..00000000000
--- a/chromium/content/browser/origin_manifest/origin_manifest_parser_unittest.cc
+++ /dev/null
@@ -1,386 +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 <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_browsertest.cc b/chromium/content/browser/payments/payment_app_browsertest.cc
index bd35aa9b848..0c837e8f51b 100644
--- a/chromium/content/browser/payments/payment_app_browsertest.cc
+++ b/chromium/content/browser/payments/payment_app_browsertest.cc
@@ -183,7 +183,7 @@ class PaymentAppBrowserTest : public ContentBrowserTest {
event_data->payment_request_origin = GURL("https://example.com");
event_data->method_data.push_back(PaymentMethodData::New());
- event_data->method_data[0]->supported_methods = {supported_method};
+ event_data->method_data[0]->supported_method = supported_method;
PaymentDetailsModifierPtr modifier = PaymentDetailsModifier::New();
modifier->total = PaymentItem::New();
@@ -191,7 +191,7 @@ class PaymentAppBrowserTest : public ContentBrowserTest {
modifier->total->amount->currency = "USD";
modifier->total->amount->value = "55";
modifier->method_data = PaymentMethodData::New();
- modifier->method_data->supported_methods = {supported_method};
+ modifier->method_data->supported_method = supported_method;
event_data->modifiers.push_back(std::move(modifier));
return event_data;
@@ -209,7 +209,7 @@ class PaymentAppBrowserTest : public ContentBrowserTest {
event_data->payment_request_id = "payment-request-id";
event_data->method_data.push_back(PaymentMethodData::New());
- event_data->method_data[0]->supported_methods = {supported_method};
+ event_data->method_data[0]->supported_method = supported_method;
event_data->total = PaymentCurrencyAmount::New();
event_data->total->currency = "USD";
@@ -221,7 +221,7 @@ class PaymentAppBrowserTest : public ContentBrowserTest {
modifier->total->amount->currency = "USD";
modifier->total->amount->value = "55";
modifier->method_data = PaymentMethodData::New();
- modifier->method_data->supported_methods = {supported_method};
+ modifier->method_data->supported_method = supported_method;
event_data->modifiers.push_back(std::move(modifier));
event_data->instrument_key = instrument_key;
@@ -275,10 +275,10 @@ IN_PROC_BROWSER_TEST_F(PaymentAppBrowserTest, CanMakePayment) {
EXPECT_EQ("https://example.com/", PopConsoleString() /* topOrigin */);
EXPECT_EQ("https://example.com/",
PopConsoleString() /* paymentRequestOrigin */);
- EXPECT_EQ("[{\"supportedMethods\":[\"basic-card\"]}]",
+ EXPECT_EQ("[{\"supportedMethods\":\"basic-card\"}]",
PopConsoleString() /* methodData */);
EXPECT_EQ(
- "[{\"additionalDisplayItems\":[],\"supportedMethods\":[\"basic-card\"],"
+ "[{\"additionalDisplayItems\":[],\"supportedMethods\":\"basic-card\","
"\"total\":{\"amount\":{\"currency\":\"USD\","
"\"value\":\"55\"},\"label\":\"\",\"pending\":false}}"
"]",
@@ -320,14 +320,14 @@ IN_PROC_BROWSER_TEST_F(PaymentAppBrowserTest, PaymentAppInvocation) {
EXPECT_EQ("https://example.com/",
PopConsoleString() /* paymentRequestOrigin */);
EXPECT_EQ("payment-request-id", PopConsoleString() /* paymentRequestId */);
- EXPECT_EQ("[{\"supportedMethods\":[\"basic-card\"]}]",
+ EXPECT_EQ("[{\"supportedMethods\":\"basic-card\"}]",
PopConsoleString() /* methodData */);
EXPECT_EQ(
"{\"currency\":\"USD\","
"\"value\":\"55\"}",
PopConsoleString() /* total */);
EXPECT_EQ(
- "[{\"additionalDisplayItems\":[],\"supportedMethods\":[\"basic-card\"],"
+ "[{\"additionalDisplayItems\":[],\"supportedMethods\":\"basic-card\","
"\"total\":{\"amount\":{\"currency\":\"USD\","
"\"value\":\"55\"},\"label\":\"\",\"pending\":false}}"
"]",
@@ -357,13 +357,13 @@ IN_PROC_BROWSER_TEST_F(PaymentAppBrowserTest, PaymentAppOpenWindowFailed) {
EXPECT_EQ("https://example.com/",
PopConsoleString() /* paymentRequestOrigin */);
EXPECT_EQ("payment-request-id", PopConsoleString() /* paymentRequestId */);
- EXPECT_EQ("[{\"supportedMethods\":[\"https://bobpay.com\"]}]",
+ EXPECT_EQ("[{\"supportedMethods\":\"https://bobpay.com\"}]",
PopConsoleString() /* methodData */);
EXPECT_EQ("{\"currency\":\"USD\",\"value\":\"55\"}",
PopConsoleString() /* total */);
EXPECT_EQ(
- "[{\"additionalDisplayItems\":[],\"supportedMethods\":[\"https://"
- "bobpay.com\"],"
+ "[{\"additionalDisplayItems\":[],\"supportedMethods\":\"https://"
+ "bobpay.com\","
"\"total\":{\"amount\":{\"currency\":\"USD\","
"\"value\":\"55\"},\"label\":\"\",\"pending\":false}}"
"]",
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 35732115848..d604c1992fa 100644
--- a/chromium/content/browser/payments/payment_app_content_unittest_base.cc
+++ b/chromium/content/browser/payments/payment_app_content_unittest_base.cc
@@ -15,12 +15,12 @@
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/storage_partition_impl.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.mojom.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/interface_request.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
namespace content {
@@ -29,17 +29,19 @@ namespace {
void RegisterServiceWorkerCallback(bool* called,
int64_t* out_registration_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id) {
- EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
+ << blink::ServiceWorkerStatusToString(status);
*called = true;
*out_registration_id = registration_id;
}
void UnregisterServiceWorkerCallback(bool* called,
- ServiceWorkerStatusCode status) {
- EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
+ blink::ServiceWorkerStatusCode status) {
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
+ << blink::ServiceWorkerStatusToString(status);
*called = true;
}
@@ -64,7 +66,7 @@ class PaymentAppContentUnitTestBase::PaymentAppForWorkerTestHelper
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
@@ -76,7 +78,7 @@ class PaymentAppContentUnitTestBase::PaymentAppForWorkerTestHelper
last_sw_scope_ = scope;
EmbeddedWorkerTestHelper::OnStartWorker(
embedded_worker_id, service_worker_version_id, scope, script_url,
- pause_after_download, std::move(dispatcher_request),
+ pause_after_download, std::move(service_worker_request),
std::move(controller_request), std::move(instance_host),
std::move(provider_info), std::move(installed_scripts_info));
}
@@ -84,8 +86,8 @@ class PaymentAppContentUnitTestBase::PaymentAppForWorkerTestHelper
void OnPaymentRequestEvent(
payments::mojom::PaymentRequestEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchPaymentRequestEventCallback
- callback) override {
+ mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback)
+ override {
if (respond_payment_request_immediately) {
EmbeddedWorkerTestHelper::OnPaymentRequestEvent(
std::move(event_data), std::move(response_callback),
@@ -100,8 +102,8 @@ class PaymentAppContentUnitTestBase::PaymentAppForWorkerTestHelper
void OnCanMakePaymentEvent(
payments::mojom::CanMakePaymentEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchCanMakePaymentEventCallback
- callback) override {
+ mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback)
+ override {
EmbeddedWorkerTestHelper::OnCanMakePaymentEvent(
std::move(event_data), std::move(response_callback),
std::move(callback));
@@ -109,8 +111,8 @@ class PaymentAppContentUnitTestBase::PaymentAppForWorkerTestHelper
void OnAbortPaymentEvent(
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchCanMakePaymentEventCallback
- callback) override {
+ mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback)
+ override {
EmbeddedWorkerTestHelper::OnAbortPaymentEvent(std::move(response_callback),
std::move(callback));
}
diff --git a/chromium/content/browser/payments/payment_app_database.cc b/chromium/content/browser/payments/payment_app_database.cc
index 664e105455e..924d36591cc 100644
--- a/chromium/content/browser/payments/payment_app_database.cc
+++ b/chromium/content/browser/payments/payment_app_database.cc
@@ -71,7 +71,7 @@ PaymentInstrumentPtr ToPaymentInstrumentForMojo(const std::string& input) {
PaymentInstrumentPtr instrument = PaymentInstrument::New();
instrument->name = instrument_proto.name();
for (const auto& icon_proto : instrument_proto.icons()) {
- blink::Manifest::Icon icon;
+ blink::Manifest::ImageResource icon;
icon.src = GURL(icon_proto.src());
icon.type = base::UTF8ToUTF16(icon_proto.type());
for (const auto& size_proto : icon_proto.sizes()) {
@@ -197,7 +197,7 @@ void PaymentAppDatabase::WritePaymentInstrument(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (instrument->icons.size() > 0) {
- std::vector<blink::Manifest::Icon> icons(instrument->icons);
+ std::vector<blink::Manifest::ImageResource> icons(instrument->icons);
PaymentInstrumentIconFetcher::Start(
scope, service_worker_context_->GetProviderHostIds(scope.GetOrigin()),
icons,
@@ -264,10 +264,10 @@ void PaymentAppDatabase::FetchPaymentAppInfoCallback(
void PaymentAppDatabase::DidFindRegistrationToUpdatePaymentAppInfo(
FetchAndUpdatePaymentAppInfoCallback callback,
std::unique_ptr<PaymentAppInfoFetcher::PaymentAppInfo> app_info,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(PaymentHandlerStatus::NO_ACTIVE_WORKER);
return;
}
@@ -285,9 +285,9 @@ void PaymentAppDatabase::DidGetPaymentAppInfoToUpdatePaymentAppInfo(
std::unique_ptr<PaymentAppInfoFetcher::PaymentAppInfo> app_info,
scoped_refptr<ServiceWorkerRegistration> registration,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(PaymentHandlerStatus::NO_ACTIVE_WORKER);
return;
}
@@ -331,14 +331,14 @@ void PaymentAppDatabase::DidGetPaymentAppInfoToUpdatePaymentAppInfo(
void PaymentAppDatabase::DidUpdatePaymentApp(
FetchAndUpdatePaymentAppInfoCallback callback,
bool fetch_app_info_failed,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
PaymentHandlerStatus handler_status =
fetch_app_info_failed
? PaymentHandlerStatus::FETCH_PAYMENT_APP_INFO_FAILED
: PaymentHandlerStatus::SUCCESS;
- handler_status = status == SERVICE_WORKER_OK
+ handler_status = status == blink::ServiceWorkerStatusCode::kOk
? handler_status
: PaymentHandlerStatus::STORAGE_OPERATION_FAILED;
return std::move(callback).Run(handler_status);
@@ -369,10 +369,10 @@ void PaymentAppDatabase::SetPaymentAppUserHint(const GURL& scope,
void PaymentAppDatabase::DidFindRegistrationToSetPaymentAppUserHint(
const std::string& user_hint,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK)
+ if (status != blink::ServiceWorkerStatusCode::kOk)
return;
service_worker_context_->GetRegistrationUserDataByKeyPrefix(
@@ -387,9 +387,9 @@ void PaymentAppDatabase::DidGetPaymentAppInfoToSetUserHint(
int64_t registration_id,
const GURL& pattern,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK)
+ if (status != blink::ServiceWorkerStatusCode::kOk)
return;
DCHECK_LE(data.size(), 1U);
@@ -411,9 +411,9 @@ void PaymentAppDatabase::DidGetPaymentAppInfoToSetUserHint(
}
void PaymentAppDatabase::DidSetPaymentAppUserHint(
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(status == SERVICE_WORKER_OK);
+ DCHECK(status == blink::ServiceWorkerStatusCode::kOk);
}
void PaymentAppDatabase::SetPaymentAppInfoForRegisteredServiceWorker(
@@ -438,11 +438,11 @@ void PaymentAppDatabase::DidFindRegistrationToSetPaymentApp(
const std::string& icon,
const std::string& method,
SetPaymentAppInfoCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(PaymentHandlerStatus::NO_ACTIVE_WORKER);
return;
}
@@ -477,10 +477,10 @@ void PaymentAppDatabase::DidWritePaymentAppForSetPaymentApp(
const std::string& method,
SetPaymentAppInfoCallback callback,
scoped_refptr<ServiceWorkerRegistration> registration,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(PaymentHandlerStatus::STORAGE_OPERATION_FAILED);
return;
}
@@ -514,10 +514,10 @@ void PaymentAppDatabase::DidWritePaymentAppForSetPaymentApp(
void PaymentAppDatabase::DidWritePaymentInstrumentForSetPaymentApp(
SetPaymentAppInfoCallback callback,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return std::move(callback).Run(
- status == SERVICE_WORKER_OK
+ status == blink::ServiceWorkerStatusCode::kOk
? PaymentHandlerStatus::SUCCESS
: PaymentHandlerStatus::STORAGE_OPERATION_FAILED);
}
@@ -525,9 +525,9 @@ void PaymentAppDatabase::DidWritePaymentInstrumentForSetPaymentApp(
void PaymentAppDatabase::DidReadAllPaymentApps(
ReadAllPaymentAppsCallback callback,
const std::vector<std::pair<int64_t, std::string>>& raw_data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(PaymentApps());
return;
}
@@ -556,9 +556,9 @@ void PaymentAppDatabase::DidReadAllPaymentInstruments(
PaymentApps apps,
ReadAllPaymentAppsCallback callback,
const std::vector<std::pair<int64_t, std::string>>& raw_data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(std::move(apps));
return;
}
@@ -589,10 +589,10 @@ void PaymentAppDatabase::DidReadAllPaymentInstruments(
void PaymentAppDatabase::DidFindRegistrationToDeletePaymentInstrument(
const std::string& instrument_key,
DeletePaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(PaymentHandlerStatus::NO_ACTIVE_WORKER);
return;
}
@@ -609,9 +609,9 @@ void PaymentAppDatabase::DidFindPaymentInstrument(
const std::string& instrument_key,
DeletePaymentInstrumentCallback callback,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK || data.size() != 1) {
+ if (status != blink::ServiceWorkerStatusCode::kOk || data.size() != 1) {
std::move(callback).Run(PaymentHandlerStatus::NOT_FOUND);
return;
}
@@ -626,9 +626,9 @@ void PaymentAppDatabase::DidFindPaymentInstrument(
void PaymentAppDatabase::DidDeletePaymentInstrument(
DeletePaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return std::move(callback).Run(status == SERVICE_WORKER_OK
+ return std::move(callback).Run(status == blink::ServiceWorkerStatusCode::kOk
? PaymentHandlerStatus::SUCCESS
: PaymentHandlerStatus::NOT_FOUND);
}
@@ -636,10 +636,10 @@ void PaymentAppDatabase::DidDeletePaymentInstrument(
void PaymentAppDatabase::DidFindRegistrationToReadPaymentInstrument(
const std::string& instrument_key,
ReadPaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(PaymentInstrument::New(),
PaymentHandlerStatus::NO_ACTIVE_WORKER);
return;
@@ -654,9 +654,9 @@ void PaymentAppDatabase::DidFindRegistrationToReadPaymentInstrument(
void PaymentAppDatabase::DidReadPaymentInstrument(
ReadPaymentInstrumentCallback callback,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK || data.size() != 1) {
+ if (status != blink::ServiceWorkerStatusCode::kOk || data.size() != 1) {
std::move(callback).Run(PaymentInstrument::New(),
PaymentHandlerStatus::NOT_FOUND);
return;
@@ -674,10 +674,10 @@ void PaymentAppDatabase::DidReadPaymentInstrument(
void PaymentAppDatabase::DidFindRegistrationToGetKeys(
KeysOfPaymentInstrumentsCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(std::vector<std::string>(),
PaymentHandlerStatus::NO_ACTIVE_WORKER);
return;
@@ -692,9 +692,9 @@ void PaymentAppDatabase::DidFindRegistrationToGetKeys(
void PaymentAppDatabase::DidGetKeysOfPaymentInstruments(
KeysOfPaymentInstrumentsCallback callback,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(std::vector<std::string>(),
PaymentHandlerStatus::NOT_FOUND);
return;
@@ -711,10 +711,10 @@ void PaymentAppDatabase::DidGetKeysOfPaymentInstruments(
void PaymentAppDatabase::DidFindRegistrationToHasPaymentInstrument(
const std::string& instrument_key,
HasPaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(PaymentHandlerStatus::NO_ACTIVE_WORKER);
return;
}
@@ -728,9 +728,9 @@ void PaymentAppDatabase::DidFindRegistrationToHasPaymentInstrument(
void PaymentAppDatabase::DidHasPaymentInstrument(
DeletePaymentInstrumentCallback callback,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK || data.size() != 1) {
+ if (status != blink::ServiceWorkerStatusCode::kOk || data.size() != 1) {
std::move(callback).Run(PaymentHandlerStatus::NOT_FOUND);
return;
}
@@ -743,10 +743,10 @@ void PaymentAppDatabase::DidFindRegistrationToWritePaymentInstrument(
PaymentInstrumentPtr instrument,
const std::string& decoded_instrument_icon,
WritePaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(PaymentHandlerStatus::NO_ACTIVE_WORKER);
return;
}
@@ -800,10 +800,10 @@ void PaymentAppDatabase::DidFindRegistrationToWritePaymentInstrument(
void PaymentAppDatabase::DidWritePaymentInstrument(
WritePaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
return std::move(callback).Run(
- status == SERVICE_WORKER_OK
+ status == blink::ServiceWorkerStatusCode::kOk
? PaymentHandlerStatus::SUCCESS
: PaymentHandlerStatus::STORAGE_OPERATION_FAILED);
}
@@ -811,11 +811,11 @@ void PaymentAppDatabase::DidWritePaymentInstrument(
void PaymentAppDatabase::DidFindRegistrationToClearPaymentInstruments(
const GURL& scope,
ClearPaymentInstrumentsCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(PaymentHandlerStatus::NO_ACTIVE_WORKER);
return;
}
@@ -857,9 +857,9 @@ void PaymentAppDatabase::DidGetKeysToClearPaymentInstruments(
void PaymentAppDatabase::DidClearPaymentInstruments(
ClearPaymentInstrumentsCallback callback,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return std::move(callback).Run(status == SERVICE_WORKER_OK
+ return std::move(callback).Run(status == blink::ServiceWorkerStatusCode::kOk
? PaymentHandlerStatus::SUCCESS
: PaymentHandlerStatus::NOT_FOUND);
}
diff --git a/chromium/content/browser/payments/payment_app_database.h b/chromium/content/browser/payments/payment_app_database.h
index baca8a422be..07bb2e8c310 100644
--- a/chromium/content/browser/payments/payment_app_database.h
+++ b/chromium/content/browser/payments/payment_app_database.h
@@ -16,9 +16,9 @@
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/public/browser/stored_payment_app.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/platform/modules/payments/payment_app.mojom.h"
namespace content {
@@ -90,55 +90,55 @@ class CONTENT_EXPORT PaymentAppDatabase {
void DidReadAllPaymentApps(
ReadAllPaymentAppsCallback callback,
const std::vector<std::pair<int64_t, std::string>>& raw_data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void DidReadAllPaymentInstruments(
PaymentApps apps,
ReadAllPaymentAppsCallback callback,
const std::vector<std::pair<int64_t, std::string>>& raw_data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// DeletePaymentInstrument callbacks
void DidFindRegistrationToDeletePaymentInstrument(
const std::string& instrument_key,
DeletePaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void DidFindPaymentInstrument(int64_t registration_id,
const std::string& instrument_key,
DeletePaymentInstrumentCallback callback,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void DidDeletePaymentInstrument(DeletePaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// ReadPaymentInstrument callbacks
void DidFindRegistrationToReadPaymentInstrument(
const std::string& instrument_key,
ReadPaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void DidReadPaymentInstrument(ReadPaymentInstrumentCallback callback,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// KeysOfPaymentInstruments callbacks
void DidFindRegistrationToGetKeys(
KeysOfPaymentInstrumentsCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void DidGetKeysOfPaymentInstruments(KeysOfPaymentInstrumentsCallback callback,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// HasPaymentInstrument callbacks
void DidFindRegistrationToHasPaymentInstrument(
const std::string& instrument_key,
HasPaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void DidHasPaymentInstrument(DeletePaymentInstrumentCallback callback,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// WritePaymentInstrument callbacks
void DidFindRegistrationToWritePaymentInstrument(
@@ -146,10 +146,10 @@ class CONTENT_EXPORT PaymentAppDatabase {
payments::mojom::PaymentInstrumentPtr instrument,
const std::string& decoded_instrument_icon,
WritePaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void DidWritePaymentInstrument(WritePaymentInstrumentCallback callback,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// FetchAndUpdatePaymentAppInfo callbacks.
void FetchPaymentAppInfoCallback(
@@ -159,17 +159,17 @@ class CONTENT_EXPORT PaymentAppDatabase {
void DidFindRegistrationToUpdatePaymentAppInfo(
FetchAndUpdatePaymentAppInfoCallback callback,
std::unique_ptr<PaymentAppInfoFetcher::PaymentAppInfo> app_info,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void DidGetPaymentAppInfoToUpdatePaymentAppInfo(
FetchAndUpdatePaymentAppInfoCallback callback,
std::unique_ptr<PaymentAppInfoFetcher::PaymentAppInfo> app_info,
scoped_refptr<ServiceWorkerRegistration> registration,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void DidUpdatePaymentApp(FetchAndUpdatePaymentAppInfoCallback callback,
bool fetch_app_info_failed,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// PaymentInstrumentIconFetcherCallback.
void DidFetchedPaymentInstrumentIcon(
@@ -183,7 +183,7 @@ class CONTENT_EXPORT PaymentAppDatabase {
void DidFindRegistrationToClearPaymentInstruments(
const GURL& scope,
ClearPaymentInstrumentsCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void DidGetKeysToClearPaymentInstruments(
scoped_refptr<ServiceWorkerRegistration> registration,
@@ -191,19 +191,19 @@ class CONTENT_EXPORT PaymentAppDatabase {
const std::vector<std::string>& keys,
payments::mojom::PaymentHandlerStatus status);
void DidClearPaymentInstruments(ClearPaymentInstrumentsCallback callback,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// SetPaymentAppUserHint callbacks.
void DidFindRegistrationToSetPaymentAppUserHint(
const std::string& user_hint,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void DidGetPaymentAppInfoToSetUserHint(const std::string& user_hint,
int64_t registration_id,
const GURL& pattern,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode status);
- void DidSetPaymentAppUserHint(ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
+ void DidSetPaymentAppUserHint(blink::ServiceWorkerStatusCode status);
// SetPaymentAppInfoForRegisteredServiceWorker callbacks.
void DidFindRegistrationToSetPaymentApp(
@@ -212,17 +212,17 @@ class CONTENT_EXPORT PaymentAppDatabase {
const std::string& icon,
const std::string& method,
SetPaymentAppInfoCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void DidWritePaymentAppForSetPaymentApp(
const std::string& instrument_key,
const std::string& method,
SetPaymentAppInfoCallback callback,
scoped_refptr<ServiceWorkerRegistration> registration,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void DidWritePaymentInstrumentForSetPaymentApp(
SetPaymentAppInfoCallback callback,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
base::WeakPtrFactory<PaymentAppDatabase> weak_ptr_factory_;
diff --git a/chromium/content/browser/payments/payment_app_info_fetcher.cc b/chromium/content/browser/payments/payment_app_info_fetcher.cc
index 7ffe9e44457..5ba89bcdda3 100644
--- a/chromium/content/browser/payments/payment_app_info_fetcher.cc
+++ b/chromium/content/browser/payments/payment_app_info_fetcher.cc
@@ -11,8 +11,8 @@
#include "content/browser/web_contents/web_contents_impl.h"
#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 "third_party/blink/public/common/manifest/manifest_icon_selector.h"
#include "ui/gfx/image/image.h"
#include "url/origin.h"
@@ -209,9 +209,9 @@ void PaymentAppInfoFetcher::SelfDeleteFetcher::FetchPaymentAppManifestCallback(
return;
}
- icon_url_ = ManifestIconSelector::FindBestMatchingIcon(
+ icon_url_ = blink::ManifestIconSelector::FindBestMatchingIcon(
manifest.icons, kPaymentAppIdealIconSize, kPaymentAppMinimumIconSize,
- blink::Manifest::Icon::ANY);
+ blink::Manifest::ImageResource::Purpose::ANY);
if (!icon_url_.is_valid()) {
WarnIfPossible(
"No suitable payment handler icon found in the \"icons\" field defined "
@@ -233,7 +233,7 @@ void PaymentAppInfoFetcher::SelfDeleteFetcher::FetchPaymentAppManifestCallback(
return;
}
- bool can_download = content::ManifestIconDownloader::Download(
+ bool can_download = ManifestIconDownloader::Download(
web_contents_helper_->web_contents(), icon_url_, kPaymentAppIdealIconSize,
kPaymentAppMinimumIconSize,
base::Bind(&PaymentAppInfoFetcher::SelfDeleteFetcher::OnIconFetched,
diff --git a/chromium/content/browser/payments/payment_app_provider_impl.cc b/chromium/content/browser/payments/payment_app_provider_impl.cc
index db44e03f061..3cfa0bde2bc 100644
--- a/chromium/content/browser/payments/payment_app_provider_impl.cc
+++ b/chromium/content/browser/payments/payment_app_provider_impl.cc
@@ -12,14 +12,14 @@
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/storage_partition_impl.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/permission_manager.h"
+#include "content/public/browser/permission_controller.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "mojo/public/mojom/base/time.mojom.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -30,7 +30,7 @@ namespace {
using ServiceWorkerStartCallback =
base::OnceCallback<void(scoped_refptr<ServiceWorkerVersion>,
- ServiceWorkerStatusCode)>;
+ blink::ServiceWorkerStatusCode)>;
class RespondWithCallbacks;
@@ -163,9 +163,9 @@ class RespondWithCallbacks
delete this;
}
- void OnErrorStatus(ServiceWorkerStatusCode service_worker_status) {
+ void OnErrorStatus(blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(service_worker_status != SERVICE_WORKER_OK);
+ DCHECK(service_worker_status != blink::ServiceWorkerStatusCode::kOk);
if (event_type_ == ServiceWorkerMetrics::EventType::PAYMENT_REQUEST) {
BrowserThread::PostTask(
@@ -194,7 +194,7 @@ class RespondWithCallbacks
service_worker_version_->FinishRequest(request_id_, false,
base::Time::Now());
- OnErrorStatus(SERVICE_WORKER_ERROR_ABORT);
+ OnErrorStatus(blink::ServiceWorkerStatusCode::kErrorAbort);
}
private:
@@ -249,10 +249,10 @@ void DispatchAbortPaymentEvent(
BrowserContext* browser_context,
PaymentAppProvider::PaymentEventResultCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (service_worker_status != SERVICE_WORKER_OK) {
+ if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(callback), false));
return;
@@ -268,8 +268,7 @@ void DispatchAbortPaymentEvent(
browser_context, ServiceWorkerMetrics::EventType::ABORT_PAYMENT,
active_version, std::move(callback));
- active_version->event_dispatcher()->DispatchAbortPaymentEvent(
- invocation_callbacks->request_id(),
+ active_version->endpoint()->DispatchAbortPaymentEvent(
invocation_callbacks->CreateInterfacePtrAndBind(),
active_version->CreateSimpleEventCallback(event_finish_id));
}
@@ -279,10 +278,10 @@ void DispatchCanMakePaymentEvent(
payments::mojom::CanMakePaymentEventDataPtr event_data,
PaymentAppProvider::PaymentEventResultCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (service_worker_status != SERVICE_WORKER_OK) {
+ if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(callback), false));
return;
@@ -298,9 +297,8 @@ void DispatchCanMakePaymentEvent(
browser_context, ServiceWorkerMetrics::EventType::CAN_MAKE_PAYMENT,
active_version, std::move(callback));
- active_version->event_dispatcher()->DispatchCanMakePaymentEvent(
- invocation_callbacks->request_id(), std::move(event_data),
- invocation_callbacks->CreateInterfacePtrAndBind(),
+ active_version->endpoint()->DispatchCanMakePaymentEvent(
+ std::move(event_data), invocation_callbacks->CreateInterfacePtrAndBind(),
active_version->CreateSimpleEventCallback(event_finish_id));
}
@@ -309,10 +307,10 @@ void DispatchPaymentRequestEvent(
payments::mojom::PaymentRequestEventDataPtr event_data,
PaymentAppProvider::InvokePaymentAppCallback callback,
scoped_refptr<ServiceWorkerVersion> active_version,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (service_worker_status != SERVICE_WORKER_OK) {
+ if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(callback),
@@ -330,19 +328,18 @@ void DispatchPaymentRequestEvent(
browser_context, ServiceWorkerMetrics::EventType::PAYMENT_REQUEST,
active_version, std::move(callback));
- active_version->event_dispatcher()->DispatchPaymentRequestEvent(
- invocation_callbacks->request_id(), std::move(event_data),
- invocation_callbacks->CreateInterfacePtrAndBind(),
+ active_version->endpoint()->DispatchPaymentRequestEvent(
+ std::move(event_data), invocation_callbacks->CreateInterfacePtrAndBind(),
active_version->CreateSimpleEventCallback(event_finish_id));
}
void DidFindRegistrationOnIO(
ServiceWorkerStartCallback callback,
- ServiceWorkerStatusCode service_worker_status,
+ blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (service_worker_status != SERVICE_WORKER_OK) {
+ if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(nullptr, service_worker_status);
return;
}
@@ -404,18 +401,15 @@ void CheckPermissionForPaymentApps(
PaymentAppProvider::PaymentApps apps) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- PermissionManager* permission_manager =
- browser_context->GetPermissionManager();
- if (!permission_manager) {
- std::move(callback).Run(PaymentAppProvider::PaymentApps());
- return;
- }
+ PermissionController* permission_controller =
+ BrowserContext::GetPermissionController(browser_context);
+ DCHECK(permission_controller);
PaymentAppProvider::PaymentApps permitted_apps;
for (auto& app : apps) {
GURL origin = app.second->scope.GetOrigin();
- if (permission_manager->GetPermissionStatus(PermissionType::PAYMENT_HANDLER,
- origin, origin) ==
+ if (permission_controller->GetPermissionStatus(
+ PermissionType::PAYMENT_HANDLER, origin, origin) ==
blink::mojom::PermissionStatus::GRANTED) {
permitted_apps[app.first] = std::move(app.second);
}
@@ -581,13 +575,15 @@ bool PaymentAppProviderImpl::IsValidInstallablePaymentApp(
DCHECK(manifest_url.is_valid() && sw_js_url.is_valid() &&
sw_scope.is_valid());
- // TODO(crbug.com/853924): Unify duplicated code between here and
- // ServiceWorkerProviderHost::IsValidRegisterMessage.
- if (ServiceWorkerUtils::ContainsDisallowedCharacter(sw_js_url, sw_scope,
- error_message)) {
+ // Scope will be checked against service worker js url when registering, but
+ // we check it here earlier to avoid presenting unusable payment handlers.
+ if (!ServiceWorkerUtils::IsPathRestrictionSatisfiedWithoutHeader(
+ sw_scope, sw_js_url, error_message)) {
return false;
}
+ // TODO(crbug.com/855312): Unify duplicated code between here and
+ // ServiceWorkerProviderHost::IsValidRegisterMessage.
std::vector<GURL> urls = {manifest_url, sw_js_url, sw_scope};
if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) {
*error_message =
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 6143488d152..4ed0f9bb1ad 100644
--- a/chromium/content/browser/payments/payment_app_provider_impl_unittest.cc
+++ b/chromium/content/browser/payments/payment_app_provider_impl_unittest.cc
@@ -65,7 +65,7 @@ class PaymentAppProviderTest : public PaymentAppContentUnitTestBase {
.WillByDefault(
testing::Return(blink::mojom::PermissionStatus::GRANTED));
static_cast<TestBrowserContext*>(browser_context())
- ->SetPermissionManager(std::move(mock_permission_manager));
+ ->SetPermissionControllerDelegate(std::move(mock_permission_manager));
}
~PaymentAppProviderTest() override {}
@@ -159,7 +159,7 @@ TEST_F(PaymentAppProviderTest, CanMakePaymentTest) {
payments::mojom::CanMakePaymentEventData::New();
payments::mojom::PaymentMethodDataPtr methodData =
payments::mojom::PaymentMethodData::New();
- methodData->supported_methods.push_back("test-method");
+ methodData->supported_method = "test-method";
event_data->method_data.push_back(std::move(methodData));
bool can_make_payment = false;
diff --git a/chromium/content/browser/payments/payment_instrument_icon_fetcher.cc b/chromium/content/browser/payments/payment_instrument_icon_fetcher.cc
index bfcb804f5d0..8ef0de4e991 100644
--- a/chromium/content/browser/payments/payment_instrument_icon_fetcher.cc
+++ b/chromium/content/browser/payments/payment_instrument_icon_fetcher.cc
@@ -11,7 +11,7 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/manifest_icon_downloader.h"
-#include "content/public/browser/manifest_icon_selector.h"
+#include "third_party/blink/public/common/manifest/manifest_icon_selector.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image.h"
@@ -28,13 +28,13 @@ const int kPaymentAppMinimumIconSize = 0;
void DownloadBestMatchingIcon(
WebContents* web_contents,
- const std::vector<blink::Manifest::Icon>& icons,
+ const std::vector<blink::Manifest::ImageResource>& icons,
PaymentInstrumentIconFetcher::PaymentInstrumentIconFetcherCallback
callback);
void OnIconFetched(
WebContents* web_contents,
- const std::vector<blink::Manifest::Icon>& icons,
+ const std::vector<blink::Manifest::ImageResource>& icons,
PaymentInstrumentIconFetcher::PaymentInstrumentIconFetcherCallback callback,
const SkBitmap& bitmap) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -64,14 +64,14 @@ void OnIconFetched(
void DownloadBestMatchingIcon(
WebContents* web_contents,
- const std::vector<blink::Manifest::Icon>& icons,
+ const std::vector<blink::Manifest::ImageResource>& icons,
PaymentInstrumentIconFetcher::PaymentInstrumentIconFetcherCallback
callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- GURL icon_url = ManifestIconSelector::FindBestMatchingIcon(
+ GURL icon_url = blink::ManifestIconSelector::FindBestMatchingIcon(
icons, kPaymentAppIdealIconSize, kPaymentAppMinimumIconSize,
- blink::Manifest::Icon::IconPurpose::ANY);
+ blink::Manifest::ImageResource::Purpose::ANY);
if (web_contents == nullptr || !icon_url.is_valid()) {
// If the icon url is invalid, it's better to give the information to
// developers in advance unlike when fetching or decoding fails. We already
@@ -82,7 +82,7 @@ void DownloadBestMatchingIcon(
return;
}
- std::vector<blink::Manifest::Icon> copy_icons;
+ std::vector<blink::Manifest::ImageResource> copy_icons;
for (const auto& icon : icons) {
if (icon.src != icon_url) {
copy_icons.emplace_back(icon);
@@ -123,7 +123,7 @@ WebContents* GetWebContentsFromProviderHostIds(
void StartOnUI(
const GURL& scope,
std::unique_ptr<std::vector<std::pair<int, int>>> provider_hosts,
- const std::vector<blink::Manifest::Icon>& icons,
+ const std::vector<blink::Manifest::ImageResource>& icons,
PaymentInstrumentIconFetcher::PaymentInstrumentIconFetcherCallback
callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -139,7 +139,7 @@ void StartOnUI(
void PaymentInstrumentIconFetcher::Start(
const GURL& scope,
std::unique_ptr<std::vector<std::pair<int, int>>> provider_hosts,
- const std::vector<blink::Manifest::Icon>& icons,
+ const std::vector<blink::Manifest::ImageResource>& icons,
PaymentInstrumentIconFetcherCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
diff --git a/chromium/content/browser/payments/payment_instrument_icon_fetcher.h b/chromium/content/browser/payments/payment_instrument_icon_fetcher.h
index e3c5f8e608d..c31d531fcc7 100644
--- a/chromium/content/browser/payments/payment_instrument_icon_fetcher.h
+++ b/chromium/content/browser/payments/payment_instrument_icon_fetcher.h
@@ -25,7 +25,7 @@ class PaymentInstrumentIconFetcher {
static void Start(
const GURL& scope,
std::unique_ptr<std::vector<std::pair<int, int>>> provider_hosts,
- const std::vector<blink::Manifest::Icon>& icons,
+ const std::vector<blink::Manifest::ImageResource>& icons,
PaymentInstrumentIconFetcherCallback callback);
private:
diff --git a/chromium/content/browser/performance_memory_browsertest.cc b/chromium/content/browser/performance_memory_browsertest.cc
new file mode 100644
index 00000000000..f4872b252b3
--- /dev/null
+++ b/chromium/content/browser/performance_memory_browsertest.cc
@@ -0,0 +1,56 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/frame_host/frame_tree.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/web_contents.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/content_browser_test_utils_internal.h"
+#include "net/dns/mock_host_resolver.h"
+
+namespace content {
+
+class PerformanceMemoryBrowserTest : public ContentBrowserTest {
+ public:
+ PerformanceMemoryBrowserTest() {}
+
+ protected:
+ void SetUpOnMainThread() override {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ SetupCrossSiteRedirector(embedded_test_server());
+ ASSERT_TRUE(embedded_test_server()->Start());
+ }
+};
+
+// Verify that performance.memory is not bucketized when sites are isolated for
+// testing, and that it is bucketized when they are not.
+IN_PROC_BROWSER_TEST_F(PerformanceMemoryBrowserTest, PerformanceMemory) {
+ GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ WebContents* contents = shell()->web_contents();
+ FrameTreeNode* root =
+ static_cast<WebContentsImpl*>(contents)->GetFrameTree()->root();
+ int usedJSHeapSize = -1;
+ EXPECT_TRUE(ExecuteScriptAndExtractInt(
+ root,
+ "window.domAutomationController.send(performance.memory.usedJSHeapSize);",
+ &usedJSHeapSize));
+
+ EXPECT_GE(usedJSHeapSize, 0);
+ // There is no explicit way to check if the memory values are bucketized or
+ // not. As in third_party/blink/renderer/core/timing/memory_info_test.cc,
+ // check that the value mod 100000 is non-zero to verify that it is
+ // not bucketized. This should be the case when the renderer process is locked
+ // to a site (i.e. scheme plus eTLD+1).
+ if (AreAllSitesIsolatedForTesting())
+ EXPECT_NE(0, usedJSHeapSize % 100000);
+ else
+ EXPECT_EQ(0, usedJSHeapSize % 100000);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/permissions/permission_controller_impl.cc b/chromium/content/browser/permissions/permission_controller_impl.cc
new file mode 100644
index 00000000000..75ccdf0efb4
--- /dev/null
+++ b/chromium/content/browser/permissions/permission_controller_impl.cc
@@ -0,0 +1,126 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_PERMISSIONS_PERMISSION_CONTROLLER_IMPL_CC_
+#define CONTENT_BROWSER_PERMISSIONS_PERMISSION_CONTROLLER_IMPL_CC_
+
+#include "content/browser/permissions/permission_controller_impl.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/permission_controller_delegate.h"
+#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
+
+class GURL;
+
+namespace content {
+
+PermissionControllerImpl::PermissionControllerImpl(
+ BrowserContext* browser_context)
+ : browser_context_(browser_context) {}
+
+// static
+PermissionControllerImpl* PermissionControllerImpl::FromBrowserContext(
+ BrowserContext* browser_context) {
+ return static_cast<PermissionControllerImpl*>(
+ BrowserContext::GetPermissionController(browser_context));
+}
+
+PermissionControllerImpl::~PermissionControllerImpl() = default;
+
+int PermissionControllerImpl::RequestPermission(
+ PermissionType permission,
+ RenderFrameHost* render_frame_host,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+ PermissionControllerDelegate* delegate =
+ browser_context_->GetPermissionControllerDelegate();
+ if (!delegate) {
+ callback.Run(blink::mojom::PermissionStatus::DENIED);
+ return kNoPendingOperation;
+ }
+ return delegate->RequestPermission(permission, render_frame_host,
+ requesting_origin, user_gesture, callback);
+}
+
+int PermissionControllerImpl::RequestPermissions(
+ const std::vector<PermissionType>& permissions,
+ RenderFrameHost* render_frame_host,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ const base::Callback<
+ void(const std::vector<blink::mojom::PermissionStatus>&)>& callback) {
+ PermissionControllerDelegate* delegate =
+ browser_context_->GetPermissionControllerDelegate();
+ if (!delegate) {
+ std::vector<blink::mojom::PermissionStatus> result(
+ permissions.size(), blink::mojom::PermissionStatus::DENIED);
+ callback.Run(result);
+ return kNoPendingOperation;
+ }
+ return delegate->RequestPermissions(permissions, render_frame_host,
+ requesting_origin, user_gesture,
+ callback);
+}
+
+blink::mojom::PermissionStatus PermissionControllerImpl::GetPermissionStatus(
+ PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin) {
+ PermissionControllerDelegate* delegate =
+ browser_context_->GetPermissionControllerDelegate();
+ if (!delegate)
+ return blink::mojom::PermissionStatus::DENIED;
+ return delegate->GetPermissionStatus(permission, requesting_origin,
+ embedding_origin);
+}
+
+blink::mojom::PermissionStatus
+PermissionControllerImpl::GetPermissionStatusForFrame(
+ PermissionType permission,
+ RenderFrameHost* render_frame_host,
+ const GURL& requesting_origin) {
+ PermissionControllerDelegate* delegate =
+ browser_context_->GetPermissionControllerDelegate();
+ if (!delegate)
+ return blink::mojom::PermissionStatus::DENIED;
+ return delegate->GetPermissionStatusForFrame(permission, render_frame_host,
+ requesting_origin);
+}
+
+void PermissionControllerImpl::ResetPermission(PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin) {
+ PermissionControllerDelegate* delegate =
+ browser_context_->GetPermissionControllerDelegate();
+ if (!delegate)
+ return;
+ delegate->ResetPermission(permission, requesting_origin, embedding_origin);
+}
+
+int PermissionControllerImpl::SubscribePermissionStatusChange(
+ PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin,
+ const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+ PermissionControllerDelegate* delegate =
+ browser_context_->GetPermissionControllerDelegate();
+ if (!delegate)
+ return kNoPendingOperation;
+ return delegate->SubscribePermissionStatusChange(
+ permission, requesting_origin, embedding_origin, callback);
+}
+
+void PermissionControllerImpl::UnsubscribePermissionStatusChange(
+ int subscription_id) {
+ PermissionControllerDelegate* delegate =
+ browser_context_->GetPermissionControllerDelegate();
+ if (!delegate)
+ return;
+ delegate->UnsubscribePermissionStatusChange(subscription_id);
+}
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_PERMISSIONS_PERMISSION_CONTROLLER_IMPL_CC_
diff --git a/chromium/content/browser/permissions/permission_controller_impl.h b/chromium/content/browser/permissions/permission_controller_impl.h
new file mode 100644
index 00000000000..460f033513a
--- /dev/null
+++ b/chromium/content/browser/permissions/permission_controller_impl.h
@@ -0,0 +1,72 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_PERMISSIONS_PERMISSION_CONTROLLER_IMPL_H_
+#define CONTENT_BROWSER_PERMISSIONS_PERMISSION_CONTROLLER_IMPL_H_
+
+#include "content/common/content_export.h"
+#include "content/public/browser/permission_controller.h"
+
+namespace content {
+
+class BrowserContext;
+
+// Implementation of the PermissionController interface. This
+// is used by content/ layer to manage permissions.
+// There is one instance of this class per BrowserContext.
+class CONTENT_EXPORT PermissionControllerImpl : public PermissionController {
+ public:
+ explicit PermissionControllerImpl(BrowserContext* browser_context);
+ ~PermissionControllerImpl() override;
+
+ static PermissionControllerImpl* FromBrowserContext(
+ BrowserContext* browser_context);
+
+ // PermissionController implementation.
+ blink::mojom::PermissionStatus GetPermissionStatus(
+ PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin) override;
+
+ blink::mojom::PermissionStatus GetPermissionStatusForFrame(
+ PermissionType permission,
+ RenderFrameHost* render_frame_host,
+ const GURL& requesting_origin) override;
+
+ int RequestPermission(
+ PermissionType permission,
+ RenderFrameHost* render_frame_host,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ const base::Callback<void(blink::mojom::PermissionStatus)>& callback);
+
+ int RequestPermissions(
+ const std::vector<PermissionType>& permission,
+ RenderFrameHost* render_frame_host,
+ const GURL& requesting_origin,
+ bool user_gesture,
+ const base::Callback<
+ void(const std::vector<blink::mojom::PermissionStatus>&)>& callback);
+
+ void ResetPermission(PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin);
+
+ int SubscribePermissionStatusChange(
+ PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin,
+ const base::Callback<void(blink::mojom::PermissionStatus)>& callback);
+
+ void UnsubscribePermissionStatusChange(int subscription_id);
+
+ private:
+ BrowserContext* browser_context_;
+
+ DISALLOW_COPY_AND_ASSIGN(PermissionControllerImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_PERMISSIONS_PERMISSION_CONTROLLER_IMPL_H_
diff --git a/chromium/content/browser/permissions/permission_service_context.cc b/chromium/content/browser/permissions/permission_service_context.cc
index e115a1a959d..05cd21bd9ec 100644
--- a/chromium/content/browser/permissions/permission_service_context.cc
+++ b/chromium/content/browser/permissions/permission_service_context.cc
@@ -6,10 +6,11 @@
#include <utility>
+#include "content/browser/permissions/permission_controller_impl.h"
#include "content/browser/permissions/permission_service_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_handle.h"
-#include "content/public/browser/permission_manager.h"
+#include "content/public/browser/permission_controller.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
@@ -30,8 +31,8 @@ class PermissionServiceContext::PermissionSubscription {
~PermissionSubscription() {
DCHECK_NE(id_, 0);
BrowserContext* browser_context = context_->GetBrowserContext();
- if (browser_context && browser_context->GetPermissionManager()) {
- browser_context->GetPermissionManager()
+ if (browser_context) {
+ PermissionControllerImpl::FromBrowserContext(browser_context)
->UnsubscribePermissionStatusChange(id_);
}
}
@@ -90,7 +91,7 @@ void PermissionServiceContext::CreateSubscription(
const url::Origin& origin,
PermissionObserverPtr observer) {
BrowserContext* browser_context = GetBrowserContext();
- if (!browser_context || !browser_context->GetPermissionManager())
+ if (!browser_context)
return;
auto subscription =
@@ -98,12 +99,15 @@ void PermissionServiceContext::CreateSubscription(
GURL requesting_origin(origin.Serialize());
GURL embedding_origin = GetEmbeddingOrigin();
int subscription_id =
- browser_context->GetPermissionManager()->SubscribePermissionStatusChange(
- permission_type, requesting_origin,
- // If the embedding_origin is empty, we'll use the |origin| instead.
- embedding_origin.is_empty() ? requesting_origin : embedding_origin,
- base::Bind(&PermissionSubscription::OnPermissionStatusChanged,
- base::Unretained(subscription.get())));
+ PermissionControllerImpl::FromBrowserContext(browser_context)
+ ->SubscribePermissionStatusChange(
+ permission_type, requesting_origin,
+ // If the embedding_origin is empty, we'll use the |origin|
+ // instead.
+ embedding_origin.is_empty() ? requesting_origin
+ : embedding_origin,
+ base::Bind(&PermissionSubscription::OnPermissionStatusChanged,
+ base::Unretained(subscription.get())));
subscription->set_id(subscription_id);
subscriptions_[subscription_id] = std::move(subscription);
}
diff --git a/chromium/content/browser/permissions/permission_service_impl.cc b/chromium/content/browser/permissions/permission_service_impl.cc
index 4c86c799dc9..f84599df41c 100644
--- a/chromium/content/browser/permissions/permission_service_impl.cc
+++ b/chromium/content/browser/permissions/permission_service_impl.cc
@@ -14,8 +14,8 @@
#include "base/memory/ptr_util.h"
#include "build/build_config.h"
#include "content/browser/bad_message.h"
+#include "content/browser/permissions/permission_controller_impl.h"
#include "content/public/browser/browser_context.h"
-#include "content/public/browser/permission_manager.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/render_frame_host.h"
@@ -121,7 +121,7 @@ class PermissionServiceImpl::PendingRequest {
}
private:
- // Request ID received from the PermissionManager.
+ // Request ID received from the PermissionController.
int id_;
RequestPermissionsCallback callback_;
size_t request_size_;
@@ -159,8 +159,7 @@ void PermissionServiceImpl::RequestPermissions(
if (!browser_context)
return;
- if (!context_->render_frame_host() ||
- !browser_context->GetPermissionManager()) {
+ if (!context_->render_frame_host()) {
std::vector<PermissionStatus> result(permissions.size());
for (size_t i = 0; i < permissions.size(); ++i)
result[i] = GetPermissionStatus(permissions[i]);
@@ -187,10 +186,13 @@ void PermissionServiceImpl::RequestPermissions(
std::make_unique<PendingRequest>(types, std::move(callback));
int pending_request_id = pending_requests_.Add(std::move(pending_request));
- int id = browser_context->GetPermissionManager()->RequestPermissions(
- types, context_->render_frame_host(), origin_.GetURL(), user_gesture,
- base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse,
- weak_factory_.GetWeakPtr(), pending_request_id));
+ int id =
+ PermissionControllerImpl::FromBrowserContext(browser_context)
+ ->RequestPermissions(
+ types, context_->render_frame_host(), origin_.GetURL(),
+ user_gesture,
+ base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse,
+ weak_factory_.GetWeakPtr(), pending_request_id));
// Check if the request still exists. It may have been removed by the
// the response callback.
@@ -271,18 +273,16 @@ PermissionStatus PermissionServiceImpl::GetPermissionStatusFromType(
if (!browser_context)
return PermissionStatus::DENIED;
- if (!browser_context->GetPermissionManager())
- return PermissionStatus::DENIED;
-
GURL requesting_origin(origin_.GetURL());
if (context_->render_frame_host()) {
- return browser_context->GetPermissionManager()->GetPermissionStatusForFrame(
- type, context_->render_frame_host(), requesting_origin);
+ return BrowserContext::GetPermissionController(browser_context)
+ ->GetPermissionStatusForFrame(type, context_->render_frame_host(),
+ requesting_origin);
}
DCHECK(context_->GetEmbeddingOrigin().is_empty());
- return browser_context->GetPermissionManager()->GetPermissionStatus(
- type, requesting_origin, requesting_origin);
+ return BrowserContext::GetPermissionController(browser_context)
+ ->GetPermissionStatus(type, requesting_origin, requesting_origin);
}
void PermissionServiceImpl::ResetPermissionStatus(PermissionType type) {
@@ -290,15 +290,13 @@ void PermissionServiceImpl::ResetPermissionStatus(PermissionType type) {
if (!browser_context)
return;
- if (!browser_context->GetPermissionManager())
- return;
-
GURL requesting_origin(origin_.GetURL());
// If the embedding_origin is empty we'll use |origin_| instead.
GURL embedding_origin = context_->GetEmbeddingOrigin();
- browser_context->GetPermissionManager()->ResetPermission(
- type, requesting_origin,
- embedding_origin.is_empty() ? requesting_origin : embedding_origin);
+ PermissionControllerImpl::FromBrowserContext(browser_context)
+ ->ResetPermission(
+ type, requesting_origin,
+ embedding_origin.is_empty() ? requesting_origin : embedding_origin);
}
void PermissionServiceImpl::ReceivedBadMessage() {
diff --git a/chromium/content/browser/picture_in_picture/overlay_surface_embedder.cc b/chromium/content/browser/picture_in_picture/overlay_surface_embedder.cc
index 5e8617b1ddf..412d8895b63 100644
--- a/chromium/content/browser/picture_in_picture/overlay_surface_embedder.cc
+++ b/chromium/content/browser/picture_in_picture/overlay_surface_embedder.cc
@@ -11,6 +11,15 @@ namespace content {
OverlaySurfaceEmbedder::OverlaySurfaceEmbedder(OverlayWindow* window)
: window_(window) {
DCHECK(window_);
+ // Add window background.
+ window_background_layer_ = window_->GetWindowBackgroundLayer();
+ window_background_layer_->SetBounds(
+ gfx::Rect(gfx::Point(0, 0), window_->GetBounds().size()));
+
+ // Add |window_background_layer_| to |window_| and stack it at the bottom.
+ window_->GetLayer()->Add(window_background_layer_);
+ window_->GetLayer()->StackAtBottom(window_background_layer_);
+
video_layer_ = window_->GetVideoLayer();
video_layer_->SetMasksToBounds(true);
@@ -21,55 +30,35 @@ OverlaySurfaceEmbedder::OverlaySurfaceEmbedder(OverlayWindow* window)
// positioning of |window_| is dictated by itself.
video_layer_->SetBounds(
gfx::Rect(gfx::Point(0, 0), window_->GetBounds().size()));
- window_->GetLayer()->Add(video_layer_);
- AddControlsLayers();
+ // Add |video_layer_| to |window_| and stack it above
+ // |window_background_layer_|.
+ window_->GetLayer()->Add(video_layer_);
+ window_->GetLayer()->StackAbove(video_layer_, window_background_layer_);
}
OverlaySurfaceEmbedder::~OverlaySurfaceEmbedder() = default;
-void OverlaySurfaceEmbedder::SetPrimarySurfaceId(
- const viz::SurfaceId& surface_id) {
+void OverlaySurfaceEmbedder::SetSurfaceId(const viz::SurfaceId& surface_id) {
+ video_layer_ = window_->GetVideoLayer();
// SurfaceInfo has information about the embedded surface.
video_layer_->SetShowPrimarySurface(
surface_id, window_->GetBounds().size(), SK_ColorBLACK,
cc::DeadlinePolicy::UseDefaultDeadline(),
true /* stretch_content_to_fill_bounds */);
+ video_layer_->SetFallbackSurfaceId(surface_id);
}
void OverlaySurfaceEmbedder::UpdateLayerBounds() {
- // Update the size and position of the video to stretch on the entire window.
- gfx::Size window_size = window_->GetBounds().size();
- gfx::Rect window_bounds = gfx::Rect(gfx::Point(0, 0), window_size);
- video_layer_->SetBounds(window_bounds);
- video_layer_->SetSurfaceSize(window_size);
-
- // Update the size and position of controls.
- controls_background_layer_->SetBounds(window_bounds);
- close_controls_layer_->SetBounds(window_->GetCloseControlsBounds());
- play_pause_controls_layer_->SetBounds(window_->GetPlayPauseControlsBounds());
-}
-
-void OverlaySurfaceEmbedder::AddControlsLayers() {
- // These control layers are expected to be set up by |window_|.
- controls_background_layer_ = window_->GetControlsBackgroundLayer();
- DCHECK(controls_background_layer_);
- controls_background_layer_->SetBounds(
+ // Update the size of window background.
+ window_background_layer_ = window_->GetWindowBackgroundLayer();
+ window_background_layer_->SetBounds(
gfx::Rect(gfx::Point(0, 0), window_->GetBounds().size()));
- close_controls_layer_ = window_->GetCloseControlsLayer();
- DCHECK(close_controls_layer_);
- close_controls_layer_->SetFillsBoundsOpaquely(false);
- close_controls_layer_->SetBounds(window_->GetCloseControlsBounds());
-
- play_pause_controls_layer_ = window_->GetPlayPauseControlsLayer();
- DCHECK(play_pause_controls_layer_);
- play_pause_controls_layer_->SetFillsBoundsOpaquely(false);
- play_pause_controls_layer_->SetBounds(window_->GetPlayPauseControlsBounds());
-
- window_->GetLayer()->Add(controls_background_layer_);
- window_->GetLayer()->Add(close_controls_layer_);
- window_->GetLayer()->Add(play_pause_controls_layer_);
+ // Update the size and position of the video to stretch on the entire window.
+ video_layer_ = window_->GetVideoLayer();
+ video_layer_->SetBounds(window_->GetVideoBounds());
+ video_layer_->SetSurfaceSize(window_->GetVideoBounds().size());
}
} // namespace content
diff --git a/chromium/content/browser/picture_in_picture/overlay_surface_embedder.h b/chromium/content/browser/picture_in_picture/overlay_surface_embedder.h
index dd0f277dc6d..9307f38e8d8 100644
--- a/chromium/content/browser/picture_in_picture/overlay_surface_embedder.h
+++ b/chromium/content/browser/picture_in_picture/overlay_surface_embedder.h
@@ -23,9 +23,8 @@ class OverlaySurfaceEmbedder {
explicit OverlaySurfaceEmbedder(OverlayWindow* window);
~OverlaySurfaceEmbedder();
- void SetPrimarySurfaceId(const viz::SurfaceId& surface_id);
+ void SetSurfaceId(const viz::SurfaceId&);
void UpdateLayerBounds();
- void AddControlsLayers();
private:
// The window which embeds the client. Weak pointer since the
@@ -36,11 +35,9 @@ class OverlaySurfaceEmbedder {
std::unique_ptr<ui::Layer> surface_layer_;
// Owned by the OverlayWindow implementation.
- // These are set in AddControlsLayer(), which is called in the constructor.
+ // These are set in the constructor.
+ ui::Layer* window_background_layer_ = nullptr;
ui::Layer* video_layer_ = nullptr;
- ui::Layer* controls_background_layer_ = nullptr;
- ui::Layer* close_controls_layer_ = nullptr;
- ui::Layer* play_pause_controls_layer_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(OverlaySurfaceEmbedder);
};
diff --git a/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
index f0835214f02..fcb1e96e6cd 100644
--- a/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
+++ b/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -48,7 +48,7 @@ PictureInPictureWindowControllerImpl::~PictureInPictureWindowControllerImpl() {
return;
initiator_->SetHasPictureInPictureVideo(false);
- OnLeavingPictureInPicture();
+ OnLeavingPictureInPicture(true /* should_pause_video */);
}
PictureInPictureWindowControllerImpl::PictureInPictureWindowControllerImpl(
@@ -58,8 +58,7 @@ PictureInPictureWindowControllerImpl::PictureInPictureWindowControllerImpl(
media_web_contents_observer_ = initiator_->media_web_contents_observer();
- window_ =
- GetContentClient()->browser()->CreateWindowForPictureInPicture(this);
+ EnsureWindow();
DCHECK(window_) << "Picture in Picture requires a valid window.";
}
@@ -73,21 +72,36 @@ gfx::Size PictureInPictureWindowControllerImpl::Show() {
return window_->GetBounds().size();
}
-void PictureInPictureWindowControllerImpl::Close() {
+void PictureInPictureWindowControllerImpl::ClickCustomControl(
+ const std::string& control_id) {
DCHECK(window_);
- window_->Hide();
- initiator_->SetHasPictureInPictureVideo(false);
+ media_player_id_->render_frame_host->Send(
+ new MediaPlayerDelegateMsg_ClickPictureInPictureControl(
+ media_player_id_->render_frame_host->GetRoutingID(),
+ media_player_id_->delegate_id, control_id));
+}
- surface_id_ = viz::SurfaceId();
+void PictureInPictureWindowControllerImpl::Close(bool should_pause_video) {
+ if (!window_ || !window_->IsVisible())
+ return;
+
+ window_->Hide();
+ CloseInternal(should_pause_video);
+}
- OnLeavingPictureInPicture();
+void PictureInPictureWindowControllerImpl::OnWindowDestroyed() {
+ window_ = nullptr;
+ embedder_ = nullptr;
+ CloseInternal(true /* should_pause_video */);
}
void PictureInPictureWindowControllerImpl::EmbedSurface(
const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) {
+ EnsureWindow();
DCHECK(window_);
+
DCHECK(surface_id.is_valid());
surface_id_ = surface_id;
@@ -97,12 +111,13 @@ void PictureInPictureWindowControllerImpl::EmbedSurface(
// |initiator_| enters Picture-in-Picture mode.
media_player_id_ =
media_web_contents_observer_->GetPictureInPictureVideoMediaPlayerId();
+ UpdatePlaybackState(IsPlayerActive(), !media_player_id_.has_value());
window_->UpdateVideoSize(natural_size);
if (!embedder_)
embedder_.reset(new OverlaySurfaceEmbedder(window_.get()));
- embedder_->SetPrimarySurfaceId(surface_id_);
+ embedder_->SetSurfaceId(surface_id_);
}
OverlayWindow* PictureInPictureWindowControllerImpl::GetWindowForTesting() {
@@ -110,7 +125,7 @@ OverlayWindow* PictureInPictureWindowControllerImpl::GetWindowForTesting() {
}
void PictureInPictureWindowControllerImpl::UpdateLayerBounds() {
- if (window_) {
+ if (window_ && window_->IsVisible()) {
media_web_contents_observer_->OnPictureInPictureWindowResize(
window_->GetBounds().size());
}
@@ -120,8 +135,10 @@ void PictureInPictureWindowControllerImpl::UpdateLayerBounds() {
}
bool PictureInPictureWindowControllerImpl::IsPlayerActive() {
- if (!media_player_id_.has_value())
- media_web_contents_observer_->GetPictureInPictureVideoMediaPlayerId();
+ if (!media_player_id_.has_value()) {
+ media_player_id_ =
+ media_web_contents_observer_->GetPictureInPictureVideoMediaPlayerId();
+ }
return media_player_id_.has_value() &&
media_web_contents_observer_->IsPlayerActive(*media_player_id_);
@@ -131,30 +148,72 @@ WebContents* PictureInPictureWindowControllerImpl::GetInitiatorWebContents() {
return initiator_;
}
+void PictureInPictureWindowControllerImpl::UpdatePlaybackState(
+ bool is_playing,
+ bool reached_end_of_stream) {
+ if (!window_)
+ return;
+
+ if (reached_end_of_stream) {
+ media_player_id_.reset();
+ window_->SetPlaybackState(OverlayWindow::PlaybackState::kNoVideo);
+ return;
+ }
+
+ DCHECK(media_player_id_.has_value());
+
+ window_->SetPlaybackState(is_playing ? OverlayWindow::PlaybackState::kPlaying
+ : OverlayWindow::PlaybackState::kPaused);
+}
+
bool PictureInPictureWindowControllerImpl::TogglePlayPause() {
DCHECK(window_ && window_->IsActive());
if (IsPlayerActive()) {
- media_player_id_->first->Send(new MediaPlayerDelegateMsg_Pause(
- media_player_id_->first->GetRoutingID(), media_player_id_->second));
+ media_player_id_->render_frame_host->Send(new MediaPlayerDelegateMsg_Pause(
+ media_player_id_->render_frame_host->GetRoutingID(),
+ media_player_id_->delegate_id));
return false;
}
- media_player_id_->first->Send(new MediaPlayerDelegateMsg_Play(
- media_player_id_->first->GetRoutingID(), media_player_id_->second));
+ media_player_id_->render_frame_host->Send(new MediaPlayerDelegateMsg_Play(
+ media_player_id_->render_frame_host->GetRoutingID(),
+ media_player_id_->delegate_id));
return true;
}
-void PictureInPictureWindowControllerImpl::OnLeavingPictureInPicture() {
- if (IsPlayerActive()) {
+void PictureInPictureWindowControllerImpl::OnLeavingPictureInPicture(
+ bool should_pause_video) {
+ if (IsPlayerActive() && should_pause_video) {
// Pause the current video so there is only one video playing at a time.
- media_player_id_->first->Send(new MediaPlayerDelegateMsg_Pause(
- media_player_id_->first->GetRoutingID(), media_player_id_->second));
+ media_player_id_->render_frame_host->Send(new MediaPlayerDelegateMsg_Pause(
+ media_player_id_->render_frame_host->GetRoutingID(),
+ media_player_id_->delegate_id));
}
- media_player_id_->first->Send(
- new MediaPlayerDelegateMsg_EndPictureInPictureMode(
- media_player_id_->first->GetRoutingID(), media_player_id_->second));
+ if (media_player_id_.has_value()) {
+ media_player_id_->render_frame_host->Send(
+ new MediaPlayerDelegateMsg_EndPictureInPictureMode(
+ media_player_id_->render_frame_host->GetRoutingID(),
+ media_player_id_->delegate_id));
+ }
+}
+
+void PictureInPictureWindowControllerImpl::CloseInternal(
+ bool should_pause_video) {
+ initiator_->SetHasPictureInPictureVideo(false);
+
+ surface_id_ = viz::SurfaceId();
+
+ OnLeavingPictureInPicture(should_pause_video);
+}
+
+void PictureInPictureWindowControllerImpl::EnsureWindow() {
+ if (window_)
+ return;
+
+ window_ =
+ GetContentClient()->browser()->CreateWindowForPictureInPicture(this);
}
} // namespace content
diff --git a/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h b/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h
index 7a960800ec2..7ce6d853fc4 100644
--- a/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h
+++ b/chromium/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.h
@@ -35,7 +35,10 @@ class PictureInPictureWindowControllerImpl
// PictureInPictureWindowController:
CONTENT_EXPORT gfx::Size Show() override;
- CONTENT_EXPORT void Close() override;
+ CONTENT_EXPORT void Close(bool should_pause_video) override;
+ CONTENT_EXPORT void OnWindowDestroyed() override;
+ CONTENT_EXPORT void ClickCustomControl(
+ const std::string& control_id) override;
CONTENT_EXPORT void EmbedSurface(const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) override;
CONTENT_EXPORT OverlayWindow* GetWindowForTesting() override;
@@ -43,6 +46,8 @@ class PictureInPictureWindowControllerImpl
CONTENT_EXPORT bool IsPlayerActive() override;
CONTENT_EXPORT WebContents* GetInitiatorWebContents() override;
CONTENT_EXPORT bool TogglePlayPause() override;
+ CONTENT_EXPORT void UpdatePlaybackState(bool is_playing,
+ bool reached_end_of_stream) override;
private:
friend class WebContentsUserData<PictureInPictureWindowControllerImpl>;
@@ -53,7 +58,15 @@ class PictureInPictureWindowControllerImpl
WebContents* initiator);
// Signal to the media player that |this| is leaving Picture-in-Picture mode.
- void OnLeavingPictureInPicture();
+ void OnLeavingPictureInPicture(bool should_pause_video);
+
+ // Internal method to set the states after the window was closed, whether via
+ // the system or Chromium.
+ void CloseInternal(bool should_pause_video);
+
+ // Creates a new window if the previous one was destroyed. It can happen
+ // because of the system control of the window.
+ void EnsureWindow();
std::unique_ptr<OverlayWindow> window_;
std::unique_ptr<OverlaySurfaceEmbedder> embedder_;
diff --git a/chromium/content/browser/plugin_service_impl.cc b/chromium/content/browser/plugin_service_impl.cc
index dcdae19642b..e4e5a87af7e 100644
--- a/chromium/content/browser/plugin_service_impl.cc
+++ b/chromium/content/browser/plugin_service_impl.cc
@@ -25,6 +25,7 @@
#include "content/browser/ppapi_plugin_process_host.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/content_switches_internal.h"
#include "content/common/pepper_plugin_list.h"
#include "content/common/plugin_list.h"
@@ -65,13 +66,12 @@ void WillLoadPluginsCallback(base::SequenceChecker* sequence_checker) {
// static
void PluginServiceImpl::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);
+ ukm::SourceId source_id = static_cast<WebContentsImpl*>(web_contents)
+ ->GetUkmSourceIdForLastCommittedSource();
+ ukm::builders::Pepper_Broker(source_id).Record(ukm::UkmRecorder::Get());
}
}
diff --git a/chromium/content/browser/plugin_service_impl_unittest.cc b/chromium/content/browser/plugin_service_impl_unittest.cc
index 72022dd1436..ed9ec8c472b 100644
--- a/chromium/content/browser/plugin_service_impl_unittest.cc
+++ b/chromium/content/browser/plugin_service_impl_unittest.cc
@@ -10,6 +10,7 @@
#include "components/ukm/test_ukm_recorder.h"
#include "components/ukm/ukm_source.h"
#include "content/browser/ppapi_plugin_process_host.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
@@ -50,16 +51,18 @@ class PluginServiceImplTest : public RenderViewHostTestHarness {
test_ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
}
- bool RecordedBrokerEvent(const GURL& url) {
+ // Check if count events were recorded and if they were all recorded with
+ // the specified source_id.
+ bool RecordedBrokerEvents(ukm::SourceId source_id, size_t count) {
RunAllPendingInMessageLoop(BrowserThread::UI);
auto entries = test_ukm_recorder_->GetEntriesByName(kPepperBrokerEvent);
+ if (entries.size() != count)
+ return false;
for (const auto* const entry : entries) {
- const ukm::UkmSource* source =
- test_ukm_recorder_->GetSourceForSourceId(entry->source_id);
- if (source && source->url() == url)
- return true;
+ if (entry->source_id != source_id)
+ return false;
}
- return false;
+ return true;
}
void ResetUKM() {
@@ -76,20 +79,21 @@ TEST_F(PluginServiceImplTest, RecordBrokerUsage) {
TestBrokerClient client;
NavigateAndCommit(GURL(kURL1));
+ ukm::SourceId source_id = static_cast<WebContentsImpl*>(web_contents())
+ ->GetUkmSourceIdForLastCommittedSource();
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)));
+ EXPECT_TRUE(RecordedBrokerEvents(source_id, 0));
// 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)));
+ EXPECT_TRUE(RecordedBrokerEvents(source_id, 1));
ResetUKM();
@@ -103,8 +107,7 @@ TEST_F(PluginServiceImplTest, RecordBrokerUsage) {
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)));
+ EXPECT_TRUE(RecordedBrokerEvents(source_id, 1));
}
} // namespace content
diff --git a/chromium/content/browser/pointer_lock_browsertest.cc b/chromium/content/browser/pointer_lock_browsertest.cc
index 1e547b71308..b4f10231ad3 100644
--- a/chromium/content/browser/pointer_lock_browsertest.cc
+++ b/chromium/content/browser/pointer_lock_browsertest.cc
@@ -12,6 +12,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/hit_test_region_observer.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
@@ -25,32 +26,45 @@
namespace content {
-namespace {
+class MockPointerLockWebContentsDelegate : public WebContentsDelegate {
+ public:
+ MockPointerLockWebContentsDelegate() {}
+ ~MockPointerLockWebContentsDelegate() override {}
+
+ void RequestToLockMouse(WebContents* web_contents,
+ bool user_gesture,
+ bool last_unlocked_by_target) override {
+ web_contents->GotResponseToLockMouseRequest(true);
+ }
+
+ void LostMouseLock() override {}
+};
#ifdef USE_AURA
-class MockRenderWidgetHostView : public RenderWidgetHostViewAura {
+class MockPointerLockRenderWidgetHostView : public RenderWidgetHostViewAura {
public:
- MockRenderWidgetHostView(RenderWidgetHost* host, bool is_guest_view_hack)
+ MockPointerLockRenderWidgetHostView(RenderWidgetHost* host,
+ bool is_guest_view_hack)
: RenderWidgetHostViewAura(host,
is_guest_view_hack,
false /* is_mus_browser_plugin_guest */),
host_(RenderWidgetHostImpl::From(host)) {}
- ~MockRenderWidgetHostView() override {
- if (mouse_locked_)
+ ~MockPointerLockRenderWidgetHostView() override {
+ if (IsMouseLocked())
UnlockMouse();
}
bool LockMouse() override {
- mouse_locked_ = true;
+ event_handler()->mouse_locked_ = true;
return true;
}
void UnlockMouse() override {
host_->LostMouseLock();
- mouse_locked_ = false;
+ event_handler()->mouse_locked_ = false;
}
- bool IsMouseLocked() override { return mouse_locked_; }
+ bool IsMouseLocked() override { return event_handler()->mouse_locked(); }
bool HasFocus() const override { return true; }
@@ -61,30 +75,13 @@ class MockRenderWidgetHostView : public RenderWidgetHostViewAura {
RenderWidgetHostImpl* host_;
};
-#endif // USE_AURA
-
-} // namespace
-
-class MockPointerLockWebContentsDelegate : public WebContentsDelegate {
- public:
- MockPointerLockWebContentsDelegate() {}
- ~MockPointerLockWebContentsDelegate() override {}
-
- void RequestToLockMouse(WebContents* web_contents,
- bool user_gesture,
- bool last_unlocked_by_target) override {
- web_contents->GotResponseToLockMouseRequest(true);
- }
-
- void LostMouseLock() override {}
-};
-#ifdef USE_AURA
void InstallCreateHooksForPointerLockBrowserTests() {
WebContentsViewAura::InstallCreateHookForTests(
[](RenderWidgetHost* host,
bool is_guest_view_hack) -> RenderWidgetHostViewAura* {
- return new MockRenderWidgetHostView(host, is_guest_view_hack);
+ return new MockPointerLockRenderWidgetHostView(host,
+ is_guest_view_hack);
});
}
#endif // USE_AURA
@@ -179,7 +176,7 @@ IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockEventRouting) {
RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>(
child->current_frame_host()->GetView());
- WaitForChildFrameSurfaceReady(child->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child->current_frame_host());
// Request a pointer lock on the root frame's body.
EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()"));
@@ -397,7 +394,7 @@ IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWheelEventRouting) {
RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>(
child->current_frame_host()->GetView());
- WaitForChildFrameSurfaceReady(child->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child->current_frame_host());
// Request a pointer lock on the root frame's body.
EXPECT_TRUE(ExecuteScript(root, "document.body.requestPointerLock()"));
@@ -431,18 +428,16 @@ IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWheelEventRouting) {
// Make sure that the renderer handled the input event.
root_observer.Wait();
- if (root_view->wheel_scroll_latching_enabled()) {
- // When wheel scroll latching is enabled all wheel events during a scroll
- // sequence will be sent to a single target. Send a wheel end event to the
- // current target before sending wheel events to a new target.
- wheel_event.delta_x = 0;
- wheel_event.delta_y = 0;
- wheel_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
- router->RouteMouseWheelEvent(root_view, &wheel_event, ui::LatencyInfo());
-
- // Make sure that the renderer handled the input event.
- root_observer.Wait();
- }
+ // All wheel events during a scroll sequence will be sent to a single target.
+ // Send a wheel end event to the current target before sending wheel events to
+ // a new target.
+ wheel_event.delta_x = 0;
+ wheel_event.delta_y = 0;
+ wheel_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
+ router->RouteMouseWheelEvent(root_view, &wheel_event, ui::LatencyInfo());
+
+ // Make sure that the renderer handled the input event.
+ root_observer.Wait();
int x, y, deltaX, deltaY;
EXPECT_TRUE(ExecuteScriptAndExtractInt(
@@ -489,8 +484,7 @@ IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWheelEventRouting) {
-transformed_point.y() + 15);
wheel_event.delta_x = -16;
wheel_event.delta_y = -17;
- if (root_view->wheel_scroll_latching_enabled())
- wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
+ wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
// We use root_view intentionally as the RenderWidgetHostInputEventRouter is
// responsible for correctly routing the event to the child frame.
router->RouteMouseWheelEvent(root_view, &wheel_event, ui::LatencyInfo());
@@ -522,7 +516,7 @@ IN_PROC_BROWSER_TEST_F(PointerLockBrowserTest, PointerLockWidgetHidden) {
RenderWidgetHostViewBase* child_view = static_cast<RenderWidgetHostViewBase*>(
child->current_frame_host()->GetView());
- WaitForChildFrameSurfaceReady(child->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child->current_frame_host());
// Request a pointer lock on the child frame's body.
EXPECT_TRUE(ExecuteScript(child, "document.body.requestPointerLock()"));
diff --git a/chromium/content/browser/pointer_lock_browsertest_mac.mm b/chromium/content/browser/pointer_lock_browsertest_mac.mm
index 26adc174a32..75c02abf8b9 100644
--- a/chromium/content/browser/pointer_lock_browsertest_mac.mm
+++ b/chromium/content/browser/pointer_lock_browsertest_mac.mm
@@ -10,13 +10,12 @@
namespace content {
-namespace {
-
-class MockRenderWidgetHostView : public RenderWidgetHostViewMac {
+class MockPointerLockRenderWidgetHostView : public RenderWidgetHostViewMac {
public:
- MockRenderWidgetHostView(RenderWidgetHost* host, bool is_guest_view_hack)
+ MockPointerLockRenderWidgetHostView(RenderWidgetHost* host,
+ bool is_guest_view_hack)
: RenderWidgetHostViewMac(host, is_guest_view_hack) {}
- ~MockRenderWidgetHostView() override {
+ ~MockPointerLockRenderWidgetHostView() override {
if (mouse_locked_)
UnlockMouse();
}
@@ -40,13 +39,12 @@ class MockRenderWidgetHostView : public RenderWidgetHostViewMac {
bool HasFocus() const override { return true; }
};
-} // namespace
-
void InstallCreateHooksForPointerLockBrowserTests() {
WebContentsViewMac::InstallCreateHookForTests(
[](RenderWidgetHost* host,
bool is_guest_view_hack) -> RenderWidgetHostViewMac* {
- return new MockRenderWidgetHostView(host, is_guest_view_hack);
+ return new MockPointerLockRenderWidgetHostView(host,
+ is_guest_view_hack);
});
}
diff --git a/chromium/content/browser/power_monitor_browsertest.cc b/chromium/content/browser/power_monitor_browsertest.cc
index 633b768ff5f..ffd7190d197 100644
--- a/chromium/content/browser/power_monitor_browsertest.cc
+++ b/chromium/content/browser/power_monitor_browsertest.cc
@@ -47,6 +47,7 @@ void StartUtilityProcessOnIOThread(mojom::PowerMonitorTestRequest request) {
UtilityProcessHost* host =
new UtilityProcessHost(/*client=*/nullptr,
/*client_task_runner=*/nullptr);
+ host->SetMetricsName("test_process");
host->SetName(base::ASCIIToUTF16("TestProcess"));
EXPECT_TRUE(host->Start());
@@ -92,17 +93,18 @@ class MockPowerMonitorMessageBroadcaster : public device::mojom::PowerMonitor {
class PowerMonitorTest : public ContentBrowserTest {
public:
- PowerMonitorTest() = default;
-
- void SetUp() override {
+ PowerMonitorTest() {
// Because Device Service also runs in this process(browser process), we can
// set our binder to intercept requests for PowerMonitor interface to it.
service_manager::ServiceContext::SetGlobalBinderForTesting(
device::mojom::kServiceName, device::mojom::PowerMonitor::Name_,
base::Bind(&PowerMonitorTest::BindPowerMonitor,
base::Unretained(this)));
+ }
- ContentBrowserTest::SetUp();
+ ~PowerMonitorTest() override {
+ service_manager::ServiceContext::ClearGlobalBindersForTesting(
+ device::mojom::kServiceName);
}
void BindPowerMonitor(const std::string& interface_name,
diff --git a/chromium/content/browser/ppapi_plugin_process_host.cc b/chromium/content/browser/ppapi_plugin_process_host.cc
index f2de22ce7fe..3cf4e5d1f53 100644
--- a/chromium/content/browser/ppapi_plugin_process_host.cc
+++ b/chromium/content/browser/ppapi_plugin_process_host.cc
@@ -29,7 +29,6 @@
#include "content/public/common/process_type.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/common/service_names.mojom.h"
-#include "mojo/edk/embedder/embedder.h"
#include "net/base/network_change_notifier.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "services/service_manager/sandbox/sandbox_type.h"
diff --git a/chromium/content/browser/presentation/presentation_service_impl_unittest.cc b/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
index ad4ff3ef346..a635d4413a8 100644
--- a/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
+++ b/chromium/content/browser/presentation/presentation_service_impl_unittest.cc
@@ -132,7 +132,7 @@ class MockPresentationServiceDelegate
int render_frame_id,
const std::string& presentation_id));
MOCK_METHOD3(GetMediaController,
- std::unique_ptr<content::MediaController>(
+ std::unique_ptr<media::MediaController>(
int render_process_id,
int render_frame_id,
const std::string& presentation_id));
diff --git a/chromium/content/browser/process_internals/process_internals.mojom b/chromium/content/browser/process_internals/process_internals.mojom
index da65f0ffb15..d8fe8594f2d 100644
--- a/chromium/content/browser/process_internals/process_internals.mojom
+++ b/chromium/content/browser/process_internals/process_internals.mojom
@@ -11,7 +11,6 @@ interface ProcessInternalsHandler {
// Returns a string containing the currently active isolation modes.
GetIsolationMode() => (string mode);
- // Returns a list of isolated origins in their serialized to string
- // format. This avoids duplicating serialization code to JavaScript.
- GetIsolatedOrigins() => (array<string> isolated_origins);
+ // Returns the number of isolated origins.
+ GetIsolatedOriginsSize() => (uint32 size);
};
diff --git a/chromium/content/browser/process_internals/process_internals_handler_impl.cc b/chromium/content/browser/process_internals/process_internals_handler_impl.cc
index ae4fc6d9ac6..dbd0e5792b1 100644
--- a/chromium/content/browser/process_internals/process_internals_handler_impl.cc
+++ b/chromium/content/browser/process_internals/process_internals_handler_impl.cc
@@ -30,15 +30,10 @@ void ProcessInternalsHandlerImpl::GetIsolationMode(
: base::JoinString(modes, ", "));
}
-void ProcessInternalsHandlerImpl::GetIsolatedOrigins(
- GetIsolatedOriginsCallback callback) {
- std::vector<url::Origin> origins_list =
- SiteIsolationPolicy::GetIsolatedOrigins();
- std::vector<std::string> origins;
- for (size_t i = 0; i < origins_list.size(); ++i)
- origins.push_back(origins_list[i].Serialize());
-
- std::move(callback).Run(origins);
+void ProcessInternalsHandlerImpl::GetIsolatedOriginsSize(
+ GetIsolatedOriginsSizeCallback callback) {
+ int size = SiteIsolationPolicy::GetIsolatedOrigins().size();
+ std::move(callback).Run(size);
}
} // namespace content
diff --git a/chromium/content/browser/process_internals/process_internals_handler_impl.h b/chromium/content/browser/process_internals/process_internals_handler_impl.h
index 3a8ee50a94e..54b7def12f9 100644
--- a/chromium/content/browser/process_internals/process_internals_handler_impl.h
+++ b/chromium/content/browser/process_internals/process_internals_handler_impl.h
@@ -22,7 +22,7 @@ class ProcessInternalsHandlerImpl : public ::mojom::ProcessInternalsHandler {
// mojom::ProcessInternalsHandler overrides:
void GetIsolationMode(GetIsolationModeCallback callback) override;
- void GetIsolatedOrigins(GetIsolatedOriginsCallback callback) override;
+ void GetIsolatedOriginsSize(GetIsolatedOriginsSizeCallback callback) override;
private:
mojo::Binding<::mojom::ProcessInternalsHandler> binding_;
diff --git a/chromium/content/browser/process_internals/process_internals_ui.cc b/chromium/content/browser/process_internals/process_internals_ui.cc
index f6015e79efd..8c3558c5b61 100644
--- a/chromium/content/browser/process_internals/process_internals_ui.cc
+++ b/chromium/content/browser/process_internals/process_internals_ui.cc
@@ -28,7 +28,7 @@ ProcessInternalsUI::ProcessInternalsUI(WebUI* web_ui)
: WebUIController(web_ui), WebContentsObserver(web_ui->GetWebContents()) {
// Grant only Mojo WebUI bindings, since this WebUI will not use
// chrome.send().
- web_ui->SetBindings(content::BINDINGS_POLICY_WEB_UI);
+ web_ui->SetBindings(content::BINDINGS_POLICY_MOJO_WEB_UI);
// Create a WebUIDataSource to serve the HTML/JS files to the WebUI.
WebUIDataSource* source =
diff --git a/chromium/content/browser/push_messaging/push_messaging_manager.cc b/chromium/content/browser/push_messaging/push_messaging_manager.cc
index fef1c37b56c..bc6ee59fe0c 100644
--- a/chromium/content/browser/push_messaging/push_messaging_manager.cc
+++ b/chromium/content/browser/push_messaging/push_messaging_manager.cc
@@ -14,13 +14,13 @@
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
+#include "content/browser/permissions/permission_controller_impl.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/common/push_messaging.mojom.h"
#include "content/public/browser/browser_context.h"
-#include "content/public/browser/permission_manager.h"
#include "content/public/browser/permission_type.h"
#include "content/public/browser/push_messaging_service.h"
#include "content/public/browser/render_frame_host.h"
@@ -335,12 +335,12 @@ void PushMessagingManager::Subscribe(int32_t render_frame_id,
void PushMessagingManager::DidCheckForExistingRegistration(
RegisterData data,
const std::vector<std::string>& subscription_id_and_sender_id,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Validate the stored subscription against the subscription request made by
// the developer. The authorized entity must match.
- if (service_worker_status == SERVICE_WORKER_OK) {
+ if (service_worker_status == blink::ServiceWorkerStatusCode::kOk) {
DCHECK_EQ(2u, subscription_id_and_sender_id.size());
const std::string& subscription_id = subscription_id_and_sender_id[0];
@@ -363,8 +363,9 @@ void PushMessagingManager::DidCheckForExistingRegistration(
data.existing_subscription_id = subscription_id;
}
- // TODO(peter): Handle failures other than SERVICE_WORKER_ERROR_NOT_FOUND by
- // rejecting the subscription algorithm instead of trying to subscribe.
+ // TODO(peter): Handle failures other than
+ // blink::ServiceWorkerStatusCode::kErrorNotFound by rejecting
+ // the subscription algorithm instead of trying to subscribe.
if (!data.options.sender_info.empty()) {
BrowserThread::PostTask(
@@ -385,9 +386,9 @@ void PushMessagingManager::DidCheckForExistingRegistration(
void PushMessagingManager::DidGetSenderIdFromStorage(
RegisterData data,
const std::vector<std::string>& stored_sender_id,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (service_worker_status != SERVICE_WORKER_OK) {
+ if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
SendSubscriptionError(std::move(data),
mojom::PushRegistrationStatus::NO_SENDER_ID);
return;
@@ -444,29 +445,17 @@ void PushMessagingManager::Core::RegisterOnUI(
BrowserContext* browser_context = web_contents->GetBrowserContext();
- // It's valid for embedders to return a null permission manager.
- // Immediately reject the permission request when this happens.
- if (!browser_context->GetPermissionManager()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&PushMessagingManager::SendSubscriptionError,
- io_parent_, std::move(data),
- mojom::PushRegistrationStatus::
- INCOGNITO_PERMISSION_DENIED));
-
- return;
- }
-
// 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::NOTIFICATIONS, render_frame_host,
- requesting_origin, data.user_gesture,
- base::Bind(
- &PushMessagingManager::Core::DidRequestPermissionInIncognito,
- weak_factory_ui_to_ui_.GetWeakPtr(), base::Passed(&data)));
+ PermissionControllerImpl::FromBrowserContext(browser_context)
+ ->RequestPermission(
+ PermissionType::NOTIFICATIONS, render_frame_host,
+ data.requesting_origin, data.user_gesture,
+ base::Bind(&PushMessagingManager::Core::
+ DidRequestPermissionInIncognito,
+ weak_factory_ui_to_ui_.GetWeakPtr(),
+ base::Passed(&data)));
}
}
}
@@ -563,9 +552,9 @@ void PushMessagingManager::DidPersistRegistrationOnIO(
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth,
mojom::PushRegistrationStatus push_registration_status,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (service_worker_status == SERVICE_WORKER_OK) {
+ if (service_worker_status == blink::ServiceWorkerStatusCode::kOk) {
SendSubscriptionSuccess(std::move(data), push_registration_status,
push_subscription_id, p256dh, auth);
} else {
@@ -638,11 +627,11 @@ void PushMessagingManager::UnsubscribeHavingGottenSenderId(
int64_t service_worker_registration_id,
const GURL& requesting_origin,
const std::vector<std::string>& sender_ids,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::string sender_id;
- if (service_worker_status == SERVICE_WORKER_OK) {
+ if (service_worker_status == blink::ServiceWorkerStatusCode::kOk) {
DCHECK_EQ(1u, sender_ids.size());
sender_id = sender_ids[0];
}
@@ -746,12 +735,12 @@ void PushMessagingManager::DidGetSubscription(
GetSubscriptionCallback callback,
int64_t service_worker_registration_id,
const std::vector<std::string>& push_subscription_id_and_sender_info,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
mojom::PushGetRegistrationStatus get_status =
mojom::PushGetRegistrationStatus::STORAGE_ERROR;
switch (service_worker_status) {
- case SERVICE_WORKER_OK: {
+ case blink::ServiceWorkerStatusCode::kOk: {
DCHECK_EQ(2u, push_subscription_id_and_sender_info.size());
const std::string& push_subscription_id =
push_subscription_id_and_sender_info[0];
@@ -794,33 +783,33 @@ void PushMessagingManager::DidGetSubscription(
return;
}
- case SERVICE_WORKER_ERROR_NOT_FOUND: {
+ case blink::ServiceWorkerStatusCode::kErrorNotFound: {
get_status = mojom::PushGetRegistrationStatus::REGISTRATION_NOT_FOUND;
break;
}
- case SERVICE_WORKER_ERROR_FAILED: {
+ case blink::ServiceWorkerStatusCode::kErrorFailed: {
get_status = mojom::PushGetRegistrationStatus::STORAGE_ERROR;
break;
}
- case SERVICE_WORKER_ERROR_ABORT:
- 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: {
- NOTREACHED() << "Got unexpected error code: " << service_worker_status
- << " " << ServiceWorkerStatusToString(service_worker_status);
+ case blink::ServiceWorkerStatusCode::kErrorAbort:
+ case blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorProcessNotFound:
+ case blink::ServiceWorkerStatusCode::kErrorExists:
+ case blink::ServiceWorkerStatusCode::kErrorInstallWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorActivateWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorIpcFailed:
+ case blink::ServiceWorkerStatusCode::kErrorNetwork:
+ case blink::ServiceWorkerStatusCode::kErrorSecurity:
+ case blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected:
+ case blink::ServiceWorkerStatusCode::kErrorState:
+ case blink::ServiceWorkerStatusCode::kErrorTimeout:
+ case blink::ServiceWorkerStatusCode::kErrorScriptEvaluateFailed:
+ case blink::ServiceWorkerStatusCode::kErrorDiskCache:
+ case blink::ServiceWorkerStatusCode::kErrorRedundant:
+ case blink::ServiceWorkerStatusCode::kErrorDisallowed: {
+ NOTREACHED() << "Got unexpected error code: "
+ << static_cast<uint32_t>(service_worker_status) << " "
+ << blink::ServiceWorkerStatusToString(service_worker_status);
get_status = mojom::PushGetRegistrationStatus::STORAGE_ERROR;
break;
}
diff --git a/chromium/content/browser/push_messaging/push_messaging_manager.h b/chromium/content/browser/push_messaging/push_messaging_manager.h
index e064154aa01..36ce6e248b9 100644
--- a/chromium/content/browser/push_messaging/push_messaging_manager.h
+++ b/chromium/content/browser/push_messaging/push_messaging_manager.h
@@ -14,9 +14,9 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/push_messaging.mojom.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/binding_set.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"
namespace content {
@@ -65,11 +65,12 @@ class PushMessagingManager : public mojom::PushMessaging {
void DidCheckForExistingRegistration(
RegisterData data,
const std::vector<std::string>& subscription_id_and_sender_id,
- ServiceWorkerStatusCode service_worker_status);
+ blink::ServiceWorkerStatusCode service_worker_status);
- void DidGetSenderIdFromStorage(RegisterData data,
- const std::vector<std::string>& sender_id,
- ServiceWorkerStatusCode service_worker_status);
+ void DidGetSenderIdFromStorage(
+ RegisterData data,
+ const std::vector<std::string>& sender_id,
+ blink::ServiceWorkerStatusCode service_worker_status);
// Called via PostTask from UI thread.
void PersistRegistrationOnIO(RegisterData data,
@@ -84,7 +85,7 @@ class PushMessagingManager : public mojom::PushMessaging {
const std::vector<uint8_t>& p256dh,
const std::vector<uint8_t>& auth,
mojom::PushRegistrationStatus push_registration_status,
- ServiceWorkerStatusCode service_worker_status);
+ blink::ServiceWorkerStatusCode service_worker_status);
// Called both from IO thread, and via PostTask from UI thread.
void SendSubscriptionError(RegisterData data,
@@ -101,7 +102,7 @@ class PushMessagingManager : public mojom::PushMessaging {
int64_t service_worker_registration_id,
const GURL& requesting_origin,
const std::vector<std::string>& sender_id,
- ServiceWorkerStatusCode service_worker_status);
+ blink::ServiceWorkerStatusCode service_worker_status);
// Called both from IO thread, and via PostTask from UI thread.
void DidUnregister(UnsubscribeCallback callback,
@@ -111,7 +112,7 @@ class PushMessagingManager : public mojom::PushMessaging {
GetSubscriptionCallback callback,
int64_t service_worker_registration_id,
const std::vector<std::string>& push_subscription_id_and_sender_info,
- ServiceWorkerStatusCode service_worker_status);
+ blink::ServiceWorkerStatusCode service_worker_status);
// Helper methods on either thread -------------------------------------------
diff --git a/chromium/content/browser/push_messaging/push_messaging_router.cc b/chromium/content/browser/push_messaging/push_messaging_router.cc
index 05e3d73578d..a648b5d11fa 100644
--- a/chromium/content/browser/push_messaging/push_messaging_router.cc
+++ b/chromium/content/browser/push_messaging/push_messaging_router.cc
@@ -12,12 +12,12 @@
#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_messages.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/push_event_payload.h"
#include "content/public/common/push_messaging_status.mojom.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
@@ -75,18 +75,17 @@ void PushMessagingRouter::FindServiceWorkerRegistration(
void PushMessagingRouter::FindServiceWorkerRegistrationCallback(
const PushEventPayload& payload,
const DeliverMessageCallback& deliver_message_callback,
- ServiceWorkerStatusCode service_worker_status,
+ blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
UMA_HISTOGRAM_ENUMERATION("PushMessaging.DeliveryStatus.FindServiceWorker",
- service_worker_status,
- SERVICE_WORKER_ERROR_MAX_VALUE);
- if (service_worker_status == SERVICE_WORKER_ERROR_NOT_FOUND) {
+ service_worker_status);
+ if (service_worker_status == blink::ServiceWorkerStatusCode::kErrorNotFound) {
RunDeliverCallback(deliver_message_callback,
mojom::PushDeliveryStatus::NO_SERVICE_WORKER);
return;
}
- if (service_worker_status != SERVICE_WORKER_OK) {
+ if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
RunDeliverCallback(deliver_message_callback,
mojom::PushDeliveryStatus::SERVICE_WORKER_ERROR);
return;
@@ -112,9 +111,9 @@ void PushMessagingRouter::DeliverMessageToWorker(
const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
const PushEventPayload& payload,
const DeliverMessageCallback& deliver_message_callback,
- ServiceWorkerStatusCode start_worker_status) {
+ blink::ServiceWorkerStatusCode start_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (start_worker_status != SERVICE_WORKER_OK) {
+ if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) {
DeliverMessageEnd(deliver_message_callback, service_worker_registration,
start_worker_status);
return;
@@ -127,7 +126,7 @@ void PushMessagingRouter::DeliverMessageToWorker(
base::TimeDelta::FromSeconds(mojom::kPushEventTimeoutSeconds),
ServiceWorkerVersion::KILL_ON_TIMEOUT);
- service_worker->event_dispatcher()->DispatchPushEvent(
+ service_worker->endpoint()->DispatchPushEvent(
payload, service_worker->CreateSimpleEventCallback(request_id));
}
@@ -135,44 +134,43 @@ void PushMessagingRouter::DeliverMessageToWorker(
void PushMessagingRouter::DeliverMessageEnd(
const DeliverMessageCallback& deliver_message_callback,
const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
UMA_HISTOGRAM_ENUMERATION("PushMessaging.DeliveryStatus.ServiceWorkerEvent",
- service_worker_status,
- SERVICE_WORKER_ERROR_MAX_VALUE);
+ service_worker_status);
mojom::PushDeliveryStatus delivery_status =
mojom::PushDeliveryStatus::SERVICE_WORKER_ERROR;
switch (service_worker_status) {
- case SERVICE_WORKER_OK:
+ case blink::ServiceWorkerStatusCode::kOk:
delivery_status = mojom::PushDeliveryStatus::SUCCESS;
break;
- case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
+ case blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected:
delivery_status = mojom::PushDeliveryStatus::EVENT_WAITUNTIL_REJECTED;
break;
- case SERVICE_WORKER_ERROR_TIMEOUT:
+ case blink::ServiceWorkerStatusCode::kErrorTimeout:
delivery_status = mojom::PushDeliveryStatus::TIMEOUT;
break;
- case SERVICE_WORKER_ERROR_FAILED:
- case SERVICE_WORKER_ERROR_ABORT:
- case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
- case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
- case SERVICE_WORKER_ERROR_NOT_FOUND:
- case SERVICE_WORKER_ERROR_IPC_FAILED:
- case SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED:
- case SERVICE_WORKER_ERROR_DISK_CACHE:
- case SERVICE_WORKER_ERROR_REDUNDANT:
- case SERVICE_WORKER_ERROR_DISALLOWED:
+ case blink::ServiceWorkerStatusCode::kErrorFailed:
+ case blink::ServiceWorkerStatusCode::kErrorAbort:
+ case blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorProcessNotFound:
+ case blink::ServiceWorkerStatusCode::kErrorNotFound:
+ case blink::ServiceWorkerStatusCode::kErrorIpcFailed:
+ case blink::ServiceWorkerStatusCode::kErrorScriptEvaluateFailed:
+ case blink::ServiceWorkerStatusCode::kErrorDiskCache:
+ case blink::ServiceWorkerStatusCode::kErrorRedundant:
+ case blink::ServiceWorkerStatusCode::kErrorDisallowed:
delivery_status = mojom::PushDeliveryStatus::SERVICE_WORKER_ERROR;
break;
- case SERVICE_WORKER_ERROR_EXISTS:
- case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED:
- case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED:
- case SERVICE_WORKER_ERROR_NETWORK:
- case SERVICE_WORKER_ERROR_SECURITY:
- case SERVICE_WORKER_ERROR_STATE:
- case SERVICE_WORKER_ERROR_MAX_VALUE:
- NOTREACHED() << "Got unexpected error code: " << service_worker_status
- << " " << ServiceWorkerStatusToString(service_worker_status);
+ case blink::ServiceWorkerStatusCode::kErrorExists:
+ case blink::ServiceWorkerStatusCode::kErrorInstallWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorActivateWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorNetwork:
+ case blink::ServiceWorkerStatusCode::kErrorSecurity:
+ case blink::ServiceWorkerStatusCode::kErrorState:
+ NOTREACHED() << "Got unexpected error code: "
+ << static_cast<uint32_t>(service_worker_status) << " "
+ << blink::ServiceWorkerStatusToString(service_worker_status);
delivery_status = mojom::PushDeliveryStatus::SERVICE_WORKER_ERROR;
break;
}
diff --git a/chromium/content/browser/push_messaging/push_messaging_router.h b/chromium/content/browser/push_messaging/push_messaging_router.h
index e2ae5da2242..71bb530f425 100644
--- a/chromium/content/browser/push_messaging/push_messaging_router.h
+++ b/chromium/content/browser/push_messaging/push_messaging_router.h
@@ -10,7 +10,7 @@
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"
namespace content {
@@ -56,7 +56,7 @@ class PushMessagingRouter {
static void FindServiceWorkerRegistrationCallback(
const PushEventPayload& payload,
const DeliverMessageCallback& deliver_message_callback,
- ServiceWorkerStatusCode service_worker_status,
+ blink::ServiceWorkerStatusCode service_worker_status,
scoped_refptr<ServiceWorkerRegistration> service_worker_registration);
// Delivers a push message with |data| to a specific |service_worker|.
@@ -67,7 +67,7 @@ class PushMessagingRouter {
service_worker_registration,
const PushEventPayload& payload,
const DeliverMessageCallback& deliver_message_callback,
- ServiceWorkerStatusCode start_worker_status);
+ blink::ServiceWorkerStatusCode start_worker_status);
// Gets called asynchronously after the Service Worker has dispatched the push
// event. Must be called on the IO thread.
@@ -75,7 +75,7 @@ class PushMessagingRouter {
const DeliverMessageCallback& deliver_message_callback,
const scoped_refptr<ServiceWorkerRegistration>&
service_worker_registration,
- ServiceWorkerStatusCode service_worker_status);
+ blink::ServiceWorkerStatusCode service_worker_status);
DISALLOW_IMPLICIT_CONSTRUCTORS(PushMessagingRouter);
};
diff --git a/chromium/content/browser/renderer_host/OWNERS b/chromium/content/browser/renderer_host/OWNERS
index d671fbdac2c..5108375b6e4 100644
--- a/chromium/content/browser/renderer_host/OWNERS
+++ b/chromium/content/browser/renderer_host/OWNERS
@@ -11,6 +11,10 @@ asvitkine@chromium.org
kbr@chromium.org
ccameron@chromium.org
+# for *android*
+per-file *android*=ericrk@chromium.org
+per-file *android*=khushalsagar@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 bc9eba153a6..46be85eea4b 100644
--- a/chromium/content/browser/renderer_host/browser_compositor_view_mac.h
+++ b/chromium/content/browser/renderer_host/browser_compositor_view_mac.h
@@ -20,12 +20,11 @@
namespace ui {
class AcceleratedWidgetMacNSView;
+class RecyclableCompositorMac;
}
namespace content {
-class RecyclableCompositorMac;
-
class BrowserCompositorMacClient {
public:
virtual SkColor BrowserCompositorMacGetGutterColor() const = 0;
@@ -33,7 +32,9 @@ class BrowserCompositorMacClient {
virtual void OnFrameTokenChanged(uint32_t frame_token) = 0;
virtual void DidReceiveFirstFrameAfterNavigation() = 0;
virtual void DestroyCompositorForShutdown() = 0;
- virtual bool SynchronizeVisualProperties() = 0;
+ virtual bool SynchronizeVisualProperties(
+ const base::Optional<viz::LocalSurfaceId>&
+ child_allocated_local_surface_id) = 0;
};
// This class owns a DelegatedFrameHost, and will dynamically attach and
@@ -51,7 +52,6 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient,
ui::AcceleratedWidgetMacNSView* accelerated_widget_mac_ns_view,
BrowserCompositorMacClient* client,
bool render_widget_host_is_hidden,
- bool ns_view_attached_to_window,
const display::Display& initial_display,
const viz::FrameSinkId& frame_sink_id);
~BrowserCompositorMac() override;
@@ -69,7 +69,6 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient,
// no valid frame is available.
const gfx::CALayerParams* GetLastCALayerParams() const;
- gfx::AcceleratedWidget GetAcceleratedWidget();
void DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink);
void OnDidNotProduceFrame(const viz::BeginFrameAck& ack);
@@ -90,6 +89,7 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient,
// Update the renderer's SurfaceId to reflect |new_size_in_pixels| in
// anticipation of the NSView resizing during auto-resize.
void SynchronizeVisualProperties(
+ float new_device_scale_factor,
const gfx::Size& new_size_in_pixels,
const viz::LocalSurfaceId& child_allocated_local_surface_id);
@@ -105,6 +105,9 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient,
// hidden (e.g, because it is occluded by another window).
void SetNSViewAttachedToWindow(bool attached);
+ // Specify if the ui::Layer should be visible or not.
+ void SetViewVisible(bool visible);
+
// Sets or clears the parent ui::Layer and updates state to reflect that
// we are now using the ui::Compositor from |parent_ui_layer| (if non-nullptr)
// or one from |recyclable_compositor_| (if a compositor is needed).
@@ -117,8 +120,10 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient,
viz::ScopedSurfaceIdAllocator GetScopedRendererSurfaceIdAllocator(
base::OnceCallback<void()> allocation_task);
const viz::LocalSurfaceId& GetRendererLocalSurfaceId();
+ const viz::LocalSurfaceId& AllocateNewRendererLocalSurfaceId();
bool UpdateRendererLocalSurfaceIdFromChild(
const viz::LocalSurfaceId& child_allocated_local_surface_id);
+ void TransformPointToRootSurface(gfx::PointF* point);
// Indicate that the recyclable compositor should be destroyed, and no future
// compositors should be recycled.
@@ -139,8 +144,6 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient,
void DidNavigate();
- void BeginPauseForFrame(bool auto_resize_enabled);
- void EndPauseForFrame();
bool ShouldContinueToPauseForFrame() const;
bool ForceNewSurfaceForTesting();
@@ -151,7 +154,7 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient,
// ui::LayerObserver implementation:
void LayerDestroyed(ui::Layer* layer) override;
- cc::DeadlinePolicy GetDeadlinePolicy() const;
+ cc::DeadlinePolicy GetDeadlinePolicy(bool is_resize) const;
// The state of |delegated_frame_host_| and |recyclable_compositor_| to
// manage being visible, occluded, hidden, or drawn via a ui::Layer. Note that
@@ -197,14 +200,15 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient,
// Weak pointer to the layer supplied and reset via SetParentUiLayer. |this|
// is an observer of |parent_ui_layer_|, to ensure that |parent_ui_layer_|
- // always be valid when non-null.
+ // always be valid when non-null. The UpdateState function will re-parent
+ // |root_layer_| to be under |parent_ui_layer_|, if needed.
ui::Layer* parent_ui_layer_ = nullptr;
bool render_widget_host_is_hidden_ = true;
bool ns_view_attached_to_window_ = false;
BrowserCompositorMacClient* client_ = nullptr;
ui::AcceleratedWidgetMacNSView* accelerated_widget_mac_ns_view_ = nullptr;
- std::unique_ptr<RecyclableCompositorMac> recyclable_compositor_;
+ std::unique_ptr<ui::RecyclableCompositorMac> recyclable_compositor_;
std::unique_ptr<DelegatedFrameHost> delegated_frame_host_;
std::unique_ptr<ui::Layer> root_layer_;
@@ -221,18 +225,6 @@ class CONTENT_EXPORT BrowserCompositorMac : public DelegatedFrameHostClient,
gfx::Size dfh_size_dip_;
display::Display dfh_display_;
- // Used to disable screen updates while resizing (because frames are drawn in
- // the GPU process, they can end up appearing on-screen before our window
- // resizes).
- enum class RepaintState {
- // No repaint in progress.
- None,
- // Synchronously waiting for a new frame.
- Paused,
- // Screen updates are disabled while a new frame is swapped in.
- ScreenUpdatesDisabled,
- } repaint_state_ = RepaintState::None;
- bool repaint_auto_resize_enabled_ = false;
bool is_first_navigation_ = true;
base::WeakPtrFactory<BrowserCompositorMac> weak_factory_;
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 3d12a1126a0..92afcc77910 100644
--- a/chromium/content/browser/renderer_host/browser_compositor_view_mac.mm
+++ b/chromium/content/browser/renderer_host/browser_compositor_view_mac.mm
@@ -20,6 +20,7 @@
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
#include "ui/base/layout.h"
+#include "ui/compositor/recyclable_compositor_mac.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/dip_util.h"
@@ -37,170 +38,15 @@ namespace {
base::LazyInstance<std::set<BrowserCompositorMac*>>::Leaky
g_browser_compositors;
-// A spare RecyclableCompositorMac kept around for recycling.
-base::LazyInstance<base::circular_deque<
- std::unique_ptr<RecyclableCompositorMac>>>::DestructorAtExit
- g_spare_recyclable_compositors;
-
-void ReleaseSpareCompositors() {
- // Allow at most one spare recyclable compositor.
- while (g_spare_recyclable_compositors.Get().size() > 1)
- g_spare_recyclable_compositors.Get().pop_front();
-
- if (g_browser_compositors.Get().empty())
- g_spare_recyclable_compositors.Get().clear();
-}
-
} // namespace
////////////////////////////////////////////////////////////////////////////////
-// RecyclableCompositorMac
-
-// A ui::Compositor and a gfx::AcceleratedWidget (and helper) that it draws
-// into. This structure is used to efficiently recycle these structures across
-// tabs (because creating a new ui::Compositor for each tab would be expensive
-// in terms of time and resources).
-class RecyclableCompositorMac : public ui::CompositorObserver {
- public:
- ~RecyclableCompositorMac() override;
-
- // Create a compositor, or recycle a preexisting one.
- static std::unique_ptr<RecyclableCompositorMac> Create();
-
- // Delete a compositor, or allow it to be recycled.
- static void Recycle(std::unique_ptr<RecyclableCompositorMac> compositor);
-
- ui::Compositor* compositor() { return &compositor_; }
- ui::AcceleratedWidgetMac* accelerated_widget_mac() {
- return accelerated_widget_mac_.get();
- }
- const gfx::Size pixel_size() const { return size_pixels_; }
- float scale_factor() const { return scale_factor_; }
-
- // Suspend will prevent the compositor from producing new frames. This should
- // be called to avoid creating spurious frames while changing state.
- // Compositors are created as suspended.
- void Suspend();
- void Unsuspend();
-
- // Update the compositor's surface information, if needed.
- void UpdateSurface(const gfx::Size& size_pixels, float scale_factor);
- // Invalidate the compositor's surface information.
- void InvalidateSurface();
-
- // The viz::ParentLocalSurfaceIdAllocator for the ui::Compositor dispenses
- // viz::LocalSurfaceIds that are renderered into by the ui::Compositor.
- viz::ParentLocalSurfaceIdAllocator local_surface_id_allocator_;
- gfx::Size size_pixels_;
- float scale_factor_ = 1.f;
-
- private:
- RecyclableCompositorMac();
-
- // ui::CompositorObserver implementation:
- void OnCompositingDidCommit(ui::Compositor* compositor) override;
- void OnCompositingStarted(ui::Compositor* compositor,
- 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_;
- ui::Compositor compositor_;
- std::unique_ptr<ui::CompositorLock> compositor_suspended_lock_;
-
- DISALLOW_COPY_AND_ASSIGN(RecyclableCompositorMac);
-};
-
-RecyclableCompositorMac::RecyclableCompositorMac()
- : accelerated_widget_mac_(new ui::AcceleratedWidgetMac()),
- compositor_(content::GetContextFactoryPrivate()->AllocateFrameSinkId(),
- content::GetContextFactory(),
- content::GetContextFactoryPrivate(),
- ui::WindowResizeHelperMac::Get()->task_runner(),
- features::IsSurfaceSynchronizationEnabled(),
- false /* enable_pixel_canvas */) {
- compositor_.SetAcceleratedWidget(
- accelerated_widget_mac_->accelerated_widget());
- Suspend();
- compositor_.AddObserver(this);
-}
-
-RecyclableCompositorMac::~RecyclableCompositorMac() {
- compositor_.RemoveObserver(this);
-}
-
-void RecyclableCompositorMac::Suspend() {
- // Requests a compositor lock without a timeout.
- compositor_suspended_lock_ =
- compositor_.GetCompositorLock(nullptr, base::TimeDelta());
-}
-
-void RecyclableCompositorMac::Unsuspend() {
- compositor_suspended_lock_ = nullptr;
-}
-
-void RecyclableCompositorMac::UpdateSurface(const gfx::Size& size_pixels,
- float scale_factor) {
- if (size_pixels != size_pixels_ || scale_factor != scale_factor_) {
- size_pixels_ = size_pixels;
- scale_factor_ = scale_factor;
- compositor()->SetScaleAndSize(scale_factor_, size_pixels_,
- local_surface_id_allocator_.GenerateId());
- }
-}
-
-void RecyclableCompositorMac::InvalidateSurface() {
- size_pixels_ = gfx::Size();
- scale_factor_ = 1.f;
- local_surface_id_allocator_.Invalidate();
- compositor()->SetScaleAndSize(
- scale_factor_, size_pixels_,
- local_surface_id_allocator_.GetCurrentLocalSurfaceId());
-}
-
-void RecyclableCompositorMac::OnCompositingDidCommit(
- ui::Compositor* compositor_that_did_commit) {
- DCHECK_EQ(compositor_that_did_commit, compositor());
- accelerated_widget_mac_->SetSuspended(false);
-}
-
-// static
-std::unique_ptr<RecyclableCompositorMac> RecyclableCompositorMac::Create() {
- DCHECK(ui::WindowResizeHelperMac::Get()->task_runner());
- if (!g_spare_recyclable_compositors.Get().empty()) {
- std::unique_ptr<RecyclableCompositorMac> result;
- result = std::move(g_spare_recyclable_compositors.Get().back());
- g_spare_recyclable_compositors.Get().pop_back();
- return result;
- }
- return std::unique_ptr<RecyclableCompositorMac>(new RecyclableCompositorMac);
-}
-
-// static
-void RecyclableCompositorMac::Recycle(
- std::unique_ptr<RecyclableCompositorMac> compositor) {
- compositor->accelerated_widget_mac_->SetSuspended(true);
-
- // Make this RecyclableCompositorMac recyclable for future instances.
- g_spare_recyclable_compositors.Get().push_back(std::move(compositor));
-
- // Post a task to free up the spare ui::Compositors when needed. Post this
- // to the browser main thread so that we won't free any compositors while
- // in a nested loop waiting to put up a new frame.
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE, base::Bind(&ReleaseSpareCompositors));
-}
-
-////////////////////////////////////////////////////////////////////////////////
// BrowserCompositorMac
BrowserCompositorMac::BrowserCompositorMac(
ui::AcceleratedWidgetMacNSView* accelerated_widget_mac_ns_view,
BrowserCompositorMacClient* client,
bool render_widget_host_is_hidden,
- bool ns_view_attached_to_window,
const display::Display& initial_display,
const viz::FrameSinkId& frame_sink_id)
: client_(client),
@@ -219,7 +65,7 @@ BrowserCompositorMac::BrowserCompositorMac(
true /* should_register_frame_sink_id */));
SetRenderWidgetHostIsHidden(render_widget_host_is_hidden);
- SetNSViewAttachedToWindow(ns_view_attached_to_window);
+ SetNSViewAttachedToWindow(false);
}
BrowserCompositorMac::~BrowserCompositorMac() {
@@ -233,19 +79,6 @@ BrowserCompositorMac::~BrowserCompositorMac() {
size_t num_erased = g_browser_compositors.Get().erase(this);
DCHECK_EQ(1u, num_erased);
-
- // If there are no compositors allocated, destroy the recyclable
- // RecyclableCompositorMac.
- if (g_browser_compositors.Get().empty())
- g_spare_recyclable_compositors.Get().clear();
-}
-
-gfx::AcceleratedWidget BrowserCompositorMac::GetAcceleratedWidget() {
- if (recyclable_compositor_) {
- return recyclable_compositor_->accelerated_widget_mac()
- ->accelerated_widget();
- }
- return gfx::kNullAcceleratedWidget;
}
DelegatedFrameHost* BrowserCompositorMac::GetDelegatedFrameHost() {
@@ -267,16 +100,16 @@ void BrowserCompositorMac::ClearCompositorFrame() {
bool BrowserCompositorMac::RequestRepaintForTesting() {
const viz::LocalSurfaceId& new_local_surface_id =
dfh_local_surface_id_allocator_.GenerateId();
- delegated_frame_host_->SynchronizeVisualProperties(
+ delegated_frame_host_->EmbedSurface(
new_local_surface_id, dfh_size_dip_,
cc::DeadlinePolicy::UseExistingDeadline());
- return client_->SynchronizeVisualProperties();
+ return client_->SynchronizeVisualProperties(new_local_surface_id);
}
const gfx::CALayerParams* BrowserCompositorMac::GetLastCALayerParams() const {
if (!recyclable_compositor_)
return nullptr;
- return recyclable_compositor_->accelerated_widget_mac()->GetCALayerParams();
+ return recyclable_compositor_->widget()->GetCALayerParams();
}
viz::FrameSinkId BrowserCompositorMac::GetRootFrameSinkId() {
@@ -310,6 +143,8 @@ bool BrowserCompositorMac::UpdateNSViewAndDisplay(
if (new_size_dip == dfh_size_dip_ && new_display == dfh_display_)
return false;
+ bool is_resize = !dfh_size_dip_.IsEmpty() && new_size_dip != dfh_size_dip_;
+
bool needs_new_surface_id =
new_size_dip != dfh_size_dip_ ||
new_display.device_scale_factor() != dfh_display_.device_scale_factor();
@@ -323,9 +158,9 @@ bool BrowserCompositorMac::UpdateNSViewAndDisplay(
if (needs_new_surface_id) {
if (recyclable_compositor_)
recyclable_compositor_->Suspend();
- GetDelegatedFrameHost()->SynchronizeVisualProperties(
+ GetDelegatedFrameHost()->EmbedSurface(
dfh_local_surface_id_allocator_.GenerateId(), dfh_size_dip_,
- GetDeadlinePolicy());
+ GetDeadlinePolicy(is_resize));
}
if (recyclable_compositor_) {
@@ -339,10 +174,12 @@ bool BrowserCompositorMac::UpdateNSViewAndDisplay(
}
void BrowserCompositorMac::SynchronizeVisualProperties(
+ float new_device_scale_factor,
const gfx::Size& new_size_in_pixels,
const viz::LocalSurfaceId& child_allocated_local_surface_id) {
if (dfh_local_surface_id_allocator_.UpdateFromChild(
child_allocated_local_surface_id)) {
+ dfh_display_.set_device_scale_factor(new_device_scale_factor);
dfh_size_dip_ = gfx::ConvertSizeToDIP(dfh_display_.device_scale_factor(),
new_size_in_pixels);
dfh_size_pixels_ = new_size_in_pixels;
@@ -351,20 +188,29 @@ void BrowserCompositorMac::SynchronizeVisualProperties(
recyclable_compositor_->UpdateSurface(dfh_size_pixels_,
dfh_display_.device_scale_factor());
}
- GetDelegatedFrameHost()->SynchronizeVisualProperties(
+ GetDelegatedFrameHost()->EmbedSurface(
dfh_local_surface_id_allocator_.GetCurrentLocalSurfaceId(),
- dfh_size_dip_, GetDeadlinePolicy());
+ dfh_size_dip_, GetDeadlinePolicy(true /* is_resize */));
}
- client_->SynchronizeVisualProperties();
+ client_->SynchronizeVisualProperties(child_allocated_local_surface_id);
}
void BrowserCompositorMac::UpdateVSyncParameters(
const base::TimeTicks& timebase,
const base::TimeDelta& interval) {
- if (recyclable_compositor_) {
- recyclable_compositor_->compositor()->SetDisplayVSyncParameters(
- timebase, interval);
- }
+ ui::Compositor* compositor = nullptr;
+ if (recyclable_compositor_)
+ compositor = recyclable_compositor_->compositor();
+ // TODO(ccameron): VSync parameters for a ui::Compositor should be tracked
+ // with the owner of that ui::Compositor (which, in the case of MacViews, is
+ // BridgedNativeView). For the moment, push the VSync parameters from here to
+ // the BridgedNativeView's ui::Compositor because that is a small change and
+ // is easy to merge.
+ // https://crbug.com/869129
+ if (parent_ui_layer_)
+ compositor = parent_ui_layer_->GetCompositor();
+ if (compositor)
+ compositor->SetDisplayVSyncParameters(timebase, interval);
}
void BrowserCompositorMac::SetRenderWidgetHostIsHidden(bool hidden) {
@@ -377,6 +223,10 @@ void BrowserCompositorMac::SetNSViewAttachedToWindow(bool attached) {
UpdateState();
}
+void BrowserCompositorMac::SetViewVisible(bool visible) {
+ root_layer_->SetVisible(visible);
+}
+
void BrowserCompositorMac::UpdateState() {
// Always use the parent ui::Layer's ui::Compositor if available.
if (parent_ui_layer_) {
@@ -405,9 +255,12 @@ void BrowserCompositorMac::TransitionToState(State new_state) {
// Note that the state enum values represent the other through which
// transitions must be done (see comments in State definition).
- // Transition UseParentLayerCompositor -> HasNoCompositor.
+ // Transition UseParentLayerCompositor -> HasNoCompositor. Note that this
+ // transition will be made if we are already in UseParentLayerCompositor, but
+ // with a different parent layer.
if (state_ == UseParentLayerCompositor &&
- new_state < UseParentLayerCompositor) {
+ (new_state < UseParentLayerCompositor ||
+ parent_ui_layer_ != root_layer_->parent())) {
DCHECK(root_layer_->parent());
root_layer_->parent()->RemoveObserver(this);
root_layer_->parent()->Remove(root_layer_.get());
@@ -418,14 +271,16 @@ void BrowserCompositorMac::TransitionToState(State new_state) {
// Transition HasNoCompositor -> HasDetachedCompositor.
if (state_ == HasNoCompositor && new_state < HasNoCompositor) {
- recyclable_compositor_ = RecyclableCompositorMac::Create();
+ recyclable_compositor_ =
+ ui::RecyclableCompositorMacFactory::Get()->CreateCompositor(
+ content::GetContextFactory(), content::GetContextFactoryPrivate());
recyclable_compositor_->UpdateSurface(dfh_size_pixels_,
dfh_display_.device_scale_factor());
recyclable_compositor_->compositor()->SetRootLayer(root_layer_.get());
recyclable_compositor_->compositor()->SetBackgroundColor(background_color_);
recyclable_compositor_->compositor()->SetDisplayColorSpace(
dfh_display_.color_space());
- recyclable_compositor_->accelerated_widget_mac()->SetNSView(
+ recyclable_compositor_->widget()->SetNSView(
accelerated_widget_mac_ns_view_);
state_ = HasDetachedCompositor;
}
@@ -434,7 +289,7 @@ void BrowserCompositorMac::TransitionToState(State new_state) {
if (state_ == HasDetachedCompositor && new_state < HasDetachedCompositor) {
delegated_frame_host_->SetCompositor(recyclable_compositor_->compositor());
delegated_frame_host_->WasShown(GetRendererLocalSurfaceId(), dfh_size_dip_,
- ui::LatencyInfo());
+ false /* record_presentation_time */);
// If there exists a saved frame ready to display, unsuspend the compositor
// now (if one is not ready, the compositor will unsuspend on first surface
@@ -459,10 +314,11 @@ void BrowserCompositorMac::TransitionToState(State new_state) {
// Transition HasDetachedCompositor -> HasNoCompositor.
if (state_ == HasDetachedCompositor && new_state > HasDetachedCompositor) {
- recyclable_compositor_->accelerated_widget_mac()->ResetNSView();
+ recyclable_compositor_->widget()->ResetNSView();
recyclable_compositor_->compositor()->SetRootLayer(nullptr);
recyclable_compositor_->InvalidateSurface();
- RecyclableCompositorMac::Recycle(std::move(recyclable_compositor_));
+ ui::RecyclableCompositorMacFactory::Get()->RecycleCompositor(
+ std::move(recyclable_compositor_));
state_ = HasNoCompositor;
}
@@ -473,7 +329,7 @@ void BrowserCompositorMac::TransitionToState(State new_state) {
DCHECK(!root_layer_->parent());
delegated_frame_host_->SetCompositor(parent_ui_layer_->GetCompositor());
delegated_frame_host_->WasShown(GetRendererLocalSurfaceId(), dfh_size_dip_,
- ui::LatencyInfo());
+ false /* record_presentation_time */);
parent_ui_layer_->Add(root_layer_.get());
parent_ui_layer_->AddObserver(this);
state_ = UseParentLayerCompositor;
@@ -490,7 +346,8 @@ void BrowserCompositorMac::DisableRecyclingForShutdown() {
*g_browser_compositors.Get().begin();
browser_compositor->client_->DestroyCompositorForShutdown();
}
- g_spare_recyclable_compositors.Get().clear();
+
+ ui::RecyclableCompositorMacFactory::Get()->DisableRecyclingForShutdown();
}
void BrowserCompositorMac::SetNeedsBeginFrames(bool needs_begin_frames) {
@@ -534,19 +391,6 @@ void BrowserCompositorMac::OnFirstSurfaceActivation(
return;
recyclable_compositor_->Unsuspend();
-
- // Disable screen updates until the frame of the new size appears (because the
- // content is drawn in the GPU process, it may change before we want it to).
- if (repaint_state_ == RepaintState::Paused) {
- bool compositor_is_nsview_size =
- recyclable_compositor_->pixel_size() == dfh_size_pixels_ &&
- recyclable_compositor_->scale_factor() ==
- dfh_display_.device_scale_factor();
- if (compositor_is_nsview_size || repaint_auto_resize_enabled_) {
- NSDisableScreenUpdates();
- repaint_state_ = RepaintState::ScreenUpdatesDisabled;
- }
- }
}
void BrowserCompositorMac::OnBeginFrame(base::TimeTicks frame_time) {
@@ -564,10 +408,10 @@ void BrowserCompositorMac::DidNavigate() {
dfh_local_surface_id_allocator_.GenerateId();
const viz::LocalSurfaceId& local_surface_id =
dfh_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
- delegated_frame_host_->SynchronizeVisualProperties(
+ delegated_frame_host_->EmbedSurface(
local_surface_id, dfh_size_dip_,
cc::DeadlinePolicy::UseExistingDeadline());
- client_->SynchronizeVisualProperties();
+ client_->SynchronizeVisualProperties(local_surface_id);
delegated_frame_host_->DidNavigate();
is_first_navigation_ = false;
}
@@ -576,17 +420,6 @@ void BrowserCompositorMac::DidReceiveFirstFrameAfterNavigation() {
client_->DidReceiveFirstFrameAfterNavigation();
}
-void BrowserCompositorMac::BeginPauseForFrame(bool auto_resize_enabled) {
- repaint_auto_resize_enabled_ = auto_resize_enabled;
- repaint_state_ = RepaintState::Paused;
-}
-
-void BrowserCompositorMac::EndPauseForFrame() {
- if (repaint_state_ == RepaintState::ScreenUpdatesDisabled)
- NSEnableScreenUpdates();
- repaint_state_ = RepaintState::None;
-}
-
bool BrowserCompositorMac::ShouldContinueToPauseForFrame() const {
if (state_ == UseParentLayerCompositor)
return false;
@@ -599,21 +432,20 @@ bool BrowserCompositorMac::ShouldContinueToPauseForFrame() const {
if (!recyclable_compositor_)
return false;
- return !recyclable_compositor_->accelerated_widget_mac()->HasFrameOfSize(
- dfh_size_dip_);
+ return !recyclable_compositor_->widget()->HasFrameOfSize(dfh_size_dip_);
}
void BrowserCompositorMac::SetParentUiLayer(ui::Layer* new_parent_ui_layer) {
- if (new_parent_ui_layer) {
+ if (new_parent_ui_layer)
DCHECK(new_parent_ui_layer->GetCompositor());
- DCHECK(!parent_ui_layer_);
- parent_ui_layer_ = new_parent_ui_layer;
- } else if (parent_ui_layer_) {
- DCHECK(root_layer_->parent());
- DCHECK_EQ(root_layer_->parent(), parent_ui_layer_);
- parent_ui_layer_ = nullptr;
- }
+
+ // Set |parent_ui_layer_| to the new value, which potentially not match the
+ // value of |root_layer_->parent()|. The call to UpdateState will re-parent
+ // |root_layer_|.
+ DCHECK_EQ(root_layer_->parent(), parent_ui_layer_);
+ parent_ui_layer_ = new_parent_ui_layer;
UpdateState();
+ DCHECK_EQ(root_layer_->parent(), parent_ui_layer_);
}
bool BrowserCompositorMac::ForceNewSurfaceForTesting() {
@@ -641,12 +473,24 @@ const viz::LocalSurfaceId& BrowserCompositorMac::GetRendererLocalSurfaceId() {
return dfh_local_surface_id_allocator_.GenerateId();
}
+const viz::LocalSurfaceId&
+BrowserCompositorMac::AllocateNewRendererLocalSurfaceId() {
+ return dfh_local_surface_id_allocator_.GenerateId();
+}
+
bool BrowserCompositorMac::UpdateRendererLocalSurfaceIdFromChild(
const viz::LocalSurfaceId& child_allocated_local_surface_id) {
return dfh_local_surface_id_allocator_.UpdateFromChild(
child_allocated_local_surface_id);
}
+void BrowserCompositorMac::TransformPointToRootSurface(gfx::PointF* point) {
+ gfx::Transform transform_to_root;
+ if (parent_ui_layer_)
+ parent_ui_layer_->GetTargetTransformRelativeTo(nullptr, &transform_to_root);
+ transform_to_root.TransformPoint(point);
+}
+
void BrowserCompositorMac::LayerDestroyed(ui::Layer* layer) {
DCHECK_EQ(layer, parent_ui_layer_);
SetParentUiLayer(nullptr);
@@ -658,9 +502,12 @@ ui::Compositor* BrowserCompositorMac::GetCompositorForTesting() const {
return nullptr;
}
-cc::DeadlinePolicy BrowserCompositorMac::GetDeadlinePolicy() const {
- // Determined empirically for smoothness.
- uint32_t frames_to_wait = 8;
+cc::DeadlinePolicy BrowserCompositorMac::GetDeadlinePolicy(
+ bool is_resize) const {
+ // Determined empirically for smoothness. Don't wait for non-resize frames,
+ // as it can cause jank at new tab creation.
+ // https://crbug.com/855364
+ uint32_t frames_to_wait = is_resize ? 8 : 0;
// When using the RecyclableCompositor, never wait for frames to arrive
// (surface sync is managed by the Suspend/Unsuspend lock).
diff --git a/chromium/content/browser/renderer_host/clipboard_host_impl.cc b/chromium/content/browser/renderer_host/clipboard_host_impl.cc
index a951584df7c..60928166661 100644
--- a/chromium/content/browser/renderer_host/clipboard_host_impl.cc
+++ b/chromium/content/browser/renderer_host/clipboard_host_impl.cc
@@ -4,100 +4,30 @@
#include "content/browser/renderer_host/clipboard_host_impl.h"
-#include <limits>
#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 "content/public/browser/browser_thread.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);
-}
-
-void OnReadAndEncodeImageFinished(
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
- std::vector<uint8_t> png_data,
- ClipboardHostImpl::ReadImageCallback callback) {
- // |blob_storage_context| must be accessed only on the IO thread.
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- blink::mojom::SerializedBlobPtr blob;
- 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::string blob_uuid = blob_handle->GetUUID();
- blob = blink::mojom::SerializedBlob::New(
- blob_uuid, ui::Clipboard::kMimeTypePNG,
- static_cast<int64_t>(png_data.size()),
- blob_handle->PassBlob().PassInterface());
- }
- }
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), std::move(blob)));
-}
-
-void ReadAndEncodeImage(
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
- const SkBitmap& bitmap,
- ClipboardHostImpl::ReadImageCallback callback) {
- std::vector<uint8_t> png_data;
- if (!gfx::PNGCodec::FastEncodeBGRASkBitmap(bitmap, false, &png_data)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), nullptr));
- return;
- }
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&OnReadAndEncodeImageFinished,
- std::move(blob_storage_context), std::move(png_data),
- std::move(callback)));
-}
-
-} // namespace
-
-ClipboardHostImpl::ClipboardHostImpl(
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context)
+ClipboardHostImpl::ClipboardHostImpl()
: 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);
-}
+ new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE)) {}
-void ClipboardHostImpl::Create(
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
- blink::mojom::ClipboardHostRequest request) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
+void ClipboardHostImpl::Create(blink::mojom::ClipboardHostRequest request) {
mojo::MakeStrongBinding(
- base::WrapUnique<ClipboardHostImpl>(
- new ClipboardHostImpl(std::move(blob_storage_context))),
+ base::WrapUnique<ClipboardHostImpl>(new ClipboardHostImpl()),
std::move(request));
}
@@ -107,14 +37,12 @@ ClipboardHostImpl::~ClipboardHostImpl() {
void ClipboardHostImpl::GetSequenceNumber(ui::ClipboardType clipboard_type,
GetSequenceNumberCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::move(callback).Run(clipboard_->GetSequenceNumber(clipboard_type));
}
void ClipboardHostImpl::ReadAvailableTypes(
ui::ClipboardType clipboard_type,
ReadAvailableTypesCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::vector<base::string16> types;
bool contains_filenames;
clipboard_->ReadAvailableTypes(clipboard_type, &types, &contains_filenames);
@@ -124,7 +52,6 @@ void ClipboardHostImpl::ReadAvailableTypes(
void ClipboardHostImpl::IsFormatAvailable(blink::mojom::ClipboardFormat format,
ui::ClipboardType clipboard_type,
IsFormatAvailableCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
bool result = false;
switch (format) {
case blink::mojom::ClipboardFormat::kPlaintext:
@@ -155,8 +82,6 @@ void ClipboardHostImpl::IsFormatAvailable(blink::mojom::ClipboardFormat format,
void ClipboardHostImpl::ReadText(ui::ClipboardType clipboard_type,
ReadTextCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
base::string16 result;
if (clipboard_->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(),
clipboard_type)) {
@@ -172,8 +97,6 @@ void ClipboardHostImpl::ReadText(ui::ClipboardType clipboard_type,
void ClipboardHostImpl::ReadHtml(ui::ClipboardType clipboard_type,
ReadHtmlCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
base::string16 markup;
std::string src_url_str;
uint32_t fragment_start = 0;
@@ -186,8 +109,6 @@ void ClipboardHostImpl::ReadHtml(ui::ClipboardType clipboard_type,
void ClipboardHostImpl::ReadRtf(ui::ClipboardType clipboard_type,
ReadRtfCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
std::string result;
clipboard_->ReadRTF(clipboard_type, &result);
std::move(callback).Run(result);
@@ -195,27 +116,13 @@ void ClipboardHostImpl::ReadRtf(ui::ClipboardType clipboard_type,
void ClipboardHostImpl::ReadImage(ui::ClipboardType clipboard_type,
ReadImageCallback callback) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
- SkBitmap bitmap = clipboard_->ReadImage(clipboard_type);
-
- if (bitmap.isNull()) {
- std::move(callback).Run(nullptr);
- return;
- }
- base::PostTaskWithTraits(
- FROM_HERE,
- {base::MayBlock(), base::TaskPriority::BACKGROUND,
- base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
- base::BindOnce(&ReadAndEncodeImage, blob_storage_context_,
- std::move(bitmap), std::move(callback)));
+ SkBitmap result = clipboard_->ReadImage(clipboard_type);
+ std::move(callback).Run(result);
}
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);
@@ -223,26 +130,22 @@ void ClipboardHostImpl::ReadCustomData(ui::ClipboardType clipboard_type,
void ClipboardHostImpl::WriteText(ui::ClipboardType,
const base::string16& text) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
clipboard_writer_->WriteText(text);
}
void ClipboardHostImpl::WriteHtml(ui::ClipboardType,
const base::string16& markup,
const GURL& url) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
clipboard_writer_->WriteHTML(markup, url.spec());
}
void ClipboardHostImpl::WriteSmartPasteMarker(ui::ClipboardType) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
clipboard_writer_->WriteWebSmartPaste();
}
void ClipboardHostImpl::WriteCustomData(
ui::ClipboardType,
const base::flat_map<base::string16, base::string16>& data) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
base::Pickle pickle;
ui::WriteCustomDataToPickle(data, &pickle);
clipboard_writer_->WritePickledData(
@@ -252,41 +155,14 @@ void ClipboardHostImpl::WriteCustomData(
void ClipboardHostImpl::WriteBookmark(ui::ClipboardType,
const std::string& url,
const base::string16& title) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
clipboard_writer_->WriteBookmark(title, url);
}
-void ClipboardHostImpl::WriteImage(
- ui::ClipboardType,
- 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();
+void ClipboardHostImpl::WriteImage(ui::ClipboardType, const SkBitmap& bitmap) {
clipboard_writer_->WriteImage(bitmap);
}
void ClipboardHostImpl::CommitWrite(ui::ClipboardType) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
clipboard_writer_.reset(
new ui::ScopedClipboardWriter(ui::CLIPBOARD_TYPE_COPY_PASTE));
}
diff --git a/chromium/content/browser/renderer_host/clipboard_host_impl.h b/chromium/content/browser/renderer_host/clipboard_host_impl.h
index 7199ebced1b..f9c6a3db4af 100644
--- a/chromium/content/browser/renderer_host/clipboard_host_impl.h
+++ b/chromium/content/browser/renderer_host/clipboard_host_impl.h
@@ -5,50 +5,35 @@
#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 <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/content_export.h"
-#include "content/public/browser/browser_associated_interface.h"
-#include "content/public/browser/browser_message_filter.h"
#include "third_party/blink/public/mojom/clipboard/clipboard.mojom.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 blink::mojom::ClipboardHost {
public:
~ClipboardHostImpl() override;
- static void Create(
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context,
- blink::mojom::ClipboardHostRequest request);
+ static void Create(blink::mojom::ClipboardHostRequest request);
private:
friend class ClipboardHostImplTest;
- explicit ClipboardHostImpl(
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context);
+ ClipboardHostImpl();
// content::mojom::ClipboardHost
void GetSequenceNumber(ui::ClipboardType clipboard_type,
@@ -82,15 +67,13 @@ class CONTENT_EXPORT ClipboardHostImpl : public blink::mojom::ClipboardHost {
const std::string& url,
const base::string16& title) override;
void WriteImage(ui::ClipboardType clipboard_type,
- const gfx::Size& size_in_pixels,
- mojo::ScopedSharedBufferHandle shared_buffer_handle) override;
+ const SkBitmap& bitmap) override;
void CommitWrite(ui::ClipboardType clipboard_type) override;
#if defined(OS_MACOSX)
void WriteStringToFindPboard(const base::string16& text) override;
#endif
ui::Clipboard* clipboard_; // Not owned
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
std::unique_ptr<ui::ScopedClipboardWriter> clipboard_writer_;
};
diff --git a/chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc b/chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc
index 704acc6673d..a3a0e92ec35 100644
--- a/chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc
+++ b/chromium/content/browser/renderer_host/clipboard_host_impl_unittest.cc
@@ -6,41 +6,31 @@
#include <stddef.h>
#include <stdint.h>
-#include <string.h>
-#include "base/memory/ref_counted.h"
-#include "base/process/process_handle.h"
#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"
-#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/skia_util.h"
namespace content {
class ClipboardHostImplTest : public ::testing::Test {
protected:
ClipboardHostImplTest()
- : host_(new ClipboardHostImpl(nullptr)),
- clipboard_(ui::TestClipboard::CreateForCurrentThread()) {}
+ : clipboard_(ui::TestClipboard::CreateForCurrentThread()) {}
~ClipboardHostImplTest() override {
ui::Clipboard::DestroyClipboardForCurrentThread();
}
- void CallWriteImage(const gfx::Size& size,
- 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 CallWriteImage(const SkBitmap& bitmap) {
+ host_.WriteImage(ui::CLIPBOARD_TYPE_COPY_PASTE, bitmap);
}
void CallCommitWrite() {
- host_->CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
+ host_.CommitWrite(ui::CLIPBOARD_TYPE_COPY_PASTE);
base::RunLoop().RunUntilIdle();
}
@@ -48,27 +38,16 @@ class ClipboardHostImplTest : public ::testing::Test {
private:
const TestBrowserThreadBundle thread_bundle_;
- const std::unique_ptr<ClipboardHostImpl> host_;
+ ClipboardHostImpl host_;
ui::Clipboard* const clipboard_;
};
// Test that it actually works.
TEST_F(ClipboardHostImplTest, SimpleImage) {
- static const uint32_t bitmap_data[] = {
- 0x33333333, 0xdddddddd, 0xeeeeeeee, 0x00000000, 0x88888888, 0x66666666,
- 0x55555555, 0xbbbbbbbb, 0x44444444, 0xaaaaaaaa, 0x99999999, 0x77777777,
- 0xffffffff, 0x11111111, 0x22222222, 0xcccccccc,
- };
-
- mojo::ScopedSharedBufferHandle shared_memory =
- mojo::SharedBufferHandle::Create(sizeof(bitmap_data));
- mojo::ScopedSharedBufferMapping mapping =
- shared_memory->Map(sizeof(bitmap_data));
-
- memcpy(mapping.get(), bitmap_data, sizeof(bitmap_data));
-
- CallWriteImage(gfx::Size(4, 4), std::move(shared_memory),
- sizeof(bitmap_data));
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(3, 2);
+ bitmap.eraseARGB(255, 0, 255, 0);
+ CallWriteImage(bitmap);
uint64_t sequence_number =
clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE);
CallCommitWrite();
@@ -81,26 +60,7 @@ TEST_F(ClipboardHostImplTest, SimpleImage) {
ui::Clipboard::GetBitmapFormatType(), ui::CLIPBOARD_TYPE_COPY_PASTE));
SkBitmap actual = clipboard()->ReadImage(ui::CLIPBOARD_TYPE_COPY_PASTE);
- EXPECT_EQ(sizeof(bitmap_data), actual.computeByteSize());
- EXPECT_EQ(0,
- memcmp(bitmap_data, actual.getAddr32(0, 0), sizeof(bitmap_data)));
-}
-
-// Test with a size that would overflow a naive 32-bit row bytes calculation.
-TEST_F(ClipboardHostImplTest, ImageSizeOverflows32BitRowBytes) {
- mojo::ScopedSharedBufferHandle shared_memory =
- mojo::SharedBufferHandle::Create(0x20000000);
-
- mojo::ScopedSharedBufferMapping mapping = shared_memory->Map(0x20000000);
-
- CallWriteImage(gfx::Size(0x20000000, 1), std::move(shared_memory),
- 0x20000000);
- uint64_t sequence_number =
- clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE);
- CallCommitWrite();
-
- EXPECT_EQ(sequence_number,
- clipboard()->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE));
+ EXPECT_TRUE(gfx::BitmapsAreEqual(bitmap, actual));
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.cc b/chromium/content/browser/renderer_host/compositor_impl_android.cc
index 12b20bd638a..454ebcafa7a 100644
--- a/chromium/content/browser/renderer_host/compositor_impl_android.cc
+++ b/chromium/content/browser/renderer_host/compositor_impl_android.cc
@@ -34,11 +34,11 @@
#include "cc/base/switches.h"
#include "cc/input/input_handler.h"
#include "cc/layers/layer.h"
+#include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
#include "cc/raster/single_thread_task_graph_runner.h"
#include "cc/resources/ui_resource_manager.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_settings.h"
-#include "components/viz/client/client_layer_tree_frame_sink.h"
#include "components/viz/client/frame_eviction_manager.h"
#include "components/viz/client/hit_test_data_provider_draw_quad.h"
#include "components/viz/client/local_surface_id_provider.h"
@@ -48,6 +48,7 @@
#include "components/viz/common/gpu/vulkan_in_process_context_provider.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/surfaces/frame_sink_id_allocator.h"
+#include "components/viz/host/host_display_client.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "components/viz/service/display/display.h"
#include "components/viz/service/display/display_scheduler.h"
@@ -59,15 +60,16 @@
#include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "content/browser/browser_main_loop.h"
-#include "content/browser/compositor/in_process_display_client.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/gpu/compositor_util.h"
+#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/gpu_stream_constants.h"
#include "content/public/browser/android/compositor.h"
#include "content/public/browser/android/compositor_client.h"
#include "content/public/browser/browser_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/command_buffer/common/swap_buffers_complete_params.h"
@@ -76,6 +78,8 @@
#include "gpu/ipc/client/gpu_channel_host.h"
#include "gpu/ipc/common/gpu_surface_tracker.h"
#include "gpu/vulkan/buildflags.h"
+#include "gpu/vulkan/init/vulkan_factory.h"
+#include "gpu/vulkan/vulkan_implementation.h"
#include "gpu/vulkan/vulkan_surface.h"
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h"
@@ -84,6 +88,7 @@
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/skia/include/core/SkMallocPixelRef.h"
#include "ui/android/window_android.h"
+#include "ui/compositor/host/external_begin_frame_controller_client_impl.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/ca_layer_params.h"
@@ -112,6 +117,24 @@ class SingleThreadTaskGraphRunner : public cc::SingleThreadTaskGraphRunner {
~SingleThreadTaskGraphRunner() override { Shutdown(); }
};
+// An implementation of HostDisplayClient which handles swap callbacks.
+class AndroidHostDisplayClient : public viz::HostDisplayClient {
+ public:
+ explicit AndroidHostDisplayClient(
+ base::RepeatingCallback<void(const gfx::Size&)> on_swap)
+ : HostDisplayClient(gfx::kNullAcceleratedWidget),
+ on_swap_(std::move(on_swap)) {}
+
+ // viz::mojom::DisplayClient implementation:
+ void DidCompleteSwapWithSize(const gfx::Size& pixel_size) override {
+ if (on_swap_)
+ on_swap_.Run(pixel_size);
+ }
+
+ private:
+ base::RepeatingCallback<void(const gfx::Size&)> on_swap_;
+};
+
class CompositorDependencies {
public:
static CompositorDependencies& Get() {
@@ -129,13 +152,13 @@ class CompositorDependencies {
mojo::MakeRequest(&frame_sink_manager_client);
// Setup HostFrameSinkManager with interface endpoints.
- GetHostFrameSinkManager()->BindAndSetManager(
+ host_frame_sink_manager.BindAndSetManager(
std::move(frame_sink_manager_client_request),
base::ThreadTaskRunnerHandle::Get(), std::move(frame_sink_manager));
// Set up a callback to automatically re-connect if we lose our
// connection.
- GetHostFrameSinkManager()->SetConnectionLostCallback(base::BindRepeating(
+ host_frame_sink_manager.SetConnectionLostCallback(base::BindRepeating(
[]() { CompositorDependencies::Get().CreateVizFrameSinkManager(); }));
BrowserMainLoop::GetInstance()
@@ -160,11 +183,8 @@ class CompositorDependencies {
// http://crbug.com/657959.
std::unique_ptr<viz::FrameSinkManagerImpl> frame_sink_manager_impl;
- // Viz-only members:
- viz::mojom::DisplayPrivateAssociatedPtr display_private;
- std::unique_ptr<InProcessDisplayClient> display_client;
-
#if BUILDFLAG(ENABLE_VULKAN)
+ std::unique_ptr<gpu::VulkanImplementation> vulkan_implementation;
scoped_refptr<viz::VulkanContextProvider> vulkan_context_provider;
#endif
private:
@@ -174,9 +194,14 @@ class CompositorDependencies {
bool enable_viz =
base::FeatureList::IsEnabled(features::kVizDisplayCompositor);
if (!enable_viz) {
- frame_sink_manager_impl = std::make_unique<viz::FrameSinkManagerImpl>();
+ // The SharedBitmapManager can be null as software compositing is not
+ // supported or used on Android.
+ frame_sink_manager_impl = std::make_unique<viz::FrameSinkManagerImpl>(
+ /*shared_bitmap_manager=*/nullptr);
surface_utils::ConnectWithLocalFrameSinkManager(
&host_frame_sink_manager, frame_sink_manager_impl.get());
+ } else {
+ CreateVizFrameSinkManager();
}
}
@@ -219,15 +244,21 @@ const unsigned int kMaxDisplaySwapBuffers = 1U;
#if BUILDFLAG(ENABLE_VULKAN)
scoped_refptr<viz::VulkanContextProvider> GetSharedVulkanContextProvider() {
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableVulkan)) {
- scoped_refptr<viz::VulkanContextProvider> context_provider =
- CompositorDependencies::Get().vulkan_context_provider;
- if (!*context_provider)
- *context_provider = viz::VulkanInProcessContextProvider::Create();
- return *context_provider;
+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableVulkan))
+ return nullptr;
+
+ scoped_refptr<viz::VulkanContextProvider>& context_provider =
+ CompositorDependencies::Get().vulkan_context_provider;
+ if (!context_provider) {
+ std::unique_ptr<gpu::VulkanImplementation>& vulkan_implementation =
+ CompositorDependencies::Get().vulkan_implementation;
+ DCHECK(!vulkan_implementation);
+ vulkan_implementation = gpu::CreateVulkanImplementation();
+ context_provider = viz::VulkanInProcessContextProvider::Create(
+ vulkan_implementation.get());
}
- return nullptr;
+ return context_provider;
}
#endif
@@ -336,7 +367,7 @@ void CreateContextProviderAfterGpuChannelEstablished(
GURL(std::string("chrome://gpu/Compositor::CreateContextProvider")),
automatic_flushes, support_locking, support_grcontext,
shared_memory_limits, attributes,
- ui::command_buffer_metrics::CONTEXT_TYPE_UNKNOWN);
+ ui::command_buffer_metrics::ContextType::UNKNOWN);
callback.Run(std::move(context_provider));
}
@@ -344,7 +375,7 @@ class AndroidOutputSurface : public viz::OutputSurface {
public:
AndroidOutputSurface(
scoped_refptr<ui::ContextProviderCommandBuffer> context_provider,
- base::RepeatingCallback<void(gfx::Size)> swap_buffers_callback)
+ base::RepeatingCallback<void(const gfx::Size&)> swap_buffers_callback)
: viz::OutputSurface(std::move(context_provider)),
swap_buffers_callback_(std::move(swap_buffers_callback)),
overlay_candidate_validator_(
@@ -356,9 +387,6 @@ class AndroidOutputSurface : public viz::OutputSurface {
~AndroidOutputSurface() override = default;
void SwapBuffers(viz::OutputSurfaceFrame frame) override {
- if (LatencyInfoHasSnapshotRequest(frame.latency_info))
- GetCommandBufferProxy()->SetSnapshotRequested();
-
auto callback =
base::BindOnce(&AndroidOutputSurface::OnSwapBuffersCompleted,
weak_ptr_factory_.GetWeakPtr(),
@@ -381,6 +409,13 @@ class AndroidOutputSurface : public viz::OutputSurface {
}
}
+#if BUILDFLAG(ENABLE_VULKAN)
+ gpu::VulkanSurface* GetVulkanSurface() override {
+ NOTIMPLEMENTED();
+ return nullptr;
+ }
+#endif
+
void BindToClient(viz::OutputSurfaceClient* client) override {
DCHECK(client);
DCHECK(!client_);
@@ -446,7 +481,6 @@ class AndroidOutputSurface : public viz::OutputSurface {
client_->DidReceiveSwapBuffersAck();
swap_buffers_callback_.Run(swap_size);
UpdateLatencyInfoOnSwap(params.swap_response, &latency_info);
- RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(latency_info);
latency_tracker_.OnGpuSwapBuffersCompleted(latency_info);
}
@@ -456,7 +490,7 @@ class AndroidOutputSurface : public viz::OutputSurface {
private:
viz::OutputSurfaceClient* client_ = nullptr;
- base::RepeatingCallback<void(gfx::Size)> swap_buffers_callback_;
+ base::RepeatingCallback<void(const gfx::Size&)> swap_buffers_callback_;
std::unique_ptr<viz::OverlayCandidateValidator> overlay_candidate_validator_;
ui::LatencyTracker latency_tracker_;
@@ -478,7 +512,8 @@ class VulkanOutputSurface : public viz::OutputSurface {
bool Initialize(gfx::AcceleratedWidget widget) {
DCHECK(!surface_);
std::unique_ptr<gpu::VulkanSurface> surface(
- gpu::VulkanSurface::CreateViewSurface(widget));
+ vulkan_context_provider()->GetVulkanImplementation()->CreateViewSurface(
+ widget));
if (!surface->Initialize(vulkan_context_provider()->GetDeviceQueue(),
gpu::VulkanSurface::DEFAULT_SURFACE_FORMAT)) {
return false;
@@ -488,19 +523,73 @@ class VulkanOutputSurface : public viz::OutputSurface {
return true;
}
- bool BindToClient(viz::OutputSurfaceClient* client) override {
- if (!OutputSurface::BindToClient(client))
- return false;
- return true;
+ void BindToClient(viz::OutputSurfaceClient* client) override {
+ client_ = client;
}
- void SwapBuffers(viz::CompositorFrame frame) override {
+ void EnsureBackbuffer() override { NOTIMPLEMENTED(); }
+
+ void DiscardBackbuffer() override { NOTIMPLEMENTED(); }
+
+ void BindFramebuffer() override { NOTIMPLEMENTED(); }
+
+ void SetDrawRectangle(const gfx::Rect& rect) override { NOTIMPLEMENTED(); }
+
+ viz::OverlayCandidateValidator* GetOverlayCandidateValidator()
+ const override {
+ NOTIMPLEMENTED();
+ return nullptr;
+ }
+
+ bool IsDisplayedAsOverlayPlane() const override {
+ NOTIMPLEMENTED();
+ return false;
+ }
+
+ unsigned GetOverlayTextureId() const override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
+
+ gfx::BufferFormat GetOverlayBufferFormat() const override {
+ NOTIMPLEMENTED();
+ return gfx::BufferFormat::BGRA_8888;
+ }
+
+ void Reshape(const gfx::Size& size,
+ float device_scale_factor,
+ const gfx::ColorSpace& color_space,
+ bool has_alpha,
+ bool use_stencil) override {
+ NOTIMPLEMENTED();
+ }
+
+ bool HasExternalStencilTest() const override {
+ NOTIMPLEMENTED();
+ return false;
+ }
+
+ void ApplyExternalStencil() override { NOTIMPLEMENTED(); }
+
+ uint32_t GetFramebufferCopyTextureFormat() override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
+
+ void SwapBuffers(viz::OutputSurfaceFrame frame) override {
surface_->SwapBuffers();
task_runner_->PostTask(FROM_HERE,
base::Bind(&VulkanOutputSurface::SwapBuffersAck,
weak_ptr_factory_.GetWeakPtr()));
}
+ gpu::VulkanSurface* GetVulkanSurface() override { return surface_.get(); }
+
+ unsigned UpdateGpuFence() override {
+ NOTIMPLEMENTED();
+ return 0;
+ }
+
void Destroy() {
if (surface_) {
surface_->Destroy();
@@ -511,9 +600,8 @@ class VulkanOutputSurface : public viz::OutputSurface {
private:
void SwapBuffersAck() { client_->DidReceiveSwapBuffersAck(); }
-#if BUILDFLAG(ENABLE_VULKAN)
std::unique_ptr<gpu::VulkanSurface> surface_;
-#endif
+ viz::OutputSurfaceClient* client_ = nullptr;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::WeakPtrFactory<VulkanOutputSurface> weak_ptr_factory_;
@@ -521,6 +609,11 @@ class VulkanOutputSurface : public viz::OutputSurface {
};
#endif
+// TODO(khushalsagar): These are being sent based on the CompositorImpl
+// visiblity which bakes in the assumption that there is a single CompositorImpl
+// instance per application, while the embedder could potentially create
+// multiple compositor instances. We should use the ApplicationStateListener to
+// send these notifications to the GPU instead. See crbug.com/859723.
void SendOnBackgroundedToGpuService() {
content::GpuProcessHost::CallOnIO(
content::GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
@@ -610,12 +703,6 @@ CompositorImpl::CompositorImpl(CompositorClient* client,
enable_viz_(
base::FeatureList::IsEnabled(features::kVizDisplayCompositor)),
weak_factory_(this) {
- // In Viz mode, we create the frame sink manager here. For some reason we
- // can't do this in the CompositorDependencies constructor.
- // TODO(ericrk): Investigate this.
- if (enable_viz_)
- CompositorDependencies::Get().CreateVizFrameSinkManager();
-
GetHostFrameSinkManager()->RegisterFrameSinkId(frame_sink_id_, this);
GetHostFrameSinkManager()->SetFrameSinkDebugLabel(frame_sink_id_,
"CompositorImpl");
@@ -641,10 +728,6 @@ void CompositorImpl::DetachRootWindow() {
root_window_->SetLayer(nullptr);
}
-bool CompositorImpl::IsForSubframe() {
- return false;
-}
-
ui::UIResourceProvider& CompositorImpl::GetUIResourceProvider() {
return *this;
}
@@ -751,6 +834,8 @@ void CompositorImpl::CreateLayerTreeHost() {
command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
settings.initial_debug_state.show_fps_counter =
command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
+ if (command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders))
+ settings.initial_debug_state.show_debug_borders.set();
settings.single_thread_proxy_scheduler = true;
settings.use_painted_device_scale_factor = true;
@@ -791,6 +876,7 @@ void CompositorImpl::SetVisible(bool visible) {
root_window_->GetBeginFrameSource());
}
display_.reset();
+ GpuDataManagerImpl::GetInstance()->SetApplicationVisible(false);
SendOnBackgroundedToGpuService();
EnqueueLowEndBackgroundCleanup();
} else {
@@ -798,11 +884,12 @@ void CompositorImpl::SetVisible(bool visible) {
has_submitted_frame_since_became_visible_ = false;
if (layer_tree_frame_sink_request_pending_)
HandlePendingLayerTreeFrameSinkRequest();
+ GpuDataManagerImpl::GetInstance()->SetApplicationVisible(true);
SendOnForegroundedToGpuService();
low_end_background_cleanup_task_.Cancel();
}
- if (CompositorDependencies::Get().display_private)
- CompositorDependencies::Get().display_private->SetDisplayVisible(visible);
+ if (display_private_)
+ display_private_->SetDisplayVisible(visible);
}
void CompositorImpl::SetWindowBounds(const gfx::Size& size) {
@@ -817,6 +904,10 @@ void CompositorImpl::SetWindowBounds(const gfx::Size& size) {
}
if (display_)
display_->Resize(size);
+
+ if (display_private_)
+ display_private_->Resize(size);
+
root_window_->GetLayer()->SetBounds(size);
}
@@ -872,8 +963,7 @@ void CompositorImpl::HandlePendingLayerTreeFrameSinkRequest() {
return;
#if BUILDFLAG(ENABLE_VULKAN)
- CreateVulkanOutputSurface()
- if (display_)
+ if (CreateVulkanOutputSurface())
return;
#endif
@@ -886,23 +976,25 @@ void CompositorImpl::HandlePendingLayerTreeFrameSinkRequest() {
}
#if BUILDFLAG(ENABLE_VULKAN)
-void CompositorImpl::CreateVulkanOutputSurface() {
+bool CompositorImpl::CreateVulkanOutputSurface() {
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableVulkan))
- return;
+ return false;
scoped_refptr<viz::VulkanContextProvider> vulkan_context_provider =
GetSharedVulkanContextProvider();
if (!vulkan_context_provider)
- return;
+ return false;
// TODO(crbug.com/582558): Need to match GL and implement DidSwapBuffers.
auto vulkan_surface = std::make_unique<VulkanOutputSurface>(
vulkan_context_provider, base::ThreadTaskRunnerHandle::Get());
if (!vulkan_surface->Initialize(window_))
- return;
+ return false;
InitializeDisplay(std::move(vulkan_surface), nullptr);
+
+ return !!display_;
}
#endif
@@ -953,7 +1045,7 @@ void CompositorImpl::OnGpuChannelEstablished(
GetCompositorContextSharedMemoryLimits(root_window_),
GetCompositorContextAttributes(display_color_space_,
requires_alpha_channel_),
- ui::command_buffer_metrics::DISPLAY_COMPOSITOR_ONSCREEN_CONTEXT);
+ ui::command_buffer_metrics::ContextType::BROWSER_COMPOSITOR);
auto result = context_provider->BindToCurrentThread();
LOG_IF(FATAL, result == gpu::ContextResult::kFatalFailure)
<< "Fatal error making Gpu context";
@@ -1006,9 +1098,8 @@ void CompositorImpl::InitializeDisplay(
const bool should_register_begin_frame_source = !display_;
display_ = std::make_unique<viz::Display>(
- viz::ServerSharedBitmapManager::current(), renderer_settings,
- frame_sink_id_, std::move(display_output_surface), std::move(scheduler),
- task_runner);
+ nullptr, renderer_settings, frame_sink_id_,
+ std::move(display_output_surface), std::move(scheduler), task_runner);
auto layer_tree_frame_sink = std::make_unique<viz::DirectLayerTreeFrameSink>(
frame_sink_id_, GetHostFrameSinkManager(), manager, display_.get(),
@@ -1026,8 +1117,11 @@ void CompositorImpl::InitializeDisplay(
host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
}
-void CompositorImpl::DidSwapBuffers(gfx::Size swap_size) {
+void CompositorImpl::DidSwapBuffers(const gfx::Size& swap_size) {
client_->DidSwapBuffers(swap_size);
+
+ if (swap_completed_with_size_for_testing_)
+ swap_completed_with_size_for_testing_.Run(swap_size);
}
cc::UIResourceId CompositorImpl::CreateUIResource(
@@ -1049,12 +1143,6 @@ void CompositorImpl::DidSubmitCompositorFrame() {
TRACE_EVENT0("compositor", "CompositorImpl::DidSubmitCompositorFrame");
pending_frames_++;
has_submitted_frame_since_became_visible_ = true;
-
- if (enable_viz_) {
- // TODO(ericrk): Viz should use the actual swap callback from the Viz
- // process. This is just a workaround until we wire that up.
- DidSwapBuffers(size_);
- }
}
void CompositorImpl::DidReceiveCompositorFrameAck() {
@@ -1116,19 +1204,6 @@ void CompositorImpl::RemoveChildFrameSink(
frame_sink_id);
}
-void CompositorImpl::OnFirstSurfaceActivation(
- const viz::SurfaceInfo& surface_info) {
- if (enable_viz_) {
- // Force a new surface to be generated.
- // TODO(ericrk): Remove this once we correctly set up fallback surfaces.
- host_->SetViewportSizeAndScale(size_, root_window_->GetDipScale(),
- GenerateLocalSurfaceId());
- }
-
- // TODO(fsamuel): Once surface synchronization is turned on, the fallback
- // surface should be set here.
-}
-
void CompositorImpl::OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) {
if (changed_metrics & display::DisplayObserver::DisplayMetric::
@@ -1197,7 +1272,6 @@ void CompositorImpl::InitializeVizLayerTreeFrameSink(
scoped_refptr<ui::ContextProviderCommandBuffer> context_provider) {
DCHECK(enable_viz_);
- auto& deps = CompositorDependencies::Get();
pending_frames_ = 0;
gpu_capabilities_ = context_provider->ContextCapabilities();
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
@@ -1205,15 +1279,20 @@ void CompositorImpl::InitializeVizLayerTreeFrameSink(
auto root_params = viz::mojom::RootCompositorFrameSinkParams::New();
+ // Android requires swap size notifications.
+ root_params->send_swap_size_notifications = true;
+
// Create interfaces for a root CompositorFrameSink.
viz::mojom::CompositorFrameSinkAssociatedPtrInfo sink_info;
root_params->compositor_frame_sink = mojo::MakeRequest(&sink_info);
viz::mojom::CompositorFrameSinkClientRequest client_request =
mojo::MakeRequest(&root_params->compositor_frame_sink_client);
- root_params->display_private = mojo::MakeRequest(&deps.display_private);
- deps.display_client = std::make_unique<InProcessDisplayClient>(window_);
+ root_params->display_private = mojo::MakeRequest(&display_private_);
+ display_client_ =
+ std::make_unique<AndroidHostDisplayClient>(base::BindRepeating(
+ &CompositorImpl::DidSwapBuffers, weak_factory_.GetWeakPtr()));
root_params->display_client =
- deps.display_client->GetBoundPtr(task_runner).PassInterface();
+ display_client_->GetBoundPtr(task_runner).PassInterface();
viz::RendererSettings renderer_settings;
renderer_settings.allow_antialiasing = false;
@@ -1227,7 +1306,7 @@ void CompositorImpl::InitializeVizLayerTreeFrameSink(
std::move(root_params));
// Create LayerTreeFrameSink with the browser end of CompositorFrameSink.
- viz::ClientLayerTreeFrameSink::InitParams params;
+ cc::mojo_embedder::AsyncLayerTreeFrameSink::InitParams params;
params.compositor_task_runner = task_runner;
params.gpu_memory_buffer_manager = BrowserMainLoop::GetInstance()
->gpu_channel_establish_factory()
@@ -1240,10 +1319,12 @@ void CompositorImpl::InitializeVizLayerTreeFrameSink(
params.hit_test_data_provider =
std::make_unique<viz::HitTestDataProviderDrawQuad>(
/*should_ask_for_child_region=*/false);
- auto layer_tree_frame_sink = std::make_unique<viz::ClientLayerTreeFrameSink>(
- std::move(context_provider), nullptr, &params);
+ auto layer_tree_frame_sink =
+ std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>(
+ std::move(context_provider), nullptr, &params);
host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
- CompositorDependencies::Get().display_private->SetDisplayVisible(true);
+ display_private_->SetDisplayVisible(true);
+ display_private_->Resize(size_);
}
viz::LocalSurfaceId CompositorImpl::GenerateLocalSurfaceId() const {
diff --git a/chromium/content/browser/renderer_host/compositor_impl_android.h b/chromium/content/browser/renderer_host/compositor_impl_android.h
index c55917e4a60..ad8f0ea0358 100644
--- a/chromium/content/browser/renderer_host/compositor_impl_android.h
+++ b/chromium/content/browser/renderer_host/compositor_impl_android.h
@@ -16,6 +16,7 @@
#include "base/observer_list.h"
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_host_single_thread_client.h"
+#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "components/viz/host/host_frame_sink_client.h"
@@ -25,11 +26,13 @@
#include "gpu/ipc/common/surface_handle.h"
#include "gpu/vulkan/buildflags.h"
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
+#include "services/viz/privileged/interfaces/compositing/display_private.mojom.h"
#include "third_party/khronos/GLES2/gl2.h"
#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/compositor/compositor_lock.h"
+#include "ui/compositor/external_begin_frame_client.h"
#include "ui/display/display_observer.h"
struct ANativeWindow;
@@ -40,10 +43,15 @@ class Layer;
class LayerTreeHost;
}
+namespace ui {
+class ExternalBeginFrameControllerClientImpl;
+}
+
namespace viz {
class Display;
class FrameSinkId;
class FrameSinkManagerImpl;
+class HostDisplayClient;
class HostFrameSinkManager;
class OutputSurface;
}
@@ -81,6 +89,10 @@ class CONTENT_EXPORT CompositorImpl
// Test functions:
bool IsLockedForTesting() const { return lock_manager_.IsLocked(); }
void SetVisibleForTesting(bool visible) { SetVisible(visible); }
+ void SetSwapCompletedWithSizeCallbackForTesting(
+ base::RepeatingCallback<void(const gfx::Size&)> cb) {
+ swap_completed_with_size_for_testing_ = std::move(cb);
+ }
private:
// Compositor implementation.
@@ -116,7 +128,9 @@ class CONTENT_EXPORT CompositorImpl
void DidCommitAndDrawFrame() override {}
void DidReceiveCompositorFrameAck() override;
void DidCompletePageScaleAnimation() override {}
- bool IsForSubframe() override;
+ void DidPresentCompositorFrame(
+ uint32_t frame_token,
+ const gfx::PresentationFeedback& feedback) override {}
// LayerTreeHostSingleThreadClient implementation.
void DidSubmitCompositorFrame() override;
@@ -136,7 +150,8 @@ class CONTENT_EXPORT CompositorImpl
bool IsDrawingFirstVisibleFrame() const override;
// viz::HostFrameSinkClient implementation.
- void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
+ void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override {
+ }
void OnFrameTokenChanged(uint32_t frame_token) override {}
// display::DisplayObserver implementation.
@@ -152,14 +167,14 @@ class CONTENT_EXPORT CompositorImpl
void HandlePendingLayerTreeFrameSinkRequest();
#if BUILDFLAG(ENABLE_VULKAN)
- void CreateVulkanOutputSurface();
+ bool CreateVulkanOutputSurface();
#endif
void OnGpuChannelEstablished(
scoped_refptr<gpu::GpuChannelHost> gpu_channel_host);
void InitializeDisplay(
std::unique_ptr<viz::OutputSurface> display_output_surface,
scoped_refptr<viz::ContextProvider> context_provider);
- void DidSwapBuffers(gfx::Size swap_size);
+ void DidSwapBuffers(const gfx::Size& swap_size);
bool HavePendingReadbacks();
@@ -235,6 +250,14 @@ class CONTENT_EXPORT CompositorImpl
// If true, we are using a Viz process.
const bool enable_viz_;
+ // Viz-specific members for communicating with the display.
+ viz::mojom::DisplayPrivateAssociatedPtr display_private_;
+ std::unique_ptr<viz::HostDisplayClient> display_client_;
+
+ // Test-only. Called when we are notified of a swap.
+ base::RepeatingCallback<void(const gfx::Size&)>
+ swap_completed_with_size_for_testing_;
+
base::WeakPtrFactory<CompositorImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CompositorImpl);
diff --git a/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc b/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc
index bfaadc54359..a2b349b0a46 100644
--- a/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc
+++ b/chromium/content/browser/renderer_host/compositor_impl_android_browsertest.cc
@@ -3,6 +3,8 @@
// found in the LICENSE file.
#include "base/base_switches.h"
+#include "base/test/scoped_feature_list.h"
+#include "components/viz/common/features.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
@@ -26,13 +28,35 @@ namespace content {
namespace {
-class CompositorImplLowEndBrowserTest : public ContentBrowserTest {
+enum class CompositorImplMode {
+ kNormal,
+ kViz,
+ kVizSkDDL,
+};
+
+class CompositorImplBrowserTest
+ : public testing::WithParamInterface<CompositorImplMode>,
+ public ContentBrowserTest {
public:
- CompositorImplLowEndBrowserTest() {}
- void SetUpCommandLine(base::CommandLine* command_line) override {
- command_line->AppendSwitch(switches::kEnableLowEndDeviceMode);
- command_line->AppendSwitch(switches::kInProcessGPU);
- content::ContentBrowserTest::SetUpCommandLine(command_line);
+ CompositorImplBrowserTest() {}
+
+ void SetUp() override {
+ switch (GetParam()) {
+ case CompositorImplMode::kNormal:
+ break;
+ case CompositorImplMode::kViz:
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kVizDisplayCompositor);
+ break;
+ case CompositorImplMode::kVizSkDDL:
+ scoped_feature_list_.InitWithFeatures(
+ {features::kVizDisplayCompositor,
+ features::kUseSkiaDeferredDisplayList, features::kUseSkiaRenderer},
+ {});
+ break;
+ }
+
+ ContentBrowserTest::SetUp();
}
protected:
@@ -63,9 +87,33 @@ class CompositorImplLowEndBrowserTest : public ContentBrowserTest {
}
private:
- DISALLOW_COPY_AND_ASSIGN(CompositorImplLowEndBrowserTest);
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompositorImplBrowserTest);
+};
+
+INSTANTIATE_TEST_CASE_P(P,
+ CompositorImplBrowserTest,
+ ::testing::Values(CompositorImplMode::kNormal,
+ CompositorImplMode::kViz,
+ CompositorImplMode::kVizSkDDL));
+
+class CompositorImplLowEndBrowserTest : public CompositorImplBrowserTest {
+ public:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitch(switches::kEnableLowEndDeviceMode);
+ command_line->AppendSwitch(switches::kInProcessGPU);
+ content::ContentBrowserTest::SetUpCommandLine(command_line);
+ }
};
+// Viz on android is not yet compatible with in-process GPU. Only run in
+// kNormal mode.
+// TODO(ericrk): Make this work everywhere. https://crbug.com/851643
+INSTANTIATE_TEST_CASE_P(P,
+ CompositorImplLowEndBrowserTest,
+ ::testing::Values(CompositorImplMode::kNormal));
+
// RunLoop implementation that calls glFlush() every second until it observes
// OnContextLost().
class ContextLostRunLoop : public viz::ContextLostObserver {
@@ -130,8 +178,15 @@ class CompositorFrameRunLoop : public ui::WindowAndroidObserver {
DISALLOW_COPY_AND_ASSIGN(CompositorFrameRunLoop);
};
-IN_PROC_BROWSER_TEST_F(CompositorImplLowEndBrowserTest,
+IN_PROC_BROWSER_TEST_P(CompositorImplLowEndBrowserTest,
CompositorImplDropsResourcesOnBackground) {
+ // This test makes invalid assumptions when surface synchronization is
+ // enabled. The compositor lock is obsolete, and inspecting frames
+ // from the CompositorImpl does not guarantee renderer CompositorFrames
+ // are ready.
+ if (features::IsSurfaceSynchronizationEnabled())
+ return;
+
auto* rwhva = render_widget_host_view_android();
auto* compositor = compositor_impl();
auto context = GpuBrowsertestCreateContext(
@@ -166,5 +221,35 @@ IN_PROC_BROWSER_TEST_F(CompositorImplLowEndBrowserTest,
EXPECT_TRUE(rwhva->HasValidFrame());
}
+// RunLoop implementation that runs until it observes a swap with size.
+class CompositorSwapRunLoop {
+ public:
+ CompositorSwapRunLoop(CompositorImpl* compositor) : compositor_(compositor) {
+ compositor_->SetSwapCompletedWithSizeCallbackForTesting(base::BindRepeating(
+ &CompositorSwapRunLoop::DidSwap, base::Unretained(this)));
+ }
+ ~CompositorSwapRunLoop() {
+ compositor_->SetSwapCompletedWithSizeCallbackForTesting(base::DoNothing());
+ }
+
+ void RunUntilSwap() { run_loop_.Run(); }
+
+ private:
+ void DidSwap(const gfx::Size& pixel_size) {
+ EXPECT_FALSE(pixel_size.IsEmpty());
+ run_loop_.Quit();
+ }
+
+ CompositorImpl* compositor_;
+ base::RunLoop run_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompositorSwapRunLoop);
+};
+
+IN_PROC_BROWSER_TEST_P(CompositorImplBrowserTest,
+ CompositorImplReceivesSwapCallbacks) {
+ CompositorSwapRunLoop(compositor_impl()).RunUntilSwap();
+}
+
} // namespace
} // namespace content
diff --git a/chromium/content/browser/renderer_host/delegated_frame_host.cc b/chromium/content/browser/renderer_host/delegated_frame_host.cc
index 47455e4a512..8b8bc279ccf 100644
--- a/chromium/content/browser/renderer_host/delegated_frame_host.cc
+++ b/chromium/content/browser/renderer_host/delegated_frame_host.cc
@@ -11,6 +11,8 @@
#include "base/callback_helpers.h"
#include "base/command_line.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
@@ -23,6 +25,7 @@
#include "components/viz/service/surfaces/surface_hittest.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/gpu/compositor_util.h"
+#include "content/common/tab_switching_time_callback.h"
#include "content/public/common/content_switches.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/dip_util.h"
@@ -68,17 +71,17 @@ DelegatedFrameHost::~DelegatedFrameHost() {
void DelegatedFrameHost::WasShown(
const viz::LocalSurfaceId& new_pending_local_surface_id,
const gfx::Size& new_pending_dip_size,
- const ui::LatencyInfo& latency_info) {
+ bool record_presentation_time) {
frame_evictor_->SetVisible(true);
-
- if (compositor_)
- compositor_->SetLatencyInfo(latency_info);
+ if (record_presentation_time && compositor_) {
+ compositor_->RequestPresentationTimeForNextFrame(
+ CreateTabSwitchingTimeRecorder(base::TimeTicks::Now()));
+ }
// Use the default deadline to synchronize web content with browser UI.
// TODO(fsamuel): Investigate if there is a better deadline to use here.
- SynchronizeVisualProperties(new_pending_local_surface_id,
- new_pending_dip_size,
- cc::DeadlinePolicy::UseDefaultDeadline());
+ EmbedSurface(new_pending_local_surface_id, new_pending_dip_size,
+ cc::DeadlinePolicy::UseDefaultDeadline());
}
bool DelegatedFrameHost::HasSavedFrame() const {
@@ -111,7 +114,8 @@ void DelegatedFrameHost::CopyFromCompositingSurface(
// If there is enough information to populate the copy output request fields,
// then process it now. Otherwise, wait until the information becomes
// available.
- if (CanCopyFromCompositingSurface())
+ if (CanCopyFromCompositingSurface() &&
+ active_local_surface_id_ == pending_local_surface_id_)
ProcessCopyOutputRequest(std::move(request));
else
pending_first_frame_requests_.push_back(std::move(request));
@@ -122,14 +126,18 @@ void DelegatedFrameHost::ProcessCopyOutputRequest(
if (!request->has_area())
request->set_area(gfx::Rect(pending_surface_dip_size_));
- // TODO(vmpstr): Should use pending device scale factor. We need to plumb
- // it here.
request->set_area(
gfx::ScaleToRoundedRect(request->area(), active_device_scale_factor_));
if (request->has_result_selection()) {
const gfx::Rect& area = request->area();
const gfx::Rect& result_selection = request->result_selection();
+ if (area.IsEmpty() || result_selection.IsEmpty()) {
+ // Viz would normally return an empty result for an empty selection.
+ // However, this guard here is still necessary to protect against setting
+ // an illegal scaling ratio.
+ return;
+ }
request->SetScaleRatio(
gfx::Vector2d(area.width(), area.height()),
gfx::Vector2d(result_selection.width(), result_selection.height()));
@@ -216,7 +224,7 @@ bool DelegatedFrameHost::HasFallbackSurface() const {
return fallback_surface_id && fallback_surface_id->is_valid();
}
-void DelegatedFrameHost::SynchronizeVisualProperties(
+void DelegatedFrameHost::EmbedSurface(
const viz::LocalSurfaceId& new_pending_local_surface_id,
const gfx::Size& new_pending_dip_size,
cc::DeadlinePolicy deadline_policy) {
@@ -238,8 +246,7 @@ void DelegatedFrameHost::SynchronizeVisualProperties(
}
// Don't update the SurfaceLayer when invisible to avoid blocking on
// renderers that do not submit CompositorFrames. Next time the renderer
- // is visible, SynchronizeVisualProperties will be called again. See
- // WasShown.
+ // is visible, EmbedSurface will be called again. See WasShown.
return;
}
@@ -278,10 +285,6 @@ SkColor DelegatedFrameHost::GetGutterColor() const {
return client_->DelegatedFrameHostGetGutterColor();
}
-gfx::Size DelegatedFrameHost::GetRequestedRendererSize() const {
- return pending_surface_dip_size_;
-}
-
void DelegatedFrameHost::DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
ResetCompositorFrameSinkSupport();
@@ -312,18 +315,11 @@ 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::DidPresentCompositorFrame(
+ uint32_t presentation_token,
+ const gfx::PresentationFeedback& feedback) {
+ renderer_compositor_frame_sink_->DidPresentCompositorFrame(presentation_token,
+ feedback);
}
void DelegatedFrameHost::ReclaimResources(
@@ -406,13 +402,8 @@ void DelegatedFrameHost::OnBeginFrame(const viz::BeginFrameArgs& args) {
}
void DelegatedFrameHost::EvictDelegatedFrame() {
- // It is possible that we are embedding the contents of previous
- // DelegatedFrameHost. In this case, HasSavedFrame() will return false but we
- // still need to clear the layer.
- if (HasFallbackSurface()) {
- client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
- viz::SurfaceId());
- }
+ // Replaces the SurfaceLayer with a SolidColorLayer.
+ client_->DelegatedFrameHostGetLayer()->SetShowSolidColorContent();
if (!HasSavedFrame())
return;
@@ -446,10 +437,21 @@ void DelegatedFrameHost::OnCompositingShuttingDown(ui::Compositor* compositor) {
}
////////////////////////////////////////////////////////////////////////////////
-// DelegatedFrameHost, ImageTransportFactoryObserver implementation:
+// DelegatedFrameHost, ContextFactoryObserver implementation:
-void DelegatedFrameHost::OnLostResources() {
- EvictDelegatedFrame();
+void DelegatedFrameHost::OnLostSharedContext() {}
+
+void DelegatedFrameHost::OnLostVizProcess() {
+ // With OOP-D renderer surface was destroyed if the GPU process crashed. Reset
+ // the fallback Surface but leave the primary so we embed the renderer surface
+ // again.
+ if (HasFallbackSurface()) {
+ client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
+ viz::SurfaceId());
+ }
+
+ if (HasSavedFrame())
+ frame_evictor_->DiscardedFrame();
}
////////////////////////////////////////////////////////////////////////////////
@@ -529,10 +531,9 @@ void DelegatedFrameHost::WindowTitleChanged(const std::string& title) {
}
void DelegatedFrameHost::TakeFallbackContentFrom(DelegatedFrameHost* other) {
- if (!other->HasFallbackSurface())
- return;
- if (HasFallbackSurface())
+ if (!other->HasFallbackSurface() || HasFallbackSurface())
return;
+
if (!HasPrimarySurface()) {
client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface(
*other->client_->DelegatedFrameHostGetLayer()->GetFallbackSurfaceId(),
@@ -541,6 +542,7 @@ void DelegatedFrameHost::TakeFallbackContentFrom(DelegatedFrameHost* other) {
cc::DeadlinePolicy::UseDefaultDeadline(),
false /* stretch_content_to_fill_bounds */);
}
+
client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId(
*other->client_->DelegatedFrameHostGetLayer()->GetFallbackSurfaceId());
}
diff --git a/chromium/content/browser/renderer_host/delegated_frame_host.h b/chromium/content/browser/renderer_host/delegated_frame_host.h
index 98f59da7af8..d8f5261cc35 100644
--- a/chromium/content/browser/renderer_host/delegated_frame_host.h
+++ b/chromium/content/browser/renderer_host/delegated_frame_host.h
@@ -87,7 +87,8 @@ class CONTENT_EXPORT DelegatedFrameHost
void OnCompositingShuttingDown(ui::Compositor* compositor) override;
// ui::ContextFactoryObserver implementation.
- void OnLostResources() override;
+ void OnLostSharedContext() override;
+ void OnLostVizProcess() override;
// FrameEvictorClient implementation.
void EvictDelegatedFrame() override;
@@ -95,11 +96,9 @@ 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 DidPresentCompositorFrame(
+ uint32_t presentation_token,
+ const gfx::PresentationFeedback& feedback) override;
void OnBeginFrame(const viz::BeginFrameArgs& args) override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
@@ -122,12 +121,11 @@ class CONTENT_EXPORT DelegatedFrameHost
// TODO(ccameron): Include device scale factor here.
void WasShown(const viz::LocalSurfaceId& local_surface_id,
const gfx::Size& dip_size,
- const ui::LatencyInfo& latency_info);
- void SynchronizeVisualProperties(const viz::LocalSurfaceId& local_surface_id,
- const gfx::Size& dip_size,
- cc::DeadlinePolicy deadline_policy);
+ bool record_presentation_time);
+ void EmbedSurface(const viz::LocalSurfaceId& local_surface_id,
+ const gfx::Size& dip_size,
+ cc::DeadlinePolicy deadline_policy);
bool HasSavedFrame() const;
- gfx::Size GetRequestedRendererSize() const;
void SetCompositor(ui::Compositor* compositor);
void ResetCompositor();
// Note: |src_subrect| is specified in DIP dimensions while |output_size|
@@ -226,7 +224,7 @@ class CONTENT_EXPORT DelegatedFrameHost
float active_device_scale_factor_ = 0.f;
// The local surface id as of the most recent call to
- // SynchronizeVisualProperties or WasShown. This is the surface that we expect
+ // EmbedSurface or WasShown. This is the surface that we expect
// future frames to reference. This will eventually equal the active surface.
viz::LocalSurfaceId pending_local_surface_id_;
// The size of the above surface (updated at the same time).
@@ -234,7 +232,7 @@ class CONTENT_EXPORT DelegatedFrameHost
// In non-surface sync, this is the size of the most recently activated
// surface (which is suitable for calculating gutter size). In surface sync,
- // this is most recent size set in SynchronizeVisualProperties.
+ // this is most recent size set in EmbedSurface.
// TODO(ccameron): The meaning of "current" should be made more clear here.
gfx::Size current_frame_size_in_dip_;
@@ -256,6 +254,8 @@ class CONTENT_EXPORT DelegatedFrameHost
std::vector<std::unique_ptr<viz::CopyOutputRequest>>
pending_first_frame_requests_;
+
+ DISALLOW_COPY_AND_ASSIGN(DelegatedFrameHost);
};
} // namespace content
diff --git a/chromium/content/browser/renderer_host/display_util.cc b/chromium/content/browser/renderer_host/display_util.cc
index 204211f7404..7d0d3d89f5d 100644
--- a/chromium/content/browser/renderer_host/display_util.cc
+++ b/chromium/content/browser/renderer_host/display_util.cc
@@ -21,10 +21,6 @@ void DisplayUtil::DisplayToScreenInfo(ScreenInfo* screen_info,
screen_info->available_rect = display.work_area();
screen_info->device_scale_factor = display.device_scale_factor();
screen_info->color_space = display.color_space();
-#if defined(OS_MACOSX)
- screen_info->icc_profile =
- gfx::ICCProfile::FromCacheMac(display.color_space());
-#endif
screen_info->depth = display.color_depth();
screen_info->depth_per_component = display.depth_per_component();
screen_info->is_monochrome = display.is_monochrome();
diff --git a/chromium/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc b/chromium/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc
index 02999045b0b..71073a5ff02 100644
--- a/chromium/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc
+++ b/chromium/content/browser/renderer_host/embedded_frame_sink_provider_impl_unittest.cc
@@ -13,6 +13,7 @@
#include "build/build_config.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/host/host_frame_sink_manager.h"
+#include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "components/viz/test/compositor_frame_helpers.h"
#include "components/viz/test/fake_host_frame_sink_client.h"
@@ -119,7 +120,8 @@ class EmbeddedFrameSinkProviderImplTest : public testing::Test {
host_frame_sink_manager_ = std::make_unique<viz::HostFrameSinkManager>();
// The FrameSinkManagerImpl implementation is in-process here for tests.
- frame_sink_manager_ = std::make_unique<viz::FrameSinkManagerImpl>();
+ frame_sink_manager_ =
+ std::make_unique<viz::FrameSinkManagerImpl>(&shared_bitmap_manager_);
surface_utils::ConnectWithLocalFrameSinkManager(
host_frame_sink_manager_.get(), frame_sink_manager_.get());
@@ -140,6 +142,7 @@ class EmbeddedFrameSinkProviderImplTest : public testing::Test {
// A MessageLoop is required for mojo bindings which are used to
// connect to graphics services.
base::MessageLoop message_loop_;
+ viz::ServerSharedBitmapManager shared_bitmap_manager_;
viz::FakeHostFrameSinkClient host_frame_sink_client_;
std::unique_ptr<viz::HostFrameSinkManager> host_frame_sink_manager_;
std::unique_ptr<viz::FrameSinkManagerImpl> frame_sink_manager_;
diff --git a/chromium/content/browser/renderer_host/font_utils_linux.cc b/chromium/content/browser/renderer_host/font_utils_linux.cc
deleted file mode 100644
index e5fd81a17d8..00000000000
--- a/chromium/content/browser/renderer_host/font_utils_linux.cc
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <fcntl.h>
-#include <fontconfig/fontconfig.h>
-#include <stddef.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <string>
-
-#include "base/posix/eintr_wrapper.h"
-
-// TODO(crbug/685022): Guard the inclusion of ppapi headers with
-// BUILDFLAG(ENABLE_PLUGINS).
-#include "ppapi/c/private/pp_private_font_charset.h" // nogncheck
-#include "ppapi/c/trusted/ppb_browser_font_trusted.h" // nogncheck
-
-namespace {
-
-// MSCharSetToFontconfig translates a Microsoft charset identifier to a
-// fontconfig language set by appending to |langset|.
-// Returns true if |langset| is Latin/Greek/Cyrillic.
-bool MSCharSetToFontconfig(FcLangSet* langset, unsigned fdwCharSet) {
- // We have need to translate raw fdwCharSet values into terms that
- // fontconfig can understand. (See the description of fdwCharSet in the MSDN
- // documentation for CreateFont:
- // http://msdn.microsoft.com/en-us/library/dd183499(VS.85).aspx )
- //
- // Although the argument is /called/ 'charset', the actual values conflate
- // character sets (which are sets of Unicode code points) and character
- // encodings (which are algorithms for turning a series of bits into a
- // series of code points.) Sometimes the values will name a language,
- // sometimes they'll name an encoding. In the latter case I'm assuming that
- // they mean the set of code points in the domain of that encoding.
- //
- // fontconfig deals with ISO 639-1 language codes:
- // http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
- //
- // So, for each of the documented fdwCharSet values I've had to take a
- // guess at the set of ISO 639-1 languages intended.
-
- bool is_lgc = false;
- switch (fdwCharSet) {
- case PP_PRIVATEFONTCHARSET_ANSI:
- // These values I don't really know what to do with, so I'm going to map
- // them to English also.
- case PP_PRIVATEFONTCHARSET_DEFAULT:
- case PP_PRIVATEFONTCHARSET_MAC:
- case PP_PRIVATEFONTCHARSET_OEM:
- case PP_PRIVATEFONTCHARSET_SYMBOL:
- is_lgc = true;
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("en"));
- break;
- case PP_PRIVATEFONTCHARSET_BALTIC:
- // The three baltic languages.
- is_lgc = true;
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("et"));
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("lv"));
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("lt"));
- break;
- case PP_PRIVATEFONTCHARSET_CHINESEBIG5:
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("zh-tw"));
- break;
- case PP_PRIVATEFONTCHARSET_GB2312:
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("zh-cn"));
- break;
- case PP_PRIVATEFONTCHARSET_EASTEUROPE:
- // A scattering of eastern European languages.
- is_lgc = true;
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("pl"));
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("cs"));
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("sk"));
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("hu"));
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("hr"));
- break;
- case PP_PRIVATEFONTCHARSET_GREEK:
- is_lgc = true;
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("el"));
- break;
- case PP_PRIVATEFONTCHARSET_HANGUL:
- case PP_PRIVATEFONTCHARSET_JOHAB:
- // Korean
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ko"));
- break;
- case PP_PRIVATEFONTCHARSET_RUSSIAN:
- is_lgc = true;
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ru"));
- break;
- case PP_PRIVATEFONTCHARSET_SHIFTJIS:
- // Japanese
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ja"));
- break;
- case PP_PRIVATEFONTCHARSET_TURKISH:
- is_lgc = true;
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("tr"));
- break;
- case PP_PRIVATEFONTCHARSET_VIETNAMESE:
- is_lgc = true;
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("vi"));
- break;
- case PP_PRIVATEFONTCHARSET_ARABIC:
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ar"));
- break;
- case PP_PRIVATEFONTCHARSET_HEBREW:
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("he"));
- break;
- case PP_PRIVATEFONTCHARSET_THAI:
- FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("th"));
- break;
- // default:
- // Don't add any languages in that case that we don't recognise the
- // constant.
- }
- return is_lgc;
-}
-
-} // namespace
-
-namespace content {
-
-int MatchFontFaceWithFallback(const std::string& face,
- bool is_bold,
- bool is_italic,
- uint32_t charset,
- uint32_t fallback_family) {
- FcLangSet* langset = FcLangSetCreate();
- bool is_lgc = MSCharSetToFontconfig(langset, charset);
- FcPattern* pattern = FcPatternCreate();
- FcPatternAddString(
- pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(face.c_str()));
-
- // TODO(thestig) Check if we can access Chrome's per-script font preference
- // here and select better default fonts for non-LGC case.
- std::string generic_font_name;
- if (is_lgc) {
- switch (fallback_family) {
- case PP_BROWSERFONT_TRUSTED_FAMILY_SERIF:
- generic_font_name = "Times New Roman";
- break;
- case PP_BROWSERFONT_TRUSTED_FAMILY_SANSSERIF:
- generic_font_name = "Arial";
- break;
- case PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE:
- generic_font_name = "Courier New";
- break;
- }
- }
- if (!generic_font_name.empty()) {
- const FcChar8* fc_generic_font_name =
- reinterpret_cast<const FcChar8*>(generic_font_name.c_str());
- FcPatternAddString(pattern, FC_FAMILY, fc_generic_font_name);
- }
-
- if (is_bold)
- FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
- if (is_italic)
- FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
- FcPatternAddLangSet(pattern, FC_LANG, langset);
- FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
- FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
-
- FcResult 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;
-
- if (font_set) {
- for (int i = 0; i < font_set->nfont; ++i) {
- FcPattern* current = font_set->fonts[i];
-
- // Older versions of fontconfig have a bug where they cannot select
- // only scalable fonts so we have to manually filter the results.
- FcBool is_scalable;
- if (FcPatternGetBool(current, FC_SCALABLE, 0, &is_scalable) !=
- FcResultMatch ||
- !is_scalable) {
- continue;
- }
-
- FcChar8* c_filename;
- if (FcPatternGetString(current, FC_FILE, 0, &c_filename) !=
- FcResultMatch) {
- continue;
- }
-
- // We only want to return sfnt (TrueType) based fonts. We don't have a
- // very good way of detecting this so we'll filter based on the
- // filename.
- bool is_sfnt = false;
- static const char kSFNTExtensions[][5] = {".ttf", ".otc", ".TTF", ".ttc",
- ""};
- const size_t filename_len = strlen(reinterpret_cast<char*>(c_filename));
- for (unsigned j = 0;; j++) {
- if (kSFNTExtensions[j][0] == 0) {
- // None of the extensions matched.
- break;
- }
- const size_t ext_len = strlen(kSFNTExtensions[j]);
- if (filename_len > ext_len &&
- memcmp(c_filename + filename_len - ext_len,
- kSFNTExtensions[j],
- ext_len) == 0) {
- is_sfnt = true;
- break;
- }
- }
-
- if (!is_sfnt)
- continue;
-
- // This font is good enough to pass muster, but we might be able to do
- // better with subsequent ones.
- if (!good_enough_index_set) {
- good_enough_index = i;
- good_enough_index_set = true;
- }
-
- FcValue matrix;
- bool have_matrix = FcPatternGet(current, FC_MATRIX, 0, &matrix) == 0;
-
- if (is_italic && have_matrix) {
- // we asked for an italic font, but fontconfig is giving us a
- // non-italic font with a transformation matrix.
- continue;
- }
-
- FcValue embolden;
- const bool have_embolden =
- FcPatternGet(current, FC_EMBOLDEN, 0, &embolden) == 0;
-
- if (is_bold && have_embolden) {
- // we asked for a bold font, but fontconfig gave us a non-bold font
- // and asked us to apply fake bolding.
- continue;
- }
-
- font_fd =
- HANDLE_EINTR(open(reinterpret_cast<char*>(c_filename), O_RDONLY));
- if (font_fd >= 0)
- break;
- }
- }
-
- if (font_fd == -1 && good_enough_index_set) {
- // We didn't find a font that we liked, so we fallback to something
- // acceptable.
- FcPattern* current = font_set->fonts[good_enough_index];
- FcChar8* c_filename;
- FcPatternGetString(current, FC_FILE, 0, &c_filename);
- font_fd = HANDLE_EINTR(open(reinterpret_cast<char*>(c_filename), O_RDONLY));
- }
-
- if (font_set)
- FcFontSetDestroy(font_set);
- FcPatternDestroy(pattern);
-
- return font_fd;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/renderer_host/font_utils_linux.h b/chromium/content/browser/renderer_host/font_utils_linux.h
deleted file mode 100644
index 33b31af68d7..00000000000
--- a/chromium/content/browser/renderer_host/font_utils_linux.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_FONT_UTILS_LINUX_H_
-#define CONTENT_BROWSER_RENDERER_HOST_FONT_UTILS_LINUX_H_
-
-#include <stdint.h>
-
-#include <string>
-
-namespace content {
-
-int MatchFontFaceWithFallback(const std::string& face,
- bool is_bold,
- bool is_italic,
- uint32_t charset,
- uint32_t fallback_family);
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_FONT_UTILS_LINUX_H_
diff --git a/chromium/content/browser/renderer_host/frame_connector_delegate.h b/chromium/content/browser/renderer_host/frame_connector_delegate.h
index a1239217056..00a5e62ade0 100644
--- a/chromium/content/browser/renderer_host/frame_connector_delegate.h
+++ b/chromium/content/browser/renderer_host/frame_connector_delegate.h
@@ -71,7 +71,7 @@ class CONTENT_EXPORT FrameConnectorDelegate {
// Provide the SurfaceInfo to the embedder, which becomes a reference to the
// current view's Surface that is included in higher-level compositor
// frames.
- virtual void SetChildFrameSurface(const viz::SurfaceInfo& surface_info) {}
+ virtual void FirstSurfaceActivation(const viz::SurfaceInfo& surface_info) {}
// Sends the given intrinsic sizing information from a sub-frame to
// its corresponding remote frame in the parent frame's renderer.
@@ -149,6 +149,11 @@ class CONTENT_EXPORT FrameConnectorDelegate {
const TouchEventWithLatencyInfo& touch,
InputEventAckState ack_result) {}
+ // Pass acked touchpad pinch gesture events to the root view for processing.
+ virtual void ForwardAckedTouchpadPinchGestureEvent(
+ const blink::WebGestureEvent& event,
+ InputEventAckState ack_result) {}
+
// Gesture events with unused scroll deltas must be bubbled to ancestors
// who may consume the delta.
virtual void BubbleScrollEvent(const blink::WebGestureEvent& event) {}
diff --git a/chromium/content/browser/renderer_host/frame_metadata_util.cc b/chromium/content/browser/renderer_host/frame_metadata_util.cc
index de9edebd775..e5717aaaf67 100644
--- a/chromium/content/browser/renderer_host/frame_metadata_util.cc
+++ b/chromium/content/browser/renderer_host/frame_metadata_util.cc
@@ -13,16 +13,16 @@ namespace {
// V1 saw errors of ~0.065 between computed window and content widths.
const float kMobileViewportWidthEpsilon = 0.15f;
-bool HasFixedPageScale(const viz::CompositorFrameMetadata& frame_metadata) {
- return frame_metadata.min_page_scale_factor ==
- frame_metadata.max_page_scale_factor;
+bool HasFixedPageScale(float min_page_scale_factor,
+ float max_page_scale_factor) {
+ return min_page_scale_factor == max_page_scale_factor;
}
-bool HasMobileViewport(const viz::CompositorFrameMetadata& frame_metadata) {
- float window_width_dip =
- frame_metadata.page_scale_factor *
- frame_metadata.scrollable_viewport_size.width();
- float content_width_css = frame_metadata.root_layer_size.width();
+bool HasMobileViewport(float page_scale_factor,
+ const gfx::SizeF& scrollable_viewport_size,
+ const gfx::SizeF& root_layer_size) {
+ float window_width_dip = page_scale_factor * scrollable_viewport_size.width();
+ float content_width_css = root_layer_size.width();
return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon;
}
@@ -30,10 +30,15 @@ bool HasMobileViewport(const viz::CompositorFrameMetadata& frame_metadata) {
namespace content {
-bool IsMobileOptimizedFrame(
- const viz::CompositorFrameMetadata& frame_metadata) {
- bool has_mobile_viewport = HasMobileViewport(frame_metadata);
- bool has_fixed_page_scale = HasFixedPageScale(frame_metadata);
+bool IsMobileOptimizedFrame(float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor,
+ const gfx::SizeF& scrollable_viewport_size,
+ const gfx::SizeF& root_layer_size) {
+ bool has_mobile_viewport = HasMobileViewport(
+ page_scale_factor, scrollable_viewport_size, root_layer_size);
+ bool has_fixed_page_scale =
+ HasFixedPageScale(min_page_scale_factor, max_page_scale_factor);
return has_fixed_page_scale || has_mobile_viewport;
}
diff --git a/chromium/content/browser/renderer_host/frame_metadata_util.h b/chromium/content/browser/renderer_host/frame_metadata_util.h
index 50de6fba264..dfa4585f5c6 100644
--- a/chromium/content/browser/renderer_host/frame_metadata_util.h
+++ b/chromium/content/browser/renderer_host/frame_metadata_util.h
@@ -7,8 +7,8 @@
#include "content/common/content_export.h"
-namespace viz {
-class CompositorFrameMetadata;
+namespace gfx {
+class SizeF;
}
namespace content {
@@ -19,7 +19,11 @@ namespace content {
// (indicating that this is a mobile-optimized or responsive web design);
// - page that prevents zooming in or out.
CONTENT_EXPORT bool IsMobileOptimizedFrame(
- const viz::CompositorFrameMetadata& frame_metadata);
+ float page_scale_factor,
+ float min_page_scale_factor,
+ float max_page_scale_factor,
+ const gfx::SizeF& scrollable_viewport_size,
+ const gfx::SizeF& root_layer_size);
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/README.md b/chromium/content/browser/renderer_host/input/README.md
new file mode 100644
index 00000000000..6348b985031
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/README.md
@@ -0,0 +1,23 @@
+# Renderer Host Input
+
+This directory contains browser side input event handling code.
+
+## TouchpadPinchEventQueue
+
+In order for pages to override the behaviour of touchpad pinch zooming, we offer
+synthetic wheel events that may be canceled. The `TouchpadPinchEventQueue`
+accepts the gesture pinch events created from native events and sends the
+appropriate wheel events to the renderer. Once the renderer has acknowledged a
+wheel event, we offer the corresponding gesture pinch event back to the client
+of the `TouchpadPinchEventQueue`. If the pinch has not been consumed by the page,
+the client may go on to send the actual gesture pinch event to the renderer which
+will perform the pinch zoom.
+
+Note that for touchscreen gesture pinch events, there is no need for a similar
+queue as touch events would have already been offered to the renderer before
+being recognized as a pinch gesture.
+
+See [issue 289887](https://crbug.com/289887) for the discussion on offering
+wheel events for touchpad pinch.
+
+Touchpad pinch zoom [design doc](https://docs.google.com/document/d/1cYdt9r9stHLA2lbJ2I-Ucl_djhdSyngYFbmufZaLRHE/edit?usp=sharing).
diff --git a/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc b/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc
index b20cceec519..835b21e194f 100644
--- a/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/compositor_event_ack_browsertest.cc
@@ -245,6 +245,14 @@ IN_PROC_BROWSER_TEST_F(CompositorEventAckBrowserTest,
MAYBE_TouchStartDuringFling) {
LoadURL(kBlockingTouchStartDataURL);
+ // Send a TouchStart so that we can set allowed touch action to Auto.
+ SyntheticWebTouchEvent touch_event;
+ touch_event.PressPoint(50, 50);
+ touch_event.SetTimeStamp(ui::EventTimeForNow());
+ GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch_event,
+ ui::LatencyInfo());
+ GetWidgetHost()->input_router()->OnSetTouchAction(cc::kTouchActionAuto);
+
// Send GSB to start scrolling sequence.
blink::WebGestureEvent gesture_scroll_begin(
blink::WebGestureEvent::kGestureScrollBegin,
@@ -273,13 +281,17 @@ IN_PROC_BROWSER_TEST_F(CompositorEventAckBrowserTest,
.y() <= 0)
observer.WaitForMetadataChange();
+ touch_event.ReleasePoint(0);
+ GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch_event,
+ ui::LatencyInfo());
+ touch_event.ResetPoints();
+
// Send a touch start event and wait for its ack. The touch start must be
// uncancelable since there is an on-going fling with touchscreen source. The
// test will timeout if the touch start event is cancelable since there is a
// busy loop in the blocking touch start event listener.
InputEventAckWaiter touch_start_ack_observer(GetWidgetHost(),
WebInputEvent::kTouchStart);
- SyntheticWebTouchEvent touch_event;
touch_event.PressPoint(50, 50);
touch_event.SetTimeStamp(ui::EventTimeForNow());
GetWidgetHost()->ForwardTouchEventWithLatencyInfo(touch_event,
diff --git a/chromium/content/browser/renderer_host/input/fling_browsertest.cc b/chromium/content/browser/renderer_host/input/fling_browsertest.cc
index 401de60bf93..b8371dc58c6 100644
--- a/chromium/content/browser/renderer_host/input/fling_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/fling_browsertest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "build/build_config.h"
+#include "content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.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"
@@ -28,6 +29,19 @@ const std::string kBrowserFlingDataURL = R"HTML(
<script>
document.title='ready';
</script>)HTML";
+
+const std::string kTouchActionFilterDataURL = R"HTML(
+ <!DOCTYPE html>
+ <meta name='viewport' content='width=device-width'/>
+ <style>
+ body {
+ height: 10000px;
+ touch-action: pan-y;
+ }
+ </style>
+ <script>
+ document.title='ready';
+ </script>)HTML";
} // namespace
namespace content {
@@ -42,6 +56,11 @@ class BrowserSideFlingBrowserTest : public ContentBrowserTest {
"MiddleClickAutoscroll");
}
+ void OnSyntheticGestureCompleted(SyntheticGesture::Result result) {
+ EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
+ run_loop_->Quit();
+ }
+
protected:
RenderWidgetHostImpl* GetWidgetHost() {
return RenderWidgetHostImpl::From(
@@ -81,6 +100,8 @@ class BrowserSideFlingBrowserTest : public ContentBrowserTest {
GetWidgetHost()->ForwardMouseEvent(up_event);
}
+ std::unique_ptr<base::RunLoop> run_loop_;
+
private:
DISALLOW_COPY_AND_ASSIGN(BrowserSideFlingBrowserTest);
};
@@ -149,13 +170,8 @@ IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, TouchpadFling) {
}
}
-// TODO(sahel): This test is flaking on OS_CHROMEOS https://crbug.com/838769
-#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
-#define MAYBE_AutoscrollFling DISABLED_AutoscrollFling
-#else
-#define MAYBE_AutoscrollFling AutoscrollFling
-#endif
-IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, MAYBE_AutoscrollFling) {
+// TODO(sahel): This test is flaky https://crbug.com/838769
+IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest, DISABLED_AutoscrollFling) {
LoadURL(kBrowserFlingDataURL);
// Start autoscroll with middle click.
@@ -220,4 +236,64 @@ IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest,
}
}
+// Disabled on MacOS because it doesn't support touchscreen scroll.
+#if defined(OS_MACOSX)
+#define MAYBE_ScrollEndGeneratedForFilteredFling \
+ DISABLED_ScrollEndGeneratedForFilteredFling
+#else
+// Flaky, see https://crbug.com/850455
+#define MAYBE_ScrollEndGeneratedForFilteredFling \
+ DISABLED_ScrollEndGeneratedForFilteredFling
+#endif
+IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest,
+ MAYBE_ScrollEndGeneratedForFilteredFling) {
+ LoadURL(kTouchActionFilterDataURL);
+
+ // Necessary for checking the ACK source of the sent events. The events are
+ // filtered when the Browser is the source.
+ auto scroll_begin_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kGestureScrollBegin);
+ auto fling_start_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kGestureFlingStart);
+ auto scroll_end_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kGestureScrollEnd);
+
+ // Do a horizontal touchscreen scroll followed by a fling. The GFS must get
+ // filtered since the GSB is filtered.
+ SyntheticSmoothScrollGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params.anchor = gfx::PointF(10, 10);
+ params.distances.push_back(gfx::Vector2d(-60, 0));
+ params.prevent_fling = false;
+
+ run_loop_ = std::make_unique<base::RunLoop>();
+
+ std::unique_ptr<SyntheticSmoothScrollGesture> gesture(
+ new SyntheticSmoothScrollGesture(params));
+ GetWidgetHost()->QueueSyntheticGesture(
+ std::move(gesture),
+ base::BindOnce(&BrowserSideFlingBrowserTest::OnSyntheticGestureCompleted,
+ base::Unretained(this)));
+
+ // Runs until we get the OnSyntheticGestureCompleted callback.
+ run_loop_->Run();
+
+ scroll_begin_watcher->GetAckStateWaitIfNecessary();
+ EXPECT_EQ(InputEventAckSource::BROWSER,
+ scroll_begin_watcher->last_event_ack_source());
+
+ fling_start_watcher->GetAckStateWaitIfNecessary();
+ EXPECT_EQ(InputEventAckSource::BROWSER,
+ fling_start_watcher->last_event_ack_source());
+
+ // Since the GFS is filtered. the input_router_impl will generate and forward
+ // a GSE to make sure that the scrolling sequence and the touch action filter
+ // state get reset properly. The generated GSE will also get filtered since
+ // its equivalent GSB is filtered. The test will timeout if the GSE is not
+ // generated.
+ scroll_end_watcher->GetAckStateWaitIfNecessary();
+ EXPECT_EQ(InputEventAckSource::BROWSER,
+ scroll_end_watcher->last_event_ack_source());
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/fling_controller.cc b/chromium/content/browser/renderer_host/input/fling_controller.cc
index ce13d23f10a..ef40b4f664a 100644
--- a/chromium/content/browser/renderer_host/input/fling_controller.cc
+++ b/chromium/content/browser/renderer_host/input/fling_controller.cc
@@ -6,7 +6,8 @@
#include "base/trace_event/trace_event.h"
#include "content/browser/renderer_host/input/gesture_event_queue.h"
-#include "content/public/common/content_features.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/common/content_client.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/fling_booster.h"
#include "ui/events/gestures/blink/web_gesture_curve_impl.h"
@@ -42,10 +43,6 @@ FlingController::FlingController(
touchscreen_tap_suppression_controller_(
config.touchscreen_tap_suppression_config),
fling_in_progress_(false),
- send_wheel_events_nonblocking_(
- base::FeatureList::IsEnabled(
- features::kTouchpadAndWheelScrollLatching) &&
- base::FeatureList::IsEnabled(features::kAsyncWheelEvents)),
weak_ptr_factory_(this) {
DCHECK(gesture_event_queue);
DCHECK(event_sender_client);
@@ -103,13 +100,6 @@ bool FlingController::FilterGestureEventForFlingBoosting(
if (!fling_booster_)
return false;
- // TODO(sahel): Don't boost touchpad fling for now. Once browserside
- // touchscreen fling is implemented, move the fling_controller_ from
- // GestureEventQueue to RednerWidgetHostImpl. This will gaurantee proper
- // gesture scroll event order in RednerWidgetHostImpl while boosting.
- if (gesture_event.event.SourceDevice() == blink::kWebGestureDeviceTouchpad)
- return false;
-
bool cancel_current_fling;
bool should_filter_event = fling_booster_->FilterGestureEventForFlingBoosting(
gesture_event.event, &cancel_current_fling);
@@ -270,15 +260,8 @@ void FlingController::GenerateAndSendWheelEvents(
synthetic_wheel.event.SetPositionInWidget(current_fling_parameters_.point);
synthetic_wheel.event.SetPositionInScreen(
current_fling_parameters_.global_point);
- // Send wheel end events nonblocking since they have zero delta and are not
- // sent to JS.
- if (phase == blink::WebMouseWheelEvent::kPhaseEnded) {
- synthetic_wheel.event.dispatch_type = WebInputEvent::kEventNonBlocking;
- } else {
- synthetic_wheel.event.dispatch_type = send_wheel_events_nonblocking_
- ? WebInputEvent::kEventNonBlocking
- : WebInputEvent::kBlocking;
- }
+ // Send wheel events nonblocking.
+ synthetic_wheel.event.dispatch_type = WebInputEvent::kEventNonBlocking;
event_sender_client_->SendGeneratedWheelEvent(synthetic_wheel);
}
@@ -370,8 +353,13 @@ void FlingController::CancelCurrentFling() {
// Synthesize a GestureScrollBegin, as the original event was suppressed. It
// is important to send the GSB after resetting the fling_booster_ otherwise
- // it will get filtered by the booster again.
+ // it will get filtered by the booster again. This is necessary for
+ // touchscreen fling cancelation only, since autoscroll fling cancelation
+ // doesn't get deferred and when the touchpad fling cancelation gets deferred,
+ // the first wheel event after the cancelation will cause a GSB generation.
if (fling_cancellation_is_deferred &&
+ last_fling_boost_event.SourceDevice() ==
+ blink::kWebGestureDeviceTouchscreen &&
(last_fling_boost_event.GetType() == WebInputEvent::kGestureScrollBegin ||
last_fling_boost_event.GetType() ==
WebInputEvent::kGestureScrollUpdate)) {
@@ -387,19 +375,11 @@ void FlingController::CancelCurrentFling() {
: last_fling_boost_event.data.scroll_begin.delta_y_hint;
scroll_begin_event.data.scroll_begin.delta_x_hint = delta_x_hint;
scroll_begin_event.data.scroll_begin.delta_y_hint = delta_y_hint;
- ui::SourceEventType latency_source_event_type =
- ui::SourceEventType::UNKNOWN;
- if (scroll_begin_event.SourceDevice() ==
- blink::kWebGestureDeviceTouchscreen) {
- latency_source_event_type = ui::SourceEventType::INERTIAL;
- } else if (scroll_begin_event.SourceDevice() ==
- blink::kWebGestureDeviceTouchpad) {
- latency_source_event_type = ui::SourceEventType::WHEEL;
- }
event_sender_client_->SendGeneratedGestureScrollEvents(
GestureEventWithLatencyInfo(
- scroll_begin_event, ui::LatencyInfo(latency_source_event_type)));
+ scroll_begin_event,
+ ui::LatencyInfo(ui::SourceEventType::INERTIAL)));
}
if (had_active_fling) {
@@ -430,7 +410,8 @@ bool FlingController::UpdateCurrentFlingState(
ui::WebGestureCurveImpl::CreateFromDefaultPlatformCurve(
current_fling_parameters_.source_device,
current_fling_parameters_.velocity,
- gfx::Vector2dF() /*initial_offset*/, false /*on_main_thread*/));
+ gfx::Vector2dF() /*initial_offset*/, false /*on_main_thread*/,
+ GetContentClient()->browser()->ShouldUseMobileFlingCurve()));
return true;
}
diff --git a/chromium/content/browser/renderer_host/input/fling_controller.h b/chromium/content/browser/renderer_host/input/fling_controller.h
index 929d35ec1c8..869e17b79e2 100644
--- a/chromium/content/browser/renderer_host/input/fling_controller.h
+++ b/chromium/content/browser/renderer_host/input/fling_controller.h
@@ -178,8 +178,6 @@ class CONTENT_EXPORT FlingController {
// for determining if the fling start time should be re-initialized.
bool has_fling_animation_started_;
- bool send_wheel_events_nonblocking_;
-
base::WeakPtrFactory<FlingController> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(FlingController);
diff --git a/chromium/content/browser/renderer_host/input/fling_controller_unittest.cc b/chromium/content/browser/renderer_host/input/fling_controller_unittest.cc
index 31a8d531226..9f658accb9f 100644
--- a/chromium/content/browser/renderer_host/input/fling_controller_unittest.cc
+++ b/chromium/content/browser/renderer_host/input/fling_controller_unittest.cc
@@ -5,10 +5,8 @@
#include "content/browser/renderer_host/input/fling_controller.h"
#include "base/run_loop.h"
-#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "content/browser/renderer_host/input/gesture_event_queue.h"
-#include "content/public/common/content_features.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/fling_booster.h"
@@ -51,8 +49,6 @@ class FlingControllerTest : public testing::Test,
GestureEventQueue::Config());
fling_controller_ = std::make_unique<FakeFlingController>(
queue_.get(), this, this, FlingController::Config());
- feature_list_.InitFromCommandLine(
- features::kTouchpadAndWheelScrollLatching.name, "");
}
// GestureEventQueueClient
@@ -129,7 +125,6 @@ class FlingControllerTest : public testing::Test,
private:
base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<GestureEventQueue> queue_;
- base::test::ScopedFeatureList feature_list_;
};
TEST_F(FlingControllerTest,
@@ -167,8 +162,15 @@ TEST_F(FlingControllerTest, ControllerHandlesTouchpadGestureFling) {
EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, last_sent_wheel_.momentum_phase);
EXPECT_GT(last_sent_wheel_.delta_x, 0.f);
- // Now cancel the fling. The GFC will end the fling.
+ // Now cancel the fling. The GFC will get suppressed by fling booster.
SimulateFlingCancel(blink::kWebGestureDeviceTouchpad);
+ EXPECT_TRUE(last_fling_cancel_filtered_);
+ EXPECT_TRUE(FlingInProgress());
+
+ // Wait for the boosting timer to expire. The delayed cancelation must work.
+ progress_time += base::TimeDelta::FromMilliseconds(500);
+ ProgressFling(progress_time);
+ EXPECT_FALSE(FlingInProgress());
EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, last_sent_wheel_.momentum_phase);
EXPECT_EQ(0.f, last_sent_wheel_.delta_x);
EXPECT_EQ(0.f, last_sent_wheel_.delta_y);
@@ -400,9 +402,7 @@ TEST_F(FlingControllerTest, GestureFlingWithNegativeTimeDelta) {
EXPECT_GT(last_sent_gesture_.data.scroll_update.delta_x, 0.f);
}
-// TODO(sahel): Enable the test once boosting is enabled for touchpad fling.
-// https://crbug.com/249063
-TEST_F(FlingControllerTest, DISABLED_ControllerBoostsTouchpadFling) {
+TEST_F(FlingControllerTest, ControllerBoostsTouchpadFling) {
base::TimeTicks progress_time = base::TimeTicks::Now();
SimulateFlingStart(blink::kWebGestureDeviceTouchpad, gfx::Vector2dF(1000, 0));
EXPECT_TRUE(FlingInProgress());
diff --git a/chromium/content/browser/renderer_host/input/fling_scheduler.cc b/chromium/content/browser/renderer_host/input/fling_scheduler.cc
index 0b6ab39313d..63a6f7cca39 100644
--- a/chromium/content/browser/renderer_host/input/fling_scheduler.cc
+++ b/chromium/content/browser/renderer_host/input/fling_scheduler.cc
@@ -78,6 +78,7 @@ ui::Compositor* FlingScheduler::GetCompositor() {
}
void FlingScheduler::OnAnimationStep(base::TimeTicks timestamp) {
+ DCHECK(observed_compositor_);
if (fling_controller_)
fling_controller_->ProgressFling(timestamp);
}
diff --git a/chromium/content/browser/renderer_host/input/fling_scheduler.h b/chromium/content/browser/renderer_host/input/fling_scheduler.h
index c29c0fc43f5..634904e7b14 100644
--- a/chromium/content/browser/renderer_host/input/fling_scheduler.h
+++ b/chromium/content/browser/renderer_host/input/fling_scheduler.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_RENDERER_HOST_INPUT_FLING_SCHEDULER_H_
#include "content/browser/renderer_host/input/fling_controller.h"
+#include "content/browser/renderer_host/input/fling_scheduler_base.h"
#include "ui/compositor/compositor_animation_observer.h"
namespace ui {
@@ -16,7 +17,7 @@ namespace content {
class RenderWidgetHostImpl;
-class CONTENT_EXPORT FlingScheduler : public FlingControllerSchedulerClient,
+class CONTENT_EXPORT FlingScheduler : public FlingSchedulerBase,
private ui::CompositorAnimationObserver {
public:
FlingScheduler(RenderWidgetHostImpl* host);
@@ -28,7 +29,8 @@ class CONTENT_EXPORT FlingScheduler : public FlingControllerSchedulerClient,
void DidStopFlingingOnBrowser(
base::WeakPtr<FlingController> fling_controller) override;
- void ProgressFlingOnBeginFrameIfneeded(base::TimeTicks current_time);
+ // FlingSchedulerBase
+ void ProgressFlingOnBeginFrameIfneeded(base::TimeTicks current_time) override;
protected:
virtual ui::Compositor* GetCompositor();
diff --git a/chromium/content/browser/renderer_host/input/fling_scheduler_android.cc b/chromium/content/browser/renderer_host/input/fling_scheduler_android.cc
new file mode 100644
index 00000000000..c2e968437ea
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/fling_scheduler_android.cc
@@ -0,0 +1,83 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/fling_scheduler_android.h"
+
+#include "build/build_config.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "ui/compositor/compositor.h"
+
+namespace content {
+
+FlingSchedulerAndroid::FlingSchedulerAndroid(RenderWidgetHostImpl* host)
+ : host_(host) {
+ DCHECK(host);
+}
+
+FlingSchedulerAndroid::~FlingSchedulerAndroid() {
+ if (observed_window_)
+ observed_window_->RemoveObserver(this);
+}
+
+void FlingSchedulerAndroid::ScheduleFlingProgress(
+ base::WeakPtr<FlingController> fling_controller) {
+ DCHECK(fling_controller);
+ fling_controller_ = fling_controller;
+ if (!observed_window_) {
+ ui::WindowAndroid* window = GetRootWindow();
+ // If the root window does not have a Compositor (happens on Android
+ // WebView), we'll never receive an OnAnimate call. In this case fall back
+ // to BeginFrames coming from the host.
+ if (!window || !window->GetCompositor()) {
+ host_->SetNeedsBeginFrameForFlingProgress();
+ return;
+ }
+ window->AddObserver(this);
+ observed_window_ = window;
+ }
+ observed_window_->SetNeedsAnimate();
+}
+
+void FlingSchedulerAndroid::DidStopFlingingOnBrowser(
+ base::WeakPtr<FlingController> fling_controller) {
+ DCHECK(fling_controller);
+ if (observed_window_) {
+ observed_window_->RemoveObserver(this);
+ observed_window_ = nullptr;
+ }
+ fling_controller_ = nullptr;
+ host_->DidStopFlinging();
+}
+
+void FlingSchedulerAndroid::ProgressFlingOnBeginFrameIfneeded(
+ base::TimeTicks current_time) {
+ // If a WindowAndroid is being observed, there is no need for BeginFrames
+ // coming from the host.
+ if (observed_window_)
+ return;
+ if (!fling_controller_)
+ return;
+ fling_controller_->ProgressFling(current_time);
+}
+
+ui::WindowAndroid* FlingSchedulerAndroid::GetRootWindow() {
+ if (!host_->GetView())
+ return nullptr;
+ return host_->GetView()->GetNativeView()->GetWindowAndroid();
+}
+
+void FlingSchedulerAndroid::OnDetachCompositor() {
+ // Once the window's compositor has detached, we will no longer receive
+ // OnAnimate calls. Stop observing the window.
+ observed_window_->RemoveObserver(this);
+ observed_window_ = nullptr;
+}
+
+void FlingSchedulerAndroid::OnAnimate(base::TimeTicks frame_begin_time) {
+ DCHECK(observed_window_);
+ if (fling_controller_)
+ fling_controller_->ProgressFling(frame_begin_time);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/fling_scheduler_android.h b/chromium/content/browser/renderer_host/input/fling_scheduler_android.h
new file mode 100644
index 00000000000..cbe1e6e119d
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/fling_scheduler_android.h
@@ -0,0 +1,55 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_FLING_SCHEDULER_ANDROID_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_FLING_SCHEDULER_ANDROID_H_
+
+#include "content/browser/renderer_host/input/fling_scheduler_base.h"
+#include "content/common/content_export.h"
+#include "ui/android/window_android.h"
+#include "ui/android/window_android_observer.h"
+
+namespace content {
+
+class RenderWidgetHostImpl;
+
+class CONTENT_EXPORT FlingSchedulerAndroid : public FlingSchedulerBase,
+ public ui::WindowAndroidObserver {
+ public:
+ explicit FlingSchedulerAndroid(RenderWidgetHostImpl* host);
+ ~FlingSchedulerAndroid() override;
+
+ // FlingControllerSchedulerClient
+ void ScheduleFlingProgress(
+ base::WeakPtr<FlingController> fling_controller) override;
+ void DidStopFlingingOnBrowser(
+ base::WeakPtr<FlingController> fling_controller) override;
+
+ // FlingSchedulerBase
+ void ProgressFlingOnBeginFrameIfneeded(base::TimeTicks current_time) override;
+
+ protected:
+ RenderWidgetHostImpl* host_;
+ base::WeakPtr<FlingController> fling_controller_;
+
+ private:
+ ui::WindowAndroid* GetRootWindow();
+
+ // WindowAndroidObserver implementation.
+ void OnCompositingDidCommit() override {}
+ void OnRootWindowVisibilityChanged(bool visible) override {}
+ void OnAttachCompositor() override {}
+ void OnDetachCompositor() override;
+ void OnAnimate(base::TimeTicks frame_begin_time) override;
+ void OnActivityStopped() override {}
+ void OnActivityStarted() override {}
+
+ ui::WindowAndroid* observed_window_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(FlingSchedulerAndroid);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_FLING_SCHEDULER_ANDROID_H_
diff --git a/chromium/content/browser/renderer_host/input/fling_scheduler_base.h b/chromium/content/browser/renderer_host/input/fling_scheduler_base.h
new file mode 100644
index 00000000000..cc4b13a7b9c
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/fling_scheduler_base.h
@@ -0,0 +1,20 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_FLING_SCHEDULER_BASE_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_FLING_SCHEDULER_BASE_H_
+
+#include "content/browser/renderer_host/input/fling_controller.h"
+
+namespace content {
+
+class FlingSchedulerBase : public FlingControllerSchedulerClient {
+ public:
+ virtual void ProgressFlingOnBeginFrameIfneeded(
+ base::TimeTicks current_time) = 0;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_FLING_SCHEDULER_BASE_H_
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 10cdaaf1a25..a9ff466e23a 100644
--- a/chromium/content/browser/renderer_host/input/gesture_event_queue.cc
+++ b/chromium/content/browser/renderer_host/input/gesture_event_queue.cc
@@ -47,13 +47,22 @@ GestureEventQueue::GestureEventQueue(
GestureEventQueue::~GestureEventQueue() { }
-bool GestureEventQueue::QueueEvent(
+bool GestureEventQueue::DebounceOrQueueEvent(
const GestureEventWithLatencyInfo& gesture_event) {
- TRACE_EVENT0("input", "GestureEventQueue::QueueEvent");
- if (!ShouldForwardForBounceReduction(gesture_event) ||
- fling_controller_.FilterGestureEvent(gesture_event)) {
+ // GFS should have been filtered in FlingControllerFilterEvent.
+ DCHECK_NE(gesture_event.event.GetType(), WebInputEvent::kGestureFlingStart);
+ if (!ShouldForwardForBounceReduction(gesture_event))
return false;
- }
+
+ QueueAndForwardIfNecessary(gesture_event);
+ return true;
+}
+
+bool GestureEventQueue::FlingControllerFilterEvent(
+ const GestureEventWithLatencyInfo& gesture_event) {
+ TRACE_EVENT0("input", "GestureEventQueue::QueueEvent");
+ if (fling_controller_.FilterGestureEvent(gesture_event))
+ return true;
// fling_controller_ is in charge of handling GFS events and the events are
// not sent to the renderer, the controller processes the fling and generates
@@ -62,7 +71,7 @@ bool GestureEventQueue::QueueEvent(
if (gesture_event.event.GetType() == WebInputEvent::kGestureFlingStart) {
fling_controller_.ProcessGestureFlingStart(gesture_event);
fling_in_progress_ = true;
- return false;
+ return true;
}
// If the GestureFlingStart event is processed by the fling_controller_, the
@@ -70,11 +79,10 @@ bool GestureEventQueue::QueueEvent(
if (gesture_event.event.GetType() == WebInputEvent::kGestureFlingCancel) {
fling_controller_.ProcessGestureFlingCancel(gesture_event);
fling_in_progress_ = false;
- return false;
+ return true;
}
- QueueAndForwardIfNecessary(gesture_event);
- return true;
+ return false;
}
void GestureEventQueue::StopFling() {
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 db490fde11b..f07f3cd6220 100644
--- a/chromium/content/browser/renderer_host/input/gesture_event_queue.h
+++ b/chromium/content/browser/renderer_host/input/gesture_event_queue.h
@@ -77,10 +77,13 @@ class CONTENT_EXPORT GestureEventQueue {
const Config& config);
~GestureEventQueue();
- // Adds a gesture to the queue if it passes the relevant filters. If
- // there are no events currently queued, the event will be forwarded
- // immediately. Returns false if the event wasn't queued and was filtered.
- bool QueueEvent(const GestureEventWithLatencyInfo&);
+ // Uses fling controller to filter the gesture event. Returns true if the
+ // event wasn't queued and was filtered.
+ bool FlingControllerFilterEvent(const GestureEventWithLatencyInfo&);
+
+ // Check for debouncing, or add the gesture event to the queue. Returns false
+ // if the event wasn't queued.
+ bool DebounceOrQueueEvent(const GestureEventWithLatencyInfo&);
// 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
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 d9fc411f476..a977b1921b5 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
@@ -118,7 +118,10 @@ class GestureEventQueueTest : public testing::Test,
}
void SimulateGestureEvent(const WebGestureEvent& gesture) {
- queue()->QueueEvent(GestureEventWithLatencyInfo(gesture));
+ GestureEventWithLatencyInfo gesture_event(gesture);
+ if (!queue()->FlingControllerFilterEvent(gesture_event)) {
+ queue()->DebounceOrQueueEvent(gesture_event);
+ }
}
void SimulateGestureEvent(WebInputEvent::Type type,
@@ -1030,10 +1033,10 @@ TEST_F(GestureEventQueueTest, DebounceDefersFollowingGestureEvents) {
EXPECT_EQ(2U, GestureEventQueueSize());
EXPECT_EQ(2U, GestureEventDebouncingQueueSize());
+ base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMilliseconds(5));
- base::RunLoop().Run();
+ FROM_HERE, run_loop.QuitClosure(), TimeDelta::FromMilliseconds(5));
+ run_loop.Run();
// The deferred events are correctly queued in coalescing queue.
EXPECT_EQ(0U, GetAndResetSentGestureEventCount());
@@ -1053,64 +1056,6 @@ TEST_F(GestureEventQueueTest, DebounceDefersFollowingGestureEvents) {
}
}
-// Test that a GestureFlingStart is not filtered out by debouncing and that
-// GestureFlingStart causes debouncing queue to empty into gesture queue.
-TEST_F(GestureEventQueueTest, DebounceEndsWithFlingStartEvent) {
- SetUpForDebounce(3);
-
- SimulateGestureEvent(WebInputEvent::kGestureScrollUpdate,
- blink::kWebGestureDeviceTouchpad);
- EXPECT_EQ(1U, GetAndResetSentGestureEventCount());
- EXPECT_EQ(1U, GestureEventQueueSize());
- EXPECT_EQ(0U, GestureEventDebouncingQueueSize());
- EXPECT_TRUE(ScrollingInProgress());
-
- SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
- blink::kWebGestureDeviceTouchpad);
- EXPECT_EQ(0U, GetAndResetSentGestureEventCount());
- EXPECT_EQ(1U, GestureEventQueueSize());
- EXPECT_EQ(1U, GestureEventDebouncingQueueSize());
-
- // The deferred events are correctly queued in coalescing queue. The GFS with
- // touchpad source is not queued since it is handled by fling controller.
- SimulateGestureFlingStartEvent(0, 10, blink::kWebGestureDeviceTouchpad);
- EXPECT_EQ(0U, GetAndResetSentGestureEventCount());
- EXPECT_EQ(2U, GestureEventQueueSize());
- EXPECT_EQ(0U, GestureEventDebouncingQueueSize());
- EXPECT_FALSE(ScrollingInProgress());
- EXPECT_TRUE(FlingInProgress());
-
- // While fling is in progress events don't get debounced.
- SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
- blink::kWebGestureDeviceTouchpad);
- EXPECT_EQ(0U, GetAndResetSentGestureEventCount());
- EXPECT_EQ(3U, GestureEventQueueSize());
- EXPECT_EQ(0U, GestureEventDebouncingQueueSize());
-
- SimulateGestureEvent(WebInputEvent::kGestureScrollUpdate,
- blink::kWebGestureDeviceTouchpad);
- EXPECT_EQ(0U, GetAndResetSentGestureEventCount());
- EXPECT_EQ(4U, GestureEventQueueSize());
- EXPECT_EQ(0U, GestureEventDebouncingQueueSize());
-
- SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
- blink::kWebGestureDeviceTouchpad);
- EXPECT_EQ(0U, GetAndResetSentGestureEventCount());
- EXPECT_EQ(5U, GestureEventQueueSize());
- EXPECT_EQ(0U, GestureEventDebouncingQueueSize());
-
- // Verify that the coalescing queue contains the correct events.
- WebInputEvent::Type expected[] = {
- WebInputEvent::kGestureScrollUpdate, WebInputEvent::kGestureScrollEnd,
- WebInputEvent::kGestureScrollBegin, WebInputEvent::kGestureScrollUpdate};
-
- for (unsigned i = 0; i < sizeof(expected) / sizeof(WebInputEvent::Type);
- i++) {
- WebGestureEvent merged_event = GestureEventQueueEventAt(i);
- EXPECT_EQ(expected[i], merged_event.GetType());
- }
-}
-
// Test that non-scroll events are deferred while scrolling during the debounce
// interval and are discarded if a GestureScrollUpdate event arrives before the
// interval end.
diff --git a/chromium/content/browser/renderer_host/input/input_router.h b/chromium/content/browser/renderer_host/input/input_router.h
index 7b6c6f8cb4b..49cde65f553 100644
--- a/chromium/content/browser/renderer_host/input/input_router.h
+++ b/chromium/content/browser/renderer_host/input/input_router.h
@@ -62,7 +62,7 @@ class InputRouter : public IPC::Listener {
virtual void SetFrameTreeNodeId(int frameTreeNodeId) = 0;
// Return the currently allowed touch-action.
- virtual cc::TouchAction AllowedTouchAction() = 0;
+ virtual base::Optional<cc::TouchAction> AllowedTouchAction() = 0;
virtual void SetForceEnableZoom(bool enabled) = 0;
@@ -75,6 +75,15 @@ class InputRouter : public IPC::Listener {
// Used to check if a fling cancellation is deferred due to boosting or not.
virtual bool FlingCancellationIsDeferred() = 0;
+
+ // Called when a set-touch-action message is received from the renderer
+ // for a touch start event that is currently in flight.
+ virtual void OnSetTouchAction(cc::TouchAction touch_action) = 0;
+
+ // In the case when a gesture event is bubbled from a child frame to the main
+ // frame, we set the touch action in the main frame Auto even if there is no
+ // pending touch start.
+ virtual void ForceSetTouchActionAuto() = 0;
};
} // namespace content
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 c1308d16722..788b74bd305 100644
--- a/chromium/content/browser/renderer_host/input/input_router_impl.cc
+++ b/chromium/content/browser/renderer_host/input/input_router_impl.cc
@@ -23,7 +23,6 @@
#include "content/common/view_messages.h"
#include "content/public/browser/notification_service.h"
#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"
@@ -78,10 +77,9 @@ InputRouterImpl::InputRouterImpl(
frame_tree_node_id_(-1),
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_),
+ wheel_event_queue_(this),
touch_event_queue_(this, config.touch_config),
+ touchpad_pinch_event_queue_(this),
gesture_event_queue_(this,
this,
fling_scheduler_client,
@@ -136,6 +134,13 @@ void InputRouterImpl::SendGestureEvent(
GestureEventWithLatencyInfo gesture_event(original_gesture_event);
+ if (gesture_event_queue_.FlingControllerFilterEvent(gesture_event)) {
+ disposition_handler_->OnGestureEventAck(gesture_event,
+ InputEventAckSource::BROWSER,
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ return;
+ }
+
if (touch_action_filter_.FilterGestureEvent(&gesture_event.event) ==
FilterGestureEventResult::kFilterGestureEventFiltered) {
disposition_handler_->OnGestureEventAck(gesture_event,
@@ -164,7 +169,14 @@ void InputRouterImpl::SendGestureEvent(
touch_event_queue_.OnGestureScrollEvent(gesture_event);
}
- if (!gesture_event_queue_.QueueEvent(gesture_event)) {
+ if (blink::WebInputEvent::IsPinchGestureEventType(
+ gesture_event.event.GetType()) &&
+ gesture_event.event.NeedsWheelEvent()) {
+ touchpad_pinch_event_queue_.QueueEvent(gesture_event);
+ return;
+ }
+
+ if (!gesture_event_queue_.DebounceOrQueueEvent(gesture_event)) {
disposition_handler_->OnGestureEventAck(gesture_event,
InputEventAckSource::BROWSER,
INPUT_EVENT_ACK_STATE_CONSUMED);
@@ -185,7 +197,9 @@ void InputRouterImpl::NotifySiteIsMobileOptimized(bool is_mobile_optimized) {
bool InputRouterImpl::HasPendingEvents() const {
return !touch_event_queue_.Empty() || !gesture_event_queue_.empty() ||
- wheel_event_queue_.has_pending() || active_renderer_fling_count_ > 0;
+ wheel_event_queue_.has_pending() ||
+ touchpad_pinch_event_queue_.has_pending() ||
+ active_renderer_fling_count_ > 0;
}
void InputRouterImpl::SetDeviceScaleFactor(float device_scale_factor) {
@@ -200,8 +214,9 @@ void InputRouterImpl::SetForceEnableZoom(bool enabled) {
touch_action_filter_.SetForceEnableZoom(enabled);
}
-cc::TouchAction InputRouterImpl::AllowedTouchAction() {
- return touch_action_filter_.allowed_touch_action();
+base::Optional<cc::TouchAction> InputRouterImpl::AllowedTouchAction() {
+ return touch_action_filter_.allowed_touch_action().value_or(
+ cc::kTouchActionAuto);
}
void InputRouterImpl::BindHost(mojom::WidgetInputHandlerHostRequest request,
@@ -224,15 +239,12 @@ bool InputRouterImpl::FlingCancellationIsDeferred() {
}
void InputRouterImpl::CancelTouchTimeout() {
- touch_event_queue_.SetAckTimeoutEnabled(false);
+ UpdateTouchAckTimeoutEnabled();
}
void InputRouterImpl::SetWhiteListedTouchAction(cc::TouchAction touch_action,
uint32_t unique_touch_event_id,
InputEventAckState state) {
- // TODO(hayleyferr): Catch the cases that we have filtered out sending the
- // touchstart.
-
touch_action_filter_.OnSetWhiteListedTouchAction(touch_action);
client_->OnSetWhiteListedTouchAction(touch_action);
}
@@ -337,12 +349,12 @@ void InputRouterImpl::OnTouchEventAck(const TouchEventWithLatencyInfo& event,
// in some cases we may filter out sending the touchstart - catch those here.
if (WebTouchEventTraits::IsTouchSequenceStart(event.event) &&
ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS) {
- touch_action_filter_.ResetTouchAction();
+ // Touch action must be auto when there is no consumer
+ touch_action_filter_.OnSetTouchAction(cc::kTouchActionAuto);
UpdateTouchAckTimeoutEnabled();
}
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)) {
touch_action_filter_.ReportAndResetTouchAction();
UpdateTouchAckTimeoutEnabled();
@@ -413,6 +425,18 @@ void InputRouterImpl::ForwardGestureEventWithLatencyInfo(
client_->ForwardGestureEventWithLatencyInfo(event, latency_info);
}
+void InputRouterImpl::SendMouseWheelEventForPinchImmediately(
+ const MouseWheelEventWithLatencyInfo& event) {
+ SendMouseWheelEventImmediately(event);
+}
+
+void InputRouterImpl::OnGestureEventForPinchAck(
+ const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
+ InputEventAckState ack_result) {
+ OnGestureEventAck(event, ack_source, ack_result);
+}
+
bool InputRouterImpl::IsWheelScrollInProgress() {
return client_->IsWheelScrollInProgress();
}
@@ -444,8 +468,7 @@ void InputRouterImpl::FilterAndSendWebInputEvent(
std::unique_ptr<InputEvent> event = std::make_unique<InputEvent>(
ScaleEvent(input_event, device_scale_factor_), latency_info);
- if (WebInputEventTraits::ShouldBlockEventStream(
- input_event, wheel_scroll_latching_enabled_)) {
+ if (WebInputEventTraits::ShouldBlockEventStream(input_event)) {
TRACE_EVENT_INSTANT0("input", "InputEventSentBlocking",
TRACE_EVENT_SCOPE_THREAD);
client_->IncrementInFlightEventCount();
@@ -573,23 +596,23 @@ void InputRouterImpl::MouseWheelEventHandled(
DidOverscroll(overscroll.value());
wheel_event_queue_.ProcessMouseWheelAck(source, state, event.latency);
+ touchpad_pinch_event_queue_.ProcessMouseWheelAck(source, state,
+ event.latency);
}
void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) {
TRACE_EVENT1("input", "InputRouterImpl::OnHasTouchEventHandlers",
"has_handlers", has_handlers);
- // Lack of a touch handler indicates that the page either has no touch-action
- // modifiers or that all its touch-action modifiers are auto. Resetting the
- // touch-action here allows forwarding of subsequent gestures even if the
- // underlying touches never reach the router.
- if (!has_handlers)
- touch_action_filter_.ResetTouchAction();
-
+ touch_action_filter_.OnHasTouchEventHandlers(has_handlers);
touch_event_queue_.OnHasTouchEventHandlers(has_handlers);
client_->OnHasTouchEventHandlers(has_handlers);
}
+void InputRouterImpl::ForceSetTouchActionAuto() {
+ touch_action_filter_.OnSetTouchAction(cc::kTouchActionAuto);
+}
+
void InputRouterImpl::OnSetTouchAction(cc::TouchAction touch_action) {
TRACE_EVENT1("input", "InputRouterImpl::OnSetTouchAction", "action",
touch_action);
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 205cb3abc83..53605ce1286 100644
--- a/chromium/content/browser/renderer_host/input/input_router_impl.h
+++ b/chromium/content/browser/renderer_host/input/input_router_impl.h
@@ -22,6 +22,7 @@
#include "content/browser/renderer_host/input/mouse_wheel_event_queue.h"
#include "content/browser/renderer_host/input/passthrough_touch_event_queue.h"
#include "content/browser/renderer_host/input/touch_action_filter.h"
+#include "content/browser/renderer_host/input/touchpad_pinch_event_queue.h"
#include "content/common/input/input_event_stream_validator.h"
#include "content/common/input/input_handler.mojom.h"
#include "content/common/widget.mojom.h"
@@ -55,6 +56,7 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter,
public FlingControllerEventSenderClient,
public MouseWheelEventQueueClient,
public PassthroughTouchEventQueueClient,
+ public TouchpadPinchEventQueueClient,
public mojom::WidgetInputHandlerHost {
public:
InputRouterImpl(InputRouterImplClient* client,
@@ -77,11 +79,13 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter,
void SetDeviceScaleFactor(float device_scale_factor) override;
void SetFrameTreeNodeId(int frame_tree_node_id) override;
void SetForceEnableZoom(bool enabled) override;
- cc::TouchAction AllowedTouchAction() override;
+ base::Optional<cc::TouchAction> AllowedTouchAction() override;
void BindHost(mojom::WidgetInputHandlerHostRequest request,
bool frame_handler) override;
void StopFling() override;
bool FlingCancellationIsDeferred() override;
+ void OnSetTouchAction(cc::TouchAction touch_action) override;
+ void ForceSetTouchActionAuto() override;
// InputHandlerHost impl
void CancelTouchTimeout() override;
@@ -109,6 +113,7 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter,
private:
friend class InputRouterImplTest;
friend class MockRenderWidgetHost;
+ friend class RenderWidgetHostBrowserTest;
// Keeps track of last position of touch points and sets MovementXY for them.
void SetMovementXYForTouchPoints(blink::WebTouchEvent* event);
@@ -148,6 +153,13 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter,
const ui::LatencyInfo& latency_info) override;
bool IsWheelScrollInProgress() override;
+ // TouchpadPinchEventQueueClient
+ void SendMouseWheelEventForPinchImmediately(
+ const MouseWheelEventWithLatencyInfo& event) override;
+ void OnGestureEventForPinchAck(const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
+ InputEventAckState ack_result) override;
+
void FilterAndSendWebInputEvent(
const blink::WebInputEvent& input_event,
const ui::LatencyInfo& latency_info,
@@ -191,7 +203,6 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter,
// IPC message handlers
void OnHasTouchEventHandlers(bool has_handlers);
- void OnSetTouchAction(cc::TouchAction touch_action);
// Called when a touch timeout-affecting bit has changed, in turn toggling the
// touch ack timeout feature of the |touch_event_queue_| as appropriate. Input
@@ -213,9 +224,9 @@ class CONTENT_EXPORT InputRouterImpl : public InputRouter,
// gesture scroll yet.
bool touch_scroll_started_sent_;
- bool wheel_scroll_latching_enabled_;
MouseWheelEventQueue wheel_event_queue_;
PassthroughTouchEventQueue touch_event_queue_;
+ TouchpadPinchEventQueue touchpad_pinch_event_queue_;
GestureEventQueue gesture_event_queue_;
TouchActionFilter touch_action_filter_;
InputEventStreamValidator input_stream_validator_;
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 3e580d0864f..5ff4766f351 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
@@ -64,9 +64,7 @@ namespace content {
namespace {
bool ShouldBlockEventStream(const blink::WebInputEvent& event) {
- return ui::WebInputEventTraits::ShouldBlockEventStream(
- event,
- base::FeatureList::IsEnabled(features::kTouchpadAndWheelScrollLatching));
+ return ui::WebInputEventTraits::ShouldBlockEventStream(event);
}
WebInputEvent& GetEventWithType(WebInputEvent::Type type) {
@@ -92,12 +90,6 @@ WebInputEvent& GetEventWithType(WebInputEvent::Type type) {
return *event;
}
-enum WheelScrollingMode {
- kWheelScrollingModeNone,
- kWheelScrollLatching,
- kAsyncWheelEvents,
-};
-
} // namespace
// TODO(dtapuska): Remove this class when we don't have multiple implementations
@@ -212,26 +204,9 @@ class MockInputRouterImplClient : public InputRouterImplClient {
class InputRouterImplTest : public testing::Test {
public:
- InputRouterImplTest(
- WheelScrollingMode wheel_scrolling_mode = kWheelScrollLatching)
- : wheel_scroll_latching_enabled_(wheel_scrolling_mode !=
- kWheelScrollingModeNone),
- scoped_task_environment_(
+ InputRouterImplTest()
+ : scoped_task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::UI) {
- if (wheel_scrolling_mode == kAsyncWheelEvents) {
- feature_list_.InitWithFeatures({features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents},
- {});
- } else if (wheel_scrolling_mode == kWheelScrollLatching) {
- feature_list_.InitWithFeatures(
- {features::kTouchpadAndWheelScrollLatching},
- {features::kAsyncWheelEvents});
- } else if (wheel_scrolling_mode == kWheelScrollingModeNone) {
- feature_list_.InitWithFeatures({},
- {features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents});
- }
-
vsync_feature_list_.InitAndEnableFeature(
features::kVsyncAlignedInputEvents);
}
@@ -282,17 +257,6 @@ class InputRouterImplTest : public testing::Test {
}
void SimulateWheelEvent(float x,
- float y,
- float dX,
- float dY,
- int modifiers,
- bool precise) {
- input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(
- SyntheticWebMouseWheelEventBuilder::Build(x, y, dX, dY, modifiers,
- precise)));
- }
-
- void SimulateWheelEventWithPhase(float x,
float y,
float dX,
float dY,
@@ -305,19 +269,9 @@ class InputRouterImplTest : public testing::Test {
input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(wheel_event));
}
- void SimulateWheelEventPossiblyIncludingPhase(
- bool ignore_phase,
- float x,
- float y,
- float dX,
- float dY,
- int modifiers,
- bool precise,
- WebMouseWheelEvent::Phase phase) {
- if (ignore_phase)
- SimulateWheelEvent(x, y, dX, dY, modifiers, precise);
- else
- SimulateWheelEventWithPhase(x, y, dX, dY, modifiers, precise, phase);
+ void SimulateWheelEvent(WebMouseWheelEvent::Phase phase) {
+ input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(
+ SyntheticWebMouseWheelEventBuilder::Build(phase)));
}
void SimulateMouseEvent(WebInputEvent::Type type, int x, int y) {
@@ -325,11 +279,6 @@ class InputRouterImplTest : public testing::Test {
SyntheticWebMouseEventBuilder::Build(type, x, y, 0)));
}
- void SimulateWheelEventWithPhase(WebMouseWheelEvent::Phase phase) {
- input_router_->SendWheelEvent(MouseWheelEventWithLatencyInfo(
- SyntheticWebMouseWheelEventBuilder::Build(phase)));
- }
-
void SimulateGestureEvent(WebGestureEvent gesture) {
if (gesture.GetType() == WebInputEvent::kGestureScrollBegin &&
gesture.SourceDevice() == blink::kWebGestureDeviceTouchscreen &&
@@ -373,6 +322,28 @@ class InputRouterImplTest : public testing::Test {
scale, anchor_x, anchor_y, modifiers, source_device));
}
+ void SimulateTouchpadGesturePinchEventWithoutWheel(WebInputEvent::Type type,
+ float scale,
+ float anchor_x,
+ float anchor_y,
+ int modifiers) {
+ DCHECK(blink::WebInputEvent::IsPinchGestureEventType(type));
+ WebGestureEvent event =
+ (type == blink::WebInputEvent::kGesturePinchUpdate
+ ? SyntheticWebGestureEventBuilder::BuildPinchUpdate(
+ scale, anchor_x, anchor_y, modifiers,
+ blink::kWebGestureDeviceTouchpad)
+ : SyntheticWebGestureEventBuilder::Build(
+ type, blink::kWebGestureDeviceTouchpad));
+ // For touchpad pinch, we first send wheel events to the renderer. Only
+ // after these have been acknowledged do we send the actual gesture pinch
+ // events to the renderer. We indicate here that the wheel sending phase is
+ // done for the purpose of testing the sending of the gesture events
+ // themselves.
+ event.SetNeedsWheelEvent(false);
+ SimulateGestureEvent(event);
+ }
+
void SimulateGestureFlingStartEvent(float velocity_x,
float velocity_y,
WebGestureDevice source_device) {
@@ -427,44 +398,39 @@ class InputRouterImplTest : public testing::Test {
unique_touch_event_id, ack_result);
}
+ void ResetTouchAction() {
+ input_router_->touch_action_filter_.ResetTouchAction();
+ }
+
DispatchedMessages GetAndResetDispatchedMessages() {
return client_->GetAndResetDispatchedMessages();
}
static void RunTasksAndWait(base::TimeDelta delay) {
+ base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- delay);
- base::RunLoop().Run();
+ FROM_HERE, run_loop.QuitClosure(), delay);
+ run_loop.Run();
}
- void OverscrollDispatch();
+ void PressAndSetTouchActionAuto() {
+ PressTouchPoint(1, 1);
+ SendTouchEvent();
+ input_router_->OnSetTouchAction(cc::kTouchActionAuto);
+ GetAndResetDispatchedMessages();
+ disposition_handler_->GetAndResetAckCount();
+ }
InputRouter::Config config_;
std::unique_ptr<MockInputRouterImplClient> client_;
std::unique_ptr<InputRouterImpl> input_router_;
std::unique_ptr<MockInputDispositionHandler> disposition_handler_;
- bool wheel_scroll_latching_enabled_;
private:
base::test::ScopedTaskEnvironment scoped_task_environment_;
SyntheticWebTouchEvent touch_event_;
base::test::ScopedFeatureList vsync_feature_list_;
- base::test::ScopedFeatureList feature_list_;
-};
-
-class InputRouterImplWheelScrollLatchingDisabledTest
- : public InputRouterImplTest {
- public:
- InputRouterImplWheelScrollLatchingDisabledTest()
- : InputRouterImplTest(kWheelScrollingModeNone) {}
-};
-
-class InputRouterImplAsyncWheelEventEnabledTest : public InputRouterImplTest {
- public:
- InputRouterImplAsyncWheelEventEnabledTest()
- : InputRouterImplTest(kAsyncWheelEvents) {}
};
TEST_F(InputRouterImplTest, HandledInputEvent) {
@@ -521,24 +487,22 @@ TEST_F(InputRouterImplTest, HandleKeyEventsWeSent) {
TEST_F(InputRouterImplTest, CoalescesWheelEvents) {
// Simulate wheel events.
- SimulateWheelEventPossiblyIncludingPhase(
- !wheel_scroll_latching_enabled_, 0, 0, 0, -5, 0, false,
- WebMouseWheelEvent::kPhaseBegan); // sent directly
- SimulateWheelEventPossiblyIncludingPhase(
- !wheel_scroll_latching_enabled_, 0, 0, 0, -10, 0, false,
- WebMouseWheelEvent::kPhaseChanged); // enqueued
- SimulateWheelEventPossiblyIncludingPhase(
- !wheel_scroll_latching_enabled_, 0, 0, 8, -6, 0, false,
+ SimulateWheelEvent(0, 0, 0, -5, 0, false,
+ WebMouseWheelEvent::kPhaseBegan); // sent directly
+ SimulateWheelEvent(0, 0, 0, -10, 0, false,
+ WebMouseWheelEvent::kPhaseChanged); // enqueued
+ SimulateWheelEvent(
+ 0, 0, 8, -6, 0, false,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
- SimulateWheelEventPossiblyIncludingPhase(
- !wheel_scroll_latching_enabled_, 0, 0, 9, -7, 1, false,
+ SimulateWheelEvent(
+ 0, 0, 9, -7, 1, false,
WebMouseWheelEvent::kPhaseChanged); // enqueued, different modifiers
- SimulateWheelEventPossiblyIncludingPhase(
- !wheel_scroll_latching_enabled_, 0, 0, 0, -10, 0, false,
+ SimulateWheelEvent(
+ 0, 0, 0, -10, 0, false,
WebMouseWheelEvent::kPhaseChanged); // enqueued, different modifiers
// Explicitly verify that PhaseEnd isn't coalesced to avoid bugs like
// https://crbug.com/154740.
- SimulateWheelEventWithPhase(WebMouseWheelEvent::kPhaseEnded); // enqueued
+ SimulateWheelEvent(WebMouseWheelEvent::kPhaseEnded); // enqueued
// Check that only the first event was sent.
DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
@@ -697,162 +661,8 @@ TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
TEST_F(InputRouterImplTest, UnhandledWheelEvent) {
// Simulate wheel events.
- SimulateWheelEventPossiblyIncludingPhase(!wheel_scroll_latching_enabled_, 0,
- 0, 0, -5, 0, false,
- WebMouseWheelEvent::kPhaseBegan);
- SimulateWheelEventPossiblyIncludingPhase(!wheel_scroll_latching_enabled_, 0,
- 0, 0, -10, 0, false,
- WebMouseWheelEvent::kPhaseChanged);
-
- // Check that only the first event was sent.
- DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
- ASSERT_EQ(1U, dispatched_messages.size());
- ASSERT_TRUE(dispatched_messages[0]->ToEvent());
-
- // Indicate that the wheel event was unhandled.
- dispatched_messages[0]->ToEvent()->CallCallback(
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- dispatched_messages = GetAndResetDispatchedMessages();
-
- // GestureEventQueue allows multiple in-flight events, so there should be a
- // ScrollBegin, ScrollUpdate, and MouseWheel sent.
- 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_messages[0]->ToEvent()->Event()->web_event->GetType());
- ASSERT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_messages[1]->ToEvent()->Event()->web_event->GetType());
- ASSERT_EQ(WebInputEvent::kMouseWheel,
- 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.
- EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
- EXPECT_EQ(disposition_handler_->acked_wheel_event().delta_y, -5);
-
- // Ack the gesture scroll update event.
- dispatched_messages[1]->ToEvent()->CallCallback(
- INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
-
- // Ack the mouse wheel event.
- dispatched_messages[2]->ToEvent()->CallCallback(
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
-
- dispatched_messages = GetAndResetDispatchedMessages();
- ASSERT_EQ(1U, dispatched_messages.size());
- ASSERT_TRUE(dispatched_messages[0]->ToEvent());
- ASSERT_EQ(WebInputEvent::kGestureScrollUpdate,
- 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);
-
- dispatched_messages[0]->ToEvent()->CallCallback(
- INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // Check that the ack for ScrollUpdate were processed.
- EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
-}
-TEST_F(InputRouterImplWheelScrollLatchingDisabledTest, UnhandledWheelEvent) {
- // Simulate wheel events.
- SimulateWheelEventPossiblyIncludingPhase(!wheel_scroll_latching_enabled_, 0,
- 0, 0, -5, 0, false,
- WebMouseWheelEvent::kPhaseBegan);
- SimulateWheelEventPossiblyIncludingPhase(!wheel_scroll_latching_enabled_, 0,
- 0, 0, -10, 0, false,
- WebMouseWheelEvent::kPhaseChanged);
-
- // Check that only the first event was sent.
- DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
- ASSERT_EQ(1U, dispatched_messages.size());
- ASSERT_TRUE(dispatched_messages[0]->ToEvent());
-
- // Indicate that the wheel event was unhandled.
- dispatched_messages[0]->ToEvent()->CallCallback(
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- 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.
- 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_messages[0]->ToEvent()->Event()->web_event->GetType());
- ASSERT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_messages[1]->ToEvent()->Event()->web_event->GetType());
- ASSERT_EQ(WebInputEvent::kGestureScrollEnd,
- dispatched_messages[2]->ToEvent()->Event()->web_event->GetType());
- ASSERT_EQ(WebInputEvent::kMouseWheel,
- dispatched_messages[3]->ToEvent()->Event()->web_event->GetType());
-
- // Ack the ScrollUpdate
- 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, GetAndResetDispatchedMessages().size());
-
- // Ack the MouseWheel.
- 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_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_messages[0]->ToEvent()->Event()->web_event->GetType());
- ASSERT_EQ(WebInputEvent::kGestureScrollUpdate,
- dispatched_messages[1]->ToEvent()->Event()->web_event->GetType());
- ASSERT_EQ(WebInputEvent::kGestureScrollEnd,
- 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);
-
- dispatched_messages[1]->ToEvent()->CallCallback(
- INPUT_EVENT_ACK_STATE_CONSUMED);
- // The GestureScrollEnd should have already been processed.
- EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
-
- // Check that the ack for the ScrollUpdate and ScrollEnd were processed.
- EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
-}
-
-TEST_F(InputRouterImplAsyncWheelEventEnabledTest, UnhandledWheelEvent) {
- // Simulate wheel events.
- SimulateWheelEventWithPhase(0, 0, 0, -5, 0, false,
- WebMouseWheelEvent::kPhaseBegan);
- SimulateWheelEventWithPhase(0, 0, 0, -10, 0, false,
- WebMouseWheelEvent::kPhaseChanged);
+ SimulateWheelEvent(0, 0, 0, -5, 0, false, WebMouseWheelEvent::kPhaseBegan);
+ SimulateWheelEvent(0, 0, 0, -10, 0, false, WebMouseWheelEvent::kPhaseChanged);
// Check that only the first event was sent.
DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
@@ -928,6 +738,7 @@ TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) {
// Precede the TouchCancel with an appropriate TouchStart;
PressTouchPoint(1, 1);
SendTouchEvent();
+ input_router_->OnSetTouchAction(cc::kTouchActionAuto);
DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
ASSERT_EQ(1U, dispatched_messages.size());
ASSERT_TRUE(dispatched_messages[0]->ToEvent());
@@ -971,6 +782,7 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAck) {
for (size_t i = 0; i < arraysize(eventTypes); ++i) {
WebInputEvent::Type type = eventTypes[i];
if (ShouldBlockEventStream(GetEventWithType(type))) {
+ PressAndSetTouchActionAuto();
SimulateGestureEvent(type, blink::kWebGestureDeviceTouchscreen);
DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
@@ -1001,6 +813,10 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAck) {
EXPECT_EQ(0, client_->in_flight_event_count());
EXPECT_FALSE(HasPendingEvents());
continue;
+
+ ReleaseTouchPoint(0);
+ SendTouchEvent();
+ GetAndResetDispatchedMessages();
}
SimulateGestureEvent(type, blink::kWebGestureDeviceTouchscreen);
@@ -1067,7 +883,7 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
// Interleave a few events that do and do not ignore acks. All gesture events
// should be dispatched immediately, but the acks will be blocked on blocking
// events.
-
+ PressAndSetTouchActionAuto();
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
@@ -1153,11 +969,15 @@ TEST_F(InputRouterImplTest, GestureTypesIgnoringAckInterleaved) {
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
EXPECT_EQ(2U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
+
+ ReleaseTouchPoint(0);
+ SendTouchEvent();
}
// Test that GestureShowPress events don't get out of order due to
// ignoring their acks.
TEST_F(InputRouterImplTest, GestureShowPressIsInOrder) {
+ PressAndSetTouchActionAuto();
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
@@ -1209,6 +1029,9 @@ TEST_F(InputRouterImplTest, GestureShowPressIsInOrder) {
EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
EXPECT_EQ(3U, disposition_handler_->GetAndResetAckCount());
EXPECT_EQ(0, client_->in_flight_event_count());
+
+ ReleaseTouchPoint(0);
+ SendTouchEvent();
}
// Test that touch ack timeout behavior is properly configured for
@@ -1242,6 +1065,8 @@ TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
ReleaseTouchPoint(0);
SendTouchEvent();
EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
+
+ PressAndSetTouchActionAuto();
EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
ASSERT_TRUE(TouchEventTimeoutEnabled());
@@ -1272,6 +1097,7 @@ TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
PressTouchPoint(1, 1);
SendTouchEvent();
+ input_router_->OnSetTouchAction(cc::kTouchActionNone);
DispatchedMessages touch_press_event3 = GetAndResetDispatchedMessages();
ASSERT_EQ(1u, touch_press_event3.size());
ASSERT_TRUE(touch_press_event3[0]->ToEvent());
@@ -1291,6 +1117,8 @@ TEST_F(InputRouterImplTest, TouchAckTimeoutConfigured) {
// should be restored.
PressTouchPoint(1, 1);
SendTouchEvent();
+ ResetTouchAction();
+ input_router_->OnSetTouchAction(cc::kTouchActionAuto);
EXPECT_TRUE(TouchEventTimeoutEnabled());
}
@@ -1336,6 +1164,8 @@ TEST_F(InputRouterImplTest,
// End the touch sequence.
ReleaseTouchPoint(0);
SendTouchEvent();
+ ResetTouchAction();
+ input_router_->OnSetTouchAction(cc::kTouchActionAuto);
dispatched_messages = GetAndResetDispatchedMessages();
EXPECT_EQ(1U, dispatched_messages.size());
dispatched_messages[0]->ToEvent()->CallCallback(
@@ -1417,6 +1247,9 @@ TEST_F(InputRouterImplTest, TouchActionResetBeforeEventReachesRenderer) {
// Ensure touch action has been set to auto, as a new touch sequence has
// started.
touch_press_event2[0]->ToEvent()->CallCallback(
+ InputEventAckSource::COMPOSITOR_THREAD, ui::LatencyInfo(),
+ INPUT_EVENT_ACK_STATE_CONSUMED, base::nullopt, cc::kTouchActionAuto);
+ 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());
@@ -1487,6 +1320,7 @@ TEST_F(InputRouterImplTest, TouchActionResetWhenTouchHasNoConsumer) {
touch_press_event2[0]->ToEvent()->CallCallback(
INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ PressAndSetTouchActionAuto();
// Ensure touch action has been set to auto, as the touch had no consumer.
EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
@@ -1561,6 +1395,7 @@ TEST_F(InputRouterImplTest, AsyncTouchMoveAckedImmediately) {
PressTouchPoint(1, 1);
SendTouchEvent();
+ input_router_->OnSetTouchAction(cc::kTouchActionAuto);
EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
ASSERT_EQ(1U, dispatched_messages.size());
@@ -1676,6 +1511,12 @@ TEST_F(InputRouterImplTest, TouchpadPinchUpdate) {
// Note that the Touchscreen case is verified as NOT doing this as
// part of the ShowPressIsInOrder test.
+ SimulateGestureEvent(WebInputEvent::kGesturePinchBegin,
+ blink::kWebGestureDeviceTouchpad);
+ EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
+ ASSERT_EQ(WebInputEvent::kGesturePinchBegin,
+ disposition_handler_->ack_event_type());
+
SimulateGesturePinchUpdateEvent(1.5f, 20, 25, 0,
blink::kWebGestureDeviceTouchpad);
@@ -1685,13 +1526,15 @@ TEST_F(InputRouterImplTest, TouchpadPinchUpdate) {
ASSERT_TRUE(dispatched_messages[0]->ToEvent());
const WebInputEvent* input_event =
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);
- EXPECT_EQ(20, gesture_event->PositionInWidget().x);
- EXPECT_EQ(25, gesture_event->PositionInWidget().y);
- EXPECT_EQ(20, gesture_event->PositionInScreen().x);
- EXPECT_EQ(25, gesture_event->PositionInScreen().y);
+ ASSERT_EQ(WebInputEvent::kMouseWheel, input_event->GetType());
+ const WebMouseWheelEvent* synthetic_wheel =
+ static_cast<const WebMouseWheelEvent*>(input_event);
+ EXPECT_EQ(20, synthetic_wheel->PositionInWidget().x);
+ EXPECT_EQ(25, synthetic_wheel->PositionInWidget().y);
+ EXPECT_EQ(20, synthetic_wheel->PositionInScreen().x);
+ EXPECT_EQ(25, synthetic_wheel->PositionInScreen().y);
+ EXPECT_TRUE(synthetic_wheel->GetModifiers() &
+ blink::WebInputEvent::kControlKey);
dispatched_messages[0]->ToEvent()->CallCallback(
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
@@ -1714,8 +1557,8 @@ TEST_F(InputRouterImplTest, TouchpadPinchUpdate) {
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);
+ ASSERT_EQ(WebInputEvent::kMouseWheel, input_event->GetType());
+ synthetic_wheel = static_cast<const WebMouseWheelEvent*>(input_event);
dispatched_messages[0]->ToEvent()->CallCallback(
INPUT_EVENT_ACK_STATE_CONSUMED);
@@ -1728,6 +1571,12 @@ TEST_F(InputRouterImplTest, TouchpadPinchUpdate) {
EXPECT_FLOAT_EQ(
0.3f,
disposition_handler_->acked_gesture_event().data.pinch_update.scale);
+
+ SimulateGestureEvent(WebInputEvent::kGesturePinchEnd,
+ blink::kWebGestureDeviceTouchpad);
+ EXPECT_EQ(1U, disposition_handler_->GetAndResetAckCount());
+ ASSERT_EQ(WebInputEvent::kGesturePinchEnd,
+ disposition_handler_->ack_event_type());
}
// Test proper handling of touchpad Gesture{Pinch,Scroll}Update sequences.
@@ -1744,8 +1593,8 @@ TEST_F(InputRouterImplTest, TouchpadPinchAndScrollUpdate) {
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);
+ SimulateTouchpadGesturePinchEventWithoutWheel(
+ WebInputEvent::kGesturePinchUpdate, 1.5f, 20, 25, 0);
DispatchedMessages temp_dispatched_messages = GetAndResetDispatchedMessages();
ASSERT_EQ(1U, temp_dispatched_messages.size());
ASSERT_TRUE(temp_dispatched_messages[0]->ToEvent());
@@ -1760,8 +1609,8 @@ TEST_F(InputRouterImplTest, TouchpadPinchAndScrollUpdate) {
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);
+ SimulateTouchpadGesturePinchEventWithoutWheel(
+ WebInputEvent::kGesturePinchUpdate, 1.5f, 20, 25, 0);
temp_dispatched_messages = GetAndResetDispatchedMessages();
ASSERT_EQ(1U, temp_dispatched_messages.size());
ASSERT_TRUE(temp_dispatched_messages[0]->ToEvent());
@@ -1815,7 +1664,7 @@ TEST_F(InputRouterImplTest, TouchpadPinchAndScrollUpdate) {
// Test proper routing of overscroll notifications received either from
// event acks or from |DidOverscroll| IPC messages.
-void InputRouterImplTest::OverscrollDispatch() {
+TEST_F(InputRouterImplTest, OverscrollDispatch) {
DidOverscrollParams overscroll;
overscroll.accumulated_overscroll = gfx::Vector2dF(-14, 14);
overscroll.latest_overscroll_delta = gfx::Vector2dF(-7, 0);
@@ -1838,9 +1687,7 @@ void InputRouterImplTest::OverscrollDispatch() {
wheel_overscroll.latest_overscroll_delta = gfx::Vector2dF(3, 0);
wheel_overscroll.current_fling_velocity = gfx::Vector2dF(1, 0);
- SimulateWheelEventPossiblyIncludingPhase(!wheel_scroll_latching_enabled_, 0,
- 0, 3, 0, 0, false,
- WebMouseWheelEvent::kPhaseBegan);
+ SimulateWheelEvent(0, 0, 3, 0, 0, false, WebMouseWheelEvent::kPhaseBegan);
DispatchedMessages dispatched_messages = GetAndResetDispatchedMessages();
ASSERT_EQ(1U, dispatched_messages.size());
ASSERT_TRUE(dispatched_messages[0]->ToEvent());
@@ -1862,16 +1709,6 @@ void InputRouterImplTest::OverscrollDispatch() {
EXPECT_EQ(gfx::Vector2dF(), client_overscroll.current_fling_velocity);
}
-TEST_F(InputRouterImplTest, OverscrollDispatch) {
- OverscrollDispatch();
-}
-TEST_F(InputRouterImplWheelScrollLatchingDisabledTest, OverscrollDispatch) {
- OverscrollDispatch();
-}
-TEST_F(InputRouterImplAsyncWheelEventEnabledTest, OverscrollDispatch) {
- OverscrollDispatch();
-}
-
// Test proper routing of whitelisted touch action notifications received from
// |SetWhiteListedTouchAction| IPC messages.
TEST_F(InputRouterImplTest, OnSetWhiteListedTouchAction) {
@@ -1934,8 +1771,10 @@ TEST_F(InputRouterImplTest, TouchActionInCallback) {
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());
+ base::Optional<cc::TouchAction> allowed_touch_action =
+ input_router_->AllowedTouchAction();
+ DCHECK(allowed_touch_action.has_value());
+ EXPECT_EQ(cc::TouchAction::kTouchActionNone, allowed_touch_action.value());
}
namespace {
@@ -2005,8 +1844,7 @@ TEST_F(InputRouterImplScaleMouseEventTest, ScaleMouseEventTest) {
}
TEST_F(InputRouterImplScaleEventTest, ScaleMouseWheelEventTest) {
- SimulateWheelEventWithPhase(5, 5, 10, 10, 0, false,
- WebMouseWheelEvent::kPhaseBegan);
+ SimulateWheelEvent(5, 5, 10, 10, 0, false, WebMouseWheelEvent::kPhaseBegan);
UpdateDispatchedMessages();
const WebMouseWheelEvent* sent_event =
@@ -2106,6 +1944,7 @@ class InputRouterImplScaleTouchEventTest
} // namespace
TEST_F(InputRouterImplScaleTouchEventTest, ScaleTouchEventTest) {
+ ResetTouchAction();
// Press
PressTouchPoint(10, 20);
PressTouchPoint(100, 200);
@@ -2251,6 +2090,7 @@ TEST_F(InputRouterImplScaleGestureEventTest, GestureScrollUpdate) {
}
TEST_F(InputRouterImplScaleGestureEventTest, GestureScrollBegin) {
+ PressAndSetTouchActionAuto();
SimulateGestureEvent(SyntheticWebGestureEventBuilder::BuildScrollBegin(
10.f, 20.f, blink::kWebGestureDeviceTouchscreen));
FlushGestureEvent(WebInputEvent::kGestureScrollBegin);
@@ -2267,8 +2107,8 @@ TEST_F(InputRouterImplScaleGestureEventTest, GestureScrollBegin) {
TEST_F(InputRouterImplScaleGestureEventTest, GesturePinchUpdate) {
const gfx::PointF orig(10, 20), scaled(20, 40);
- SimulateGesturePinchUpdateEvent(1.5f, orig.x(), orig.y(), 0,
- blink::kWebGestureDeviceTouchpad);
+ SimulateTouchpadGesturePinchEventWithoutWheel(
+ WebInputEvent::kGesturePinchUpdate, 1.5f, orig.x(), orig.y(), 0);
FlushGestureEvent(WebInputEvent::kGesturePinchUpdate);
const WebGestureEvent* sent_event = GetSentWebInputEvent<WebGestureEvent>();
TestLocationInSentEvent(sent_event, orig, scaled);
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 e899b036cad..a7c0c6dca37 100644
--- a/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/mouse_latency_browsertest.cc
@@ -39,8 +39,6 @@ const char kDataURL[] =
"<html>"
"<head>"
"<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', () => {"
@@ -48,6 +46,12 @@ const char kDataURL[] =
" while(performance.now() < end);"
" document.body.style.backgroundColor = 'rgb(' + (i++) + ',0,0)'"
" });"
+ " document.addEventListener('wheel', (e) => {"
+ " if (!e.cancelable)"
+ " return;"
+ " var end = performance.now() + 50;"
+ " while(performance.now() < end);"
+ " });"
"</script>"
"<style>"
"body {"
@@ -79,11 +83,18 @@ class TracingRenderWidgetHost : public RenderWidgetHostImpl {
process,
routing_id,
std::move(widget),
- hidden) {}
- void OnGpuSwapBuffersCompletedInternal(
- const ui::LatencyInfo& latency_info) override {
- RenderWidgetHostImpl::OnGpuSwapBuffersCompletedInternal(latency_info);
- RunClosureIfNecessary(latency_info);
+ hidden) {
+ ui::LatencyTracker::SetLatencyInfoProcessorForTesting(base::BindRepeating(
+ &TracingRenderWidgetHost::HandleLatencyInfoAfterGpuSwap,
+ base::Unretained(this)));
+ }
+
+ void HandleLatencyInfoAfterGpuSwap(
+ const std::vector<ui::LatencyInfo>& latency_infos) {
+ for (const auto& latency_info : latency_infos) {
+ if (latency_info.terminated())
+ RunClosureIfNecessary(latency_info);
+ }
}
void OnMouseEventAck(const MouseEventWithLatencyInfo& event,
@@ -214,6 +225,24 @@ class MouseLatencyBrowserTest : public ContentBrowserTest {
runner_->Run();
}
+ // Generate mouse wheel scroll.
+ void DoSyncCoalescedMouseWheel(const gfx::PointF position,
+ const gfx::Vector2dF& delta) {
+ SyntheticSmoothScrollGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
+ params.anchor = position;
+ params.distances.push_back(delta);
+
+ GetWidgetHost()->QueueSyntheticGesture(
+ SyntheticGesture::Create(params),
+ base::BindOnce(&MouseLatencyBrowserTest::OnSyntheticGestureCompleted,
+ base::Unretained(this)));
+
+ // Runs until we get the OnSyntheticGestureCompleted callback
+ runner_ = std::make_unique<base::RunLoop>();
+ runner_->Run();
+ }
+
void StartTracing() {
base::trace_event::TraceConfig trace_config(
"{"
@@ -245,6 +274,37 @@ class MouseLatencyBrowserTest : public ContentBrowserTest {
return trace_data_;
}
+ void AssertTraceIdsBeginAndEnd(const base::Value& trace_data,
+ const std::string& trace_event_name) {
+ const base::DictionaryValue* 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 != trace_event_name)
+ 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);
+ }
+ }
+
private:
base::MessageLoop loop_;
std::unique_ptr<base::RunLoop> runner_;
@@ -311,16 +371,10 @@ IN_PROC_BROWSER_TEST_F(MouseLatencyBrowserTest,
// 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).
-// http://crbug.com/801629 : Flaky on Linux and Windows
-#if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_LINUX)
-#define MAYBE_CoalescedMouseMovesCorrectlyTerminated \
- DISABLED_CoalescedMouseMovesCorrectlyTerminated
-#else
-#define MAYBE_CoalescedMouseMovesCorrectlyTerminated \
- CoalescedMouseMovesCorrectlyTerminated
-#endif
+// http://crbug.com/801629 : Flaky on Linux and Windows, and Mac with
+// --enable-features=VizDisplayCompositor
IN_PROC_BROWSER_TEST_F(MouseLatencyBrowserTest,
- MAYBE_CoalescedMouseMovesCorrectlyTerminated) {
+ DISABLED_CoalescedMouseMovesCorrectlyTerminated) {
LoadURL();
StartTracing();
@@ -331,34 +385,18 @@ IN_PROC_BROWSER_TEST_F(MouseLatencyBrowserTest,
->WaitFor("InputLatency::MouseUp");
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));
+ AssertTraceIdsBeginAndEnd(trace_data, "InputLatency::MouseMove");
+}
- if (name != "InputLatency::MouseMove")
- continue;
+IN_PROC_BROWSER_TEST_F(MouseLatencyBrowserTest,
+ CoalescedMouseWheelsCorrectlyTerminated) {
+ LoadURL();
- std::string id;
- if (traceEvent->GetString("id", &id))
- ++trace_ids[id];
- }
+ StartTracing();
+ DoSyncCoalescedMouseWheel(gfx::PointF(100, 100), gfx::Vector2dF(0, -100));
+ const base::Value& trace_data = StopTracing();
- 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);
- }
+ AssertTraceIdsBeginAndEnd(trace_data, "InputLatency::MouseWheel");
}
} // 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 c3f4641e852..702915772e4 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
@@ -35,15 +35,8 @@ class QueuedWebMouseWheelEvent : public MouseWheelEventWithLatencyInfo {
DISALLOW_COPY_AND_ASSIGN(QueuedWebMouseWheelEvent);
};
-MouseWheelEventQueue::MouseWheelEventQueue(MouseWheelEventQueueClient* client,
- bool enable_scroll_latching)
+MouseWheelEventQueue::MouseWheelEventQueue(MouseWheelEventQueueClient* client)
: client_(client),
- needs_scroll_begin_when_scroll_latching_disabled_(true),
- needs_scroll_end_when_scroll_latching_disabled_(false),
- enable_scroll_latching_(enable_scroll_latching),
- enable_async_wheel_events_(
- base::FeatureList::IsEnabled(features::kAsyncWheelEvents) &&
- enable_scroll_latching),
send_wheel_events_async_(false),
scrolling_device_(blink::kWebGestureDeviceUninitialized) {
DCHECK(client);
@@ -59,6 +52,9 @@ void MouseWheelEventQueue::QueueEvent(
if (event_sent_for_gesture_ack_ && !wheel_queue_.empty()) {
QueuedWebMouseWheelEvent* last_event = wheel_queue_.back().get();
if (last_event->CanCoalesceWith(event)) {
+ // Terminate the LatencyInfo of the event before it gets coalesced away.
+ event.latency.Terminate();
+
last_event->CoalesceWith(event);
TRACE_EVENT_INSTANT2("input", "MouseWheelEventQueue::CoalescedWheelEvent",
TRACE_EVENT_SCOPE_THREAD, "total_dx",
@@ -144,8 +140,7 @@ void MouseWheelEventQueue::ProcessMouseWheelAck(
scroll_update.data.scroll_update.delta_y =
event_sent_for_gesture_ack_->event.delta_y;
}
- // Only OSX populates the phase and momentumPhase; so
- // |inertialPhase| will be UnknownMomentumPhase on all other platforms.
+
if (event_sent_for_gesture_ack_->event.momentum_phase !=
blink::WebMouseWheelEvent::kPhaseNone) {
scroll_update.data.scroll_update.inertial_phase =
@@ -209,77 +204,29 @@ void MouseWheelEventQueue::ProcessMouseWheelAck(
if (needs_update)
RecordLatchingUmaMetric(client_->IsWheelScrollInProgress());
- 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;
-
- if (!client_->IsWheelScrollInProgress())
- SendScrollBegin(scroll_update, synthetic);
- }
-
- if (needs_update) {
- // It is possible that the wheel event with phaseBegan is consumed and
- // no GSB is sent.
- if (!client_->IsWheelScrollInProgress())
- 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);
- client_->ForwardGestureEventWithLatencyInfo(scroll_update, latency);
- }
-
- if (current_phase_ended && client_->IsWheelScrollInProgress()) {
- // Send GSE when scroll latching is enabled, GSB is sent, and no fling
- // is going to happen next.
- SendScrollEnd(scroll_update, synthetic);
- }
- } else { // !enable_scroll_latching_
-
- // If there is no update to send and the current phase is ended yet a GSB
- // needs to be sent, this event sequence doesn't need to be generated
- // 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_when_scroll_latching_disabled_ &&
- current_phase_ended &&
- !event_sent_for_gesture_ack_->event.has_synthetic_phase;
- if (needs_update || !empty_sequence) {
- 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) {
- // If a GSB has been sent, generate a synthetic GSB if we have phase
- // information. This should be removed once crbug.com/526463 is
- // fully implemented.
- SendScrollBegin(scroll_update, true);
- }
-
- if (needs_update) {
- ui::LatencyInfo latency = ui::LatencyInfo(ui::SourceEventType::WHEEL);
- latency.AddLatencyNumber(
- ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL,
- 0);
- client_->ForwardGestureEventWithLatencyInfo(scroll_update, latency);
- }
-
- if (current_phase_ended) {
- // Non-synthetic GSEs are sent when the current phase is canceled or
- // ended.
- SendScrollEnd(scroll_update, false);
- } else if (has_phase_info) {
- // Generate a synthetic GSE for every update to force hit testing so
- // that the non-latching behavior is preserved. Remove once
- // crbug.com/526463 is fully implemented.
- SendScrollEnd(scroll_update, true);
- } else if (!has_phase_info) {
- SendScrollEnd(scroll_update, false);
- }
- }
+ 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;
+
+ if (!client_->IsWheelScrollInProgress())
+ SendScrollBegin(scroll_update, synthetic);
+ }
+
+ if (needs_update) {
+ // It is possible that the wheel event with phaseBegan is consumed and
+ // no GSB is sent.
+ if (!client_->IsWheelScrollInProgress())
+ SendScrollBegin(scroll_update, synthetic);
+ client_->ForwardGestureEventWithLatencyInfo(
+ scroll_update, ui::LatencyInfo(ui::SourceEventType::WHEEL));
+ }
+
+ if (current_phase_ended && client_->IsWheelScrollInProgress()) {
+ // Send GSE when GSB is sent and no fling is going to happen next.
+ SendScrollEnd(scroll_update, synthetic);
}
}
@@ -312,18 +259,16 @@ void MouseWheelEventQueue::TryForwardNextEventToRenderer() {
event_sent_for_gesture_ack_ = std::move(wheel_queue_.front());
wheel_queue_.pop_front();
- if (enable_async_wheel_events_) {
- DCHECK(event_sent_for_gesture_ack_->event.phase !=
- blink::WebMouseWheelEvent::kPhaseNone ||
- event_sent_for_gesture_ack_->event.momentum_phase !=
- blink::WebMouseWheelEvent::kPhaseNone);
- if (event_sent_for_gesture_ack_->event.phase ==
- blink::WebMouseWheelEvent::kPhaseBegan) {
- send_wheel_events_async_ = false;
- } else if (send_wheel_events_async_) {
- event_sent_for_gesture_ack_->event.dispatch_type =
- WebInputEvent::kEventNonBlocking;
- }
+ DCHECK(event_sent_for_gesture_ack_->event.phase !=
+ blink::WebMouseWheelEvent::kPhaseNone ||
+ event_sent_for_gesture_ack_->event.momentum_phase !=
+ blink::WebMouseWheelEvent::kPhaseNone);
+ if (event_sent_for_gesture_ack_->event.phase ==
+ blink::WebMouseWheelEvent::kPhaseBegan) {
+ send_wheel_events_async_ = false;
+ } else if (send_wheel_events_async_) {
+ event_sent_for_gesture_ack_->event.dispatch_type =
+ WebInputEvent::kEventNonBlocking;
}
client_->SendMouseWheelEventImmediately(*event_sent_for_gesture_ack_);
@@ -331,10 +276,6 @@ void MouseWheelEventQueue::TryForwardNextEventToRenderer() {
void MouseWheelEventQueue::SendScrollEnd(WebGestureEvent update_event,
bool synthetic) {
- DCHECK(enable_scroll_latching_ ||
- (synthetic && !needs_scroll_end_when_scroll_latching_disabled_) ||
- needs_scroll_end_when_scroll_latching_disabled_);
-
DCHECK(client_->IsWheelScrollInProgress());
WebGestureEvent scroll_end(update_event);
@@ -347,10 +288,6 @@ void MouseWheelEventQueue::SendScrollEnd(WebGestureEvent update_event,
scroll_end.data.scroll_end.delta_units =
update_event.data.scroll_update.delta_units;
- if (!synthetic) {
- 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));
}
@@ -358,10 +295,6 @@ void MouseWheelEventQueue::SendScrollEnd(WebGestureEvent update_event,
void MouseWheelEventQueue::SendScrollBegin(
const WebGestureEvent& gesture_update,
bool synthetic) {
- DCHECK(enable_scroll_latching_ ||
- (synthetic && !needs_scroll_begin_when_scroll_latching_disabled_) ||
- needs_scroll_begin_when_scroll_latching_disabled_);
-
DCHECK(!client_->IsWheelScrollInProgress());
WebGestureEvent scroll_begin(gesture_update);
@@ -377,8 +310,6 @@ void MouseWheelEventQueue::SendScrollBegin(
scroll_begin.data.scroll_begin.delta_hint_units =
gesture_update.data.scroll_update.delta_units;
- 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));
}
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 b7042a7f493..20730400dce 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
@@ -39,13 +39,10 @@ class CONTENT_EXPORT MouseWheelEventQueueClient {
// A queue for throttling and coalescing mouse wheel events.
class CONTENT_EXPORT MouseWheelEventQueue {
public:
- // The |client| must outlive the MouseWheelEventQueue. |send_gestures|
- // indicates whether mouse wheel events should generate
- // Scroll[Begin|Update|End] on unhandled acknowledge events.
- // |scroll_transaction_ms| is the duration in which the
- // ScrollEnd should be sent after a ScrollUpdate.
- MouseWheelEventQueue(MouseWheelEventQueueClient* client,
- bool enable_scroll_latching);
+ // The |client| must outlive the MouseWheelEventQueue.
+ // |IsWheelScrollInProgress| indicates whether mouse wheel events should
+ // generate Scroll[Begin|Update|End] on unhandled acknowledge events.
+ MouseWheelEventQueue(MouseWheelEventQueueClient* client);
~MouseWheelEventQueue();
@@ -92,21 +89,6 @@ class CONTENT_EXPORT MouseWheelEventQueue {
base::circular_deque<std::unique_ptr<QueuedWebMouseWheelEvent>> wheel_queue_;
std::unique_ptr<QueuedWebMouseWheelEvent> event_sent_for_gesture_ack_;
- // True if a non-synthetic GSB needs to be sent before a GSU is sent.
- // 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.
- // This variable is used only when scroll latching is disabled.
- bool needs_scroll_end_when_scroll_latching_disabled_;
-
- // True if the touchpad and wheel scroll latching flag is enabled.
- bool enable_scroll_latching_;
-
- // True if the async wheel events flag is enabled.
- bool enable_async_wheel_events_;
-
// True if the ack for the first wheel event in a scroll sequence is not
// consumed. This lets us to send the rest of the wheel events in the sequence
// as non-blocking.
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 62bfefc9972..b8f0067c4a8 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
@@ -12,13 +12,11 @@
#include "base/location.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/metrics/histogram_tester.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/public/common/content_features.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "ui/events/base_event_utils.h"
@@ -137,43 +135,17 @@ const float kWheelScrollGlobalY = 72;
#define EXPECT_MOUSE_WHEEL(event) \
EXPECT_EQ(WebInputEvent::kMouseWheel, event->GetType());
-enum WheelScrollingMode {
- kWheelScrollingModeNone,
- kWheelScrollLatching,
- kAsyncWheelEvents,
-};
-
} // namespace
-class MouseWheelEventQueueTest
- : public testing::TestWithParam<WheelScrollingMode>,
- public MouseWheelEventQueueClient {
+class MouseWheelEventQueueTest : public testing::Test,
+ public MouseWheelEventQueueClient {
public:
MouseWheelEventQueueTest()
: scoped_task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::UI),
acked_event_count_(0),
last_acked_event_state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {
- scroll_latching_enabled_ = GetParam() != kWheelScrollingModeNone;
- switch (GetParam()) {
- case kWheelScrollingModeNone:
- feature_list_.InitWithFeatures(
- {}, {features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents});
- break;
- case kWheelScrollLatching:
- feature_list_.InitWithFeatures(
- {features::kTouchpadAndWheelScrollLatching},
- {features::kAsyncWheelEvents});
- break;
- case kAsyncWheelEvents:
- feature_list_.InitWithFeatures(
- {features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents},
- {});
- }
-
- queue_.reset(new MouseWheelEventQueue(this, scroll_latching_enabled_));
+ queue_.reset(new MouseWheelEventQueue(this));
}
~MouseWheelEventQueueTest() override {}
@@ -213,8 +185,6 @@ class MouseWheelEventQueueTest
return is_wheel_scroll_in_progress_;
}
- bool scroll_latching_enabled() { return scroll_latching_enabled_; }
-
protected:
size_t queued_event_count() const { return queue_->queued_size(); }
@@ -249,34 +219,7 @@ class MouseWheelEventQueueTest
queue_->ProcessMouseWheelAck(InputEventAckSource::COMPOSITOR_THREAD,
ack_result, ui::LatencyInfo());
}
-
void SendMouseWheel(float x,
- float y,
- float global_x,
- float global_y,
- float dX,
- float dY,
- int modifiers,
- bool high_precision,
- WebInputEvent::RailsMode rails_mode) {
- WebMouseWheelEvent event = SyntheticWebMouseWheelEventBuilder::Build(
- x, y, global_x, global_y, dX, dY, modifiers, high_precision);
- event.rails_mode = rails_mode;
- queue_->QueueEvent(MouseWheelEventWithLatencyInfo(event));
- }
-
- void SendMouseWheel(float x,
- float y,
- float global_x,
- float global_y,
- float dX,
- float dY,
- int modifiers,
- bool high_precision) {
- SendMouseWheel(x, y, global_x, global_y, dX, dY, modifiers, high_precision,
- WebInputEvent::kRailsModeFree);
- }
- void SendMouseWheelWithPhase(float x,
float y,
float global_x,
float global_y,
@@ -294,60 +237,18 @@ class MouseWheelEventQueueTest
event.rails_mode = rails_mode;
queue_->QueueEvent(MouseWheelEventWithLatencyInfo(event));
}
- void SendMouseWheelWithPhase(
- float x,
- float y,
- float global_x,
- float global_y,
- float dX,
- float dY,
- int modifiers,
- bool high_precision,
- blink::WebMouseWheelEvent::Phase phase,
- blink::WebMouseWheelEvent::Phase momentum_phase) {
- SendMouseWheelWithPhase(x, y, global_x, global_y, dX, dY, modifiers,
- high_precision, phase, momentum_phase,
- WebInputEvent::kRailsModeFree);
- }
-
- void SendMouseWheelPossiblyIncludingPhase(
- bool ignore_phase,
- float x,
- float y,
- float global_x,
- float global_y,
- float dX,
- float dY,
- int modifiers,
- bool high_precision,
- blink::WebMouseWheelEvent::Phase phase,
- blink::WebMouseWheelEvent::Phase momentum_phase,
- WebInputEvent::RailsMode rails_mode) {
- if (ignore_phase) {
- SendMouseWheel(x, y, global_x, global_y, dX, dY, modifiers,
- high_precision, rails_mode);
- } else {
- SendMouseWheelWithPhase(x, y, global_x, global_y, dX, dY, modifiers,
- high_precision, phase, momentum_phase,
- rails_mode);
- }
- }
-
- void SendMouseWheelPossiblyIncludingPhase(
- bool ignore_phase,
- float x,
- float y,
- float global_x,
- float global_y,
- float dX,
- float dY,
- int modifiers,
- bool high_precision,
- blink::WebMouseWheelEvent::Phase phase,
- blink::WebMouseWheelEvent::Phase momentum_phase) {
- SendMouseWheelPossiblyIncludingPhase(
- ignore_phase, x, y, global_x, global_y, dX, dY, modifiers,
- high_precision, phase, momentum_phase, WebInputEvent::kRailsModeFree);
+ void SendMouseWheel(float x,
+ float y,
+ float global_x,
+ float global_y,
+ float dX,
+ float dY,
+ int modifiers,
+ bool high_precision,
+ blink::WebMouseWheelEvent::Phase phase,
+ blink::WebMouseWheelEvent::Phase momentum_phase) {
+ SendMouseWheel(x, y, global_x, global_y, dX, dY, modifiers, high_precision,
+ phase, momentum_phase, WebInputEvent::kRailsModeFree);
}
void SendGestureEvent(WebInputEvent::Type type) {
@@ -369,20 +270,20 @@ class MouseWheelEventQueueTest
const WebGestureEvent::ScrollUnits scroll_units =
high_precision ? WebGestureEvent::kPrecisePixels
: WebGestureEvent::kPixels;
- SendMouseWheelPossiblyIncludingPhase(
- !scroll_latching_enabled_, kWheelScrollX, kWheelScrollY,
- kWheelScrollGlobalX, kWheelScrollGlobalY, 1, 1, 0, high_precision,
- WebMouseWheelEvent::kPhaseBegan, WebMouseWheelEvent::kPhaseNone);
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 1, 1, 0, high_precision,
+ WebMouseWheelEvent::kPhaseBegan,
+ WebMouseWheelEvent::kPhaseNone);
EXPECT_EQ(0U, queued_event_count());
EXPECT_TRUE(event_in_flight());
EXPECT_EQ(1U, GetAndResetSentEventCount());
// The second mouse wheel should not be sent since one is already in
// queue.
- SendMouseWheelPossiblyIncludingPhase(
- !scroll_latching_enabled_, kWheelScrollX, kWheelScrollY,
- kWheelScrollGlobalX, kWheelScrollGlobalY, 5, 5, 0, high_precision,
- WebMouseWheelEvent::kPhaseChanged, WebMouseWheelEvent::kPhaseNone);
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 5, 5, 0, high_precision,
+ WebMouseWheelEvent::kPhaseChanged,
+ WebMouseWheelEvent::kPhaseNone);
EXPECT_EQ(1U, queued_event_count());
EXPECT_TRUE(event_in_flight());
EXPECT_EQ(0U, GetAndResetSentEventCount());
@@ -394,20 +295,11 @@ class MouseWheelEventQueueTest
EXPECT_TRUE(event_in_flight());
EXPECT_EQ(WebInputEvent::kMouseWheel, acked_event().GetType());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
- if (scroll_latching_enabled_) {
- EXPECT_EQ(3U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_BEGIN_WITH_PHASE(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
- EXPECT_MOUSE_WHEEL(sent_input_event(2));
- EXPECT_EQ(3U, GetAndResetSentEventCount());
- } else {
- EXPECT_EQ(4U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_BEGIN(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE(sent_gesture_event(1));
- EXPECT_GESTURE_SCROLL_END(sent_gesture_event(2));
- EXPECT_MOUSE_WHEEL(sent_input_event(3));
- EXPECT_EQ(4U, GetAndResetSentEventCount());
- }
+ EXPECT_EQ(3U, all_sent_events().size());
+ EXPECT_GESTURE_SCROLL_BEGIN_WITH_PHASE(sent_gesture_event(0));
+ EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
+ EXPECT_MOUSE_WHEEL(sent_input_event(2));
+ EXPECT_EQ(3U, GetAndResetSentEventCount());
}
void PhaseGestureSendingTest(bool high_precision) {
@@ -415,124 +307,59 @@ class MouseWheelEventQueueTest
high_precision ? WebGestureEvent::kPrecisePixels
: WebGestureEvent::kPixels;
- SendMouseWheelWithPhase(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
- kWheelScrollGlobalY, 1, 1, 0, high_precision,
- WebMouseWheelEvent::kPhaseBegan,
- WebMouseWheelEvent::kPhaseNone);
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 1, 1, 0, high_precision,
+ WebMouseWheelEvent::kPhaseBegan,
+ WebMouseWheelEvent::kPhaseNone);
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendMouseWheelEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- if (scroll_latching_enabled_) {
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_BEGIN_WITH_PHASE(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- } else {
- EXPECT_EQ(3U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_BEGIN_WITH_PHASE(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
- EXPECT_SYNTHETIC_GESTURE_SCROLL_END(sent_gesture_event(2));
- EXPECT_EQ(3U, GetAndResetSentEventCount());
- }
+ EXPECT_EQ(2U, all_sent_events().size());
+ EXPECT_GESTURE_SCROLL_BEGIN_WITH_PHASE(sent_gesture_event(0));
+ EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
+ EXPECT_EQ(2U, GetAndResetSentEventCount());
- SendMouseWheelWithPhase(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
- kWheelScrollGlobalY, 5, 5, 0, high_precision,
- WebMouseWheelEvent::kPhaseChanged,
- WebMouseWheelEvent::kPhaseNone);
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 5, 5, 0, high_precision,
+ WebMouseWheelEvent::kPhaseChanged,
+ WebMouseWheelEvent::kPhaseNone);
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendMouseWheelEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- if (scroll_latching_enabled_) {
- EXPECT_EQ(1U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(0));
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- } else {
- EXPECT_EQ(3U, all_sent_events().size());
- EXPECT_SYNTHETIC_GESTURE_SCROLL_BEGIN(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
- EXPECT_SYNTHETIC_GESTURE_SCROLL_END(sent_gesture_event(2));
- EXPECT_EQ(3U, GetAndResetSentEventCount());
- }
-
- // When wheel scroll latching is enabled no wheel event with phase =
- // |kPhaseEnded| will be sent before a wheel event with momentum_phase =
- // |kPhaseBegan|.
- if (!scroll_latching_enabled_) {
- SendMouseWheelWithPhase(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
- kWheelScrollGlobalY, 0, 0, 0, high_precision,
- WebMouseWheelEvent::kPhaseEnded,
- WebMouseWheelEvent::kPhaseNone);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendMouseWheelEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_SYNTHETIC_GESTURE_SCROLL_BEGIN(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_END_WITH_PHASE(sent_gesture_event(1));
- EXPECT_EQ(2U, GetAndResetSentEventCount());
-
- // Send a double phase end; OSX does it consistently.
- SendMouseWheelWithPhase(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
- kWheelScrollGlobalY, 0, 0, 0, high_precision,
- WebMouseWheelEvent::kPhaseEnded,
- WebMouseWheelEvent::kPhaseNone);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendMouseWheelEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, all_sent_events().size());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- }
+ EXPECT_EQ(1U, all_sent_events().size());
+ EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(0));
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendMouseWheelWithPhase(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
- kWheelScrollGlobalY, 5, 5, 0, high_precision,
- WebMouseWheelEvent::kPhaseNone,
- WebMouseWheelEvent::kPhaseBegan);
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 5, 5, 0, high_precision,
+ WebMouseWheelEvent::kPhaseNone,
+ WebMouseWheelEvent::kPhaseBegan);
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendMouseWheelEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- if (scroll_latching_enabled_) {
- // A fling has started, no ScrollEnd/ScrollBegin is sent.
- EXPECT_EQ(1U, all_sent_events().size());
- EXPECT_INERTIAL_GESTURE_SCROLL_UPDATE(sent_gesture_event(0));
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- } else {
- EXPECT_EQ(3U, all_sent_events().size());
- EXPECT_INERTIAL_GESTURE_SCROLL_BEGIN(sent_gesture_event(0));
- EXPECT_INERTIAL_GESTURE_SCROLL_UPDATE(sent_gesture_event(1));
- EXPECT_SYNTHETIC_INERTIAL_GESTURE_SCROLL_END(sent_gesture_event(2));
- EXPECT_EQ(3U, GetAndResetSentEventCount());
- }
+ // A fling has started, no ScrollEnd/ScrollBegin is sent.
+ EXPECT_EQ(1U, all_sent_events().size());
+ EXPECT_INERTIAL_GESTURE_SCROLL_UPDATE(sent_gesture_event(0));
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendMouseWheelWithPhase(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
- kWheelScrollGlobalY, 5, 5, 0, high_precision,
- WebMouseWheelEvent::kPhaseNone,
- WebMouseWheelEvent::kPhaseChanged);
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 5, 5, 0, high_precision,
+ WebMouseWheelEvent::kPhaseNone,
+ WebMouseWheelEvent::kPhaseChanged);
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendMouseWheelEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- if (scroll_latching_enabled_) {
- EXPECT_EQ(1U, all_sent_events().size());
- EXPECT_INERTIAL_GESTURE_SCROLL_UPDATE(sent_gesture_event(0));
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- } else {
- EXPECT_EQ(3U, all_sent_events().size());
- EXPECT_SYNTHETIC_INERTIAL_GESTURE_SCROLL_BEGIN(sent_gesture_event(0));
- EXPECT_INERTIAL_GESTURE_SCROLL_UPDATE(sent_gesture_event(1));
- EXPECT_SYNTHETIC_INERTIAL_GESTURE_SCROLL_END(sent_gesture_event(2));
- EXPECT_EQ(3U, GetAndResetSentEventCount());
- }
+ EXPECT_EQ(1U, all_sent_events().size());
+ EXPECT_INERTIAL_GESTURE_SCROLL_UPDATE(sent_gesture_event(0));
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendMouseWheelWithPhase(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
- kWheelScrollGlobalY, 0, 0, 0, high_precision,
- WebMouseWheelEvent::kPhaseNone,
- WebMouseWheelEvent::kPhaseEnded);
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 0, 0, 0, high_precision,
+ WebMouseWheelEvent::kPhaseNone,
+ WebMouseWheelEvent::kPhaseEnded);
EXPECT_EQ(1U, GetAndResetSentEventCount());
SendMouseWheelEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- if (scroll_latching_enabled_) {
- // MomentumPhase is ended, the scroll is done, and GSE is sent
- // immediately.
- EXPECT_EQ(1U, all_sent_events().size());
- EXPECT_INERTIAL_GESTURE_SCROLL_END(sent_gesture_event(0));
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- } else {
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_SYNTHETIC_INERTIAL_GESTURE_SCROLL_BEGIN(sent_gesture_event(0));
- EXPECT_INERTIAL_GESTURE_SCROLL_END(sent_gesture_event(1));
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- }
+ // MomentumPhase is ended, the scroll is done, and GSE is sent
+ // immediately.
+ EXPECT_EQ(1U, all_sent_events().size());
+ EXPECT_INERTIAL_GESTURE_SCROLL_END(sent_gesture_event(0));
+ EXPECT_EQ(1U, GetAndResetSentEventCount());
}
base::test::ScopedTaskEnvironment scoped_task_environment_;
@@ -541,28 +368,26 @@ class MouseWheelEventQueueTest
size_t acked_event_count_;
InputEventAckState last_acked_event_state_;
WebMouseWheelEvent last_acked_event_;
- bool scroll_latching_enabled_;
private:
bool is_wheel_scroll_in_progress_ = false;
- base::test::ScopedFeatureList feature_list_;
};
// Tests that mouse wheel events are queued properly.
-TEST_P(MouseWheelEventQueueTest, Basic) {
- SendMouseWheelPossiblyIncludingPhase(
- !scroll_latching_enabled_, kWheelScrollX, kWheelScrollY,
- kWheelScrollGlobalX, kWheelScrollGlobalY, 1, 1, 0, false,
- WebMouseWheelEvent::kPhaseBegan, WebMouseWheelEvent::kPhaseNone);
+TEST_F(MouseWheelEventQueueTest, Basic) {
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 1, 1, 0, false,
+ WebMouseWheelEvent::kPhaseBegan,
+ WebMouseWheelEvent::kPhaseNone);
EXPECT_EQ(0U, queued_event_count());
EXPECT_TRUE(event_in_flight());
EXPECT_EQ(1U, GetAndResetSentEventCount());
// The second mouse wheel should not be sent since one is already in queue.
- SendMouseWheelPossiblyIncludingPhase(
- !scroll_latching_enabled_, kWheelScrollX, kWheelScrollY,
- kWheelScrollGlobalX, kWheelScrollGlobalY, 5, 5, 0, false,
- WebMouseWheelEvent::kPhaseChanged, WebMouseWheelEvent::kPhaseNone);
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 5, 5, 0, false,
+ WebMouseWheelEvent::kPhaseChanged,
+ WebMouseWheelEvent::kPhaseNone);
EXPECT_EQ(1U, queued_event_count());
EXPECT_TRUE(event_in_flight());
EXPECT_EQ(0U, GetAndResetSentEventCount());
@@ -584,29 +409,29 @@ TEST_P(MouseWheelEventQueueTest, Basic) {
EXPECT_EQ(WebInputEvent::kMouseWheel, acked_event().GetType());
}
-TEST_P(MouseWheelEventQueueTest, GestureSending) {
+TEST_F(MouseWheelEventQueueTest, GestureSending) {
GestureSendingTest(false);
}
-TEST_P(MouseWheelEventQueueTest, GestureSendingPrecisePixels) {
+TEST_F(MouseWheelEventQueueTest, GestureSendingPrecisePixels) {
GestureSendingTest(true);
}
-TEST_P(MouseWheelEventQueueTest, GestureSendingWithPhaseInformation) {
+TEST_F(MouseWheelEventQueueTest, GestureSendingWithPhaseInformation) {
PhaseGestureSendingTest(false);
}
-TEST_P(MouseWheelEventQueueTest,
+TEST_F(MouseWheelEventQueueTest,
GestureSendingWithPhaseInformationPrecisePixels) {
PhaseGestureSendingTest(true);
}
-TEST_P(MouseWheelEventQueueTest, GestureSendingInterrupted) {
+TEST_F(MouseWheelEventQueueTest, GestureSendingInterrupted) {
const WebGestureEvent::ScrollUnits scroll_units = WebGestureEvent::kPixels;
- SendMouseWheelPossiblyIncludingPhase(
- !scroll_latching_enabled_, kWheelScrollX, kWheelScrollY,
- kWheelScrollGlobalX, kWheelScrollGlobalY, 1, 1, 0, false,
- WebMouseWheelEvent::kPhaseBegan, WebMouseWheelEvent::kPhaseNone);
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 1, 1, 0, false,
+ WebMouseWheelEvent::kPhaseBegan,
+ WebMouseWheelEvent::kPhaseNone);
EXPECT_EQ(0U, queued_event_count());
EXPECT_TRUE(event_in_flight());
EXPECT_EQ(1U, GetAndResetSentEventCount());
@@ -617,46 +442,32 @@ TEST_P(MouseWheelEventQueueTest, GestureSendingInterrupted) {
EXPECT_FALSE(event_in_flight());
EXPECT_EQ(WebInputEvent::kMouseWheel, acked_event().GetType());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
- if (scroll_latching_enabled_) {
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_BEGIN_WITH_PHASE(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- } else {
- EXPECT_EQ(3U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_BEGIN(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE(sent_gesture_event(1));
- EXPECT_GESTURE_SCROLL_END(sent_gesture_event(2));
- EXPECT_EQ(3U, GetAndResetSentEventCount());
- }
+ EXPECT_EQ(2U, all_sent_events().size());
+ EXPECT_GESTURE_SCROLL_BEGIN_WITH_PHASE(sent_gesture_event(0));
+ EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
+ EXPECT_EQ(2U, GetAndResetSentEventCount());
- // When wheel scroll latching is enabled and a touch based GSB arrives in the
+ // When a touch based GSB arrives in the
// middle of wheel scrolling sequence, a synthetic wheel event with zero
// deltas and phase = |kPhaseEnded| will be sent.
- if (scroll_latching_enabled_) {
- SendMouseWheelWithPhase(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
- kWheelScrollGlobalY, 0, 0, 0, false,
- WebMouseWheelEvent::kPhaseEnded,
- WebMouseWheelEvent::kPhaseNone);
- SendMouseWheelEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- }
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 0, 0, 0, false,
+ WebMouseWheelEvent::kPhaseEnded,
+ WebMouseWheelEvent::kPhaseNone);
+ SendMouseWheelEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
+ EXPECT_EQ(1U, GetAndResetAckedEventCount());
+
// Ensure that a gesture scroll begin terminates the current scroll event.
SendGestureEvent(WebInputEvent::kGestureScrollBegin);
- if (scroll_latching_enabled_) {
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_END_WITH_PHASE(sent_gesture_event(1));
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- } else {
- // ScrollEnd has already been sent.
- EXPECT_EQ(0U, all_sent_events().size());
- }
+ EXPECT_EQ(2U, all_sent_events().size());
+ EXPECT_GESTURE_SCROLL_END_WITH_PHASE(sent_gesture_event(1));
+ EXPECT_EQ(2U, GetAndResetSentEventCount());
- SendMouseWheelPossiblyIncludingPhase(
- !scroll_latching_enabled_, kWheelScrollX, kWheelScrollY,
- kWheelScrollGlobalX, kWheelScrollGlobalY, 1, 1, 0, false,
- WebMouseWheelEvent::kPhaseBegan, WebMouseWheelEvent::kPhaseNone);
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 1, 1, 0, false,
+ WebMouseWheelEvent::kPhaseBegan,
+ WebMouseWheelEvent::kPhaseNone);
EXPECT_EQ(0U, queued_event_count());
EXPECT_TRUE(event_in_flight());
@@ -674,10 +485,10 @@ TEST_P(MouseWheelEventQueueTest, GestureSendingInterrupted) {
SendGestureEvent(WebInputEvent::kGestureScrollEnd);
EXPECT_EQ(0U, all_sent_events().size());
- SendMouseWheelPossiblyIncludingPhase(
- !scroll_latching_enabled_, kWheelScrollX, kWheelScrollY,
- kWheelScrollGlobalX, kWheelScrollGlobalY, 1, 1, 0, false,
- WebMouseWheelEvent::kPhaseBegan, WebMouseWheelEvent::kPhaseNone);
+ SendMouseWheel(kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX,
+ kWheelScrollGlobalY, 1, 1, 0, false,
+ WebMouseWheelEvent::kPhaseBegan,
+ WebMouseWheelEvent::kPhaseNone);
EXPECT_EQ(0U, queued_event_count());
EXPECT_TRUE(event_in_flight());
@@ -689,28 +500,18 @@ TEST_P(MouseWheelEventQueueTest, GestureSendingInterrupted) {
EXPECT_FALSE(event_in_flight());
EXPECT_EQ(WebInputEvent::kMouseWheel, acked_event().GetType());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
- if (scroll_latching_enabled_) {
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_BEGIN_WITH_PHASE(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- } else {
- EXPECT_EQ(3U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_BEGIN(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE(sent_gesture_event(1));
- EXPECT_GESTURE_SCROLL_END(sent_gesture_event(2));
- EXPECT_EQ(3U, GetAndResetSentEventCount());
- }
+ EXPECT_EQ(2U, all_sent_events().size());
+ EXPECT_GESTURE_SCROLL_BEGIN_WITH_PHASE(sent_gesture_event(0));
+ EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
+ EXPECT_EQ(2U, GetAndResetSentEventCount());
}
-TEST_P(MouseWheelEventQueueTest, GestureRailScrolling) {
+TEST_F(MouseWheelEventQueueTest, GestureRailScrolling) {
const WebGestureEvent::ScrollUnits scroll_units = WebGestureEvent::kPixels;
-
- SendMouseWheelPossiblyIncludingPhase(
- !scroll_latching_enabled_, kWheelScrollX, kWheelScrollY,
- kWheelScrollGlobalX, kWheelScrollGlobalY, 1, 1, 0, false,
- WebMouseWheelEvent::kPhaseBegan, WebMouseWheelEvent::kPhaseNone,
- WebInputEvent::kRailsModeHorizontal);
+ SendMouseWheel(
+ kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX, kWheelScrollGlobalY, 1,
+ 1, 0, false, WebMouseWheelEvent::kPhaseBegan,
+ WebMouseWheelEvent::kPhaseNone, WebInputEvent::kRailsModeHorizontal);
EXPECT_EQ(0U, queued_event_count());
EXPECT_TRUE(event_in_flight());
EXPECT_EQ(1U, GetAndResetSentEventCount());
@@ -721,27 +522,17 @@ TEST_P(MouseWheelEventQueueTest, GestureRailScrolling) {
EXPECT_FALSE(event_in_flight());
EXPECT_EQ(WebInputEvent::kMouseWheel, acked_event().GetType());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
- if (scroll_latching_enabled_) {
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_BEGIN_WITH_PHASE(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
- EXPECT_EQ(1U, sent_gesture_event(1)->data.scroll_update.delta_x);
- EXPECT_EQ(0U, sent_gesture_event(1)->data.scroll_update.delta_y);
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- } else {
- EXPECT_EQ(3U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_BEGIN(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE(sent_gesture_event(1));
- EXPECT_GESTURE_SCROLL_END(sent_gesture_event(2));
- EXPECT_EQ(1U, sent_gesture_event(1)->data.scroll_update.delta_x);
- EXPECT_EQ(0U, sent_gesture_event(1)->data.scroll_update.delta_y);
- EXPECT_EQ(3U, GetAndResetSentEventCount());
- }
- SendMouseWheelPossiblyIncludingPhase(
- !scroll_latching_enabled_, kWheelScrollX, kWheelScrollY,
- kWheelScrollGlobalX, kWheelScrollGlobalY, 1, 1, 0, false,
- WebMouseWheelEvent::kPhaseChanged, WebMouseWheelEvent::kPhaseNone,
- WebInputEvent::kRailsModeVertical);
+ EXPECT_EQ(2U, all_sent_events().size());
+ EXPECT_GESTURE_SCROLL_BEGIN_WITH_PHASE(sent_gesture_event(0));
+ EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(1));
+ EXPECT_EQ(1U, sent_gesture_event(1)->data.scroll_update.delta_x);
+ EXPECT_EQ(0U, sent_gesture_event(1)->data.scroll_update.delta_y);
+ EXPECT_EQ(2U, GetAndResetSentEventCount());
+
+ SendMouseWheel(
+ kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX, kWheelScrollGlobalY, 1,
+ 1, 0, false, WebMouseWheelEvent::kPhaseChanged,
+ WebMouseWheelEvent::kPhaseNone, WebInputEvent::kRailsModeVertical);
EXPECT_EQ(0U, queued_event_count());
EXPECT_TRUE(event_in_flight());
@@ -754,32 +545,19 @@ TEST_P(MouseWheelEventQueueTest, GestureRailScrolling) {
EXPECT_EQ(WebInputEvent::kMouseWheel, acked_event().GetType());
EXPECT_EQ(1U, GetAndResetAckedEventCount());
size_t scroll_update_index = 0;
- if (scroll_latching_enabled_) {
- EXPECT_EQ(1U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(0));
- } else {
- EXPECT_EQ(3U, all_sent_events().size());
- EXPECT_GESTURE_SCROLL_BEGIN(sent_gesture_event(0));
- EXPECT_GESTURE_SCROLL_UPDATE(sent_gesture_event(1));
- EXPECT_GESTURE_SCROLL_END(sent_gesture_event(2));
- scroll_update_index = 1;
- }
+ EXPECT_EQ(1U, all_sent_events().size());
+ EXPECT_GESTURE_SCROLL_UPDATE_WITH_PHASE(sent_gesture_event(0));
+
EXPECT_EQ(
0U, sent_gesture_event(scroll_update_index)->data.scroll_update.delta_x);
EXPECT_EQ(
1U, sent_gesture_event(scroll_update_index)->data.scroll_update.delta_y);
- if (scroll_latching_enabled_)
EXPECT_EQ(1U, GetAndResetSentEventCount());
- else
- EXPECT_EQ(3U, GetAndResetSentEventCount());
}
-TEST_P(MouseWheelEventQueueTest, WheelScrollLatching) {
- if (!scroll_latching_enabled_)
- return;
-
+TEST_F(MouseWheelEventQueueTest, WheelScrollLatching) {
const WebGestureEvent::ScrollUnits scroll_units = WebGestureEvent::kPixels;
- SendMouseWheelWithPhase(
+ SendMouseWheel(
kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX, kWheelScrollGlobalY, 1,
1, 0, false, WebMouseWheelEvent::kPhaseBegan,
WebMouseWheelEvent::kPhaseNone, WebInputEvent::kRailsModeVertical);
@@ -800,7 +578,7 @@ TEST_P(MouseWheelEventQueueTest, WheelScrollLatching) {
EXPECT_EQ(1U, sent_gesture_event(1)->data.scroll_update.delta_y);
EXPECT_EQ(2U, GetAndResetSentEventCount());
- SendMouseWheelWithPhase(
+ SendMouseWheel(
kWheelScrollX, kWheelScrollY, kWheelScrollGlobalX, kWheelScrollGlobalY, 1,
1, 0, false, WebMouseWheelEvent::kPhaseChanged,
WebMouseWheelEvent::kPhaseNone, WebInputEvent::kRailsModeVertical);
@@ -823,34 +601,24 @@ TEST_P(MouseWheelEventQueueTest, WheelScrollLatching) {
EXPECT_EQ(1U, GetAndResetSentEventCount());
}
-TEST_P(MouseWheelEventQueueTest, WheelScrollingWasLatchedHistogramCheck) {
+TEST_F(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);
+ SendMouseWheel(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);
+ SendMouseWheel(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,
- kWheelScrollLatching,
- kAsyncWheelEvents));
-
} // namespace content
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 d1daf8e1aa6..a13243f3727 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
@@ -102,9 +102,7 @@ void MouseWheelPhaseHandler::DispatchPendingWheelEndEvent() {
TRACE_EVENT_INSTANT0("input", "MouseWheelPhaseHandler Dispatched",
TRACE_EVENT_SCOPE_THREAD);
- base::Closure task = mouse_wheel_end_dispatch_timer_.user_task();
- mouse_wheel_end_dispatch_timer_.Stop();
- std::move(task).Run();
+ mouse_wheel_end_dispatch_timer_.FireNow();
}
void MouseWheelPhaseHandler::IgnorePendingWheelEndEvent() {
@@ -157,7 +155,6 @@ void MouseWheelPhaseHandler::SendSyntheticWheelEventWithPhaseEnded(
bool should_route_event) {
TRACE_EVENT0("input",
"MouseWheelPhaseHandler::SendSyntheticWheelEventWithPhaseEnded");
- DCHECK(host_view_->wheel_scroll_latching_enabled());
last_mouse_wheel_event_.SetTimeStamp(ui::EventTimeForNow());
last_mouse_wheel_event_.delta_x = 0;
last_mouse_wheel_event_.delta_y = 0;
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 4f7c03d6293..305095fc420 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
@@ -80,6 +80,12 @@ class MouseWheelPhaseHandler {
void GestureEventAck(const blink::WebGestureEvent& event,
InputEventAckState ack_result);
+ // Used to verify the correctness of touchpad_scroll_phase_state_'s value in
+ // testing.
+ TouchpadScrollPhaseState touchpad_scroll_phase_state_for_test() const {
+ return touchpad_scroll_phase_state_;
+ }
+
private:
void SendSyntheticWheelEventWithPhaseEnded(
bool should_route_event);
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 0677a6df8f6..3f23c3a3ed1 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
@@ -310,10 +310,10 @@ class PassthroughTouchEventQueueTest : public testing::Test,
}
static void RunTasksAndWait(base::TimeDelta delay) {
+ base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- delay);
- base::RunLoop().Run();
+ FROM_HERE, run_loop.QuitClosure(), delay);
+ run_loop.Run();
}
int GetUniqueTouchEventID() { return sent_events_ids_.back(); }
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 185919454c6..e94cc9ba251 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
@@ -26,38 +26,18 @@ using blink::WebTouchEvent;
using ui::LatencyInfo;
namespace content {
-namespace {
-
-ukm::SourceId GenerateUkmSourceId() {
- ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
- return ukm_recorder ? ukm_recorder->GetNewSourceID() : ukm::kInvalidSourceId;
-}
-
-} // namespace
RenderWidgetHostLatencyTracker::RenderWidgetHostLatencyTracker(
RenderWidgetHostDelegate* delegate)
- : ukm_source_id_(GenerateUkmSourceId()),
- last_event_id_(0),
- latency_component_id_(0),
- has_seen_first_gesture_scroll_update_(false),
+ : has_seen_first_gesture_scroll_update_(false),
active_multi_finger_gesture_(false),
touch_start_default_prevented_(false),
render_widget_host_delegate_(delegate) {}
RenderWidgetHostLatencyTracker::~RenderWidgetHostLatencyTracker() {}
-void RenderWidgetHostLatencyTracker::Initialize(int routing_id,
- int process_id) {
- DCHECK_EQ(0, last_event_id_);
- DCHECK_EQ(0, latency_component_id_);
- last_event_id_ = static_cast<int64_t>(process_id) << 32;
- latency_component_id_ = routing_id | last_event_id_;
-}
-
void RenderWidgetHostLatencyTracker::ComputeInputLatencyHistograms(
WebInputEvent::Type type,
- int64_t latency_component_id,
const LatencyInfo& latency,
InputEventAckState ack_result) {
// If this event was coalesced into another event, ignore it, as the event it
@@ -72,12 +52,10 @@ void RenderWidgetHostLatencyTracker::ComputeInputLatencyHistograms(
// The event will have gone through OnInputEvent(). So the BEGIN_RWH component
// should always be available here.
- LatencyInfo::LatencyComponent rwh_component;
- bool found_component =
- latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- latency_component_id, &rwh_component);
+ base::TimeTicks rwh_timestamp;
+ bool found_component = latency.FindLatency(
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, &rwh_timestamp);
DCHECK(found_component);
- DCHECK_EQ(rwh_component.event_count, 1u);
bool multi_finger_touch_gesture =
WebInputEvent::IsTouchEventType(type) && active_multi_finger_gesture_;
@@ -98,26 +76,23 @@ void RenderWidgetHostLatencyTracker::ComputeInputLatencyHistograms(
std::string default_action_status =
action_prevented ? "DefaultPrevented" : "DefaultAllowed";
- LatencyInfo::LatencyComponent main_component;
- if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0,
- &main_component)) {
- DCHECK_EQ(main_component.event_count, 1u);
+ base::TimeTicks main_thread_timestamp;
+ if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT,
+ &main_thread_timestamp)) {
if (!multi_finger_touch_gesture) {
UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS(
"Event.Latency.QueueingTime." + event_name + default_action_status,
- rwh_component, main_component);
+ rwh_timestamp, main_thread_timestamp);
}
}
- LatencyInfo::LatencyComponent acked_component;
- if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0,
- &acked_component)) {
- DCHECK_EQ(acked_component.event_count, 1u);
- if (!multi_finger_touch_gesture &&
- main_component.event_time != base::TimeTicks()) {
+ base::TimeTicks rwh_ack_timestamp;
+ if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT,
+ &rwh_ack_timestamp)) {
+ if (!multi_finger_touch_gesture && !main_thread_timestamp.is_null()) {
UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS(
"Event.Latency.BlockingTime." + event_name + default_action_status,
- main_component, acked_component);
+ main_thread_timestamp, rwh_ack_timestamp);
}
}
}
@@ -129,12 +104,6 @@ void RenderWidgetHostLatencyTracker::OnInputEvent(
DCHECK_CURRENTLY_ON(BrowserThread::UI);
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 =
@@ -150,13 +119,12 @@ void RenderWidgetHostLatencyTracker::OnInputEvent(
// 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);
+ bool found_component = latency->FindLatency(
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr);
DCHECK(!found_component);
if (!event.TimeStamp().is_null() &&
- !latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0,
+ !latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
nullptr)) {
base::TimeTicks timestamp_now = base::TimeTicks::Now();
base::TimeTicks timestamp_original = event.TimeStamp();
@@ -170,13 +138,12 @@ void RenderWidgetHostLatencyTracker::OnInputEvent(
latency->AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
- 0,
timestamp_original,
1);
}
latency->AddLatencyNumberWithTraceName(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, latency_component_id_,
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
WebInputEvent::GetName(event.GetType()));
if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
@@ -185,15 +152,14 @@ void RenderWidgetHostLatencyTracker::OnInputEvent(
// Make a copy of the INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT with a
// different name INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT.
// So we can track the latency specifically for scroll update events.
- LatencyInfo::LatencyComponent original_component;
- if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0,
- &original_component)) {
+ base::TimeTicks original_event_timestamp;
+ if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
+ &original_event_timestamp)) {
latency->AddLatencyNumberWithTimestamp(
has_seen_first_gesture_scroll_update_
? ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT
: ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- latency_component_id_, original_component.event_time,
- original_component.event_count);
+ original_event_timestamp, 1);
}
has_seen_first_gesture_scroll_update_ = true;
@@ -207,9 +173,9 @@ void RenderWidgetHostLatencyTracker::OnInputEventAck(
// Latency ends if an event is acked but does not cause render scheduling.
bool rendering_scheduled = latency->FindLatency(
- ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, 0, nullptr);
+ ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, nullptr);
rendering_scheduled |= latency->FindLatency(
- ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, 0, nullptr);
+ ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, nullptr);
if (WebInputEvent::IsTouchEventType(event.GetType())) {
const WebTouchEvent& touch_event =
@@ -223,23 +189,25 @@ void RenderWidgetHostLatencyTracker::OnInputEventAck(
}
}
- latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0);
+ latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT);
// If this event couldn't have caused a gesture event, and it didn't trigger
// 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);
+ // terminate it as well. We also exclude cases where we're against the scroll
+ // extent from scrolling metrics.
+ if (!rendering_scheduled || latency->coalesced() ||
+ (event.GetType() == WebInputEvent::kGestureScrollUpdate &&
+ ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS)) {
+ latency->Terminate();
}
- ComputeInputLatencyHistograms(event.GetType(), latency_component_id_,
- *latency, ack_result);
+ ComputeInputLatencyHistograms(event.GetType(), *latency, ack_result);
}
void RenderWidgetHostLatencyTracker::OnEventStart(ui::LatencyInfo* latency) {
static uint64_t global_trace_id = 0;
latency->set_trace_id(++global_trace_id);
- latency->set_ukm_source_id(ukm_source_id_);
+ latency->set_ukm_source_id(
+ render_widget_host_delegate_->GetUkmSourceIdForLastCommittedSource());
}
} // 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 5f51b9170ab..ab481225e5c 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
@@ -32,7 +32,6 @@ class CONTENT_EXPORT RenderWidgetHostLatencyTracker {
void Initialize(int routing_id, int process_id);
void ComputeInputLatencyHistograms(blink::WebInputEvent::Type type,
- int64_t latency_component_id,
const ui::LatencyInfo& latency,
InputEventAckState ack_result);
@@ -52,18 +51,10 @@ class CONTENT_EXPORT RenderWidgetHostLatencyTracker {
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_; }
-
private:
void OnEventStart(ui::LatencyInfo* latency);
- ukm::SourceId ukm_source_id_;
- int64_t last_event_id_;
- int64_t latency_component_id_;
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_;
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 629d56804fd..b174affcfc1 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
@@ -3,12 +3,14 @@
// found in the LICENSE file.
#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 "base/test/metrics/histogram_tester.h"
#include "components/rappor/public/rappor_utils.h"
#include "components/rappor/test_rappor_service.h"
#include "components/ukm/test_ukm_recorder.h"
#include "components/ukm/ukm_source.h"
+#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/test/test_content_browser_client.h"
@@ -34,23 +36,22 @@ void AddFakeComponentsWithTimeStamp(
ui::LatencyInfo* latency,
base::TimeTicks time_stamp) {
latency->AddLatencyNumberWithTimestamp(ui::INPUT_EVENT_LATENCY_UI_COMPONENT,
- 0, time_stamp, 1);
+ time_stamp, 1);
latency->AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, time_stamp,
- 1);
+ ui::INPUT_EVENT_LATENCY_FRAME_SWAP_COMPONENT, time_stamp, 1);
latency->AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, time_stamp, 1);
+ ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, time_stamp, 1);
latency->AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, 0, time_stamp, 1);
+ ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, time_stamp, 1);
latency->AddLatencyNumberWithTimestamp(
- ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, 0, time_stamp, 1);
+ ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, time_stamp, 1);
}
void AddFakeComponents(const RenderWidgetHostLatencyTracker& tracker,
ui::LatencyInfo* latency) {
latency->AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker.latency_component_id(), base::TimeTicks::Now(), 1);
+ base::TimeTicks::Now(), 1);
AddFakeComponentsWithTimeStamp(tracker, latency, base::TimeTicks::Now());
}
@@ -59,13 +60,13 @@ void AddRenderingScheduledComponent(ui::LatencyInfo* latency,
base::TimeTicks time_stamp) {
if (main) {
latency->AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, 0,
- time_stamp, 1);
+ ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, time_stamp,
+ 1);
} else {
latency->AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, 0,
- time_stamp, 1);
+ ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, time_stamp,
+ 1);
}
}
@@ -91,7 +92,8 @@ class RenderWidgetHostLatencyTrackerTest
ResetHistograms();
}
- void ExpectUkmReported(const char* event_name,
+ void ExpectUkmReported(ukm::SourceId source_id,
+ const char* event_name,
const std::vector<std::string>& metric_names,
size_t expected_count) {
const ukm::TestUkmRecorder* ukm_recoder =
@@ -100,7 +102,7 @@ class RenderWidgetHostLatencyTrackerTest
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_EQ(source_id, entry->source_id);
for (const auto& metric_name : metric_names) {
EXPECT_TRUE(ukm_recoder->EntryHasMetric(entry, metric_name.c_str()));
}
@@ -135,7 +137,6 @@ class RenderWidgetHostLatencyTrackerTest
RenderViewHostImplTestHarness::SetUp();
old_browser_client_ = SetBrowserClientForTesting(&test_browser_client_);
tracker_ = std::make_unique<RenderWidgetHostLatencyTracker>(contents());
- tracker_->Initialize(kTestRoutingId, kTestProcessId);
viz_tracker_.DisableMetricSamplingForTesting();
}
@@ -146,14 +147,12 @@ class RenderWidgetHostLatencyTrackerTest
}
protected:
- DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostLatencyTrackerTest);
- const int kTestRoutingId = 3;
- const int kTestProcessId = 1;
std::unique_ptr<base::HistogramTester> histogram_tester_;
std::unique_ptr<RenderWidgetHostLatencyTracker> tracker_;
ui::LatencyTracker viz_tracker_;
RenderWidgetHostLatencyTrackerTestBrowserClient test_browser_client_;
ContentBrowserClient* old_browser_client_;
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostLatencyTrackerTest);
};
TEST_F(RenderWidgetHostLatencyTrackerTest, TestValidEventTiming) {
@@ -164,32 +163,31 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestValidEventTiming) {
latency_info.set_source_event_type(ui::SourceEventType::WHEEL);
latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
now + base::TimeDelta::FromMilliseconds(60), 1);
latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT,
now + base::TimeDelta::FromMilliseconds(50), 1);
latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT,
now + base::TimeDelta::FromMilliseconds(40), 1);
latency_info.AddLatencyNumberWithTimestamp(
- ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, 0,
+ ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT,
now + base::TimeDelta::FromMilliseconds(30), 1);
latency_info.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(),
now + base::TimeDelta::FromMilliseconds(20), 1);
latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0,
+ ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT,
now + base::TimeDelta::FromMilliseconds(10), 1);
latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, now, 1);
+ ui::INPUT_EVENT_LATENCY_FRAME_SWAP_COMPONENT, now, 1);
viz_tracker()->OnGpuSwapBuffersCompleted(latency_info);
@@ -219,6 +217,9 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToFirstScrollHistograms) {
const GURL url(kUrl);
size_t total_ukm_entry_count = 0;
contents()->NavigateAndCommit(url);
+ ukm::SourceId source_id = static_cast<WebContentsImpl*>(contents())
+ ->GetUkmSourceIdForLastCommittedSource();
+ EXPECT_NE(ukm::kInvalidSourceId, source_id);
for (bool rendering_on_main : {false, true}) {
ResetHistograms();
{
@@ -228,16 +229,15 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToFirstScrollHistograms) {
wheel.SetTimeStamp(now);
ui::LatencyInfo wheel_latency(ui::SourceEventType::WHEEL);
wheel_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker()->latency_component_id(), now, 1);
+ ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, now,
+ 1);
AddFakeComponentsWithTimeStamp(*tracker(), &wheel_latency, now);
AddRenderingScheduledComponent(&wheel_latency, rendering_on_main, now);
tracker()->OnInputEvent(wheel, &wheel_latency);
EXPECT_TRUE(wheel_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
EXPECT_TRUE(wheel_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr));
tracker()->OnInputEventAck(wheel, &wheel_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
viz_tracker()->OnGpuSwapBuffersCompleted(wheel_latency);
@@ -245,7 +245,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToFirstScrollHistograms) {
// UKM metrics.
total_ukm_entry_count++;
ExpectUkmReported(
- "Event.ScrollBegin.Wheel",
+ source_id, "Event.ScrollBegin.Wheel",
{"TimeToScrollUpdateSwapBegin", "TimeToHandled", "IsMainThread"},
total_ukm_entry_count);
@@ -331,6 +331,9 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToScrollHistograms) {
const GURL url(kUrl);
size_t total_ukm_entry_count = 0;
contents()->NavigateAndCommit(url);
+ ukm::SourceId source_id = static_cast<WebContentsImpl*>(contents())
+ ->GetUkmSourceIdForLastCommittedSource();
+ EXPECT_NE(ukm::kInvalidSourceId, source_id);
for (bool rendering_on_main : {false, true}) {
ResetHistograms();
{
@@ -340,16 +343,14 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToScrollHistograms) {
wheel.SetTimeStamp(now);
ui::LatencyInfo wheel_latency(ui::SourceEventType::WHEEL);
wheel_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker()->latency_component_id(), now, 1);
+ ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, now, 1);
AddFakeComponentsWithTimeStamp(*tracker(), &wheel_latency, now);
AddRenderingScheduledComponent(&wheel_latency, rendering_on_main, now);
tracker()->OnInputEvent(wheel, &wheel_latency);
EXPECT_TRUE(wheel_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
EXPECT_TRUE(wheel_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr));
tracker()->OnInputEventAck(wheel, &wheel_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
viz_tracker()->OnGpuSwapBuffersCompleted(wheel_latency);
@@ -357,7 +358,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestWheelToScrollHistograms) {
// UKM metrics.
total_ukm_entry_count++;
ExpectUkmReported(
- "Event.ScrollUpdate.Wheel",
+ source_id, "Event.ScrollUpdate.Wheel",
{"TimeToScrollUpdateSwapBegin", "TimeToHandled", "IsMainThread"},
total_ukm_entry_count);
@@ -451,17 +452,13 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestInertialToScrollHistograms) {
base::TimeTicks now = base::TimeTicks::Now();
scroll.SetTimeStamp(now);
ui::LatencyInfo scroll_latency(ui::SourceEventType::INERTIAL);
- scroll_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker()->latency_component_id(), now, 1);
AddFakeComponentsWithTimeStamp(*tracker(), &scroll_latency, now);
AddRenderingScheduledComponent(&scroll_latency, rendering_on_main, now);
tracker()->OnInputEvent(scroll, &scroll_latency);
EXPECT_TRUE(scroll_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
EXPECT_TRUE(scroll_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr));
tracker()->OnInputEventAck(scroll, &scroll_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
viz_tracker()->OnGpuSwapBuffersCompleted(scroll_latency);
@@ -503,6 +500,9 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToFirstScrollHistograms) {
const GURL url(kUrl);
contents()->NavigateAndCommit(url);
size_t total_ukm_entry_count = 0;
+ ukm::SourceId source_id = static_cast<WebContentsImpl*>(contents())
+ ->GetUkmSourceIdForLastCommittedSource();
+ EXPECT_NE(ukm::kInvalidSourceId, source_id);
for (bool rendering_on_main : {false, true}) {
ResetHistograms();
{
@@ -511,17 +511,13 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToFirstScrollHistograms) {
base::TimeTicks now = base::TimeTicks::Now();
scroll.SetTimeStamp(now);
ui::LatencyInfo scroll_latency;
- scroll_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker()->latency_component_id(), now, 1);
AddFakeComponentsWithTimeStamp(*tracker(), &scroll_latency, now);
AddRenderingScheduledComponent(&scroll_latency, rendering_on_main, now);
tracker()->OnInputEvent(scroll, &scroll_latency);
EXPECT_TRUE(scroll_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
EXPECT_TRUE(scroll_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr));
tracker()->OnInputEventAck(scroll, &scroll_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
}
@@ -533,16 +529,15 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToFirstScrollHistograms) {
ui::LatencyInfo touch_latency(ui::SourceEventType::TOUCH);
base::TimeTicks now = base::TimeTicks::Now();
touch_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker()->latency_component_id(), now, 1);
+ ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, now,
+ 1);
AddFakeComponentsWithTimeStamp(*tracker(), &touch_latency, now);
AddRenderingScheduledComponent(&touch_latency, rendering_on_main, now);
tracker()->OnInputEvent(touch, &touch_latency);
EXPECT_TRUE(touch_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
EXPECT_TRUE(touch_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr));
tracker()->OnInputEventAck(touch, &touch_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
viz_tracker()->OnGpuSwapBuffersCompleted(touch_latency);
@@ -551,7 +546,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToFirstScrollHistograms) {
// UKM metrics.
total_ukm_entry_count++;
ExpectUkmReported(
- "Event.ScrollBegin.Touch",
+ source_id, "Event.ScrollBegin.Touch",
{"TimeToScrollUpdateSwapBegin", "TimeToHandled", "IsMainThread"},
total_ukm_entry_count);
@@ -617,6 +612,9 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToScrollHistograms) {
const GURL url(kUrl);
contents()->NavigateAndCommit(url);
size_t total_ukm_entry_count = 0;
+ ukm::SourceId source_id = static_cast<WebContentsImpl*>(contents())
+ ->GetUkmSourceIdForLastCommittedSource();
+ EXPECT_NE(ukm::kInvalidSourceId, source_id);
for (bool rendering_on_main : {false, true}) {
ResetHistograms();
{
@@ -625,17 +623,13 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToScrollHistograms) {
base::TimeTicks now = base::TimeTicks::Now();
scroll.SetTimeStamp(now);
ui::LatencyInfo scroll_latency;
- scroll_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker()->latency_component_id(), now, 1);
AddFakeComponentsWithTimeStamp(*tracker(), &scroll_latency, now);
AddRenderingScheduledComponent(&scroll_latency, rendering_on_main, now);
tracker()->OnInputEvent(scroll, &scroll_latency);
EXPECT_TRUE(scroll_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
EXPECT_TRUE(scroll_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr));
tracker()->OnInputEventAck(scroll, &scroll_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
}
@@ -647,16 +641,14 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToScrollHistograms) {
ui::LatencyInfo touch_latency(ui::SourceEventType::TOUCH);
base::TimeTicks now = base::TimeTicks::Now();
touch_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker()->latency_component_id(), now, 1);
+ ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, now, 1);
AddFakeComponentsWithTimeStamp(*tracker(), &touch_latency, now);
AddRenderingScheduledComponent(&touch_latency, rendering_on_main, now);
tracker()->OnInputEvent(touch, &touch_latency);
EXPECT_TRUE(touch_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
EXPECT_TRUE(touch_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr));
tracker()->OnInputEventAck(touch, &touch_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
viz_tracker()->OnGpuSwapBuffersCompleted(touch_latency);
@@ -665,7 +657,7 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TestTouchToScrollHistograms) {
// UKM metrics.
total_ukm_entry_count++;
ExpectUkmReported(
- "Event.ScrollUpdate.Touch",
+ source_id, "Event.ScrollUpdate.Touch",
{"TimeToScrollUpdateSwapBegin", "TimeToHandled", "IsMainThread"},
total_ukm_entry_count);
@@ -737,8 +729,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest,
tracker()->OnInputEvent(scroll, &scroll_latency);
tracker()->OnInputEventAck(scroll, &scroll_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_TRUE(scroll_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_TERMINATED_NO_SWAP_COMPONENT, 0, nullptr));
EXPECT_TRUE(scroll_latency.terminated());
}
@@ -751,8 +741,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest,
tracker()->OnInputEvent(wheel, &wheel_latency);
tracker()->OnInputEventAck(wheel, &wheel_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_TRUE(wheel_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_TERMINATED_NO_SWAP_COMPONENT, 0, nullptr));
EXPECT_TRUE(wheel_latency.terminated());
}
@@ -765,8 +753,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest,
tracker()->OnInputEvent(touch, &touch_latency);
tracker()->OnInputEventAck(touch, &touch_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_TRUE(touch_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_TERMINATED_NO_SWAP_COMPONENT, 0, nullptr));
EXPECT_TRUE(touch_latency.terminated());
}
@@ -778,8 +764,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest,
tracker()->OnInputEvent(mouse_move, &mouse_latency);
tracker()->OnInputEventAck(mouse_move, &mouse_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_TRUE(mouse_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_TERMINATED_NO_SWAP_COMPONENT, 0, nullptr));
EXPECT_TRUE(mouse_latency.terminated());
}
@@ -792,8 +776,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest,
tracker()->OnInputEvent(key_event, &key_latency);
tracker()->OnInputEventAck(key_event, &key_latency,
INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_TRUE(key_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_TERMINATED_NO_SWAP_COMPONENT, 0, nullptr));
EXPECT_TRUE(key_latency.terminated());
}
@@ -812,16 +794,38 @@ TEST_F(RenderWidgetHostLatencyTrackerTest,
EXPECT_TRUE(HistogramSizeEq("Event.Latency.ScrollUpdate.GpuSwap", 0));
}
+TEST_F(RenderWidgetHostLatencyTrackerTest, LatencyTerminatedOnAckIfGSUIgnored) {
+ for (blink::WebGestureDevice source_device :
+ {blink::kWebGestureDeviceTouchscreen,
+ blink::kWebGestureDeviceTouchpad}) {
+ for (bool rendering_on_main : {false, true}) {
+ auto scroll = SyntheticWebGestureEventBuilder::BuildScrollUpdate(
+ 5.f, -5.f, 0, source_device);
+ base::TimeTicks now = base::TimeTicks::Now();
+ scroll.SetTimeStamp(now);
+ ui::LatencyInfo scroll_latency;
+ scroll_latency.set_source_event_type(
+ source_device == blink::kWebGestureDeviceTouchscreen
+ ? ui::SourceEventType::TOUCH
+ : ui::SourceEventType::WHEEL);
+ AddFakeComponentsWithTimeStamp(*tracker(), &scroll_latency, now);
+ AddRenderingScheduledComponent(&scroll_latency, rendering_on_main, now);
+ tracker()->OnInputEvent(scroll, &scroll_latency);
+ tracker()->OnInputEventAck(scroll, &scroll_latency,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ EXPECT_TRUE(scroll_latency.terminated());
+ }
+ }
+}
+
TEST_F(RenderWidgetHostLatencyTrackerTest, ScrollLatency) {
auto scroll_begin = SyntheticWebGestureEventBuilder::BuildScrollBegin(
5, -5, blink::kWebGestureDeviceTouchscreen);
ui::LatencyInfo scroll_latency;
- scroll_latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
- 0);
+ scroll_latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT);
tracker()->OnInputEvent(scroll_begin, &scroll_latency);
- EXPECT_TRUE(
- scroll_latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ EXPECT_TRUE(scroll_latency.FindLatency(
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
EXPECT_EQ(2U, scroll_latency.latency_components().size());
// The first GestureScrollUpdate should be provided with
@@ -829,18 +833,14 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, ScrollLatency) {
auto first_scroll_update = SyntheticWebGestureEventBuilder::BuildScrollUpdate(
5.f, -5.f, 0, blink::kWebGestureDeviceTouchscreen);
scroll_latency = ui::LatencyInfo();
- scroll_latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
- 0);
+ scroll_latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT);
tracker()->OnInputEvent(first_scroll_update, &scroll_latency);
- EXPECT_TRUE(
- scroll_latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
EXPECT_TRUE(scroll_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
+ EXPECT_TRUE(scroll_latency.FindLatency(
+ ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, nullptr));
EXPECT_FALSE(scroll_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, nullptr));
EXPECT_EQ(3U, scroll_latency.latency_components().size());
// Subsequent GestureScrollUpdates should be provided with
@@ -848,18 +848,14 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, ScrollLatency) {
auto scroll_update = SyntheticWebGestureEventBuilder::BuildScrollUpdate(
-5.f, 5.f, 0, blink::kWebGestureDeviceTouchscreen);
scroll_latency = ui::LatencyInfo();
- scroll_latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
- 0);
+ scroll_latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT);
tracker()->OnInputEvent(scroll_update, &scroll_latency);
- EXPECT_TRUE(
- scroll_latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ EXPECT_TRUE(scroll_latency.FindLatency(
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
EXPECT_FALSE(scroll_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, nullptr));
EXPECT_TRUE(scroll_latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, nullptr));
EXPECT_EQ(3U, scroll_latency.latency_components().size());
}
@@ -885,28 +881,26 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TouchBlockingAndQueueingTime) {
fake_latency.set_source_event_type(ui::SourceEventType::TOUCH);
fake_latency.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(),
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchstart_timestamps_ms[0]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchstart_timestamps_ms[1]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchstart_timestamps_ms[2]),
1);
// Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck
// overwriting components.
- tracker()->ComputeInputLatencyHistograms(
- event.GetType(), tracker()->latency_component_id(), fake_latency,
- blocking);
+ tracker()->ComputeInputLatencyHistograms(event.GetType(), fake_latency,
+ blocking);
tracker()->OnInputEventAck(event, &latency,
blocking);
@@ -920,10 +914,9 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TouchBlockingAndQueueingTime) {
tracker()->OnInputEvent(event, &latency);
EXPECT_TRUE(latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
- EXPECT_TRUE(
- latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr));
+ EXPECT_TRUE(latency.FindLatency(
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
EXPECT_EQ(2U, latency.latency_components().size());
@@ -932,28 +925,26 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TouchBlockingAndQueueingTime) {
fake_latency.set_source_event_type(ui::SourceEventType::TOUCH);
fake_latency.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(),
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchmove_timestamps_ms[0]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchmove_timestamps_ms[1]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchmove_timestamps_ms[2]),
1);
// Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck
// overwriting components.
- tracker()->ComputeInputLatencyHistograms(
- event.GetType(), tracker()->latency_component_id(), fake_latency,
- blocking);
+ tracker()->ComputeInputLatencyHistograms(event.GetType(), fake_latency,
+ blocking);
}
{
@@ -964,10 +955,9 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TouchBlockingAndQueueingTime) {
tracker()->OnInputEvent(event, &latency);
EXPECT_TRUE(latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, nullptr));
- EXPECT_TRUE(
- latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(), nullptr));
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr));
+ EXPECT_TRUE(latency.FindLatency(
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
EXPECT_EQ(2U, latency.latency_components().size());
@@ -976,28 +966,26 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, TouchBlockingAndQueueingTime) {
fake_latency.set_source_event_type(ui::SourceEventType::TOUCH);
fake_latency.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(),
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchend_timestamps_ms[0]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchend_timestamps_ms[1]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchend_timestamps_ms[2]),
1);
// Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck
// overwriting components.
- tracker()->ComputeInputLatencyHistograms(
- event.GetType(), tracker()->latency_component_id(), fake_latency,
- blocking);
+ tracker()->ComputeInputLatencyHistograms(event.GetType(), fake_latency,
+ blocking);
}
}
@@ -1079,28 +1067,26 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, KeyBlockingAndQueueingTime) {
fake_latency.set_source_event_type(ui::SourceEventType::KEY_PRESS);
fake_latency.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(),
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(event_timestamps_ms[0]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(event_timestamps_ms[1]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(event_timestamps_ms[2]),
1);
// Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck
// overwriting components.
- tracker()->ComputeInputLatencyHistograms(
- event.GetType(), tracker()->latency_component_id(), fake_latency,
- blocking);
+ tracker()->ComputeInputLatencyHistograms(event.GetType(), fake_latency,
+ blocking);
tracker()->OnInputEventAck(event, &latency_info, blocking);
}
@@ -1132,26 +1118,25 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, KeyEndToEndLatency) {
latency_info.set_trace_id(kTraceEventId);
latency_info.set_source_event_type(ui::SourceEventType::KEY_PRESS);
latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMicroseconds(event_timestamps_microseconds[0]),
1);
latency_info.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(),
base::TimeTicks() +
base::TimeDelta::FromMicroseconds(event_timestamps_microseconds[0]),
1);
latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0,
+ ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMicroseconds(event_timestamps_microseconds[1]),
1);
latency_info.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_FRAME_SWAP_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMicroseconds(event_timestamps_microseconds[1]),
1);
@@ -1192,19 +1177,18 @@ TEST_F(RenderWidgetHostLatencyTrackerTest,
fake_latency.set_trace_id(kTraceEventId);
fake_latency.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(),
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchstart_timestamps_ms[0]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchstart_timestamps_ms[1]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT,
base::TimeTicks() +
base::TimeDelta::FromMilliseconds(touchstart_timestamps_ms[2]),
1);
@@ -1212,7 +1196,6 @@ TEST_F(RenderWidgetHostLatencyTrackerTest,
// Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck
// overwriting components.
tracker()->ComputeInputLatencyHistograms(event.GetType(),
- tracker()->latency_component_id(),
fake_latency, ack_state);
tracker()->OnInputEventAck(event, &latency, ack_state);
@@ -1263,24 +1246,22 @@ TEST_F(RenderWidgetHostLatencyTrackerTest, WheelDuringMultiFingerTouch) {
fake_latency.set_source_event_type(ui::SourceEventType::TOUCH);
fake_latency.AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
- tracker()->latency_component_id(),
base::TimeTicks() + base::TimeDelta::FromMilliseconds(timestamps_ms[0]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT,
base::TimeTicks() + base::TimeDelta::FromMilliseconds(timestamps_ms[1]),
1);
fake_latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0,
+ ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT,
base::TimeTicks() + base::TimeDelta::FromMilliseconds(timestamps_ms[2]),
1);
// Call ComputeInputLatencyHistograms directly to avoid OnInputEventAck
// overwriting components.
tracker()->ComputeInputLatencyHistograms(wheel_event.GetType(),
- tracker()->latency_component_id(),
fake_latency, ack_state);
tracker()->OnInputEventAck(wheel_event, &latency, ack_state);
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 156ca38da6e..2d8e33bd72a 100644
--- a/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/scroll_latency_browsertest.cc
@@ -7,7 +7,7 @@
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#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"
@@ -30,7 +30,7 @@ const char kDataURL[] =
"<!DOCTYPE html>"
"<html>"
"<head>"
- "<title>Mouse wheel latency histograms reported.</title>"
+ "<title>Scroll latency histograms browsertests.</title>"
"<script src=\"../../resources/testharness.js\"></script>"
"<script src=\"../../resources/testharnessreport.js\"></script>"
"<style>"
@@ -40,7 +40,20 @@ const char kDataURL[] =
"</style>"
"</head>"
"<body>"
+ "<div id='spinner'>Spinning</div>"
"</body>"
+ "<script>"
+ "var degree = 0;"
+ "function spin() {"
+ "degree = degree + 3;"
+ "if (degree >= 360)"
+ "degree -= 360;"
+ "document.getElementById('spinner').style['transform'] = "
+ "'rotate(' + degree + 'deg)';"
+ "requestAnimationFrame(spin);"
+ "}"
+ "spin();"
+ "</script>"
"</html>";
} // namespace
@@ -73,6 +86,11 @@ class ScrollLatencyBrowserTest : public ContentBrowserTest {
frame_observer_->Wait();
}
+ void OnSyntheticGestureCompleted(SyntheticGesture::Result result) {
+ EXPECT_EQ(SyntheticGesture::GESTURE_FINISHED, result);
+ run_loop_->Quit();
+ }
+
protected:
void LoadURL() {
const GURL data_url(kDataURL);
@@ -109,9 +127,20 @@ class ScrollLatencyBrowserTest : public ContentBrowserTest {
GetWidgetHost()->ForwardGestureEvent(event2);
}
+ // Returns true if the given histogram has recorded the expected number of
+ // samples.
+ bool VerifyRecordedSamplesForHistogram(
+ const size_t num_samples,
+ const std::string& histogram_name) const {
+ return num_samples ==
+ histogram_tester_.GetAllSamples(histogram_name).size();
+ }
+
+ std::unique_ptr<base::RunLoop> run_loop_;
+
private:
+ base::HistogramTester histogram_tester_;
base::MessageLoop loop_;
- base::RunLoop runner_;
std::unique_ptr<MainThreadFrameObserver> frame_observer_;
DISALLOW_COPY_AND_ASSIGN(ScrollLatencyBrowserTest);
@@ -122,20 +151,63 @@ class ScrollLatencyBrowserTest : public ContentBrowserTest {
IN_PROC_BROWSER_TEST_F(ScrollLatencyBrowserTest, SmoothWheelScroll) {
LoadURL();
- base::HistogramTester histogram_tester;
DoSmoothWheelScroll(gfx::Vector2d(0, 100));
-
- size_t num_samples = 0;
-
- while (num_samples == 0) {
- FetchHistogramsFromChildProcesses();
- num_samples =
- histogram_tester
- .GetAllSamples(
- "Event.Latency.ScrollBegin.Wheel.TimeToScrollUpdateSwapBegin2")
- .size();
+ while (!VerifyRecordedSamplesForHistogram(
+ 1, "Event.Latency.ScrollBegin.Wheel.TimeToScrollUpdateSwapBegin2")) {
GiveItSomeTime();
+ FetchHistogramsFromChildProcesses();
}
}
+// Do an upward wheel scroll, and verify that no scroll metrics is recorded when
+// the scroll event is ignored.
+IN_PROC_BROWSER_TEST_F(ScrollLatencyBrowserTest,
+ ScrollLatencyNotRecordedIfGSUIgnored) {
+ LoadURL();
+ auto scroll_update_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kGestureScrollUpdate);
+
+ // Try to scroll upward, the GSU(s) will get ignored since the scroller is at
+ // its extent.
+ SyntheticSmoothScrollGestureParams params;
+ params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params.anchor = gfx::PointF(10, 10);
+ params.distances.push_back(gfx::Vector2d(0, 60));
+
+ run_loop_ = std::make_unique<base::RunLoop>();
+
+ std::unique_ptr<SyntheticSmoothScrollGesture> gesture(
+ new SyntheticSmoothScrollGesture(params));
+ GetWidgetHost()->QueueSyntheticGesture(
+ std::move(gesture),
+ base::BindOnce(&ScrollLatencyBrowserTest::OnSyntheticGestureCompleted,
+ base::Unretained(this)));
+
+ // Runs until we get the OnSyntheticGestureCompleted callback and verify that
+ // the first GSU event is ignored.
+ run_loop_->Run();
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS,
+ scroll_update_watcher->GetAckStateWaitIfNecessary());
+
+ // Wait for one frame and then verify that the scroll metrics are not
+ // recorded.
+ std::unique_ptr<RenderFrameSubmissionObserver> frame_observer =
+ std::make_unique<RenderFrameSubmissionObserver>(
+ GetWidgetHost()->render_frame_metadata_provider());
+ frame_observer->WaitForAnyFrameSubmission();
+ FetchHistogramsFromChildProcesses();
+ EXPECT_TRUE(VerifyRecordedSamplesForHistogram(
+ 0, "Event.Latency.ScrollBegin.Touch.BrowserNotifiedToBeforeGpuSwap2"));
+ EXPECT_TRUE(VerifyRecordedSamplesForHistogram(
+ 0, "Event.Latency.ScrollBegin.Touch.GpuSwap2"));
+ EXPECT_TRUE(VerifyRecordedSamplesForHistogram(
+ 0, "Event.Latency.ScrollBegin.Touch.HandledToRendererSwap2_Impl"));
+ EXPECT_TRUE(VerifyRecordedSamplesForHistogram(
+ 0, "Event.Latency.ScrollBegin.Touch.RendererSwapToBrowserNotified2"));
+ EXPECT_TRUE(VerifyRecordedSamplesForHistogram(
+ 0, "Event.Latency.ScrollBegin.Touch.TimeToHandled2_Impl"));
+ EXPECT_TRUE(VerifyRecordedSamplesForHistogram(
+ 0, "Event.Latency.ScrollBegin.Touch.TimeToScrollUpdateSwapBegin2"));
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/stylus_text_selector.cc b/chromium/content/browser/renderer_host/input/stylus_text_selector.cc
index 89660b8b72a..cc4e7ebd16f 100644
--- a/chromium/content/browser/renderer_host/input/stylus_text_selector.cc
+++ b/chromium/content/browser/renderer_host/input/stylus_text_selector.cc
@@ -103,7 +103,7 @@ bool StylusTextSelector::OnTouchEvent(const MotionEvent& event) {
if (!gesture_detector_)
gesture_detector_ = CreateGestureDetector(this);
- gesture_detector_->OnTouchEvent(event);
+ gesture_detector_->OnTouchEvent(event, false /* should_process_double_tap */);
// Always return true, even if |gesture_detector_| technically doesn't
// consume the event. This prevents forwarding of a partial touch stream.
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 33c478a33f8..63a710082da 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
@@ -96,6 +96,22 @@ WebInputEvent::Type ToWebMouseEventType(
return WebInputEvent::kUndefined;
}
+WebInputEvent::Type WebTouchPointStateToEventType(
+ blink::WebTouchPoint::State state) {
+ switch (state) {
+ case blink::WebTouchPoint::kStateReleased:
+ return WebInputEvent::kTouchEnd;
+ case blink::WebTouchPoint::kStatePressed:
+ return WebInputEvent::kTouchStart;
+ case blink::WebTouchPoint::kStateMoved:
+ return WebInputEvent::kTouchMove;
+ case blink::WebTouchPoint::kStateCancelled:
+ return WebInputEvent::kTouchCancel;
+ default:
+ return WebInputEvent::kUndefined;
+ }
+}
+
class MockSyntheticGesture : public SyntheticGesture {
public:
MockSyntheticGesture(bool* finished, int num_steps)
@@ -541,11 +557,13 @@ class MockSyntheticPointerTouchActionTarget
const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event);
type_ = touch_event.GetType();
for (size_t i = 0; i < WebTouchEvent::kTouchesLengthCap; ++i) {
+ if (WebTouchPointStateToEventType(touch_event.touches[i].state) != type_)
+ continue;
+
indexes_[i] = touch_event.touches[i].id;
positions_[i] = gfx::PointF(touch_event.touches[i].PositionInWidget());
states_[i] = touch_event.touches[i].state;
}
- touch_length_ = touch_event.touches_length;
num_actions_dispatched_++;
}
@@ -581,16 +599,12 @@ class MockSyntheticPointerTouchActionTarget
testing::AssertionResult SyntheticTouchActionListDispatchedCorrectly(
const std::vector<SyntheticPointerActionParams>& params_list) {
- if (touch_length_ != params_list.size()) {
- return testing::AssertionFailure() << "Touch point length was "
- << touch_length_ << ", expected "
- << params_list.size() << ".";
- }
-
testing::AssertionResult result = testing::AssertionSuccess();
for (size_t i = 0; i < params_list.size(); ++i) {
- result = SyntheticTouchActionDispatchedCorrectly(params_list[i],
- params_list[i].index());
+ if (params_list[i].pointer_action_type() !=
+ SyntheticPointerActionParams::PointerActionType::IDLE)
+ result = SyntheticTouchActionDispatchedCorrectly(
+ params_list[i], params_list[i].index());
if (result == testing::AssertionFailure())
return result;
}
@@ -599,7 +613,6 @@ class MockSyntheticPointerTouchActionTarget
private:
gfx::PointF positions_[kTouchPointersLength];
- unsigned touch_length_;
int indexes_[kTouchPointersLength];
WebTouchPoint::State states_[kTouchPointersLength];
};
@@ -1655,7 +1668,7 @@ TEST_F(SyntheticGestureControllerTest, PointerTouchAction) {
static_cast<MockSyntheticPointerTouchActionTarget*>(target_);
EXPECT_EQ(1, num_success_);
EXPECT_EQ(0, num_failure_);
- EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 1);
+ EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 2);
EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly(
param_list));
@@ -1676,7 +1689,7 @@ TEST_F(SyntheticGestureControllerTest, PointerTouchAction) {
EXPECT_EQ(2, num_success_);
EXPECT_EQ(0, num_failure_);
- EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 2);
+ EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 4);
EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly(
param_list));
@@ -1693,7 +1706,7 @@ TEST_F(SyntheticGestureControllerTest, PointerTouchAction) {
EXPECT_EQ(3, num_success_);
EXPECT_EQ(0, num_failure_);
- EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 3);
+ EXPECT_EQ(pointer_touch_target->num_actions_dispatched(), 5);
EXPECT_TRUE(pointer_touch_target->SyntheticTouchActionListDispatchedCorrectly(
param_list));
}
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 56c9d367e7e..c238c21add2 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
@@ -49,7 +49,7 @@ void SyntheticGestureTargetBase::DispatchInputEventToPlatform(
"type", WebInputEvent::GetName(event.GetType()));
ui::LatencyInfo latency_info;
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT);
if (WebInputEvent::IsTouchEventType(event.GetType())) {
const WebTouchEvent& web_touch =
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc b/chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc
index 38de025910c..bc0526b5fee 100644
--- a/chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc
+++ b/chromium/content/browser/renderer_host/input/synthetic_pointer_action.cc
@@ -79,8 +79,9 @@ SyntheticPointerAction::ForwardTouchOrMouseInputEvents(
case SyntheticPointerActionParams::PointerActionType::NOT_INITIALIZED:
return INVALID;
}
+ synthetic_pointer_driver_->DispatchEvent(target, timestamp);
}
- synthetic_pointer_driver_->DispatchEvent(target, timestamp);
+
num_actions_dispatched_++;
if (num_actions_dispatched_ == params_.params.size())
return DONE;
diff --git a/chromium/content/browser/renderer_host/input/synthetic_pointer_action_unittest.cc b/chromium/content/browser/renderer_host/input/synthetic_pointer_action_unittest.cc
index 0c681c68c67..c4d45f9d825 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
@@ -60,6 +60,22 @@ WebInputEvent::Type ToWebMouseEventType(
return WebInputEvent::kUndefined;
}
+WebInputEvent::Type WebTouchPointStateToEventType(
+ blink::WebTouchPoint::State state) {
+ switch (state) {
+ case blink::WebTouchPoint::kStateReleased:
+ return WebInputEvent::kTouchEnd;
+ case blink::WebTouchPoint::kStatePressed:
+ return WebInputEvent::kTouchStart;
+ case blink::WebTouchPoint::kStateMoved:
+ return WebInputEvent::kTouchMove;
+ case blink::WebTouchPoint::kStateCancelled:
+ return WebInputEvent::kTouchCancel;
+ default:
+ return WebInputEvent::kUndefined;
+ }
+}
+
class MockSyntheticPointerActionTarget : public SyntheticGestureTarget {
public:
MockSyntheticPointerActionTarget() {}
@@ -107,11 +123,13 @@ class MockSyntheticPointerTouchActionTarget
const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event);
type_ = touch_event.GetType();
for (size_t i = 0; i < WebTouchEvent::kTouchesLengthCap; ++i) {
+ if (WebTouchPointStateToEventType(touch_event.touches[i].state) != type_)
+ continue;
+
indexes_[i] = touch_event.touches[i].id;
positions_[i] = gfx::PointF(touch_event.touches[i].PositionInWidget());
states_[i] = touch_event.touches[i].state;
}
- touch_length_ = touch_event.touches_length;
}
testing::AssertionResult SyntheticTouchActionDispatchedCorrectly(
@@ -146,16 +164,12 @@ class MockSyntheticPointerTouchActionTarget
testing::AssertionResult SyntheticTouchActionListDispatchedCorrectly(
const std::vector<SyntheticPointerActionParams>& params_list) {
- if (touch_length_ != params_list.size()) {
- return testing::AssertionFailure() << "Touch point length was "
- << touch_length_ << ", expected "
- << params_list.size() << ".";
- }
-
testing::AssertionResult result = testing::AssertionSuccess();
for (size_t i = 0; i < params_list.size(); ++i) {
- result = SyntheticTouchActionDispatchedCorrectly(params_list[i],
- params_list[i].index());
+ if (params_list[i].pointer_action_type() !=
+ SyntheticPointerActionParams::PointerActionType::IDLE)
+ result = SyntheticTouchActionDispatchedCorrectly(
+ params_list[i], params_list[i].index());
if (result == testing::AssertionFailure())
return result;
}
@@ -169,7 +183,6 @@ class MockSyntheticPointerTouchActionTarget
private:
gfx::PointF positions_[WebTouchEvent::kTouchesLengthCap];
- unsigned touch_length_;
int indexes_[WebTouchEvent::kTouchesLengthCap];
WebTouchPoint::State states_[WebTouchEvent::kTouchesLengthCap];
};
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 f06e309f256..41c2c94fe34 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc
+++ b/chromium/content/browser/renderer_host/input/touch_action_browsertest.cc
@@ -101,9 +101,9 @@ const char kTouchActionURLWithOverlapArea[] =
" touch-action: pan-x;"
"}"
"</style>"
+ "<div class='box ta-auto'></div>"
"<div class='box ta-panx'></div>"
"<div class='box ta-pany'></div>"
- "<div class='box ta-auto'></div>"
"<div class=spacer></div>"
"<script>"
" document.title='ready';"
@@ -279,10 +279,25 @@ class TouchActionBrowserTest : public ContentBrowserTest {
ExecuteScriptAndExtractInt("document.documentElement.scrollHeight");
EXPECT_EQ(expected_scroll_height_after_scroll, scroll_height);
+ float page_scale_factor =
+ frame_observer_->LastRenderFrameMetadata().page_scale_factor;
+ if (page_scale_factor == 0)
+ page_scale_factor = 1.0f;
+ gfx::PointF touch_point(point);
+ if (page_scale_factor != 1.0f) {
+ touch_point.set_x(touch_point.x() * page_scale_factor);
+ touch_point.set_y(touch_point.y() * page_scale_factor);
+ }
SyntheticSmoothScrollGestureParams params;
params.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
- params.anchor = gfx::PointF(point);
+ params.anchor = touch_point;
params.distances.push_back(-distance);
+ // Set the speed to very high so that there is one GSU only.
+ // It seems that when the speed is too high, it has a race with the timeout
+ // test.
+ if (jank_time != kLongJankTime) {
+ params.speed_in_pixels_s = 1000000;
+ }
run_loop_ = std::make_unique<base::RunLoop>();
@@ -331,7 +346,7 @@ class TouchActionBrowserTest : public ContentBrowserTest {
int scroll_top = GetScrollTop();
int scroll_left = GetScrollLeft();
- // Allow for 1px rounding inaccuracies for some screen sizes.
+ // Expect it scrolled at least half of the expected distance.
EXPECT_LE(expected_scroll_position_after_scroll.y() / 2, scroll_top);
EXPECT_LE(expected_scroll_position_after_scroll.x() / 2, scroll_left);
}
@@ -342,10 +357,9 @@ class TouchActionBrowserTest : public ContentBrowserTest {
DISALLOW_COPY_AND_ASSIGN(TouchActionBrowserTest);
};
-// Mac doesn't yet have a gesture recognizer, so can't support turning touch
-// events into scroll gestures.
-// Will be fixed with http://crbug.com/337142
-#if defined(OS_MACOSX)
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || \
+ defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
+ defined(THREAD_SANITIZER)
#define MAYBE_DefaultAuto DISABLED_DefaultAuto
#else
#define MAYBE_DefaultAuto DefaultAuto
@@ -367,8 +381,9 @@ IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest, MAYBE_DefaultAuto) {
// Verify that touching a touch-action: none region disables scrolling and
// enables all touch events to be sent.
-// Disabled on MacOS because it doesn't support touch input.
-#if defined(OS_MACOSX)
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || \
+ defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
+ defined(THREAD_SANITIZER)
#define MAYBE_TouchActionNone DISABLED_TouchActionNone
#else
#define MAYBE_TouchActionNone TouchActionNone
@@ -385,7 +400,9 @@ IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest, MAYBE_TouchActionNone) {
EXPECT_EQ(0, ExecuteScriptAndExtractInt("eventCounts.touchcancel"));
}
-#if defined(OS_MACOSX)
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || \
+ defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
+ defined(THREAD_SANITIZER)
#define MAYBE_PanYMainThreadJanky DISABLED_PanYMainThreadJanky
#else
#define MAYBE_PanYMainThreadJanky PanYMainThreadJanky
@@ -397,7 +414,9 @@ IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest, MAYBE_PanYMainThreadJanky) {
gfx::Vector2d(0, 45), kShortJankTime);
}
-#if defined(OS_MACOSX)
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || \
+ defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
+ defined(THREAD_SANITIZER)
#define MAYBE_PanXMainThreadJanky DISABLED_PanXMainThreadJanky
#else
#define MAYBE_PanXMainThreadJanky PanXMainThreadJanky
@@ -438,7 +457,9 @@ IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest,
DoTwoFingerTouchScroll(false, gfx::Vector2d(20, 0));
}
-#if defined(OS_MACOSX)
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || \
+ defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
+ defined(THREAD_SANITIZER)
#define MAYBE_PanXYMainThreadJanky DISABLED_PanXYMainThreadJanky
#else
#define MAYBE_PanXYMainThreadJanky PanXYMainThreadJanky
@@ -450,8 +471,9 @@ IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest, MAYBE_PanXYMainThreadJanky) {
gfx::Vector2d(45, 45), kShortJankTime);
}
-#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
-// Flaky: https://crbug.com/833015
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || \
+ defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
+ defined(THREAD_SANITIZER)
#define MAYBE_PanXYAtXAreaMainThreadJanky DISABLED_PanXYAtXAreaMainThreadJanky
#else
#define MAYBE_PanXYAtXAreaMainThreadJanky PanXYAtXAreaMainThreadJanky
@@ -460,12 +482,13 @@ IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest,
MAYBE_PanXYAtXAreaMainThreadJanky) {
LoadURL(kTouchActionURLWithOverlapArea);
- DoTouchScroll(gfx::Point(125, 25), gfx::Vector2d(45, 45), false, 10000,
+ DoTouchScroll(gfx::Point(125, 25), gfx::Vector2d(45, 20), false, 10000,
gfx::Vector2d(45, 0), kShortJankTime);
}
-#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
-// Flaky: https://crbug.com/833015
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || \
+ defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
+ defined(THREAD_SANITIZER)
#define MAYBE_PanXYAtYAreaMainThreadJanky DISABLED_PanXYAtYAreaMainThreadJanky
#else
#define MAYBE_PanXYAtYAreaMainThreadJanky PanXYAtYAreaMainThreadJanky
@@ -474,11 +497,13 @@ IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest,
MAYBE_PanXYAtYAreaMainThreadJanky) {
LoadURL(kTouchActionURLWithOverlapArea);
- DoTouchScroll(gfx::Point(25, 125), gfx::Vector2d(45, 45), false, 10000,
+ DoTouchScroll(gfx::Point(25, 125), gfx::Vector2d(20, 45), false, 10000,
gfx::Vector2d(0, 45), kShortJankTime);
}
-#if defined(OS_MACOSX)
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || \
+ defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
+ defined(THREAD_SANITIZER)
#define MAYBE_PanXYAtAutoYOverlapAreaMainThreadJanky \
DISABLED_PanXYAtAutoYOverlapAreaMainThreadJanky
#else
@@ -489,11 +514,13 @@ IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest,
MAYBE_PanXYAtAutoYOverlapAreaMainThreadJanky) {
LoadURL(kTouchActionURLWithOverlapArea);
- DoTouchScroll(gfx::Point(75, 125), gfx::Vector2d(45, 45), false, 10000,
+ DoTouchScroll(gfx::Point(75, 125), gfx::Vector2d(20, 45), false, 10000,
gfx::Vector2d(0, 45), kShortJankTime);
}
-#if defined(OS_MACOSX)
+#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || \
+ defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
+ defined(THREAD_SANITIZER)
#define MAYBE_PanXYAtAutoXOverlapAreaMainThreadJanky \
DISABLED_PanXYAtAutoXOverlapAreaMainThreadJanky
#else
@@ -504,7 +531,7 @@ IN_PROC_BROWSER_TEST_F(TouchActionBrowserTest,
MAYBE_PanXYAtAutoXOverlapAreaMainThreadJanky) {
LoadURL(kTouchActionURLWithOverlapArea);
- DoTouchScroll(gfx::Point(125, 75), gfx::Vector2d(45, 45), false, 10000,
+ DoTouchScroll(gfx::Point(125, 75), gfx::Vector2d(45, 20), false, 10000,
gfx::Vector2d(45, 0), kShortJankTime);
}
diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter.cc b/chromium/content/browser/renderer_host/input/touch_action_filter.cc
index a7cd888a9cb..16e30e8e392 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_filter.cc
+++ b/chromium/content/browser/renderer_host/input/touch_action_filter.cc
@@ -38,8 +38,7 @@ TouchActionFilter::TouchActionFilter()
: suppress_manipulation_events_(false),
drop_current_tap_ending_event_(false),
allow_current_double_tap_event_(true),
- force_enable_zoom_(false),
- allowed_touch_action_(cc::kTouchActionAuto) {}
+ force_enable_zoom_(false) {}
FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
WebGestureEvent* gesture_event) {
@@ -49,15 +48,21 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
// Filter for allowable touch actions first (eg. before the TouchEventQueue
// can decide to send a touch cancel event).
switch (gesture_event->GetType()) {
- case WebInputEvent::kGestureScrollBegin:
+ case WebInputEvent::kGestureScrollBegin: {
DCHECK(!suppress_manipulation_events_);
+ DCHECK(!touchscreen_scroll_in_progress_);
+ touchscreen_scroll_in_progress_ = true;
+ // TODO(https://crbug.com/851644): Make sure the value is properly set.
+ if (!scrolling_touch_action_.has_value())
+ SetTouchAction(cc::kTouchActionAuto);
suppress_manipulation_events_ =
ShouldSuppressManipulation(*gesture_event);
return suppress_manipulation_events_
? FilterGestureEventResult::kFilterGestureEventFiltered
: FilterGestureEventResult::kFilterGestureEventAllowed;
+ }
- case WebInputEvent::kGestureScrollUpdate:
+ case WebInputEvent::kGestureScrollUpdate: {
if (suppress_manipulation_events_)
return FilterGestureEventResult::kFilterGestureEventFiltered;
@@ -69,39 +74,25 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
// two-finger scrolling but a "touch-action: pan-x pinch-zoom" region
// doesn't.
// TODO(mustaq): Add it to spec?
- if (IsYAxisActionDisallowed(allowed_touch_action_)) {
+ if (IsYAxisActionDisallowed(scrolling_touch_action_.value())) {
gesture_event->data.scroll_update.delta_y = 0;
gesture_event->data.scroll_update.velocity_y = 0;
- } else if (IsXAxisActionDisallowed(allowed_touch_action_)) {
+ } else if (IsXAxisActionDisallowed(scrolling_touch_action_.value())) {
gesture_event->data.scroll_update.delta_x = 0;
gesture_event->data.scroll_update.velocity_x = 0;
}
break;
+ }
case WebInputEvent::kGestureFlingStart:
- ReportGestureEventFiltered(suppress_manipulation_events_);
- // Touchscreen flings should always have non-zero velocity.
- DCHECK(gesture_event->data.fling_start.velocity_x ||
- gesture_event->data.fling_start.velocity_y);
- if (!suppress_manipulation_events_) {
- // Flings restricted to a specific axis shouldn't permit velocity
- // in the perpendicular axis.
- if (IsYAxisActionDisallowed(allowed_touch_action_))
- gesture_event->data.fling_start.velocity_y = 0;
- else if (IsXAxisActionDisallowed(allowed_touch_action_))
- gesture_event->data.fling_start.velocity_x = 0;
- // As the renderer expects a scroll-ending event, but does not expect a
- // zero-velocity fling, convert the now zero-velocity fling accordingly.
- if (!gesture_event->data.fling_start.velocity_x &&
- !gesture_event->data.fling_start.velocity_y) {
- gesture_event->SetType(WebInputEvent::kGestureScrollEnd);
- }
- }
- return FilterManipulationEventAndResetState()
- ? FilterGestureEventResult::kFilterGestureEventFiltered
- : FilterGestureEventResult::kFilterGestureEventAllowed;
+ // Fling controller processes FlingStart event, and we should never get
+ // it here.
+ NOTREACHED();
+ break;
case WebInputEvent::kGestureScrollEnd:
+ DCHECK(touchscreen_scroll_in_progress_);
+ touchscreen_scroll_in_progress_ = false;
ReportGestureEventFiltered(suppress_manipulation_events_);
return FilterManipulationEventAndResetState()
? FilterGestureEventResult::kFilterGestureEventFiltered
@@ -125,21 +116,21 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
break;
// If double tap is disabled, there's no reason for the tap delay.
- case WebInputEvent::kGestureTapUnconfirmed:
+ case WebInputEvent::kGestureTapUnconfirmed: {
DCHECK_EQ(1, gesture_event->data.tap.tap_count);
- allow_current_double_tap_event_ =
- (allowed_touch_action_ & cc::kTouchActionDoubleTapZoom) != 0;
+ // TODO(https://crbug.com/851644): Make sure the value is properly set.
+ if (!scrolling_touch_action_.has_value())
+ SetTouchAction(cc::kTouchActionAuto);
+ allow_current_double_tap_event_ = (scrolling_touch_action_.value() &
+ cc::kTouchActionDoubleTapZoom) != 0;
if (!allow_current_double_tap_event_) {
gesture_event->SetType(WebInputEvent::kGestureTap);
drop_current_tap_ending_event_ = true;
}
break;
+ }
case WebInputEvent::kGestureTap:
- allow_current_double_tap_event_ =
- (allowed_touch_action_ & cc::kTouchActionDoubleTapZoom) != 0;
- FALLTHROUGH;
-
case WebInputEvent::kGestureTapCancel:
if (drop_current_tap_ending_event_) {
drop_current_tap_ending_event_ = false;
@@ -148,6 +139,16 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
break;
case WebInputEvent::kGestureTapDown:
+ // If the gesture is hitting a region that has a non-blocking (such as a
+ // passive) event listener.
+ if (gesture_event->is_source_touch_event_set_non_blocking)
+ SetTouchAction(cc::kTouchActionAuto);
+ scrolling_touch_action_ = allowed_touch_action_;
+ // TODO(https://crbug.com/851644): The value may not set in the case when
+ // the gesture event is flushed due to touch ack time out after the finger
+ // is lifted up. Make sure the value is properly set.
+ if (!scrolling_touch_action_.has_value())
+ SetTouchAction(cc::kTouchActionAuto);
DCHECK(!drop_current_tap_ending_event_);
break;
@@ -160,6 +161,11 @@ FilterGestureEventResult TouchActionFilter::FilterGestureEvent(
return FilterGestureEventResult::kFilterGestureEventAllowed;
}
+void TouchActionFilter::SetTouchAction(cc::TouchAction touch_action) {
+ allowed_touch_action_ = touch_action;
+ scrolling_touch_action_ = allowed_touch_action_;
+}
+
bool TouchActionFilter::FilterManipulationEventAndResetState() {
if (suppress_manipulation_events_) {
suppress_manipulation_events_ = false;
@@ -169,6 +175,8 @@ bool TouchActionFilter::FilterManipulationEventAndResetState() {
}
void TouchActionFilter::OnSetTouchAction(cc::TouchAction touch_action) {
+ // TODO(https://crbug.com/849819): add a DCHECK for
+ // |has_touch_event_handler_|.
// For multiple fingers, we take the intersection of the touch actions for
// all fingers that have gone down during this action. In the majority of
// real-world scenarios the touch action for all fingers will be the same.
@@ -180,22 +188,35 @@ void TouchActionFilter::OnSetTouchAction(cc::TouchAction touch_action) {
// down "at once" will be deterministic.
// 2. Only subtractive - eg. can't trigger scrolling on a element that
// otherwise has scrolling disabling by the addition of a finger.
- allowed_touch_action_ &= touch_action;
+ allowed_touch_action_ =
+ allowed_touch_action_.value_or(cc::kTouchActionAuto) & touch_action;
// When user enabled force enable zoom, we should always allow pinch-zoom
// except for touch-action:none.
- if (force_enable_zoom_ && allowed_touch_action_ != cc::kTouchActionNone)
- allowed_touch_action_ |= cc::kTouchActionPinchZoom;
+ if (force_enable_zoom_ && allowed_touch_action_ != cc::kTouchActionNone) {
+ allowed_touch_action_ =
+ allowed_touch_action_.value() | cc::kTouchActionPinchZoom;
+ }
+ scrolling_touch_action_ = allowed_touch_action_;
}
void TouchActionFilter::ReportAndResetTouchAction() {
+ ReportTouchAction();
+ ResetTouchAction();
+}
+
+void TouchActionFilter::ReportTouchAction() {
+ // TODO(https://crbug.com/851644): make sure the value is properly set.
+ if (!scrolling_touch_action_.has_value())
+ SetTouchAction(cc::kTouchActionAuto);
// Report the effective touch action computed by blink such as
// kTouchActionNone, kTouchActionPanX, etc.
// Since |cc::kTouchActionAuto| is equivalent to |cc::kTouchActionMax|, we
// must add one to the upper bound to be able to visualize the number of
// times |cc::kTouchActionAuto| is hit.
UMA_HISTOGRAM_ENUMERATION("TouchAction.EffectiveTouchAction",
- allowed_touch_action_, cc::kTouchActionMax + 1);
+ scrolling_touch_action_.value(),
+ cc::kTouchActionMax + 1);
// Report how often the effective touch action computed by blink is or is
// not equivalent to the whitelisted touch action computed by the
@@ -203,16 +224,25 @@ void TouchActionFilter::ReportAndResetTouchAction() {
if (white_listed_touch_action_.has_value()) {
UMA_HISTOGRAM_BOOLEAN(
"TouchAction.EquivalentEffectiveAndWhiteListed",
- allowed_touch_action_ == white_listed_touch_action_.value());
+ scrolling_touch_action_.value() == white_listed_touch_action_.value());
}
- ResetTouchAction();
}
void TouchActionFilter::ResetTouchAction() {
// Note that resetting the action mid-sequence is tolerated. Gestures that had
- // their begin event(s) suppressed will be suppressed until the next sequence.
- allowed_touch_action_ = cc::kTouchActionAuto;
- white_listed_touch_action_.reset();
+ // their begin event(s) suppressed will be suppressed until the next
+ // sequenceo.
+ if (has_touch_event_handler_) {
+ allowed_touch_action_.reset();
+ white_listed_touch_action_.reset();
+ } else {
+ // Lack of a touch handler indicates that the page either has no
+ // touch-action modifiers or that all its touch-action modifiers are auto.
+ // Resetting the touch-action here allows forwarding of subsequent gestures
+ // even if the underlying touches never reach the router.
+ SetTouchAction(cc::kTouchActionAuto);
+ white_listed_touch_action_ = cc::kTouchActionAuto;
+ }
}
void TouchActionFilter::OnSetWhiteListedTouchAction(
@@ -235,7 +265,7 @@ bool TouchActionFilter::ShouldSuppressManipulation(
// Any GestureScrollBegin with more than one fingers is like a pinch-zoom
// for touch-actions, see crbug.com/632525. Therefore, we switch to
// blocked-manipulation mode iff pinch-zoom is disallowed.
- return (allowed_touch_action_ & cc::kTouchActionPinchZoom) == 0;
+ return (scrolling_touch_action_.value() & cc::kTouchActionPinchZoom) == 0;
}
const float& deltaXHint = gesture_event.data.scroll_begin.delta_x_hint;
@@ -262,7 +292,24 @@ bool TouchActionFilter::ShouldSuppressManipulation(
}
DCHECK(minimal_conforming_touch_action != cc::kTouchActionNone);
- return (allowed_touch_action_ & minimal_conforming_touch_action) == 0;
+ return (scrolling_touch_action_.value() & minimal_conforming_touch_action) ==
+ 0;
+}
+
+void TouchActionFilter::OnHasTouchEventHandlers(bool has_handlers) {
+ // The has_touch_event_handler_ is default to false which is why we have the
+ // "&&" condition here, to ensure that touch actions will be set if there is
+ // no touch event handler on a page.
+ if (has_handlers && has_touch_event_handler_ == has_handlers)
+ return;
+ has_touch_event_handler_ = has_handlers;
+ ResetTouchAction();
+ // If a page has a touch event handler, this function can be called twice with
+ // has_handlers = false first and then true later. When it is true, we need to
+ // reset the |scrolling_touch_action_|. However, we do not want to reset it if
+ // there is an active scroll in progress.
+ if (has_touch_event_handler_ && !touchscreen_scroll_in_progress_)
+ scrolling_touch_action_.reset();
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter.h b/chromium/content/browser/renderer_host/input/touch_action_filter.h
index 851d92e954b..d1167ae83d6 100644
--- a/chromium/content/browser/renderer_host/input/touch_action_filter.h
+++ b/chromium/content/browser/renderer_host/input/touch_action_filter.h
@@ -57,15 +57,22 @@ class CONTENT_EXPORT TouchActionFilter {
// renderer for a touch start event that is currently in flight.
void OnSetWhiteListedTouchAction(cc::TouchAction white_listed_touch_action);
- cc::TouchAction allowed_touch_action() const { return allowed_touch_action_; }
+ base::Optional<cc::TouchAction> allowed_touch_action() const {
+ return allowed_touch_action_;
+ }
void SetForceEnableZoom(bool enabled) { force_enable_zoom_ = enabled; }
+ void OnHasTouchEventHandlers(bool has_handlers);
+
private:
friend class MockRenderWidgetHost;
+ friend class TouchActionFilterTest;
bool ShouldSuppressManipulation(const blink::WebGestureEvent&);
bool FilterManipulationEventAndResetState();
+ void ReportTouchAction();
+ void SetTouchAction(cc::TouchAction touch_action);
// Whether scroll and pinch gestures should be discarded due to touch-action.
bool suppress_manipulation_events_;
@@ -83,8 +90,23 @@ class CONTENT_EXPORT TouchActionFilter {
// Force enable zoom for Accessibility.
bool force_enable_zoom_;
+ // Indicates whether this page has touch event handler or not. Set by
+ // InputRouterImpl::OnHasTouchEventHandler.
+ // TODO(https://crbug.com/850238): default to true or make it Optional.
+ bool has_touch_event_handler_ = false;
+
+ // True if an active touch scroll gesture is in progress. i.e. after GSB and
+ // before GSE.
+ bool touchscreen_scroll_in_progress_ = false;
+
// What touch actions are currently permitted.
- cc::TouchAction allowed_touch_action_;
+ base::Optional<cc::TouchAction> allowed_touch_action_;
+
+ // The touch action that is used for the current scrolling gesture sequence.
+ // At the touch sequence end, the |allowed_touch_action| is reset while this
+ // remains set as the effective touch action, for the still in progress scroll
+ // sequence due to fling.
+ base::Optional<cc::TouchAction> scrolling_touch_action_;
// Whitelisted touch action received from the compositor.
base::Optional<cc::TouchAction> white_listed_touch_action_;
diff --git a/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc b/chromium/content/browser/renderer_host/input/touch_action_filter_unittest.cc
index eadd374e19c..9a5d4a8c41c 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
@@ -20,175 +20,177 @@ const blink::WebGestureDevice kSourceDevice =
} // namespace
-static void PanTest(cc::TouchAction action,
- float scroll_x,
- float scroll_y,
- float dx,
- float dy,
- float fling_x,
- float fling_y,
- float expected_dx,
- float expected_dy,
- float expected_fling_x,
- float expected_fling_y) {
- TouchActionFilter filter;
- WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
- WebInputEvent::kGestureScrollEnd, kSourceDevice);
-
- {
- // Scrolls with no direction hint are permitted in the |action| direction.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(action);
-
- WebGestureEvent scroll_begin =
- SyntheticWebGestureEventBuilder::BuildScrollBegin(0, 0, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
- FilterGestureEventResult::kFilterGestureEventAllowed);
-
- WebGestureEvent scroll_update =
- SyntheticWebGestureEventBuilder::BuildScrollUpdate(dx, dy, 0,
- kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(expected_dx, scroll_update.data.scroll_update.delta_x);
- EXPECT_EQ(expected_dy, scroll_update.data.scroll_update.delta_y);
-
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- }
-
- {
- // Scrolls biased towards the touch-action axis are permitted.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(action);
- WebGestureEvent scroll_begin =
- SyntheticWebGestureEventBuilder::BuildScrollBegin(scroll_x, scroll_y,
- kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
- FilterGestureEventResult::kFilterGestureEventAllowed);
-
- WebGestureEvent scroll_update =
- SyntheticWebGestureEventBuilder::BuildScrollUpdate(dx, dy, 0,
- kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(expected_dx, scroll_update.data.scroll_update.delta_x);
- EXPECT_EQ(expected_dy, scroll_update.data.scroll_update.delta_y);
-
- // Ensure that scrolls in the opposite direction are not filtered once
- // scrolling has started. (Once scrolling is started, the direction may
- // be reversed by the user even if scrolls that start in the reversed
- // direction are disallowed.
- WebGestureEvent scroll_update2 =
- SyntheticWebGestureEventBuilder::BuildScrollUpdate(-dx, -dy, 0,
- kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update2),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(-expected_dx, scroll_update2.data.scroll_update.delta_x);
- EXPECT_EQ(-expected_dy, scroll_update2.data.scroll_update.delta_y);
-
- WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
- fling_x, fling_y, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&fling_start),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(expected_fling_x, fling_start.data.fling_start.velocity_x);
- EXPECT_EQ(expected_fling_y, fling_start.data.fling_start.velocity_y);
- }
-
- {
- // Scrolls biased towards the perpendicular of the touch-action axis are
- // suppressed entirely.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(action);
- WebGestureEvent scroll_begin =
- SyntheticWebGestureEventBuilder::BuildScrollBegin(scroll_y, scroll_x,
- kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
- FilterGestureEventResult::kFilterGestureEventFiltered);
-
- WebGestureEvent scroll_update =
- SyntheticWebGestureEventBuilder::BuildScrollUpdate(dx, dy, 0,
- kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
- FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(dx, scroll_update.data.scroll_update.delta_x);
- EXPECT_EQ(dy, scroll_update.data.scroll_update.delta_y);
+class TouchActionFilterTest : public testing::Test {
+ public:
+ TouchActionFilterTest(){};
+ ~TouchActionFilterTest() override {}
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
- FilterGestureEventResult::kFilterGestureEventFiltered);
+ protected:
+ base::Optional<cc::TouchAction> ScrollingTouchAction() const {
+ return filter_.scrolling_touch_action_;
}
-}
-
-static void PanTestForUnidirectionalTouchAction(cc::TouchAction action,
- float scroll_x,
- float scroll_y) {
- TouchActionFilter filter;
- WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
- WebInputEvent::kGestureScrollEnd, kSourceDevice);
-
- {
- // Scrolls towards the touch-action direction are permitted.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(action);
- WebGestureEvent scroll_begin =
- SyntheticWebGestureEventBuilder::BuildScrollBegin(scroll_x, scroll_y,
- kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
- FilterGestureEventResult::kFilterGestureEventAllowed);
+ void PanTest(cc::TouchAction action,
+ float scroll_x,
+ float scroll_y,
+ float dx,
+ float dy,
+ float expected_dx,
+ float expected_dy) {
+ WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::kGestureScrollEnd, kSourceDevice);
- WebGestureEvent scroll_update =
- SyntheticWebGestureEventBuilder::BuildScrollUpdate(scroll_x, scroll_y,
- 0, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
- FilterGestureEventResult::kFilterGestureEventAllowed);
+ {
+ // Scrolls with no direction hint are permitted in the |action| direction.
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(action);
+
+ WebGestureEvent scroll_begin =
+ SyntheticWebGestureEventBuilder::BuildScrollBegin(0, 0,
+ kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+
+ WebGestureEvent scroll_update =
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(dx, dy, 0,
+ kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_EQ(expected_dx, scroll_update.data.scroll_update.delta_x);
+ EXPECT_EQ(expected_dy, scroll_update.data.scroll_update.delta_y);
+
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ }
+
+ {
+ // Scrolls biased towards the touch-action axis are permitted.
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(action);
+ WebGestureEvent scroll_begin =
+ SyntheticWebGestureEventBuilder::BuildScrollBegin(scroll_x, scroll_y,
+ kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+
+ WebGestureEvent scroll_update =
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(dx, dy, 0,
+ kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_EQ(expected_dx, scroll_update.data.scroll_update.delta_x);
+ EXPECT_EQ(expected_dy, scroll_update.data.scroll_update.delta_y);
+
+ // Ensure that scrolls in the opposite direction are not filtered once
+ // scrolling has started. (Once scrolling is started, the direction may
+ // be reversed by the user even if scrolls that start in the reversed
+ // direction are disallowed.
+ WebGestureEvent scroll_update2 =
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(-dx, -dy, 0,
+ kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update2),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_EQ(-expected_dx, scroll_update2.data.scroll_update.delta_x);
+ EXPECT_EQ(-expected_dy, scroll_update2.data.scroll_update.delta_y);
+
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ }
+
+ {
+ // Scrolls biased towards the perpendicular of the touch-action axis are
+ // suppressed entirely.
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(action);
+ WebGestureEvent scroll_begin =
+ SyntheticWebGestureEventBuilder::BuildScrollBegin(scroll_y, scroll_x,
+ kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
+ FilterGestureEventResult::kFilterGestureEventFiltered);
+
+ WebGestureEvent scroll_update =
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(dx, dy, 0,
+ kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
+ FilterGestureEventResult::kFilterGestureEventFiltered);
+ EXPECT_EQ(dx, scroll_update.data.scroll_update.delta_x);
+ EXPECT_EQ(dy, scroll_update.data.scroll_update.delta_y);
+
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
+ FilterGestureEventResult::kFilterGestureEventFiltered);
+ }
}
- {
- // Scrolls towards the exact opposite of the touch-action direction are
- // suppressed entirely.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(action);
- WebGestureEvent scroll_begin =
- SyntheticWebGestureEventBuilder::BuildScrollBegin(-scroll_x, -scroll_y,
- kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
- FilterGestureEventResult::kFilterGestureEventFiltered);
+ void PanTestForUnidirectionalTouchAction(cc::TouchAction action,
+ float scroll_x,
+ float scroll_y) {
+ WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::kGestureScrollEnd, kSourceDevice);
- WebGestureEvent scroll_update =
- SyntheticWebGestureEventBuilder::BuildScrollUpdate(-scroll_x, -scroll_y,
- 0, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
- FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
- FilterGestureEventResult::kFilterGestureEventFiltered);
+ {
+ // Scrolls towards the touch-action direction are permitted.
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(action);
+ WebGestureEvent scroll_begin =
+ SyntheticWebGestureEventBuilder::BuildScrollBegin(scroll_x, scroll_y,
+ kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+
+ WebGestureEvent scroll_update =
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(scroll_x, scroll_y,
+ 0, kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ }
+
+ {
+ // Scrolls towards the exact opposite of the touch-action direction are
+ // suppressed entirely.
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(action);
+ WebGestureEvent scroll_begin =
+ SyntheticWebGestureEventBuilder::BuildScrollBegin(
+ -scroll_x, -scroll_y, kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
+ FilterGestureEventResult::kFilterGestureEventFiltered);
+
+ WebGestureEvent scroll_update =
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(
+ -scroll_x, -scroll_y, 0, kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
+ FilterGestureEventResult::kFilterGestureEventFiltered);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
+ FilterGestureEventResult::kFilterGestureEventFiltered);
+ }
+
+ {
+ // Scrolls towards the diagonal opposite of the touch-action direction are
+ // suppressed entirely.
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(action);
+ WebGestureEvent scroll_begin =
+ SyntheticWebGestureEventBuilder::BuildScrollBegin(
+ -scroll_x - scroll_y, -scroll_x - scroll_y, kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
+ FilterGestureEventResult::kFilterGestureEventFiltered);
+
+ WebGestureEvent scroll_update =
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(
+ -scroll_x - scroll_y, -scroll_x - scroll_y, 0, kSourceDevice);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
+ FilterGestureEventResult::kFilterGestureEventFiltered);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
+ FilterGestureEventResult::kFilterGestureEventFiltered);
+ }
}
+ TouchActionFilter filter_;
+};
- {
- // Scrolls towards the diagonal opposite of the touch-action direction are
- // suppressed entirely.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(action);
- WebGestureEvent scroll_begin =
- SyntheticWebGestureEventBuilder::BuildScrollBegin(
- -scroll_x - scroll_y, -scroll_x - scroll_y, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
- FilterGestureEventResult::kFilterGestureEventFiltered);
-
- WebGestureEvent scroll_update =
- SyntheticWebGestureEventBuilder::BuildScrollUpdate(
- -scroll_x - scroll_y, -scroll_x - scroll_y, 0, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
- FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
- FilterGestureEventResult::kFilterGestureEventFiltered);
- }
-}
-
-TEST(TouchActionFilterTest, SimpleFilter) {
- TouchActionFilter filter;
-
+TEST_F(TouchActionFilterTest, SimpleFilter) {
+ WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::kGestureTapDown, kSourceDevice);
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(2, 3, kSourceDevice);
const float kDeltaX = 5;
@@ -201,287 +203,209 @@ TEST(TouchActionFilterTest, SimpleFilter) {
WebGestureEvent tap = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureTap, kSourceDevice);
- // No events filtered by default.
- filter.ResetTouchAction();
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(kDeltaX, scroll_update.data.scroll_update.delta_x);
- EXPECT_EQ(kDeltaY, scroll_update.data.scroll_update.delta_y);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- filter.ResetTouchAction();
- EXPECT_EQ(filter.FilterGestureEvent(&tap),
- FilterGestureEventResult::kFilterGestureEventAllowed);
-
// cc::kTouchActionAuto doesn't cause any filtering.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionAuto);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(kDeltaX, scroll_update.data.scroll_update.delta_x);
EXPECT_EQ(kDeltaY, scroll_update.data.scroll_update.delta_y);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
// cc::kTouchActionNone filters out all scroll events, but no other events.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&tap),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
EXPECT_EQ(kDeltaX, scroll_update.data.scroll_update.delta_x);
EXPECT_EQ(kDeltaY, scroll_update.data.scroll_update.delta_y);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
// When a new touch sequence begins, the state is reset.
- filter.ResetTouchAction();
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
// Setting touch action doesn't impact any in-progress gestures.
- filter.ResetTouchAction();
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
// And the state is still cleared for the next gesture.
- filter.ResetTouchAction();
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
// Changing the touch action during a gesture has no effect.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- filter.OnSetTouchAction(cc::kTouchActionAuto);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
EXPECT_EQ(kDeltaX, scroll_update.data.scroll_update.delta_x);
EXPECT_EQ(kDeltaY, scroll_update.data.scroll_update.delta_y);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
}
-TEST(TouchActionFilterTest, Fling) {
- TouchActionFilter filter;
-
- WebGestureEvent scroll_begin =
- SyntheticWebGestureEventBuilder::BuildScrollBegin(2, 3, kSourceDevice);
- WebGestureEvent scroll_update =
- SyntheticWebGestureEventBuilder::BuildScrollUpdate(5, 10, 0,
- kSourceDevice);
- const float kFlingX = 7;
- const float kFlingY = -4;
- WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
- kFlingX, kFlingY, kSourceDevice);
- WebGestureEvent pad_fling = SyntheticWebGestureEventBuilder::BuildFling(
- kFlingX, kFlingY, blink::kWebGestureDeviceTouchpad);
-
- // cc::kTouchActionNone filters out fling events.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
- FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
- FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&fling_start),
- FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(kFlingX, fling_start.data.fling_start.velocity_x);
- EXPECT_EQ(kFlingY, fling_start.data.fling_start.velocity_y);
-
- // touchpad flings aren't filtered.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
- FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
- FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pad_fling),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&fling_start),
- FilterGestureEventResult::kFilterGestureEventFiltered);
-}
-
-TEST(TouchActionFilterTest, PanLeft) {
+TEST_F(TouchActionFilterTest, PanLeft) {
const float kDX = 5;
const float kDY = 10;
const float kScrollX = 7;
const float kScrollY = 6;
- const float kFlingX = 7;
- const float kFlingY = -4;
- PanTest(cc::kTouchActionPanLeft, kScrollX, kScrollY, kDX, kDY, kFlingX,
- kFlingY, kDX, 0, kFlingX, 0);
+ PanTest(cc::kTouchActionPanLeft, kScrollX, kScrollY, kDX, kDY, kDX, 0);
PanTestForUnidirectionalTouchAction(cc::kTouchActionPanLeft, kScrollX, 0);
}
-TEST(TouchActionFilterTest, PanRight) {
+TEST_F(TouchActionFilterTest, PanRight) {
const float kDX = 5;
const float kDY = 10;
const float kScrollX = -7;
const float kScrollY = 6;
- const float kFlingX = 7;
- const float kFlingY = -4;
- PanTest(cc::kTouchActionPanRight, kScrollX, kScrollY, kDX, kDY, kFlingX,
- kFlingY, kDX, 0, kFlingX, 0);
+ PanTest(cc::kTouchActionPanRight, kScrollX, kScrollY, kDX, kDY, kDX, 0);
PanTestForUnidirectionalTouchAction(cc::kTouchActionPanRight, kScrollX, 0);
}
-TEST(TouchActionFilterTest, PanX) {
+TEST_F(TouchActionFilterTest, PanX) {
const float kDX = 5;
const float kDY = 10;
const float kScrollX = 7;
const float kScrollY = 6;
- const float kFlingX = 7;
- const float kFlingY = -4;
- PanTest(cc::kTouchActionPanX, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY,
- kDX, 0, kFlingX, 0);
+ PanTest(cc::kTouchActionPanX, kScrollX, kScrollY, kDX, kDY, kDX, 0);
}
-TEST(TouchActionFilterTest, PanUp) {
+TEST_F(TouchActionFilterTest, PanUp) {
const float kDX = 5;
const float kDY = 10;
const float kScrollX = 6;
const float kScrollY = 7;
- const float kFlingX = 7;
- const float kFlingY = -4;
- PanTest(cc::kTouchActionPanUp, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY,
- 0, kDY, 0, kFlingY);
+ PanTest(cc::kTouchActionPanUp, kScrollX, kScrollY, kDX, kDY, 0, kDY);
PanTestForUnidirectionalTouchAction(cc::kTouchActionPanUp, 0, kScrollY);
}
-TEST(TouchActionFilterTest, PanDown) {
+TEST_F(TouchActionFilterTest, PanDown) {
const float kDX = 5;
const float kDY = 10;
const float kScrollX = 6;
const float kScrollY = -7;
- const float kFlingX = 7;
- const float kFlingY = -4;
- PanTest(cc::kTouchActionPanDown, kScrollX, kScrollY, kDX, kDY, kFlingX,
- kFlingY, 0, kDY, 0, kFlingY);
+ PanTest(cc::kTouchActionPanDown, kScrollX, kScrollY, kDX, kDY, 0, kDY);
PanTestForUnidirectionalTouchAction(cc::kTouchActionPanDown, 0, kScrollY);
}
-TEST(TouchActionFilterTest, PanY) {
+TEST_F(TouchActionFilterTest, PanY) {
const float kDX = 5;
const float kDY = 10;
const float kScrollX = 6;
const float kScrollY = 7;
- const float kFlingX = 7;
- const float kFlingY = -4;
- PanTest(cc::kTouchActionPanY, kScrollX, kScrollY, kDX, kDY, kFlingX, kFlingY,
- 0, kDY, 0, kFlingY);
+ PanTest(cc::kTouchActionPanY, kScrollX, kScrollY, kDX, kDY, 0, kDY);
}
-TEST(TouchActionFilterTest, PanXY) {
- TouchActionFilter filter;
+TEST_F(TouchActionFilterTest, PanXY) {
const float kDX = 5;
const float kDY = 10;
- const float kFlingX = 7;
- const float kFlingY = -4;
+ WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::kGestureScrollEnd, kSourceDevice);
{
// Scrolls hinted in the X axis are permitted and unmodified.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionPan);
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionPan);
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(-7, 6, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
WebGestureEvent scroll_update =
SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDX, kDY, 0,
kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(kDX, scroll_update.data.scroll_update.delta_x);
EXPECT_EQ(kDY, scroll_update.data.scroll_update.delta_y);
- WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
- kFlingX, kFlingY, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&fling_start),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(kFlingX, fling_start.data.fling_start.velocity_x);
- EXPECT_EQ(kFlingY, fling_start.data.fling_start.velocity_y);
}
{
// Scrolls hinted in the Y axis are permitted and unmodified.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionPan);
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionPan);
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
WebGestureEvent scroll_update =
SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDX, kDY, 0,
kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(kDX, scroll_update.data.scroll_update.delta_x);
EXPECT_EQ(kDY, scroll_update.data.scroll_update.delta_y);
- WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
- kFlingX, kFlingY, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&fling_start),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(kFlingX, fling_start.data.fling_start.velocity_x);
- EXPECT_EQ(kFlingY, fling_start.data.fling_start.velocity_y);
}
{
// A two-finger gesture is not allowed.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionPan);
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionPan);
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7, kSourceDevice,
2);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
WebGestureEvent scroll_update =
SyntheticWebGestureEventBuilder::BuildScrollUpdate(kDX, kDY, 0,
kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
- WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
- kFlingX, kFlingY, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&fling_start),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
}
}
-TEST(TouchActionFilterTest, BitMath) {
+TEST_F(TouchActionFilterTest, BitMath) {
// Verify that the simple flag mixing properties we depend on are now
// trivially true.
EXPECT_EQ(cc::kTouchActionNone, cc::kTouchActionNone & cc::kTouchActionAuto);
@@ -495,9 +419,7 @@ TEST(TouchActionFilterTest, BitMath) {
cc::kTouchActionManipulation | cc::kTouchActionDoubleTapZoom);
}
-TEST(TouchActionFilterTest, MultiTouch) {
- TouchActionFilter filter;
-
+TEST_F(TouchActionFilterTest, MultiTouch) {
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(2, 3, kSourceDevice);
const float kDeltaX = 5;
@@ -509,38 +431,37 @@ TEST(TouchActionFilterTest, MultiTouch) {
WebInputEvent::kGestureScrollEnd, kSourceDevice);
// For multiple points, the intersection is what matters.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionNone);
- filter.OnSetTouchAction(cc::kTouchActionAuto);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
EXPECT_EQ(kDeltaX, scroll_update.data.scroll_update.delta_x);
EXPECT_EQ(kDeltaY, scroll_update.data.scroll_update.delta_y);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
// Intersection of PAN_X and PAN_Y is NONE.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionPanX);
- filter.OnSetTouchAction(cc::kTouchActionPanY);
- filter.OnSetTouchAction(cc::kTouchActionPan);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionPanX);
+ filter_.OnSetTouchAction(cc::kTouchActionPanY);
+ filter_.OnSetTouchAction(cc::kTouchActionPan);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
}
class TouchActionFilterPinchTest : public testing::Test {
public:
void RunTest(bool force_enable_zoom) {
- TouchActionFilter filter;
- filter.SetForceEnableZoom(force_enable_zoom);
+ filter_.SetForceEnableZoom(force_enable_zoom);
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(2, 3, kSourceDevice,
@@ -556,171 +477,175 @@ class TouchActionFilterPinchTest : public testing::Test {
WebInputEvent::kGestureScrollEnd, kSourceDevice);
// Pinch is allowed with touch-action: auto.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionAuto);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
// Pinch is not allowed with touch-action: none.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
// Pinch is not allowed with touch-action: pan-x pan-y except for force
// enable zoom.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionPan);
- EXPECT_NE(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionPan);
+ EXPECT_NE(filter_.FilterGestureEvent(&scroll_begin),
force_enable_zoom
? FilterGestureEventResult::kFilterGestureEventFiltered
: FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_NE(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_NE(filter_.FilterGestureEvent(&pinch_begin),
force_enable_zoom
? FilterGestureEventResult::kFilterGestureEventFiltered
: FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_NE(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_NE(filter_.FilterGestureEvent(&pinch_update),
force_enable_zoom
? FilterGestureEventResult::kFilterGestureEventFiltered
: FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_NE(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_NE(filter_.FilterGestureEvent(&pinch_end),
force_enable_zoom
? FilterGestureEventResult::kFilterGestureEventFiltered
: FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_NE(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_NE(filter_.FilterGestureEvent(&scroll_end),
force_enable_zoom
? FilterGestureEventResult::kFilterGestureEventFiltered
: FilterGestureEventResult::kFilterGestureEventAllowed);
// Pinch is allowed with touch-action: manipulation.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionManipulation);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionManipulation);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
// Pinch state is automatically reset at the end of a scroll.
- filter.ResetTouchAction();
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
// Pinching is only computed at GestureScrollBegin time.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionAuto);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- filter.OnSetTouchAction(cc::kTouchActionAuto);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
// Once a pinch has started, any change in state won't affect the pinch
// gestures since it is computed in GestureScrollBegin.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionAuto);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
// Scrolling is allowed when two fingers are down.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionPinchZoom);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionPinchZoom);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
// A pinch event sequence with only one pointer is equivalent to a scroll
// gesture, so disallowed as a pinch gesture.
scroll_begin.data.scroll_begin.pointer_count = 1;
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionPinchZoom);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionPinchZoom);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
}
+
+ private:
+ TouchActionFilter filter_;
};
TEST_F(TouchActionFilterPinchTest, Pinch) {
@@ -733,9 +658,7 @@ TEST_F(TouchActionFilterPinchTest, ForceEnableZoom) {
RunTest(true);
}
-TEST(TouchActionFilterTest, DoubleTapWithTouchActionAuto) {
- TouchActionFilter filter;
-
+TEST_F(TouchActionFilterTest, DoubleTapWithTouchActionAuto) {
WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureTapDown, kSourceDevice);
WebGestureEvent unconfirmed_tap = SyntheticWebGestureEventBuilder::Build(
@@ -746,28 +669,27 @@ TEST(TouchActionFilterTest, DoubleTapWithTouchActionAuto) {
WebInputEvent::kGestureDoubleTap, kSourceDevice);
// Double tap is allowed with touch action auto.
- filter.ResetTouchAction();
- EXPECT_EQ(filter.FilterGestureEvent(&tap_down),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&unconfirmed_tap),
+ EXPECT_EQ(filter_.FilterGestureEvent(&unconfirmed_tap),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(unconfirmed_tap.GetType(), WebInputEvent::kGestureTapUnconfirmed);
// The tap cancel will come as part of the next touch sequence.
- filter.ResetTouchAction();
+ filter_.ResetTouchAction();
// Changing the touch action for the second tap doesn't effect the behaviour
// of the event.
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&tap_cancel),
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_cancel),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&tap_down),
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&double_tap),
+ EXPECT_EQ(filter_.FilterGestureEvent(&double_tap),
FilterGestureEventResult::kFilterGestureEventAllowed);
}
-TEST(TouchActionFilterTest, DoubleTap) {
- TouchActionFilter filter;
-
+TEST_F(TouchActionFilterTest, DoubleTap) {
WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureTapDown, kSourceDevice);
WebGestureEvent unconfirmed_tap = SyntheticWebGestureEventBuilder::Build(
@@ -778,29 +700,27 @@ TEST(TouchActionFilterTest, DoubleTap) {
WebInputEvent::kGestureDoubleTap, kSourceDevice);
// Double tap is disabled with any touch action other than auto.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionManipulation);
- EXPECT_EQ(filter.FilterGestureEvent(&tap_down),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionManipulation);
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&unconfirmed_tap),
+ EXPECT_EQ(filter_.FilterGestureEvent(&unconfirmed_tap),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(WebInputEvent::kGestureTap, unconfirmed_tap.GetType());
// Changing the touch action for the second tap doesn't effect the behaviour
// of the event. The tap cancel will come as part of the next touch sequence.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionAuto);
- EXPECT_EQ(filter.FilterGestureEvent(&tap_cancel),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_cancel),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&tap_down),
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&double_tap),
+ EXPECT_EQ(filter_.FilterGestureEvent(&double_tap),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(WebInputEvent::kGestureTap, double_tap.GetType());
}
-TEST(TouchActionFilterTest, SingleTapWithTouchActionAuto) {
- TouchActionFilter filter;
-
+TEST_F(TouchActionFilterTest, SingleTapWithTouchActionAuto) {
WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureTapDown, kSourceDevice);
WebGestureEvent unconfirmed_tap1 = SyntheticWebGestureEventBuilder::Build(
@@ -809,19 +729,18 @@ TEST(TouchActionFilterTest, SingleTapWithTouchActionAuto) {
WebInputEvent::kGestureTap, kSourceDevice);
// Single tap is allowed with touch action auto.
- filter.ResetTouchAction();
- EXPECT_EQ(filter.FilterGestureEvent(&tap_down),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&unconfirmed_tap1),
+ EXPECT_EQ(filter_.FilterGestureEvent(&unconfirmed_tap1),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(WebInputEvent::kGestureTapUnconfirmed, unconfirmed_tap1.GetType());
- EXPECT_EQ(filter.FilterGestureEvent(&tap),
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap),
FilterGestureEventResult::kFilterGestureEventAllowed);
}
-TEST(TouchActionFilterTest, SingleTap) {
- TouchActionFilter filter;
-
+TEST_F(TouchActionFilterTest, SingleTap) {
WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureTapDown, kSourceDevice);
WebGestureEvent unconfirmed_tap1 = SyntheticWebGestureEventBuilder::Build(
@@ -830,20 +749,20 @@ TEST(TouchActionFilterTest, SingleTap) {
WebInputEvent::kGestureTap, kSourceDevice);
// With touch action other than auto, tap unconfirmed is turned into tap.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&tap_down),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&unconfirmed_tap1),
+ EXPECT_EQ(filter_.FilterGestureEvent(&unconfirmed_tap1),
FilterGestureEventResult::kFilterGestureEventAllowed);
EXPECT_EQ(WebInputEvent::kGestureTap, unconfirmed_tap1.GetType());
- EXPECT_EQ(filter.FilterGestureEvent(&tap),
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap),
FilterGestureEventResult::kFilterGestureEventFiltered);
}
-TEST(TouchActionFilterTest, TouchActionResetsOnResetTouchAction) {
- TouchActionFilter filter;
-
+TEST_F(TouchActionFilterTest, TouchActionResetsOnResetTouchAction) {
+ WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::kGestureTapDown, kSourceDevice);
WebGestureEvent tap = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureTap, kSourceDevice);
WebGestureEvent scroll_begin =
@@ -851,26 +770,27 @@ TEST(TouchActionFilterTest, TouchActionResetsOnResetTouchAction) {
WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureScrollEnd, kSourceDevice);
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&tap),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap),
FilterGestureEventResult::kFilterGestureEventAllowed);
- filter.ResetTouchAction();
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
}
-TEST(TouchActionFilterTest, TouchActionResetMidSequence) {
- TouchActionFilter filter;
-
+TEST_F(TouchActionFilterTest, TouchActionResetMidSequence) {
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(2, 3, kSourceDevice);
WebGestureEvent pinch_begin = SyntheticWebGestureEventBuilder::Build(
@@ -883,95 +803,104 @@ TEST(TouchActionFilterTest, TouchActionResetMidSequence) {
WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
WebInputEvent::kGestureScrollEnd, kSourceDevice);
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
// Even though the allowed action is auto after the reset, the remaining
// scroll and pinch events should be suppressed.
- filter.ResetTouchAction();
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventFiltered);
// A new scroll and pinch sequence should be allowed.
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_begin),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
// Resetting from auto to auto mid-stream should have no effect.
- filter.ResetTouchAction();
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_update),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionAuto);
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_update),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&pinch_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&pinch_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_end),
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
FilterGestureEventResult::kFilterGestureEventAllowed);
}
-TEST(TouchActionFilterTest, ZeroVelocityFlingsConvertedToScrollEnd) {
- TouchActionFilter filter;
- const float kFlingX = 7;
- const float kFlingY = -4;
+// This test makes sure that we do not reset scrolling touch action in the
+// middle of a gesture sequence.
+TEST_F(TouchActionFilterTest, TouchActionNotResetWithinGestureSequence) {
+ filter_.OnHasTouchEventHandlers(true);
+ EXPECT_FALSE(filter_.allowed_touch_action().has_value());
+ filter_.OnSetTouchAction(cc::kTouchActionPanY);
- {
- // Scrolls hinted mostly in the Y axis will suppress flings with a
- // component solely on the X axis, converting them to a GestureScrollEnd.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionPanY);
- WebGestureEvent scroll_begin =
- SyntheticWebGestureEventBuilder::BuildScrollBegin(-6, 7, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
- FilterGestureEventResult::kFilterGestureEventAllowed);
+ WebGestureEvent tap_down = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::kGestureTapDown, kSourceDevice);
+ WebGestureEvent scroll_begin =
+ SyntheticWebGestureEventBuilder::BuildScrollBegin(1, 3, kSourceDevice);
+ WebGestureEvent scroll_update =
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(1, 5, 0,
+ kSourceDevice);
+ WebGestureEvent scroll_end = SyntheticWebGestureEventBuilder::Build(
+ WebInputEvent::kGestureScrollEnd, kSourceDevice);
- WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
- kFlingX, 0, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&fling_start),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(WebInputEvent::kGestureScrollEnd, fling_start.GetType());
- }
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_EQ(cc::kTouchActionPanY, ScrollingTouchAction().value());
- filter.ResetTouchAction();
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ // Simulate a touch sequence end by calling ReportAndResetTouchAction.
+ filter_.ReportAndResetTouchAction();
+ EXPECT_FALSE(filter_.allowed_touch_action().has_value());
+ EXPECT_EQ(cc::kTouchActionPanY, ScrollingTouchAction().value());
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ // The |allowed_touch_action_| should have been reset, but not the
+ // |scrolling_touch_action_|.
+ EXPECT_FALSE(filter_.allowed_touch_action().has_value());
+ EXPECT_EQ(cc::kTouchActionPanY, ScrollingTouchAction().value());
- {
- // Scrolls hinted mostly in the X axis will suppress flings with a
- // component solely on the Y axis, converting them to a GestureScrollEnd.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionPanX);
- WebGestureEvent scroll_begin =
- SyntheticWebGestureEventBuilder::BuildScrollBegin(-7, 6, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
- FilterGestureEventResult::kFilterGestureEventAllowed);
+ // In the fling boosting case, we won't get a TapDown after the previous GSE.
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_update),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_end),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
- WebGestureEvent fling_start = SyntheticWebGestureEventBuilder::BuildFling(
- 0, kFlingY, kSourceDevice);
- EXPECT_EQ(filter.FilterGestureEvent(&fling_start),
- FilterGestureEventResult::kFilterGestureEventAllowed);
- EXPECT_EQ(WebInputEvent::kGestureScrollEnd, fling_start.GetType());
- }
+ EXPECT_EQ(filter_.FilterGestureEvent(&tap_down),
+ FilterGestureEventResult::kFilterGestureEventAllowed);
+ EXPECT_TRUE(filter_.allowed_touch_action().has_value());
+ EXPECT_TRUE(ScrollingTouchAction().has_value());
}
-TEST(TouchActionFilterTest, TouchpadScroll) {
- TouchActionFilter filter;
-
+TEST_F(TouchActionFilterTest, TouchpadScroll) {
WebGestureEvent scroll_begin =
SyntheticWebGestureEventBuilder::BuildScrollBegin(
2, 3, blink::kWebGestureDeviceTouchpad);
// cc::kTouchActionNone filters out only touchscreen scroll events.
- filter.ResetTouchAction();
- filter.OnSetTouchAction(cc::kTouchActionNone);
- EXPECT_EQ(filter.FilterGestureEvent(&scroll_begin),
+ filter_.ResetTouchAction();
+ filter_.OnSetTouchAction(cc::kTouchActionNone);
+ EXPECT_EQ(filter_.FilterGestureEvent(&scroll_begin),
FilterGestureEventResult::kFilterGestureEventAllowed);
}
diff --git a/chromium/content/browser/renderer_host/input/touch_emulator.cc b/chromium/content/browser/renderer_host/input/touch_emulator.cc
index e8aa3c16478..bb6fb67ff9f 100644
--- a/chromium/content/browser/renderer_host/input/touch_emulator.cc
+++ b/chromium/content/browser/renderer_host/input/touch_emulator.cc
@@ -439,6 +439,10 @@ void TouchEmulator::OnGestureEvent(const ui::GestureEventData& gesture) {
}
}
+bool TouchEmulator::RequiresDoubleTapGestureEvents() const {
+ return true;
+}
+
void TouchEmulator::InjectTouchEvent(const blink::WebTouchEvent& event,
RenderWidgetHostViewBase* target_view,
base::OnceClosure callback) {
diff --git a/chromium/content/browser/renderer_host/input/touch_emulator.h b/chromium/content/browser/renderer_host/input/touch_emulator.h
index c419968b6ef..3ff06e2158b 100644
--- a/chromium/content/browser/renderer_host/input/touch_emulator.h
+++ b/chromium/content/browser/renderer_host/input/touch_emulator.h
@@ -88,6 +88,7 @@ class CONTENT_EXPORT TouchEmulator : public ui::GestureProviderClient {
private:
// ui::GestureProviderClient implementation.
void OnGestureEvent(const ui::GestureEventData& gesture) override;
+ bool RequiresDoubleTapGestureEvents() const override;
// Returns cursor size in DIP.
gfx::SizeF InitCursorFromResource(
diff --git a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
index 746afa48833..3b7ecd5a70f 100644
--- a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
+++ b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.cc
@@ -130,8 +130,7 @@ TouchSelectionControllerClientAura::TouchSelectionControllerClientAura(
FROM_HERE,
base::TimeDelta::FromMilliseconds(kQuickMenuDelayInMs),
base::Bind(&TouchSelectionControllerClientAura::ShowQuickMenu,
- base::Unretained(this)),
- false),
+ base::Unretained(this))),
quick_menu_requested_(false),
touch_down_(false),
scroll_in_progress_(false),
diff --git a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.h b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
index 791ee5a4d32..a18886536d5 100644
--- a/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
+++ b/chromium/content/browser/renderer_host/input/touch_selection_controller_client_aura.h
@@ -125,7 +125,7 @@ class CONTENT_EXPORT TouchSelectionControllerClientAura
base::ObserverList<TouchSelectionControllerClientManager::Observer>
observers_;
- base::Timer quick_menu_timer_;
+ base::RetainingOneShotTimer quick_menu_timer_;
bool quick_menu_requested_;
bool touch_down_;
bool scroll_in_progress_;
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 c6ee3bdf7c2..d8350f38862 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
@@ -19,6 +19,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/hit_test_region_observer.h"
#include "content/public/test/scoped_overscroll_modes.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
@@ -422,7 +423,7 @@ IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAuraSiteIsolationTest,
// The child will change with the cross-site navigation. It shouldn't change
// after this.
child = root->child_at(0);
- WaitForChildFrameSurfaceReady(child->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child->current_frame_host());
RenderWidgetHostViewChildFrame* child_view =
static_cast<RenderWidgetHostViewChildFrame*>(
@@ -529,7 +530,7 @@ IN_PROC_BROWSER_TEST_P(TouchSelectionControllerClientAuraSiteIsolationTest,
// The child will change with the cross-site navigation. It shouldn't change
// after this.
child = root->child_at(0);
- WaitForChildFrameSurfaceReady(child->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child->current_frame_host());
RenderWidgetHostViewChildFrame* child_view =
static_cast<RenderWidgetHostViewChildFrame*>(
@@ -1049,6 +1050,13 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAuraScaleFactorTest,
gfx::PointF point;
ASSERT_TRUE(GetPointInsideTextfield(&point));
+
+ ui::GestureEventDetails gesture_tap_down_details(ui::ET_GESTURE_TAP_DOWN);
+ gesture_tap_down_details.set_device_type(
+ ui::GestureDeviceType::DEVICE_TOUCHSCREEN);
+ ui::GestureEvent gesture_tap_down(2, 2, 0, ui::EventTimeForNow(),
+ gesture_tap_down_details);
+ rwhva->OnGestureEvent(&gesture_tap_down);
ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP);
tap_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHSCREEN);
tap_details.set_tap_count(1);
diff --git a/chromium/content/browser/renderer_host/input/touchpad_pinch_browsertest.cc b/chromium/content/browser/renderer_host/input/touchpad_pinch_browsertest.cc
new file mode 100644
index 00000000000..7111ab6ae9c
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/touchpad_pinch_browsertest.cc
@@ -0,0 +1,187 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/run_loop.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+
+namespace {
+
+const char kTouchpadPinchDataURL[] =
+ "data:text/html;charset=utf-8,"
+ "<!DOCTYPE html>"
+ "<style>"
+ "html,body {"
+ " height: 100%;"
+ "}"
+ "</style>"
+ "<p>Hello.</p>"
+ "<script>"
+ " var resolveHandlerPromise = null;"
+ " var handlerPromise = new Promise(function(resolve) {"
+ " resolveHandlerPromise = resolve;"
+ " });"
+ " function preventPinchListener(e) {"
+ " e.preventDefault();"
+ " resolveHandlerPromise(e);"
+ " }"
+ " function allowPinchListener(e) {"
+ " resolveHandlerPromise(e);"
+ " }"
+ " function setListener(prevent) {"
+ " document.body.addEventListener("
+ " 'wheel',"
+ " (prevent ? preventPinchListener : allowPinchListener),"
+ " {passive: false});"
+ " }"
+ " function reset() {"
+ " document.body.removeEventListener("
+ " 'wheel', preventPinchListener, {passive: false});"
+ " document.body.removeEventListener("
+ " 'wheel', allowPinchListener, {passive: false});"
+ " handlerPromise = new Promise(function(resolve) {"
+ " resolveHandlerPromise = resolve;"
+ " });"
+ " }"
+ "</script>";
+
+} // namespace
+
+namespace content {
+
+class TouchpadPinchBrowserTest : public ContentBrowserTest {
+ public:
+ TouchpadPinchBrowserTest() = default;
+ ~TouchpadPinchBrowserTest() override = default;
+
+ protected:
+ void LoadURL() {
+ const GURL data_url(kTouchpadPinchDataURL);
+ NavigateToURL(shell(), data_url);
+ SynchronizeThreads();
+ }
+
+ RenderWidgetHostImpl* GetRenderWidgetHost() {
+ return RenderWidgetHostImpl::From(shell()
+ ->web_contents()
+ ->GetRenderWidgetHostView()
+ ->GetRenderWidgetHost());
+ }
+
+ void SynchronizeThreads() {
+ MainThreadFrameObserver observer(GetRenderWidgetHost());
+ observer.Wait();
+ }
+};
+
+// Performing a touchpad pinch gesture should change the page scale.
+IN_PROC_BROWSER_TEST_F(TouchpadPinchBrowserTest,
+ TouchpadPinchChangesPageScale) {
+ LoadURL();
+
+ content::TestPageScaleObserver scale_observer(shell()->web_contents());
+
+ const gfx::Rect contents_rect = shell()->web_contents()->GetContainerBounds();
+ const gfx::Point pinch_position(contents_rect.width() / 2,
+ contents_rect.height() / 2);
+ SimulateGesturePinchSequence(shell()->web_contents(), pinch_position, 1.23,
+ blink::kWebGestureDeviceTouchpad);
+
+ scale_observer.WaitForPageScaleUpdate();
+}
+
+// We should offer synthetic wheel events to the page when a touchpad pinch
+// is performed.
+IN_PROC_BROWSER_TEST_F(TouchpadPinchBrowserTest, WheelListenerAllowingPinch) {
+ LoadURL();
+ ASSERT_TRUE(
+ content::ExecuteScript(shell()->web_contents(), "setListener(false);"));
+ SynchronizeThreads();
+
+ content::TestPageScaleObserver scale_observer(shell()->web_contents());
+
+ const gfx::Rect contents_rect = shell()->web_contents()->GetContainerBounds();
+ const gfx::Point pinch_position(contents_rect.width() / 2,
+ contents_rect.height() / 2);
+ SimulateGesturePinchSequence(shell()->web_contents(), pinch_position, 1.23,
+ blink::kWebGestureDeviceTouchpad);
+
+ // Ensure that the page saw the synthetic wheel.
+ bool default_prevented = false;
+ ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
+ shell()->web_contents(),
+ "handlerPromise.then(function(e) {"
+ " window.domAutomationController.send(e.defaultPrevented);"
+ "});",
+ &default_prevented));
+ EXPECT_FALSE(default_prevented);
+
+ // Since the listener did not cancel the synthetic wheel, we should still
+ // change the page scale.
+ scale_observer.WaitForPageScaleUpdate();
+}
+
+// If the synthetic wheel event for a touchpad pinch is canceled, we should not
+// change the page scale.
+IN_PROC_BROWSER_TEST_F(TouchpadPinchBrowserTest, WheelListenerPreventingPinch) {
+ LoadURL();
+
+ // Perform an initial pinch so we can figure out the page scale we're
+ // starting with for the test proper.
+ content::TestPageScaleObserver starting_scale_observer(
+ shell()->web_contents());
+ const gfx::Rect contents_rect = shell()->web_contents()->GetContainerBounds();
+ const gfx::Point pinch_position(contents_rect.width() / 2,
+ contents_rect.height() / 2);
+ SimulateGesturePinchSequence(shell()->web_contents(), pinch_position, 1.23,
+ blink::kWebGestureDeviceTouchpad);
+ const float starting_scale_factor =
+ starting_scale_observer.WaitForPageScaleUpdate();
+ ASSERT_GT(starting_scale_factor, 0.f);
+
+ ASSERT_TRUE(
+ content::ExecuteScript(shell()->web_contents(), "setListener(true);"));
+ SynchronizeThreads();
+
+ SimulateGesturePinchSequence(shell()->web_contents(), pinch_position, 1.5,
+ blink::kWebGestureDeviceTouchpad);
+
+ // Ensure the page handled a wheel event that it was able to cancel.
+ bool default_prevented = false;
+ ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
+ shell()->web_contents(),
+ "handlerPromise.then(function(e) {"
+ " window.domAutomationController.send(e.defaultPrevented);"
+ "});",
+ &default_prevented));
+ EXPECT_TRUE(default_prevented);
+
+ // We'll check that the previous pinch did not cause a scale change by
+ // performing another pinch that does change the scale.
+ ASSERT_TRUE(content::ExecuteScript(shell()->web_contents(),
+ "reset(); "
+ "setListener(false);"));
+ SynchronizeThreads();
+
+ content::TestPageScaleObserver scale_observer(shell()->web_contents());
+ SimulateGesturePinchSequence(shell()->web_contents(), pinch_position, 2.0,
+ blink::kWebGestureDeviceTouchpad);
+ ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
+ shell()->web_contents(),
+ "handlerPromise.then(function(e) {"
+ " window.domAutomationController.send(e.defaultPrevented);"
+ "});",
+ &default_prevented));
+ EXPECT_FALSE(default_prevented);
+
+ const float last_scale_factor = scale_observer.WaitForPageScaleUpdate();
+ EXPECT_FLOAT_EQ(starting_scale_factor * 2.0, last_scale_factor);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue.cc b/chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue.cc
new file mode 100644
index 00000000000..f0279ae7225
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue.cc
@@ -0,0 +1,161 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/touchpad_pinch_event_queue.h"
+
+#include "base/trace_event/trace_event.h"
+#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
+#include "ui/events/base_event_utils.h"
+#include "ui/events/blink/blink_event_util.h"
+#include "ui/latency/latency_info.h"
+
+namespace content {
+
+namespace {
+
+blink::WebMouseWheelEvent CreateSyntheticWheelFromTouchpadPinchEvent(
+ const blink::WebGestureEvent& pinch_event) {
+ DCHECK_EQ(blink::WebInputEvent::kGesturePinchUpdate, pinch_event.GetType());
+
+ // For pinch gesture events, similar to ctrl+wheel zooming, allow content to
+ // prevent the browser from zooming by sending fake wheel events with the ctrl
+ // modifier set when we see trackpad pinch gestures. Ideally we'd someday get
+ // a platform 'pinch' event and send that instead.
+ blink::WebMouseWheelEvent wheel_event(
+ blink::WebInputEvent::kMouseWheel,
+ pinch_event.GetModifiers() | blink::WebInputEvent::kControlKey,
+ pinch_event.TimeStamp());
+ wheel_event.SetPositionInWidget(pinch_event.PositionInWidget());
+ wheel_event.SetPositionInScreen(pinch_event.PositionInScreen());
+ wheel_event.delta_x = 0;
+
+ // The function to convert scales to deltaY values is designed to be
+ // compatible with websites existing use of wheel events, and with existing
+ // Windows trackpad behavior. In particular, we want:
+ // - deltas should accumulate via addition: f(s1*s2)==f(s1)+f(s2)
+ // - deltas should invert via negation: f(1/s) == -f(s)
+ // - zoom in should be positive: f(s) > 0 iff s > 1
+ // - magnitude roughly matches wheels: f(2) > 25 && f(2) < 100
+ // - a formula that's relatively easy to use from JavaScript
+ // Note that 'wheel' event deltaY values have their sign inverted. So to
+ // convert a wheel deltaY back to a scale use Math.exp(-deltaY/100).
+ DCHECK_GT(pinch_event.data.pinch_update.scale, 0);
+ wheel_event.delta_y = 100.0f * log(pinch_event.data.pinch_update.scale);
+ wheel_event.has_precise_scrolling_deltas = true;
+ wheel_event.wheel_ticks_x = 0;
+ wheel_event.wheel_ticks_y = pinch_event.data.pinch_update.scale > 1 ? 1 : -1;
+
+ return wheel_event;
+}
+
+} // namespace
+
+// This is a single queued pinch event to which we add trace events.
+class QueuedTouchpadPinchEvent : public GestureEventWithLatencyInfo {
+ public:
+ QueuedTouchpadPinchEvent(const GestureEventWithLatencyInfo& original_event)
+ : GestureEventWithLatencyInfo(original_event) {
+ TRACE_EVENT_ASYNC_BEGIN0("input", "TouchpadPinchEventQueue::QueueEvent",
+ this);
+ }
+
+ ~QueuedTouchpadPinchEvent() {
+ TRACE_EVENT_ASYNC_END0("input", "TouchpadPinchEventQueue::QueueEvent",
+ this);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(QueuedTouchpadPinchEvent);
+};
+
+TouchpadPinchEventQueue::TouchpadPinchEventQueue(
+ TouchpadPinchEventQueueClient* client)
+ : client_(client) {
+ DCHECK(client_);
+}
+
+TouchpadPinchEventQueue::~TouchpadPinchEventQueue() = default;
+
+void TouchpadPinchEventQueue::QueueEvent(
+ const GestureEventWithLatencyInfo& event) {
+ TRACE_EVENT0("input", "TouchpadPinchEventQueue::QueueEvent");
+
+ if (!pinch_queue_.empty()) {
+ QueuedTouchpadPinchEvent* last_event = pinch_queue_.back().get();
+ if (last_event->CanCoalesceWith(event)) {
+ // Terminate the LatencyInfo of the event before it gets coalesced away.
+ event.latency.Terminate();
+
+ last_event->CoalesceWith(event);
+ DCHECK_EQ(blink::WebInputEvent::kGesturePinchUpdate,
+ last_event->event.GetType());
+ TRACE_EVENT_INSTANT1("input",
+ "TouchpadPinchEventQueue::CoalescedPinchEvent",
+ TRACE_EVENT_SCOPE_THREAD, "scale",
+ last_event->event.data.pinch_update.scale);
+ return;
+ }
+ }
+
+ pinch_queue_.push_back(std::make_unique<QueuedTouchpadPinchEvent>(event));
+ TryForwardNextEventToRenderer();
+}
+
+void TouchpadPinchEventQueue::ProcessMouseWheelAck(
+ InputEventAckSource ack_source,
+ InputEventAckState ack_result,
+ const ui::LatencyInfo& latency_info) {
+ TRACE_EVENT0("input", "TouchpadPinchEventQueue::ProcessMouseWheelAck");
+ if (!pinch_event_awaiting_ack_)
+ return;
+
+ pinch_event_awaiting_ack_->latency.AddNewLatencyFrom(latency_info);
+ client_->OnGestureEventForPinchAck(*pinch_event_awaiting_ack_, ack_source,
+ ack_result);
+
+ pinch_event_awaiting_ack_.reset();
+ TryForwardNextEventToRenderer();
+}
+
+void TouchpadPinchEventQueue::TryForwardNextEventToRenderer() {
+ TRACE_EVENT0("input",
+ "TouchpadPinchEventQueue::TryForwardNextEventToRenderer");
+
+ if (pinch_queue_.empty() || pinch_event_awaiting_ack_)
+ return;
+
+ pinch_event_awaiting_ack_ = std::move(pinch_queue_.front());
+ pinch_queue_.pop_front();
+
+ if (pinch_event_awaiting_ack_->event.GetType() ==
+ blink::WebInputEvent::kGesturePinchBegin ||
+ pinch_event_awaiting_ack_->event.GetType() ==
+ blink::WebInputEvent::kGesturePinchEnd) {
+ // Wheel event listeners are given individual events with no phase
+ // information, so we don't need to do anything at the beginning or
+ // end of a pinch.
+ // TODO(565980): Consider sending the rest of the wheel events as
+ // non-blocking if the first wheel event of the pinch sequence is not
+ // consumed.
+ client_->OnGestureEventForPinchAck(*pinch_event_awaiting_ack_,
+ InputEventAckSource::BROWSER,
+ INPUT_EVENT_ACK_STATE_IGNORED);
+ pinch_event_awaiting_ack_.reset();
+ TryForwardNextEventToRenderer();
+ return;
+ }
+
+ const MouseWheelEventWithLatencyInfo synthetic_wheel(
+ CreateSyntheticWheelFromTouchpadPinchEvent(
+ pinch_event_awaiting_ack_->event),
+ pinch_event_awaiting_ack_->latency);
+
+ client_->SendMouseWheelEventForPinchImmediately(synthetic_wheel);
+}
+
+bool TouchpadPinchEventQueue::has_pending() const {
+ return !pinch_queue_.empty() || pinch_event_awaiting_ack_;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue.h b/chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue.h
new file mode 100644
index 00000000000..f7def2c8636
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue.h
@@ -0,0 +1,76 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_PINCH_EVENT_QUEUE_H_
+#define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_PINCH_EVENT_QUEUE_H_
+
+#include <memory>
+
+#include "base/containers/circular_deque.h"
+#include "content/common/content_export.h"
+#include "content/common/input/event_with_latency_info.h"
+#include "content/public/common/input_event_ack_source.h"
+#include "content/public/common/input_event_ack_state.h"
+#include "third_party/blink/public/platform/web_input_event.h"
+
+namespace ui {
+class LatencyInfo;
+} // namespace ui
+
+namespace content {
+
+class QueuedTouchpadPinchEvent;
+
+// Interface with which TouchpadPinchEventQueue can forward synthetic mouse
+// wheel events and notify of pinch events.
+class CONTENT_EXPORT TouchpadPinchEventQueueClient {
+ public:
+ virtual ~TouchpadPinchEventQueueClient() = default;
+
+ virtual void SendMouseWheelEventForPinchImmediately(
+ const MouseWheelEventWithLatencyInfo& event) = 0;
+ virtual void OnGestureEventForPinchAck(
+ const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
+ InputEventAckState ack_result) = 0;
+};
+
+// A queue for sending synthetic mouse wheel events for touchpad pinches.
+// In order for a page to prevent touchpad pinch zooming, we send synthetic
+// wheel events which may be cancelled. Once we've determined whether a page
+// has prevented the pinch, the TouchpadPinchEventQueueClient may proceed with
+// handling the pinch.
+// See README.md for further details.
+class CONTENT_EXPORT TouchpadPinchEventQueue {
+ public:
+ // The |client| must outlive the TouchpadPinchEventQueue.
+ TouchpadPinchEventQueue(TouchpadPinchEventQueueClient* client);
+ ~TouchpadPinchEventQueue();
+
+ // Adds the given touchpad pinch |event| to the queue. The event may be
+ // coalesced with previously queued events.
+ void QueueEvent(const GestureEventWithLatencyInfo& event);
+
+ // Notifies the queue that a synthetic mouse wheel event has been processed
+ // by the renderer.
+ void ProcessMouseWheelAck(InputEventAckSource ack_source,
+ InputEventAckState ack_result,
+ const ui::LatencyInfo& latency_info);
+
+ bool has_pending() const WARN_UNUSED_RESULT;
+
+ private:
+ void TryForwardNextEventToRenderer();
+
+ TouchpadPinchEventQueueClient* client_;
+
+ base::circular_deque<std::unique_ptr<QueuedTouchpadPinchEvent>> pinch_queue_;
+ std::unique_ptr<QueuedTouchpadPinchEvent> pinch_event_awaiting_ack_;
+
+ DISALLOW_COPY_AND_ASSIGN(TouchpadPinchEventQueue);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCHPAD_PINCH_EVENT_QUEUE_H_
diff --git a/chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue_unittest.cc b/chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue_unittest.cc
new file mode 100644
index 00000000000..73c6424a06e
--- /dev/null
+++ b/chromium/content/browser/renderer_host/input/touchpad_pinch_event_queue_unittest.cc
@@ -0,0 +1,350 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/touchpad_pinch_event_queue.h"
+
+#include <string>
+
+#include "content/common/input/event_with_latency_info.h"
+#include "content/public/common/input_event_ack_source.h"
+#include "content/public/common/input_event_ack_state.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/point_f.h"
+#include "ui/latency/latency_info.h"
+
+namespace content {
+
+class MockTouchpadPinchEventQueueClient : public TouchpadPinchEventQueueClient {
+ public:
+ MockTouchpadPinchEventQueueClient() = default;
+ ~MockTouchpadPinchEventQueueClient() override = default;
+
+ // TouchpadPinchEventQueueClient
+ MOCK_METHOD1(SendMouseWheelEventForPinchImmediately,
+ void(const MouseWheelEventWithLatencyInfo& event));
+ MOCK_METHOD3(OnGestureEventForPinchAck,
+ void(const GestureEventWithLatencyInfo& event,
+ InputEventAckSource ack_source,
+ InputEventAckState ack_result));
+};
+
+class TouchpadPinchEventQueueTest : public ::testing::Test {
+ protected:
+ TouchpadPinchEventQueueTest() : queue_(&mock_client_) {}
+ ~TouchpadPinchEventQueueTest() = default;
+
+ void QueueEvent(const blink::WebGestureEvent& event) {
+ queue_.QueueEvent(GestureEventWithLatencyInfo(event));
+ }
+
+ void QueuePinchBegin() {
+ blink::WebGestureEvent event(
+ blink::WebInputEvent::kGesturePinchBegin,
+ blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::GetStaticTimeStampForTests(),
+ blink::kWebGestureDeviceTouchpad);
+ event.SetPositionInWidget(gfx::PointF(1, 1));
+ event.SetPositionInScreen(gfx::PointF(1, 1));
+ event.SetNeedsWheelEvent(true);
+ QueueEvent(event);
+ }
+
+ void QueuePinchEnd() {
+ blink::WebGestureEvent event(
+ blink::WebInputEvent::kGesturePinchEnd,
+ blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::GetStaticTimeStampForTests(),
+ blink::kWebGestureDeviceTouchpad);
+ event.SetPositionInWidget(gfx::PointF(1, 1));
+ event.SetPositionInScreen(gfx::PointF(1, 1));
+ event.SetNeedsWheelEvent(true);
+ QueueEvent(event);
+ }
+
+ void QueuePinchUpdate(float scale, bool zoom_disabled) {
+ blink::WebGestureEvent event(
+ blink::WebInputEvent::kGesturePinchUpdate,
+ blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::GetStaticTimeStampForTests(),
+ blink::kWebGestureDeviceTouchpad);
+ event.SetPositionInWidget(gfx::PointF(1, 1));
+ event.SetPositionInScreen(gfx::PointF(1, 1));
+ event.SetNeedsWheelEvent(true);
+ event.data.pinch_update.zoom_disabled = zoom_disabled;
+ event.data.pinch_update.scale = scale;
+ QueueEvent(event);
+ }
+
+ void SendWheelEventAck(InputEventAckSource ack_source,
+ InputEventAckState ack_result) {
+ queue_.ProcessMouseWheelAck(ack_source, ack_result, ui::LatencyInfo());
+ }
+
+ testing::StrictMock<MockTouchpadPinchEventQueueClient> mock_client_;
+ TouchpadPinchEventQueue queue_;
+};
+
+MATCHER_P(EventHasType,
+ type,
+ std::string(negation ? "does not have" : "has") + " type " +
+ ::testing::PrintToString(type)) {
+ return arg.event.GetType() == type;
+}
+
+MATCHER(EventHasCtrlModifier,
+ std::string(negation ? "does not have" : "has") + " control modifier") {
+ return (arg.event.GetModifiers() & blink::WebInputEvent::kControlKey) != 0;
+}
+
+MATCHER(EventIsBlocking,
+ std::string(negation ? "is not" : "is") + " blocking") {
+ return arg.event.dispatch_type == blink::WebInputEvent::kBlocking;
+}
+
+// Ensure that when the queue receives a touchpad pinch sequence, it sends a
+// synthetic mouse wheel event and acks the pinch events back to the client.
+TEST_F(TouchpadPinchEventQueueTest, Basic) {
+ ::testing::InSequence sequence;
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchBegin),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+ EXPECT_CALL(mock_client_,
+ SendMouseWheelEventForPinchImmediately(
+ ::testing::AllOf(EventHasCtrlModifier(), EventIsBlocking())));
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchUpdate),
+ InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS));
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchEnd),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+
+ QueuePinchBegin();
+ QueuePinchUpdate(1.23, false);
+ SendWheelEventAck(InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ QueuePinchEnd();
+}
+
+// Ensure that if the renderer consumes the synthetic wheel event, the ack of
+// the GesturePinchUpdate reflects this.
+TEST_F(TouchpadPinchEventQueueTest, Consumed) {
+ ::testing::InSequence sequence;
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchBegin),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+ EXPECT_CALL(mock_client_,
+ SendMouseWheelEventForPinchImmediately(
+ ::testing::AllOf(EventHasCtrlModifier(), EventIsBlocking())));
+ EXPECT_CALL(
+ mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchUpdate),
+ InputEventAckSource::MAIN_THREAD, INPUT_EVENT_ACK_STATE_CONSUMED));
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchEnd),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+
+ QueuePinchBegin();
+ QueuePinchUpdate(1.23, false);
+ SendWheelEventAck(InputEventAckSource::MAIN_THREAD,
+ INPUT_EVENT_ACK_STATE_CONSUMED);
+ QueuePinchEnd();
+}
+
+// Ensure that the queue sends wheel events for updates with |zoom_disabled| as
+// well.
+TEST_F(TouchpadPinchEventQueueTest, ZoomDisabled) {
+ ::testing::InSequence sequence;
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchBegin),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+ EXPECT_CALL(mock_client_,
+ SendMouseWheelEventForPinchImmediately(
+ ::testing::AllOf(EventHasCtrlModifier(), EventIsBlocking())));
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchUpdate),
+ InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS));
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchEnd),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+
+ QueuePinchBegin();
+ QueuePinchUpdate(1.23, true);
+ SendWheelEventAck(InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ QueuePinchEnd();
+}
+
+TEST_F(TouchpadPinchEventQueueTest, MultipleSequences) {
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchBegin),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED))
+ .Times(2);
+ EXPECT_CALL(mock_client_, SendMouseWheelEventForPinchImmediately(testing::_))
+ .Times(2);
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchUpdate),
+ InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS))
+ .Times(2);
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchEnd),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED))
+ .Times(2);
+
+ QueuePinchBegin();
+ QueuePinchUpdate(1.23, false);
+ SendWheelEventAck(InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ QueuePinchEnd();
+
+ QueuePinchBegin();
+ QueuePinchUpdate(1.23, false);
+ SendWheelEventAck(InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ QueuePinchEnd();
+}
+
+// Ensure we can queue additional pinch event sequences while the queue is
+// waiting for a wheel event ack.
+TEST_F(TouchpadPinchEventQueueTest, MultipleQueuedSequences) {
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchBegin),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+ EXPECT_CALL(mock_client_, SendMouseWheelEventForPinchImmediately(testing::_));
+ QueuePinchBegin();
+ QueuePinchUpdate(1.23, false);
+
+ testing::Mock::VerifyAndClearExpectations(&mock_client_);
+
+ QueuePinchEnd();
+
+ QueuePinchBegin();
+ QueuePinchUpdate(1.23, false);
+ QueuePinchEnd();
+
+ // No calls since we're still waiting on the ack for the first wheel event.
+ testing::Mock::VerifyAndClearExpectations(&mock_client_);
+
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchUpdate),
+ InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS));
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchEnd),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchBegin),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+ EXPECT_CALL(mock_client_, SendMouseWheelEventForPinchImmediately(testing::_));
+ SendWheelEventAck(InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+
+ // After acking the first wheel event, the queue continues.
+ testing::Mock::VerifyAndClearExpectations(&mock_client_);
+
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchUpdate),
+ InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS));
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchEnd),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+ SendWheelEventAck(InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+}
+
+// Ensure the queue handles pinch event sequences with multiple updates.
+TEST_F(TouchpadPinchEventQueueTest, MultipleUpdatesInSequence) {
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchBegin),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+ EXPECT_CALL(mock_client_,
+ SendMouseWheelEventForPinchImmediately(EventHasCtrlModifier()))
+ .Times(3);
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchUpdate),
+ InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS))
+ .Times(3);
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchEnd),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+
+ QueuePinchBegin();
+ QueuePinchUpdate(1.23, false);
+ SendWheelEventAck(InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ QueuePinchUpdate(1.23, false);
+ SendWheelEventAck(InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ QueuePinchUpdate(1.23, false);
+ SendWheelEventAck(InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ QueuePinchEnd();
+}
+
+// Ensure the queue coalesces pinch update events.
+TEST_F(TouchpadPinchEventQueueTest, MultipleUpdatesCoalesced) {
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchBegin),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+ EXPECT_CALL(mock_client_,
+ SendMouseWheelEventForPinchImmediately(EventHasCtrlModifier()))
+ .Times(2);
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchUpdate),
+ InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS))
+ .Times(2);
+ EXPECT_CALL(mock_client_,
+ OnGestureEventForPinchAck(
+ EventHasType(blink::WebInputEvent::kGesturePinchEnd),
+ InputEventAckSource::BROWSER, INPUT_EVENT_ACK_STATE_IGNORED));
+
+ QueuePinchBegin();
+ // The queue will send the first wheel event for this first update.
+ QueuePinchUpdate(1.23, false);
+ // Before the first wheel event is acked, queue another update.
+ QueuePinchUpdate(1.23, false);
+ // Queue a third update. This will be coalesced with the second update which
+ // is currently in the queue.
+ QueuePinchUpdate(1.23, false);
+ QueuePinchEnd();
+
+ // Ack for the wheel event corresponding to the first update.
+ SendWheelEventAck(InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ // Ack for the wheel event corresponding to the second and third updates.
+ SendWheelEventAck(InputEventAckSource::COMPOSITOR_THREAD,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ EXPECT_FALSE(queue_.has_pending());
+}
+
+} // namespace content
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 f2f2b661322..be7624b1be3 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
@@ -536,8 +536,12 @@ blink::WebGestureEvent WebGestureEventBuilder::Build(NSEvent* event,
switch ([event type]) {
case NSEventTypeMagnify:
+ // We don't need to set the type based on |[event phase]| as the caller
+ // must set the begin and end types in order to support older Mac
+ // versions.
result.SetType(blink::WebInputEvent::kGesturePinchUpdate);
result.data.pinch_update.scale = [event magnification] + 1.0;
+ result.SetNeedsWheelEvent(true);
break;
case NSEventTypeSmartMagnify:
// Map the Cocoa "double-tap with two fingers" zoom gesture to regular
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 0aed4733809..c2dfa603d1b 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
@@ -3,12 +3,10 @@
// found in the LICENSE file.
#include "base/run_loop.h"
-#include "base/test/scoped_feature_list.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
-#include "content/public/common/content_features.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
@@ -29,62 +27,52 @@ void GiveItSomeTime() {
run_loop.Run();
}
-const char kWheelEventLatchingDataURL[] =
- "data:text/html;charset=utf-8,"
- "<!DOCTYPE html>"
- "<meta name='viewport' content='width=device-width, minimum-scale=1'>"
- "<style>"
- "body {"
- " height: 10000px;"
- "}"
- "%23scrollableDiv {"
- " position: absolute;"
- " left: 50px;"
- " top: 100px;"
- " width: 200px;"
- " height: 200px;"
- " overflow: scroll;"
- " background: red;"
- "}"
- "%23nestedDiv {"
- " width: 200px;"
- " height: 8000px;"
- " opacity: 0;"
- "}"
- "</style>"
- "<div id='scrollableDiv'>"
- " <div id='nestedDiv'></div>"
- "</div>"
- "<script>"
- " var scrollableDiv = document.getElementById('scrollableDiv');"
- " var scrollableDivWheelEventCounter = 0;"
- " var documentWheelEventCounter = 0;"
- " scrollableDiv.addEventListener('wheel',"
- " function(e) { scrollableDivWheelEventCounter++;"
- " e.stopPropagation(); });"
- " document.scrollingElement.addEventListener('wheel',"
- " function(e) { documentWheelEventCounter++; });"
- "</script>";
-
-enum WheelScrollingMode {
- kWheelScrollingModeNone,
- kWheelScrollLatching,
- kAsyncWheelEvents,
-};
+const char kWheelEventLatchingDataURL[] = R"HTML(
+ data:text/html;charset=utf-8,
+ <!DOCTYPE html>
+ <meta name='viewport' content='width=device-width, minimum-scale=1'>
+ <style>
+ body {
+ height: 10000px;
+ }
+ %23scrollableDiv {
+ position: absolute;
+ left: 50px;
+ top: 100px;
+ width: 200px;
+ height: 200px;
+ overflow: scroll;
+ background: red;
+ }
+ %23nestedDiv {
+ width: 200px;
+ height: 8000px;
+ opacity: 0;
+ }
+ </style>
+ <div id='scrollableDiv'>
+ <div id='nestedDiv'></div>
+ </div>
+ <script>
+ var scrollableDiv = document.getElementById('scrollableDiv');
+ var scrollableDivWheelEventCounter = 0;
+ var documentWheelEventCounter = 0;
+ scrollableDiv.addEventListener('wheel',
+ function(e) {
+ scrollableDivWheelEventCounter++;
+ e.stopPropagation();
+ });
+ document.scrollingElement.addEventListener('wheel',
+ function(e) { documentWheelEventCounter++; });
+ </script>)HTML";
} // namespace
namespace content {
class WheelScrollLatchingBrowserTest : public ContentBrowserTest {
public:
- WheelScrollLatchingBrowserTest(
- WheelScrollingMode wheel_scrolling_mode = kWheelScrollLatching)
- : wheel_scrolling_mode_(wheel_scrolling_mode),
- wheel_scroll_latching_enabled_(wheel_scrolling_mode_ !=
- kWheelScrollingModeNone) {
+ WheelScrollLatchingBrowserTest() {
ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
0);
-
- SetFeatureList();
}
~WheelScrollLatchingBrowserTest() override {}
@@ -110,8 +98,8 @@ class WheelScrollLatchingBrowserTest : public ContentBrowserTest {
->GetView());
}
- void LoadURL() {
- const GURL data_url(kWheelEventLatchingDataURL);
+ void LoadURL(const std::string& page_data) {
+ const GURL data_url("data:text/html," + page_data);
NavigateToURL(shell(), data_url);
RenderWidgetHostImpl* host = GetWidgetHost();
@@ -139,49 +127,16 @@ class WheelScrollLatchingBrowserTest : public ContentBrowserTest {
shell(), "domAutomationController.send(" + script + ")", &value));
return value;
}
- void SetFeatureList() {
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- feature_list_.InitWithFeatures({features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents},
- {});
- } else if (wheel_scrolling_mode_ == kWheelScrollLatching) {
- feature_list_.InitWithFeatures(
- {features::kTouchpadAndWheelScrollLatching},
- {features::kAsyncWheelEvents});
- } else if (wheel_scrolling_mode_ == kWheelScrollingModeNone) {
- feature_list_.InitWithFeatures({},
- {features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents});
- }
- }
-
- void WheelEventTargetTest();
- void WheelEventRetargetWhenTargetRemovedTest();
- void WheelScrollingRelatchWhenLatchedScrollerRemovedTest();
-
- private:
- base::test::ScopedFeatureList feature_list_;
- WheelScrollingMode wheel_scrolling_mode_;
- bool wheel_scroll_latching_enabled_;
};
-class WheelScrollLatchingDisabledBrowserTest
- : public WheelScrollLatchingBrowserTest {
- public:
- WheelScrollLatchingDisabledBrowserTest()
- : WheelScrollLatchingBrowserTest(kWheelScrollingModeNone) {}
- ~WheelScrollLatchingDisabledBrowserTest() override {}
-};
-
-class AsyncWheelEventsBrowserTest : public WheelScrollLatchingBrowserTest {
- public:
- AsyncWheelEventsBrowserTest()
- : WheelScrollLatchingBrowserTest(kAsyncWheelEvents) {}
- ~AsyncWheelEventsBrowserTest() override {}
-};
-
-void WheelScrollLatchingBrowserTest::WheelEventTargetTest() {
- LoadURL();
+// Start scrolling by mouse wheel on the document: the wheel event will be sent
+// to the document's scrolling element, the scrollable div will be under the
+// cursor after applying the scrolling. Continue scrolling by mouse wheel, since
+// wheel scroll latching is enabled the wheel event will be still sent to the
+// document's scrolling element and the document's scrolling element will
+// continue scrolling.
+IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest, WheelEventTarget) {
+ LoadURL(kWheelEventLatchingDataURL);
EXPECT_EQ(0, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
@@ -226,63 +181,18 @@ void WheelScrollLatchingBrowserTest::WheelEventTargetTest() {
GetRouter()->RouteMouseWheelEvent(GetRootView(), &wheel_event,
ui::LatencyInfo());
- if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- // Runs until we get the InputMsgAck callback.
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
- input_msg_watcher->WaitForAck());
- }
-
- if (wheel_scroll_latching_enabled_) {
- while (ExecuteScriptAndExtractDouble(
- "document.scrollingElement.scrollTop") < -2 * delta_y) {
- frame_observer.Wait();
- }
-
- EXPECT_EQ(0, ExecuteScriptAndExtractDouble("scrollableDiv.scrollTop"));
- EXPECT_EQ(2, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
- EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
- } else { // !wheel_scroll_latching_enabled_
- while (ExecuteScriptAndExtractDouble("scrollableDiv.scrollTop") <
- -delta_y)
- frame_observer.Wait();
-
- EXPECT_EQ(1, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
- EXPECT_EQ(1,
- ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
- }
+ while (ExecuteScriptAndExtractDouble("document.scrollingElement.scrollTop") <
+ -2 * delta_y) {
+ frame_observer.Wait();
}
-// Start scrolling by mouse wheel on the document: the wheel event will be sent
-// to the document's scrolling element, the scrollable div will be under the
-// cursor after applying the scrolling. Continue scrolling by mouse wheel, since
-// wheel scroll latching is enabled the wheel event will be still sent to the
-// document's scrolling element and the document's scrolling element will
-// continue scrolling.
-IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest, WheelEventTarget) {
- WheelEventTargetTest();
-}
-IN_PROC_BROWSER_TEST_F(AsyncWheelEventsBrowserTest, WheelEventTarget) {
- WheelEventTargetTest();
-}
-
-// Start scrolling by mouse wheel on the document: the wheel event will be sent
-// to the document's scrolling element, the scrollable div will be under the
-// cursor after applying the scrolloffsets. Continue scrolling by mouse wheel,
-// since wheel scroll latching is disabled the wheel event will be still sent to
-// the scrollable div which is currently under the cursor. The div will start
-// scrolling.
-IN_PROC_BROWSER_TEST_F(WheelScrollLatchingDisabledBrowserTest,
- WheelEventTarget) {
- WheelEventTargetTest();
+ EXPECT_EQ(0, ExecuteScriptAndExtractDouble("scrollableDiv.scrollTop"));
+ EXPECT_EQ(2, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
+ EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
}
-// Tests that wheel events are retargeted if their target gets deleted in the
-// middle of scrolling.
-void WheelScrollLatchingBrowserTest::WheelEventRetargetWhenTargetRemovedTest() {
- // The test is valid only when wheel scroll latching is enabled.
- if (!wheel_scroll_latching_enabled_)
- return;
-
- LoadURL();
+IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest,
+ WheelEventRetargetWhenTargetRemoved) {
+ LoadURL(kWheelEventLatchingDataURL);
EXPECT_EQ(0, ExecuteScriptAndExtractInt("documentWheelEventCounter"));
EXPECT_EQ(0, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
@@ -332,14 +242,6 @@ void WheelScrollLatchingBrowserTest::WheelEventRetargetWhenTargetRemovedTest() {
EXPECT_EQ(1, ExecuteScriptAndExtractInt("scrollableDivWheelEventCounter"));
}
-IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest,
- WheelEventRetargetWhenTargetRemoved) {
- WheelEventRetargetWhenTargetRemovedTest();
-}
-IN_PROC_BROWSER_TEST_F(AsyncWheelEventsBrowserTest,
- WheelEventRetargetWhenTargetRemoved) {
- WheelEventRetargetWhenTargetRemovedTest();
-}
// crbug.com/777258 Flaky on Android.
#if defined(OS_ANDROID)
@@ -349,13 +251,9 @@ IN_PROC_BROWSER_TEST_F(AsyncWheelEventsBrowserTest,
#define MAYBE_WheelScrollingRelatchWhenLatchedScrollerRemoved \
WheelScrollingRelatchWhenLatchedScrollerRemoved
#endif
-void WheelScrollLatchingBrowserTest::
- WheelScrollingRelatchWhenLatchedScrollerRemovedTest() {
- // The test is valid only when wheel scroll latching is enabled.
- if (!wheel_scroll_latching_enabled_)
- return;
-
- LoadURL();
+IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest,
+ MAYBE_WheelScrollingRelatchWhenLatchedScrollerRemoved) {
+ LoadURL(kWheelEventLatchingDataURL);
EXPECT_EQ(
ExecuteScriptAndExtractDouble("document.scrollingElement.scrollTop"), 0);
EXPECT_EQ(ExecuteScriptAndExtractDouble("scrollableDiv.scrollTop"), 0);
@@ -414,13 +312,83 @@ void WheelScrollLatchingBrowserTest::
GiveItSomeTime();
}
}
+
+const char kWheelRetargetIfPreventedByDefault[] = R"HTML(
+ data:text/html;charset=utf-8,
+ <!DOCTYPE html>
+ <meta name='viewport' content='width=device-width, minimum-scale=1'>
+ <style>
+ %23blueDiv {
+ position: absolute;
+ left: 50px;
+ top: 100px;
+ width: 200px;
+ height: 200px;
+ display: block;
+ background: blue;
+ }
+ %23redDiv {
+ width: 200px;
+ height: 200px;
+ display: none;
+ background: red;
+ }
+ </style>
+ <body>
+ <div id='blueDiv'>
+ <div id='redDiv'></div>
+ </div>
+ </body>
+ <script>
+ var blueDiv = document.getElementById('blueDiv');
+ var redDiv = document.getElementById('redDiv');
+ var domTarget = 'noTarget';
+ var x = (blueDiv.getBoundingClientRect().left +
+ blueDiv.getBoundingClientRect().right) / 2;
+ var y = (blueDiv.getBoundingClientRect().top +
+ blueDiv.getBoundingClientRect().bottom) /2;
+ blueDiv.addEventListener('wheel', function(e) {
+ e.preventDefault();
+ domTarget = 'blueDiv';
+ redDiv.style.display = 'block';
+ });
+ redDiv.addEventListener('wheel', function(e) {
+ domTarget = 'redDiv';
+ e.stopPropagation();
+ });
+ </script>)HTML";
+
IN_PROC_BROWSER_TEST_F(WheelScrollLatchingBrowserTest,
- MAYBE_WheelScrollingRelatchWhenLatchedScrollerRemoved) {
- WheelScrollingRelatchWhenLatchedScrollerRemovedTest();
-}
-IN_PROC_BROWSER_TEST_F(AsyncWheelEventsBrowserTest,
- MAYBE_WheelScrollingRelatchWhenLatchedScrollerRemoved) {
- WheelScrollingRelatchWhenLatchedScrollerRemovedTest();
+ WheelEventRetargetOnPreventDefault) {
+ LoadURL(kWheelRetargetIfPreventedByDefault);
+
+ float x = ExecuteScriptAndExtractDouble("x");
+ float y = ExecuteScriptAndExtractDouble("y");
+
+ // Send the first wheel event.
+ auto wheel_msg_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kMouseWheel);
+ blink::WebMouseWheelEvent wheel_event =
+ SyntheticWebMouseWheelEventBuilder::Build(x, y, x, y, 1, 1, 0, true);
+ wheel_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
+ GetRouter()->RouteMouseWheelEvent(GetRootView(), &wheel_event,
+ ui::LatencyInfo());
+
+ // Run until we get the callback, then check the target.
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, wheel_msg_watcher->WaitForAck());
+ EXPECT_EQ("blueDiv", ExecuteScriptAndExtractString("domTarget"));
+
+ // Send the second wheel event.
+ wheel_msg_watcher = std::make_unique<InputMsgWatcher>(
+ GetWidgetHost(), blink::WebInputEvent::kMouseWheel);
+ wheel_event.phase = blink::WebMouseWheelEvent::kPhaseChanged;
+ GetRouter()->RouteMouseWheelEvent(GetRootView(), &wheel_event,
+ ui::LatencyInfo());
+
+ // Run until we get the callback, then check the target.
+ EXPECT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
+ wheel_msg_watcher->WaitForAck());
+ EXPECT_EQ("redDiv", ExecuteScriptAndExtractString("domTarget"));
}
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/audio_input_stream_handle.cc b/chromium/content/browser/renderer_host/media/audio_input_stream_handle.cc
index b92446bd173..159b776860a 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_stream_handle.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_stream_handle.cc
@@ -56,8 +56,9 @@ void AudioInputStreamHandle::SetOutputDeviceForAec(
stream_.SetOutputDeviceForAec(raw_output_device_id);
}
-void AudioInputStreamHandle::OnCreated(media::mojom::AudioDataPipePtr data_pipe,
- bool initially_muted) {
+void AudioInputStreamHandle::OnCreated(
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
+ bool initially_muted) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(client_);
DCHECK(deleter_callback_)
diff --git a/chromium/content/browser/renderer_host/media/audio_input_stream_handle.h b/chromium/content/browser/renderer_host/media/audio_input_stream_handle.h
index 0a30e0085d2..c36e892dc87 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_stream_handle.h
+++ b/chromium/content/browser/renderer_host/media/audio_input_stream_handle.h
@@ -37,7 +37,7 @@ class CONTENT_EXPORT AudioInputStreamHandle {
void SetOutputDeviceForAec(const std::string& raw_output_device_id);
private:
- void OnCreated(media::mojom::AudioDataPipePtr, bool initially_muted);
+ void OnCreated(media::mojom::ReadOnlyAudioDataPipePtr, bool initially_muted);
void CallDeleter();
diff --git a/chromium/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc b/chromium/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc
index 90be42dc659..a843d538ebf 100644
--- a/chromium/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_input_stream_handle_unittest.cc
@@ -49,7 +49,7 @@ class MockRendererAudioInputStreamFactoryClient
void StreamCreated(
media::mojom::AudioInputStreamPtr input_stream,
media::mojom::AudioInputStreamClientRequest client_request,
- media::mojom::AudioDataPipePtr data_pipe,
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
bool initially_muted,
const base::Optional<base::UnguessableToken>& stream_id) override {
EXPECT_TRUE(stream_id.has_value());
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 1b601ac380f..239c8be2a1e 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
@@ -253,10 +253,10 @@ void AudioOutputAuthorizationHandler::AccessChecked(
devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
media_stream_manager_->media_devices_manager()->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&AudioOutputAuthorizationHandler::TranslateDeviceID,
- weak_factory_.GetWeakPtr(), base::Passed(&trace_scope),
- base::Passed(&cb), device_id, std::move(salt),
- std::move(security_origin)));
+ base::BindOnce(&AudioOutputAuthorizationHandler::TranslateDeviceID,
+ weak_factory_.GetWeakPtr(), base::Passed(&trace_scope),
+ base::Passed(&cb), device_id, std::move(salt),
+ std::move(security_origin)));
}
void AudioOutputAuthorizationHandler::TranslateDeviceID(
diff --git a/chromium/content/browser/renderer_host/media/audio_service_listener.cc b/chromium/content/browser/renderer_host/media/audio_service_listener.cc
index 08157dce240..a97377898da 100644
--- a/chromium/content/browser/renderer_host/media/audio_service_listener.cc
+++ b/chromium/content/browser/renderer_host/media/audio_service_listener.cc
@@ -6,12 +6,16 @@
#include <utility>
+#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/default_tick_clock.h"
+#include "content/browser/media/audio_log_factory.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/child_process_termination_info.h"
+#include "content/public/common/content_features.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/audio/public/mojom/constants.mojom.h"
+#include "services/audio/public/mojom/log_factory_manager.mojom.h"
namespace content {
@@ -88,14 +92,15 @@ void AudioServiceListener::Metrics::LogServiceStartStatus(
AudioServiceListener::AudioServiceListener(
std::unique_ptr<service_manager::Connector> connector)
: binding_(this),
+ connector_(std::move(connector)),
metrics_(base::DefaultTickClock::GetInstance()) {
DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
- if (!connector)
+ if (!connector_)
return; // Happens in unittests.
service_manager::mojom::ServiceManagerPtr service_manager;
- connector->BindInterface(service_manager::mojom::kServiceName,
- &service_manager);
+ connector_->BindInterface(service_manager::mojom::kServiceName,
+ &service_manager);
service_manager::mojom::ServiceManagerListenerPtr listener;
service_manager::mojom::ServiceManagerListenerRequest request(
mojo::MakeRequest(&listener));
@@ -123,6 +128,7 @@ void AudioServiceListener::OnInit(
if (instance->identity.name() == audio::mojom::kServiceName) {
process_id_ = instance->pid;
metrics_.ServiceAlreadyRunning();
+ MaybeSetLogFactory();
break;
}
}
@@ -134,6 +140,7 @@ void AudioServiceListener::OnServiceCreated(
if (service->identity.name() != audio::mojom::kServiceName)
return;
metrics_.ServiceCreated();
+ MaybeSetLogFactory();
}
void AudioServiceListener::OnServiceStarted(
@@ -169,6 +176,7 @@ void AudioServiceListener::OnServiceStopped(
if (identity.name() != audio::mojom::kServiceName)
return;
metrics_.ServiceStopped();
+ log_factory_is_set_ = false;
}
void AudioServiceListener::BrowserChildProcessHostDisconnected(
@@ -203,4 +211,20 @@ void AudioServiceListener::BrowserChildProcessKilled(
Metrics::ServiceProcessTerminationStatus::kKill);
}
+void AudioServiceListener::MaybeSetLogFactory() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
+ if (!base::FeatureList::IsEnabled(features::kAudioServiceOutOfProcess) ||
+ !connector_ || log_factory_is_set_)
+ return;
+
+ media::mojom::AudioLogFactoryPtr audio_log_factory_ptr;
+ mojo::MakeStrongBinding(std::make_unique<AudioLogFactory>(),
+ mojo::MakeRequest(&audio_log_factory_ptr));
+ audio::mojom::LogFactoryManagerPtr log_factory_manager_ptr;
+ connector_->BindInterface(audio::mojom::kServiceName,
+ mojo::MakeRequest(&log_factory_manager_ptr));
+ log_factory_manager_ptr->SetLogFactory(std::move(audio_log_factory_ptr));
+ log_factory_is_set_ = true;
+}
+
} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/audio_service_listener.h b/chromium/content/browser/renderer_host/media/audio_service_listener.h
index 60623985912..41942d5bda5 100644
--- a/chromium/content/browser/renderer_host/media/audio_service_listener.h
+++ b/chromium/content/browser/renderer_host/media/audio_service_listener.h
@@ -116,9 +116,13 @@ class CONTENT_EXPORT AudioServiceListener
void BrowserChildProcessKilled(const ChildProcessData& data,
const ChildProcessTerminationInfo& info) final;
+ void MaybeSetLogFactory();
+
mojo::Binding<service_manager::mojom::ServiceManagerListener> binding_;
+ std::unique_ptr<service_manager::Connector> connector_;
base::ProcessId process_id_ = base::kNullProcessId;
Metrics metrics_;
+ bool log_factory_is_set_ = false;
SEQUENCE_CHECKER(owning_sequence_);
DISALLOW_COPY_AND_ASSIGN(AudioServiceListener);
diff --git a/chromium/content/browser/renderer_host/media/audio_service_listener_unittest.cc b/chromium/content/browser/renderer_host/media/audio_service_listener_unittest.cc
index 2afcfb7833b..d6a66a9d5b4 100644
--- a/chromium/content/browser/renderer_host/media/audio_service_listener_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/audio_service_listener_unittest.cc
@@ -7,7 +7,7 @@
#include <utility>
#include "base/process/kill.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_tick_clock.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/browser/child_process_termination_info.h"
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
index 5874c901f67..cad67364595 100644
--- 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
@@ -78,6 +78,7 @@ void FakeVideoCaptureDeviceLauncher::LaunchDeviceAsync(
std::make_unique<media::VideoCaptureBufferTrackerFactoryImpl>(),
kMaxBufferCount));
auto device_client = std::make_unique<media::VideoCaptureDeviceClient>(
+ media::VideoCaptureBufferType::kSharedMemory,
std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
receiver, base::ThreadTaskRunnerHandle::Get()),
std::move(buffer_pool), std::move(empty_jpeg_decoder_factory_cb));
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 3e68e40eed4..77742e8cd19 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
@@ -9,13 +9,14 @@
#include "build/build_config.h"
#include "content/browser/renderer_host/media/in_process_launched_video_capture_device.h"
#include "content/browser/renderer_host/media/video_capture_controller.h"
-#include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h"
+#include "content/browser/renderer_host/media/video_capture_dependencies.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/media_stream_request.h"
#include "media/base/bind_to_current_loop.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_impl.h"
#include "media/capture/video/video_frame_receiver.h"
#include "media/capture/video/video_frame_receiver_on_task_runner.h"
@@ -38,7 +39,11 @@ namespace {
std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb,
base::Callback<void(const std::string&)> send_log_message_cb) {
- return std::make_unique<content::VideoCaptureGpuJpegDecoder>(
+ return std::make_unique<media::VideoCaptureJpegDecoderImpl>(
+ base::BindRepeating(
+ &content::VideoCaptureDependencies::CreateJpegDecodeAccelerator),
+ content::BrowserThread::GetTaskRunnerForThread(
+ content::BrowserThread::IO),
std::move(decode_done_cb), std::move(send_log_message_cb));
}
@@ -109,7 +114,8 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
&InProcessVideoCaptureDeviceLauncher::
DoStartDeviceCaptureOnDeviceThread,
base::Unretained(this), device_id, params,
- CreateDeviceClient(kMaxNumberOfBuffers, std::move(receiver),
+ CreateDeviceClient(media::VideoCaptureBufferType::kSharedMemory,
+ kMaxNumberOfBuffers, std::move(receiver),
std::move(receiver_on_io_thread)),
std::move(after_start_capture_callback));
break;
@@ -176,7 +182,8 @@ void InProcessVideoCaptureDeviceLauncher::LaunchDeviceAsync(
&InProcessVideoCaptureDeviceLauncher::
DoStartDesktopCaptureOnDeviceThread,
base::Unretained(this), desktop_id, params,
- CreateDeviceClient(kMaxNumberOfBuffers, std::move(receiver),
+ CreateDeviceClient(media::VideoCaptureBufferType::kSharedMemory,
+ kMaxNumberOfBuffers, std::move(receiver),
std::move(receiver_on_io_thread)),
std::move(after_start_capture_callback));
break;
@@ -202,6 +209,7 @@ void InProcessVideoCaptureDeviceLauncher::AbortLaunch() {
std::unique_ptr<media::VideoCaptureDeviceClient>
InProcessVideoCaptureDeviceLauncher::CreateDeviceClient(
+ media::VideoCaptureBufferType requested_buffer_type,
int buffer_pool_max_buffer_count,
std::unique_ptr<media::VideoFrameReceiver> receiver,
base::WeakPtr<media::VideoFrameReceiver> receiver_on_io_thread) {
@@ -213,7 +221,7 @@ InProcessVideoCaptureDeviceLauncher::CreateDeviceClient(
buffer_pool_max_buffer_count);
return std::make_unique<media::VideoCaptureDeviceClient>(
- std::move(receiver), std::move(buffer_pool),
+ requested_buffer_type, std::move(receiver), std::move(buffer_pool),
base::BindRepeating(
&CreateGpuJpegDecoder,
base::BindRepeating(&media::VideoFrameReceiver::OnFrameReadyInBuffer,
diff --git a/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.h b/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.h
index b2919080aff..ce862c58484 100644
--- a/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.h
+++ b/chromium/content/browser/renderer_host/media/in_process_video_capture_device_launcher.h
@@ -51,6 +51,7 @@ class InProcessVideoCaptureDeviceLauncher : public VideoCaptureDeviceLauncher {
};
std::unique_ptr<media::VideoCaptureDeviceClient> CreateDeviceClient(
+ media::VideoCaptureBufferType requested_buffer_type,
int buffer_pool_max_buffer_count,
std::unique_ptr<media::VideoFrameReceiver> receiver,
base::WeakPtr<media::VideoFrameReceiver> receiver_on_io_thread);
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 6818c2288c5..c87ff868818 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
@@ -36,15 +36,18 @@ std::vector<blink::mojom::AudioInputDeviceCapabilitiesPtr>
ToVectorAudioInputDeviceCapabilitiesPtr(
const std::vector<blink::mojom::AudioInputDeviceCapabilities>&
capabilities_vector,
- const url::Origin& security_origin,
- const std::string& salt) {
+ const MediaDeviceSaltAndOrigin& salt_and_origin) {
std::vector<blink::mojom::AudioInputDeviceCapabilitiesPtr> result;
result.reserve(capabilities_vector.size());
for (auto& capabilities : capabilities_vector) {
blink::mojom::AudioInputDeviceCapabilitiesPtr capabilities_ptr =
blink::mojom::AudioInputDeviceCapabilities::New();
capabilities_ptr->device_id =
- GetHMACForMediaDeviceID(salt, security_origin, capabilities.device_id);
+ GetHMACForMediaDeviceID(salt_and_origin.device_id_salt,
+ salt_and_origin.origin, capabilities.device_id);
+ capabilities_ptr->group_id =
+ GetHMACForMediaDeviceID(salt_and_origin.group_id_salt,
+ salt_and_origin.origin, capabilities.group_id);
capabilities_ptr->parameters = capabilities.parameters;
result.push_back(std::move(capabilities_ptr));
}
@@ -202,9 +205,10 @@ void MediaDevicesDispatcherHost::GotDefaultVideoInputDeviceID(
requested_types[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = true;
media_stream_manager_->media_devices_manager()->EnumerateDevices(
requested_types,
- base::Bind(&MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities,
- weak_factory_.GetWeakPtr(), base::Passed(&client_callback),
- std::move(salt_and_origin), std::move(default_device_id)));
+ base::BindOnce(
+ &MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities,
+ weak_factory_.GetWeakPtr(), base::Passed(&client_callback),
+ std::move(salt_and_origin), std::move(default_device_id)));
}
void MediaDevicesDispatcherHost::FinalizeGetVideoInputCapabilities(
@@ -292,8 +296,7 @@ void MediaDevicesDispatcherHost::FinalizeGetVideoInputDeviceFormats(
}
struct MediaDevicesDispatcherHost::AudioInputCapabilitiesRequest {
- std::string device_id_salt;
- url::Origin security_origin;
+ MediaDeviceSaltAndOrigin salt_and_origin;
GetAudioInputCapabilitiesCallback client_callback;
};
@@ -302,8 +305,7 @@ void MediaDevicesDispatcherHost::GetDefaultAudioInputDeviceID(
const MediaDeviceSaltAndOrigin& salt_and_origin) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
pending_audio_input_capabilities_requests_.push_back(
- AudioInputCapabilitiesRequest{salt_and_origin.device_id_salt,
- salt_and_origin.origin,
+ AudioInputCapabilitiesRequest{salt_and_origin,
std::move(client_callback)});
if (pending_audio_input_capabilities_requests_.size() > 1U)
return;
@@ -324,8 +326,8 @@ void MediaDevicesDispatcherHost::GotDefaultAudioInputDeviceID(
devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true;
media_stream_manager_->media_devices_manager()->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesDispatcherHost::GotAudioInputEnumeration,
- weak_factory_.GetWeakPtr(), default_device_id));
+ base::BindOnce(&MediaDevicesDispatcherHost::GotAudioInputEnumeration,
+ weak_factory_.GetWeakPtr(), default_device_id));
}
void MediaDevicesDispatcherHost::GotAudioInputEnumeration(
@@ -337,7 +339,7 @@ void MediaDevicesDispatcherHost::GotAudioInputEnumeration(
DCHECK_EQ(num_pending_audio_input_parameters_, 0U);
for (const auto& device_info : enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT]) {
blink::mojom::AudioInputDeviceCapabilities capabilities(
- device_info.device_id,
+ device_info.device_id, device_info.group_id,
media::AudioParameters::UnavailableDeviceParams());
if (device_info.device_id == default_device_id)
current_audio_input_capabilities_.insert(
@@ -386,8 +388,7 @@ void MediaDevicesDispatcherHost::FinalizeGetAudioInputCapabilities() {
for (auto& request : pending_audio_input_capabilities_requests_) {
std::move(request.client_callback)
.Run(ToVectorAudioInputDeviceCapabilitiesPtr(
- current_audio_input_capabilities_, request.security_origin,
- request.device_id_salt));
+ current_audio_input_capabilities_, request.salt_and_origin));
}
current_audio_input_capabilities_.clear();
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 93c8f2ba585..c9fcb5e765b 100644
--- a/chromium/content/browser/renderer_host/media/media_devices_manager.cc
+++ b/chromium/content/browser/renderer_host/media/media_devices_manager.cc
@@ -124,6 +124,13 @@ static bool EqualDeviceAndGroupID(const MediaDeviceInfo& lhs,
return lhs == rhs && lhs.group_id == rhs.group_id;
}
+void ReplaceInvalidFrameRatesWithFallback(media::VideoCaptureFormats* formats) {
+ for (auto& format : *formats) {
+ if (format.frame_rate <= 0)
+ format.frame_rate = kFallbackVideoFrameRates[0];
+ }
+}
+
} // namespace
std::string GuessVideoGroupID(const MediaDeviceInfoArray& audio_infos,
@@ -194,8 +201,8 @@ std::string GuessVideoGroupID(const MediaDeviceInfoArray& audio_infos,
struct MediaDevicesManager::EnumerationRequest {
EnumerationRequest(const BoolDeviceTypes& requested_types,
- const EnumerationCallback& callback)
- : callback(callback) {
+ EnumerationCallback callback)
+ : callback(std::move(callback)) {
requested = requested_types;
has_seen_result.fill(false);
}
@@ -360,12 +367,14 @@ class MediaDevicesManager::AudioServiceDeviceListener
MediaDevicesManager::MediaDevicesManager(
media::AudioSystem* audio_system,
const scoped_refptr<VideoCaptureManager>& video_capture_manager,
- MediaStreamManager* media_stream_manager)
+ StopRemovedInputDeviceCallback stop_removed_input_device_cb,
+ UIInputDeviceChangeCallback ui_input_device_change_cb)
: use_fake_devices_(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseFakeDeviceForMediaStream)),
audio_system_(audio_system),
video_capture_manager_(video_capture_manager),
- media_stream_manager_(media_stream_manager),
+ stop_removed_input_device_cb_(std::move(stop_removed_input_device_cb)),
+ ui_input_device_change_cb_(std::move(ui_input_device_change_cb)),
permission_checker_(std::make_unique<MediaDevicesPermissionChecker>()),
cache_infos_(NUM_MEDIA_DEVICE_TYPES),
monitoring_started_(false),
@@ -375,6 +384,8 @@ MediaDevicesManager::MediaDevicesManager(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(audio_system_);
DCHECK(video_capture_manager_.get());
+ DCHECK(!stop_removed_input_device_cb_.is_null());
+ DCHECK(!ui_input_device_change_cb_.is_null());
cache_policies_.fill(CachePolicy::NO_CACHE);
has_seen_result_.fill(false);
}
@@ -385,11 +396,11 @@ MediaDevicesManager::~MediaDevicesManager() {
void MediaDevicesManager::EnumerateDevices(
const BoolDeviceTypes& requested_types,
- const EnumerationCallback& callback) {
+ EnumerationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
StartMonitoring();
- requests_.emplace_back(requested_types, callback);
+ requests_.emplace_back(requested_types, std::move(callback));
bool all_results_cached = true;
for (size_t i = 0; i < NUM_MEDIA_DEVICE_TYPES; ++i) {
if (requested_types[i] && cache_policies_[i] == CachePolicy::NO_CACHE) {
@@ -565,11 +576,13 @@ media::VideoCaptureFormats MediaDevicesManager::GetVideoInputFormats(
device_id);
if (format.has_value()) {
formats.push_back(format.value());
+ ReplaceInvalidFrameRatesWithFallback(&formats);
return formats;
}
}
video_capture_manager_->GetDeviceSupportedFormats(device_id, &formats);
+ ReplaceInvalidFrameRatesWithFallback(&formats);
// Remove formats that have zero resolution.
formats.erase(std::remove_if(formats.begin(), formats.end(),
[](const media::VideoCaptureFormat& format) {
@@ -651,11 +664,10 @@ void MediaDevicesManager::OnPermissionsCheckDone(
EnumerateDevices(
internal_requested_types,
- base::BindRepeating(&MediaDevicesManager::OnDevicesEnumerated,
- weak_factory_.GetWeakPtr(), requested_types,
- request_video_input_capabilities,
- base::Passed(&callback), std::move(salt_and_origin),
- has_permissions));
+ base::BindOnce(&MediaDevicesManager::OnDevicesEnumerated,
+ weak_factory_.GetWeakPtr(), requested_types,
+ request_video_input_capabilities, base::Passed(&callback),
+ std::move(salt_and_origin), has_permissions));
}
void MediaDevicesManager::OnDevicesEnumerated(
@@ -681,24 +693,27 @@ void MediaDevicesManager::OnDevicesEnumerated(
}
}
- std::move(callback).Run(
- std::move(result),
- video_input_capabilities_requested
- ? ComputeVideoInputCapabilities(result[MEDIA_DEVICE_TYPE_VIDEO_INPUT])
- : std::vector<VideoInputDeviceCapabilitiesPtr>());
+ std::move(callback).Run(std::move(result),
+ video_input_capabilities_requested
+ ? ComputeVideoInputCapabilities(
+ enumeration[MEDIA_DEVICE_TYPE_VIDEO_INPUT],
+ result[MEDIA_DEVICE_TYPE_VIDEO_INPUT])
+ : std::vector<VideoInputDeviceCapabilitiesPtr>());
}
std::vector<VideoInputDeviceCapabilitiesPtr>
MediaDevicesManager::ComputeVideoInputCapabilities(
- const MediaDeviceInfoArray& device_infos) {
+ const MediaDeviceInfoArray& raw_device_infos,
+ const MediaDeviceInfoArray& translated_device_infos) {
+ DCHECK_EQ(raw_device_infos.size(), translated_device_infos.size());
std::vector<VideoInputDeviceCapabilitiesPtr> video_input_capabilities;
- for (const auto& device_info : device_infos) {
+ for (size_t i = 0; i < raw_device_infos.size(); ++i) {
VideoInputDeviceCapabilitiesPtr capabilities =
blink::mojom::VideoInputDeviceCapabilities::New();
- capabilities->device_id = device_info.device_id;
- capabilities->formats = GetVideoInputFormats(device_info.device_id,
+ capabilities->device_id = translated_device_infos[i].device_id;
+ capabilities->formats = GetVideoInputFormats(raw_device_infos[i].device_id,
false /* try_in_use_first */);
- capabilities->facing_mode = device_info.video_facing;
+ capabilities->facing_mode = translated_device_infos[i].video_facing;
video_input_capabilities.push_back(std::move(capabilities));
}
return video_input_capabilities;
@@ -804,10 +819,9 @@ void MediaDevicesManager::UpdateSnapshot(
bool need_update_device_change_subscribers = false;
MediaDeviceInfoArray& old_snapshot = current_snapshot_[type];
- if (old_snapshot.size() != new_snapshot.size() &&
- (type == MEDIA_DEVICE_TYPE_AUDIO_INPUT ||
- type == MEDIA_DEVICE_TYPE_VIDEO_INPUT)) {
- StopRemovedDevices(type, new_snapshot);
+ if (type == MEDIA_DEVICE_TYPE_AUDIO_INPUT ||
+ type == MEDIA_DEVICE_TYPE_VIDEO_INPUT) {
+ MaybeStopRemovedInputDevices(type, new_snapshot);
}
// Update the cached snapshot and send notifications only if the device list
@@ -824,9 +838,8 @@ void MediaDevicesManager::UpdateSnapshot(
bool is_video_with_good_group_ids =
type == MEDIA_DEVICE_TYPE_VIDEO_INPUT &&
(new_snapshot.size() == 0 || !new_snapshot[0].group_id.empty());
- if (type == MEDIA_DEVICE_TYPE_AUDIO_INPUT || is_video_with_good_group_ids) {
- NotifyMediaStreamManager(type, new_snapshot);
- }
+ if (type == MEDIA_DEVICE_TYPE_AUDIO_INPUT || is_video_with_good_group_ids)
+ ui_input_device_change_cb_.Run(type, new_snapshot);
// Do not notify device-change subscribers after the first enumeration
// result, since it is not due to an actual device change.
@@ -858,15 +871,16 @@ void MediaDevicesManager::ProcessRequests() {
false /* ignore_group_id */);
}
- requests_.erase(std::remove_if(requests_.begin(), requests_.end(),
- [this](const EnumerationRequest& request) {
- if (IsEnumerationRequestReady(request)) {
- request.callback.Run(current_snapshot_);
- return true;
- }
- return false;
- }),
- requests_.end());
+ requests_.erase(
+ std::remove_if(requests_.begin(), requests_.end(),
+ [this](EnumerationRequest& request) {
+ if (IsEnumerationRequestReady(request)) {
+ std::move(request.callback).Run(current_snapshot_);
+ return true;
+ }
+ return false;
+ }),
+ requests_.end());
}
bool MediaDevicesManager::IsEnumerationRequestReady(
@@ -899,16 +913,13 @@ void MediaDevicesManager::HandleDevicesChanged(MediaDeviceType type) {
DoEnumerateDevices(type);
}
-void MediaDevicesManager::StopRemovedDevices(
+void MediaDevicesManager::MaybeStopRemovedInputDevices(
MediaDeviceType type,
const MediaDeviceInfoArray& new_snapshot) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(type == MEDIA_DEVICE_TYPE_AUDIO_INPUT ||
type == MEDIA_DEVICE_TYPE_VIDEO_INPUT);
- if (!media_stream_manager_)
- return;
-
for (const auto& old_device_info : current_snapshot_[type]) {
auto it = std::find_if(new_snapshot.begin(), new_snapshot.end(),
[&old_device_info](const MediaDeviceInfo& info) {
@@ -918,23 +929,10 @@ void MediaDevicesManager::StopRemovedDevices(
// If a device was removed, notify the MediaStreamManager to stop all
// streams using that device.
if (it == new_snapshot.end())
- media_stream_manager_->StopRemovedDevice(type, old_device_info);
+ stop_removed_input_device_cb_.Run(type, old_device_info);
}
}
-void MediaDevicesManager::NotifyMediaStreamManager(
- MediaDeviceType type,
- const MediaDeviceInfoArray& new_snapshot) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(type == MEDIA_DEVICE_TYPE_AUDIO_INPUT ||
- type == MEDIA_DEVICE_TYPE_VIDEO_INPUT);
-
- if (!media_stream_manager_)
- return;
-
- media_stream_manager_->NotifyDevicesChanged(type, new_snapshot);
-}
-
void MediaDevicesManager::NotifyDeviceChangeSubscribers(
MediaDeviceType type,
const MediaDeviceInfoArray& snapshot) {
diff --git a/chromium/content/browser/renderer_host/media/media_devices_manager.h b/chromium/content/browser/renderer_host/media/media_devices_manager.h
index c0f7ae1262a..7ba5aff3293 100644
--- a/chromium/content/browser/renderer_host/media/media_devices_manager.h
+++ b/chromium/content/browser/renderer_host/media/media_devices_manager.h
@@ -37,7 +37,6 @@ class Connector;
namespace content {
class MediaDevicesPermissionChecker;
-class MediaStreamManager;
class VideoCaptureManager;
// Use MediaDeviceType values to index on this type.
@@ -60,15 +59,22 @@ class CONTENT_EXPORT MediaDevicesManager
};
using EnumerationCallback =
- base::Callback<void(const MediaDeviceEnumeration&)>;
+ base::OnceCallback<void(const MediaDeviceEnumeration&)>;
using EnumerateDevicesCallback =
base::OnceCallback<void(const std::vector<MediaDeviceInfoArray>&,
std::vector<VideoInputDeviceCapabilitiesPtr>)>;
+ using StopRemovedInputDeviceCallback =
+ base::RepeatingCallback<void(MediaDeviceType type,
+ const MediaDeviceInfo& media_device_info)>;
+ using UIInputDeviceChangeCallback =
+ base::RepeatingCallback<void(MediaDeviceType stream_type,
+ const MediaDeviceInfoArray& devices)>;
MediaDevicesManager(
media::AudioSystem* audio_system,
const scoped_refptr<VideoCaptureManager>& video_capture_manager,
- MediaStreamManager* media_stream_manager);
+ StopRemovedInputDeviceCallback stop_removed_input_device_cb,
+ UIInputDeviceChangeCallback ui_input_device_change_cb);
~MediaDevicesManager() override;
// Performs a possibly cached device enumeration for the requested device
@@ -79,13 +85,16 @@ class CONTENT_EXPORT MediaDevicesManager
// another call to EnumerateDevices, it must do so by posting a task to the
// IO thread.
void EnumerateDevices(const BoolDeviceTypes& requested_types,
- const EnumerationCallback& callback);
+ EnumerationCallback callback);
// Performs a possibly cached device enumeration for the requested device
// types and reports the results to |callback|. The enumeration results are
// translated for use by the renderer process and frame identified with
// |render_process_id| and |render_frame_id|, based on the frame origin's
// permissions, an internal media-device salts.
+ // If |request_video_input_capabilities| is true, video formats supported
+ // by each device are returned in |callback|. These video formats are in
+ // no particular order and may contain duplicate entries.
void EnumerateDevices(int render_process_id,
int render_frame_id,
const BoolDeviceTypes& requested_types,
@@ -114,7 +123,8 @@ class CONTENT_EXPORT MediaDevicesManager
// changes.
void OnDevicesChanged(base::SystemMonitor::DeviceType device_type) override;
- // Returns the supported video formats for the given |device_id|.
+ // Returns the supported video formats for the given |device_id|. The returned
+ // formats are in no particular order and may contain duplicate entries.
// If |try_in_use_first| is true and the device is being used, only the format
// in use is returned. Otherwise, all formats supported by the device are
// returned.
@@ -197,7 +207,8 @@ class CONTENT_EXPORT MediaDevicesManager
const MediaDeviceEnumeration& enumeration);
std::vector<VideoInputDeviceCapabilitiesPtr> ComputeVideoInputCapabilities(
- const MediaDeviceInfoArray& device_infos);
+ const MediaDeviceInfoArray& raw_device_infos,
+ const MediaDeviceInfoArray& translated_device_infos);
// Helpers to issue low-level device enumerations.
void DoEnumerateDevices(MediaDeviceType type);
@@ -223,10 +234,8 @@ class CONTENT_EXPORT MediaDevicesManager
// Helpers to handle device-change notification.
void HandleDevicesChanged(MediaDeviceType type);
- void StopRemovedDevices(MediaDeviceType type,
- const MediaDeviceInfoArray& new_snapshot);
- void NotifyMediaStreamManager(MediaDeviceType type,
- const MediaDeviceInfoArray& new_snapshot);
+ void MaybeStopRemovedInputDevices(MediaDeviceType type,
+ const MediaDeviceInfoArray& new_snapshot);
void NotifyDeviceChangeSubscribers(MediaDeviceType type,
const MediaDeviceInfoArray& snapshot);
void CheckPermissionForDeviceChange(uint32_t subscription_id,
@@ -248,7 +257,8 @@ class CONTENT_EXPORT MediaDevicesManager
bool use_fake_devices_;
media::AudioSystem* const audio_system_; // not owned
scoped_refptr<VideoCaptureManager> video_capture_manager_;
- MediaStreamManager* const media_stream_manager_; // not owned
+ StopRemovedInputDeviceCallback stop_removed_input_device_cb_;
+ UIInputDeviceChangeCallback ui_input_device_change_cb_;
std::unique_ptr<MediaDevicesPermissionChecker> permission_checker_;
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 761b26e26cd..6fd207bbffc 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
@@ -13,6 +13,7 @@
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "content/browser/media/media_devices_permission_checker.h"
#include "content/browser/renderer_host/media/in_process_video_capture_provider.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -149,6 +150,16 @@ class MockMediaDevicesListener : public blink::mojom::MediaDevicesListener {
mojo::BindingSet<blink::mojom::MediaDevicesListener> bindings_;
};
+class MockMediaDevicesManagerClient {
+ public:
+ MOCK_METHOD2(StopRemovedInputDevice,
+ void(MediaDeviceType type,
+ const MediaDeviceInfo& media_device_info));
+ MOCK_METHOD2(InputDevicesChangedUI,
+ void(MediaDeviceType stream_type,
+ const MediaDeviceInfoArray& devices));
+};
+
void VerifyDeviceAndGroupID(const std::vector<MediaDeviceInfoArray>& array) {
for (const auto& device_infos : array) {
for (const auto& device_info : device_infos) {
@@ -181,6 +192,27 @@ class MediaDevicesManagerTest : public ::testing::Test {
run_loop->Quit();
}
+ void EnumerateWithCapabilitiesCallback(
+ const std::vector<media::FakeVideoCaptureDeviceSettings>&
+ expected_video_capture_device_settings,
+ base::RunLoop* run_loop,
+ const std::vector<MediaDeviceInfoArray>& devices,
+ std::vector<VideoInputDeviceCapabilitiesPtr> capabilities) {
+ EXPECT_EQ(capabilities.size(),
+ expected_video_capture_device_settings.size());
+ for (size_t i = 0; i < capabilities.size(); ++i) {
+ EXPECT_EQ(
+ capabilities[i]->formats.size(),
+ expected_video_capture_device_settings[i].supported_formats.size());
+ for (size_t j = 0; j < capabilities[i]->formats.size(); ++j) {
+ EXPECT_EQ(
+ capabilities[i]->formats[j],
+ expected_video_capture_device_settings[i].supported_formats[j]);
+ }
+ }
+ run_loop->Quit();
+ }
+
protected:
void SetUp() override {
audio_manager_ = std::make_unique<MockAudioManager>();
@@ -198,9 +230,17 @@ class MediaDevicesManagerTest : public ::testing::Test {
video_capture_manager_ = new VideoCaptureManager(
std::move(video_capture_provider), kIgnoreLogMessageCB);
media_devices_manager_.reset(new MediaDevicesManager(
- audio_system_.get(), video_capture_manager_, nullptr));
+ audio_system_.get(), video_capture_manager_,
+ base::BindRepeating(
+ &MockMediaDevicesManagerClient::StopRemovedInputDevice,
+ base::Unretained(&media_devices_manager_client_)),
+ base::BindRepeating(
+ &MockMediaDevicesManagerClient::InputDevicesChangedUI,
+ base::Unretained(&media_devices_manager_client_))));
media_devices_manager_->set_salt_and_origin_callback_for_testing(
base::BindRepeating(&GetSaltAndOrigin));
+ media_devices_manager_->SetPermissionChecker(
+ std::make_unique<MediaDevicesPermissionChecker>(true));
}
void EnableCache(MediaDeviceType type) {
@@ -217,6 +257,8 @@ class MediaDevicesManagerTest : public ::testing::Test {
MockVideoCaptureDeviceFactory* video_capture_device_factory_;
std::unique_ptr<MockAudioManager> audio_manager_;
std::unique_ptr<media::AudioSystem> audio_system_;
+ testing::StrictMock<MockMediaDevicesManagerClient>
+ media_devices_manager_client_;
private:
DISALLOW_COPY_AND_ASSIGN(MediaDevicesManagerTest);
@@ -229,14 +271,15 @@ TEST_F(MediaDevicesManagerTest, EnumerateNoCacheAudioInput) {
.Times(0);
EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(0);
EXPECT_CALL(*this, MockCallback(_)).Times(kNumCalls);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _));
MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true;
for (int i = 0; i < kNumCalls; i++) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
}
}
@@ -247,14 +290,15 @@ TEST_F(MediaDevicesManagerTest, EnumerateNoCacheVideoInput) {
.Times(kNumCalls);
EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(0);
EXPECT_CALL(*this, MockCallback(_)).Times(kNumCalls);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _));
MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
devices_to_enumerate[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = true;
for (int i = 0; i < kNumCalls; i++) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
}
}
@@ -272,8 +316,8 @@ TEST_F(MediaDevicesManagerTest, EnumerateNoCacheAudioOutput) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
}
}
@@ -284,6 +328,7 @@ TEST_F(MediaDevicesManagerTest, EnumerateNoCacheAudio) {
EXPECT_CALL(*audio_manager_, MockGetAudioInputDeviceNames(_))
.Times(kNumCalls);
EXPECT_CALL(*this, MockCallback(_)).Times(kNumCalls);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _));
MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_INPUT] = true;
devices_to_enumerate[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
@@ -291,8 +336,8 @@ TEST_F(MediaDevicesManagerTest, EnumerateNoCacheAudio) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
}
}
@@ -303,6 +348,7 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheAudio) {
.Times(0);
EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(1);
EXPECT_CALL(*this, MockCallback(_)).Times(kNumCalls);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _));
EnableCache(MEDIA_DEVICE_TYPE_AUDIO_INPUT);
EnableCache(MEDIA_DEVICE_TYPE_AUDIO_OUTPUT);
MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
@@ -312,8 +358,8 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheAudio) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
}
}
@@ -324,6 +370,7 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheVideo) {
.Times(1);
EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(0);
EXPECT_CALL(*this, MockCallback(_)).Times(kNumCalls);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _));
EnableCache(MEDIA_DEVICE_TYPE_VIDEO_INPUT);
MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
devices_to_enumerate[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = true;
@@ -331,22 +378,22 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheVideo) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
}
}
TEST_F(MediaDevicesManagerTest, EnumerateCacheAudioWithDeviceChanges) {
MediaDeviceEnumeration enumeration;
- EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(2);
+ EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(3);
EXPECT_CALL(*video_capture_device_factory_, MockGetDeviceDescriptors())
.Times(0);
- EXPECT_CALL(*audio_manager_, MockGetAudioInputDeviceNames(_)).Times(2);
+ EXPECT_CALL(*audio_manager_, MockGetAudioInputDeviceNames(_)).Times(3);
EXPECT_CALL(*this, MockCallback(_))
- .Times(2 * kNumCalls)
+ .Times(3 * kNumCalls)
.WillRepeatedly(SaveArg<0>(&enumeration));
-
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _));
size_t num_audio_input_devices = 5;
size_t num_audio_output_devices = 3;
audio_manager_->SetNumAudioInputDevices(num_audio_input_devices);
@@ -360,8 +407,8 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheAudioWithDeviceChanges) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
EXPECT_EQ(num_audio_input_devices,
enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT].size());
@@ -369,19 +416,49 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheAudioWithDeviceChanges) {
enumeration[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT].size());
}
- // Simulate device change
+ // Simulate removal of devices.
+ size_t old_num_audio_input_devices = num_audio_input_devices;
num_audio_input_devices = 3;
- num_audio_output_devices = 4;
+ num_audio_output_devices = 2;
+ ASSERT_LT(num_audio_input_devices, old_num_audio_input_devices);
+ size_t num_removed_audio_input_devices =
+ old_num_audio_input_devices - num_audio_input_devices;
+ EXPECT_CALL(media_devices_manager_client_, StopRemovedInputDevice(_, _))
+ .Times(num_removed_audio_input_devices);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _));
+
audio_manager_->SetNumAudioInputDevices(num_audio_input_devices);
audio_manager_->SetNumAudioOutputDevices(num_audio_output_devices);
media_devices_manager_->OnDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO);
+ for (int i = 0; i < kNumCalls; i++) {
+ base::RunLoop run_loop;
+ media_devices_manager_->EnumerateDevices(
+ devices_to_enumerate,
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
+ run_loop.Run();
+ EXPECT_EQ(num_audio_input_devices,
+ enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT].size());
+ EXPECT_EQ(num_audio_output_devices,
+ enumeration[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT].size());
+ }
+
+ // Simulate addition of devices.
+ old_num_audio_input_devices = num_audio_input_devices;
+ num_audio_input_devices = 4;
+ num_audio_output_devices = 3;
+ ASSERT_GT(num_audio_input_devices, old_num_audio_input_devices);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _));
+ audio_manager_->SetNumAudioInputDevices(num_audio_input_devices);
+ audio_manager_->SetNumAudioOutputDevices(num_audio_output_devices);
+ media_devices_manager_->OnDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO);
for (int i = 0; i < kNumCalls; i++) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
EXPECT_EQ(num_audio_input_devices,
enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT].size());
@@ -394,13 +471,14 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheVideoWithDeviceChanges) {
MediaDeviceEnumeration enumeration;
EXPECT_CALL(*audio_manager_, MockGetAudioOutputDeviceNames(_)).Times(0);
EXPECT_CALL(*video_capture_device_factory_, MockGetDeviceDescriptors())
- .Times(2);
+ .Times(3);
EXPECT_CALL(*audio_manager_, MockGetAudioInputDeviceNames(_)).Times(0);
EXPECT_CALL(*this, MockCallback(_))
- .Times(2 * kNumCalls)
+ .Times(3 * kNumCalls)
.WillRepeatedly(SaveArg<0>(&enumeration));
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _));
- // Simulate device change
+ // First enumeration.
size_t num_video_input_devices = 5;
video_capture_device_factory_->SetToDefaultDevicesConfig(
num_video_input_devices);
@@ -411,15 +489,43 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheVideoWithDeviceChanges) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
EXPECT_EQ(num_video_input_devices,
enumeration[MEDIA_DEVICE_TYPE_VIDEO_INPUT].size());
}
- // Simulate device change
+ // Simulate addition of devices.
+ size_t old_num_video_input_devices = num_video_input_devices;
num_video_input_devices = 9;
+ ASSERT_GT(num_video_input_devices, old_num_video_input_devices);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _));
+ video_capture_device_factory_->SetToDefaultDevicesConfig(
+ num_video_input_devices);
+ media_devices_manager_->OnDevicesChanged(
+ base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
+
+ for (int i = 0; i < kNumCalls; i++) {
+ base::RunLoop run_loop;
+ media_devices_manager_->EnumerateDevices(
+ devices_to_enumerate,
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
+ run_loop.Run();
+ EXPECT_EQ(num_video_input_devices,
+ enumeration[MEDIA_DEVICE_TYPE_VIDEO_INPUT].size());
+ }
+
+ // Simulate removal of devices.
+ old_num_video_input_devices = num_video_input_devices;
+ num_video_input_devices = 7;
+ ASSERT_LT(num_video_input_devices, old_num_video_input_devices);
+ size_t num_removed_video_input_devices =
+ old_num_video_input_devices - num_video_input_devices;
+ EXPECT_CALL(media_devices_manager_client_, StopRemovedInputDevice(_, _))
+ .Times(num_removed_video_input_devices);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _));
video_capture_device_factory_->SetToDefaultDevicesConfig(
num_video_input_devices);
media_devices_manager_->OnDevicesChanged(
@@ -429,8 +535,8 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheVideoWithDeviceChanges) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
EXPECT_EQ(num_video_input_devices,
enumeration[MEDIA_DEVICE_TYPE_VIDEO_INPUT].size());
@@ -446,6 +552,8 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheAllWithDeviceChanges) {
EXPECT_CALL(*this, MockCallback(_))
.Times(2 * kNumCalls)
.WillRepeatedly(SaveArg<0>(&enumeration));
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _))
+ .Times(2);
size_t num_audio_input_devices = 5;
size_t num_video_input_devices = 4;
@@ -465,8 +573,8 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheAllWithDeviceChanges) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
EXPECT_EQ(num_audio_input_devices,
enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT].size());
@@ -477,9 +585,20 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheAllWithDeviceChanges) {
}
// Simulate device changes
+ size_t old_num_audio_input_devices = num_audio_input_devices;
+ size_t old_num_video_input_devices = num_video_input_devices;
num_audio_input_devices = 3;
num_video_input_devices = 2;
num_audio_output_devices = 4;
+ ASSERT_LT(num_audio_input_devices, old_num_audio_input_devices);
+ ASSERT_LT(num_video_input_devices, old_num_video_input_devices);
+ size_t num_removed_input_devices =
+ old_num_audio_input_devices - num_audio_input_devices +
+ old_num_video_input_devices - num_video_input_devices;
+ EXPECT_CALL(media_devices_manager_client_, StopRemovedInputDevice(_, _))
+ .Times(num_removed_input_devices);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _))
+ .Times(2);
audio_manager_->SetNumAudioInputDevices(num_audio_input_devices);
video_capture_device_factory_->SetToDefaultDevicesConfig(
num_video_input_devices);
@@ -492,8 +611,8 @@ TEST_F(MediaDevicesManagerTest, EnumerateCacheAllWithDeviceChanges) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
EXPECT_EQ(num_audio_input_devices,
enumeration[MEDIA_DEVICE_TYPE_AUDIO_INPUT].size());
@@ -509,6 +628,8 @@ TEST_F(MediaDevicesManagerTest, SubscribeDeviceChanges) {
EXPECT_CALL(*video_capture_device_factory_, MockGetDeviceDescriptors())
.Times(3);
EXPECT_CALL(*audio_manager_, MockGetAudioInputDeviceNames(_)).Times(3);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _))
+ .Times(2);
size_t num_audio_input_devices = 5;
size_t num_video_input_devices = 4;
@@ -528,8 +649,8 @@ TEST_F(MediaDevicesManagerTest, SubscribeDeviceChanges) {
base::RunLoop run_loop;
media_devices_manager_->EnumerateDevices(
devices_to_enumerate,
- base::Bind(&MediaDevicesManagerTest::EnumerateCallback,
- base::Unretained(this), &run_loop));
+ base::BindOnce(&MediaDevicesManagerTest::EnumerateCallback,
+ base::Unretained(this), &run_loop));
run_loop.Run();
// Add device-change event listeners.
@@ -595,9 +716,20 @@ TEST_F(MediaDevicesManagerTest, SubscribeDeviceChanges) {
.WillRepeatedly(SaveArg<1>(&notification_all_audio_output));
// Simulate device changes.
+ size_t old_num_audio_input_devices = num_audio_input_devices;
+ size_t old_num_video_input_devices = num_video_input_devices;
num_audio_input_devices = 3;
num_video_input_devices = 2;
num_audio_output_devices = 4;
+ ASSERT_LT(num_audio_input_devices, old_num_audio_input_devices);
+ ASSERT_LT(num_video_input_devices, old_num_video_input_devices);
+ size_t num_removed_input_devices =
+ old_num_audio_input_devices - num_audio_input_devices +
+ old_num_video_input_devices - num_video_input_devices;
+ EXPECT_CALL(media_devices_manager_client_, StopRemovedInputDevice(_, _))
+ .Times(num_removed_input_devices);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _))
+ .Times(2);
audio_manager_->SetNumAudioInputDevices(num_audio_input_devices);
video_capture_device_factory_->SetToDefaultDevicesConfig(
num_video_input_devices);
@@ -626,9 +758,20 @@ TEST_F(MediaDevicesManagerTest, SubscribeDeviceChanges) {
// Simulate further device changes. Only the objects still subscribed to the
// device-change events will receive notifications.
+ old_num_audio_input_devices = num_audio_input_devices;
+ old_num_video_input_devices = num_video_input_devices;
num_audio_input_devices = 2;
num_video_input_devices = 1;
num_audio_output_devices = 3;
+ ASSERT_LT(num_audio_input_devices, old_num_audio_input_devices);
+ ASSERT_LT(num_video_input_devices, old_num_video_input_devices);
+ num_removed_input_devices =
+ old_num_audio_input_devices - num_audio_input_devices +
+ old_num_video_input_devices - num_video_input_devices;
+ EXPECT_CALL(media_devices_manager_client_, StopRemovedInputDevice(_, _))
+ .Times(num_removed_input_devices);
+ EXPECT_CALL(media_devices_manager_client_, InputDevicesChangedUI(_, _))
+ .Times(2);
audio_manager_->SetNumAudioInputDevices(num_audio_input_devices);
video_capture_device_factory_->SetToDefaultDevicesConfig(
num_video_input_devices);
@@ -645,6 +788,49 @@ TEST_F(MediaDevicesManagerTest, SubscribeDeviceChanges) {
notification_all_audio_output});
}
+TEST_F(MediaDevicesManagerTest, EnumerateDevicesWithCapabilities) {
+ // Audio is enumerated due to heuristics to compute video group IDs.
+ EXPECT_CALL(*audio_manager_, MockGetAudioInputDeviceNames(_));
+ EXPECT_CALL(media_devices_manager_client_,
+ InputDevicesChangedUI(MEDIA_DEVICE_TYPE_AUDIO_INPUT, _));
+ EXPECT_CALL(*video_capture_device_factory_, MockGetDeviceDescriptors());
+ EXPECT_CALL(media_devices_manager_client_,
+ InputDevicesChangedUI(MEDIA_DEVICE_TYPE_VIDEO_INPUT, _));
+ // Configure fake devices with video formats different from the fallback
+ // formats to make sure that expected capabilities are what devices actually
+ // report.
+ media::FakeVideoCaptureDeviceSettings fake_device1;
+ fake_device1.device_id = "fake_id_1";
+ fake_device1.delivery_mode =
+ media::FakeVideoCaptureDevice::DeliveryMode::USE_DEVICE_INTERNAL_BUFFERS;
+ fake_device1.supported_formats = {
+ {{1000, 1000}, 60.0, media::PIXEL_FORMAT_I420},
+ {{2000, 2000}, 120.0, media::PIXEL_FORMAT_I420}};
+
+ media::FakeVideoCaptureDeviceSettings fake_device2;
+ fake_device2.device_id = "fake_id_2";
+ fake_device2.delivery_mode =
+ media::FakeVideoCaptureDevice::DeliveryMode::USE_DEVICE_INTERNAL_BUFFERS;
+ fake_device2.supported_formats = {
+ {{100, 100}, 6.0, media::PIXEL_FORMAT_I420},
+ {{200, 200}, 12.0, media::PIXEL_FORMAT_I420}};
+
+ std::vector<media::FakeVideoCaptureDeviceSettings>
+ fake_capture_device_settings = {fake_device1, fake_device2};
+ video_capture_device_factory_->SetToCustomDevicesConfig(
+ fake_capture_device_settings);
+
+ MediaDevicesManager::BoolDeviceTypes devices_to_enumerate;
+ devices_to_enumerate[MEDIA_DEVICE_TYPE_VIDEO_INPUT] = true;
+ base::RunLoop run_loop;
+ media_devices_manager_->EnumerateDevices(
+ -1, -1, devices_to_enumerate, true,
+ base::BindOnce(
+ &MediaDevicesManagerTest::EnumerateWithCapabilitiesCallback,
+ base::Unretained(this), fake_capture_device_settings, &run_loop));
+ run_loop.Run();
+}
+
TEST_F(MediaDevicesManagerTest, GuessVideoGroupID) {
MediaDeviceInfoArray audio_devices = {
{media::AudioDeviceDescription::kDefaultDeviceId,
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 6f59da110bf..71f785312be 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_manager.cc
+++ b/chromium/content/browser/renderer_host/media/media_stream_manager.cc
@@ -36,6 +36,7 @@
#include "content/browser/renderer_host/media/media_devices_manager.h"
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "content/browser/renderer_host/media/service_video_capture_provider.h"
+#include "content/browser/renderer_host/media/video_capture_dependencies.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/browser/renderer_host/media/video_capture_provider_switcher.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
@@ -54,7 +55,7 @@
#include "media/base/audio_parameters.h"
#include "media/base/channel_layout.h"
#include "media/base/media_switches.h"
-#include "media/capture/video/video_capture_device_factory.h"
+#include "media/capture/video/create_video_capture_device_factory.h"
#include "media/capture/video/video_capture_system_impl.h"
#include "services/video_capture/public/uma/video_capture_service_event.h"
#include "url/gurl.h"
@@ -66,6 +67,9 @@
#if defined(OS_CHROMEOS)
#include "chromeos/audio/cras_audio_handler.h"
+#include "media/capture/video/chromeos/camera_hal_dispatcher_impl.h"
+#include "media/capture/video/chromeos/public/cros_features.h"
+#include "media/capture/video/chromeos/video_capture_device_factory_chromeos.h"
#endif
namespace content {
@@ -96,42 +100,6 @@ std::string RandomLabel() {
return label;
}
-void CreateJpegDecodeAcceleratorOnIOThread(
- media::mojom::JpegDecodeAcceleratorRequest request) {
- auto* host =
- GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, false);
- if (host) {
- host->gpu_service()->CreateJpegDecodeAccelerator(std::move(request));
- } else {
- LOG(ERROR) << "No GpuProcessHost";
- }
-}
-
-void CreateJpegDecodeAccelerator(
- media::mojom::JpegDecodeAcceleratorRequest request) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CreateJpegDecodeAcceleratorOnIOThread,
- std::move(request)));
-}
-
-void CreateJpegEncodeAcceleratorOnIOThread(
- media::mojom::JpegEncodeAcceleratorRequest request) {
- auto* host =
- GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, false);
- if (host) {
- host->gpu_service()->CreateJpegEncodeAccelerator(std::move(request));
- } else {
- LOG(ERROR) << "No GpuProcessHost";
- }
-}
-
-void CreateJpegEncodeAccelerator(
- media::mojom::JpegEncodeAcceleratorRequest request) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&CreateJpegEncodeAcceleratorOnIOThread,
- std::move(request)));
-}
-
void ParseStreamType(const StreamControls& controls,
MediaStreamType* audio_type,
MediaStreamType* video_type) {
@@ -199,13 +167,6 @@ void EnableHotwordEffect(const StreamControls& controls, int* effects) {
}
}
-bool CalledOnIOThread() {
- // Check if this function call is on the IO thread, except for unittests where
- // an IO thread might not have been created.
- return BrowserThread::CurrentlyOn(BrowserThread::IO) ||
- !BrowserThread::IsThreadInitialized(BrowserThread::IO);
-}
-
bool GetDeviceIDFromHMAC(const std::string& salt,
const url::Origin& security_origin,
const std::string& hmac_device_id,
@@ -502,6 +463,18 @@ MediaStreamManager::MediaStreamManager(
device_task_runner = video_capture_thread_->task_runner();
}
+#if defined(OS_CHROMEOS)
+ if (media::ShouldUseCrosCameraService()) {
+ media::VideoCaptureDeviceFactoryChromeOS::SetGpuBufferManager(
+ BrowserGpuMemoryBufferManager::current());
+ media::CameraHalDispatcherImpl::GetInstance()->Start(
+ base::BindRepeating(
+ &VideoCaptureDependencies::CreateJpegDecodeAccelerator),
+ base::BindRepeating(
+ &VideoCaptureDependencies::CreateJpegEncodeAccelerator));
+ }
+#endif
+
if (base::FeatureList::IsEnabled(features::kMojoVideoCapture)) {
video_capture_provider = std::make_unique<VideoCaptureProviderSwitcher>(
std::make_unique<ServiceVideoCaptureProvider>(
@@ -514,11 +487,8 @@ MediaStreamManager::MediaStreamManager(
video_capture::uma::BROWSER_USING_LEGACY_CAPTURE);
video_capture_provider = InProcessVideoCaptureProvider::CreateInstance(
std::make_unique<media::VideoCaptureSystemImpl>(
- media::VideoCaptureDeviceFactory::CreateFactory(
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
- BrowserGpuMemoryBufferManager::current(),
- base::BindRepeating(&CreateJpegDecodeAccelerator),
- base::BindRepeating(&CreateJpegEncodeAccelerator))),
+ media::CreateVideoCaptureDeviceFactory(
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::UI))),
std::move(device_task_runner),
base::BindRepeating(&SendVideoCaptureLogMessage));
}
@@ -767,6 +737,7 @@ int MediaStreamManager::VideoDeviceIdToSessionId(
}
void MediaStreamManager::StopDevice(MediaStreamType type, int session_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DVLOG(1) << "StopDevice"
<< "{type = " << type << "}"
<< "{session_id = " << session_id << "}";
@@ -805,6 +776,7 @@ void MediaStreamManager::StopDevice(MediaStreamType type, int session_id) {
}
void MediaStreamManager::CloseDevice(MediaStreamType type, int session_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DVLOG(1) << "CloseDevice("
<< "{type = " << type << "} "
<< "{session_id = " << session_id << "})";
@@ -1016,6 +988,7 @@ std::string MediaStreamManager::AddRequest(DeviceRequest* request) {
MediaStreamManager::DeviceRequest* MediaStreamManager::FindRequest(
const std::string& label) const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
for (const LabeledDeviceRequest& labeled_request : requests_) {
if (labeled_request.first == label)
return labeled_request.second;
@@ -1024,6 +997,7 @@ MediaStreamManager::DeviceRequest* MediaStreamManager::FindRequest(
}
void MediaStreamManager::DeleteRequest(const std::string& label) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DVLOG(1) << "DeleteRequest({label= " << label << "})";
for (DeviceRequests::iterator request_it = requests_.begin();
request_it != requests_.end(); ++request_it) {
@@ -1052,23 +1026,26 @@ void MediaStreamManager::ReadOutputParamsAndPostRequestToUI(
audio_system_->GetOutputStreamParameters(
media::AudioDeviceDescription::kDefaultDeviceId,
base::BindOnce(&MediaStreamManager::PostRequestToUI,
- base::Unretained(this), label, request, enumeration));
+ base::Unretained(this), label, enumeration));
} else {
- PostRequestToUI(label, request, enumeration,
+ PostRequestToUI(label, enumeration,
base::Optional<media::AudioParameters>());
}
}
void MediaStreamManager::PostRequestToUI(
const std::string& label,
- DeviceRequest* request,
const MediaDeviceEnumeration& enumeration,
const base::Optional<media::AudioParameters>& output_parameters) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(request->HasUIRequest());
DCHECK(!output_parameters || output_parameters->IsValid());
DVLOG(1) << "PostRequestToUI({label= " << label << "})";
+ DeviceRequest* request = FindRequest(label);
+ if (!request)
+ return;
+ DCHECK(request->HasUIRequest());
+
const MediaStreamType audio_type = request->audio_type();
const MediaStreamType video_type = request->video_type();
@@ -1254,6 +1231,7 @@ bool MediaStreamManager::SetupScreenCaptureRequest(DeviceRequest* request) {
MediaStreamDevices MediaStreamManager::GetDevicesOpenedByRequest(
const std::string& label) const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DeviceRequest* request = FindRequest(label);
if (!request)
return MediaStreamDevices();
@@ -1265,6 +1243,7 @@ bool MediaStreamManager::FindExistingRequestedDevice(
const MediaStreamDevice& new_device,
MediaStreamDevice* existing_device,
MediaRequestState* existing_request_state) const {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(existing_device);
DCHECK(existing_request_state);
@@ -1364,6 +1343,7 @@ void MediaStreamManager::FinalizeMediaAccessRequest(
const std::string& label,
DeviceRequest* request,
const MediaStreamDevices& devices) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(request->media_access_request_cb);
std::move(request->media_access_request_cb)
.Run(devices, std::move(request->ui_proxy));
@@ -1405,8 +1385,14 @@ void MediaStreamManager::InitializeMaybeAsync(
base::BindRepeating(&SendVideoCaptureLogMessage));
video_capture_manager_->RegisterListener(this);
- media_devices_manager_.reset(
- new MediaDevicesManager(audio_system_, video_capture_manager_, this));
+ // Using base::Unretained(this) is safe because |this| owns and therefore
+ // outlives |media_devices_manager_|.
+ media_devices_manager_.reset(new MediaDevicesManager(
+ audio_system_, video_capture_manager_,
+ base::BindRepeating(&MediaStreamManager::StopRemovedDevice,
+ base::Unretained(this)),
+ base::BindRepeating(&MediaStreamManager::NotifyDevicesChanged,
+ base::Unretained(this))));
}
void MediaStreamManager::Opened(MediaStreamType stream_type,
@@ -1689,7 +1675,8 @@ void MediaStreamManager::StopMediaStreamFromBrowser(const std::string& label) {
void MediaStreamManager::WillDestroyCurrentMessageLoop() {
DVLOG(3) << "MediaStreamManager::WillDestroyCurrentMessageLoop()";
- DCHECK(CalledOnIOThread());
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO) ||
+ !BrowserThread::IsThreadInitialized(BrowserThread::IO));
if (media_devices_manager_)
media_devices_manager_->StopMonitoring();
if (video_capture_manager_)
@@ -1898,6 +1885,7 @@ MediaStreamDevices MediaStreamManager::ConvertToMediaStreamDevices(
}
void MediaStreamManager::OnStreamStarted(const std::string& label) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DeviceRequest* const request = FindRequest(label);
if (!request)
return;
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 82fee09f21e..c73c8d60c26 100644
--- a/chromium/content/browser/renderer_host/media/media_stream_manager.h
+++ b/chromium/content/browser/renderer_host/media/media_stream_manager.h
@@ -175,19 +175,22 @@ class CONTENT_EXPORT MediaStreamManager
GenerateStreamCallback generate_stream_cb,
DeviceStoppedCallback device_stopped_cb);
+ // Cancel an open request identified by |page_request_id| for the given frame.
+ // Must be called on the IO thread.
void CancelRequest(int render_process_id,
int render_frame_id,
int page_request_id);
- // Cancel an open request identified by |label|.
+ // Cancel an open request identified by |label|. Must be called on the IO
+ // thread.
void CancelRequest(const std::string& label);
// Cancel all requests for the given |render_process_id| and
- // |render_frame_id|.
+ // |render_frame_id|. Must be called on the IO thread.
void CancelAllRequests(int render_process_id, int render_frame_id);
// Closes the stream device for a certain render frame. The stream must have
- // been opened by a call to GenerateStream.
+ // been opened by a call to GenerateStream. Must be called on the IO thread.
void StopStreamDevice(int render_process_id,
int render_frame_id,
const std::string& device_id,
@@ -218,7 +221,7 @@ class CONTENT_EXPORT MediaStreamManager
std::string* device_id) const;
// Find |device_id| in the list of |requests_|, and returns its session id,
- // or MediaStreamDevice::kNoId if not found.
+ // or MediaStreamDevice::kNoId if not found. Must be called on the IO thread.
int VideoDeviceIdToSessionId(const std::string& device_id) const;
// Called by UI to make sure the device monitor is started so that UI receive
@@ -283,6 +286,7 @@ class CONTENT_EXPORT MediaStreamManager
// Set whether the capturing is secure for the capturing session with given
// |session_id|, |render_process_id|, and the MediaStreamType |type|.
+ // Must be called on the IO thread.
void SetCapturingLinkSecured(int render_process_id,
int session_id,
content::MediaStreamType type,
@@ -295,7 +299,7 @@ class CONTENT_EXPORT MediaStreamManager
// This method is called when an audio or video device is removed. It makes
// sure all MediaStreams that use a removed device are stopped and that the
- // render process is notified.
+ // render process is notified. Must be called on the IO thread.
void StopRemovedDevice(MediaDeviceType type,
const MediaDeviceInfo& media_device_info);
@@ -370,7 +374,6 @@ class CONTENT_EXPORT MediaStreamManager
// Called when audio output parameters have been read if needed.
void PostRequestToUI(
const std::string& label,
- DeviceRequest* request,
const MediaDeviceEnumeration& enumeration,
const base::Optional<media::AudioParameters>& output_parameters);
// Returns true if a device with |device_id| has already been requested with
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 a9a89760950..0acf2f42c16 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
@@ -30,9 +30,13 @@ namespace content {
namespace {
class MockRenderFrameHostDelegate : public RenderFrameHostDelegate {
public:
+ void RequestMediaAccessPermission(const MediaStreamRequest& request,
+ MediaResponseCallback callback) {
+ return RequestMediaAccessPermission(request, &callback);
+ }
MOCK_METHOD2(RequestMediaAccessPermission,
void(const MediaStreamRequest& request,
- const MediaResponseCallback& callback));
+ MediaResponseCallback* callback));
MOCK_METHOD3(CheckMediaAccessPermission,
bool(RenderFrameHost* render_frame_host,
const url::Origin& security_origin,
@@ -122,14 +126,17 @@ TEST_F(MediaStreamUIProxyTest, MAYBE_Deny) {
base::BindOnce(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_)));
MediaResponseCallback callback;
- EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr),
- _))
- .WillOnce(SaveArg<1>(&callback));
+ EXPECT_CALL(delegate_,
+ RequestMediaAccessPermission(SameRequest(request_ptr), _))
+ .WillOnce([&](testing::Unused, MediaResponseCallback* cb) {
+ callback = std::move(*cb);
+ });
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(callback.is_null());
MediaStreamDevices devices;
- callback.Run(devices, MEDIA_DEVICE_OK, std::unique_ptr<MediaStreamUI>());
+ std::move(callback).Run(devices, MEDIA_DEVICE_OK,
+ std::unique_ptr<MediaStreamUI>());
MediaStreamDevices response;
EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _))
@@ -150,9 +157,11 @@ TEST_F(MediaStreamUIProxyTest, MAYBE_AcceptAndStart) {
base::BindOnce(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_)));
MediaResponseCallback callback;
- EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr),
- _))
- .WillOnce(SaveArg<1>(&callback));
+ EXPECT_CALL(delegate_,
+ RequestMediaAccessPermission(SameRequest(request_ptr), _))
+ .WillOnce([&](testing::Unused, MediaResponseCallback* cb) {
+ callback = std::move(*cb);
+ });
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(callback.is_null());
@@ -161,7 +170,7 @@ TEST_F(MediaStreamUIProxyTest, MAYBE_AcceptAndStart) {
MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, "Mic", "Mic"));
std::unique_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
EXPECT_CALL(*ui, OnStarted(_)).WillOnce(Return(0));
- callback.Run(devices, MEDIA_DEVICE_OK, std::move(ui));
+ std::move(callback).Run(devices, MEDIA_DEVICE_OK, std::move(ui));
MediaStreamDevices response;
EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _))
@@ -186,9 +195,11 @@ TEST_F(MediaStreamUIProxyTest, MAYBE_DeleteBeforeAccepted) {
base::BindOnce(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_)));
MediaResponseCallback callback;
- EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr)
- , _))
- .WillOnce(SaveArg<1>(&callback));
+ EXPECT_CALL(delegate_,
+ RequestMediaAccessPermission(SameRequest(request_ptr), _))
+ .WillOnce([&](testing::Unused, MediaResponseCallback* cb) {
+ callback = std::move(*cb);
+ });
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(callback.is_null());
@@ -196,7 +207,7 @@ TEST_F(MediaStreamUIProxyTest, MAYBE_DeleteBeforeAccepted) {
MediaStreamDevices devices;
std::unique_ptr<MediaStreamUI> ui;
- callback.Run(devices, MEDIA_DEVICE_OK, std::move(ui));
+ std::move(callback).Run(devices, MEDIA_DEVICE_OK, std::move(ui));
}
TEST_F(MediaStreamUIProxyTest, MAYBE_StopFromUI) {
@@ -210,9 +221,11 @@ TEST_F(MediaStreamUIProxyTest, MAYBE_StopFromUI) {
base::BindOnce(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_)));
MediaResponseCallback callback;
- EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr)
- , _))
- .WillOnce(SaveArg<1>(&callback));
+ EXPECT_CALL(delegate_,
+ RequestMediaAccessPermission(SameRequest(request_ptr), _))
+ .WillOnce([&](testing::Unused, MediaResponseCallback* cb) {
+ callback = std::move(*cb);
+ });
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(callback.is_null());
@@ -224,7 +237,7 @@ TEST_F(MediaStreamUIProxyTest, MAYBE_StopFromUI) {
std::unique_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
EXPECT_CALL(*ui, OnStarted(_))
.WillOnce(testing::DoAll(SaveArg<0>(&stop_callback), Return(0)));
- callback.Run(devices, MEDIA_DEVICE_OK, std::move(ui));
+ std::move(callback).Run(devices, MEDIA_DEVICE_OK, std::move(ui));
MediaStreamDevices response;
EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _))
@@ -257,16 +270,18 @@ TEST_F(MediaStreamUIProxyTest, MAYBE_WindowIdCallbackCalled) {
base::BindOnce(&MockResponseCallback::OnAccessRequestResponse,
base::Unretained(&response_callback_)));
MediaResponseCallback callback;
- EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request_ptr),
- _))
- .WillOnce(SaveArg<1>(&callback));
+ EXPECT_CALL(delegate_,
+ RequestMediaAccessPermission(SameRequest(request_ptr), _))
+ .WillOnce([&](testing::Unused, MediaResponseCallback* cb) {
+ callback = std::move(*cb);
+ });
base::RunLoop().RunUntilIdle();
const int kWindowId = 1;
std::unique_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
EXPECT_CALL(*ui, OnStarted(_)).WillOnce(Return(kWindowId));
- callback.Run(MediaStreamDevices(), MEDIA_DEVICE_OK, std::move(ui));
+ std::move(callback).Run(MediaStreamDevices(), MEDIA_DEVICE_OK, std::move(ui));
EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _));
MockStopStreamHandler handler;
@@ -332,9 +347,8 @@ class MediaStreamUIProxyFeaturePolicyTest
private:
class TestRFHDelegate : public RenderFrameHostDelegate {
- void RequestMediaAccessPermission(
- const MediaStreamRequest& request,
- const MediaResponseCallback& callback) override {
+ void RequestMediaAccessPermission(const MediaStreamRequest& request,
+ MediaResponseCallback callback) override {
MediaStreamDevices devices;
if (request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE) {
devices.push_back(
@@ -345,7 +359,7 @@ class MediaStreamUIProxyFeaturePolicyTest
MediaStreamDevice(MEDIA_DEVICE_VIDEO_CAPTURE, "Camera", "Camera"));
}
std::unique_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
- callback.Run(devices, MEDIA_DEVICE_OK, std::move(ui));
+ std::move(callback).Run(devices, MEDIA_DEVICE_OK, std::move(ui));
}
};
diff --git a/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.cc b/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.cc
index 0252b256dbd..6e33963efe7 100644
--- a/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.cc
+++ b/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.cc
@@ -46,8 +46,8 @@ void OldEnumerateOutputDevices(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
MediaDevicesManager::BoolDeviceTypes device_types;
device_types[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
- media_devices_manager->EnumerateDevices(
- device_types, base::BindRepeating(cb, salt_and_origin));
+ media_devices_manager->EnumerateDevices(device_types,
+ base::BindOnce(cb, salt_and_origin));
}
} // namespace
diff --git a/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory_unittest.cc b/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory_unittest.cc
index 206fa9c9755..fb2e934df02 100644
--- a/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory_unittest.cc
@@ -78,7 +78,7 @@ class MockRendererAudioInputStreamFactoryClient
void StreamCreated(
media::mojom::AudioInputStreamPtr input_stream,
media::mojom::AudioInputStreamClientRequest client_request,
- media::mojom::AudioDataPipePtr data_pipe,
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
bool initially_muted,
const base::Optional<base::UnguessableToken>& stream_id) override {
EXPECT_TRUE(stream_id.has_value());
diff --git a/chromium/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory_unittest.cc b/chromium/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory_unittest.cc
index 94a1fb4c25a..b4f527af64f 100644
--- a/chromium/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory_unittest.cc
@@ -178,7 +178,7 @@ class MockClient : public AudioOutputStreamProviderClient {
}
void Created(AudioOutputStreamPtr stream,
- media::mojom::AudioDataPipePtr data_pipe) override {
+ media::mojom::ReadWriteAudioDataPipePtr data_pipe) override {
was_called_ = true;
stream_ = std::move(stream);
}
diff --git a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc
index 9dccd399f82..2e3d9fd57ce 100644
--- a/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc
+++ b/chromium/content/browser/renderer_host/media/peer_connection_tracker_host.cc
@@ -62,16 +62,19 @@ void PeerConnectionTrackerHost::OnChannelClosing() {
void PeerConnectionTrackerHost::OnAddPeerConnection(
const PeerConnectionInfo& info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
WebRTCInternals* webrtc_internals = WebRTCInternals::GetInstance();
if (webrtc_internals) {
webrtc_internals->OnAddPeerConnection(
render_process_id_, peer_pid(), info.lid, info.url,
info.rtc_configuration, info.constraints);
}
+
WebRtcEventLogger* const logger = WebRtcEventLogger::Get();
if (logger) {
logger->PeerConnectionAdded(render_process_id_, info.lid,
- info.peer_connection_id);
+ info.peer_connection_id,
+ base::OnceCallback<void(bool)>());
}
}
@@ -89,7 +92,8 @@ void PeerConnectionTrackerHost::RemovePeerConnection(int lid) {
}
WebRtcEventLogger* const logger = WebRtcEventLogger::Get();
if (logger) {
- logger->PeerConnectionRemoved(render_process_id_, lid);
+ logger->PeerConnectionRemoved(render_process_id_, lid,
+ base::OnceCallback<void(bool)>());
}
}
@@ -107,7 +111,8 @@ void PeerConnectionTrackerHost::UpdatePeerConnection(int lid,
if (type == "stop") {
WebRtcEventLogger* const logger = WebRtcEventLogger::Get();
if (logger) {
- logger->PeerConnectionStopped(render_process_id_, lid);
+ logger->PeerConnectionStopped(render_process_id_, lid,
+ base::OnceCallback<void(bool)>());
}
}
@@ -157,7 +162,9 @@ void PeerConnectionTrackerHost::WebRtcEventLogWrite(int lid,
}
WebRtcEventLogger* const logger = WebRtcEventLogger::Get();
if (logger) {
- logger->OnWebRtcEventLogWrite(render_process_id_, lid, output);
+ logger->OnWebRtcEventLogWrite(
+ render_process_id_, lid, output,
+ base::OnceCallback<void(std::pair<bool, bool>)>());
}
}
diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc
index 7a264cbd8cd..a07394101ea 100644
--- a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc
+++ b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc
@@ -4,6 +4,7 @@
#include "content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h"
+#include <string>
#include <utility>
#include "base/trace_event/trace_event.h"
@@ -45,8 +46,8 @@ void EnumerateOutputDevices(MediaStreamManager* media_stream_manager,
DCHECK_CURRENTLY_ON(BrowserThread::IO);
MediaDevicesManager::BoolDeviceTypes device_types;
device_types[MEDIA_DEVICE_TYPE_AUDIO_OUTPUT] = true;
- media_stream_manager->media_devices_manager()->EnumerateDevices(device_types,
- cb);
+ media_stream_manager->media_devices_manager()->EnumerateDevices(
+ device_types, std::move(cb));
}
void TranslateDeviceId(const std::string& device_id,
diff --git a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc
index 312193601b3..0a78c678b37 100644
--- a/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc
+++ b/chromium/content/browser/renderer_host/media/render_frame_audio_input_stream_factory_unittest.cc
@@ -127,7 +127,7 @@ class RenderFrameAudioInputStreamFactoryTest
void StreamCreated(
media::mojom::AudioInputStreamPtr stream,
media::mojom::AudioInputStreamClientRequest client_request,
- media::mojom::AudioDataPipePtr data_pipe,
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
bool initially_muted,
const base::Optional<base::UnguessableToken>& stream_id) override {}
};
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 f54b3f57900..2c04a18d030 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
@@ -40,6 +40,7 @@ class MockDeviceFactory : public video_capture::mojom::DeviceFactory {
void AddSharedMemoryVirtualDevice(
const media::VideoCaptureDeviceInfo& device_info,
video_capture::mojom::ProducerPtr producer,
+ bool send_buffer_handles_to_producer_as_raw_file_descriptors,
video_capture::mojom::SharedMemoryVirtualDeviceRequest virtual_device)
override {
DoAddVirtualDevice(device_info, producer.get(), &virtual_device);
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 1211057d4b8..52ae899701f 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
@@ -4,11 +4,15 @@
#include "content/browser/renderer_host/media/service_video_capture_provider.h"
+#include "content/browser/gpu/gpu_client_impl.h"
#include "content/browser/renderer_host/media/service_video_capture_device_launcher.h"
+#include "content/browser/renderer_host/media/video_capture_dependencies.h"
#include "content/browser/renderer_host/media/video_capture_factory_delegate.h"
+#include "content/common/child_process_host_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/service_manager_connection.h"
#include "mojo/public/cpp/bindings/callback_helpers.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/video_capture/public/mojom/constants.mojom.h"
#include "services/video_capture/public/uma/video_capture_service_event.h"
@@ -19,7 +23,7 @@ class ServiceConnectorImpl
: public content::ServiceVideoCaptureProvider::ServiceConnector {
public:
ServiceConnectorImpl() {
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// In unit test environments, there may not be any connector.
auto* connection = content::ServiceManagerConnection::GetForProcess();
if (!connection)
@@ -44,34 +48,51 @@ class ServiceConnectorImpl
std::unique_ptr<service_manager::Connector> connector_;
};
+class DelegateToBrowserGpuServiceAcceleratorFactory
+ : public video_capture::mojom::AcceleratorFactory {
+ public:
+ void CreateJpegDecodeAccelerator(
+ media::mojom::JpegDecodeAcceleratorRequest jda_request) override {
+ content::VideoCaptureDependencies::CreateJpegDecodeAccelerator(
+ std::move(jda_request));
+ }
+};
+
+std::unique_ptr<video_capture::mojom::AcceleratorFactory>
+CreateAcceleratorFactory() {
+ return std::make_unique<DelegateToBrowserGpuServiceAcceleratorFactory>();
+}
+
} // anonymous namespace
namespace content {
ServiceVideoCaptureProvider::ServiceVideoCaptureProvider(
base::RepeatingCallback<void(const std::string&)> emit_log_message_cb)
- : ServiceVideoCaptureProvider(std::make_unique<ServiceConnectorImpl>(),
- std::move(emit_log_message_cb)) {}
+ : ServiceVideoCaptureProvider(
+ std::make_unique<ServiceConnectorImpl>(),
+ base::BindRepeating(&CreateAcceleratorFactory),
+ std::move(emit_log_message_cb)) {}
ServiceVideoCaptureProvider::ServiceVideoCaptureProvider(
std::unique_ptr<ServiceConnector> service_connector,
+ CreateAcceleratorFactoryCallback create_accelerator_factory_cb,
base::RepeatingCallback<void(const std::string&)> emit_log_message_cb)
: service_connector_(std::move(service_connector)),
+ create_accelerator_factory_cb_(std::move(create_accelerator_factory_cb)),
emit_log_message_cb_(std::move(emit_log_message_cb)),
usage_count_(0),
launcher_has_connected_to_device_factory_(false),
- weak_ptr_factory_(this) {
- DETACH_FROM_SEQUENCE(sequence_checker_);
-}
+ weak_ptr_factory_(this) {}
ServiceVideoCaptureProvider::~ServiceVideoCaptureProvider() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
UninitializeInternal(ReasonForUninitialize::kShutdown);
}
void ServiceVideoCaptureProvider::GetDeviceInfosAsync(
GetDeviceInfosCallback result_callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
emit_log_message_cb_.Run("ServiceVideoCaptureProvider::GetDeviceInfosAsync");
IncreaseUsageCount();
LazyConnectToService();
@@ -86,7 +107,7 @@ void ServiceVideoCaptureProvider::GetDeviceInfosAsync(
std::unique_ptr<VideoCaptureDeviceLauncher>
ServiceVideoCaptureProvider::CreateDeviceLauncher() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
return std::make_unique<ServiceVideoCaptureDeviceLauncher>(
base::BindRepeating(&ServiceVideoCaptureProvider::ConnectToDeviceFactory,
weak_ptr_factory_.GetWeakPtr()));
@@ -94,7 +115,7 @@ ServiceVideoCaptureProvider::CreateDeviceLauncher() {
void ServiceVideoCaptureProvider::ConnectToDeviceFactory(
std::unique_ptr<VideoCaptureFactoryDelegate>* out_factory) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
IncreaseUsageCount();
LazyConnectToService();
launcher_has_connected_to_device_factory_ = true;
@@ -105,6 +126,7 @@ void ServiceVideoCaptureProvider::ConnectToDeviceFactory(
}
void ServiceVideoCaptureProvider::LazyConnectToService() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (device_factory_provider_.is_bound())
return;
@@ -123,7 +145,12 @@ void ServiceVideoCaptureProvider::LazyConnectToService() {
launcher_has_connected_to_device_factory_ = false;
time_of_last_connect_ = base::TimeTicks::Now();
+ video_capture::mojom::AcceleratorFactoryPtr accelerator_factory;
+ mojo::MakeStrongBinding(create_accelerator_factory_cb_.Run(),
+ mojo::MakeRequest(&accelerator_factory));
service_connector_->BindFactoryProvider(&device_factory_provider_);
+ device_factory_provider_->InjectGpuDependencies(
+ std::move(accelerator_factory));
device_factory_provider_->ConnectToDeviceFactory(
mojo::MakeRequest(&device_factory_));
// Unretained |this| is safe, because |this| owns |device_factory_|.
@@ -135,13 +162,13 @@ void ServiceVideoCaptureProvider::LazyConnectToService() {
void ServiceVideoCaptureProvider::OnDeviceInfosReceived(
GetDeviceInfosCallback result_callback,
const std::vector<media::VideoCaptureDeviceInfo>& infos) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
base::ResetAndReturn(&result_callback).Run(infos);
DecreaseUsageCount();
}
void ServiceVideoCaptureProvider::OnLostConnectionToDeviceFactory() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
emit_log_message_cb_.Run(
"ServiceVideoCaptureProvider::OnLostConnectionToDeviceFactory");
// This may indicate that the video capture service has crashed. Uninitialize
@@ -151,12 +178,12 @@ void ServiceVideoCaptureProvider::OnLostConnectionToDeviceFactory() {
}
void ServiceVideoCaptureProvider::IncreaseUsageCount() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
usage_count_++;
}
void ServiceVideoCaptureProvider::DecreaseUsageCount() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
usage_count_--;
DCHECK_GE(usage_count_, 0);
if (usage_count_ == 0)
@@ -165,7 +192,7 @@ void ServiceVideoCaptureProvider::DecreaseUsageCount() {
void ServiceVideoCaptureProvider::UninitializeInternal(
ReasonForUninitialize reason) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
if (!device_factory_.is_bound()) {
return;
}
diff --git a/chromium/content/browser/renderer_host/media/service_video_capture_provider.h b/chromium/content/browser/renderer_host/media/service_video_capture_provider.h
index 2ee46aae38d..7cc051d35af 100644
--- a/chromium/content/browser/renderer_host/media/service_video_capture_provider.h
+++ b/chromium/content/browser/renderer_host/media/service_video_capture_provider.h
@@ -27,14 +27,20 @@ class CONTENT_EXPORT ServiceVideoCaptureProvider : public VideoCaptureProvider {
video_capture::mojom::DeviceFactoryProviderPtr* provider) = 0;
};
- // The parameterless constructor creates a default ServiceConnector which
+ using CreateAcceleratorFactoryCallback = base::RepeatingCallback<
+ std::unique_ptr<video_capture::mojom::AcceleratorFactory>()>;
+
+ // This constructor creates a default ServiceConnector which
// uses the ServiceManager associated with the current process to connect
- // to the video capture service.
+ // to the video capture service. It uses a default factory for instances of
+ // ui::mojom::Gpu which produces instances of class content::GpuClient.
explicit ServiceVideoCaptureProvider(
base::RepeatingCallback<void(const std::string&)> emit_log_message_cb);
- // Lets clients provide a custom ServiceConnector.
+ // Lets clients provide a custom ServiceConnector and factory method for
+ // creating instances of ui::mojom::Gpu.
ServiceVideoCaptureProvider(
std::unique_ptr<ServiceConnector> service_connector,
+ CreateAcceleratorFactoryCallback create_accelerator_factory_cb,
base::RepeatingCallback<void(const std::string&)> emit_log_message_cb);
~ServiceVideoCaptureProvider() override;
@@ -56,6 +62,7 @@ class CONTENT_EXPORT ServiceVideoCaptureProvider : public VideoCaptureProvider {
void UninitializeInternal(ReasonForUninitialize reason);
std::unique_ptr<ServiceConnector> service_connector_;
+ CreateAcceleratorFactoryCallback create_accelerator_factory_cb_;
base::RepeatingCallback<void(const std::string&)> emit_log_message_cb_;
// We must hold on to |device_factory_provider_| because it holds the
// service-side binding for |device_factory_|.
@@ -63,7 +70,6 @@ class CONTENT_EXPORT ServiceVideoCaptureProvider : public VideoCaptureProvider {
video_capture::mojom::DeviceFactoryPtr device_factory_;
// Used for automatically uninitializing when no longer in use.
int usage_count_;
- SEQUENCE_CHECKER(sequence_checker_);
bool launcher_has_connected_to_device_factory_;
base::TimeTicks time_of_last_connect_;
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 6a683e5f5d1..b080b096ec5 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
@@ -6,9 +6,9 @@
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
-#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "content/public/browser/video_capture_device_launcher.h"
+#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/video_capture/public/mojom/device_factory.mojom.h"
#include "services/video_capture/public/mojom/device_factory_provider.mojom.h"
@@ -44,6 +44,14 @@ class MockDeviceFactoryProvider
DoConnectToDeviceFactory(request);
}
+ void InjectGpuDependencies(video_capture::mojom::AcceleratorFactoryPtr
+ accelerator_factory) override {
+ DoInjectGpuDependencies(accelerator_factory);
+ }
+
+ MOCK_METHOD1(
+ DoInjectGpuDependencies,
+ void(video_capture::mojom::AcceleratorFactoryPtr& accelerator_factory));
MOCK_METHOD1(SetShutdownDelayInSeconds, void(float seconds));
MOCK_METHOD1(DoConnectToDeviceFactory,
void(video_capture::mojom::DeviceFactoryRequest& request));
@@ -62,6 +70,7 @@ class MockDeviceFactory : public video_capture::mojom::DeviceFactory {
void AddSharedMemoryVirtualDevice(
const media::VideoCaptureDeviceInfo& device_info,
video_capture::mojom::ProducerPtr producer,
+ bool send_buffer_handles_to_producer_as_raw_file_descriptors,
video_capture::mojom::SharedMemoryVirtualDeviceRequest virtual_device)
override {
DoAddVirtualDevice(device_info, producer.get(), &virtual_device);
@@ -110,7 +119,10 @@ class ServiceVideoCaptureProviderTest : public testing::Test {
auto mock_service_connector = std::make_unique<MockServiceConnector>();
mock_service_connector_ = mock_service_connector.get();
provider_ = std::make_unique<ServiceVideoCaptureProvider>(
- std::move(mock_service_connector), kIgnoreLogMessageCB);
+ std::move(mock_service_connector), base::BindRepeating([]() {
+ return std::unique_ptr<video_capture::mojom::AcceleratorFactory>();
+ }),
+ kIgnoreLogMessageCB);
ON_CALL(*mock_service_connector_, BindFactoryProvider(_))
.WillByDefault(
@@ -133,7 +145,7 @@ class ServiceVideoCaptureProviderTest : public testing::Test {
void TearDown() override {}
- base::test::ScopedTaskEnvironment scoped_task_environment_;
+ content::TestBrowserThreadBundle test_browser_thread_bundle_;
MockServiceConnector* mock_service_connector_;
MockDeviceFactoryProvider mock_device_factory_provider_;
mojo::Binding<video_capture::mojom::DeviceFactoryProvider>
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 59b89dc83ae..ee5dd193529 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_browsertest.cc
@@ -115,6 +115,8 @@ class VideoCaptureBrowserTest : public ContentBrowserTest,
params_ = TestParams(GetParam());
if (params_.use_mojo_service) {
scoped_feature_list_.InitAndEnableFeature(features::kMojoVideoCapture);
+ } else {
+ scoped_feature_list_.InitAndDisableFeature(features::kMojoVideoCapture);
}
}
@@ -231,11 +233,6 @@ IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, StartAndImmediatelyStop) {
if (params_.use_mojo_service)
return;
#endif
- // Mojo video capture currently does not support accelerated jpeg decoding.
- // TODO(chfremer): Remove this as soon as https://crbug.com/720604 is
- // resolved.
- if (params_.use_mojo_service && params_.exercise_accelerated_jpeg_decoding)
- return;
SetUpRequiringBrowserMainLoopOnMainThread();
base::RunLoop run_loop;
@@ -274,21 +271,11 @@ IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest,
if (params_.use_mojo_service)
return;
#endif
- // Mojo video capture currently does not support accelerated jpeg decoding.
- // TODO(chfremer): Remove this as soon as https://crbug.com/720604 is
- // resolved.
- if (params_.use_mojo_service && params_.exercise_accelerated_jpeg_decoding)
- return;
// Only fake device with index 2 delivers MJPEG.
if (params_.exercise_accelerated_jpeg_decoding &&
- params_.device_index_to_use != 2)
- return;
- // There is an intermittent use-after-free in GpuChannelHost::Send() during
- // Browser shutdown, which causes MSan tests to fail.
- // TODO(chfremer): Remove this as soon as https://crbug.com/725271 is
- // resolved.
- if (params_.exercise_accelerated_jpeg_decoding)
+ params_.device_index_to_use != 2) {
return;
+ }
SetUpRequiringBrowserMainLoopOnMainThread();
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 26a225d1b9f..4a948b2c47f 100644
--- a/chromium/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/chromium/content/browser/renderer_host/media/video_capture_controller.cc
@@ -225,7 +225,8 @@ void VideoCaptureController::AddClient(
// report an error immediately and punt.
if (!params.IsValid() ||
!(params.requested_format.pixel_format == media::PIXEL_FORMAT_I420 ||
- params.requested_format.pixel_format == media::PIXEL_FORMAT_Y16)) {
+ params.requested_format.pixel_format == media::PIXEL_FORMAT_Y16 ||
+ params.requested_format.pixel_format == media::PIXEL_FORMAT_ARGB)) {
// Crash in debug builds since the renderer should not have asked for
// invalid or unsupported parameters.
LOG(DFATAL) << "Invalid or unsupported video capture parameters requested: "
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 cb0e9112390..a9ae13311f3 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
@@ -22,7 +22,6 @@
#include "content/browser/renderer_host/media/media_stream_provider.h"
#include "content/browser/renderer_host/media/mock_video_capture_provider.h"
#include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
-#include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h"
#include "content/browser/renderer_host/media/video_capture_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -31,6 +30,7 @@
#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_impl.h"
#include "media/capture/video/video_frame_receiver_on_task_runner.h"
#include "media/capture/video_capture_types.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -44,12 +44,6 @@ using ::testing::SaveArg;
namespace content {
-std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder(
- media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb) {
- return std::make_unique<content::VideoCaptureGpuJpegDecoder>(
- std::move(decode_done_cb), base::DoNothing());
-}
-
class MockVideoCaptureControllerEventHandler
: public VideoCaptureControllerEventHandler {
public:
@@ -160,13 +154,11 @@ class VideoCaptureControllerTest
std::make_unique<media::VideoCaptureBufferTrackerFactoryImpl>(),
kPoolSize);
device_client_.reset(new media::VideoCaptureDeviceClient(
+ media::VideoCaptureBufferType::kSharedMemory,
std::make_unique<media::VideoFrameReceiverOnTaskRunner>(
controller_->GetWeakPtrForIOThread(),
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)),
- buffer_pool_,
- base::Bind(&CreateGpuJpegDecoder,
- base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer,
- controller_->GetWeakPtrForIOThread()))));
+ buffer_pool_, media::VideoCaptureJpegDecoderFactoryCB()));
}
void SendStubFrameToDeviceClient(const media::VideoCaptureFormat format) {
diff --git a/chromium/content/browser/renderer_host/media/video_capture_dependencies.cc b/chromium/content/browser/renderer_host/media/video_capture_dependencies.cc
new file mode 100644
index 00000000000..26567c6579b
--- /dev/null
+++ b/chromium/content/browser/renderer_host/media/video_capture_dependencies.cc
@@ -0,0 +1,53 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/media/video_capture_dependencies.h"
+
+#include "content/browser/gpu/gpu_process_host.h"
+#include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace content {
+
+// static
+void VideoCaptureDependencies::CreateJpegDecodeAccelerator(
+ media::mojom::JpegDecodeAcceleratorRequest accelerator) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&VideoCaptureDependencies::CreateJpegDecodeAccelerator,
+ std::move(accelerator)));
+ return;
+ }
+
+ auto* host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
+ true /*force_create*/);
+ if (host) {
+ host->gpu_service()->CreateJpegDecodeAccelerator(std::move(accelerator));
+ } else {
+ LOG(ERROR) << "No GpuProcessHost";
+ }
+}
+
+// static
+void VideoCaptureDependencies::CreateJpegEncodeAccelerator(
+ media::mojom::JpegEncodeAcceleratorRequest accelerator) {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&VideoCaptureDependencies::CreateJpegEncodeAccelerator,
+ std::move(accelerator)));
+ return;
+ }
+
+ auto* host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
+ true /*force_create*/);
+ if (host) {
+ host->gpu_service()->CreateJpegEncodeAccelerator(std::move(accelerator));
+ } else {
+ LOG(ERROR) << "No GpuProcessHost";
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/media/video_capture_dependencies.h b/chromium/content/browser/renderer_host/media/video_capture_dependencies.h
new file mode 100644
index 00000000000..5804eef9f03
--- /dev/null
+++ b/chromium/content/browser/renderer_host/media/video_capture_dependencies.h
@@ -0,0 +1,25 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_DEPENDENCIES_H_
+#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_DEPENDENCIES_H_
+
+#include "content/common/content_export.h"
+#include "services/video_capture/public/mojom/device_factory.mojom.h"
+#include "services/viz/privileged/interfaces/gl/gpu_service.mojom.h"
+
+namespace content {
+
+// Browser-provided GPU dependencies for video capture.
+class CONTENT_EXPORT VideoCaptureDependencies {
+ public:
+ static void CreateJpegDecodeAccelerator(
+ media::mojom::JpegDecodeAcceleratorRequest accelerator);
+ static void CreateJpegEncodeAccelerator(
+ media::mojom::JpegEncodeAcceleratorRequest accelerator);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_DEPENDENCIES_H_
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
deleted file mode 100644
index f97690233f2..00000000000
--- a/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc
+++ /dev/null
@@ -1,336 +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/renderer_host/media/video_capture_gpu_jpeg_decoder.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#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"
-#include "content/browser/browser_main_loop.h"
-#include "content/browser/gpu/gpu_process_host.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_switches.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/base/media_switches.h"
-#include "media/base/video_frame.h"
-#include "mojo/public/cpp/system/platform_handle.h"
-#include "services/ui/public/cpp/gpu/gpu.h"
-
-namespace content {
-
-VideoCaptureGpuJpegDecoder::VideoCaptureGpuJpegDecoder(
- DecodeDoneCB decode_done_cb,
- base::Callback<void(const std::string&)> send_log_message_cb)
- : decode_done_cb_(std::move(decode_done_cb)),
- send_log_message_cb_(std::move(send_log_message_cb)),
- has_received_decoded_frame_(false),
- next_bitstream_buffer_id_(0),
- in_buffer_id_(media::JpegDecodeAccelerator::kInvalidBitstreamBufferId),
- decoder_status_(INIT_PENDING),
- weak_ptr_factory_(this) {}
-
-VideoCaptureGpuJpegDecoder::~VideoCaptureGpuJpegDecoder() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- // |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::BindOnce(&VideoCaptureGpuJpegDecoder::DestroyDecoderOnIOThread,
- base::Unretained(this), &event));
- event.Wait();
- }
-}
-
-void VideoCaptureGpuJpegDecoder::Initialize() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
- base::AutoLock lock(lock_);
- bool is_platform_supported =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kUseFakeJpegDecodeAccelerator);
-#if defined(OS_CHROMEOS)
- // Non-ChromeOS platforms do not support HW JPEG decode now. Do not establish
- // gpu channel to avoid introducing overhead.
- is_platform_supported = true;
-#endif
-
- if (!is_platform_supported ||
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableAcceleratedMjpegDecode)) {
- decoder_status_ = FAILED;
- RecordInitDecodeUMA_Locked();
- return;
- }
-
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&RequestGPUInfoOnIOThread,
- base::ThreadTaskRunnerHandle::Get(),
- weak_ptr_factory_.GetWeakPtr()));
-}
-
-VideoCaptureGpuJpegDecoder::STATUS VideoCaptureGpuJpegDecoder::GetStatus()
- const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- base::AutoLock lock(lock_);
- return decoder_status_;
-}
-
-void VideoCaptureGpuJpegDecoder::DecodeCapturedData(
- const uint8_t* data,
- size_t in_buffer_size,
- const media::VideoCaptureFormat& frame_format,
- base::TimeTicks reference_time,
- base::TimeDelta timestamp,
- media::VideoCaptureDevice::Client::Buffer out_buffer) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(decoder_);
-
- TRACE_EVENT_ASYNC_BEGIN0("jpeg", "VideoCaptureGpuJpegDecoder decoding",
- next_bitstream_buffer_id_);
- TRACE_EVENT0("jpeg", "VideoCaptureGpuJpegDecoder::DecodeCapturedData");
-
- // TODO(kcwu): enqueue decode requests in case decoding is not fast enough
- // (say, if decoding time is longer than 16ms for 60fps 4k image)
- {
- base::AutoLock lock(lock_);
- if (IsDecoding_Locked()) {
- DVLOG(1) << "Drop captured frame. Previous jpeg frame is still decoding";
- return;
- }
- }
-
- // Enlarge input buffer if necessary.
- if (!in_shared_memory_.get() ||
- in_buffer_size > in_shared_memory_->mapped_size()) {
- // Reserve 2x space to avoid frequent reallocations for initial frames.
- const size_t reserved_size = 2 * in_buffer_size;
- in_shared_memory_.reset(new base::SharedMemory);
- if (!in_shared_memory_->CreateAndMapAnonymous(reserved_size)) {
- base::AutoLock lock(lock_);
- decoder_status_ = FAILED;
- LOG(WARNING) << "CreateAndMapAnonymous failed, size=" << reserved_size;
- return;
- }
- }
- memcpy(in_shared_memory_->memory(), data, in_buffer_size);
-
- // No need to lock for |in_buffer_id_| since IsDecoding_Locked() is false.
- in_buffer_id_ = next_bitstream_buffer_id_;
- media::BitstreamBuffer in_buffer(in_buffer_id_, in_shared_memory_->handle(),
- in_buffer_size);
- // Mask against 30 bits, to avoid (undefined) wraparound on signed integer.
- next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF;
-
- // The API of |decoder_| requires us to wrap the |out_buffer| in a VideoFrame.
- const gfx::Size dimensions = frame_format.frame_size;
- std::unique_ptr<media::VideoCaptureBufferHandle> out_buffer_access =
- out_buffer.handle_provider->GetHandleForInProcessAccess();
- base::SharedMemoryHandle out_handle =
- out_buffer.handle_provider->GetNonOwnedSharedMemoryHandleForLegacyIPC();
- scoped_refptr<media::VideoFrame> out_frame =
- media::VideoFrame::WrapExternalSharedMemory(
- media::PIXEL_FORMAT_I420, // format
- dimensions, // coded_size
- gfx::Rect(dimensions), // visible_rect
- dimensions, // natural_size
- out_buffer_access->data(), // data
- out_buffer_access->mapped_size(), // data_size
- out_handle, // handle
- 0, // shared_memory_offset
- timestamp); // timestamp
- if (!out_frame) {
- base::AutoLock lock(lock_);
- decoder_status_ = FAILED;
- LOG(ERROR) << "DecodeCapturedData: WrapExternalSharedMemory failed";
- return;
- }
- // Hold onto the buffer access handle for the lifetime of the VideoFrame, to
- // ensure the data pointers remain valid.
- out_frame->AddDestructionObserver(base::BindOnce(
- [](std::unique_ptr<media::VideoCaptureBufferHandle> handle) {},
- std::move(out_buffer_access)));
- out_frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE,
- frame_format.frame_rate);
-
- out_frame->metadata()->SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME,
- reference_time);
-
- media::mojom::VideoFrameInfoPtr out_frame_info =
- media::mojom::VideoFrameInfo::New();
- out_frame_info->timestamp = timestamp;
- out_frame_info->pixel_format = media::PIXEL_FORMAT_I420;
- out_frame_info->coded_size = dimensions;
- out_frame_info->visible_rect = gfx::Rect(dimensions);
- out_frame_info->metadata = out_frame->metadata()->GetInternalValues().Clone();
-
- {
- base::AutoLock lock(lock_);
- decode_done_closure_ =
- base::Bind(decode_done_cb_, out_buffer.id, out_buffer.frame_feedback_id,
- base::Passed(&out_buffer.access_permission),
- base::Passed(&out_frame_info));
- }
-
- // base::Unretained is safe because |decoder_| is deleted on the IO thread.
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&media::JpegDecodeAccelerator::Decode,
- base::Unretained(decoder_.get()),
- in_buffer, std::move(out_frame)));
-}
-
-void VideoCaptureGpuJpegDecoder::VideoFrameReady(int32_t bitstream_buffer_id) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- TRACE_EVENT0("jpeg", "VideoCaptureGpuJpegDecoder::VideoFrameReady");
- if (!has_received_decoded_frame_) {
- send_log_message_cb_.Run("Received decoded frame from Gpu Jpeg decoder");
- has_received_decoded_frame_ = true;
- }
- base::AutoLock lock(lock_);
-
- if (!IsDecoding_Locked()) {
- LOG(ERROR) << "Got decode response while not decoding";
- return;
- }
-
- if (bitstream_buffer_id != in_buffer_id_) {
- LOG(ERROR) << "Unexpected bitstream_buffer_id " << bitstream_buffer_id
- << ", expected " << in_buffer_id_;
- return;
- }
- in_buffer_id_ = media::JpegDecodeAccelerator::kInvalidBitstreamBufferId;
-
- decode_done_closure_.Run();
- decode_done_closure_.Reset();
-
- TRACE_EVENT_ASYNC_END0("jpeg", "VideoCaptureGpuJpegDecoder decoding",
- bitstream_buffer_id);
-}
-
-void VideoCaptureGpuJpegDecoder::NotifyError(
- int32_t bitstream_buffer_id,
- media::JpegDecodeAccelerator::Error error) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- LOG(ERROR) << "Decode error, bitstream_buffer_id=" << bitstream_buffer_id
- << ", error=" << error;
- send_log_message_cb_.Run("Gpu Jpeg decoder failed");
- base::AutoLock lock(lock_);
- decode_done_closure_.Reset();
- decoder_status_ = FAILED;
-}
-
-// static
-void VideoCaptureGpuJpegDecoder::RequestGPUInfoOnIOThread(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- GpuProcessHost* host =
- GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, false);
- if (host) {
- host->RequestGPUInfo(
- base::Bind(&VideoCaptureGpuJpegDecoder::DidReceiveGPUInfoOnIOThread,
- task_runner, weak_this));
- } else {
- DidReceiveGPUInfoOnIOThread(std::move(task_runner), std::move(weak_this),
- gpu::GPUInfo());
- }
-}
-
-// static
-void VideoCaptureGpuJpegDecoder::DidReceiveGPUInfoOnIOThread(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this,
- const gpu::GPUInfo& gpu_info) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
- media::mojom::JpegDecodeAcceleratorPtr remote_decoder;
-
- 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, remote_decoder.PassInterface()));
-}
-
-void VideoCaptureGpuJpegDecoder::FinishInitialization(
- 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_ = std::make_unique<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::BindOnce(&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 (!success) {
- BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, decoder_.release());
- DLOG(ERROR) << "Failed to initialize JPEG decoder";
- }
-
- decoder_status_ = success ? INIT_PASSED : FAILED;
- RecordInitDecodeUMA_Locked();
-}
-
-bool VideoCaptureGpuJpegDecoder::IsDecoding_Locked() const {
- lock_.AssertAcquired();
- return !decode_done_closure_.is_null();
-}
-
-void VideoCaptureGpuJpegDecoder::RecordInitDecodeUMA_Locked() {
- UMA_HISTOGRAM_BOOLEAN("Media.VideoCaptureGpuJpegDecoder.InitDecodeSuccess",
- 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
deleted file mode 100644
index bf089ba6e83..00000000000
--- a/chromium/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h
+++ /dev/null
@@ -1,123 +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_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_GPU_JPEG_DECODER_H_
-#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_GPU_JPEG_DECODER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
-#include "content/common/content_export.h"
-#include "gpu/config/gpu_info.h"
-#include "media/capture/video/video_capture_jpeg_decoder.h"
-#include "media/mojo/clients/mojo_jpeg_decode_accelerator.h"
-
-namespace base {
-class WaitableEvent;
-}
-
-namespace content {
-
-// Adapter to GpuJpegDecodeAccelerator for VideoCaptureDevice::Client. It takes
-// care of GpuJpegDecodeAccelerator creation, shared memory, and threading
-// issues.
-//
-// All public methods except JpegDecodeAccelerator::Client ones should be called
-// on the same thread. JpegDecodeAccelerator::Client methods should be called on
-// the IO thread.
-class CONTENT_EXPORT VideoCaptureGpuJpegDecoder
- : public media::VideoCaptureJpegDecoder,
- public media::JpegDecodeAccelerator::Client {
- public:
- // |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(
- DecodeDoneCB decode_done_cb,
- base::Callback<void(const std::string&)> send_log_message_cb);
- ~VideoCaptureGpuJpegDecoder() override;
-
- // Implementation of VideoCaptureJpegDecoder:
- void Initialize() override;
- STATUS GetStatus() const override;
- void DecodeCapturedData(
- const uint8_t* data,
- size_t in_buffer_size,
- const media::VideoCaptureFormat& frame_format,
- base::TimeTicks reference_time,
- base::TimeDelta timestamp,
- media::VideoCaptureDevice::Client::Buffer out_buffer) override;
-
- // JpegDecodeAccelerator::Client implementation.
- // These will be called on IO thread.
- void VideoFrameReady(int32_t buffer_id) override;
- void NotifyError(int32_t buffer_id,
- media::JpegDecodeAccelerator::Error error) override;
-
- private:
- static void RequestGPUInfoOnIOThread(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this);
-
- static void DidReceiveGPUInfoOnIOThread(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this,
- const gpu::GPUInfo& gpu_info);
-
- void FinishInitialization(
- 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;
-
- // Records |decoder_status_| to histogram.
- void RecordInitDecodeUMA_Locked();
-
- void DestroyDecoderOnIOThread(base::WaitableEvent* event);
-
- // The underlying JPEG decode accelerator.
- std::unique_ptr<media::JpegDecodeAccelerator> decoder_;
-
- // The callback to run when decode succeeds.
- const DecodeDoneCB decode_done_cb_;
-
- const base::Callback<void(const std::string&)> send_log_message_cb_;
- bool has_received_decoded_frame_;
-
- // Guards |decode_done_closure_| and |decoder_status_|.
- mutable base::Lock lock_;
-
- // The closure of |decode_done_cb_| with bound parameters.
- base::Closure decode_done_closure_;
-
- // Next id for input BitstreamBuffer.
- int32_t next_bitstream_buffer_id_;
-
- // The id for current input BitstreamBuffer being decoded.
- int32_t in_buffer_id_;
-
- // Shared memory to store JPEG stream buffer. The input BitstreamBuffer is
- // backed by this.
- std::unique_ptr<base::SharedMemory> in_shared_memory_;
-
- STATUS decoder_status_;
-
- SEQUENCE_CHECKER(sequence_checker_);
-
- base::WeakPtrFactory<VideoCaptureGpuJpegDecoder> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(VideoCaptureGpuJpegDecoder);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_GPU_JPEG_DECODER_H_
diff --git a/chromium/content/browser/renderer_host/overscroll_controller.cc b/chromium/content/browser/renderer_host/overscroll_controller.cc
index a4bb1af79d3..73c7bbe0e26 100644
--- a/chromium/content/browser/renderer_host/overscroll_controller.cc
+++ b/chromium/content/browser/renderer_host/overscroll_controller.cc
@@ -46,9 +46,7 @@ float ClampAbsoluteValue(float value, float max_abs) {
} // namespace
-OverscrollController::OverscrollController()
- : wheel_scroll_latching_enabled_(base::FeatureList::IsEnabled(
- features::kTouchpadAndWheelScrollLatching)) {}
+OverscrollController::OverscrollController() {}
OverscrollController::~OverscrollController() {}
@@ -343,14 +341,8 @@ bool OverscrollController::ProcessEventForOverscroll(
bool event_processed = false;
switch (event.GetType()) {
case blink::WebInputEvent::kGestureScrollBegin: {
- // When wheel scroll latching is disabled avoid resetting the state on
- // GestureScrollBegin generated from the touchpad since it is sent for
- // every wheel event.
- if (overscroll_mode_ != OVERSCROLL_NONE &&
- (!IsGestureEventFromTouchpad(event) ||
- wheel_scroll_latching_enabled_)) {
+ if (overscroll_mode_ != OVERSCROLL_NONE)
SetOverscrollMode(OVERSCROLL_NONE, OverscrollSource::NONE);
- }
break;
}
case blink::WebInputEvent::kGestureScrollEnd: {
diff --git a/chromium/content/browser/renderer_host/overscroll_controller.h b/chromium/content/browser/renderer_host/overscroll_controller.h
index dbc94c174bd..d876007493c 100644
--- a/chromium/content/browser/renderer_host/overscroll_controller.h
+++ b/chromium/content/browser/renderer_host/overscroll_controller.h
@@ -163,8 +163,6 @@ class CONTENT_EXPORT OverscrollController {
// owned by this controller.
OverscrollControllerDelegate* delegate_ = nullptr;
- bool wheel_scroll_latching_enabled_;
-
// A inertial scroll (fling) event may complete an overscroll gesture and
// navigate to a new page or cancel the overscroll animation. In both cases
// inertial scroll can continue to generate scroll-update events. These events
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 c8bfe794b21..270b2aaee40 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
@@ -14,7 +14,6 @@
#include "content/browser/renderer_host/p2p/socket_host.h"
#include "content/common/p2p_messages.h"
#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/resource_context.h"
#include "net/base/address_list.h"
#include "net/base/completion_callback.h"
#include "net/base/net_errors.h"
@@ -26,6 +25,7 @@
#include "net/socket/client_socket_factory.h"
#include "net/socket/datagram_client_socket.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 "services/network/proxy_resolving_client_socket_factory.h"
@@ -119,10 +119,8 @@ class P2PSocketDispatcherHost::DnsRequest {
};
P2PSocketDispatcherHost::P2PSocketDispatcherHost(
- content::ResourceContext* resource_context,
net::URLRequestContextGetter* url_context)
: BrowserMessageFilter(P2PMsgStart),
- resource_context_(resource_context),
url_context_(url_context),
monitoring_networks_(false),
dump_incoming_rtp_packet_(false),
@@ -140,6 +138,8 @@ void P2PSocketDispatcherHost::OnChannelClosing() {
net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
monitoring_networks_ = false;
}
+
+ proxy_resolving_socket_factory_.reset();
}
void P2PSocketDispatcherHost::OnDestruct() const {
@@ -241,7 +241,7 @@ void P2PSocketDispatcherHost::OnStopNetworkNotifications() {
void P2PSocketDispatcherHost::OnGetHostAddress(const std::string& host_name,
int32_t request_id) {
std::unique_ptr<DnsRequest> request = std::make_unique<DnsRequest>(
- request_id, resource_context_->GetHostResolver());
+ request_id, url_context_->GetURLRequestContext()->host_resolver());
DnsRequest* request_ptr = request.get();
dns_requests_.insert(std::move(request));
request_ptr->Resolve(host_name,
@@ -270,7 +270,7 @@ void P2PSocketDispatcherHost::OnCreateSocket(
if (!proxy_resolving_socket_factory_) {
proxy_resolving_socket_factory_ =
std::make_unique<network::ProxyResolvingClientSocketFactory>(
- nullptr, url_context_->GetURLRequestContext());
+ url_context_->GetURLRequestContext());
}
if (sockets_.size() > kMaxSimultaneousSockets) {
LOG(ERROR) << "Too many sockets created";
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 120adbe8a13..288c834e422 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h
+++ b/chromium/content/browser/renderer_host/p2p/socket_dispatcher_host.h
@@ -36,14 +36,12 @@ class ProxyResolvingClientSocketFactory;
namespace content {
class P2PSocketHost;
-class ResourceContext;
class P2PSocketDispatcherHost
: public content::BrowserMessageFilter,
public net::NetworkChangeNotifier::NetworkChangeObserver {
public:
- P2PSocketDispatcherHost(content::ResourceContext* resource_context,
- net::URLRequestContextGetter* url_context);
+ explicit P2PSocketDispatcherHost(net::URLRequestContextGetter* url_context);
// content::BrowserMessageFilter overrides.
void OnChannelClosing() override;
@@ -111,7 +109,6 @@ class P2PSocketDispatcherHost
void StopRtpDumpOnIOThread(bool incoming, bool outgoing);
- content::ResourceContext* resource_context_;
scoped_refptr<net::URLRequestContextGetter> url_context_;
// Initialized on browser IO thread.
std::unique_ptr<network::ProxyResolvingClientSocketFactory>
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 5a5ba5d953b..efc6c63a375 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_tcp.cc
@@ -123,10 +123,8 @@ bool P2PSocketHostTcpBase::Init(const net::IPEndPoint& local_address,
// find a way to inject this into ProxyResolvingClientSocket. This could be
// a problem on multi-homed host.
- // The default SSLConfig is good enough for us for now.
- const net::SSLConfig ssl_config;
socket_ = proxy_resolving_socket_factory_->CreateSocket(
- ssl_config, GURL("https://" + dest_host_port_pair.ToString()),
+ GURL("https://" + dest_host_port_pair.ToString()),
IsTlsClientSocket(type_));
if (IsPseudoTlsClientSocket(type_)) {
diff --git a/chromium/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc b/chromium/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
index 37dd69132e0..1017d6bb1d9 100644
--- a/chromium/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
+++ b/chromium/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
@@ -487,8 +487,7 @@ TEST(P2PSocketHostTcpWithPseudoTlsTest, Basic) {
net::MockClientSocketFactory mock_socket_factory;
context.set_client_socket_factory(&mock_socket_factory);
context.Init();
- network::ProxyResolvingClientSocketFactory factory(&mock_socket_factory,
- &context);
+ network::ProxyResolvingClientSocketFactory factory(&context);
base::StringPiece ssl_client_hello =
jingle_glue::FakeSSLClientSocket::GetSslClientHello();
@@ -544,8 +543,7 @@ TEST_P(P2PSocketHostTcpWithTlsTest, Basic) {
net::MockClientSocketFactory mock_socket_factory;
context.set_client_socket_factory(&mock_socket_factory);
context.Init();
- network::ProxyResolvingClientSocketFactory factory(&mock_socket_factory,
- &context);
+ network::ProxyResolvingClientSocketFactory factory(&context);
const net::IoMode io_mode = std::get<0>(GetParam());
const P2PSocketType socket_type = std::get<1>(GetParam());
// OnOpen() calls DoRead(), so populate the mock socket with a pending read.
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 925e600eb16..dafc06ba0fa 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
@@ -13,6 +13,7 @@
#include "base/sys_byteorder.h"
#include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
#include "content/browser/renderer_host/p2p/socket_host_throttler.h"
+#include "net/base/completion_once_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
@@ -90,7 +91,7 @@ class FakeDatagramServerSocket : public net::DatagramServerSocket {
int RecvFrom(net::IOBuffer* buf,
int buf_len,
net::IPEndPoint* address,
- const net::CompletionCallback& callback) override {
+ net::CompletionOnceCallback callback) override {
CHECK(recv_callback_.is_null());
if (incoming_packets_.size() > 0) {
scoped_refptr<net::IOBuffer> buffer(buf);
@@ -101,7 +102,7 @@ class FakeDatagramServerSocket : public net::DatagramServerSocket {
incoming_packets_.pop_front();
return size;
} else {
- recv_callback_ = callback;
+ recv_callback_ = std::move(callback);
recv_buffer_ = buf;
recv_size_ = buf_len;
recv_address_ = address;
@@ -112,7 +113,7 @@ class FakeDatagramServerSocket : public net::DatagramServerSocket {
int SendTo(net::IOBuffer* buf,
int buf_len,
const net::IPEndPoint& address,
- const net::CompletionCallback& callback) override {
+ net::CompletionOnceCallback callback) override {
scoped_refptr<net::IOBuffer> buffer(buf);
std::vector<char> data_vector(buffer->data(), buffer->data() + buf_len);
sent_packets_->push_back(UDPPacket(address, data_vector));
@@ -132,10 +133,8 @@ class FakeDatagramServerSocket : public net::DatagramServerSocket {
int size = std::min(recv_size_, static_cast<int>(data.size()));
memcpy(recv_buffer_->data(), &*data.begin(), size);
*recv_address_ = address;
- net::CompletionCallback cb = recv_callback_;
- recv_callback_.Reset();
recv_buffer_ = nullptr;
- std::move(cb).Run(size);
+ std::move(recv_callback_).Run(size);
} else {
incoming_packets_.push_back(UDPPacket(address, data));
}
@@ -188,7 +187,7 @@ class FakeDatagramServerSocket : public net::DatagramServerSocket {
scoped_refptr<net::IOBuffer> recv_buffer_;
net::IPEndPoint* recv_address_;
int recv_size_;
- net::CompletionCallback recv_callback_;
+ net::CompletionOnceCallback recv_callback_;
std::vector<uint16_t>* used_ports_;
};
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc
index dd9483958d0..474c1683dcd 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_file_io_host.cc
@@ -514,7 +514,7 @@ bool PepperFileIOHost::AddFileToReplyContext(
// A non-zero resource id signals NaClIPCAdapter to create a NaClQuotaDesc.
PP_Resource quota_file_io = check_quota_ ? pp_resource() : 0;
file_handle.set_file_handle(transit_file, open_flags, quota_file_io);
- reply_context->params.AppendHandle(file_handle);
+ reply_context->params.AppendHandle(std::move(file_handle));
return true;
}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host.cc b/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host.cc
index 94059da48e9..d4140d9d49e 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host.cc
@@ -68,11 +68,12 @@ int32_t PepperGamepadHost::OnRequestMemory(
void PepperGamepadHost::GotUserGesture(
const ppapi::host::ReplyMessageContext& context) {
- base::SharedMemoryHandle handle =
- gamepad_service_->DuplicateSharedMemoryHandle();
+ base::ReadOnlySharedMemoryRegion region =
+ gamepad_service_->DuplicateSharedMemoryRegion();
context.params.AppendHandle(ppapi::proxy::SerializedHandle(
- handle, sizeof(device::GamepadHardwareBuffer)));
+ base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
+ std::move(region))));
host()->SendReply(context, PpapiPluginMsg_Gamepad_SendMemory());
}
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc b/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc
index abe26a38266..61e40743228 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc
@@ -90,15 +90,18 @@ TEST_F(PepperGamepadHostTest, WaitForReply) {
ASSERT_TRUE(sink().GetFirstResourceReplyMatching(
PpapiPluginMsg_Gamepad_SendMemory::ID, &reply_params, &reply_msg));
- // Extract the shared memory handle.
- base::SharedMemoryHandle reply_handle;
- EXPECT_TRUE(reply_params.TakeSharedMemoryHandleAtIndex(0, &reply_handle));
+ // Extract the shared memory region.
+ base::ReadOnlySharedMemoryRegion shared_memory_region;
+ EXPECT_TRUE(reply_params.TakeReadOnlySharedMemoryRegionAtIndex(
+ 0, &shared_memory_region));
// Validate the shared memory.
- base::SharedMemory shared_memory(reply_handle, true);
- EXPECT_TRUE(shared_memory.Map(sizeof(device::GamepadHardwareBuffer)));
+ base::ReadOnlySharedMemoryMapping shared_memory_mapping =
+ shared_memory_region.Map();
+ EXPECT_TRUE(shared_memory_mapping.IsValid());
const device::GamepadHardwareBuffer* buffer =
- static_cast<const device::GamepadHardwareBuffer*>(shared_memory.memory());
+ static_cast<const device::GamepadHardwareBuffer*>(
+ shared_memory_mapping.memory());
EXPECT_EQ(button_down_data.items[0].buttons_length,
buffer->data.items[0].buttons_length);
for (size_t i = 0; i < device::Gamepad::kButtonsLengthCap; i++) {
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 a7eb91795c4..94a1f646ba9 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
@@ -15,10 +15,12 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/resource_context.h"
+#include "content/public/browser/storage_partition.h"
#include "content/public/common/socket_permission_request.h"
#include "net/base/address_list.h"
#include "net/dns/host_resolver.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_host_resolver_private.h"
#include "ppapi/c/private/ppb_net_address_private.h"
@@ -138,15 +140,14 @@ int32_t PepperHostResolverMessageFilter::OnMsgResolve(
RenderProcessHost::FromID(render_process_id_);
if (!render_process_host)
return PP_ERROR_FAILED;
- BrowserContext* browser_context = render_process_host->GetBrowserContext();
- if (!browser_context || !browser_context->GetResourceContext())
- return PP_ERROR_FAILED;
+ auto* storage_partition = render_process_host->GetStoragePartition();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::BindOnce(&PepperHostResolverMessageFilter::DoResolve, this,
- context->MakeReplyMessageContext(), host_port, hint,
- browser_context->GetResourceContext()));
+ base::BindOnce(
+ &PepperHostResolverMessageFilter::DoResolve, this,
+ context->MakeReplyMessageContext(), host_port, hint,
+ base::WrapRefCounted(storage_partition->GetURLRequestContext())));
return PP_OK_COMPLETIONPENDING;
}
@@ -154,10 +155,17 @@ void PepperHostResolverMessageFilter::DoResolve(
const ReplyMessageContext& context,
const ppapi::HostPortPair& host_port,
const PP_HostResolver_Private_Hint& hint,
- ResourceContext* resource_context) {
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- net::HostResolver* host_resolver = resource_context->GetHostResolver();
+ auto* url_request_context =
+ url_request_context_getter->GetURLRequestContext();
+ if (!url_request_context) {
+ SendResolveError(PP_ERROR_FAILED, context);
+ return;
+ }
+
+ net::HostResolver* host_resolver = url_request_context->host_resolver();
if (!host_resolver) {
SendResolveError(PP_ERROR_FAILED, context);
return;
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h b/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h
index 42f75696e13..cd9f2121322 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_host_resolver_message_filter.h
@@ -22,6 +22,7 @@ struct PP_NetAddress_Private;
namespace net {
class AddressList;
+class URLRequestContextGetter;
}
namespace ppapi {
@@ -35,7 +36,6 @@ struct HostMessageContext;
namespace content {
class BrowserPpapiHostImpl;
-class ResourceContext;
class CONTENT_EXPORT PepperHostResolverMessageFilter
: public ppapi::host::ResourceMessageFilter {
@@ -63,10 +63,11 @@ class CONTENT_EXPORT PepperHostResolverMessageFilter
// Backend for OnMsgResolve(). Delegates host resolution to the
// Browser's HostResolver. Must be called on the IO thread.
- void DoResolve(const ppapi::host::ReplyMessageContext& context,
- const ppapi::HostPortPair& host_port,
- const PP_HostResolver_Private_Hint& hint,
- ResourceContext* resource_context);
+ void DoResolve(
+ const ppapi::host::ReplyMessageContext& context,
+ const ppapi::HostPortPair& host_port,
+ const PP_HostResolver_Private_Hint& hint,
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
void OnLookupFinished(int net_result,
const net::AddressList& addresses,
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 81c7cc8958e..17d9f021651 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
@@ -19,7 +19,7 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/resource_context.h"
+#include "content/public/browser/storage_partition.h"
#include "content/public/common/socket_permission_request.h"
#include "net/base/address_family.h"
#include "net/base/host_port_pair.h"
@@ -33,6 +33,8 @@
#include "net/socket/ssl_client_socket.h"
#include "net/socket/tcp_client_socket.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/host/dispatch_host_message.h"
#include "ppapi/host/error_conversion.h"
#include "ppapi/host/ppapi_host.h"
@@ -264,15 +266,14 @@ int32_t PepperTCPSocketMessageFilter::OnMsgConnect(
RenderProcessHost::FromID(render_process_id_);
if (!render_process_host)
return PP_ERROR_FAILED;
- BrowserContext* browser_context = render_process_host->GetBrowserContext();
- if (!browser_context || !browser_context->GetResourceContext())
- return PP_ERROR_FAILED;
+ auto* storage_partition = render_process_host->GetStoragePartition();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::BindOnce(&PepperTCPSocketMessageFilter::DoConnect, this,
- context->MakeReplyMessageContext(), host, port,
- browser_context->GetResourceContext()));
+ base::BindOnce(
+ &PepperTCPSocketMessageFilter::DoConnect, this,
+ context->MakeReplyMessageContext(), host, port,
+ base::WrapRefCounted(storage_partition->GetURLRequestContext())));
return PP_OK_COMPLETIONPENDING;
}
@@ -624,7 +625,7 @@ void PepperTCPSocketMessageFilter::DoConnect(
const ppapi::host::ReplyMessageContext& context,
const std::string& host,
uint16_t port,
- ResourceContext* resource_context) {
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!state_.IsValidTransition(TCPSocketState::CONNECT)) {
@@ -632,12 +633,25 @@ void PepperTCPSocketMessageFilter::DoConnect(
return;
}
+ auto* url_request_context =
+ url_request_context_getter->GetURLRequestContext();
+ if (!url_request_context) {
+ SendConnectError(context, PP_ERROR_FAILED);
+ return;
+ }
+
+ net::HostResolver* host_resolver = url_request_context->host_resolver();
+ if (!host_resolver) {
+ SendConnectError(context, PP_ERROR_FAILED);
+ return;
+ }
+
state_.SetPendingTransition(TCPSocketState::CONNECT);
address_index_ = 0;
address_list_.clear();
net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port));
- net::HostResolver* resolver = resource_context->GetHostResolver();
- int net_result = resolver->Resolve(
+
+ int net_result = host_resolver->Resolve(
request_info, net::DEFAULT_PRIORITY, &address_list_,
base::Bind(&PepperTCPSocketMessageFilter::OnResolveCompleted,
base::Unretained(this), context),
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
index 936dd339ebe..fec0b7cbf0c 100644
--- a/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
+++ b/chromium/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h
@@ -38,6 +38,7 @@ namespace net {
class DrainableIOBuffer;
class IOBuffer;
class SSLClientSocket;
+class URLRequestContextGetter;
}
namespace ppapi {
@@ -52,7 +53,6 @@ namespace content {
class BrowserPpapiHostImpl;
class ContentBrowserPepperHostFactory;
-class ResourceContext;
class CONTENT_EXPORT PepperTCPSocketMessageFilter
: public ppapi::host::ResourceMessageFilter,
@@ -119,10 +119,11 @@ class CONTENT_EXPORT PepperTCPSocketMessageFilter
void DoBind(const ppapi::host::ReplyMessageContext& context,
const PP_NetAddress_Private& net_addr);
- void DoConnect(const ppapi::host::ReplyMessageContext& context,
- const std::string& host,
- uint16_t port,
- ResourceContext* resource_context);
+ void DoConnect(
+ const ppapi::host::ReplyMessageContext& context,
+ const std::string& host,
+ uint16_t port,
+ scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
void DoConnectWithNetAddress(const ppapi::host::ReplyMessageContext& context,
const PP_NetAddress_Private& net_addr);
void DoWrite(const ppapi::host::ReplyMessageContext& context);
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_android.cc b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_android.cc
deleted file mode 100644
index d259aae2526..00000000000
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_android.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/logging.h"
-#include "content/browser/renderer_host/pepper/pepper_truetype_font.h"
-
-namespace content {
-
-// static
-PepperTrueTypeFont* PepperTrueTypeFont::Create() {
- NOTIMPLEMENTED(); // Not implemented on Android.
- return NULL;
-}
-
-} // namespace content
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 c9a8d3fd8c6..c71954e48c5 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
@@ -14,8 +14,10 @@
#include "base/macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/sys_byteorder.h"
-#include "content/browser/renderer_host/font_utils_linux.h"
+#include "build/build_config.h"
+#include "components/services/font/ppapi_fontconfig_matching.h"
#include "content/public/common/common_sandbox_support_linux.h"
+#include "ppapi/buildflags/buildflags.h"
#include "ppapi/c/dev/ppb_truetype_font_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/trusted/ppb_browser_font_trusted.h"
@@ -74,12 +76,10 @@ int32_t PepperTrueTypeFontLinux::Initialize(
}
}
- fd_.reset(
- MatchFontFaceWithFallback(desc->family,
- desc->weight >= PP_TRUETYPEFONTWEIGHT_BOLD,
- desc->style & PP_TRUETYPEFONTSTYLE_ITALIC,
- desc->charset,
- PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT));
+ fd_.reset(font_service::MatchFontFaceWithFallback(
+ desc->family, desc->weight >= PP_TRUETYPEFONTWEIGHT_BOLD,
+ desc->style & PP_TRUETYPEFONTSTYLE_ITALIC, desc->charset,
+ PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT));
// TODO(bbudge) Modify content API to return results of font matching and
// fallback, so we can update |desc| to reflect that.
return fd_.is_valid() ? PP_OK : PP_ERROR_FAILED;
diff --git a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_android.cc b/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_android.cc
deleted file mode 100644
index 28db24f7ffa..00000000000
--- a/chromium/content/browser/renderer_host/pepper/pepper_truetype_font_list_android.cc
+++ /dev/null
@@ -1,20 +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 "base/logging.h"
-#include "content/browser/renderer_host/pepper/pepper_truetype_font_list.h"
-
-namespace content {
-
-void GetFontFamilies_SlowBlocking(std::vector<std::string>* font_families) {
- NOTIMPLEMENTED(); // Font API isn't implemented on Android.
-}
-
-void GetFontsInFamily_SlowBlocking(
- const std::string& family,
- std::vector<ppapi::proxy::SerializedTrueTypeFontDesc>* fonts_in_family) {
- NOTIMPLEMENTED(); // Font API isn't implemented on Android.
-}
-
-} // namespace content
diff --git a/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc b/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc
index 03ade3604d1..204ed5af76e 100644
--- a/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc
+++ b/chromium/content/browser/renderer_host/pepper/quota_reservation_unittest.cc
@@ -21,6 +21,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "storage/browser/fileapi/quota/quota_reservation.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "url/origin.h"
using storage::QuotaReservationManager;
@@ -44,7 +45,7 @@ class FakeBackend : public QuotaReservationManager::QuotaBackend {
~FakeBackend() override {}
void ReserveQuota(
- const GURL& origin,
+ const url::Origin& origin,
storage::FileSystemType type,
int64_t delta,
const QuotaReservationManager::ReserveQuotaCallback& callback) override {
@@ -53,17 +54,17 @@ class FakeBackend : public QuotaReservationManager::QuotaBackend {
base::File::FILE_OK, delta));
}
- void ReleaseReservedQuota(const GURL& origin,
+ void ReleaseReservedQuota(const url::Origin& origin,
storage::FileSystemType type,
int64_t size) override {}
- void CommitQuotaUsage(const GURL& origin,
+ void CommitQuotaUsage(const url::Origin& origin,
storage::FileSystemType type,
int64_t delta) override {}
- void IncrementDirtyCount(const GURL& origin,
+ void IncrementDirtyCount(const url::Origin& origin,
storage::FileSystemType type) override {}
- void DecrementDirtyCount(const GURL& origin,
+ void DecrementDirtyCount(const url::Origin& origin,
storage::FileSystemType type) override {}
private:
@@ -160,7 +161,8 @@ TEST_F(QuotaReservationTest, ReserveQuota) {
storage::FileSystemType type = kType;
scoped_refptr<storage::QuotaReservation> reservation(
- reservation_manager()->CreateReservation(origin, type));
+ reservation_manager()->CreateReservation(url::Origin::Create(origin),
+ type));
scoped_refptr<QuotaReservation> test =
CreateQuotaReservation(reservation, origin, type);
@@ -201,7 +203,8 @@ TEST_F(QuotaReservationTest, MultipleFiles) {
storage::FileSystemType type = kType;
scoped_refptr<storage::QuotaReservation> reservation(
- reservation_manager()->CreateReservation(origin, type));
+ reservation_manager()->CreateReservation(url::Origin::Create(origin),
+ type));
scoped_refptr<QuotaReservation> test =
CreateQuotaReservation(reservation, origin, type);
diff --git a/chromium/content/browser/renderer_host/plugin_registry_impl.cc b/chromium/content/browser/renderer_host/plugin_registry_impl.cc
new file mode 100644
index 00000000000..ec071f3b89c
--- /dev/null
+++ b/chromium/content/browser/renderer_host/plugin_registry_impl.cc
@@ -0,0 +1,87 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/plugin_registry_impl.h"
+
+#include "base/no_destructor.h"
+#include "content/browser/plugin_service_impl.h"
+#include "content/public/browser/plugin_service_filter.h"
+
+namespace content {
+
+namespace {
+constexpr auto kPluginRefreshThreshold = base::TimeDelta::FromSeconds(3);
+} // namespace
+
+PluginRegistryImpl::PluginRegistryImpl(ResourceContext* resource_context)
+ : resource_context_(resource_context), weak_factory_(this) {}
+
+PluginRegistryImpl::~PluginRegistryImpl() {}
+
+void PluginRegistryImpl::Bind(blink::mojom::PluginRegistryRequest request) {
+ bindings_.AddBinding(this, std::move(request));
+}
+
+void PluginRegistryImpl::GetPlugins(bool refresh,
+ const url::Origin& main_frame_origin,
+ GetPluginsCallback callback) {
+ auto* plugin_service = PluginServiceImpl::GetInstance();
+
+ // Don't refresh if the specified threshold has not been passed. Note that
+ // this check is performed before off-loading to the file thread. The reason
+ // we do this is that some pages tend to request that the list of plugins be
+ // refreshed at an excessive rate. This instigates disk scanning, as the list
+ // is accumulated by doing multiple reads from disk. This effect is
+ // multiplied when we have several pages requesting this operation.
+ if (refresh) {
+ const base::TimeTicks now = base::TimeTicks::Now();
+ if (now - last_plugin_refresh_time_ >= kPluginRefreshThreshold) {
+ // Only refresh if the threshold hasn't been exceeded yet.
+ plugin_service->RefreshPlugins();
+ last_plugin_refresh_time_ = now;
+ }
+ }
+
+ plugin_service->GetPlugins(base::BindOnce(
+ &PluginRegistryImpl::GetPluginsComplete, weak_factory_.GetWeakPtr(),
+ main_frame_origin, std::move(callback)));
+}
+
+void PluginRegistryImpl::GetPluginsComplete(
+ const url::Origin& main_frame_origin,
+ GetPluginsCallback callback,
+ const std::vector<WebPluginInfo>& all_plugins) {
+ PluginServiceFilter* filter = PluginServiceImpl::GetInstance()->GetFilter();
+ std::vector<blink::mojom::PluginInfoPtr> plugins;
+
+ const int child_process_id = -1;
+ const int routing_id = MSG_ROUTING_NONE;
+ // In this loop, copy the WebPluginInfo (and do not use a reference) because
+ // the filter might mutate it.
+ for (WebPluginInfo plugin : all_plugins) {
+ // TODO(crbug.com/621724): Pass an url::Origin instead of a GURL.
+ if (!filter ||
+ filter->IsPluginAvailable(child_process_id, routing_id,
+ resource_context_, main_frame_origin.GetURL(),
+ main_frame_origin, &plugin)) {
+ auto plugin_blink = blink::mojom::PluginInfo::New();
+ plugin_blink->name = plugin.name;
+ plugin_blink->description = plugin.desc;
+ plugin_blink->filename = plugin.path.BaseName();
+ plugin_blink->background_color = plugin.background_color;
+ for (const auto& mime_type : plugin.mime_types) {
+ auto mime_type_blink = blink::mojom::PluginMimeType::New();
+ mime_type_blink->mime_type = mime_type.mime_type;
+ mime_type_blink->description = mime_type.description;
+ mime_type_blink->file_extensions = mime_type.file_extensions;
+ plugin_blink->mime_types.push_back(std::move(mime_type_blink));
+ }
+ plugins.push_back(std::move(plugin_blink));
+ }
+ }
+
+ std::move(callback).Run(std::move(plugins));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/renderer_host/plugin_registry_impl.h b/chromium/content/browser/renderer_host/plugin_registry_impl.h
new file mode 100644
index 00000000000..3009401dac6
--- /dev/null
+++ b/chromium/content/browser/renderer_host/plugin_registry_impl.h
@@ -0,0 +1,43 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_PLUGIN_REGISTRY_IMPL_H_
+#define CONTENT_BROWSER_RENDERER_HOST_PLUGIN_REGISTRY_IMPL_H_
+
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "third_party/blink/public/mojom/plugins/plugin_registry.mojom.h"
+
+namespace content {
+
+class ResourceContext;
+struct WebPluginInfo;
+
+class PluginRegistryImpl : public blink::mojom::PluginRegistry {
+ public:
+ explicit PluginRegistryImpl(ResourceContext* resource_context);
+ ~PluginRegistryImpl() override;
+
+ void Bind(blink::mojom::PluginRegistryRequest request);
+
+ // blink::mojom::PluginRegistry
+ void GetPlugins(bool refresh,
+ const url::Origin& main_frame_origin,
+ GetPluginsCallback callback) override;
+
+ private:
+ void GetPluginsComplete(const url::Origin& main_frame_origin,
+ GetPluginsCallback callback,
+ const std::vector<WebPluginInfo>& all_plugins);
+
+ ResourceContext* const resource_context_;
+ mojo::BindingSet<PluginRegistry> bindings_;
+ base::TimeTicks last_plugin_refresh_time_;
+ base::WeakPtrFactory<PluginRegistryImpl> weak_factory_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_PLUGIN_REGISTRY_IMPL_H_
diff --git a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
index 025702c926a..c78d73722dd 100644
--- a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
+++ b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
@@ -48,11 +48,12 @@ RenderFrameMetadataProviderImpl::LastRenderFrameMetadata() const {
return last_render_frame_metadata_;
}
-void RenderFrameMetadataProviderImpl::OnFrameTokenRenderFrameMetadataChanged(
- cc::RenderFrameMetadata metadata) {
+void RenderFrameMetadataProviderImpl::
+ OnRenderFrameMetadataChangedAfterActivation(
+ cc::RenderFrameMetadata metadata) {
last_render_frame_metadata_ = std::move(metadata);
for (Observer& observer : observers_)
- observer.OnRenderFrameMetadataChanged();
+ observer.OnRenderFrameMetadataChangedAfterActivation();
}
void RenderFrameMetadataProviderImpl::OnFrameTokenFrameSubmissionForTesting() {
@@ -68,19 +69,25 @@ void RenderFrameMetadataProviderImpl::SetLastRenderFrameMetadataForTest(
void RenderFrameMetadataProviderImpl::OnRenderFrameMetadataChanged(
uint32_t frame_token,
const cc::RenderFrameMetadata& metadata) {
+ for (Observer& observer : observers_)
+ observer.OnRenderFrameMetadataChangedBeforeActivation(metadata);
+
if (metadata.local_surface_id != last_local_surface_id_) {
last_local_surface_id_ = metadata.local_surface_id;
for (Observer& observer : observers_)
observer.OnLocalSurfaceIdChanged(metadata);
}
+ if (!frame_token)
+ return;
+
// Both RenderFrameMetadataProviderImpl and FrameTokenMessageQueue are owned
// by the same RenderWidgetHostImpl. During shutdown the queue is cleared
// without running the callbacks.
frame_token_message_queue_->EnqueueOrRunFrameTokenCallback(
frame_token,
base::BindOnce(&RenderFrameMetadataProviderImpl::
- OnFrameTokenRenderFrameMetadataChanged,
+ OnRenderFrameMetadataChangedAfterActivation,
weak_factory_.GetWeakPtr(), std::move(metadata)));
}
diff --git a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h
index ff93d903d41..fe6117100bf 100644
--- a/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h
+++ b/chromium/content/browser/renderer_host/render_frame_metadata_provider_impl.h
@@ -51,7 +51,8 @@ class CONTENT_EXPORT RenderFrameMetadataProviderImpl
// methods are enqueued in |frame_token_message_queue_|. They are invoked when
// the browser process receives their associated frame tokens. These then
// notify any |observers_|.
- void OnFrameTokenRenderFrameMetadataChanged(cc::RenderFrameMetadata metadata);
+ void OnRenderFrameMetadataChangedAfterActivation(
+ cc::RenderFrameMetadata metadata);
void OnFrameTokenFrameSubmissionForTesting();
// Set |last_render_frame_metadata_| to the given |metadata| for testing
diff --git a/chromium/content/browser/renderer_host/render_message_filter.cc b/chromium/content/browser/renderer_host/render_message_filter.cc
index 765a4664465..8ca3b5ed1ff 100644
--- a/chromium/content/browser/renderer_host/render_message_filter.cc
+++ b/chromium/content/browser/renderer_host/render_message_filter.cc
@@ -29,8 +29,6 @@
#include "content/browser/cache_storage/cache_storage_cache_handle.h"
#include "content/browser/cache_storage/cache_storage_context_impl.h"
#include "content/browser/cache_storage/cache_storage_manager.h"
-#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
-#include "content/browser/dom_storage/session_storage_namespace_impl.h"
#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
@@ -98,7 +96,6 @@ RenderMessageFilter::RenderMessageFilter(
net::URLRequestContextGetter* request_context,
RenderWidgetHelper* render_widget_helper,
MediaInternals* media_internals,
- DOMStorageContextWrapper* dom_storage_context,
CacheStorageContextImpl* cache_storage_context)
: BrowserMessageFilter(kRenderFilteredMessageClasses,
arraysize(kRenderFilteredMessageClasses)),
@@ -107,7 +104,6 @@ RenderMessageFilter::RenderMessageFilter(
request_context_(request_context),
resource_context_(browser_context->GetResourceContext()),
render_widget_helper_(render_widget_helper),
- dom_storage_context_(dom_storage_context),
render_process_id_(render_process_id),
media_internals_(media_internals),
cache_storage_context_(cache_storage_context),
diff --git a/chromium/content/browser/renderer_host/render_message_filter.h b/chromium/content/browser/renderer_host/render_message_filter.h
index d22da30d122..b90944a9f34 100644
--- a/chromium/content/browser/renderer_host/render_message_filter.h
+++ b/chromium/content/browser/renderer_host/render_message_filter.h
@@ -18,7 +18,6 @@
#include "base/sequenced_task_runner_helpers.h"
#include "base/strings/string16.h"
#include "build/build_config.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
#include "content/common/render_message_filter.mojom.h"
#include "content/public/browser/browser_associated_interface.h"
#include "content/public/browser/browser_message_filter.h"
@@ -55,7 +54,6 @@ namespace content {
class BrowserContext;
class CacheStorageContextImpl;
class CacheStorageCacheHandle;
-class DOMStorageContextWrapper;
class MediaInternals;
class RenderWidgetHelper;
class ResourceContext;
@@ -74,7 +72,6 @@ class CONTENT_EXPORT RenderMessageFilter
net::URLRequestContextGetter* request_context,
RenderWidgetHelper* render_widget_helper,
MediaInternals* media_internals,
- DOMStorageContextWrapper* dom_storage_context,
CacheStorageContextImpl* cache_storage_context);
// BrowserMessageFilter methods:
@@ -149,8 +146,6 @@ class CONTENT_EXPORT RenderMessageFilter
scoped_refptr<RenderWidgetHelper> render_widget_helper_;
- scoped_refptr<DOMStorageContextWrapper> dom_storage_context_;
-
int render_process_id_;
MediaInternals* media_internals_;
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 a2106f21629..c81f8ed3587 100644
--- a/chromium/content/browser/renderer_host/render_process_host_browsertest.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_browsertest.cc
@@ -1056,7 +1056,7 @@ IN_PROC_BROWSER_TEST_F(RenderProcessHostTest, ConstructedButNotInitializedYet) {
EXPECT_FALSE(process->IsForGuestsOnly());
// There should be no OS process before Init() method is called.
- EXPECT_FALSE(process->HasConnection());
+ EXPECT_FALSE(process->IsInitializedAndNotDead());
EXPECT_FALSE(process->IsReady());
EXPECT_FALSE(process->GetProcess().IsValid());
EXPECT_EQ(base::kNullProcessHandle, process->GetProcess().Handle());
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 5ccfa4398c7..05e0ee79e5a 100644
--- a/chromium/content/browser/renderer_host/render_process_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_impl.cc
@@ -34,6 +34,7 @@
#include "base/memory/shared_memory.h"
#include "base/memory/shared_memory_handle.h"
#include "base/message_loop/message_loop.h"
+#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/persistent_histogram_allocator.h"
@@ -41,6 +42,7 @@
#include "base/metrics/statistics_recorder.h"
#include "base/metrics/user_metrics.h"
#include "base/no_destructor.h"
+#include "base/numerics/ranges.h"
#include "base/process/process_handle.h"
#include "base/rand_util.h"
#include "base/single_thread_task_runner.h"
@@ -72,7 +74,6 @@
#include "content/browser/bad_message.h"
#include "content/browser/blob_storage/blob_dispatcher_host.h"
#include "content/browser/blob_storage/blob_registry_wrapper.h"
-#include "content/browser/blob_storage/blob_url_loader_factory.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/broadcast_channel/broadcast_channel_provider.h"
#include "content/browser/browser_child_process_host_impl.h"
@@ -117,6 +118,7 @@
#include "content/browser/renderer_host/p2p/socket_dispatcher_host.h"
#include "content/browser/renderer_host/pepper/pepper_message_filter.h"
#include "content/browser/renderer_host/pepper/pepper_renderer_connection.h"
+#include "content/browser/renderer_host/plugin_registry_impl.h"
#include "content/browser/renderer_host/render_message_filter.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -144,6 +146,7 @@
#include "content/common/resource_messages.h"
#include "content/common/service_manager/child_connection.h"
#include "content/common/service_manager/service_manager_connection_impl.h"
+#include "content/common/service_worker/service_worker_utils.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
@@ -169,7 +172,6 @@
#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"
#include "gpu/command_buffer/common/context_creation_attribs.h"
@@ -183,7 +185,6 @@
#include "media/base/media_switches.h"
#include "media/media_buildflags.h"
#include "media/mojo/services/video_decode_perf_history.h"
-#include "mojo/edk/embedder/embedder.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/platform_handle.h"
@@ -220,10 +221,12 @@
#include "content/public/browser/android/java_interfaces.h"
#include "ipc/ipc_sync_channel.h"
#include "media/audio/android/audio_manager_android.h"
+#else
+#include "content/browser/compositor/image_transport_factory.h"
#endif
-#if !defined(OS_ANDROID)
-#include "content/browser/compositor/image_transport_factory.h"
+#if defined(OS_MACOSX)
+#include "content/browser/mach_broker_mac.h"
#endif
#if defined(OS_WIN)
@@ -234,12 +237,8 @@
#include "ui/display/win/dpi.h"
#endif
-#if defined(OS_MACOSX)
-#include "content/browser/mach_broker_mac.h"
-#endif
-
-#if defined(USE_OZONE)
-#include "ui/ozone/public/ozone_switches.h"
+#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
+#include "content/browser/media/key_system_support_impl.h"
#endif
#if BUILDFLAG(ENABLE_PLUGINS)
@@ -247,14 +246,18 @@
#include "ppapi/shared_impl/ppapi_switches.h" // nogncheck
#endif
-#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
-#include "content/browser/media/key_system_support_impl.h"
+#if BUILDFLAG(ENABLE_REPORTING)
+#include "content/browser/net/reporting_service_proxy.h"
#endif
#if BUILDFLAG(USE_MINIKIN_HYPHENATION)
#include "content/browser/hyphenation/hyphenation_impl.h"
#endif
+#if defined(USE_OZONE)
+#include "ui/ozone/public/ozone_switches.h"
+#endif
+
#if BUILDFLAG(USE_ZYGOTE_HANDLE)
#include "services/service_manager/zygote/common/zygote_handle.h" // nogncheck
#endif
@@ -265,10 +268,6 @@
#define IntToStringType base::IntToString
#endif
-#if BUILDFLAG(ENABLE_REPORTING)
-#include "content/browser/net/reporting_service_proxy.h"
-#endif // BUILDFLAG(ENABLE_REPORTING)
-
namespace content {
using CheckOriginLockResult =
@@ -276,6 +275,18 @@ using CheckOriginLockResult =
namespace {
+// Stores the maximum number of renderer processes the content module can
+// create. Only applies if it is set to a non-zero value.
+size_t g_max_renderer_count_override = 0;
+
+bool g_run_renderer_in_process = false;
+
+RendererMainThreadFactoryFunction g_renderer_main_thread_factory = nullptr;
+RenderProcessHostImpl::CreateStoragePartitionServiceFunction
+ g_create_storage_partition = nullptr;
+
+base::MessageLoop* g_in_process_thread;
+
const RenderProcessHostFactory* g_render_process_host_factory_ = nullptr;
const char kSiteProcessMapKeyName[] = "content_site_process_map";
@@ -418,12 +429,12 @@ class SiteProcessMap : public base::SupportsUserData::Data {
// them.
std::set<std::string> sites;
for (SiteToProcessMap::const_iterator i = map_.begin(); i != map_.end();
- i++) {
+ ++i) {
if (i->second == host)
sites.insert(i->first);
}
for (std::set<std::string>::iterator i = sites.begin(); i != sites.end();
- i++) {
+ ++i) {
SiteToProcessMap::iterator iter = map_.find(*i);
if (iter != map_.end()) {
DCHECK_EQ(iter->second, host);
@@ -439,13 +450,15 @@ class SiteProcessMap : public base::SupportsUserData::Data {
// Find the SiteProcessMap specific to the given context.
SiteProcessMap* GetSiteProcessMapForBrowserContext(BrowserContext* context) {
DCHECK(context);
- SiteProcessMap* map = static_cast<SiteProcessMap*>(
+ SiteProcessMap* existing_map = static_cast<SiteProcessMap*>(
context->GetUserData(kSiteProcessMapKeyName));
- if (!map) {
- map = new SiteProcessMap();
- context->SetUserData(kSiteProcessMapKeyName, base::WrapUnique(map));
- }
- return map;
+ if (existing_map)
+ return existing_map;
+
+ auto new_map = std::make_unique<SiteProcessMap>();
+ auto* new_map_ptr = new_map.get();
+ context->SetUserData(kSiteProcessMapKeyName, std::move(new_map));
+ return new_map_ptr;
}
// NOTE: changes to this class need to be reviewed by the security team.
@@ -619,7 +632,7 @@ class SpareRenderProcessHostManager : public RenderProcessHostObserver {
// If the spare process ends up getting killed, the spare manager should
// discard the spare RPH, so if one exists, it should always be live here.
- CHECK(spare_render_process_host_->HasConnection());
+ CHECK(spare_render_process_host_->IsInitializedAndNotDead());
DCHECK_EQ(SpareProcessMaybeTakeAction::kSpareTaken, action);
returned_process = spare_render_process_host_;
@@ -688,12 +701,6 @@ class SpareRenderProcessHostManager : public RenderProcessHostObserver {
}
}
- // RenderProcessHostObserver::RenderProcessWillExit is not overriden because:
- // 1. This simplifies reasoning when Cleanup can be called.
- // 2. In practice the spare shouldn't go through graceful shutdown.
- // 3. Handling RenderProcessExited and RenderProcessHostDestroyed is
- // sufficient from correctness perspective.
-
void RenderProcessExited(RenderProcessHost* host,
const ChildProcessTerminationInfo& info) override {
if (host == spare_render_process_host_)
@@ -771,7 +778,7 @@ class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data,
RenderProcessHost* host_ = nullptr;
};
-void CreateMemoryCoordinatorHandle(
+void CreateMemoryCoordinatorHandleForRenderProcess(
int render_process_id,
mojom::MemoryCoordinatorHandleRequest request) {
MemoryCoordinatorImpl::GetInstance()->CreateHandle(render_process_id,
@@ -1132,6 +1139,66 @@ class UnmatchedServiceWorkerProcessTracker
SiteProcessIDPairSet site_process_set_;
};
+bool ShouldBoostPriorityForPendingViews() {
+#if defined(OS_ANDROID)
+ // On Android, renderer processes with pending views get an extra boost.
+ return true;
+#else
+ // On desktop platforms, new renderer processes have been considered
+ // foreground regardless of visibility since r385608. This is because it was
+ // previously discovered that backgrounding processes that weren't responsible
+ // for visible content resulted in running foreground navigations at
+ // background priority until the main frame was committed (and became a
+ // visible widget)... Thus new processes responsible for hidden content are
+ // now foreground until explicitly made visible and hidden again. Full details
+ // @ https://crbug.com/560446.
+ //
+ // The experiment below will attempt to use the new "pending views" signal to
+ // go back to pre r385608 behavior while still boosting priority of processes
+ // with pending views (until widgets are created and visibility kicks in).
+ // This will however not keep the nice side-effect of r385608 which was to
+ // boost new page loads happening in background tabs (example use case of a
+ // foreground action in a background tab : ctrl+click link of interest and
+ // actively wait for spinner to stop before switching tabs). If we decide that
+ // the latter use case is relevant, we should support it cross-platform.
+ //
+ // Thus, while this is a "boosting" experiment, it's really a "consider the
+ // initial foreground state a boost so we can unboost and background sooner".
+ //
+ // Returning true here triggers the experiment because it will cause the
+ // initial |ChildProcessLauncherPriority::boost_for_pending_views| value to be
+ // |true| which will in turn result in a call to UpdateProcessPriority() when
+ // RemovePendingView() is invoked (without the experiment the initial state
+ // has no pending view and although UpdateProcessPriority() is invoked from
+ // RemovePendingView(), it no-ops per "no change" compared to the initial
+ // ChildProcessLauncherPriority).
+ //
+ // Furthermore, it has been discovered that there is a priority inversion in
+ // foreground navigation without this experiment, the reason being that
+ // ChildProcessLauncherPriority::operator==() notices a difference in
+ // UpdateProcessPriority() when only |boost_for_pending_views| has changed. On
+ // desktop it would start in the |false| state and AddPendingView() would
+ // toggle it. This would result in UpdateProcessPriority() but desktop not
+ // handling the presence of |boost_for_pending_views|, would look at |!visible
+ // && !has_media_stream| and decide that it's time to background (bringing
+ // back the OP of https://crbug.com/560446 but worse because actual background
+ // tabs are running as foreground per r385608 -- so during a big session
+ // restore it's possible to end up with all processes foreground except for
+ // the foreground tab's process...). Full details @
+ // https://crbug.com/560446#c74.
+ //
+ // Hence this experiment is definitely the desired behavior, running it as an
+ // experiment on Canary merely to see what was impacted by existing bugs.
+ // TODO(gab): End the experiment and turn ShouldBoostPriorityForPendingViews()
+ // into a constant when results are in.
+ static bool should_boost_for_pending_views =
+ base::StartsWith(base::FieldTrialList::FindFullName(
+ "BoostRendererPriorityForPendingViews"),
+ "Enabled", base::CompareCase::SENSITIVE);
+ return should_boost_for_pending_views;
+#endif
+}
+
void CopyFeatureSwitch(const base::CommandLine& src,
base::CommandLine* dest,
const char* switch_name) {
@@ -1142,19 +1209,6 @@ void CopyFeatureSwitch(const base::CommandLine& src,
} // namespace
-RendererMainThreadFactoryFunction g_renderer_main_thread_factory = nullptr;
-RenderProcessHostImpl::CreateStoragePartitionServiceFunction
- g_create_storage_partition = nullptr;
-
-base::MessageLoop* g_in_process_thread;
-
-// Stores the maximum number of renderer processes the content module can
-// create.
-static size_t g_max_renderer_count_override = 0;
-
-// static
-bool g_run_renderer_in_process_ = false;
-
// Held by the RPH and used to control an (unowned) ConnectionFilterImpl from
// any thread.
class RenderProcessHostImpl::ConnectionFilterController
@@ -1278,25 +1332,30 @@ size_t RenderProcessHost::GetMaxRendererProcessCount() {
return 100;
#endif
- // On other platforms, we calculate the maximum number of renderer process
- // hosts according to the amount of installed memory as reported by the OS.
- // The calculation assumes that you want the renderers to use half of the
- // installed RAM and assuming that each WebContents uses ~40MB. If you modify
- // this assumption, you need to adjust the ThirtyFourTabs test to match the
- // expected number of processes.
+ // On other platforms, calculate the maximum number of renderer process hosts
+ // according to the amount of installed memory as reported by the OS, along
+ // with some hard-coded limits. The calculation assumes that the renderers
+ // will use up to half of the installed RAM and assumes that each WebContents
+ // uses |kEstimatedWebContentsMemoryUsage| MB. If this assumption changes, the
+ // ThirtyFourTabs test needs to be adjusted to match the expected number of
+ // processes.
//
- // With the given amounts of installed memory below on a 32-bit CPU, the
- // maximum renderer count will roughly be as follows:
+ // Using the above assumptions, with the given amounts of installed memory
+ // below on a 64-bit CPU, the maximum renderer count based on available RAM
+ // alone will be as follows:
//
- // 128 MB -> 3
- // 512 MB -> 6
- // 1024 MB -> 12
- // 4096 MB -> 51
- // 16384 MB -> 82 (kMaxRendererProcessCount)
+ // 128 MB -> 1
+ // 512 MB -> 4
+ // 1024 MB -> 8
+ // 4096 MB -> 34
+ // 16384 MB -> 136
+ //
+ // Then the calculated value will be clamped by |kMinRendererProcessCount| and
+ // |kMaxRendererProcessCount|.
static size_t max_count = 0;
if (!max_count) {
- const size_t kEstimatedWebContentsMemoryUsage =
+ static constexpr size_t kEstimatedWebContentsMemoryUsage =
#if defined(ARCH_CPU_64_BITS)
60; // In MB
#else
@@ -1305,9 +1364,9 @@ size_t RenderProcessHost::GetMaxRendererProcessCount() {
max_count = base::SysInfo::AmountOfPhysicalMemoryMB() / 2;
max_count /= kEstimatedWebContentsMemoryUsage;
- const size_t kMinRendererProcessCount = 3;
- max_count = std::max(max_count, kMinRendererProcessCount);
- max_count = std::min(max_count, kMaxRendererProcessCount);
+ static constexpr size_t kMinRendererProcessCount = 3;
+ max_count = base::ClampToRange(max_count, kMinRendererProcessCount,
+ kMaxRendererProcessCount);
}
return max_count;
}
@@ -1321,12 +1380,11 @@ void RenderProcessHost::SetMaxRendererProcessCount(size_t count) {
// static
int RenderProcessHost::GetCurrentRenderProcessCountForTesting() {
- content::RenderProcessHost::iterator it =
- content::RenderProcessHost::AllHostsIterator();
+ RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator();
int count = 0;
while (!it.IsAtEnd()) {
RenderProcessHost* host = it.GetCurrentValue();
- if (host->HasConnection() &&
+ if (host->IsInitializedAndNotDead() &&
host != RenderProcessHostImpl::GetSpareRenderProcessHostForTesting()) {
count++;
}
@@ -1385,13 +1443,32 @@ RenderProcessHostImpl::RenderProcessHostImpl(
is_keep_alive_ref_count_disabled_(false),
route_provider_binding_(this),
visible_clients_(0),
- priority_({
- blink::kLaunchingProcessIsBackgrounded, frame_depth_,
- blink::kLaunchingProcessIsBoostedForPendingView,
+ priority_(!blink::kLaunchingProcessIsBackgrounded,
+ false /* has_media_stream */,
+ frame_depth_,
+ ShouldBoostPriorityForPendingViews(),
#if defined(OS_ANDROID)
- ChildProcessImportance::NORMAL,
+ // Only use |boost_for_pending_views| to infer is_background()
+ // on non-Android platforms for now to avoid changing the
+ // old behavior while the experiment is under way.
+ // Without this, the following tests were failing on Android
+ // (they assume that toggling WidgetHidden() is sufficient to
+ // toggle backgrounding):
+ // NavigationControllerBrowserTest.
+ // NoDialogsFromSwappedOutFrames
+ // SitePerProcessBrowserTest.
+ // CommitTimeoutForHungRenderer
+ // HiddenOOPIFWillNotGenerateCompositorFrames
+ // TODO(gab): Clean this up as soon as the experiment is over.
+ false
+#else
+ ShouldBoostPriorityForPendingViews()
#endif
- }),
+#if defined(OS_ANDROID)
+ ,
+ ChildProcessImportance::NORMAL
+#endif
+ ),
id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
browser_context_(browser_context),
storage_partition_impl_(storage_partition_impl),
@@ -1408,6 +1485,9 @@ RenderProcessHostImpl::RenderProcessHostImpl(
storage_partition_impl_->GetURLRequestContext(),
storage_partition_impl_->GetIndexedDBContext(),
ChromeBlobStorageContext::GetFor(browser_context_))),
+ service_worker_dispatcher_host_(new ServiceWorkerDispatcherHost(
+ storage_partition_impl_->GetServiceWorkerContext(),
+ id_)),
channel_connected_(false),
sent_render_process_ready_(false),
#if defined(OS_ANDROID)
@@ -1444,21 +1524,28 @@ RenderProcessHostImpl::RenderProcessHostImpl(
GetID(), storage_partition_impl_->GetServiceWorkerContext()));
AddObserver(indexed_db_factory_.get());
+ AddObserver(service_worker_dispatcher_host_.get());
#if defined(OS_MACOSX)
AddObserver(MachBroker::GetInstance());
#endif
InitializeChannelProxy();
- if (!base::FeatureList::IsEnabled(features::kMash))
- gpu_client_.reset(new GpuClientImpl(GetID()));
+ if (features::IsAshInBrowserProcess()) {
+ const int id = GetID();
+ const uint64_t tracing_id =
+ ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(id);
+ gpu_client_.reset(new GpuClientImpl(
+ id, tracing_id,
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)));
+ }
GetMemoryDumpProvider().AddHost(this);
}
// static
void RenderProcessHostImpl::ShutDownInProcessRenderer() {
- DCHECK(g_run_renderer_in_process_);
+ DCHECK(g_run_renderer_in_process);
switch (g_all_hosts.Pointer()->size()) {
case 0:
@@ -1524,11 +1611,9 @@ RenderProcessHostImpl::~RenderProcessHostImpl() {
bool RenderProcessHostImpl::Init() {
// calling Init() more than once does nothing, this makes it more convenient
// for the view host which may not be sure in some cases
- if (HasConnection())
+ if (IsInitializedAndNotDead())
return true;
- is_dead_ = false;
-
base::CommandLine::StringType renderer_prefix;
// A command prefix is something prepended to the command line of the spawned
// process.
@@ -1550,17 +1635,18 @@ bool RenderProcessHostImpl::Init() {
if (renderer_path.empty())
return false;
+ is_initialized_ = true;
+ is_dead_ = false;
+ sent_render_process_ready_ = false;
+
if (gpu_client_)
gpu_client_->PreEstablishGpuChannel();
- sent_render_process_ready_ = false;
-
// We may reach Init() during process death notification (e.g.
// RenderProcessExited on some observer). In this case the Channel may be
// null, so we re-initialize it here.
if (!channel_)
InitializeChannelProxy();
- DCHECK(broker_client_invitation_);
// Unpause the Channel briefly. This will be paused again below if we launch a
// real child process. Note that messages may be sent in the short window
@@ -1612,8 +1698,7 @@ bool RenderProcessHostImpl::Init() {
in_process_renderer_.reset(
g_renderer_main_thread_factory(InProcessChildThreadParams(
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
- broker_client_invitation_.get(),
- child_connection_->service_token())));
+ &mojo_invitation_, child_connection_->service_token())));
base::Thread::Options options;
#if defined(OS_WIN) && !defined(OS_MACOSX)
@@ -1649,11 +1734,10 @@ bool RenderProcessHostImpl::Init() {
// Spawn the child process asynchronously to avoid blocking the UI thread.
// As long as there's no renderer prefix, we can use the zygote process
// at this stage.
- child_process_launcher_.reset(new ChildProcessLauncher(
+ child_process_launcher_ = std::make_unique<ChildProcessLauncher>(
std::make_unique<RendererSandboxedProcessLauncherDelegate>(),
- std::move(cmd_line), GetID(), this,
- std::move(broker_client_invitation_),
- base::Bind(&RenderProcessHostImpl::OnMojoError, id_)));
+ std::move(cmd_line), GetID(), this, std::move(mojo_invitation_),
+ base::BindRepeating(&RenderProcessHostImpl::OnMojoError, id_));
channel_->Pause();
fast_shutdown_started_ = false;
@@ -1664,9 +1748,6 @@ bool RenderProcessHostImpl::Init() {
ui::GpuSwitchingManager::GetInstance()->AddObserver(this);
}
- GetRendererInterface()->SetUserAgent(GetContentClient()->GetUserAgent());
-
- is_initialized_ = true;
init_time_ = base::TimeTicks::Now();
return true;
}
@@ -1700,15 +1781,13 @@ void RenderProcessHostImpl::InitializeChannelProxy() {
}
// Establish a ServiceManager connection for the new render service instance.
- broker_client_invitation_ =
- std::make_unique<mojo::edk::OutgoingBrokerClientInvitation>();
+ mojo_invitation_ = {};
service_manager::Identity child_identity(
mojom::kRendererServiceName,
BrowserContext::GetServiceUserIdFor(GetBrowserContext()),
base::StringPrintf("%d_%d", id_, instance_id_++));
- child_connection_.reset(new ChildConnection(child_identity,
- broker_client_invitation_.get(),
- connector, io_task_runner));
+ child_connection_ = std::make_unique<ChildConnection>(
+ child_identity, &mojo_invitation_, connector, io_task_runner);
// Send an interface request to bootstrap the IPC::Channel. Note that this
// request will happily sit on the pipe until the process is launched and
@@ -1736,9 +1815,10 @@ void RenderProcessHostImpl::InitializeChannelProxy() {
&never_signaled_);
}
#endif // OS_ANDROID
- if (!channel_)
- channel_.reset(new IPC::ChannelProxy(this, io_task_runner.get(),
- base::ThreadTaskRunnerHandle::Get()));
+ if (!channel_) {
+ channel_ = std::make_unique<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
@@ -1774,7 +1854,6 @@ void RenderProcessHostImpl::ResetChannelProxy() {
void RenderProcessHostImpl::CreateMessageFilters() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- AddFilter(new ResourceSchedulerFilter(GetID()));
MediaInternals* media_internals = MediaInternals::GetInstance();
// Add BrowserPluginMessageFilter to ensure it gets the first stab at messages
// from guests.
@@ -1783,12 +1862,11 @@ void RenderProcessHostImpl::CreateMessageFilters() {
scoped_refptr<net::URLRequestContextGetter> request_context(
storage_partition_impl_->GetURLRequestContext());
- scoped_refptr<RenderMessageFilter> render_message_filter(
- new RenderMessageFilter(
+ scoped_refptr<RenderMessageFilter> render_message_filter =
+ base::MakeRefCounted<RenderMessageFilter>(
GetID(), GetBrowserContext(), request_context.get(),
widget_helper_.get(), media_internals,
- storage_partition_impl_->GetDOMStorageContext(),
- storage_partition_impl_->GetCacheStorageContext()));
+ storage_partition_impl_->GetCacheStorageContext());
AddFilter(render_message_filter.get());
render_frame_message_filter_ = new RenderFrameMessageFilter(
@@ -1844,14 +1922,8 @@ void RenderProcessHostImpl::CreateMessageFilters() {
AddFilter(new TextInputClientMessageFilter());
#endif
- auto service_worker_filter =
- base::MakeRefCounted<ServiceWorkerDispatcherHost>(GetID());
- service_worker_filter->Init(
- storage_partition_impl_->GetServiceWorkerContext());
- AddFilter(service_worker_filter.get());
-
- p2p_socket_dispatcher_host_ = new P2PSocketDispatcherHost(
- resource_context, request_context.get());
+ p2p_socket_dispatcher_host_ =
+ new P2PSocketDispatcherHost(request_context.get());
AddFilter(p2p_socket_dispatcher_host_.get());
AddFilter(new TraceMessageFilter(GetID()));
@@ -1910,6 +1982,10 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
base::Bind(&IndexedDBDispatcherHost::AddBinding,
base::Unretained(indexed_db_factory_.get())));
+ channel_->AddAssociatedInterfaceForIOThread(base::BindRepeating(
+ &ServiceWorkerDispatcherHost::AddBinding,
+ base::Unretained(service_worker_dispatcher_host_.get())));
+
AddUIThreadInterface(
registry.get(), base::Bind(&ForwardRequest<device::mojom::BatteryMonitor>,
device::mojom::kServiceName));
@@ -1944,7 +2020,8 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
storage_partition_impl_->GetBroadcastChannelProvider())));
if (base::FeatureList::IsEnabled(features::kMemoryCoordinator)) {
AddUIThreadInterface(
- registry.get(), base::Bind(&CreateMemoryCoordinatorHandle, GetID()));
+ registry.get(),
+ base::Bind(&CreateMemoryCoordinatorHandleForRenderProcess, GetID()));
}
if (resource_coordinator::IsResourceCoordinatorEnabled()) {
AddUIThreadInterface(
@@ -1952,13 +2029,8 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
base::Bind(&CreateProcessResourceCoordinator, base::Unretained(this)));
}
- BrowserContext* browser_context = GetBrowserContext();
- scoped_refptr<ChromeBlobStorageContext> blob_storage_context =
- ChromeBlobStorageContext::GetFor(browser_context);
-
AddUIThreadInterface(registry.get(),
- base::BindRepeating(&ClipboardHostImpl::Create,
- std::move(blob_storage_context)));
+ base::BindRepeating(&ClipboardHostImpl::Create));
media::VideoDecodePerfHistory* video_perf_history =
GetBrowserContext()->GetVideoDecodePerfHistory();
@@ -1979,8 +2051,6 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
registry->AddInterface(base::Bind(&device::GamepadHapticsManager::Create));
- registry->AddInterface(base::Bind(&device::GamepadMonitor::Create));
-
registry->AddInterface(
base::Bind(&PushMessagingManager::BindRequest,
base::Unretained(push_messaging_manager_.get())));
@@ -1988,8 +2058,8 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
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(&GpuClientImpl::Add, base::Unretained(gpu_client_.get())));
+ registry->AddInterface(base::BindRepeating(
+ &GpuClientImpl::Add, base::Unretained(gpu_client_.get())));
}
registry->AddInterface(
@@ -2028,7 +2098,7 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
AddUIThreadInterface(registry.get(), base::Bind(&FieldTrialRecorder::Create));
- associated_interfaces_.reset(new AssociatedInterfaceRegistryImpl());
+ associated_interfaces_ = std::make_unique<AssociatedInterfaceRegistryImpl>();
blink::AssociatedInterfaceRegistry* associated_registry =
associated_interfaces_.get();
associated_registry->AddInterface(base::Bind(
@@ -2047,6 +2117,17 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
base::BindRepeating(&BlobRegistryWrapper::Bind,
storage_partition_impl_->GetBlobRegistry(), GetID()));
+#if BUILDFLAG(ENABLE_PLUGINS)
+ // Initialization can happen more than once (in the case of a child process
+ // crash), but we don't want to lose the plugin registry in this case.
+ if (!plugin_registry_) {
+ plugin_registry_.reset(
+ new PluginRegistryImpl(GetBrowserContext()->GetResourceContext()));
+ }
+ registry->AddInterface(base::BindRepeating(
+ &PluginRegistryImpl::Bind, base::Unretained(plugin_registry_.get())));
+#endif
+
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
registry->AddInterface(base::BindRepeating(&KeySystemSupportImpl::Create));
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
@@ -2066,9 +2147,9 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
connection_filter_controller_->DisableFilter();
service_manager_connection->RemoveConnectionFilter(connection_filter_id_);
}
- std::unique_ptr<ConnectionFilterImpl> connection_filter(
- new ConnectionFilterImpl(child_connection_->child_identity(),
- std::move(registry)));
+ std::unique_ptr<ConnectionFilterImpl> connection_filter =
+ std::make_unique<ConnectionFilterImpl>(
+ child_connection_->child_identity(), std::move(registry));
connection_filter_controller_ = connection_filter->controller();
connection_filter_id_ = service_manager_connection->AddConnectionFilter(
std::move(connection_filter));
@@ -2099,16 +2180,6 @@ void RenderProcessHostImpl::GetAssociatedInterface(
listener->OnAssociatedInterfaceRequest(name, request.PassHandle());
}
-void RenderProcessHostImpl::GetBlobURLLoaderFactory(
- network::mojom::URLLoaderFactoryRequest request) {
- if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- NOTREACHED();
- return;
- }
- storage_partition_impl_->GetBlobURLLoaderFactory()->HandleRequest(
- std::move(request));
-}
-
void RenderProcessHostImpl::CreateEmbeddedFrameSinkProvider(
blink::mojom::EmbeddedFrameSinkProviderRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -2134,7 +2205,7 @@ void RenderProcessHostImpl::BindCompositingModeReporter(
}
void RenderProcessHostImpl::CreateStoragePartitionService(
- mojom::StoragePartitionServiceRequest request) {
+ blink::mojom::StoragePartitionServiceRequest request) {
if (g_create_storage_partition) {
g_create_storage_partition(this, std::move(request));
return;
@@ -2148,21 +2219,6 @@ void RenderProcessHostImpl::CreateRendererHost(
renderer_host_binding_.Bind(std::move(request));
}
-void RenderProcessHostImpl::CreateURLLoaderFactory(
- network::mojom::URLLoaderFactoryRequest request) {
- if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
- NOTREACHED();
- return;
- }
- network::mojom::URLLoaderFactoryParamsPtr params =
- network::mojom::URLLoaderFactoryParams::New();
- params->process_id = id_;
- // TODO(lukasza): https://crbug.com/792546: Start using CORB.
- params->is_corb_enabled = false;
- storage_partition_impl_->GetNetworkContext()->CreateURLLoaderFactory(
- std::move(request), std::move(params));
-}
-
int RenderProcessHostImpl::GetNextRoutingID() {
return widget_helper_->GetNextRoutingID();
}
@@ -2175,6 +2231,11 @@ void RenderProcessHostImpl::BindInterface(
const service_manager::Identity& RenderProcessHostImpl::GetChildIdentity()
const {
+ // GetChildIdentity should only be called if the RPH is (or soon will be)
+ // backed by an actual renderer process. This helps prevent leaks similar to
+ // the ones raised in https://crbug.com/813045.
+ DCHECK(IsInitializedAndNotDead());
+
return child_connection_->child_identity();
}
@@ -2189,7 +2250,7 @@ const base::TimeTicks& RenderProcessHostImpl::GetInitTimeForNavigationMetrics()
}
bool RenderProcessHostImpl::IsProcessBackgrounded() const {
- return priority_.background;
+ return priority_.is_background();
}
void RenderProcessHostImpl::IncrementKeepAliveRefCount(
@@ -2310,6 +2371,26 @@ RenderProcessHostImpl::GetProcessResourceCoordinator() {
return process_resource_coordinator_.get();
}
+void RenderProcessHostImpl::CreateURLLoaderFactory(
+ network::mojom::URLLoaderFactoryRequest request) {
+ if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&ResourceMessageFilter::Clone, resource_message_filter_,
+ std::move(request)));
+ return;
+ }
+ network::mojom::URLLoaderFactoryParamsPtr params =
+ network::mojom::URLLoaderFactoryParams::New();
+ params->process_id = id_;
+ params->disable_web_security =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableWebSecurity);
+ SiteIsolationPolicy::PopulateURLLoaderFactoryParamsPtrForCORB(params.get());
+ storage_partition_impl_->GetNetworkContext()->CreateURLLoaderFactory(
+ std::move(request), std::move(params));
+}
+
void RenderProcessHostImpl::SetIsNeverSuitableForReuse() {
is_never_suitable_for_reuse_ = true;
}
@@ -2374,8 +2455,9 @@ void RenderProcessHostImpl::ShutdownForBadMessage(
if (crash_report_mode == CrashReportMode::GENERATE_CRASH_DUMP) {
// Set crash keys to understand renderer kills related to site isolation.
auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
+ std::string lock_url = policy->GetOriginLock(GetID()).spec();
base::debug::SetCrashKeyString(bad_message::GetKilledProcessOriginLockKey(),
- policy->GetOriginLock(GetID()).spec());
+ lock_url.empty() ? "(none)" : lock_url);
std::string site_isolation_mode;
if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites())
@@ -2384,6 +2466,8 @@ void RenderProcessHostImpl::ShutdownForBadMessage(
site_isolation_mode += "tdi ";
if (SiteIsolationPolicy::AreIsolatedOriginsEnabled())
site_isolation_mode += "io ";
+ if (site_isolation_mode.empty())
+ site_isolation_mode = "(none)";
static auto* isolation_mode_key = base::debug::AllocateCrashKeyString(
"site_isolation_mode", base::debug::CrashKeySize::Size32);
@@ -2579,6 +2663,30 @@ bool RenderProcessHostImpl::HostHasNotBeenUsed() {
pending_views_ == 0;
}
+void RenderProcessHostImpl::LockToOrigin(const GURL& lock_url) {
+ ChildProcessSecurityPolicyImpl::GetInstance()->LockToOrigin(GetID(),
+ lock_url);
+
+ // Note that LockToOrigin is only called once per RenderProcessHostImpl (when
+ // committing a navigation into an empty renderer). Therefore, the call to
+ // NotifyRendererIfLockedToSite below is insufficient for setting up renderers
+ // respawned after crashing - this is handled by another call to
+ // NotifyRendererIfLockedToSite from OnProcessLaunched.
+ NotifyRendererIfLockedToSite();
+}
+
+void RenderProcessHostImpl::NotifyRendererIfLockedToSite() {
+ GURL lock_url =
+ ChildProcessSecurityPolicyImpl::GetInstance()->GetOriginLock(GetID());
+ if (!lock_url.is_valid())
+ return;
+
+ if (!SiteInstanceImpl::IsOriginLockASite(lock_url))
+ return;
+
+ GetRendererInterface()->SetIsLockedToSite();
+}
+
bool RenderProcessHostImpl::IsForGuestsOnly() const {
return is_for_guests_only_;
}
@@ -2723,6 +2831,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kDisableV8IdleTasks,
switches::kDisableWebGLImageChromium,
switches::kDomAutomationController,
+ switches::kEnableAccessibilityObjectModel,
switches::kEnableAutomation,
switches::kEnableBlinkGenPropertyTrees,
switches::kEnableExperimentalWebPlatformFeatures,
@@ -2732,28 +2841,29 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kEnableGPUServiceLogging,
switches::kEnableLowResTiling,
switches::kEnableMediaSuspend,
- switches::kEnableInbandTextTracks,
switches::kEnableLCDText,
switches::kEnableLogging,
switches::kEnableNetworkInformationDownlinkMax,
- switches::kEnableOOPRasterization,
switches::kEnablePluginPlaceholderTesting,
switches::kEnablePreciseMemoryInfo,
switches::kEnablePrintBrowser,
switches::kEnablePreferCompositingToLCDText,
switches::kEnableRGBA4444Textures,
switches::kEnableSkiaBenchmarking,
- switches::kEnableSlimmingPaintV175,
switches::kEnableSlimmingPaintV2,
switches::kEnableThreadedCompositing,
switches::kEnableTouchDragDrop,
+ switches::kEnableUnsafeWebGPU,
switches::kEnableUseZoomForDSF,
switches::kEnableViewport,
switches::kEnableVtune,
+ switches::kEnableWebGL2ComputeContext,
switches::kEnableWebGLDraftExtensions,
switches::kEnableWebGLImageChromium,
switches::kEnableWebVR,
switches::kExplicitlyAllowedPorts,
+ switches::kFileUrlPathAlias,
+ switches::kFMPNetworkQuietTimeout,
switches::kForceColorProfile,
switches::kForceDeviceScaleFactor,
switches::kForceGpuMemAvailableMb,
@@ -2766,8 +2876,8 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
switches::kLoggingLevel,
switches::kMaxUntiledLayerWidth,
switches::kMaxUntiledLayerHeight,
- switches::kMSEAudioBufferSizeLimit,
- switches::kMSEVideoBufferSizeLimit,
+ switches::kMSEAudioBufferSizeLimitMb,
+ switches::kMSEVideoBufferSizeLimitMb,
switches::kNoZygote,
switches::kOverridePluginPowerSaverForTesting,
switches::kPassiveListenersDefault,
@@ -2988,7 +3098,9 @@ bool RenderProcessHostImpl::FastShutdownIfPossible(size_t page_count,
}
bool RenderProcessHostImpl::Send(IPC::Message* msg) {
- TRACE_EVENT0("renderer_host", "RenderProcessHostImpl::Send");
+ TRACE_EVENT2("renderer_host", "RenderProcessHostImpl::Send", "class",
+ IPC_MESSAGE_ID_CLASS(msg->type()), "line",
+ IPC_MESSAGE_ID_LINE(msg->type()));
std::unique_ptr<IPC::Message> message(msg);
@@ -3003,7 +3115,7 @@ bool RenderProcessHostImpl::Send(IPC::Message* msg) {
if (message->is_sync()) {
// If Init() hasn't been called yet since construction or the last
// ProcessDied() we avoid blocking on sync IPC.
- if (!HasConnection())
+ if (!IsInitializedAndNotDead())
return false;
// Likewise if we've done Init(), but process launch has not yet completed,
@@ -3118,7 +3230,7 @@ int RenderProcessHostImpl::GetID() const {
return id_;
}
-bool RenderProcessHostImpl::HasConnection() const {
+bool RenderProcessHostImpl::IsInitializedAndNotDead() const {
return is_initialized_ && !is_dead_;
}
@@ -3185,7 +3297,7 @@ void RenderProcessHostImpl::Cleanup() {
// notify all observers that the process has exited cleanly, even though it
// will be destroyed a bit later. Observers shouldn't rely on this process
// anymore.
- if (HasConnection()) {
+ if (IsInitializedAndNotDead()) {
// Populates Android-only fields and closes the underlying base::Process.
ChildProcessTerminationInfo info =
child_process_launcher_->GetChildTerminationInfo(
@@ -3232,19 +3344,21 @@ void RenderProcessHostImpl::Cleanup() {
// reused in between now and when the Delete task runs.
UnregisterHost(GetID());
- instance_weak_factory_.reset(
- new base::WeakPtrFactory<RenderProcessHostImpl>(this));
+ instance_weak_factory_ =
+ std::make_unique<base::WeakPtrFactory<RenderProcessHostImpl>>(this);
}
void RenderProcessHostImpl::AddPendingView() {
- pending_views_++;
- UpdateProcessPriority();
+ const bool had_pending_views = pending_views_++;
+ if (!had_pending_views)
+ UpdateProcessPriority();
}
void RenderProcessHostImpl::RemovePendingView() {
DCHECK(pending_views_);
- pending_views_--;
- UpdateProcessPriority();
+ --pending_views_;
+ if (!pending_views_)
+ UpdateProcessPriority();
}
void RenderProcessHostImpl::AddWidget(RenderWidgetHost* widget) {
@@ -3492,12 +3606,12 @@ void RenderProcessHost::WarmupSpareRenderProcessHost(
// static
bool RenderProcessHost::run_renderer_in_process() {
- return g_run_renderer_in_process_;
+ return g_run_renderer_in_process;
}
// static
void RenderProcessHost::SetRunRendererInProcess(bool value) {
- g_run_renderer_in_process_ = value;
+ g_run_renderer_in_process = value;
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (value) {
@@ -3530,10 +3644,9 @@ RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
// static
RenderProcessHost* RenderProcessHost::FromRendererIdentity(
const service_manager::Identity& identity) {
- for (content::RenderProcessHost::iterator i(
- content::RenderProcessHost::AllHostsIterator());
+ for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator());
!i.IsAtEnd(); i.Advance()) {
- content::RenderProcessHost* process = i.GetCurrentValue();
+ RenderProcessHost* process = i.GetCurrentValue();
if (process->GetChildIdentity() == identity)
return process;
}
@@ -3805,11 +3918,12 @@ void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() {
// it. Memory that is not actualy used won't be physically mapped by the
// system. RendererMetrics usage, as reported in UMA, peaked around 0.7MiB
// as of 2016-12-20.
- std::unique_ptr<base::SharedMemory> shm(new base::SharedMemory());
+ auto shm = std::make_unique<base::SharedMemory>();
if (!shm->CreateAndMapAnonymous(2 << 20)) // 2 MiB
return;
- metrics_allocator_.reset(new base::SharedPersistentMemoryAllocator(
- std::move(shm), GetID(), "RendererMetrics", /*readonly=*/false));
+ metrics_allocator_ =
+ std::make_unique<base::SharedPersistentMemoryAllocator>(
+ std::move(shm), GetID(), "RendererMetrics", /*readonly=*/false);
}
HistogramController::GetInstance()->SetHistogramMemory<RenderProcessHost>(
@@ -3982,11 +4096,6 @@ void RenderProcessHostImpl::ShutdownRequest() {
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_) {
- observer.RenderProcessWillExit(this);
- }
child_control_interface_->ProcessShutdown();
}
@@ -4026,13 +4135,14 @@ void RenderProcessHostImpl::UpdateProcessPriorityInputs() {
}
bool inputs_changed = new_visible_widgets_count != visible_clients_;
-#if defined(OS_ANDROID)
- // OS_ANDROID in order to maintain the workaround on desktop to avoid
- // backgrounding a new process. See the comment in OnProcessLaunched and
- // https://crbug.com/560446. Only android uses frame_depth for now, so
- // not a huge change.
- inputs_changed = inputs_changed || frame_depth_ != new_frame_depth;
-#endif
+
+ // Hide this update behind the ShouldBoostPriorityForPendingViews() experiment
+ // at the moment to avoid causing an undesired early UpdateProcessPriority().
+ // See the comment in OnProcessLaunched() and https://crbug.com/560446.
+ if (ShouldBoostPriorityForPendingViews()) {
+ inputs_changed = inputs_changed || frame_depth_ != new_frame_depth;
+ }
+
visible_clients_ = new_visible_widgets_count;
frame_depth_ = new_frame_depth;
#if defined(OS_ANDROID)
@@ -4047,35 +4157,40 @@ void RenderProcessHostImpl::UpdateProcessPriorityInputs() {
void RenderProcessHostImpl::UpdateProcessPriority() {
if (!run_renderer_in_process() && (!child_process_launcher_.get() ||
child_process_launcher_->IsStarting())) {
- priority_.background = blink::kLaunchingProcessIsBackgrounded;
- priority_.boost_for_pending_views =
- blink::kLaunchingProcessIsBoostedForPendingView;
+ // This path can be hit early (no-op) or on ProcessDied(). Reset |priority_|
+ // to defaults in case this RenderProcessHostImpl is re-used.
+ priority_.visible = !blink::kLaunchingProcessIsBackgrounded;
+ priority_.boost_for_pending_views = ShouldBoostPriorityForPendingViews();
return;
}
- const ChildProcessLauncherPriority priority = {
- // We background a process as soon as it hosts no active audio/video streams
- // and no visible widgets -- the callers must call this function whenever we
- // transition in/out of those states.
- visible_clients_ == 0 && media_stream_count_ == 0 &&
- !base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableRendererBackgrounding),
- frame_depth_,
- // boost_for_pending_views
- !!pending_views_,
+ const ChildProcessLauncherPriority priority(
+ visible_clients_ > 0 || base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableRendererBackgrounding),
+ media_stream_count_ > 0, frame_depth_,
+ !!pending_views_ /* boost_for_pending_views */,
#if defined(OS_ANDROID)
- GetEffectiveImportance(),
+ // Same hack as in RenderProcessHostImpl::RenderProcessHostImpl.
+ // TODO(gab): Clean this up after ShouldBoostPriorityForPendingViews()
+ // experiment.
+ false
+#else
+ ShouldBoostPriorityForPendingViews()
#endif
- };
+#if defined(OS_ANDROID)
+ ,
+ GetEffectiveImportance()
+#endif
+ );
const bool should_background_changed =
- priority_.background != priority.background;
+ priority_.is_background() != priority.is_background();
if (priority_ == priority)
return;
TRACE_EVENT2("renderer_host", "RenderProcessHostImpl::UpdateProcessPriority",
- "should_background", priority.background, "has_pending_views",
- priority.boost_for_pending_views);
+ "should_background", priority.is_background(),
+ "has_pending_views", priority.boost_for_pending_views);
priority_ = priority;
#if defined(OS_WIN)
@@ -4100,11 +4215,9 @@ void RenderProcessHostImpl::UpdateProcessPriority() {
child_process_launcher_->SetProcessPriority(priority_);
}
- // 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.
+ // Notify the child process of background state.
if (should_background_changed) {
- GetRendererInterface()->SetProcessBackgrounded(priority.background);
+ GetRendererInterface()->SetProcessBackgrounded(priority_.is_background());
}
}
@@ -4118,7 +4231,9 @@ void RenderProcessHostImpl::OnProcessLaunched() {
if (child_process_launcher_) {
DCHECK(child_process_launcher_->GetProcess().IsValid());
- DCHECK_EQ(blink::kLaunchingProcessIsBackgrounded, priority_.background);
+ // TODO(https://crbug.com/875933): This should be based on
+ // |priority_.is_background()|, see similar check below.
+ DCHECK_EQ(blink::kLaunchingProcessIsBackgrounded, !priority_.visible);
// Unpause the channel now that the process is launched. We don't flush it
// yet to ensure that any initialization messages sent here (e.g., things
@@ -4131,37 +4246,42 @@ void RenderProcessHostImpl::OnProcessLaunched() {
child_process_launcher_->GetProcess().Handle());
}
- // Not all platforms launch processes in the same backgrounded state. Make
- // sure |priority_.background| reflects this platform's initial process
- // state.
+// Not all platforms launch processes in the same backgrounded state. Make
+// sure |priority_.visible| reflects this platform's initial process
+// state.
#if defined(OS_MACOSX)
- priority_.background =
- child_process_launcher_->GetProcess().IsProcessBackgrounded(
+ priority_.visible =
+ !child_process_launcher_->GetProcess().IsProcessBackgrounded(
MachBroker::GetInstance());
#elif defined(OS_ANDROID)
// Android child process priority works differently and cannot be queried
// directly from base::Process.
- DCHECK_EQ(blink::kLaunchingProcessIsBackgrounded, priority_.background);
+ // TODO(https://crbug.com/875933): Fix initial priority on Android to
+ // reflect |priority_.is_background()|.
+ DCHECK_EQ(blink::kLaunchingProcessIsBackgrounded, !priority_.visible);
#else
- priority_.background =
- child_process_launcher_->GetProcess().IsProcessBackgrounded();
+ priority_.visible =
+ !child_process_launcher_->GetProcess().IsProcessBackgrounded();
#endif // defined(OS_MACOSX)
- // Disable updating process priority on startup on desktop platforms for now
- // as it incorrectly results in backgrounding foreground navigations until
- // their first commit is made. A better long term solution would be to be
- // aware of the tab's visibility at this point. https://crbug.com/560446.
- // This is still needed on Android which uses
- // |priority_.boost_for_pending_views| and requires RenderProcessHostImpl to
- // propagate priority changes immediately to ChildProcessLauncher.
-#if defined(OS_ANDROID)
- UpdateProcessPriority();
-#endif
+ // Only update the priority on startup if boosting is enabled (to avoid
+ // reintroducing https://crbug.com/560446#c13 while pending views only
+ // experimentally result in a boost).
+ if (priority_.boost_for_pending_views)
+ UpdateProcessPriority();
// Share histograms between the renderer and this process.
CreateSharedRendererHistogramAllocator();
}
+ // Pass bits of global renderer state to the renderer.
+ GetRendererInterface()->SetUserAgent(GetContentClient()->GetUserAgent());
+ NotifyRendererIfLockedToSite();
+ if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites() &&
+ base::FeatureList::IsEnabled(features::kV8LowMemoryModeForSubframes)) {
+ GetRendererInterface()->EnableV8LowMemoryMode();
+ }
+
// NOTE: This needs to be before flushing queued messages, because
// ExtensionService uses this notification to initialize the renderer process
// with state that must be there before any JavaScript executes.
@@ -4278,7 +4398,7 @@ RenderProcessHost* RenderProcessHostImpl::FindReusableProcessHostForSite(
auto iterator = eligible_foreground_hosts.begin();
for (int i = 0; i < index; ++i)
++iterator;
- return (*iterator);
+ return *iterator;
}
if (!eligible_background_hosts.empty()) {
@@ -4286,7 +4406,7 @@ RenderProcessHost* RenderProcessHostImpl::FindReusableProcessHostForSite(
auto iterator = eligible_background_hosts.begin();
for (int i = 0; i < index; ++i)
++iterator;
- return (*iterator);
+ return *iterator;
}
return nullptr;
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 b418b4c8a0a..582d8037c2b 100644
--- a/chromium/content/browser/renderer_host/render_process_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_process_host_impl.h
@@ -40,22 +40,22 @@
#include "content/common/media/renderer_audio_output_stream_factory.mojom.h"
#include "content/common/renderer.mojom.h"
#include "content/common/renderer_host.mojom.h"
-#include "content/common/storage_partition_service.mojom.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/service_manager_connection.h"
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_platform_file.h"
#include "media/media_buildflags.h"
-#include "mojo/edk/embedder/outgoing_broker_client_invitation.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/associated_binding_set.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/public/cpp/system/invitation.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/mojom/service.mojom.h"
#include "services/ui/public/interfaces/gpu.mojom.h"
#include "services/viz/public/interfaces/compositing/compositing_mode_watcher.mojom.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gl/gpu_switching_observer.h"
@@ -79,6 +79,7 @@ class MediaStreamTrackMetricsHost;
class P2PSocketDispatcherHost;
class PermissionServiceContext;
class PeerConnectionTrackerHost;
+class PluginRegistryImpl;
class PushMessagingManager;
class RenderFrameMessageFilter;
class RenderProcessHostFactory;
@@ -86,6 +87,7 @@ class RenderWidgetHelper;
class RenderWidgetHost;
class RenderWidgetHostImpl;
class ResourceMessageFilter;
+class ServiceWorkerDispatcherHost;
class SiteInstance;
class SiteInstanceImpl;
class StoragePartition;
@@ -160,7 +162,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
BrowserContext* GetBrowserContext() const override;
bool InSameStoragePartition(StoragePartition* partition) const override;
int GetID() const override;
- bool HasConnection() const override;
+ bool IsInitializedAndNotDead() const override;
void SetIgnoreInputEvents(bool ignore_input_events) override;
bool IgnoreInputEvents() const override;
void Cleanup() override;
@@ -206,6 +208,8 @@ class CONTENT_EXPORT RenderProcessHostImpl
mojom::Renderer* GetRendererInterface() override;
resource_coordinator::ProcessResourceCoordinator*
GetProcessResourceCoordinator() override;
+ void CreateURLLoaderFactory(
+ network::mojom::URLLoaderFactoryRequest request) override;
void SetIsNeverSuitableForReuse() override;
bool MayReuseHost() override;
@@ -213,6 +217,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
void SetIsUsed() override;
bool HostHasNotBeenUsed() override;
+ void LockToOrigin(const GURL& lock_url) override;
void BindCacheStorage(blink::mojom::CacheStorageRequest request,
const url::Origin& origin) override;
@@ -323,7 +328,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
// service.
using CreateStoragePartitionServiceFunction =
void (*)(RenderProcessHostImpl* rph,
- mojom::StoragePartitionServiceRequest request);
+ blink::mojom::StoragePartitionServiceRequest request);
static void SetCreateStoragePartitionServiceFunction(
CreateStoragePartitionServiceFunction function);
@@ -466,8 +471,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
mojom::AssociatedInterfaceAssociatedRequest request) override;
// mojom::RendererHost
- void GetBlobURLLoaderFactory(
- network::mojom::URLLoaderFactoryRequest request) override;
using BrowserHistogramCallback =
mojom::RendererHost::GetBrowserHistogramCallback;
void GetBrowserHistogram(const std::string& name,
@@ -483,9 +486,8 @@ class CONTENT_EXPORT RenderProcessHostImpl
void BindCompositingModeReporter(
viz::mojom::CompositingModeReporterRequest request);
void CreateStoragePartitionService(
- mojom::StoragePartitionServiceRequest request);
+ blink::mojom::StoragePartitionServiceRequest request);
void CreateRendererHost(mojom::RendererHostAssociatedRequest request);
- void CreateURLLoaderFactory(network::mojom::URLLoaderFactoryRequest request);
// Control message handlers.
void OnUserMetricsRecordAction(const std::string& action);
@@ -574,6 +576,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
base::FilePath GetAecDumpFilePathWithExtensions(const base::FilePath& file);
base::SequencedTaskRunner& GetAecDumpFileTaskRunner();
void OnAec3Enabled();
+ void NotifyRendererIfLockedToSite();
static void OnMojoError(int render_process_id, const std::string& error);
@@ -612,8 +615,7 @@ class CONTENT_EXPORT RenderProcessHostImpl
// execute.
void CancelProcessShutdownDelayForUnload();
- std::unique_ptr<mojo::edk::OutgoingBrokerClientInvitation>
- broker_client_invitation_;
+ mojo::OutgoingInvitation mojo_invitation_;
std::unique_ptr<ChildConnection> child_connection_;
int connection_filter_id_ =
@@ -788,6 +790,9 @@ class CONTENT_EXPORT RenderProcessHostImpl
std::unique_ptr<IndexedDBDispatcherHost, BrowserThread::DeleteOnIOThread>
indexed_db_factory_;
+ std::unique_ptr<ServiceWorkerDispatcherHost, BrowserThread::DeleteOnIOThread>
+ service_worker_dispatcher_host_;
+
scoped_refptr<CacheStorageDispatcherHost> cache_storage_dispatcher_host_;
bool channel_connected_;
@@ -808,6 +813,8 @@ class CONTENT_EXPORT RenderProcessHostImpl
push_messaging_manager_;
std::unique_ptr<EmbeddedFrameSinkProviderImpl> embedded_frame_sink_provider_;
+ std::unique_ptr<PluginRegistryImpl, BrowserThread::DeleteOnIOThread>
+ plugin_registry_;
mojom::ChildControlPtr child_control_interface_;
mojom::RouteProviderAssociatedPtr remote_route_provider_;
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 1ed8e6caccc..b036f1a9a31 100644
--- a/chromium/content/browser/renderer_host/render_process_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_process_host_unittest.cc
@@ -11,7 +11,7 @@
#include "base/command_line.h"
#include "base/macros.h"
#include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "build/build_config.h"
#include "content/common/frame_messages.h"
#include "content/common/frame_owner_properties.h"
@@ -57,9 +57,6 @@ TEST_F(RenderProcessHostUnitTest, RendererProcessLimit) {
if (AreAllSitesIsolatedForTesting())
return;
- // Disable any overrides.
- RenderProcessHostImpl::SetMaxRendererProcessCount(0);
-
// Verify that the limit is between 1 and kMaxRendererProcessCount.
EXPECT_GT(RenderProcessHostImpl::GetMaxRendererProcessCount(), 0u);
EXPECT_LE(RenderProcessHostImpl::GetMaxRendererProcessCount(),
@@ -81,9 +78,6 @@ TEST_F(RenderProcessHostUnitTest, RendererProcessLimit) {
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
TEST_F(RenderProcessHostUnitTest, NoRendererProcessLimitOnAndroidOrChromeOS) {
- // Disable any overrides.
- RenderProcessHostImpl::SetMaxRendererProcessCount(0);
-
// Add a few dummy process hosts.
ASSERT_NE(0u, kMaxRendererProcessCount);
std::vector<std::unique_ptr<MockRenderProcessHost>> hosts;
@@ -888,9 +882,35 @@ TEST_F(RenderProcessHostUnitTest,
SetBrowserClientForTesting(regular_client);
}
+// Check whether we notify the renderer that it has been locked to a site or
+// not. This should depend on the URL from the SiteInstance.
+TEST_F(RenderProcessHostUnitTest, RendererLockedToSite) {
+ struct TestData {
+ GURL test_url;
+ bool should_lock_renderer;
+ } tests[] = {{GURL("http://"), false},
+ {GURL("http://foo.com"), true},
+ {GURL("http://bar.foo.com"), true},
+ {GURL(""), false},
+ {GURL("google.com"), false},
+ {GURL("http:"), false},
+ {GURL("http://user:pass@google.com:99/foo;bar?q=a#ref"), true}};
+ for (const auto& test : tests) {
+ scoped_refptr<SiteInstanceImpl> site_instance =
+ SiteInstanceImpl::CreateForURL(browser_context(), test.test_url);
+ auto* host =
+ static_cast<MockRenderProcessHost*>(site_instance->GetProcess());
+ if (AreAllSitesIsolatedForTesting())
+ EXPECT_EQ(test.should_lock_renderer, host->is_renderer_locked_to_site());
+ else
+ EXPECT_EQ(false, host->is_renderer_locked_to_site());
+ }
+}
+
class SpareRenderProcessHostUnitTest : public RenderViewHostImplTestHarness {
public:
SpareRenderProcessHostUnitTest() {}
+ ~SpareRenderProcessHostUnitTest() override = default;
protected:
void SetUp() override {
@@ -903,6 +923,13 @@ class SpareRenderProcessHostUnitTest : public RenderViewHostImplTestHarness {
}
}
+ void TearDown() override {
+ // Important: Reset the max renderer count to leave this process in a
+ // pristine state.
+ RenderProcessHost::SetMaxRendererProcessCount(0);
+ RenderViewHostImplTestHarness::TearDown();
+ }
+
MockRenderProcessHostFactory rph_factory_;
private:
@@ -1056,7 +1083,9 @@ TEST_F(SpareRenderProcessHostUnitTest,
// in this scenario would put us over the process limit and is therefore
// undesirable.
TEST_F(SpareRenderProcessHostUnitTest, JustBelowProcessLimit) {
- RenderProcessHostImpl::SetMaxRendererProcessCount(1);
+ // Override a global. TearDown() will call SetMaxRendererProcessCount() again
+ // to clean up.
+ RenderProcessHost::SetMaxRendererProcessCount(1);
// No spare or any other renderer process at the start of the test.
EXPECT_FALSE(RenderProcessHostImpl::GetSpareRenderProcessHostForTesting());
@@ -1078,7 +1107,9 @@ TEST_F(SpareRenderProcessHostUnitTest, JustBelowProcessLimit) {
// This unit test verifies that a mismatched spare RenderProcessHost is dropped
// before considering process reuse due to the process limit.
TEST_F(SpareRenderProcessHostUnitTest, AtProcessLimit) {
- RenderProcessHostImpl::SetMaxRendererProcessCount(2);
+ // Override a global. TearDown() will call SetMaxRendererProcessCount() again
+ // to clean up.
+ RenderProcessHost::SetMaxRendererProcessCount(2);
// Create and navigate the 1st WebContents.
const GURL kUrl1("http://foo.com");
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 6ceb1543e01..8aa0ca33809 100644
--- a/chromium/content/browser/renderer_host/render_view_host_delegate.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_delegate.cc
@@ -37,10 +37,6 @@ FrameTree* RenderViewHostDelegate::GetFrameTree() {
return nullptr;
}
-double RenderViewHostDelegate::GetPendingPageZoomLevel() {
- return 0.0;
-}
-
bool RenderViewHostDelegate::IsNeverVisible() {
return false;
}
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 cec02574757..f2d59fbd1f4 100644
--- a/chromium/content/browser/renderer_host/render_view_host_delegate.h
+++ b/chromium/content/browser/renderer_host/render_view_host_delegate.h
@@ -94,7 +94,7 @@ class CONTENT_EXPORT RenderViewHostDelegate {
virtual void Close(RenderViewHost* render_view_host) {}
// The page is trying to move the RenderView's representation in the client.
- virtual void RequestMove(const gfx::Rect& new_bounds) {}
+ virtual void RequestSetBounds(const gfx::Rect& new_bounds) {}
// The RenderView's main frame document element is ready. This happens when
// the document has finished parsing.
@@ -155,11 +155,6 @@ class CONTENT_EXPORT RenderViewHostDelegate {
// to this view.
virtual SessionStorageNamespaceMap GetSessionStorageNamespaceMap();
- // Returns the zoom level for the pending navigation for the page. If there
- // is no pending navigation, this returns the zoom level for the current
- // page.
- virtual double GetPendingPageZoomLevel();
-
// Returns true if the RenderViewHost will never be visible.
virtual bool IsNeverVisible();
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 7dc57079eb4..a7532fa393c 100644
--- a/chromium/content/browser/renderer_host/render_view_host_factory.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_factory.cc
@@ -26,6 +26,7 @@ RenderViewHost* RenderViewHostFactory::Create(
RenderWidgetHostDelegate* widget_delegate,
int32_t routing_id,
int32_t main_frame_routing_id,
+ int32_t widget_routing_id,
bool swapped_out,
bool hidden) {
// RenderViewHost creation can be either browser-driven (by the user opening a
@@ -34,7 +35,9 @@ RenderViewHost* RenderViewHostFactory::Create(
// In the browser-driven case, the routing ID of the view is lazily assigned:
// this is signified by passing MSG_ROUTING_NONE for |routing_id|.
if (routing_id == MSG_ROUTING_NONE) {
+ DCHECK_EQ(widget_routing_id, MSG_ROUTING_NONE);
routing_id = instance->GetProcess()->GetNextRoutingID();
+ widget_routing_id = instance->GetProcess()->GetNextRoutingID();
} else {
// Otherwise, in the renderer-driven case, the routing ID of the view is
// already set. This is due to the fact that a sync render->browser IPC is
@@ -46,14 +49,14 @@ RenderViewHost* RenderViewHostFactory::Create(
if (factory_) {
return factory_->CreateRenderViewHost(instance, delegate, widget_delegate,
routing_id, main_frame_routing_id,
- swapped_out);
+ widget_routing_id, swapped_out);
}
return new RenderViewHostImpl(
instance,
base::WrapUnique(RenderWidgetHostFactory::Create(
- widget_delegate, instance->GetProcess(), routing_id, nullptr,
+ widget_delegate, instance->GetProcess(), widget_routing_id, nullptr,
hidden)),
- delegate, main_frame_routing_id, swapped_out,
+ delegate, routing_id, main_frame_routing_id, swapped_out,
true /* has_initialized_audio_host */);
}
diff --git a/chromium/content/browser/renderer_host/render_view_host_factory.h b/chromium/content/browser/renderer_host/render_view_host_factory.h
index 51babd49079..6987d4e84e0 100644
--- a/chromium/content/browser/renderer_host/render_view_host_factory.h
+++ b/chromium/content/browser/renderer_host/render_view_host_factory.h
@@ -29,6 +29,7 @@ class RenderViewHostFactory {
RenderWidgetHostDelegate* widget_delegate,
int32_t routing_id,
int32_t main_frame_routing_id,
+ int32_t widget_routing_id,
bool swapped_out,
bool hidden);
@@ -61,6 +62,7 @@ class RenderViewHostFactory {
RenderWidgetHostDelegate* widget_delegate,
int32_t routing_id,
int32_t main_frame_routing_id,
+ int32_t widget_routing_id,
bool swapped_out) = 0;
// Registers your factory to be called when new RenderViewHosts are created.
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 e8aa2e41e8a..1f491537c8f 100644
--- a/chromium/content/browser/renderer_host/render_view_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_impl.cc
@@ -112,6 +112,12 @@ using blink::WebPluginAction;
namespace content {
namespace {
+// <process id, routing id>
+using RenderViewHostID = std::pair<int32_t, int32_t>;
+using RoutingIDViewMap = base::hash_map<RenderViewHostID, RenderViewHostImpl*>;
+base::LazyInstance<RoutingIDViewMap>::Leaky g_routing_id_view_map =
+ LAZY_INSTANCE_INITIALIZER;
+
void GetPlatformSpecificPrefs(RendererPreferences* prefs) {
#if defined(OS_WIN)
NONCLIENTMETRICS_XP metrics = {0};
@@ -173,13 +179,12 @@ RenderViewHost* RenderViewHost::From(RenderWidgetHost* rwh) {
// RenderViewHostImpl, public:
// static
-RenderViewHostImpl* RenderViewHostImpl::FromID(int render_process_id,
- int render_view_id) {
- RenderWidgetHost* widget =
- RenderWidgetHost::FromID(render_process_id, render_view_id);
- if (!widget)
- return nullptr;
- return From(widget);
+RenderViewHostImpl* RenderViewHostImpl::FromID(int process_id, int routing_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ RoutingIDViewMap* views = g_routing_id_view_map.Pointer();
+ RoutingIDViewMap::iterator it =
+ views->find(RenderViewHostID(process_id, routing_id));
+ return it == views->end() ? nullptr : it->second;
}
// static
@@ -198,6 +203,7 @@ RenderViewHostImpl::RenderViewHostImpl(
SiteInstance* instance,
std::unique_ptr<RenderWidgetHostImpl> widget,
RenderViewHostDelegate* delegate,
+ int32_t routing_id,
int32_t main_frame_routing_id,
bool swapped_out,
bool has_initialized_audio_host)
@@ -207,6 +213,7 @@ RenderViewHostImpl::RenderViewHostImpl(
instance_(static_cast<SiteInstanceImpl*>(instance)),
is_active_(!swapped_out),
is_swapped_out_(swapped_out),
+ routing_id_(routing_id),
main_frame_routing_id_(main_frame_routing_id),
is_waiting_for_close_ack_(false),
sudden_termination_allowed_(false),
@@ -216,6 +223,13 @@ RenderViewHostImpl::RenderViewHostImpl(
weak_factory_(this) {
DCHECK(instance_.get());
CHECK(delegate_); // http://crbug.com/82827
+ DCHECK_NE(GetRoutingID(), render_widget_host_->GetRoutingID());
+
+ std::pair<RoutingIDViewMap::iterator, bool> result =
+ g_routing_id_view_map.Get().emplace(
+ RenderViewHostID(GetProcess()->GetID(), routing_id_), this);
+ CHECK(result.second) << "Inserting a duplicate item!";
+ GetProcess()->AddRoute(routing_id_, this);
GetWidget()->set_owner_delegate(this);
@@ -255,6 +269,12 @@ RenderViewHostImpl::~RenderViewHostImpl() {
base::Unretained(ResourceDispatcherHostImpl::Get()),
GetProcess()->GetID(), GetRoutingID()));
}
+
+ // Detach the routing ID as the object is going away.
+ GetProcess()->RemoveRoute(GetRoutingID());
+ g_routing_id_view_map.Get().erase(
+ RenderViewHostID(GetProcess()->GetID(), GetRoutingID()));
+
delegate_->RenderViewDeleted(this);
GetProcess()->RemoveObserver(this);
}
@@ -283,7 +303,7 @@ bool RenderViewHostImpl::CreateRenderView(
// ignored, so this is safe.
if (!GetProcess()->Init())
return false;
- DCHECK(GetProcess()->HasConnection());
+ DCHECK(GetProcess()->IsInitializedAndNotDead());
DCHECK(GetProcess()->GetBrowserContext());
CHECK(main_frame_routing_id_ != MSG_ROUTING_NONE ||
proxy_route_id != MSG_ROUTING_NONE);
@@ -314,6 +334,7 @@ bool RenderViewHostImpl::CreateRenderView(
params->web_preferences = GetWebkitPreferences();
params->view_id = GetRoutingID();
params->main_frame_routing_id = main_frame_routing_id_;
+ params->main_frame_widget_routing_id = render_widget_host_->GetRoutingID();
if (main_rfh) {
main_rfh->BindInterfaceProviderRequest(
mojo::MakeRequest(&params->main_frame_interface_provider));
@@ -335,7 +356,6 @@ bool RenderViewHostImpl::CreateRenderView(
params->has_committed_real_load =
main_rfh->frame_tree_node()->has_committed_real_load();
}
- params->page_zoom_level = delegate_->GetPendingPageZoomLevel();
params->devtools_main_frame_token = devtools_frame_token;
// GuestViews in the same StoragePartition need to find each other's frames.
params->renderer_wide_named_frame_lookup =
@@ -368,7 +388,8 @@ void RenderViewHostImpl::SetIsActive(bool is_active) {
}
bool RenderViewHostImpl::IsRenderViewLive() const {
- return GetProcess()->HasConnection() && GetWidget()->renderer_initialized();
+ return GetProcess()->IsInitializedAndNotDead() &&
+ GetWidget()->renderer_initialized();
}
void RenderViewHostImpl::SyncRendererPrefs() {
@@ -558,9 +579,6 @@ WebPreferences RenderViewHostImpl::ComputeWebkitPrefs() {
prefs.background_video_track_optimization_enabled =
base::FeatureList::IsEnabled(media::kBackgroundVideoTrackOptimization);
- prefs.picture_in_picture_enabled =
- base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideo);
-
GetContentClient()->browser()->OverrideWebkitPrefs(this, &prefs);
return prefs;
}
@@ -644,7 +662,7 @@ RenderProcessHost* RenderViewHostImpl::GetProcess() const {
}
int RenderViewHostImpl::GetRoutingID() const {
- return GetWidget()->GetRoutingID();
+ return routing_id_;
}
RenderFrameHost* RenderViewHostImpl::GetMainFrame() {
@@ -758,7 +776,7 @@ bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) {
OnShowFullscreenWidget)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateTargetURL, OnUpdateTargetURL)
IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose)
- IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnRequestMove)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_RequestSetBounds, OnRequestSetBounds)
IPC_MESSAGE_HANDLER(ViewHostMsg_DocumentAvailableInMainFrame,
OnDocumentAvailableInMainFrame)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidContentsPreferredSizeChange,
@@ -781,7 +799,7 @@ void RenderViewHostImpl::RenderWidgetDidInit() {
void RenderViewHostImpl::ShutdownAndDestroy() {
// We can't release the SessionStorageNamespace until our peer
// in the renderer has wound down.
- if (GetProcess()->HasConnection()) {
+ if (GetProcess()->IsInitializedAndNotDead()) {
RenderProcessHostImpl::ReleaseOnCloseACK(
GetProcess(),
delegate_->GetSessionStorageNamespaceMap(),
@@ -808,12 +826,12 @@ void RenderViewHostImpl::CreateNewFullscreenWidget(int32_t route_id,
void RenderViewHostImpl::OnShowWidget(int route_id,
const gfx::Rect& initial_rect) {
delegate_->ShowCreatedWidget(GetProcess()->GetID(), route_id, initial_rect);
- Send(new ViewMsg_Move_ACK(route_id));
+ Send(new ViewMsg_SetBounds_ACK(route_id));
}
void RenderViewHostImpl::OnShowFullscreenWidget(int route_id) {
delegate_->ShowCreatedFullscreenWidget(GetProcess()->GetID(), route_id);
- Send(new ViewMsg_Move_ACK(route_id));
+ Send(new ViewMsg_SetBounds_ACK(route_id));
}
void RenderViewHostImpl::OnRenderProcessGone(int status, int exit_code) {
@@ -837,10 +855,10 @@ void RenderViewHostImpl::OnClose() {
ClosePageIgnoringUnloadEvents();
}
-void RenderViewHostImpl::OnRequestMove(const gfx::Rect& pos) {
+void RenderViewHostImpl::OnRequestSetBounds(const gfx::Rect& bounds) {
if (is_active_)
- delegate_->RequestMove(pos);
- Send(new ViewMsg_Move_ACK(GetRoutingID()));
+ delegate_->RequestSetBounds(bounds);
+ Send(new ViewMsg_SetBounds_ACK(GetRoutingID()));
}
void RenderViewHostImpl::OnDocumentAvailableInMainFrame(
@@ -907,6 +925,11 @@ bool RenderViewHostImpl::ShouldContributePriorityToProcess() {
return is_active_;
}
+void RenderViewHostImpl::RenderWidgetDidShutdown() {
+ bool rv = Send(new ViewMsg_Close(GetRoutingID()));
+ DCHECK(rv);
+}
+
WebPreferences RenderViewHostImpl::GetWebkitPreferences() {
if (!web_preferences_.get()) {
OnWebkitPreferencesChanged();
@@ -941,13 +964,6 @@ void RenderViewHostImpl::EnablePreferredSizeMode() {
Send(new ViewMsg_EnablePreferredSizeChangedMode(GetRoutingID()));
}
-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) {
// TODO(wjmaclean): See if this needs to be done for OOPIFs as well.
diff --git a/chromium/content/browser/renderer_host/render_view_host_impl.h b/chromium/content/browser/renderer_host/render_view_host_impl.h
index f80c4c4330b..af7f7b0d580 100644
--- a/chromium/content/browser/renderer_host/render_view_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_view_host_impl.h
@@ -63,10 +63,11 @@ class TimeoutMonitor;
// https://www.chromium.org/developers/design-documents/site-isolation.
class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
public RenderWidgetHostOwnerDelegate,
- public RenderProcessHostObserver {
+ public RenderProcessHostObserver,
+ public IPC::Listener {
public:
// Convenience function, just like RenderViewHost::FromID.
- static RenderViewHostImpl* FromID(int render_process_id, int render_view_id);
+ static RenderViewHostImpl* FromID(int process_id, int routing_id);
// Convenience function, just like RenderViewHost::From.
static RenderViewHostImpl* From(RenderWidgetHost* rwh);
@@ -74,9 +75,12 @@ class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
RenderViewHostImpl(SiteInstance* instance,
std::unique_ptr<RenderWidgetHostImpl> widget,
RenderViewHostDelegate* delegate,
+ int32_t routing_id,
int32_t main_frame_routing_id,
bool swapped_out,
bool has_initialized_audio_host);
+ // TODO(ajwong): Make destructor private. Deletion of this object should only
+ // be done via ShutdownAndDestroy(). https://crbug.com/545684
~RenderViewHostImpl() override;
// Shuts down this RenderViewHost and deletes it.
@@ -93,9 +97,6 @@ class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
const std::vector<base::FilePath>& files) override;
void DisableScrollbarsForThreshold(const gfx::Size& size) override;
void EnablePreferredSizeMode() override;
- void ExecuteMediaPlayerActionAtLocation(
- const gfx::Point& location,
- const blink::WebMediaPlayerAction& action) override;
void ExecutePluginActionAtLocation(
const gfx::Point& location,
const blink::WebPluginAction& action) override;
@@ -238,6 +239,7 @@ class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
bool MayRenderWidgetForwardKeyboardEvent(
const NativeWebKeyboardEvent& key_event) override;
bool ShouldContributePriorityToProcess() override;
+ void RenderWidgetDidShutdown() override;
// IPC message handlers.
void OnShowView(int route_id,
@@ -249,7 +251,7 @@ class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
void OnRenderProcessGone(int status, int error_code);
void OnUpdateTargetURL(const GURL& url);
void OnClose();
- void OnRequestMove(const gfx::Rect& pos);
+ void OnRequestSetBounds(const gfx::Rect& bounds);
void OnDocumentAvailableInMainFrame(bool uses_temporary_zoom_level);
void OnDidContentsPreferredSizeChange(const gfx::Size& new_size);
void OnPasteFromSelectionClipboard();
@@ -315,6 +317,9 @@ class CONTENT_EXPORT RenderViewHostImpl : public RenderViewHost,
// See https://crbug.com/745091.
bool is_swapped_out_;
+ // Routing ID for this RenderViewHost.
+ const int routing_id_;
+
// Routing ID for the main frame's RenderFrameHost.
int main_frame_routing_id_;
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 5a0fe447e12..9eaeefd55b4 100644
--- a/chromium/content/browser/renderer_host/render_view_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_view_host_unittest.cc
@@ -288,6 +288,7 @@ class TestSaveImageFromDataURL : public RenderFrameMessageFilter {
const url::Origin& initiator,
const base::string16& suggested_name,
const bool use_prompt,
+ const bool follow_cross_origin_redirects,
blink::mojom::BlobURLTokenPtrInfo blob_url_token) const override {
url_string_ = url.spec();
is_downloaded_ = true;
diff --git a/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc b/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc
index 2b5a683eb0c..373ecd28b14 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_browsertest.cc
@@ -15,6 +15,8 @@
#include "components/viz/common/quads/render_pass.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "content/browser/bad_message.h"
+#include "content/browser/renderer_host/input/input_router_impl.h"
+#include "content/browser/renderer_host/input/touch_action_filter.h"
#include "content/browser/renderer_host/input/touch_emulator.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
@@ -22,10 +24,13 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/public/platform/web_mouse_event.h"
@@ -37,7 +42,31 @@
namespace content {
-class RenderWidgetHostBrowserTest : public ContentBrowserTest {};
+class RenderWidgetHostBrowserTest : public ContentBrowserTest {
+ protected:
+ WebContentsImpl* web_contents() const {
+ return static_cast<WebContentsImpl*>(shell()->web_contents());
+ }
+
+ TouchActionFilter* GetTouchActionFilterForWidget(RenderWidgetHostImpl* rwhi) {
+ return &static_cast<InputRouterImpl*>(rwhi->input_router())
+ ->touch_action_filter_;
+ }
+};
+
+// The --site-per-porcess version of RenderWidgetHostBrowserTest.
+class RenderWidgetHostSitePerProcessTest : public RenderWidgetHostBrowserTest {
+ public:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ IsolateAllSitesForTesting(command_line);
+ }
+
+ void SetUpOnMainThread() override {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ SetupCrossSiteRedirector(embedded_test_server());
+ ASSERT_TRUE(embedded_test_server()->Start());
+ }
+};
IN_PROC_BROWSER_TEST_F(RenderWidgetHostBrowserTest,
ProhibitsCopyRequestsFromRenderer) {
@@ -370,4 +399,55 @@ IN_PROC_BROWSER_TEST_F(RenderWidgetHostTouchEmulatorBrowserTest,
host()->RemoveInputEventObserver(&observer);
}
+// Observes the WebContents until a frame finishes loading the contents of a
+// given GURL.
+class DocumentLoadObserver : WebContentsObserver {
+ public:
+ DocumentLoadObserver(WebContents* contents, const GURL& url)
+ : WebContentsObserver(contents), document_origin_(url) {}
+
+ void Wait() {
+ if (loaded_)
+ return;
+ run_loop_.reset(new base::RunLoop());
+ run_loop_->Run();
+ }
+
+ private:
+ void DidFinishLoad(RenderFrameHost* rfh, const GURL& url) override {
+ loaded_ |= (url == document_origin_);
+ if (loaded_ && run_loop_)
+ run_loop_->Quit();
+ }
+
+ bool loaded_ = false;
+ const GURL document_origin_;
+ std::unique_ptr<base::RunLoop> run_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(DocumentLoadObserver);
+};
+
+// This test verifies that when a cross-process child frame loads, the initial
+// updates for touch event handlers are sent from the renderer.
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostSitePerProcessTest,
+ OnHasTouchEventHandlers) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b)"));
+ GURL::Replacements replacement;
+ replacement.SetHostStr("b.com");
+ replacement.SetQueryStr("b()");
+ GURL target_child_url = main_url.ReplaceComponents(replacement);
+ DocumentLoadObserver child_frame_observer(shell()->web_contents(),
+ target_child_url);
+ NavigateToURL(shell(), main_url);
+ child_frame_observer.Wait();
+ auto* filter = GetTouchActionFilterForWidget(web_contents()
+ ->GetFrameTree()
+ ->root()
+ ->child_at(0)
+ ->current_frame_host()
+ ->GetRenderWidgetHost());
+ EXPECT_TRUE(filter->allowed_touch_action().has_value());
+}
+
} // namespace content
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 b41e5f828d2..00c3a8c727d 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_delegate.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_delegate.cc
@@ -27,6 +27,10 @@ bool RenderWidgetHostDelegate::PreHandleGestureEvent(
return false;
}
+double RenderWidgetHostDelegate::GetPendingPageZoomLevel() const {
+ return 0.0;
+}
+
BrowserAccessibilityManager*
RenderWidgetHostDelegate::GetRootBrowserAccessibilityManager() {
return nullptr;
@@ -114,9 +118,10 @@ bool RenderWidgetHostDelegate::AddDomainInfoToRapporSample(
return false;
}
-void RenderWidgetHostDelegate::UpdateUrlForUkmSource(
- ukm::UkmRecorder* service,
- ukm::SourceId ukm_source_id) {}
+ukm::SourceId RenderWidgetHostDelegate::GetUkmSourceIdForLastCommittedSource()
+ const {
+ return ukm::kInvalidSourceId;
+}
gfx::Size RenderWidgetHostDelegate::GetAutoResizeSize() {
return gfx::Size();
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 f8a97cb4381..b054514ea74 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_delegate.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_delegate.h
@@ -10,6 +10,7 @@
#include <string>
#include <vector>
+#include "base/callback.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/common/drag_event_source_info.h"
@@ -19,6 +20,7 @@
#include "third_party/blink/public/platform/web_drag_operation.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/range/range.h"
namespace blink {
class WebMouseWheelEvent;
@@ -34,10 +36,6 @@ namespace rappor {
class Sample;
}
-namespace ukm {
-class UkmRecorder;
-}
-
namespace content {
class BrowserAccessibilityManager;
@@ -66,6 +64,12 @@ class CONTENT_EXPORT RenderWidgetHostDelegate {
// The RenderWidgetHost got the focus.
virtual void RenderWidgetGotFocus(RenderWidgetHostImpl* render_widget_host) {}
+ // If a main frame navigation is in progress, this will return the zoom level
+ // for the pending page. Otherwise, this returns the zoom level for the
+ // current page. Note that subframe navigations do not affect the zoom level,
+ // which is tracked at the level of the page.
+ virtual double GetPendingPageZoomLevel() const;
+
// The RenderWidgetHost lost the focus.
virtual void RenderWidgetLostFocus(
RenderWidgetHostImpl* render_widget_host) {}
@@ -132,6 +136,11 @@ class CONTENT_EXPORT RenderWidgetHostDelegate {
// currently focused frame.
virtual void SelectRange(const gfx::Point& base, const gfx::Point& extent) {}
+#if defined(OS_MACOSX)
+ virtual void DidChangeTextSelection(const base::string16& text,
+ const gfx::Range& range) {}
+#endif
+
// Request the renderer to Move the caret to the new position.
virtual void MoveCaret(const gfx::Point& extent) {}
@@ -155,7 +164,10 @@ class CONTENT_EXPORT RenderWidgetHostDelegate {
// Notification that the renderer has become unresponsive. The
// delegate can use this notification to show a warning to the user.
- virtual void RendererUnresponsive(RenderWidgetHostImpl* render_widget_host) {}
+ // See also WebContentsDelegate::RendererUnresponsive.
+ virtual void RendererUnresponsive(
+ RenderWidgetHostImpl* render_widget_host,
+ base::RepeatingClosure hang_monitor_restarter) {}
// Notification that a previously unresponsive renderer has become
// responsive again. The delegate can use this notification to end the
@@ -258,10 +270,9 @@ class CONTENT_EXPORT RenderWidgetHostDelegate {
// if the eTLD+1 is not known for |render_widget_host|.
virtual bool AddDomainInfoToRapporSample(rappor::Sample* sample);
- // Update UkmRecorder for the given source with the URL. This is used for
- // URL-keyed metrics to set the url for a report.
- virtual void UpdateUrlForUkmSource(ukm::UkmRecorder* service,
- ukm::SourceId ukm_source_id);
+ // Get the UKM source ID for current content. This is used for providing
+ // data about the content to the URL-keyed metrics service.
+ virtual ukm::SourceId GetUkmSourceIdForLastCommittedSource() const;
// Notifies the delegate that a focused editable element has been touched
// inside this RenderWidgetHost. If |editable| is true then the focused
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 213f32e0891..9ab96c3f933 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.cc
@@ -115,6 +115,7 @@
#include "ui/snapshot/snapshot.h"
#if defined(OS_ANDROID)
+#include "content/browser/renderer_host/input/fling_scheduler_android.h"
#include "ui/android/view_android.h"
#endif
@@ -382,8 +383,9 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
base::checked_cast<uint32_t>(routing_id_)),
weak_factory_(this) {
#if defined(OS_MACOSX)
- auto fling_scheduler = std::make_unique<FlingSchedulerMac>(this);
- fling_scheduler_ = std::move(fling_scheduler);
+ fling_scheduler_ = std::make_unique<FlingSchedulerMac>(this);
+#elif defined(OS_ANDROID)
+ fling_scheduler_ = std::make_unique<FlingSchedulerAndroid>(this);
#else
fling_scheduler_ = std::make_unique<FlingScheduler>(this);
#endif
@@ -399,14 +401,12 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
process_->AddRoute(routing_id_, this);
process_->AddWidget(this);
- latency_tracker_.Initialize(routing_id_, GetProcess()->GetID());
-
SetupInputRouter();
SetWidget(std::move(widget));
const auto* command_line = base::CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(switches::kDisableHangMonitor)) {
- hang_monitor_timeout_.reset(new TimeoutMonitor(
+ input_event_ack_timeout_.reset(new TimeoutMonitor(
base::Bind(&RenderWidgetHostImpl::RendererIsUnresponsive,
weak_factory_.GetWeakPtr())));
}
@@ -420,6 +420,17 @@ RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
enable_surface_synchronization_ = features::IsSurfaceSynchronizationEnabled();
enable_viz_ = base::FeatureList::IsEnabled(features::kVizDisplayCompositor);
+ if (!enable_viz_) {
+#if !defined(OS_ANDROID)
+ // Software compositing is not supported or used on Android.
+ //
+ // The BrowserMainLoop is null in unit tests, but they do not use
+ // compositing and report SharedBitmapIds.
+ if (BrowserMainLoop* main_loop = BrowserMainLoop::GetInstance())
+ shared_bitmap_manager_ = main_loop->GetServerSharedBitmapManager();
+#endif
+ }
+
delegate_->RenderWidgetCreated(this);
render_frame_metadata_provider_.AddObserver(this);
}
@@ -565,7 +576,7 @@ void RenderWidgetHostImpl::UpdatePriority() {
}
void RenderWidgetHostImpl::Init() {
- DCHECK(process_->HasConnection());
+ DCHECK(process_->IsInitializedAndNotDead());
renderer_initialized_ = true;
@@ -580,7 +591,7 @@ void RenderWidgetHostImpl::Init() {
}
void RenderWidgetHostImpl::InitForFrame() {
- DCHECK(process_->HasConnection());
+ DCHECK(process_->IsInitializedAndNotDead());
renderer_initialized_ = true;
if (view_)
@@ -591,10 +602,42 @@ void RenderWidgetHostImpl::ShutdownAndDestroyWidget(bool also_delete) {
CancelKeyboardLock();
RejectMouseLockOrUnlockIfNecessary();
- if (process_->HasConnection()) {
- // Tell the renderer object to close.
- bool rv = Send(new ViewMsg_Close(routing_id_));
- DCHECK(rv);
+ if (process_->IsInitializedAndNotDead()) {
+ // This logic below simulates the routing behavior from when RenderWidget
+ // associated with RenderViews shared the same routing IDs.
+ //
+ // In the original code, the sharing of the routing ID yielded a bastardized
+ // version of dynamic dispatch wherein the ultimate static code path that
+ // handled a ViewMsg_Close changed based on if
+ //
+ // (a) the RenderWidgetImpl was also a RenderViewImpl
+ // (b) the RenderViewImpl hooked the message in OnMessageReceived
+ //
+ // In the current code, if RenderWidgetImpl IS NOT a RenderViewImpl,
+ // RenderWidgetHost WILL NOT have a |owner_delegate_| and the message can
+ // be dispatched directly. This is the simplest case.
+ //
+ // If RenderWidgetImpl IS is a RenderViewImpl, then on some platforms
+ // (seems like only Mac?) RenderViewImpl overrides ViewMsg::OnClose to do
+ // additional processing before passing it up to RenderWidgetImpl::OnClose.
+ //
+ // When it is not overridden, the message delegated up via
+ // IPC_MESSAGE_UNHANDLED to the RenderWidget's message dispatching.
+ //
+ // Basically, there are 2 overlapping hand-written implementations of
+ // dynamic dispatch occuring: one via IPC_MESSAGE_UNHANDLED, and another
+ // via calling the super-class method.
+ //
+ // TODO(ajwong): Once the routing_id split CL lands, remove one of these
+ // implementaions of hand-written dyanmic dispatch. The world does not
+ // need so many implementations of what's effectively "virtual."
+ if (owner_delegate_) {
+ owner_delegate_->RenderWidgetDidShutdown();
+ } else {
+ // Tell the non-view RendererWidget to close.
+ bool rv = Send(new ViewMsg_Close(routing_id_));
+ DCHECK(rv);
+ }
}
Destroy(also_delete);
@@ -619,7 +662,7 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnClose)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateScreenRects_ACK,
OnUpdateScreenRectsAck)
- IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnRequestMove)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_RequestSetBounds, OnRequestSetBounds)
IPC_MESSAGE_HANDLER(ViewHostMsg_SetTooltipText, OnSetTooltipText)
IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnSetCursor)
IPC_MESSAGE_HANDLER(ViewHostMsg_AutoscrollStart, OnAutoscrollStart)
@@ -636,6 +679,7 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeTouched, OnFocusedNodeTouched)
IPC_MESSAGE_HANDLER(DragHostMsg_StartDragging, OnStartDragging)
IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_ForceRedrawComplete, OnForceRedrawComplete)
IPC_MESSAGE_HANDLER(ViewHostMsg_FrameSwapMessages,
OnFrameSwapMessagesReceived)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -678,7 +722,7 @@ void RenderWidgetHostImpl::WasHidden() {
visual_properties_ack_pending_ = false;
// Don't bother reporting hung state when we aren't active.
- StopHangMonitorTimeout();
+ StopInputEventAckTimeout();
// If we have a renderer, then inform it that we are being hidden so it can
// reduce its resource utilization.
@@ -696,7 +740,7 @@ void RenderWidgetHostImpl::WasHidden() {
observer.RenderWidgetHostVisibilityChanged(this, false);
}
-void RenderWidgetHostImpl::WasShown(const ui::LatencyInfo& latency_info) {
+void RenderWidgetHostImpl::WasShown(bool record_presentation_time) {
if (!is_hidden_)
return;
@@ -708,12 +752,14 @@ void RenderWidgetHostImpl::WasShown(const ui::LatencyInfo& latency_info) {
ForceFirstFrameAfterNavigationTimeout();
SendScreenRects();
- RestartHangMonitorTimeoutIfNecessary();
+ RestartInputEventAckTimeoutIfNecessary();
// Always repaint on restore.
bool needs_repainting = true;
needs_repainting_on_restore_ = false;
- Send(new ViewMsg_WasShown(routing_id_, needs_repainting, latency_info));
+ Send(new ViewMsg_WasShown(
+ routing_id_, needs_repainting,
+ record_presentation_time ? base::TimeTicks::Now() : base::TimeTicks()));
process_->UpdateClientPriority(this);
@@ -767,9 +813,11 @@ bool RenderWidgetHostImpl::GetVisualProperties(
visual_properties->is_fullscreen_granted =
delegate_->IsFullscreenForCurrentTab();
visual_properties->display_mode = delegate_->GetDisplayMode(this);
+ visual_properties->zoom_level = delegate_->GetPendingPageZoomLevel();
} else {
visual_properties->is_fullscreen_granted = false;
visual_properties->display_mode = blink::kWebDisplayModeBrowser;
+ visual_properties->zoom_level = 0;
}
visual_properties->auto_resize_enabled = auto_resize_enabled_;
@@ -840,8 +888,12 @@ bool RenderWidgetHostImpl::GetVisualProperties(
old_parent_local_surface_id.embed_token() !=
new_parent_local_surface_id.embed_token();
+ const bool zoom_changed =
+ !old_visual_properties_ ||
+ old_visual_properties_->zoom_level != visual_properties->zoom_level;
+
bool dirty =
- size_changed || parent_local_surface_id_changed ||
+ zoom_changed || size_changed || parent_local_surface_id_changed ||
old_visual_properties_->screen_info != visual_properties->screen_info ||
old_visual_properties_->compositor_viewport_pixel_size !=
visual_properties->compositor_viewport_pixel_size ||
@@ -893,8 +945,8 @@ bool RenderWidgetHostImpl::SynchronizeVisualProperties(
bool scroll_focused_node_into_view) {
// Skip if the |delegate_| has already been detached because
// it's web contents is being deleted.
- if (visual_properties_ack_pending_ || !process_->HasConnection() || !view_ ||
- !view_->HasSize() || !renderer_initialized_ || !delegate_) {
+ if (visual_properties_ack_pending_ || !process_->IsInitializedAndNotDead() ||
+ !view_ || !view_->HasSize() || !renderer_initialized_ || !delegate_) {
return false;
}
@@ -1091,39 +1143,39 @@ bool RenderWidgetHostImpl::RequestRepaintForTesting() {
void RenderWidgetHostImpl::ProcessIgnoreInputEventsChanged(
bool ignore_input_events) {
if (ignore_input_events)
- StopHangMonitorTimeout();
+ StopInputEventAckTimeout();
else
- RestartHangMonitorTimeoutIfNecessary();
+ RestartInputEventAckTimeoutIfNecessary();
}
-void RenderWidgetHostImpl::StartHangMonitorTimeout(TimeDelta delay) {
- if (!hang_monitor_timeout_)
+void RenderWidgetHostImpl::StartInputEventAckTimeout(TimeDelta delay) {
+ if (!input_event_ack_timeout_)
return;
- hang_monitor_timeout_->Start(delay);
- hang_monitor_start_time_ = clock_->NowTicks();
+ input_event_ack_timeout_->Start(delay);
+ input_event_ack_start_time_ = clock_->NowTicks();
}
-void RenderWidgetHostImpl::RestartHangMonitorTimeoutIfNecessary() {
- if (hang_monitor_timeout_ && in_flight_event_count_ > 0 && !is_hidden_)
- hang_monitor_timeout_->Restart(hung_renderer_delay_);
+void RenderWidgetHostImpl::RestartInputEventAckTimeoutIfNecessary() {
+ if (input_event_ack_timeout_ && in_flight_event_count_ > 0 && !is_hidden_)
+ input_event_ack_timeout_->Restart(hung_renderer_delay_);
}
bool RenderWidgetHostImpl::IsCurrentlyUnresponsive() const {
return is_unresponsive_;
}
-void RenderWidgetHostImpl::StopHangMonitorTimeout() {
- if (hang_monitor_timeout_)
- hang_monitor_timeout_->Stop();
+void RenderWidgetHostImpl::StopInputEventAckTimeout() {
+ if (input_event_ack_timeout_)
+ input_event_ack_timeout_->Stop();
- if (!hang_monitor_start_time_.is_null()) {
- base::TimeDelta elapsed = clock_->NowTicks() - hang_monitor_start_time_;
+ if (!input_event_ack_start_time_.is_null()) {
+ base::TimeDelta elapsed = clock_->NowTicks() - input_event_ack_start_time_;
const base::TimeDelta kMinimumHangTimeToReport =
base::TimeDelta::FromSeconds(5);
if (elapsed >= kMinimumHangTimeToReport)
UMA_HISTOGRAM_LONG_TIMES("Renderer.Hung.Duration", elapsed);
- hang_monitor_start_time_ = TimeTicks();
+ input_event_ack_start_time_ = TimeTicks();
}
RendererIsResponsive();
}
@@ -1137,8 +1189,19 @@ void RenderWidgetHostImpl::DidNavigate(uint32_t next_source_id) {
// |visual_properties_ack_pending_| and make sure the next resize will be
// acked if the last resize before navigation was supposed to be acked.
visual_properties_ack_pending_ = false;
+ viz::LocalSurfaceId old_surface_id = view_->GetLocalSurfaceId();
if (view_)
view_->DidNavigate();
+ viz::LocalSurfaceId new_surface_id = view_->GetLocalSurfaceId();
+ // If |view_| didn't allocate a new surface id, then don't start
+ // |new_content_rendering_timeout_|. Two reasons:
+ // 1. It's not needed (because this was the first navigation event)
+ // 2. If we don't change the surface id, then we will not get the call to
+ // OnFirstSurfaceActivation, and not stop the timer (even if we get new
+ // frames).
+ // https://crbug.com/853651, https://crbug.com/535375
+ if (old_surface_id == new_surface_id)
+ return;
} else {
// 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
@@ -1284,9 +1347,8 @@ void RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo(
// the GFS are directly injected to RWHI rather than being generated
// from wheel events in MouseWheelEventQueue.
is_in_gesture_scroll_[gesture_event.SourceDevice()] = false;
- } else if (GetView()->wheel_scroll_latching_enabled()) {
- // When wheel scroll latching is enabled, no GSE is sent before GFS, so
- // is_in_gesture_scroll must be true.
+ } else {
+ // No GSE is sent before GFS, so is_in_gesture_scroll must be true.
// TODO(sahel): This often gets tripped on Debug builds in ChromeOS
// indicating some kind of gesture event ordering race.
// https://crbug.com/821237.
@@ -1300,12 +1362,6 @@ void RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo(
// and send a wheel event with phaseEnded. MouseWheelEventQueue will
// process the wheel event to generate and send a GSE which shows the
// end of a scroll sequence.
- } else { // !GetView()->IsInVR() &&
- // !GetView()->wheel_scroll_latching_enabled()
-
- // When wheel scroll latching is disabled a GSE is sent before a GFS.
- // The GSE has already finished the scroll sequence.
- DCHECK(!is_in_gesture_scroll_[gesture_event.SourceDevice()]);
}
is_in_touchpad_gesture_fling_ = true;
@@ -1406,7 +1462,7 @@ void RenderWidgetHostImpl::ForwardKeyboardEventWithCommands(
if (ShouldDropInputEvents())
return;
- if (!process_->HasConnection())
+ if (!process_->IsInitializedAndNotDead())
return;
// First, let keypress listeners take a shot at handling the event. If a
@@ -1452,9 +1508,6 @@ void RenderWidgetHostImpl::ForwardKeyboardEventWithCommands(
switch (delegate_->PreHandleKeyboardEvent(key_event)) {
case KeyboardEventProcessingResult::HANDLED:
return;
- case KeyboardEventProcessingResult::HANDLED_WANTS_KEY_UP:
- suppress_events_until_keydown_ = false;
- return;
#if defined(USE_AURA)
case KeyboardEventProcessingResult::HANDLED_DONT_UPDATE_EVENT:
if (update_event)
@@ -1520,10 +1573,6 @@ void RenderWidgetHostImpl::SendCursorVisibilityState(bool is_visible) {
GetWidgetInputHandler()->CursorVisibilityChanged(is_visible);
}
-int64_t RenderWidgetHostImpl::GetLatencyComponentId() const {
- return latency_tracker_.latency_component_id();
-}
-
// static
void RenderWidgetHostImpl::DisableResizeAckCheckForTesting() {
g_check_for_pending_visual_properties_ack = false;
@@ -1720,12 +1769,11 @@ void RenderWidgetHostImpl::NotifyScreenInfoChanged() {
void RenderWidgetHostImpl::GetSnapshotFromBrowser(
const GetSnapshotFromBrowserCallback& callback,
bool from_surface) {
- int id = next_browser_snapshot_id_++;
+ int snapshot_id = next_browser_snapshot_id_++;
if (from_surface) {
- pending_surface_browser_snapshots_.insert(std::make_pair(id, callback));
- ui::LatencyInfo latency_info;
- latency_info.AddSnapshot(GetLatencyComponentId(), id);
- Send(new ViewMsg_ForceRedraw(GetRoutingID(), latency_info));
+ pending_surface_browser_snapshots_.insert(
+ std::make_pair(snapshot_id, callback));
+ Send(new ViewMsg_ForceRedraw(GetRoutingID(), snapshot_id));
return;
}
@@ -1737,10 +1785,8 @@ void RenderWidgetHostImpl::GetSnapshotFromBrowser(
GetWakeLock()->RequestWakeLock();
#endif
// TODO(nzolghadr): Remove the duplication here and the if block just above.
- pending_browser_snapshots_.insert(std::make_pair(id, callback));
- ui::LatencyInfo latency_info;
- latency_info.AddSnapshot(GetLatencyComponentId(), id);
- Send(new ViewMsg_ForceRedraw(GetRoutingID(), latency_info));
+ pending_browser_snapshots_.insert(std::make_pair(snapshot_id, callback));
+ Send(new ViewMsg_ForceRedraw(GetRoutingID(), snapshot_id));
}
void RenderWidgetHostImpl::SelectionChanged(const base::string16& text,
@@ -1829,6 +1875,23 @@ void RenderWidgetHostImpl::OnFrameSwapMessagesReceived(
std::move(messages));
}
+void RenderWidgetHostImpl::OnForceRedrawComplete(int snapshot_id) {
+#if defined(OS_MACOSX) || defined(OS_WIN)
+ // On Mac, when using CoreAnimation, or Win32 when using GDI, there is a
+ // delay between when content is drawn to the screen, and when the
+ // snapshot will actually pick up that content. Insert a manual delay of
+ // 1/6th of a second (to simulate 10 frames at 60 fps) before actually
+ // taking the snapshot.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&RenderWidgetHostImpl::WindowSnapshotReachedScreen,
+ weak_factory_.GetWeakPtr(), snapshot_id),
+ TimeDelta::FromSecondsD(1. / 6));
+#else
+ WindowSnapshotReachedScreen(snapshot_id);
+#endif
+}
+
void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status,
int exit_code) {
if (!renderer_initialized_)
@@ -1866,7 +1929,7 @@ void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status,
// Reset this to ensure the hung renderer mechanism is working properly.
in_flight_event_count_ = 0;
- StopHangMonitorTimeout();
+ StopInputEventAckTimeout();
if (view_) {
view_->RenderProcessGone(status, exit_code);
@@ -1990,8 +2053,15 @@ void RenderWidgetHostImpl::Destroy(bool also_delete) {
// The display compositor has ownership of shared memory for each
// SharedBitmapId that has been reported from the client. Since the client is
// gone that memory can be freed. If we don't then it would leak.
- for (const auto& id : owned_bitmaps_)
- viz::ServerSharedBitmapManager::current()->ChildDeletedSharedBitmap(id);
+ if (shared_bitmap_manager_) {
+ for (const auto& id : owned_bitmaps_)
+ shared_bitmap_manager_->ChildDeletedSharedBitmap(id);
+ } else {
+ // If the display compositor is not in the browser process, then the
+ // |bitmap_manager| is not present in the process either, and no bitmaps
+ // should have been registered with this class.
+ DCHECK(owned_bitmaps_.empty());
+ }
process_->RemoveWidget(this);
process_->RemoveRoute(routing_id_);
@@ -2015,7 +2085,10 @@ void RenderWidgetHostImpl::RendererIsUnresponsive() {
is_unresponsive_ = true;
if (delegate_)
- delegate_->RendererUnresponsive(this);
+ delegate_->RendererUnresponsive(
+ this, base::BindRepeating(
+ &RenderWidgetHostImpl::RestartInputEventAckTimeoutIfNecessary,
+ weak_factory_.GetWeakPtr()));
// Do not add code after this since the Delegate may delete this
// RenderWidgetHostImpl in RendererUnresponsive.
@@ -2035,31 +2108,6 @@ void RenderWidgetHostImpl::ClearDisplayedGraphics() {
view_->ClearCompositorFrame();
}
-void RenderWidgetHostImpl::OnGpuSwapBuffersCompletedInternal(
- const ui::LatencyInfo& latency_info) {
- // Note that a compromised renderer can send LatencyInfo to a
- // RenderWidgetHostImpl other than its own. Be mindful of security
- // implications of the code you add here.
- if (latency_info.Snapshots().find(GetLatencyComponentId()) !=
- latency_info.Snapshots().end()) {
- int snapshot_id = latency_info.Snapshots().at(GetLatencyComponentId());
-#if defined(OS_MACOSX) || defined(OS_WIN)
- // On Mac, when using CoreAnimation, or Win32 when using GDI, there is a
- // delay between when content is drawn to the screen, and when the
- // snapshot will actually pick up that content. Insert a manual delay of
- // 1/6th of a second (to simulate 10 frames at 60 fps) before actually
- // taking the snapshot.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::Bind(&RenderWidgetHostImpl::WindowSnapshotReachedScreen,
- weak_factory_.GetWeakPtr(), snapshot_id),
- TimeDelta::FromSecondsD(1. / 6));
-#else
- WindowSnapshotReachedScreen(snapshot_id);
-#endif
- }
-}
-
void RenderWidgetHostImpl::OnRenderProcessGone(int status, int exit_code) {
// RenderFrameHost owns a RenderWidgetHost when it needs one, in which case
// it handles destruction.
@@ -2130,10 +2178,10 @@ void RenderWidgetHostImpl::OnUpdateScreenRectsAck() {
SendScreenRects();
}
-void RenderWidgetHostImpl::OnRequestMove(const gfx::Rect& pos) {
+void RenderWidgetHostImpl::OnRequestSetBounds(const gfx::Rect& bounds) {
if (view_) {
- view_->SetBounds(pos);
- Send(new ViewMsg_Move_ACK(routing_id_));
+ view_->SetBounds(bounds);
+ Send(new ViewMsg_SetBounds_ACK(routing_id_));
}
}
@@ -2149,8 +2197,8 @@ void RenderWidgetHostImpl::DidNotProduceFrame(const viz::BeginFrameAck& ack) {
void RenderWidgetHostImpl::DidAllocateSharedBitmap(
mojo::ScopedSharedBufferHandle buffer,
const viz::SharedBitmapId& id) {
- if (!viz::ServerSharedBitmapManager::current()->ChildAllocatedSharedBitmap(
- std::move(buffer), id)) {
+ if (!shared_bitmap_manager_->ChildAllocatedSharedBitmap(std::move(buffer),
+ id)) {
bad_message::ReceivedBadMessage(GetProcess(),
bad_message::RWH_SHARED_BITMAP);
}
@@ -2159,7 +2207,7 @@ void RenderWidgetHostImpl::DidAllocateSharedBitmap(
void RenderWidgetHostImpl::DidDeleteSharedBitmap(
const viz::SharedBitmapId& id) {
- viz::ServerSharedBitmapManager::current()->ChildDeletedSharedBitmap(id);
+ shared_bitmap_manager_->ChildDeletedSharedBitmap(id);
owned_bitmaps_.erase(id);
}
@@ -2432,12 +2480,13 @@ InputEventAckState RenderWidgetHostImpl::FilterInputEvent(
if (ShouldDropInputEvents() && event.GetType() != WebInputEvent::kTouchCancel)
return INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
- if (!process_->HasConnection())
+ if (!process_->IsInitializedAndNotDead())
return INPUT_EVENT_ACK_STATE_UNKNOWN;
if (delegate_) {
if (event.GetType() == WebInputEvent::kMouseDown ||
- event.GetType() == WebInputEvent::kTouchStart) {
+ event.GetType() == WebInputEvent::kTouchStart ||
+ event.GetType() == WebInputEvent::kGestureTap) {
delegate_->FocusOwningWebContents(this);
}
delegate_->DidReceiveInputEvent(this, event.GetType());
@@ -2450,7 +2499,7 @@ InputEventAckState RenderWidgetHostImpl::FilterInputEvent(
void RenderWidgetHostImpl::IncrementInFlightEventCount() {
++in_flight_event_count_;
if (!is_hidden_)
- StartHangMonitorTimeout(hung_renderer_delay_);
+ StartInputEventAckTimeout(hung_renderer_delay_);
}
void RenderWidgetHostImpl::DecrementInFlightEventCount(
@@ -2458,12 +2507,12 @@ void RenderWidgetHostImpl::DecrementInFlightEventCount(
--in_flight_event_count_;
if (in_flight_event_count_ <= 0) {
// Cancel pending hung renderer checks since the renderer is responsive.
- StopHangMonitorTimeout();
+ StopInputEventAckTimeout();
} else {
// Only restart the hang monitor timer if we got a response from the
// main thread.
if (ack_source == InputEventAckSource::MAIN_THREAD)
- RestartHangMonitorTimeoutIfNecessary();
+ RestartInputEventAckTimeoutIfNecessary();
}
}
@@ -2727,39 +2776,6 @@ void RenderWidgetHostImpl::OnSnapshotReceived(int snapshot_id,
#endif
}
-// static
-void RenderWidgetHostImpl::NotifyCorrespondingRenderWidgetHost(
- int64_t frame_id,
- std::set<RenderWidgetHostImpl*>& notified_hosts,
- const ui::LatencyInfo& latency_info) {
- // Matches with GetLatencyComponentId.
- int routing_id = frame_id & 0xffffffff;
- int process_id = (frame_id >> 32) & 0xffffffff;
- RenderWidgetHost* rwh = RenderWidgetHost::FromID(process_id, routing_id);
- if (!rwh)
- return;
- RenderWidgetHostImpl* rwhi = RenderWidgetHostImpl::From(rwh);
- if (notified_hosts.insert(rwhi).second)
- rwhi->OnGpuSwapBuffersCompletedInternal(latency_info);
-}
-
-// static
-void RenderWidgetHostImpl::OnGpuSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info) {
- for (size_t i = 0; i < latency_info.size(); i++) {
- std::set<RenderWidgetHostImpl*> rwhi_set;
- for (const auto& lc : latency_info[i].latency_components()) {
- if (lc.first.first == ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT ||
- lc.first.first == ui::TAB_SHOW_COMPONENT)
- NotifyCorrespondingRenderWidgetHost(lc.first.second, rwhi_set,
- latency_info[i]);
- }
- for (const auto& snapshot : latency_info[i].Snapshots())
- NotifyCorrespondingRenderWidgetHost(snapshot.first, rwhi_set,
- latency_info[i]);
- }
-}
-
BrowserAccessibilityManager*
RenderWidgetHostImpl::GetRootBrowserAccessibilityManager() {
return delegate_ ? delegate_->GetRootBrowserAccessibilityManager() : nullptr;
@@ -2815,14 +2831,22 @@ void RenderWidgetHostImpl::RequestCompositorFrameSink(
return;
}
+ // Consider any bitmaps registered with the old CompositorFrameSink as gone,
+ // they will be re-registered on the newly requested CompositorFrameSink if
+ // they are meant to be used still. https://crbug.com/862584.
+ for (const auto& id : owned_bitmaps_)
+ shared_bitmap_manager_->ChildDeletedSharedBitmap(id);
+ owned_bitmaps_.clear();
+
if (compositor_frame_sink_binding_.is_bound())
compositor_frame_sink_binding_.Close();
compositor_frame_sink_binding_.Bind(
std::move(compositor_frame_sink_request),
BrowserMainLoop::GetInstance()->GetResizeTaskRunner());
- if (view_)
+ if (view_) {
view_->DidCreateNewRendererCompositorFrameSink(
compositor_frame_sink_client.get());
+ }
renderer_compositor_frame_sink_ = std::move(compositor_frame_sink_client);
}
@@ -2867,9 +2891,6 @@ void RenderWidgetHostImpl::SubmitCompositorFrame(
viz::CompositorFrame frame,
base::Optional<viz::HitTestRegionList> hit_test_region_list,
uint64_t submit_time) {
- TRACE_EVENT_FLOW_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "SubmitCompositorFrame", local_surface_id.hash());
-
// Ensure there are no CopyOutputRequests stowed-away in the CompositorFrame.
// For security/privacy reasons, renderers are not allowed to make copy
// requests because they could use this to gain access to content from another
@@ -2880,23 +2901,11 @@ void RenderWidgetHostImpl::SubmitCompositorFrame(
return;
}
- bool tracing_enabled;
- TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- &tracing_enabled);
- if (tracing_enabled) {
- TimeDelta elapsed = clock_->NowTicks().since_origin() -
- TimeDelta::FromMicroseconds(submit_time);
- TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.ipc"),
- "SubmitCompositorFrame::TimeElapsed",
- TRACE_EVENT_SCOPE_THREAD,
- "elapsed time:", elapsed.InMicroseconds());
- }
auto new_surface_properties =
RenderWidgetSurfaceProperties::FromCompositorFrame(frame);
if (local_surface_id == last_local_surface_id_ &&
- SurfacePropertiesMismatch(new_surface_properties,
- last_surface_properties_)) {
+ new_surface_properties != last_surface_properties_) {
std::string error = base::StringPrintf(
"[OOPIF? %d] %s\n", view_ && view_->IsRenderWidgetHostViewChildFrame(),
new_surface_properties.ToDiffString(last_surface_properties_).c_str());
@@ -3014,7 +3023,7 @@ device::mojom::WakeLock* RenderWidgetHostImpl::GetWakeLock() {
void RenderWidgetHostImpl::SetupInputRouter() {
in_flight_event_count_ = 0;
- StopHangMonitorTimeout();
+ StopInputEventAckTimeout();
associated_widget_input_handler_ = nullptr;
widget_input_handler_ = nullptr;
@@ -3105,36 +3114,6 @@ void RenderWidgetHostImpl::SetScreenOrientationForTesting(
SynchronizeVisualProperties();
}
-// TODO(ericrk): On Android, with surface synchronization enabled, we need to
-// request a new surface ID when things like top/bottom control height or
-// selection handles change. This will be enabled by child surface id
-// generation. For now ignore these mismatches. Remove this function when this
-// issue is resolved: https://crbug.com/789259 and https://crbug.com/801350
-bool RenderWidgetHostImpl::SurfacePropertiesMismatch(
- const RenderWidgetSurfaceProperties& first,
- const RenderWidgetSurfaceProperties& second) const {
-#ifdef OS_ANDROID
- if (enable_surface_synchronization_) {
- // To make this comparison resistant to changes in
- // RenderWidgetSurfaceProperties, create new properties which are forced to
- // match only for those categories we want to ignore.
- RenderWidgetSurfaceProperties second_reduced = second;
- second_reduced.top_controls_height = first.top_controls_height;
- second_reduced.top_controls_shown_ratio = first.top_controls_shown_ratio;
- second_reduced.bottom_controls_height = first.bottom_controls_height;
- second_reduced.bottom_controls_shown_ratio =
- first.bottom_controls_shown_ratio;
- second_reduced.selection = first.selection;
-
- return first != second_reduced;
- }
-#endif
-
- // For non-Android or when surface synchronization is not enabled, just use a
- // basic comparison.
- return first != second;
-}
-
bool RenderWidgetHostImpl::LockKeyboard() {
if (!keyboard_lock_allowed_ || !is_focused_ || !view_)
return false;
@@ -3151,7 +3130,10 @@ void RenderWidgetHostImpl::UnlockKeyboard() {
view_->UnlockKeyboard();
}
-void RenderWidgetHostImpl::OnRenderFrameMetadataChanged() {
+void RenderWidgetHostImpl::OnRenderFrameMetadataChangedBeforeActivation(
+ const cc::RenderFrameMetadata& metadata) {}
+
+void RenderWidgetHostImpl::OnRenderFrameMetadataChangedAfterActivation() {
bool is_mobile_optimized =
render_frame_metadata_provider_.LastRenderFrameMetadata()
.is_mobile_optimized;
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 316385180c6..4af5870e7c4 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_impl.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_impl.h
@@ -11,6 +11,7 @@
#include <list>
#include <map>
#include <memory>
+#include <set>
#include <string>
#include <utility>
#include <vector>
@@ -30,7 +31,7 @@
#include "base/time/time.h"
#include "base/timer/elapsed_timer.h"
#include "build/build_config.h"
-#include "components/viz/common/quads/shared_bitmap.h"
+#include "components/viz/common/resources/shared_bitmap.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "content/browser/renderer_host/event_with_latency_info.h"
#include "content/browser/renderer_host/frame_token_message_queue.h"
@@ -96,10 +97,14 @@ namespace ui {
enum class DomCode;
}
+namespace viz {
+class ServerSharedBitmapManager;
+}
+
namespace content {
class BrowserAccessibilityManager;
-class FlingScheduler;
+class FlingSchedulerBase;
class InputRouter;
class MockRenderWidgetHost;
class RenderWidgetHostOwnerDelegate;
@@ -193,7 +198,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl
int GetRoutingID() const override;
RenderWidgetHostViewBase* GetView() const override;
bool IsLoading() const override;
- void RestartHangMonitorTimeoutIfNecessary() override;
bool IsCurrentlyUnresponsive() const override;
void SetIgnoreInputEvents(bool ignore_input_events) override;
bool SynchronizeVisualProperties() override;
@@ -301,7 +305,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// Called to notify the RenderWidget that it has been hidden or restored from
// having been hidden.
void WasHidden();
- void WasShown(const ui::LatencyInfo& latency_info);
+ void WasShown(bool record_presentation_time);
#if defined(OS_ANDROID)
// Set the importance of widget. The importance is passed onto
@@ -526,13 +530,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl
void DidReceiveRendererFrame();
- // Returns the ID that uniquely describes this component to the latency
- // subsystem.
- int64_t GetLatencyComponentId() const;
-
- static void OnGpuSwapBuffersCompleted(
- const std::vector<ui::LatencyInfo>& latency_info);
-
// Don't check whether we expected a resize ack during layout tests.
static void DisableResizeAckCheckForTesting();
@@ -728,10 +725,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// from a newly loaded page. Used for testing.
virtual void NotifyNewContentRenderingTimeoutForTesting() {}
- // Can be overriden for subclass based testing.
- virtual void OnGpuSwapBuffersCompletedInternal(
- const ui::LatencyInfo& latency_info);
-
// InputAckHandler
void OnKeyboardEventAck(const NativeWebKeyboardEventWithLatencyInfo& event,
InputEventAckSource ack_source,
@@ -763,13 +756,13 @@ class CONTENT_EXPORT RenderWidgetHostImpl
private:
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest,
- DontPostponeHangMonitorTimeout);
+ DontPostponeInputEventAckTimeout);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, HiddenPaint);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, RendererExitedNoDrag);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest,
- StopAndStartHangMonitorTimeout);
+ StopAndStartInputEventAckTimeout);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest,
- ShorterDelayHangMonitorTimeout);
+ ShorterDelayInputEventAckTimeout);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostTest, SynchronizeVisualProperties);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest, AutoResizeWithScale);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
@@ -796,17 +789,11 @@ class CONTENT_EXPORT RenderWidgetHostImpl
RenderProcessHost*,
RenderWidgetHost*);
- // Helper for notifying corresponding RenderWidgetHosts
- static void NotifyCorrespondingRenderWidgetHost(
- int64_t frame_id,
- std::set<RenderWidgetHostImpl*>&,
- const ui::LatencyInfo&);
-
// Tell this object to destroy itself. If |also_delete| is specified, the
// destructor is called as well.
void Destroy(bool also_delete);
- // Called by |hang_monitor_timeout_| on delayed response from the renderer.
+ // Called by |input_event_ack_timeout_| on delayed response from the renderer.
void RendererIsUnresponsive();
// Called by |new_content_rendering_timeout_| if a renderer has loaded new
@@ -822,7 +809,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
void OnRenderProcessGone(int status, int error_code);
void OnClose();
void OnUpdateScreenRectsAck();
- void OnRequestMove(const gfx::Rect& pos);
+ void OnRequestSetBounds(const gfx::Rect& bounds);
void OnSetTooltipText(const base::string16& tooltip_text,
blink::WebTextDirection text_direction_hint);
void OnSetCursor(const WebCursor& cursor);
@@ -850,6 +837,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
void OnUpdateDragCursor(blink::WebDragOperation current_op);
void OnFrameSwapMessagesReceived(uint32_t frame_token,
std::vector<IPC::Message> messages);
+ void OnForceRedrawComplete(int snapshot_id);
// Called when visual properties have changed in the renderer.
void DidUpdateVisualProperties(const cc::RenderFrameMetadata& metadata);
@@ -891,17 +879,18 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// Starts a hang monitor timeout. If there's already a hang monitor timeout
// the new one will only fire if it has a shorter delay than the time
// left on the existing timeouts.
- void StartHangMonitorTimeout(base::TimeDelta delay);
+ void StartInputEventAckTimeout(base::TimeDelta delay);
// Stops all existing hang monitor timeouts and assumes the renderer is
// responsive.
- void StopHangMonitorTimeout();
+ void StopInputEventAckTimeout();
- void SetupInputRouter();
+ // Implementation of |hang_monitor_restarter| callback passed to
+ // RenderWidgetHostDelegate::RendererUnresponsive if the unresponsiveness
+ // was noticed because of input event ack timeout.
+ void RestartInputEventAckTimeoutIfNecessary();
- bool SurfacePropertiesMismatch(
- const RenderWidgetSurfaceProperties& first,
- const RenderWidgetSurfaceProperties& second) const;
+ void SetupInputRouter();
// Start intercepting system keyboard events.
bool LockKeyboard();
@@ -914,7 +903,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl
#endif
// RenderFrameMetadataProvider::Observer implementation.
- void OnRenderFrameMetadataChanged() override;
+ void OnRenderFrameMetadataChangedBeforeActivation(
+ const cc::RenderFrameMetadata& metadata) override;
+ void OnRenderFrameMetadataChangedAfterActivation() override;
void OnRenderFrameSubmission() override {}
void OnLocalSurfaceIdChanged(
const cc::RenderFrameMetadata& metadata) override;
@@ -1072,8 +1063,8 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// Receives and handles all input events.
std::unique_ptr<InputRouter> input_router_;
- std::unique_ptr<TimeoutMonitor> hang_monitor_timeout_;
- base::TimeTicks hang_monitor_start_time_;
+ std::unique_ptr<TimeoutMonitor> input_event_ack_timeout_;
+ base::TimeTicks input_event_ack_start_time_;
std::unique_ptr<TimeoutMonitor> new_content_rendering_timeout_;
@@ -1174,9 +1165,15 @@ class CONTENT_EXPORT RenderWidgetHostImpl
base::Optional<uint16_t> screen_orientation_angle_for_testing_;
base::Optional<ScreenOrientationValues> screen_orientation_type_for_testing_;
+ // When the viz display compositor is in the browser process, this is used to
+ // register and unregister the bitmaps (stored in |owned_bitmaps_| reported to
+ // this class from the renderer.
+ viz::ServerSharedBitmapManager* shared_bitmap_manager_ = nullptr;
// The set of SharedBitmapIds that have been reported as allocated to this
// interface. On closing this interface, the display compositor should drop
- // ownership of the bitmaps with these ids to avoid leaking them.
+ // ownership of the bitmaps with these ids to avoid leaking them. This is only
+ // used when SharedBitmaps are reported to this class because the display
+ // compositor is in the browser process.
std::set<viz::SharedBitmapId> owned_bitmaps_;
bool force_enable_zoom_ = false;
@@ -1185,7 +1182,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl
const viz::FrameSinkId frame_sink_id_;
- std::unique_ptr<FlingScheduler> fling_scheduler_;
+ std::unique_ptr<FlingSchedulerBase> fling_scheduler_;
bool did_receive_first_frame_after_navigation_ = true;
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 1ff58114735..52a1434b1b4 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,35 +132,28 @@ void RenderWidgetHostInputEventRouter::OnRenderWidgetHostViewBaseDestroyed(
first_bubbling_scroll_target_.target = nullptr;
} else if (view == first_bubbling_scroll_target_.target) {
first_bubbling_scroll_target_.target = nullptr;
- // When wheel scroll latching is disabled
- // bubbling_gesture_scroll_target_.target should also get reset since
- // gesture scroll events are bubbled one target at a time and they need the
- // first target for getting bubbled to the current bubbling target. With
- // latching enabled gesture scroll events (other than GSB) are bubbled
- // directly to the bubbling target, the bubbling target should wait for the
- // GSE to arrive and finish scrolling sequence rather than getting reset.
- if (bubbling_gesture_scroll_target_.target &&
- !bubbling_gesture_scroll_target_.target
- ->wheel_scroll_latching_enabled()) {
- bubbling_gesture_scroll_target_.target = nullptr;
- }
}
if (view == last_mouse_move_target_) {
// When a child iframe is destroyed, consider its parent to be to be the
// most recent target, if possible. In some cases the parent might already
// have been destroyed, in which case the last target is cleared.
- if (view != last_mouse_move_root_view_)
+ if (view != last_mouse_move_root_view_) {
+ DCHECK(last_mouse_move_target_->IsRenderWidgetHostViewChildFrame());
last_mouse_move_target_ =
static_cast<RenderWidgetHostViewChildFrame*>(last_mouse_move_target_)
->GetParentView();
- else
+ } else {
last_mouse_move_target_ = nullptr;
+ }
if (!last_mouse_move_target_ || view == last_mouse_move_root_view_)
last_mouse_move_root_view_ = nullptr;
}
+ if (view == last_fling_start_target_)
+ last_fling_start_target_ = nullptr;
+
event_targeter_->ViewWillBeDestroyed(view);
}
@@ -272,7 +265,6 @@ RenderWidgetHostInputEventRouter::FindMouseWheelEventTarget(
return {target, false, transformed_point, true};
}
- if (root_view->wheel_scroll_latching_enabled()) {
if (event.phase == blink::WebMouseWheelEvent::kPhaseBegan) {
auto result = FindViewAtLocation(
root_view, event.PositionInWidget(), event.PositionInScreen(),
@@ -282,7 +274,6 @@ RenderWidgetHostInputEventRouter::FindMouseWheelEventTarget(
// For non-begin events, the target found for the previous phaseBegan is
// used.
return {nullptr, false, base::nullopt, true};
- }
auto result = FindViewAtLocation(root_view, event.PositionInWidget(),
event.PositionInScreen(),
@@ -423,8 +414,7 @@ void RenderWidgetHostInputEventRouter::DispatchMouseWheelEvent(
const ui::LatencyInfo& latency,
const base::Optional<gfx::PointF>& target_location) {
base::Optional<gfx::PointF> point_in_target = target_location;
- if (!root_view->IsMouseLocked() &&
- root_view->wheel_scroll_latching_enabled()) {
+ if (!root_view->IsMouseLocked()) {
if (mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseBegan) {
wheel_target_.target = target;
if (target_location.has_value()) {
@@ -464,16 +454,14 @@ void RenderWidgetHostInputEventRouter::DispatchMouseWheelEvent(
// If target_location doesn't have a value, it can be for two reasons:
// 1. |target| is null, in which case we would have early returned from the
// check above.
- // 2. Wheel scroll latching is enabled and the event we are receiving is not
- // a phaseBegan, in which case we should have got a valid |point_in_target|
- // from wheel_target_.delta above.
+ // 2. The event we are receiving is not a phaseBegan, in which case we should
+ // have got a valid |point_in_target| from wheel_target_.delta above.
DCHECK(point_in_target.has_value());
blink::WebMouseWheelEvent event = mouse_wheel_event;
event.SetPositionInWidget(point_in_target->x(), point_in_target->y());
target->ProcessMouseWheelEvent(event, latency);
- DCHECK(root_view->wheel_scroll_latching_enabled() || !wheel_target_.target);
if (mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseEnded ||
mouse_wheel_event.momentum_phase ==
blink::WebMouseWheelEvent::kPhaseEnded) {
@@ -673,6 +661,8 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents(
std::vector<RenderWidgetHostViewBase*> exited_views;
RenderWidgetHostViewBase* cur_view = target;
entered_views.push_back(cur_view);
+ // Non-root RWHVs are guaranteed to be RenderWidgetHostViewChildFrames,
+ // as long as they are the only embeddable RWHVs.
while (cur_view->IsRenderWidgetHostViewChildFrame()) {
cur_view =
static_cast<RenderWidgetHostViewChildFrame*>(cur_view)->GetParentView();
@@ -685,9 +675,12 @@ void RenderWidgetHostInputEventRouter::SendMouseEnterOrLeaveEvents(
}
entered_views.push_back(cur_view);
}
- // Non-root RWHVs are guaranteed to be RenderWidgetHostViewChildFrames,
- // as long as they are the only embeddable RWHVs.
- DCHECK_EQ(cur_view, root_view);
+
+ // On Windows, it appears to be possible that render widget targeting could
+ // produce a target that is outside of the specified root. For now, we'll
+ // just give up in such a case. See https://crbug.com/851958.
+ if (cur_view != root_view)
+ return;
cur_view = last_mouse_move_target_;
if (cur_view) {
@@ -799,8 +792,7 @@ void RenderWidgetHostInputEventRouter::BubbleScrollEvent(
const blink::WebGestureEvent& event,
const RenderWidgetHostViewBase* resending_view) {
DCHECK(target_view);
- DCHECK((target_view->wheel_scroll_latching_enabled() &&
- event.GetType() == blink::WebInputEvent::kGestureScrollBegin) ||
+ DCHECK(event.GetType() == blink::WebInputEvent::kGestureScrollBegin ||
event.GetType() == blink::WebInputEvent::kGestureScrollUpdate ||
event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
event.GetType() == blink::WebInputEvent::kGestureFlingStart);
@@ -808,136 +800,67 @@ void RenderWidgetHostInputEventRouter::BubbleScrollEvent(
ui::LatencyInfo latency_info =
ui::WebInputEventTraits::CreateLatencyInfoForWebGestureEvent(event);
- if (target_view->wheel_scroll_latching_enabled()) {
- if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
- // If target_view has unrelated gesture events in progress, do
- // not proceed. This could cause confusion between independent
- // scrolls.
- if (target_view == touchscreen_gesture_target_.target ||
- target_view == touchpad_gesture_target_.target ||
- target_view == touch_target_.target) {
- return;
- }
-
- // This accounts for bubbling through nested OOPIFs. A gesture scroll
- // begin has been bubbled but the target has sent back a gesture scroll
- // event ack which didn't consume any scroll delta, and so another level
- // of bubbling is needed. This requires a GestureScrollEnd be sent to the
- // last view, which will no longer be the scroll target.
- if (bubbling_gesture_scroll_target_.target) {
- SendGestureScrollEnd(
- bubbling_gesture_scroll_target_.target,
- GestureEventInTarget(event,
- bubbling_gesture_scroll_target_.target));
- } else {
- first_bubbling_scroll_target_.target = target_view;
- }
-
- bubbling_gesture_scroll_target_.target = target_view;
- } else { // !(event.GetType() == blink::WebInputEvent::kGestureScrollBegin)
- if (!bubbling_gesture_scroll_target_.target) {
- // The GestureScrollBegin event is not bubbled, don't bubble the rest of
- // the scroll events.
- return;
- }
-
- // Don't bubble the GSE events that are generated and sent to intermediate
- // bubbling targets.
- if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd &&
- target_view != first_bubbling_scroll_target_.target) {
- return;
- }
- }
-
- // If the router tries to resend a gesture scroll event back to the same
- // view, we could hang.
- DCHECK_NE(resending_view, bubbling_gesture_scroll_target_.target);
- // We've seen reports of this, but don't know the cause yet. For now,
- // instead of CHECKing or hanging, we'll report the issue and abort scroll
- // bubbling.
- // TODO(828422): Remove once this issue no longer occurs.
- if (resending_view == bubbling_gesture_scroll_target_.target) {
- ReportBubblingScrollToSameView(event, resending_view);
- first_bubbling_scroll_target_.target = nullptr;
- bubbling_gesture_scroll_target_.target = nullptr;
+ if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
+ // If target_view has unrelated gesture events in progress, do
+ // not proceed. This could cause confusion between independent
+ // scrolls.
+ if (target_view == touchscreen_gesture_target_.target ||
+ target_view == touchpad_gesture_target_.target ||
+ target_view == touch_target_.target) {
return;
}
- bubbling_gesture_scroll_target_.target->ProcessGestureEvent(
- GestureEventInTarget(event, bubbling_gesture_scroll_target_.target),
- latency_info);
- if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
- event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
- first_bubbling_scroll_target_.target = nullptr;
- bubbling_gesture_scroll_target_.target = nullptr;
+ // This accounts for bubbling through nested OOPIFs. A gesture scroll
+ // begin has been bubbled but the target has sent back a gesture scroll
+ // event ack which didn't consume any scroll delta, and so another level
+ // of bubbling is needed. This requires a GestureScrollEnd be sent to the
+ // last view, which will no longer be the scroll target.
+ if (bubbling_gesture_scroll_target_.target) {
+ SendGestureScrollEnd(
+ bubbling_gesture_scroll_target_.target,
+ GestureEventInTarget(event, bubbling_gesture_scroll_target_.target));
+ } else {
+ first_bubbling_scroll_target_.target = target_view;
}
- return;
- }
-
- DCHECK(!target_view->wheel_scroll_latching_enabled());
-
- // DCHECK_XNOR the current and original bubble targets. Both should be set
- // if a bubbling gesture scroll is in progress.
- DCHECK(!first_bubbling_scroll_target_.target ==
- !bubbling_gesture_scroll_target_.target);
+ bubbling_gesture_scroll_target_.target = target_view;
+ } else { // !(event.GetType() == blink::WebInputEvent::kGestureScrollBegin)
+ if (!bubbling_gesture_scroll_target_.target) {
+ // The GestureScrollBegin event is not bubbled, don't bubble the rest of
+ // the scroll events.
+ return;
+ }
- // If target_view is already set up for bubbled scrolls, we forward
- // the event to the current scroll target without further consideration.
- if (target_view == first_bubbling_scroll_target_.target) {
- bubbling_gesture_scroll_target_.target->ProcessGestureEvent(
- GestureEventInTarget(event, bubbling_gesture_scroll_target_.target),
- latency_info);
- if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
- event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
- first_bubbling_scroll_target_.target = nullptr;
- bubbling_gesture_scroll_target_.target = nullptr;
+ // Don't bubble the GSE events that are generated and sent to intermediate
+ // bubbling targets.
+ if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd &&
+ target_view != first_bubbling_scroll_target_.target) {
+ return;
}
- return;
}
- // Disregard GestureScrollEnd events going to non-current targets.
- // These should only happen on ACKs of synthesized GSE events that are
- // sent from SendGestureScrollEnd calls, and are not relevant here.
- if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd)
- return;
-
- // This is a special case to catch races where multiple GestureScrollUpdates
- // have been sent to a renderer before the first one was ACKed, and the ACK
- // caused a bubble retarget. In this case they all get forwarded.
- if (target_view == bubbling_gesture_scroll_target_.target) {
- bubbling_gesture_scroll_target_.target->ProcessGestureEvent(
- GestureEventInTarget(event, bubbling_gesture_scroll_target_.target),
- latency_info);
+ // If the router tries to resend a gesture scroll event back to the same
+ // view, we could hang.
+ DCHECK_NE(resending_view, bubbling_gesture_scroll_target_.target);
+ // We've seen reports of this, but don't know the cause yet. For now,
+ // instead of CHECKing or hanging, we'll report the issue and abort scroll
+ // bubbling.
+ // TODO(828422): Remove once this issue no longer occurs.
+ if (resending_view == bubbling_gesture_scroll_target_.target) {
+ ReportBubblingScrollToSameView(event, resending_view);
+ first_bubbling_scroll_target_.target = nullptr;
+ bubbling_gesture_scroll_target_.target = nullptr;
return;
}
- // If target_view has unrelated gesture events in progress, do
- // not proceed. This could cause confusion between independent
- // scrolls.
- if (target_view == touchscreen_gesture_target_.target ||
- target_view == touchpad_gesture_target_.target ||
- target_view == touch_target_.target)
- return;
-
- // This accounts for bubbling through nested OOPIFs. A gesture scroll has
- // been bubbled but the target has sent back a gesture scroll event ack with
- // unused scroll delta, and so another level of bubbling is needed. This
- // requires a GestureScrollEnd be sent to the last view, which will no
- // longer be the scroll target.
- if (bubbling_gesture_scroll_target_.target) {
- SendGestureScrollEnd(
- bubbling_gesture_scroll_target_.target,
- GestureEventInTarget(event, bubbling_gesture_scroll_target_.target));
- } else {
- first_bubbling_scroll_target_.target = target_view;
+ bubbling_gesture_scroll_target_.target->ProcessGestureEvent(
+ GestureEventInTarget(event, bubbling_gesture_scroll_target_.target),
+ latency_info);
+ if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
+ event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
+ first_bubbling_scroll_target_.target = nullptr;
+ bubbling_gesture_scroll_target_.target = nullptr;
}
-
- bubbling_gesture_scroll_target_.target = target_view;
-
- SendGestureScrollBegin(target_view, GestureEventInTarget(event, target_view));
- target_view->ProcessGestureEvent(GestureEventInTarget(event, target_view),
- latency_info);
}
void RenderWidgetHostInputEventRouter::SendGestureScrollBegin(
@@ -976,7 +899,6 @@ void RenderWidgetHostInputEventRouter::SendGestureScrollEnd(
scroll_end.SetTimeStamp(base::TimeTicks::Now());
switch (event.GetType()) {
case blink::WebInputEvent::kGestureScrollBegin:
- DCHECK(view->wheel_scroll_latching_enabled());
scroll_end.data.scroll_end.inertial_phase =
event.data.scroll_begin.inertial_phase;
scroll_end.data.scroll_end.delta_units =
@@ -1126,8 +1048,8 @@ void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
// should have been one.
if (root_view != touchscreen_gesture_target_.target &&
!rwhi->is_in_touchscreen_gesture_scroll()) {
- cc::TouchAction target_allowed_touch_action =
- cc::TouchAction::kTouchActionAuto;
+ base::Optional<cc::TouchAction> target_allowed_touch_action(
+ cc::kTouchActionNone);
if (touchscreen_gesture_target_.target) {
target_allowed_touch_action =
(static_cast<RenderWidgetHostImpl*>(
@@ -1135,7 +1057,8 @@ void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
->input_router()
->AllowedTouchAction();
}
- if (target_allowed_touch_action &
+ DCHECK(target_allowed_touch_action.has_value());
+ if (target_allowed_touch_action.value() &
cc::TouchAction::kTouchActionPinchZoom) {
gesture_pinch_did_send_scroll_begin_ = true;
SendGestureScrollBegin(root_view, gesture_event);
@@ -1167,6 +1090,12 @@ void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
return;
}
+ if (gesture_event.GetType() == blink::WebInputEvent::kGestureFlingCancel &&
+ last_fling_start_target_) {
+ last_fling_start_target_->ProcessGestureEvent(gesture_event, latency);
+ return;
+ }
+
auto gesture_target_it =
touchscreen_gesture_target_map_.find(gesture_event.unique_touch_event_id);
bool no_matching_id =
@@ -1233,6 +1162,11 @@ void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
}
}
+ // If we set a target and it's not in the map, we won't get notified if the
+ // target goes away, so drop the target and the resulting events.
+ if (!touchscreen_gesture_target_in_map_)
+ touchscreen_gesture_target_.target = nullptr;
+
if (!touchscreen_gesture_target_.target) {
root_view->GestureEventAck(gesture_event,
INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
@@ -1264,6 +1198,9 @@ void RenderWidgetHostInputEventRouter::DispatchTouchscreenGestureEvent(
base::StringPrintf("%u", static_cast<int>(owner_map_.size())));
touchscreen_gesture_target_.target->ProcessGestureEvent(event, latency);
+
+ if (gesture_event.GetType() == blink::WebInputEvent::kGestureFlingStart)
+ last_fling_start_target_ = touchscreen_gesture_target_.target;
}
void RenderWidgetHostInputEventRouter::RouteTouchscreenGestureEvent(
@@ -1279,13 +1216,13 @@ RenderWidgetHostInputEventRouter::FindTouchpadGestureEventTarget(
RenderWidgetHostViewBase* root_view,
const blink::WebGestureEvent& event) const {
if (event.GetType() != blink::WebInputEvent::kGesturePinchBegin &&
- event.GetType() != blink::WebInputEvent::kGestureFlingStart) {
+ event.GetType() != blink::WebInputEvent::kGestureFlingCancel) {
return {nullptr, false, base::nullopt, true};
}
gfx::PointF transformed_point;
return FindViewAtLocation(root_view, event.PositionInWidget(),
- event.PositionInScreen(), viz::EventSource::TOUCH,
+ event.PositionInScreen(), viz::EventSource::MOUSE,
&transformed_point);
}
@@ -1303,6 +1240,37 @@ void RenderWidgetHostInputEventRouter::DispatchTouchpadGestureEvent(
const blink::WebGestureEvent& touchpad_gesture_event,
const ui::LatencyInfo& latency,
const base::Optional<gfx::PointF>& target_location) {
+ // Touchpad gesture flings should be treated as mouse wheels for the purpose
+ // of routing.
+ if (touchpad_gesture_event.GetType() ==
+ blink::WebInputEvent::kGestureFlingStart) {
+ if (wheel_target_.target) {
+ blink::WebGestureEvent gesture_fling = touchpad_gesture_event;
+ gesture_fling.SetPositionInWidget(gesture_fling.PositionInWidget() +
+ wheel_target_.delta);
+ wheel_target_.target->ProcessGestureEvent(gesture_fling, latency);
+ last_fling_start_target_ = wheel_target_.target;
+ } else {
+ root_view->GestureEventAck(touchpad_gesture_event,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ }
+ return;
+ }
+
+ if (touchpad_gesture_event.GetType() ==
+ blink::WebInputEvent::kGestureFlingCancel) {
+ if (last_fling_start_target_) {
+ last_fling_start_target_->ProcessGestureEvent(touchpad_gesture_event,
+ latency);
+ } else if (target) {
+ target->ProcessGestureEvent(touchpad_gesture_event, latency);
+ } else {
+ root_view->GestureEventAck(touchpad_gesture_event,
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ }
+ return;
+ }
+
if (target) {
touchpad_gesture_target_.target = target;
// TODO(mohsen): Instead of just computing a delta, we should extract the
@@ -1336,6 +1304,11 @@ void RenderWidgetHostInputEventRouter::DispatchTouchpadGestureEvent(
gesture_event.SetPositionInWidget(gesture_event.PositionInWidget() +
touchpad_gesture_target_.delta);
touchpad_gesture_target_.target->ProcessGestureEvent(gesture_event, latency);
+
+ if (touchpad_gesture_event.GetType() ==
+ blink::WebInputEvent::kGesturePinchEnd) {
+ touchpad_gesture_target_.target = nullptr;
+ }
}
RenderWidgetHostViewBase*
@@ -1458,7 +1431,11 @@ void RenderWidgetHostInputEventRouter::ForwardEmulatedGestureEvent(
const blink::WebGestureEvent& event) {
TRACE_EVENT0("input",
"RenderWidgetHostInputEventRouter::ForwardEmulatedGestureEvent");
- DCHECK(last_emulated_event_root_view_);
+ // It's possible that since |last_emulated_event_root_view_| was set by the
+ // outbound touch event that the view may have gone away. Before with dispatch
+ // the GestureEvent, confirm the view is still available.
+ if (!IsViewInMap(last_emulated_event_root_view_))
+ return;
DispatchTouchscreenGestureEvent(last_emulated_event_root_view_, nullptr,
event, ui::LatencyInfo(),
event.PositionInWidget());
@@ -1501,7 +1478,11 @@ void RenderWidgetHostInputEventRouter::SetCursor(const WebCursor& cursor) {
void RenderWidgetHostInputEventRouter::ShowContextMenuAtPoint(
const gfx::Point& point,
const ui::MenuSourceType source_type) {
- DCHECK(last_mouse_move_target_);
+ // It's possible that since |last_mouse_move_target_| was set by the
+ // outbound mouse event that the view may have gone away. Before dispatching
+ // the context menu, confirm the view is still available.
+ if (!IsViewInMap(last_mouse_move_target_))
+ return;
auto* rwhi = static_cast<RenderWidgetHostImpl*>(
last_mouse_move_target_->GetRenderWidgetHost());
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 9d766924b89..68d7cf064c2 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
@@ -283,8 +283,7 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
TargetData touchpad_gesture_target_;
TargetData bubbling_gesture_scroll_target_;
TargetData first_bubbling_scroll_target_;
- // Used to target wheel events for the duration of a scroll when wheel scroll
- // latching is enabled.
+ // Used to target wheel events for the duration of a scroll.
TargetData wheel_target_;
// Maintains the same target between mouse down and mouse up.
TargetData mouse_capture_target_;
@@ -293,6 +292,9 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
RenderWidgetHostViewBase* last_mouse_move_target_;
RenderWidgetHostViewBase* last_mouse_move_root_view_;
+ // Tracked for the purpose of targeting subsequent fling cancel events.
+ RenderWidgetHostViewBase* last_fling_start_target_ = nullptr;
+
// Tracked for the purpose of providing a root_view when dispatching emulated
// touch/gesture events.
RenderWidgetHostViewBase* last_emulated_event_root_view_;
@@ -324,6 +326,8 @@ class CONTENT_EXPORT RenderWidgetHostInputEventRouter
InputEventRouterGesturePreventDefaultTargetMapTest);
FRIEND_TEST_ALL_PREFIXES(SitePerProcessHitTestBrowserTest,
InputEventRouterTouchpadGestureTargetTest);
+ FRIEND_TEST_ALL_PREFIXES(SitePerProcessHitTestBrowserTest,
+ TouchpadPinchOverOOPIF);
FRIEND_TEST_ALL_PREFIXES(SitePerProcessMouseWheelHitTestBrowserTest,
InputEventRouterWheelTargetTest);
FRIEND_TEST_ALL_PREFIXES(SitePerProcessMacBrowserTest,
diff --git a/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge.h b/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge.h
deleted file mode 100644
index 3761be5f730..00000000000
--- a/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge.h
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_H_
-#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_H_
-
-@class RenderWidgetHostViewCocoa;
-
-#include <memory>
-
-#include "base/containers/flat_set.h"
-#include "base/macros.h"
-#include "base/optional.h"
-#include "base/strings/string16.h"
-#include "content/common/mac/attributed_string_coder.h"
-#include "third_party/blink/public/web/web_popup_type.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/base/ime/text_input_type.h"
-
-namespace gfx {
-struct CALayerParams;
-class Point;
-class Range;
-class Rect;
-} // namespace gfx
-
-namespace ui {
-enum class DomCode;
-} // namespace ui
-
-namespace content {
-
-class RenderWidgetHostNSViewClient;
-class WebCursor;
-
-// The interface through which RenderWidgetHostViewMac is to manipulate its
-// corresponding NSView (potentially in another process).
-class RenderWidgetHostNSViewBridge {
- public:
- RenderWidgetHostNSViewBridge() {}
- virtual ~RenderWidgetHostNSViewBridge() {}
-
- static std::unique_ptr<RenderWidgetHostNSViewBridge> Create(
- RenderWidgetHostNSViewClient* client);
-
- // TODO(ccameron): RenderWidgetHostViewMac and other functions currently use
- // this method to communicate directly with RenderWidgetHostViewCocoa. The
- // goal of this class is to eliminate this direct communication (so this
- // method is expected to go away).
- virtual RenderWidgetHostViewCocoa* GetRenderWidgetHostViewCocoa() = 0;
-
- // Initialize the window as a popup (e.g, date/time picker).
- virtual void InitAsPopup(const gfx::Rect& content_rect,
- blink::WebPopupType popup_type) = 0;
-
- // Disable displaying any content (including the background color). This is
- // to be called on views that are to be displayed via a parent ui::Compositor.
- virtual void DisableDisplay() = 0;
-
- // Make the NSView be the first responder of its NSWindow.
- virtual void MakeFirstResponder() = 0;
-
- // Set the bounds of the NSView or its enclosing NSWindow (depending on the
- // window type).
- virtual void SetBounds(const gfx::Rect& rect) = 0;
-
- // Set the contents to display in the NSView.
- virtual void SetCALayerParams(const gfx::CALayerParams& ca_layer_params) = 0;
-
- // Set the background color of the hosted CALayer.
- virtual void SetBackgroundColor(SkColor color) = 0;
-
- // Call the -[NSView setHidden:] method.
- virtual void SetVisible(bool visible) = 0;
-
- // Call the -[NSView setToolTipAtMousePoint] method.
- virtual void SetTooltipText(const base::string16& display_text) = 0;
-
- // Forward changes in ui::TextInputType.
- virtual void SetTextInputType(ui::TextInputType text_input_type) = 0;
-
- // Forward the TextInputManager::TextSelection from the renderer.
- virtual void SetTextSelection(const base::string16& text,
- size_t offset,
- const gfx::Range& range) = 0;
-
- // Forward the TextInputManager::CompositionRangeInfo from the renderer.
- virtual void SetCompositionRangeInfo(const gfx::Range& range) = 0;
-
- // Clear the marked range.
- virtual void CancelComposition() = 0;
-
- // Indicate if the WebContext is showing a context menu.
- virtual void SetShowingContextMenu(bool showing) = 0;
-
- // Set the cursor type to display.
- virtual void DisplayCursor(const WebCursor& cursor) = 0;
-
- // Lock or unlock the cursor.
- virtual void SetCursorLocked(bool locked) = 0;
-
- // Open the dictionary overlay for the currently selected string. This
- // will roundtrip to the NSView to determine the selected range.
- virtual void ShowDictionaryOverlayForSelection() = 0;
-
- // Open the dictionary overlay for the specified string at the specified
- // point.
- virtual void ShowDictionaryOverlay(
- const mac::AttributedStringCoder::EncodedString& encoded_string,
- gfx::Point baseline_point) = 0;
-
- // Start intercepting keyboard events.
- virtual void LockKeyboard(
- base::Optional<base::flat_set<ui::DomCode>> dom_codes) = 0;
-
- // Stop intercepting keyboard events.
- virtual void UnlockKeyboard() = 0;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostNSViewBridge);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_H_
diff --git a/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h b/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h
new file mode 100644
index 00000000000..a7678f05d79
--- /dev/null
+++ b/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h
@@ -0,0 +1,99 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_LOCAL_H_
+#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_LOCAL_H_
+
+#import <Cocoa/Cocoa.h>
+
+#import "base/mac/scoped_nsobject.h"
+#import "content/browser/renderer_host/popup_window_mac.h"
+#import "content/browser/renderer_host/render_widget_host_view_cocoa.h"
+#include "content/common/render_widget_host_ns_view.mojom.h"
+#include "ui/accelerated_widget_mac/display_ca_layer_tree.h"
+#include "ui/display/display_observer.h"
+
+namespace content {
+
+// Bridge to a locally-hosted NSView -- this is always instantiated in the same
+// process as the NSView. The caller of this interface may exist in another
+// process.
+class RenderWidgetHostNSViewBridgeLocal
+ : public mojom::RenderWidgetHostNSViewBridge,
+ public display::DisplayObserver {
+ public:
+ RenderWidgetHostNSViewBridgeLocal(
+ mojom::RenderWidgetHostNSViewClient* client,
+ RenderWidgetHostNSViewLocalClient* local_client);
+ ~RenderWidgetHostNSViewBridgeLocal() override;
+
+ // TODO(ccameron): RenderWidgetHostViewMac and other functions currently use
+ // this method to communicate directly with RenderWidgetHostViewCocoa. The
+ // goal of this class is to eliminate this direct communication (so this
+ // method is expected to go away).
+ RenderWidgetHostViewCocoa* GetRenderWidgetHostViewCocoa();
+
+ // mojom::RenderWidgetHostNSViewBridge implementation.
+ void InitAsPopup(const gfx::Rect& content_rect,
+ blink::WebPopupType popup_type) override;
+ void DisableDisplay() override;
+ void MakeFirstResponder() override;
+ void SetBounds(const gfx::Rect& rect) override;
+ void SetCALayerParams(const gfx::CALayerParams& ca_layer_params) override;
+ void SetBackgroundColor(SkColor color) override;
+ void SetVisible(bool visible) override;
+ void SetTooltipText(const base::string16& display_text) override;
+ void SetTextInputType(ui::TextInputType text_input_type) override;
+ void SetTextSelection(const base::string16& text,
+ uint64_t offset,
+ const gfx::Range& range) override;
+ void SetCompositionRangeInfo(const gfx::Range& range) override;
+ void CancelComposition() override;
+ void SetShowingContextMenu(bool showing) override;
+ void DisplayCursor(const WebCursor& cursor) override;
+ void SetCursorLocked(bool locked) override;
+ void ShowDictionaryOverlayForSelection() override;
+ void ShowDictionaryOverlay(
+ const mac::AttributedStringCoder::EncodedString& encoded_string,
+ const gfx::Point& baseline_point) override;
+ void LockKeyboard(
+ const base::Optional<std::vector<uint32_t>>& uint_dom_codes) override;
+ void UnlockKeyboard() override;
+
+ private:
+ bool IsPopup() const {
+ // TODO(ccameron): If this is not equivalent to |popup_window_| then
+ // there are bugs.
+ return popup_type_ != blink::kWebPopupTypeNone;
+ }
+
+ // display::DisplayObserver implementation.
+ void OnDisplayMetricsChanged(const display::Display& display,
+ uint32_t metrics) override;
+
+ // The NSView used for input and display.
+ base::scoped_nsobject<RenderWidgetHostViewCocoa> cocoa_view_;
+
+ // Once set, all calls to set the background color or CALayer content will
+ // be ignored.
+ bool display_disabled_ = false;
+
+ // The window used for popup widgets, and its helper.
+ std::unique_ptr<PopupWindowMac> popup_window_;
+ blink::WebPopupType popup_type_ = blink::kWebPopupTypeNone;
+
+ // The background CALayer which is hosted by |cocoa_view_|, and is used as
+ // the root of |display_ca_layer_tree_|.
+ base::scoped_nsobject<CALayer> background_layer_;
+ std::unique_ptr<ui::DisplayCALayerTree> display_ca_layer_tree_;
+
+ // Cached copy of the tooltip text, to avoid redundant calls.
+ base::string16 tooltip_text_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostNSViewBridgeLocal);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_BRIDGE_LOCAL_H_
diff --git a/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge.mm b/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.mm
index 54b1c71bb4c..9df5543cc21 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_ns_view_bridge_local.mm
@@ -2,103 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#import "content/browser/renderer_host/render_widget_host_ns_view_bridge.h"
-
-#import <Cocoa/Cocoa.h>
+#import "content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h"
#include "base/mac/scoped_cftyperef.h"
-#import "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
-#import "content/browser/renderer_host/popup_window_mac.h"
-#import "content/browser/renderer_host/render_widget_host_view_cocoa.h"
#include "content/common/cursors/webcursor.h"
#import "skia/ext/skia_utils_mac.h"
-#include "ui/accelerated_widget_mac/display_ca_layer_tree.h"
#import "ui/base/cocoa/animation_utils.h"
-#include "ui/display/display_observer.h"
#include "ui/display/screen.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/gfx/mac/coordinate_conversion.h"
namespace content {
-namespace {
-
-// Bridge to a locally-hosted NSView -- this is always instantiated in the same
-// process as the NSView. The caller of this interface may exist in another
-// process.
-class RenderWidgetHostViewNSViewBridgeLocal
- : public RenderWidgetHostNSViewBridge,
- public display::DisplayObserver {
- public:
- explicit RenderWidgetHostViewNSViewBridgeLocal(
- RenderWidgetHostNSViewClient* client);
- ~RenderWidgetHostViewNSViewBridgeLocal() override;
- RenderWidgetHostViewCocoa* GetRenderWidgetHostViewCocoa() override;
-
- void InitAsPopup(const gfx::Rect& content_rect,
- blink::WebPopupType popup_type) override;
- void DisableDisplay() override;
- void MakeFirstResponder() override;
- void SetBounds(const gfx::Rect& rect) override;
- void SetCALayerParams(const gfx::CALayerParams& ca_layer_params) override;
- void SetBackgroundColor(SkColor color) override;
- void SetVisible(bool visible) override;
- void SetTooltipText(const base::string16& display_text) override;
- void SetTextInputType(ui::TextInputType text_input_type) override;
- void SetTextSelection(const base::string16& text,
- size_t offset,
- const gfx::Range& range) override;
- void SetCompositionRangeInfo(const gfx::Range& range) override;
- void CancelComposition() override;
- void SetShowingContextMenu(bool showing) override;
- void DisplayCursor(const WebCursor& cursor) override;
- void SetCursorLocked(bool locked) override;
- void ShowDictionaryOverlayForSelection() override;
- void ShowDictionaryOverlay(
- const mac::AttributedStringCoder::EncodedString& encoded_string,
- gfx::Point baseline_point) override;
- void LockKeyboard(base::Optional<base::flat_set<ui::DomCode>> codes) override;
- void UnlockKeyboard() override;
-
- private:
- bool IsPopup() const {
- // TODO(ccameron): If this is not equivalent to |popup_window_| then
- // there are bugs.
- return popup_type_ != blink::kWebPopupTypeNone;
- }
-
- // display::DisplayObserver implementation.
- void OnDisplayMetricsChanged(const display::Display& display,
- uint32_t metrics) override;
-
- // The NSView used for input and display.
- base::scoped_nsobject<RenderWidgetHostViewCocoa> cocoa_view_;
-
- // Once set, all calls to set the background color or CALayer content will
- // be ignored.
- bool display_disabled_ = false;
-
- // The window used for popup widgets, and its helper.
- std::unique_ptr<PopupWindowMac> popup_window_;
- blink::WebPopupType popup_type_ = blink::kWebPopupTypeNone;
-
- // The background CALayer which is hosted by |cocoa_view_|, and is used as
- // the root of |display_ca_layer_tree_|.
- base::scoped_nsobject<CALayer> background_layer_;
- std::unique_ptr<ui::DisplayCALayerTree> display_ca_layer_tree_;
-
- // Cached copy of the tooltip text, to avoid redundant calls.
- base::string16 tooltip_text_;
-
- DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewNSViewBridgeLocal);
-};
-
-RenderWidgetHostViewNSViewBridgeLocal::RenderWidgetHostViewNSViewBridgeLocal(
- RenderWidgetHostNSViewClient* client) {
+RenderWidgetHostNSViewBridgeLocal::RenderWidgetHostNSViewBridgeLocal(
+ mojom::RenderWidgetHostNSViewClient* client,
+ RenderWidgetHostNSViewLocalClient* local_client) {
display::Screen::GetScreen()->AddObserver(this);
- cocoa_view_.reset([[RenderWidgetHostViewCocoa alloc] initWithClient:client]);
+ cocoa_view_.reset([[RenderWidgetHostViewCocoa alloc]
+ initWithClient:client
+ withLocalClient:local_client]);
background_layer_.reset([[CALayer alloc] init]);
display_ca_layer_tree_ =
@@ -107,8 +31,7 @@ RenderWidgetHostViewNSViewBridgeLocal::RenderWidgetHostViewNSViewBridgeLocal(
[cocoa_view_ setWantsLayer:YES];
}
-RenderWidgetHostViewNSViewBridgeLocal::
- ~RenderWidgetHostViewNSViewBridgeLocal() {
+RenderWidgetHostNSViewBridgeLocal::~RenderWidgetHostNSViewBridgeLocal() {
[cocoa_view_ setClientDisconnected];
// Do not immediately remove |cocoa_view_| from the NSView heirarchy, because
// the call to -[NSView removeFromSuperview] may cause use to call into the
@@ -123,11 +46,11 @@ RenderWidgetHostViewNSViewBridgeLocal::
}
RenderWidgetHostViewCocoa*
-RenderWidgetHostViewNSViewBridgeLocal::GetRenderWidgetHostViewCocoa() {
+RenderWidgetHostNSViewBridgeLocal::GetRenderWidgetHostViewCocoa() {
return cocoa_view_;
}
-void RenderWidgetHostViewNSViewBridgeLocal::InitAsPopup(
+void RenderWidgetHostNSViewBridgeLocal::InitAsPopup(
const gfx::Rect& content_rect,
blink::WebPopupType popup_type) {
popup_type_ = popup_type;
@@ -135,11 +58,11 @@ void RenderWidgetHostViewNSViewBridgeLocal::InitAsPopup(
std::make_unique<PopupWindowMac>(content_rect, popup_type_, cocoa_view_);
}
-void RenderWidgetHostViewNSViewBridgeLocal::MakeFirstResponder() {
+void RenderWidgetHostNSViewBridgeLocal::MakeFirstResponder() {
[[cocoa_view_ window] makeFirstResponder:cocoa_view_];
}
-void RenderWidgetHostViewNSViewBridgeLocal::DisableDisplay() {
+void RenderWidgetHostNSViewBridgeLocal::DisableDisplay() {
if (display_disabled_)
return;
SetBackgroundColor(SK_ColorTRANSPARENT);
@@ -147,7 +70,7 @@ void RenderWidgetHostViewNSViewBridgeLocal::DisableDisplay() {
display_disabled_ = true;
}
-void RenderWidgetHostViewNSViewBridgeLocal::SetBounds(const gfx::Rect& rect) {
+void RenderWidgetHostNSViewBridgeLocal::SetBounds(const gfx::Rect& rect) {
// |rect.size()| is view coordinates, |rect.origin| is screen coordinates,
// TODO(thakis): fix, http://crbug.com/73362
@@ -188,14 +111,14 @@ void RenderWidgetHostViewNSViewBridgeLocal::SetBounds(const gfx::Rect& rect) {
}
}
-void RenderWidgetHostViewNSViewBridgeLocal::SetCALayerParams(
+void RenderWidgetHostNSViewBridgeLocal::SetCALayerParams(
const gfx::CALayerParams& ca_layer_params) {
if (display_disabled_)
return;
display_ca_layer_tree_->UpdateCALayerTree(ca_layer_params);
}
-void RenderWidgetHostViewNSViewBridgeLocal::SetBackgroundColor(SkColor color) {
+void RenderWidgetHostNSViewBridgeLocal::SetBackgroundColor(SkColor color) {
if (display_disabled_)
return;
ScopedCAActionDisabler disabler;
@@ -204,12 +127,12 @@ void RenderWidgetHostViewNSViewBridgeLocal::SetBackgroundColor(SkColor color) {
[background_layer_ setBackgroundColor:cg_color];
}
-void RenderWidgetHostViewNSViewBridgeLocal::SetVisible(bool visible) {
+void RenderWidgetHostNSViewBridgeLocal::SetVisible(bool visible) {
ScopedCAActionDisabler disabler;
[cocoa_view_ setHidden:!visible];
}
-void RenderWidgetHostViewNSViewBridgeLocal::SetTooltipText(
+void RenderWidgetHostNSViewBridgeLocal::SetTooltipText(
const base::string16& tooltip_text) {
// Called from the renderer to tell us what the tooltip text should be. It
// calls us frequently so we need to cache the value to prevent doing a lot
@@ -233,24 +156,24 @@ void RenderWidgetHostViewNSViewBridgeLocal::SetTooltipText(
[cocoa_view_ setToolTipAtMousePoint:tooltip_nsstring];
}
-void RenderWidgetHostViewNSViewBridgeLocal::SetCompositionRangeInfo(
+void RenderWidgetHostNSViewBridgeLocal::SetCompositionRangeInfo(
const gfx::Range& range) {
[cocoa_view_ setCompositionRange:range];
[cocoa_view_ setMarkedRange:range.ToNSRange()];
}
-void RenderWidgetHostViewNSViewBridgeLocal::CancelComposition() {
+void RenderWidgetHostNSViewBridgeLocal::CancelComposition() {
[cocoa_view_ cancelComposition];
}
-void RenderWidgetHostViewNSViewBridgeLocal::SetTextInputType(
+void RenderWidgetHostNSViewBridgeLocal::SetTextInputType(
ui::TextInputType text_input_type) {
[cocoa_view_ setTextInputType:text_input_type];
}
-void RenderWidgetHostViewNSViewBridgeLocal::SetTextSelection(
+void RenderWidgetHostNSViewBridgeLocal::SetTextSelection(
const base::string16& text,
- size_t offset,
+ uint64_t offset,
const gfx::Range& range) {
[cocoa_view_ setTextSelectionText:text offset:offset range:range];
// Updates markedRange when there is no marked text so that retrieving
@@ -261,12 +184,11 @@ void RenderWidgetHostViewNSViewBridgeLocal::SetTextSelection(
}
}
-void RenderWidgetHostViewNSViewBridgeLocal::SetShowingContextMenu(
- bool showing) {
+void RenderWidgetHostNSViewBridgeLocal::SetShowingContextMenu(bool showing) {
[cocoa_view_ setShowingContextMenu:showing];
}
-void RenderWidgetHostViewNSViewBridgeLocal::OnDisplayMetricsChanged(
+void RenderWidgetHostNSViewBridgeLocal::OnDisplayMetricsChanged(
const display::Display& display,
uint32_t changed_metrics) {
// Note that -updateScreenProperties is also be called by the notification
@@ -275,13 +197,12 @@ void RenderWidgetHostViewNSViewBridgeLocal::OnDisplayMetricsChanged(
[cocoa_view_ updateScreenProperties];
}
-void RenderWidgetHostViewNSViewBridgeLocal::DisplayCursor(
- const WebCursor& cursor) {
+void RenderWidgetHostNSViewBridgeLocal::DisplayCursor(const WebCursor& cursor) {
WebCursor non_const_cursor = cursor;
[cocoa_view_ updateCursor:non_const_cursor.GetNativeCursor()];
}
-void RenderWidgetHostViewNSViewBridgeLocal::SetCursorLocked(bool locked) {
+void RenderWidgetHostNSViewBridgeLocal::SetCursorLocked(bool locked) {
if (locked) {
CGAssociateMouseAndMouseCursorPosition(NO);
[NSCursor hide];
@@ -292,15 +213,14 @@ void RenderWidgetHostViewNSViewBridgeLocal::SetCursorLocked(bool locked) {
}
}
-void RenderWidgetHostViewNSViewBridgeLocal::
- ShowDictionaryOverlayForSelection() {
+void RenderWidgetHostNSViewBridgeLocal::ShowDictionaryOverlayForSelection() {
NSRange selection_range = [cocoa_view_ selectedRange];
[cocoa_view_ showLookUpDictionaryOverlayFromRange:selection_range];
}
-void RenderWidgetHostViewNSViewBridgeLocal::ShowDictionaryOverlay(
+void RenderWidgetHostNSViewBridgeLocal::ShowDictionaryOverlay(
const mac::AttributedStringCoder::EncodedString& encoded_string,
- gfx::Point baseline_point) {
+ const gfx::Point& baseline_point) {
NSAttributedString* string =
mac::AttributedStringCoder::Decode(&encoded_string);
if ([string length] == 0)
@@ -312,21 +232,19 @@ void RenderWidgetHostViewNSViewBridgeLocal::ShowDictionaryOverlay(
atPoint:flipped_baseline_point];
}
-void RenderWidgetHostViewNSViewBridgeLocal::LockKeyboard(
- base::Optional<base::flat_set<ui::DomCode>> dom_codes) {
+void RenderWidgetHostNSViewBridgeLocal::LockKeyboard(
+ const base::Optional<std::vector<uint32_t>>& uint_dom_codes) {
+ base::Optional<base::flat_set<ui::DomCode>> dom_codes;
+ if (uint_dom_codes) {
+ dom_codes.emplace();
+ for (const auto& uint_dom_code : *uint_dom_codes)
+ dom_codes->insert(static_cast<ui::DomCode>(uint_dom_code));
+ }
[cocoa_view_ lockKeyboard:std::move(dom_codes)];
}
-void RenderWidgetHostViewNSViewBridgeLocal::UnlockKeyboard() {
+void RenderWidgetHostNSViewBridgeLocal::UnlockKeyboard() {
[cocoa_view_ unlockKeyboard];
}
-} // namespace
-
-// static
-std::unique_ptr<RenderWidgetHostNSViewBridge>
-RenderWidgetHostNSViewBridge::Create(RenderWidgetHostNSViewClient* client) {
- return std::make_unique<RenderWidgetHostViewNSViewBridgeLocal>(client);
-}
-
} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_widget_host_ns_view_client.h b/chromium/content/browser/renderer_host/render_widget_host_ns_view_client.h
index bc2365191c6..92f4fd7407f 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_ns_view_client.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_ns_view_client.h
@@ -6,11 +6,8 @@
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_NS_VIEW_CLIENT_H_
#include "base/macros.h"
-#include "base/strings/string16.h"
-#include "content/common/edit_command.h"
-#include "content/common/mac/attributed_string_coder.h"
-#include "ui/base/ime/ime_text_span.h"
-#include "ui/base/ime/text_input_type.h"
+
+#include <vector>
namespace blink {
class WebGestureEvent;
@@ -18,170 +15,62 @@ class WebMouseEvent;
class WebMouseWheelEvent;
} // namespace blink
-namespace display {
-class Display;
-} // namespace display
-
-namespace gfx {
-class PointF;
-class Range;
-class Rect;
-} // namespace gfx
-
namespace ui {
class LatencyInfo;
} // namespace ui
namespace content {
-class RenderWidgetHostViewMac;
+class BrowserAccessibilityManager;
+struct EditCommand;
+struct NativeWebKeyboardEvent;
-// The interface through which the NSView for a RenderWidgetHostViewMac is to
+// An interface through which the NSView for a RenderWidgetHostViewMac is to
// communicate with the RenderWidgetHostViewMac (potentially in another
-// process).
-class RenderWidgetHostNSViewClient {
+// process). Unlike mojom::RenderWidgetHostNSViewClient, this object is always
+// instantiated in the local process. This is to implement functions that
+// cannot be sent across mojo (e.g, GetRootBrowserAccessibilityManager), or
+// to avoid unnecessary translation of event types.
+class RenderWidgetHostNSViewLocalClient {
public:
- RenderWidgetHostNSViewClient() {}
- virtual ~RenderWidgetHostNSViewClient() {}
+ RenderWidgetHostNSViewLocalClient() {}
+ virtual ~RenderWidgetHostNSViewLocalClient() {}
// Return the RenderWidget's BrowserAccessibilityManager.
// TODO(ccameron): This returns nullptr for non-local NSViews. A scheme for
// non-local accessibility needs to be developed.
virtual BrowserAccessibilityManager* GetRootBrowserAccessibilityManager() = 0;
- // Synchronously query if there exists a RenderViewHost for the corresponding
- // RenderWidgetHostView's RenderWidgetHost, and store the result in
- // |*is_render_view|.
- virtual void OnNSViewSyncIsRenderViewHost(bool* is_render_view) = 0;
-
- // Indicates that the RenderWidgetHost is to shut down.
- virtual void OnNSViewRequestShutdown() = 0;
-
- // Indicates whether or not the NSView is its NSWindow's first responder.
- virtual void OnNSViewIsFirstResponderChanged(bool is_first_responder) = 0;
-
- // Indicates whether or not the NSView's NSWindow is key.
- virtual void OnNSViewWindowIsKeyChanged(bool is_key) = 0;
-
- // Indicates the NSView's bounds in its NSWindow's DIP coordinate system (with
- // the origin at the upper-left corner), and indicate if the the NSView is
- // attached to an NSWindow (if it is not, then |view_bounds_in_window_dip|'s
- // origin is meaningless, but its size is still relevant).
- virtual void OnNSViewBoundsInWindowChanged(
- const gfx::Rect& view_bounds_in_window_dip,
- bool attached_to_window) = 0;
-
- // Indicates the NSView's NSWindow's frame in the global display::Screen
- // DIP coordinate system (where the origin the upper-left corner of
- // Screen::GetPrimaryDisplay).
- virtual void OnNSViewWindowFrameInScreenChanged(
- const gfx::Rect& window_frame_in_screen_dip) = 0;
-
- // Indicate the NSView's NSScreen's properties.
- virtual void OnNSViewDisplayChanged(const display::Display& display) = 0;
-
- // Indicate the begin and end block of a keyboard event. The beginning of this
- // block will record the active RenderWidgetHost, and will forward all
- // remaining keyboard and Ime messages to that RenderWidgetHost.
- virtual void OnNSViewBeginKeyboardEvent() = 0;
- virtual void OnNSViewEndKeyboardEvent() = 0;
-
// Forward a keyboard event to the RenderWidgetHost that is currently handling
// the key-down event.
- virtual void OnNSViewForwardKeyboardEvent(
- const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info) = 0;
- virtual void OnNSViewForwardKeyboardEventWithCommands(
+ virtual void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event,
+ const ui::LatencyInfo& latency_info) = 0;
+ virtual void ForwardKeyboardEventWithCommands(
const NativeWebKeyboardEvent& key_event,
const ui::LatencyInfo& latency_info,
const std::vector<EditCommand>& commands) = 0;
// Forward events to the renderer or the input router, as appropriate.
- virtual void OnNSViewRouteOrProcessMouseEvent(
+ virtual void RouteOrProcessMouseEvent(
const blink::WebMouseEvent& web_event) = 0;
- virtual void OnNSViewRouteOrProcessWheelEvent(
+ virtual void RouteOrProcessWheelEvent(
const blink::WebMouseWheelEvent& web_event) = 0;
// Special case forwarding of synthetic events to the renderer.
- virtual void OnNSViewForwardMouseEvent(
- const blink::WebMouseEvent& web_event) = 0;
- virtual void OnNSViewForwardWheelEvent(
+ virtual void ForwardMouseEvent(const blink::WebMouseEvent& web_event) = 0;
+ virtual void ForwardWheelEvent(
const blink::WebMouseWheelEvent& web_event) = 0;
// Handling pinch gesture events.
- virtual void OnNSViewGestureBegin(blink::WebGestureEvent begin_event,
- bool is_synthetically_injected) = 0;
- virtual void OnNSViewGestureUpdate(blink::WebGestureEvent update_event) = 0;
- virtual void OnNSViewGestureEnd(blink::WebGestureEvent end_event) = 0;
- virtual void OnNSViewSmartMagnify(
+ virtual void GestureBegin(blink::WebGestureEvent begin_event,
+ bool is_synthetically_injected) = 0;
+ virtual void GestureUpdate(blink::WebGestureEvent update_event) = 0;
+ virtual void GestureEnd(blink::WebGestureEvent end_event) = 0;
+ virtual void SmartMagnify(
const blink::WebGestureEvent& smart_magnify_event) = 0;
- // Forward the corresponding Ime commands to the appropriate RenderWidgetHost.
- // Appropriate, has two meanings here. If this is during a key-down event,
- // then the target is the RWH that is handling that key-down event. Otherwise,
- // it is the result of GetActiveWidget.
- virtual void OnNSViewImeSetComposition(
- const base::string16& text,
- const std::vector<ui::ImeTextSpan>& ime_text_spans,
- const gfx::Range& replacement_range,
- int selection_start,
- int selection_end) = 0;
- virtual void OnNSViewImeCommitText(const base::string16& text,
- const gfx::Range& replacement_range) = 0;
- virtual void OnNSViewImeFinishComposingText() = 0;
- virtual void OnNSViewImeCancelComposition() = 0;
-
- // Request an overlay dictionary be displayed for the text at the specified
- // point.
- virtual void OnNSViewLookUpDictionaryOverlayAtPoint(
- const gfx::PointF& root_point) = 0;
-
- // Request an overlay dictionary be displayed for the text in the the
- // specified character range.
- virtual void OnNSViewLookUpDictionaryOverlayFromRange(
- const gfx::Range& range) = 0;
-
- // Synchronously query the character index for |root_point| and return it in
- // |*index|. Sets it to UINT32_MAX if the request fails or is not completed.
- virtual void OnNSViewSyncGetCharacterIndexAtPoint(
- const gfx::PointF& root_point,
- uint32_t* index) = 0;
-
- // Synchronously query the composition character boundary rectangle and return
- // it in |*rect|. Set |*actual_range| to the range actually used for the
- // returned rectangle. If there was no focused RenderWidgetHost to query,
- // then set |*success| to false.
- virtual void OnNSViewSyncGetFirstRectForRange(
- const gfx::Range& requested_range,
- gfx::Rect* rect,
- gfx::Range* actual_range,
- bool* success) = 0;
-
- // Forward the corresponding edit menu command to the RenderWidgetHost's
- // delegate.
- virtual void OnNSViewExecuteEditCommand(const std::string& command) = 0;
- virtual void OnNSViewUndo() = 0;
- virtual void OnNSViewRedo() = 0;
- virtual void OnNSViewCut() = 0;
- virtual void OnNSViewCopy() = 0;
- virtual void OnNSViewCopyToFindPboard() = 0;
- virtual void OnNSViewPaste() = 0;
- virtual void OnNSViewPasteAndMatchStyle() = 0;
- virtual void OnNSViewSelectAll() = 0;
-
- // Speak the selected text of the appropriate RenderWidgetHostView using
- // TextServicesContextMenu.
- virtual void OnNSViewSpeakSelection() = 0;
-
- // Stop speaking using TextServicesContextMenu.
- virtual void OnNSViewStopSpeaking() = 0;
-
- // Synchronously query if TextServicesContextMenu is currently speaking and
- // store the result in |*is_speaking|.
- virtual void OnNSViewSyncIsSpeaking(bool* is_speaking) = 0;
-
private:
- DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostNSViewClient);
+ DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostNSViewLocalClient);
};
} // namespace content
diff --git a/chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h b/chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h
index 409e8efb2a7..24a08a3fdf6 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_owner_delegate.h
@@ -57,6 +57,9 @@ class CONTENT_EXPORT RenderWidgetHostOwnerDelegate {
// priority to the RenderProcessHost.
virtual bool ShouldContributePriorityToProcess() = 0;
+ // Called when the RenderWidgetHost has shutdown.
+ virtual void RenderWidgetDidShutdown() = 0;
+
protected:
virtual ~RenderWidgetHostOwnerDelegate() {}
};
diff --git a/chromium/content/browser/renderer_host/render_widget_host_unittest.cc b/chromium/content/browser/renderer_host/render_widget_host_unittest.cc
index 99e582adf7d..e5de66d7b7c 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/chromium/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -14,7 +14,7 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -127,12 +127,16 @@ class MockInputRouter : public InputRouter {
bool HasPendingEvents() const override { return false; }
void SetDeviceScaleFactor(float device_scale_factor) override {}
void SetFrameTreeNodeId(int frameTreeNodeId) override {}
- cc::TouchAction AllowedTouchAction() override { return cc::kTouchActionAuto; }
+ base::Optional<cc::TouchAction> AllowedTouchAction() override {
+ return cc::kTouchActionAuto;
+ }
void SetForceEnableZoom(bool enabled) override {}
void BindHost(mojom::WidgetInputHandlerHostRequest request,
bool frame_handler) override {}
void StopFling() override {}
bool FlingCancellationIsDeferred() override { return false; }
+ void OnSetTouchAction(cc::TouchAction touch_action) override {}
+ void ForceSetTouchActionAuto() override {}
// IPC::Listener
bool OnMessageReceived(const IPC::Message& message) override {
@@ -157,7 +161,7 @@ class MockInputRouter : public InputRouter {
class TestFrameTokenMessageQueue : public FrameTokenMessageQueue {
public:
- TestFrameTokenMessageQueue(FrameTokenMessageQueue::Client* client)
+ explicit TestFrameTokenMessageQueue(FrameTokenMessageQueue::Client* client)
: FrameTokenMessageQueue(client) {}
~TestFrameTokenMessageQueue() override {}
@@ -180,7 +184,6 @@ class TestFrameTokenMessageQueue : public FrameTokenMessageQueue {
class MockRenderWidgetHost : public RenderWidgetHostImpl {
public:
-
// Allow poking at a few private members.
using RenderWidgetHostImpl::GetVisualProperties;
using RenderWidgetHostImpl::RendererExited;
@@ -241,6 +244,8 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl {
return static_cast<MockInputRouter*>(input_router_.get());
}
+ InputRouter* input_router() { return input_router_.get(); }
+
uint32_t processed_frame_messages_count() {
CHECK(frame_token_message_queue_);
return static_cast<TestFrameTokenMessageQueue*>(
@@ -308,7 +313,7 @@ class RenderWidgetHostProcess : public MockRenderProcessHost {
}
~RenderWidgetHostProcess() override {}
- bool HasConnection() const override { return true; }
+ bool IsInitializedAndNotDead() const override { return true; }
private:
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostProcess);
@@ -403,7 +408,7 @@ class TestView : public TestRenderWidgetHostView {
float GetBottomControlsHeight() const override {
return bottom_controls_height_;
}
- viz::LocalSurfaceId GetLocalSurfaceId() const override {
+ const viz::LocalSurfaceId& GetLocalSurfaceId() const override {
return local_surface_id_allocator_.GetCurrentLocalSurfaceId();
}
@@ -560,6 +565,19 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
return render_view_host_delegate_view_.get();
}
+ void SetZoomLevel(double zoom_level) { zoom_level_ = zoom_level; }
+
+ double GetPendingPageZoomLevel() const override { return zoom_level_; }
+
+ void FocusOwningWebContents(
+ RenderWidgetHostImpl* render_widget_host) override {
+ focus_owning_web_contents_call_count++;
+ }
+
+ int GetFocusOwningWebContentsCallCount() const {
+ return focus_owning_web_contents_call_count;
+ }
+
RenderViewHostDelegateView* GetDelegateView() override {
return mock_delegate_view();
}
@@ -586,7 +604,9 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
return handle_wheel_event_;
}
- void RendererUnresponsive(RenderWidgetHostImpl* render_widget_host) override {
+ void RendererUnresponsive(
+ RenderWidgetHostImpl* render_widget_host,
+ base::RepeatingClosure hang_monitor_restarter) override {
unresponsive_timer_fired_ = true;
}
@@ -615,45 +635,23 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
std::unique_ptr<MockRenderViewHostDelegateView>
render_view_host_delegate_view_;
-};
-enum WheelScrollingMode {
- kWheelScrollingModeNone,
- kWheelScrollLatching,
- kAsyncWheelEvents,
+ double zoom_level_ = 0;
+
+ int focus_owning_web_contents_call_count = 0;
};
// RenderWidgetHostTest --------------------------------------------------------
class RenderWidgetHostTest : public testing::Test {
public:
- RenderWidgetHostTest(
- WheelScrollingMode wheel_scrolling_mode = kWheelScrollLatching)
+ RenderWidgetHostTest()
: process_(nullptr),
handle_key_press_event_(false),
handle_mouse_event_(false),
- last_simulated_event_time_(ui::EventTimeForNow()),
- wheel_scroll_latching_enabled_(wheel_scrolling_mode !=
- kWheelScrollingModeNone) {
+ last_simulated_event_time_(ui::EventTimeForNow()) {
std::vector<base::StringPiece> features;
std::vector<base::StringPiece> disabled_features;
-
- switch (wheel_scrolling_mode) {
- case kWheelScrollingModeNone:
- disabled_features.push_back(
- features::kTouchpadAndWheelScrollLatching.name);
- disabled_features.push_back(features::kAsyncWheelEvents.name);
- break;
- case kWheelScrollLatching:
- features.push_back(features::kTouchpadAndWheelScrollLatching.name);
- disabled_features.push_back(features::kAsyncWheelEvents.name);
- break;
- case kAsyncWheelEvents:
- features.push_back(features::kTouchpadAndWheelScrollLatching.name);
- features.push_back(features::kAsyncWheelEvents.name);
- break;
- }
-
features.push_back(features::kVsyncAlignedInputEvents.name);
feature_list_.InitFromCommandLine(base::JoinString(features, ","),
@@ -668,6 +666,13 @@ class RenderWidgetHostTest : public testing::Test {
return handle_mouse_event_;
}
+ void RunLoopFor(base::TimeDelta duration) {
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(), duration);
+ run_loop.Run();
+ }
+
protected:
// testing::Test
void SetUp() override {
@@ -761,8 +766,6 @@ class RenderWidgetHostTest : public testing::Test {
virtual void ConfigureView(TestView* view) {
}
- int64_t GetLatencyComponentId() { return host_->GetLatencyComponentId(); }
-
base::TimeTicks GetNextSimulatedEventTime() {
last_simulated_event_time_ += simulated_event_time_delta_;
return last_simulated_event_time_;
@@ -802,16 +805,14 @@ class RenderWidgetHostTest : public testing::Test {
0, 0, dX, dY, modifiers, precise));
}
- void SimulateWheelEventPossiblyIncludingPhase(
- float dX,
- float dY,
- int modifiers,
- bool precise,
- WebMouseWheelEvent::Phase phase) {
+ void SimulateWheelEvent(float dX,
+ float dY,
+ int modifiers,
+ bool precise,
+ WebMouseWheelEvent::Phase phase) {
WebMouseWheelEvent wheel_event = SyntheticWebMouseWheelEventBuilder::Build(
0, 0, dX, dY, modifiers, precise);
- if (wheel_scroll_latching_enabled_)
- wheel_event.phase = phase;
+ wheel_event.phase = phase;
host_->ForwardWheelEvent(wheel_event);
}
@@ -826,17 +827,15 @@ class RenderWidgetHostTest : public testing::Test {
ui_latency);
}
- void SimulateWheelEventWithLatencyInfoAndPossiblyPhase(
- float dX,
- float dY,
- int modifiers,
- bool precise,
- const ui::LatencyInfo& ui_latency,
- WebMouseWheelEvent::Phase phase) {
+ void SimulateWheelEventWithLatencyInfo(float dX,
+ float dY,
+ int modifiers,
+ bool precise,
+ const ui::LatencyInfo& ui_latency,
+ WebMouseWheelEvent::Phase phase) {
WebMouseWheelEvent wheel_event = SyntheticWebMouseWheelEventBuilder::Build(
0, 0, dX, dY, modifiers, precise);
- if (wheel_scroll_latching_enabled_)
- wheel_event.phase = phase;
+ wheel_event.phase = phase;
host_->ForwardWheelEventWithLatencyInfo(wheel_event, ui_latency);
}
@@ -865,8 +864,7 @@ class RenderWidgetHostTest : public testing::Test {
WebGestureDevice sourceDevice,
const ui::LatencyInfo& ui_latency) {
host_->ForwardGestureEventWithLatencyInfo(
- SyntheticWebGestureEventBuilder::Build(type, sourceDevice),
- ui_latency);
+ SyntheticWebGestureEventBuilder::Build(type, sourceDevice), ui_latency);
}
// Set the timestamp for the touch-event.
@@ -905,10 +903,6 @@ class RenderWidgetHostTest : public testing::Test {
return reinterpret_cast<const WebInputEvent*>(data);
}
- void UnhandledWheelEvent();
- void HandleWheelEvent();
- void InputEventRWHLatencyComponent();
-
std::unique_ptr<TestBrowserContext> browser_context_;
RenderWidgetHostProcess* process_; // Deleted automatically by the widget.
std::unique_ptr<MockRenderWidgetHostDelegate> delegate_;
@@ -924,7 +918,6 @@ class RenderWidgetHostTest : public testing::Test {
renderer_compositor_frame_sink_;
std::unique_ptr<FakeRenderFrameMetadataObserver>
renderer_render_frame_metadata_observer_;
- bool wheel_scroll_latching_enabled_;
private:
SyntheticWebTouchEvent touch_event_;
@@ -936,20 +929,6 @@ class RenderWidgetHostTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostTest);
};
-class RenderWidgetHostWheelScrollLatchingDisabledTest
- : public RenderWidgetHostTest {
- public:
- RenderWidgetHostWheelScrollLatchingDisabledTest()
- : RenderWidgetHostTest(kWheelScrollingModeNone) {}
-};
-
-class RenderWidgetHostAsyncWheelEventsEnabledTest
- : public RenderWidgetHostTest {
- public:
- RenderWidgetHostAsyncWheelEventsEnabledTest()
- : RenderWidgetHostTest(kAsyncWheelEvents) {}
-};
-
// RenderWidgetHostWithSourceTest ----------------------------------------------
// This is for tests that are to be run for all source devices.
@@ -962,8 +941,26 @@ class RenderWidgetHostWithSourceTest
// -----------------------------------------------------------------------------
TEST_F(RenderWidgetHostTest, SynchronizeVisualProperties) {
+ // The initial zoom is 0 so host should not send a sync message
+ delegate_->SetZoomLevel(0);
+ EXPECT_FALSE(host_->SynchronizeVisualProperties());
+ EXPECT_FALSE(host_->visual_properties_ack_pending_);
+ EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(
+ ViewMsg_SynchronizeVisualProperties::ID));
+
+ // The zoom has changed so host should send out a sync message
+ process_->sink().ClearMessages();
+ double new_zoom_level = content::ZoomFactorToZoomLevel(0.25);
+ delegate_->SetZoomLevel(new_zoom_level);
+ EXPECT_TRUE(host_->SynchronizeVisualProperties());
+ EXPECT_FALSE(host_->visual_properties_ack_pending_);
+ EXPECT_NEAR(new_zoom_level, host_->old_visual_properties_->zoom_level, 0.01);
+ EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(
+ ViewMsg_SynchronizeVisualProperties::ID));
+
// The initial bounds is the empty rect, so setting it to the same thing
// shouldn't send the resize message.
+ process_->sink().ClearMessages();
view_->SetBounds(gfx::Rect());
host_->SynchronizeVisualProperties();
EXPECT_FALSE(host_->visual_properties_ack_pending_);
@@ -1215,14 +1212,14 @@ TEST_F(RenderWidgetHostTest, HiddenPaint) {
// Now unhide.
process_->sink().ClearMessages();
- host_->WasShown(ui::LatencyInfo());
+ host_->WasShown(false /* record_presentation_time */);
EXPECT_FALSE(host_->is_hidden_);
// It should have sent out a restored message with a request to paint.
const IPC::Message* restored = process_->sink().GetUniqueMessageMatching(
ViewMsg_WasShown::ID);
ASSERT_TRUE(restored);
- std::tuple<bool, ui::LatencyInfo> needs_repaint;
+ std::tuple<bool, base::TimeTicks> needs_repaint;
ViewMsg_WasShown::Read(restored, &needs_repaint);
EXPECT_TRUE(std::get<0>(needs_repaint));
}
@@ -1374,9 +1371,8 @@ TEST_F(RenderWidgetHostTest, RawKeyDownShortcutEvent) {
EXPECT_EQ(WebInputEvent::kKeyUp, delegate_->unhandled_keyboard_event_type());
}
-void RenderWidgetHostTest::UnhandledWheelEvent() {
- SimulateWheelEventPossiblyIncludingPhase(-5, 0, 0, true,
- WebMouseWheelEvent::kPhaseBegan);
+TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) {
+ SimulateWheelEvent(-5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan);
MockWidgetInputHandler::MessageVector dispatched_events =
host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
@@ -1393,22 +1389,12 @@ void RenderWidgetHostTest::UnhandledWheelEvent() {
EXPECT_EQ(1, view_->unhandled_wheel_event_count());
EXPECT_EQ(-5, view_->unhandled_wheel_event().delta_x);
}
-TEST_F(RenderWidgetHostTest, UnhandledWheelEvent) {
- UnhandledWheelEvent();
-}
-TEST_F(RenderWidgetHostWheelScrollLatchingDisabledTest, UnhandledWheelEvent) {
- UnhandledWheelEvent();
-}
-TEST_F(RenderWidgetHostAsyncWheelEventsEnabledTest, UnhandledWheelEvent) {
- UnhandledWheelEvent();
-}
-void RenderWidgetHostTest::HandleWheelEvent() {
+TEST_F(RenderWidgetHostTest, HandleWheelEvent) {
// Indicate that we're going to handle this wheel event
delegate_->set_handle_wheel_event(true);
- SimulateWheelEventPossiblyIncludingPhase(-5, 0, 0, true,
- WebMouseWheelEvent::kPhaseBegan);
+ SimulateWheelEvent(-5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan);
MockWidgetInputHandler::MessageVector dispatched_events =
host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
@@ -1427,14 +1413,26 @@ void RenderWidgetHostTest::HandleWheelEvent() {
// and that it suppressed the unhandled wheel event handler.
EXPECT_EQ(0, view_->unhandled_wheel_event_count());
}
-TEST_F(RenderWidgetHostTest, HandleWheelEvent) {
- HandleWheelEvent();
-}
-TEST_F(RenderWidgetHostWheelScrollLatchingDisabledTest, HandleWheelEvent) {
- HandleWheelEvent();
-}
-TEST_F(RenderWidgetHostAsyncWheelEventsEnabledTest, HandleWheelEvent) {
- HandleWheelEvent();
+
+TEST_F(RenderWidgetHostTest, EventsCausingFocus) {
+ SimulateMouseEvent(WebInputEvent::kMouseDown);
+ EXPECT_EQ(1, delegate_->GetFocusOwningWebContentsCallCount());
+
+ PressTouchPoint(0, 1);
+ SendTouchEvent();
+ EXPECT_EQ(2, delegate_->GetFocusOwningWebContentsCallCount());
+
+ ReleaseTouchPoint(0);
+ SendTouchEvent();
+ EXPECT_EQ(2, delegate_->GetFocusOwningWebContentsCallCount());
+
+ SimulateGestureEvent(WebInputEvent::kGestureTapDown,
+ blink::kWebGestureDeviceTouchscreen);
+ EXPECT_EQ(2, delegate_->GetFocusOwningWebContentsCallCount());
+
+ SimulateGestureEvent(WebInputEvent::kGestureTap,
+ blink::kWebGestureDeviceTouchscreen);
+ EXPECT_EQ(3, delegate_->GetFocusOwningWebContentsCallCount());
}
TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) {
@@ -1458,62 +1456,53 @@ TEST_F(RenderWidgetHostTest, UnhandledGestureEvent) {
// Test that the hang monitor timer expires properly if a new timer is started
// while one is in progress (see crbug.com/11007).
-TEST_F(RenderWidgetHostTest, DontPostponeHangMonitorTimeout) {
+TEST_F(RenderWidgetHostTest, DontPostponeInputEventAckTimeout) {
// Start with a short timeout.
- host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
+ host_->StartInputEventAckTimeout(TimeDelta::FromMilliseconds(10));
// Immediately try to add a long 30 second timeout.
EXPECT_FALSE(delegate_->unresponsive_timer_fired());
- host_->StartHangMonitorTimeout(TimeDelta::FromSeconds(30));
+ host_->StartInputEventAckTimeout(TimeDelta::FromSeconds(30));
// Wait long enough for first timeout and see if it fired.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMilliseconds(10));
- base::RunLoop().Run();
+ RunLoopFor(TimeDelta::FromMilliseconds(10));
EXPECT_TRUE(delegate_->unresponsive_timer_fired());
}
// Test that the hang monitor timer expires properly if it is started, stopped,
// and then started again.
-TEST_F(RenderWidgetHostTest, StopAndStartHangMonitorTimeout) {
+TEST_F(RenderWidgetHostTest, StopAndStartInputEventAckTimeout) {
// Start with a short timeout, then stop it.
- host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
- host_->StopHangMonitorTimeout();
+ host_->StartInputEventAckTimeout(TimeDelta::FromMilliseconds(10));
+ host_->StopInputEventAckTimeout();
// Start it again to ensure it still works.
EXPECT_FALSE(delegate_->unresponsive_timer_fired());
- host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(10));
+ host_->StartInputEventAckTimeout(TimeDelta::FromMilliseconds(10));
// Wait long enough for first timeout and see if it fired.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMilliseconds(40));
- base::RunLoop().Run();
+ RunLoopFor(TimeDelta::FromMilliseconds(40));
EXPECT_TRUE(delegate_->unresponsive_timer_fired());
}
// Test that the hang monitor timer expires properly if it is started, then
// updated to a shorter duration.
-TEST_F(RenderWidgetHostTest, ShorterDelayHangMonitorTimeout) {
+TEST_F(RenderWidgetHostTest, ShorterDelayInputEventAckTimeout) {
// Start with a timeout.
- host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(100));
+ host_->StartInputEventAckTimeout(TimeDelta::FromMilliseconds(100));
// Start it again with shorter delay.
EXPECT_FALSE(delegate_->unresponsive_timer_fired());
- host_->StartHangMonitorTimeout(TimeDelta::FromMilliseconds(20));
+ host_->StartInputEventAckTimeout(TimeDelta::FromMilliseconds(20));
// Wait long enough for the second timeout and see if it fired.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMilliseconds(25));
- base::RunLoop().Run();
+ RunLoopFor(TimeDelta::FromMilliseconds(25));
EXPECT_TRUE(delegate_->unresponsive_timer_fired());
}
// Test that the hang monitor timer is effectively disabled when the widget is
// hidden.
-TEST_F(RenderWidgetHostTest, HangMonitorTimeoutDisabledForInputWhenHidden) {
+TEST_F(RenderWidgetHostTest, InputEventAckTimeoutDisabledForInputWhenHidden) {
host_->set_hung_renderer_delay(base::TimeDelta::FromMicroseconds(1));
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 10, 0, false);
@@ -1522,27 +1511,18 @@ TEST_F(RenderWidgetHostTest, HangMonitorTimeoutDisabledForInputWhenHidden) {
// The timeout should not fire.
EXPECT_FALSE(delegate_->unresponsive_timer_fired());
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMicroseconds(2));
- base::RunLoop().Run();
+ RunLoopFor(TimeDelta::FromMicroseconds(2));
EXPECT_FALSE(delegate_->unresponsive_timer_fired());
// The timeout should never reactivate while hidden.
SimulateMouseEvent(WebInputEvent::kMouseMove, 10, 10, 0, false);
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMicroseconds(2));
- base::RunLoop().Run();
+ RunLoopFor(TimeDelta::FromMicroseconds(2));
EXPECT_FALSE(delegate_->unresponsive_timer_fired());
// Showing the widget should restore the timeout, as the events have
// not yet been ack'ed.
- host_->WasShown(ui::LatencyInfo());
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMicroseconds(2));
- base::RunLoop().Run();
+ host_->WasShown(false /* record_presentation_time */);
+ RunLoopFor(TimeDelta::FromMicroseconds(2));
EXPECT_TRUE(delegate_->unresponsive_timer_fired());
}
@@ -1567,10 +1547,7 @@ TEST_F(RenderWidgetHostTest, MultipleInputEvents) {
dispatched_events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
// Wait long enough for first timeout and see if it fired.
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMicroseconds(20));
- base::RunLoop().Run();
+ RunLoopFor(TimeDelta::FromMicroseconds(20));
EXPECT_TRUE(delegate_->unresponsive_timer_fired());
}
@@ -1606,10 +1583,7 @@ TEST_F(RenderWidgetHostTest, NewContentRenderingTimeoutWithoutSurfaceSync) {
.Build();
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMicroseconds(20));
- base::RunLoop().Run();
+ RunLoopFor(TimeDelta::FromMicroseconds(20));
EXPECT_FALSE(host_->new_content_rendering_timeout_fired());
host_->reset_new_content_rendering_timeout_fired();
@@ -1623,10 +1597,7 @@ TEST_F(RenderWidgetHostTest, NewContentRenderingTimeoutWithoutSurfaceSync) {
.Build();
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMicroseconds(20));
- base::RunLoop().Run();
+ RunLoopFor(TimeDelta::FromMicroseconds(20));
EXPECT_TRUE(host_->new_content_rendering_timeout_fired());
host_->reset_new_content_rendering_timeout_fired();
@@ -1640,20 +1611,14 @@ TEST_F(RenderWidgetHostTest, NewContentRenderingTimeoutWithoutSurfaceSync) {
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
host_->DidNavigate(7);
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMicroseconds(20));
- base::RunLoop().Run();
+ RunLoopFor(TimeDelta::FromMicroseconds(20));
EXPECT_FALSE(host_->new_content_rendering_timeout_fired());
host_->reset_new_content_rendering_timeout_fired();
// Don't send any frames after the timer starts. The timer should fire.
host_->DidNavigate(20);
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- TimeDelta::FromMicroseconds(20));
- base::RunLoop().Run();
+ RunLoopFor(TimeDelta::FromMicroseconds(20));
EXPECT_TRUE(host_->new_content_rendering_timeout_fired());
host_->reset_new_content_rendering_timeout_fired();
}
@@ -1817,7 +1782,6 @@ TEST_F(RenderWidgetHostTest, InputRouterReceivesHasTouchEventHandlers) {
void CheckLatencyInfoComponentInMessage(
MockWidgetInputHandler::MessageVector& dispatched_events,
- int64_t component_id,
WebInputEvent::Type expected_type) {
ASSERT_EQ(1u, dispatched_events.size());
ASSERT_TRUE(dispatched_events[0]->ToEvent());
@@ -1826,13 +1790,12 @@ void CheckLatencyInfoComponentInMessage(
expected_type);
EXPECT_TRUE(
dispatched_events[0]->ToEvent()->Event()->latency_info.FindLatency(
- ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, component_id, nullptr));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
dispatched_events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
}
void CheckLatencyInfoComponentInGestureScrollUpdate(
- MockWidgetInputHandler::MessageVector& dispatched_events,
- int64_t component_id) {
+ MockWidgetInputHandler::MessageVector& dispatched_events) {
ASSERT_EQ(2u, dispatched_events.size());
ASSERT_TRUE(dispatched_events[0]->ToEvent());
ASSERT_TRUE(dispatched_events[1]->ToEvent());
@@ -1843,7 +1806,7 @@ void CheckLatencyInfoComponentInGestureScrollUpdate(
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));
+ ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr));
dispatched_events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
}
@@ -1851,30 +1814,29 @@ void CheckLatencyInfoComponentInGestureScrollUpdate(
// or ForwardXXXEventWithLatencyInfo(), LatencyInfo component
// ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT will always present in the
// event's LatencyInfo.
-void RenderWidgetHostTest::InputEventRWHLatencyComponent() {
+TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
// Tests RWHI::ForwardWheelEvent().
- SimulateWheelEventPossiblyIncludingPhase(-5, 0, 0, true,
- WebMouseWheelEvent::kPhaseBegan);
+ SimulateWheelEvent(-5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan);
MockWidgetInputHandler::MessageVector dispatched_events =
host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
- CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
+ CheckLatencyInfoComponentInMessage(dispatched_events,
WebInputEvent::kMouseWheel);
// Tests RWHI::ForwardWheelEventWithLatencyInfo().
- SimulateWheelEventWithLatencyInfoAndPossiblyPhase(
- -5, 0, 0, true, ui::LatencyInfo(), WebMouseWheelEvent::kPhaseChanged);
+ SimulateWheelEventWithLatencyInfo(-5, 0, 0, true, ui::LatencyInfo(),
+ WebMouseWheelEvent::kPhaseChanged);
dispatched_events =
host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
- CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
+ CheckLatencyInfoComponentInMessage(dispatched_events,
WebInputEvent::kMouseWheel);
// Tests RWHI::ForwardMouseEvent().
SimulateMouseEvent(WebInputEvent::kMouseMove);
dispatched_events =
host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
- CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
+ CheckLatencyInfoComponentInMessage(dispatched_events,
WebInputEvent::kMouseMove);
// Tests RWHI::ForwardMouseEventWithLatencyInfo().
@@ -1882,15 +1844,23 @@ void RenderWidgetHostTest::InputEventRWHLatencyComponent() {
ui::LatencyInfo());
dispatched_events =
host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
- CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
+ CheckLatencyInfoComponentInMessage(dispatched_events,
WebInputEvent::kMouseMove);
// Tests RWHI::ForwardGestureEvent().
+ PressTouchPoint(0, 1);
+ SendTouchEvent();
+ host_->input_router()->OnSetTouchAction(cc::kTouchActionAuto);
+ dispatched_events =
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
+ CheckLatencyInfoComponentInMessage(dispatched_events,
+ WebInputEvent::kTouchStart);
+
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
dispatched_events =
host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
- CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
+ CheckLatencyInfoComponentInMessage(dispatched_events,
WebInputEvent::kGestureScrollBegin);
// Tests RWHI::ForwardGestureEventWithLatencyInfo().
@@ -1899,28 +1869,21 @@ void RenderWidgetHostTest::InputEventRWHLatencyComponent() {
ui::LatencyInfo());
dispatched_events =
host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
- CheckLatencyInfoComponentInGestureScrollUpdate(dispatched_events,
- GetLatencyComponentId());
+ CheckLatencyInfoComponentInGestureScrollUpdate(dispatched_events);
+
+ ReleaseTouchPoint(0);
+ SendTouchEvent();
+ dispatched_events =
+ host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
// Tests RWHI::ForwardTouchEventWithLatencyInfo().
PressTouchPoint(0, 1);
SendTouchEvent();
dispatched_events =
host_->mock_widget_input_handler_.GetAndResetDispatchedMessages();
- CheckLatencyInfoComponentInMessage(dispatched_events, GetLatencyComponentId(),
+ CheckLatencyInfoComponentInMessage(dispatched_events,
WebInputEvent::kTouchStart);
}
-TEST_F(RenderWidgetHostTest, InputEventRWHLatencyComponent) {
- InputEventRWHLatencyComponent();
-}
-TEST_F(RenderWidgetHostWheelScrollLatchingDisabledTest,
- InputEventRWHLatencyComponent) {
- InputEventRWHLatencyComponent();
-}
-TEST_F(RenderWidgetHostAsyncWheelEventsEnabledTest,
- InputEventRWHLatencyComponent) {
- InputEventRWHLatencyComponent();
-}
TEST_F(RenderWidgetHostTest, RendererExitedResetsInputRouter) {
// RendererExited will delete the view.
@@ -1935,7 +1898,7 @@ TEST_F(RenderWidgetHostTest, RendererExitedResetsInputRouter) {
TEST_F(RenderWidgetHostTest, RendererExitedResetsIsHidden) {
// RendererExited will delete the view.
host_->SetView(new TestView(host_.get()));
- host_->WasShown(ui::LatencyInfo());
+ host_->WasShown(false /* record_presentation_time */);
ASSERT_FALSE(host_->is_hidden());
host_->RendererExited(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
@@ -2087,6 +2050,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_MessageThenFrame) {
auto frame = viz::CompositorFrameBuilder()
.AddDefaultRenderPass()
.SetFrameToken(frame_token)
+ .SetSendFrameTokenToEmbedder(true)
.Build();
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
@@ -2109,6 +2073,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_FrameThenMessage) {
auto frame = viz::CompositorFrameBuilder()
.AddDefaultRenderPass()
.SetFrameToken(frame_token)
+ .SetSendFrameTokenToEmbedder(true)
.Build();
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
@@ -2149,6 +2114,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_MultipleMessagesThenTokens) {
auto frame = viz::CompositorFrameBuilder()
.AddDefaultRenderPass()
.SetFrameToken(frame_token1)
+ .SetSendFrameTokenToEmbedder(true)
.Build();
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
@@ -2158,6 +2124,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_MultipleMessagesThenTokens) {
frame = viz::CompositorFrameBuilder()
.AddDefaultRenderPass()
.SetFrameToken(frame_token2)
+ .SetSendFrameTokenToEmbedder(true)
.Build();
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
@@ -2183,6 +2150,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_MultipleTokensThenMessages) {
auto frame = viz::CompositorFrameBuilder()
.AddDefaultRenderPass()
.SetFrameToken(frame_token1)
+ .SetSendFrameTokenToEmbedder(true)
.Build();
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
@@ -2192,6 +2160,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_MultipleTokensThenMessages) {
frame = viz::CompositorFrameBuilder()
.AddDefaultRenderPass()
.SetFrameToken(frame_token2)
+ .SetSendFrameTokenToEmbedder(true)
.Build();
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
@@ -2237,6 +2206,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_DroppedFrame) {
auto frame = viz::CompositorFrameBuilder()
.AddDefaultRenderPass()
.SetFrameToken(frame_token2)
+ .SetSendFrameTokenToEmbedder(true)
.Build();
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
@@ -2282,6 +2252,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_RendererCrash) {
auto frame = viz::CompositorFrameBuilder()
.AddDefaultRenderPass()
.SetFrameToken(frame_token2)
+ .SetSendFrameTokenToEmbedder(true)
.Build();
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
@@ -2302,6 +2273,7 @@ TEST_F(RenderWidgetHostTest, FrameToken_RendererCrash) {
frame = viz::CompositorFrameBuilder()
.AddDefaultRenderPass()
.SetFrameToken(frame_token3)
+ .SetSendFrameTokenToEmbedder(true)
.Build();
host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
base::nullopt, 0);
@@ -2366,20 +2338,20 @@ TEST_F(RenderWidgetHostTest, RenderWidgetSurfaceProperties) {
TEST_F(RenderWidgetHostTest, NavigateInBackgroundShowsBlank) {
// When visible, navigation does not immediately call into
// ClearDisplayedGraphics.
- host_->WasShown(ui::LatencyInfo());
+ host_->WasShown(false /* record_presentation_time */);
host_->DidNavigate(5);
EXPECT_FALSE(host_->new_content_rendering_timeout_fired());
// Hide then show. ClearDisplayedGraphics must be called.
host_->WasHidden();
- host_->WasShown(ui::LatencyInfo());
+ host_->WasShown(false /* record_presentation_time */);
EXPECT_TRUE(host_->new_content_rendering_timeout_fired());
host_->reset_new_content_rendering_timeout_fired();
// Hide, navigate, then show. ClearDisplayedGraphics must be called.
host_->WasHidden();
host_->DidNavigate(6);
- host_->WasShown(ui::LatencyInfo());
+ host_->WasShown(false /* record_presentation_time */);
EXPECT_TRUE(host_->new_content_rendering_timeout_fired());
}
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 c0cefeddd6b..f56a9746443 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
@@ -10,6 +10,7 @@
#include "base/android/build_info.h"
#include "base/bind.h"
+#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/logging.h"
@@ -26,6 +27,8 @@
#include "cc/trees/layer_tree_host.h"
#include "components/viz/common/features.h"
#include "components/viz/common/quads/compositor_frame.h"
+#include "components/viz/common/surfaces/frame_sink_id_allocator.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.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"
@@ -179,7 +182,6 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
stylus_text_selector_(this),
using_browser_compositor_(CompositorImpl::IsInitialized()),
synchronous_compositor_client_(nullptr),
- frame_evictor_(new viz::FrameEvictor(this)),
observing_root_window_(false),
prev_top_shown_pix_(0.f),
prev_top_controls_translate_(0.f),
@@ -198,7 +200,12 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
if (using_browser_compositor_) {
delegated_frame_host_ = std::make_unique<ui::DelegatedFrameHostAndroid>(
&view_, CompositorImpl::GetHostFrameSinkManager(), this,
- host()->GetFrameSinkId());
+ host()->GetFrameSinkId(), features::IsSurfaceSynchronizationEnabled());
+ if (is_showing_) {
+ delegated_frame_host_->WasShown(
+ local_surface_id_allocator_.GetCurrentLocalSurfaceId(),
+ GetCompositorViewportPixelSize());
+ }
// Let the page-level input event router know about our frame sink ID
// for surface-based hit testing.
@@ -223,7 +230,6 @@ RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
UpdateNativeViewTree(nullptr);
view_.set_event_handler(nullptr);
DCHECK(!ime_adapter_android_);
- DCHECK(ack_callbacks_.empty());
DCHECK(!delegated_frame_host_);
}
@@ -262,10 +268,20 @@ void RenderWidgetHostViewAndroid::InitAsFullscreen(
NOTIMPLEMENTED();
}
-bool RenderWidgetHostViewAndroid::SynchronizeVisualProperties() {
+bool RenderWidgetHostViewAndroid::SynchronizeVisualProperties(
+ const cc::DeadlinePolicy& deadline_policy,
+ const base::Optional<viz::LocalSurfaceId>&
+ child_allocated_local_surface_id) {
+ if (child_allocated_local_surface_id) {
+ local_surface_id_allocator_.UpdateFromChild(
+ *child_allocated_local_surface_id);
+ } else {
+ local_surface_id_allocator_.GenerateId();
+ }
if (delegated_frame_host_) {
- delegated_frame_host_->SynchronizeVisualProperties(
- GetCompositorViewportPixelSize());
+ delegated_frame_host_->EmbedSurface(
+ local_surface_id_allocator_.GetCurrentLocalSurfaceId(),
+ GetCompositorViewportPixelSize(), deadline_policy);
// TODO(ericrk): This can be removed once surface synchronization is
// enabled. https://crbug.com/835102
@@ -287,18 +303,16 @@ void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
}
bool RenderWidgetHostViewAndroid::HasValidFrame() const {
+ if (!delegated_frame_host_)
+ return false;
+
if (!view_.parent())
return false;
if (current_surface_size_.IsEmpty())
return false;
- // This tell us whether a valid frame has arrived or not.
- if (!frame_evictor_->HasFrame())
- return false;
- DCHECK(!delegated_frame_host_ ||
- delegated_frame_host_->HasDelegatedContent());
- return true;
+ return delegated_frame_host_->HasSavedFrame();
}
gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
@@ -321,6 +335,88 @@ void RenderWidgetHostViewAndroid::LostFocus() {
LostFocusInternal();
}
+void RenderWidgetHostViewAndroid::OnRenderFrameMetadataChangedBeforeActivation(
+ const cc::RenderFrameMetadata& metadata) {
+ if (!features::IsSurfaceSynchronizationEnabled())
+ return;
+
+ bool is_mobile_optimized = IsMobileOptimizedFrame(
+ metadata.page_scale_factor, metadata.min_page_scale_factor,
+ metadata.max_page_scale_factor, metadata.scrollable_viewport_size,
+ metadata.root_layer_size);
+
+ gesture_provider_.SetDoubleTapSupportForPageEnabled(!is_mobile_optimized);
+
+ float dip_scale = view_.GetDipScale();
+ gfx::SizeF root_layer_size_dip = metadata.root_layer_size;
+ gfx::SizeF scrollable_viewport_size_dip = metadata.scrollable_viewport_size;
+ gfx::Vector2dF root_scroll_offset_dip =
+ metadata.root_scroll_offset.value_or(gfx::Vector2dF());
+ if (IsUseZoomForDSFEnabled()) {
+ float pix_to_dip = 1 / dip_scale;
+ root_layer_size_dip.Scale(pix_to_dip);
+ scrollable_viewport_size_dip.Scale(pix_to_dip);
+ root_scroll_offset_dip.Scale(pix_to_dip);
+ }
+
+ float to_pix = IsUseZoomForDSFEnabled() ? 1.f : dip_scale;
+ // Note that the height of browser control is not affected by page scale
+ // factor. Thus, |top_content_offset| in CSS pixels is also in DIPs.
+ float top_content_offset =
+ metadata.top_controls_height * metadata.top_controls_shown_ratio;
+ float top_shown_pix = top_content_offset * to_pix;
+
+ if (ime_adapter_android_) {
+ ime_adapter_android_->UpdateFrameInfo(metadata.selection.start, dip_scale,
+ top_shown_pix);
+ }
+
+ auto* wcax = GetWebContentsAccessibilityAndroid();
+ if (wcax)
+ wcax->UpdateFrameInfo(metadata.page_scale_factor);
+
+ if (!gesture_listener_manager_)
+ return;
+
+ UpdateTouchSelectionController(metadata.selection, metadata.page_scale_factor,
+ metadata.top_controls_height,
+ metadata.top_controls_shown_ratio,
+ scrollable_viewport_size_dip);
+
+ // ViewAndroid::content_offset() must be in dip.
+ float top_content_offset_dip = IsUseZoomForDSFEnabled()
+ ? top_content_offset / dip_scale
+ : top_content_offset;
+ view_.UpdateFrameInfo({scrollable_viewport_size_dip, top_content_offset});
+ bool controls_changed = UpdateControls(
+ view_.GetDipScale(), metadata.top_controls_height,
+ metadata.top_controls_shown_ratio, metadata.bottom_controls_height,
+ metadata.bottom_controls_shown_ratio);
+
+ SetContentBackgroundColor(metadata.has_transparent_background
+ ? SK_ColorTRANSPARENT
+ : metadata.root_background_color);
+
+ if (overscroll_controller_) {
+ overscroll_controller_->OnFrameMetadataUpdated(
+ metadata.page_scale_factor, metadata.device_scale_factor,
+ metadata.scrollable_viewport_size, metadata.root_layer_size,
+ metadata.root_scroll_offset.value_or(gfx::Vector2dF()),
+ metadata.root_overflow_y_hidden);
+ }
+
+ // All offsets and sizes except |top_shown_pix| are in dip.
+ gesture_listener_manager_->UpdateScrollInfo(
+ root_scroll_offset_dip, metadata.page_scale_factor,
+ metadata.min_page_scale_factor, metadata.max_page_scale_factor,
+ root_layer_size_dip, scrollable_viewport_size_dip, top_content_offset_dip,
+ top_shown_pix, controls_changed);
+
+ page_scale_ = metadata.page_scale_factor;
+ min_page_scale_ = metadata.min_page_scale_factor;
+ max_page_scale_ = metadata.max_page_scale_factor;
+}
+
void RenderWidgetHostViewAndroid::Focus() {
if (view_.HasFocus())
GotFocus();
@@ -465,8 +561,7 @@ void RenderWidgetHostViewAndroid::OnUpdateTextInputStateCalled(
? *GetTextInputManager()->GetTextInputState()
: TextInputState();
- if (!ime_adapter_android_ || (is_in_vr_ && !base::FeatureList::IsEnabled(
- features::kVrWebInputEditing)))
+ if (!ime_adapter_android_)
return;
ime_adapter_android_->UpdateState(state);
@@ -502,11 +597,6 @@ void RenderWidgetHostViewAndroid::OnTextSelectionChanged(
RenderWidgetHostViewBase* updated_view) {
DCHECK_EQ(text_input_manager_, text_input_manager);
- // TODO(asimjour): remove the flag and fix text selection popup for
- // virtual reality mode.
- if (is_in_vr_)
- return;
-
if (!selection_popup_controller_)
return;
@@ -672,7 +762,7 @@ bool RenderWidgetHostViewAndroid::OnTouchEvent(
return false;
ui::LatencyInfo latency_info(ui::SourceEventType::TOUCH);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT);
if (ShouldRouteEvents()) {
host()->delegate()->GetInputEventRouter()->RouteTouchEvent(this, &web_event,
latency_info);
@@ -699,8 +789,7 @@ bool RenderWidgetHostViewAndroid::OnTouchHandleEvent(
int RenderWidgetHostViewAndroid::GetTouchHandleHeight() {
if (!touch_selection_controller_)
return 0;
- return static_cast<int>(
- touch_selection_controller_->GetStartHandleRect().height());
+ return static_cast<int>(touch_selection_controller_->GetTouchHandleHeight());
}
void RenderWidgetHostViewAndroid::ResetGestureDetection() {
@@ -717,7 +806,7 @@ void RenderWidgetHostViewAndroid::ResetGestureDetection() {
if (gesture_provider_.OnTouchEvent(*cancel_event).succeeded) {
bool causes_scrolling = false;
ui::LatencyInfo latency_info(ui::SourceEventType::TOUCH);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT);
blink::WebTouchEvent web_event = ui::CreateWebTouchEventFromMotionEvent(
*cancel_event, causes_scrolling /* may_cause_scrolling */,
false /* hovering */);
@@ -818,7 +907,8 @@ void RenderWidgetHostViewAndroid::CopyFromSurface(
void RenderWidgetHostViewAndroid::EnsureSurfaceSynchronizedForLayoutTest() {
++latest_capture_sequence_number_;
- SynchronizeVisualProperties();
+ SynchronizeVisualProperties(cc::DeadlinePolicy::UseInfiniteDeadline(),
+ base::nullopt);
}
uint32_t RenderWidgetHostViewAndroid::GetCaptureSequenceNumber() const {
@@ -849,48 +939,22 @@ bool RenderWidgetHostViewAndroid::ShouldRouteEvents() const {
host()->delegate()->GetInputEventRouter();
}
-void RenderWidgetHostViewAndroid::SendReclaimCompositorResources(
- bool is_swap_ack) {
- DCHECK(host());
- if (is_swap_ack) {
- renderer_compositor_frame_sink_->DidReceiveCompositorFrameAck(
- surface_returned_resources_);
- } else {
- renderer_compositor_frame_sink_->ReclaimResources(
- surface_returned_resources_);
- }
- surface_returned_resources_.clear();
-}
-
-void RenderWidgetHostViewAndroid::DidReceiveCompositorFrameAck() {
- RunAckCallbacks();
+void RenderWidgetHostViewAndroid::DidReceiveCompositorFrameAck(
+ const std::vector<viz::ReturnedResource>& resources) {
+ renderer_compositor_frame_sink_->DidReceiveCompositorFrameAck(resources);
}
void RenderWidgetHostViewAndroid::DidPresentCompositorFrame(
uint32_t presentation_token,
- base::TimeTicks time,
- base::TimeDelta refresh,
- uint32_t flags) {
- DCHECK(using_browser_compositor_);
- renderer_compositor_frame_sink_->DidPresentCompositorFrame(
- presentation_token, time, refresh, flags);
-}
-
-void RenderWidgetHostViewAndroid::DidDiscardCompositorFrame(
- uint32_t presentation_token) {
+ const gfx::PresentationFeedback& feedback) {
DCHECK(using_browser_compositor_);
- renderer_compositor_frame_sink_->DidDiscardCompositorFrame(
- presentation_token);
+ renderer_compositor_frame_sink_->DidPresentCompositorFrame(presentation_token,
+ feedback);
}
void RenderWidgetHostViewAndroid::ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) {
- if (resources.empty())
- return;
- std::copy(resources.begin(), resources.end(),
- std::back_inserter(surface_returned_resources_));
- if (ack_callbacks_.empty())
- SendReclaimCompositorResources(false /* is_swap_ack */);
+ renderer_compositor_frame_sink_->ReclaimResources(resources);
}
void RenderWidgetHostViewAndroid::OnFrameTokenChanged(uint32_t frame_token) {
@@ -913,9 +977,6 @@ void RenderWidgetHostViewAndroid::DidCreateNewRendererCompositorFrameSink(
}
delegated_frame_host_->CompositorFrameSinkChanged();
renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
- // Accumulated resources belong to the old RendererCompositorFrameSink and
- // should not be returned.
- surface_returned_resources_.clear();
}
void RenderWidgetHostViewAndroid::EvictFrameIfNecessary() {
@@ -954,50 +1015,14 @@ void RenderWidgetHostViewAndroid::SubmitCompositorFrame(
viz::CompositorFrameMetadata metadata = frame.metadata.Clone();
- bool has_content = !current_surface_size_.IsEmpty();
-
- base::Closure ack_callback =
- base::Bind(&RenderWidgetHostViewAndroid::SendReclaimCompositorResources,
- weak_ptr_factory_.GetWeakPtr(), true /* is_swap_ack */);
-
- ack_callbacks_.push(ack_callback);
-
- viz::BeginFrameAck ack = frame.metadata.begin_frame_ack;
- if (!has_content) {
- DestroyDelegatedContent();
-
- ack.has_damage = false;
- OnDidNotProduceFrame(ack);
- } else {
- delegated_frame_host_->SubmitCompositorFrame(
- local_surface_id, std::move(frame), std::move(hit_test_region_list));
- frame_evictor_->SwappedFrame(!host()->is_hidden());
- AcknowledgeBeginFrame(ack);
- }
-
- if (host()->is_hidden())
- RunAckCallbacks();
+ delegated_frame_host_->SubmitCompositorFrame(
+ local_surface_id, std::move(frame), std::move(hit_test_region_list));
// As the metadata update may trigger view invalidation, always call it after
// any potential compositor scheduling.
OnFrameMetadataUpdated(std::move(metadata), is_transparent);
}
-void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
- if (!delegated_frame_host_)
- return;
-
- DCHECK(delegated_frame_host_->HasDelegatedContent() ==
- frame_evictor_->HasFrame());
-
- delegated_frame_host_->DestroyDelegatedContent();
-
- if (frame_evictor_->HasFrame())
- frame_evictor_->DiscardedFrame();
-
- current_surface_size_.SetSize(0, 0);
-}
-
void RenderWidgetHostViewAndroid::OnDidNotProduceFrame(
const viz::BeginFrameAck& ack) {
if (!delegated_frame_host_) {
@@ -1008,48 +1033,43 @@ void RenderWidgetHostViewAndroid::OnDidNotProduceFrame(
}
delegated_frame_host_->DidNotProduceFrame(ack);
- AcknowledgeBeginFrame(ack);
-}
-
-void RenderWidgetHostViewAndroid::AcknowledgeBeginFrame(
- const viz::BeginFrameAck& ack) {
- // AcknowledgeBeginFrame is not called for the synchronous compositor path.
- if (begin_frame_source_)
- begin_frame_source_->DidFinishFrame(this);
}
void RenderWidgetHostViewAndroid::ClearCompositorFrame() {
- DestroyDelegatedContent();
+ EvictDelegatedFrame();
}
bool RenderWidgetHostViewAndroid::RequestRepaintForTesting() {
- return SynchronizeVisualProperties();
+ return SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
+ base::nullopt);
}
void RenderWidgetHostViewAndroid::SynchronousFrameMetadata(
- viz::CompositorFrameMetadata frame_metadata) {
+ viz::CompositorFrameMetadata metadata) {
if (!view_.parent())
return;
- bool is_mobile_optimized = IsMobileOptimizedFrame(frame_metadata);
+ bool is_mobile_optimized = IsMobileOptimizedFrame(
+ metadata.page_scale_factor, metadata.min_page_scale_factor,
+ metadata.max_page_scale_factor, metadata.scrollable_viewport_size,
+ metadata.root_layer_size);
if (host() && host()->input_router()) {
host()->input_router()->NotifySiteIsMobileOptimized(is_mobile_optimized);
}
- if (host() && frame_metadata.frame_token)
- host()->DidProcessFrame(frame_metadata.frame_token);
+ if (host() && metadata.frame_token)
+ host()->DidProcessFrame(metadata.frame_token);
// This is a subset of OnSwapCompositorFrame() used in the synchronous
// compositor flow.
- OnFrameMetadataUpdated(frame_metadata.Clone(), false);
+ OnFrameMetadataUpdated(metadata.Clone(), false);
// DevTools ScreenCast support for Android WebView.
RenderFrameHost* frame_host = RenderViewHost::From(host())->GetMainFrame();
if (frame_host) {
RenderFrameDevToolsAgentHost::SignalSynchronousSwapCompositorFrame(
- frame_host,
- std::move(frame_metadata));
+ frame_host, std::move(metadata));
}
}
@@ -1195,16 +1215,22 @@ RenderWidgetHostViewAndroid::GetWebContentsAccessibilityAndroid() const {
}
void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
- const viz::CompositorFrameMetadata& frame_metadata,
+ const viz::CompositorFrameMetadata& metadata,
bool is_transparent) {
- bool is_mobile_optimized = IsMobileOptimizedFrame(frame_metadata);
+ if (features::IsSurfaceSynchronizationEnabled())
+ return;
+
+ bool is_mobile_optimized = IsMobileOptimizedFrame(
+ metadata.page_scale_factor, metadata.min_page_scale_factor,
+ metadata.max_page_scale_factor, metadata.scrollable_viewport_size,
+ metadata.root_layer_size);
+
gesture_provider_.SetDoubleTapSupportForPageEnabled(!is_mobile_optimized);
float dip_scale = view_.GetDipScale();
- gfx::SizeF root_layer_size_dip = frame_metadata.root_layer_size;
- gfx::SizeF scrollable_viewport_size_dip =
- frame_metadata.scrollable_viewport_size;
- gfx::Vector2dF root_scroll_offset_dip = frame_metadata.root_scroll_offset;
+ gfx::SizeF root_layer_size_dip = metadata.root_layer_size;
+ gfx::SizeF scrollable_viewport_size_dip = metadata.scrollable_viewport_size;
+ gfx::Vector2dF root_scroll_offset_dip = metadata.root_scroll_offset;
if (IsUseZoomForDSFEnabled()) {
float pix_to_dip = 1 / dip_scale;
root_layer_size_dip.Scale(pix_to_dip);
@@ -1215,76 +1241,83 @@ void RenderWidgetHostViewAndroid::OnFrameMetadataUpdated(
float to_pix = IsUseZoomForDSFEnabled() ? 1.f : dip_scale;
// Note that the height of browser control is not affected by page scale
// factor. Thus, |top_content_offset| in CSS pixels is also in DIPs.
- float top_content_offset = frame_metadata.top_controls_height *
- frame_metadata.top_controls_shown_ratio;
+ float top_content_offset =
+ metadata.top_controls_height * metadata.top_controls_shown_ratio;
float top_shown_pix = top_content_offset * to_pix;
- if (ime_adapter_android_)
- ime_adapter_android_->UpdateFrameInfo(frame_metadata.selection.start,
- dip_scale, top_shown_pix);
+ if (ime_adapter_android_) {
+ ime_adapter_android_->UpdateFrameInfo(metadata.selection.start, dip_scale,
+ top_shown_pix);
+ }
auto* wcax = GetWebContentsAccessibilityAndroid();
if (wcax)
- wcax->UpdateFrameInfo(frame_metadata.page_scale_factor);
+ wcax->UpdateFrameInfo(metadata.page_scale_factor);
if (!gesture_listener_manager_)
return;
- if (overscroll_controller_)
- overscroll_controller_->OnFrameMetadataUpdated(frame_metadata);
-
- if (touch_selection_controller_) {
- DCHECK(touch_selection_controller_client_manager_);
- touch_selection_controller_client_manager_->UpdateClientSelectionBounds(
- frame_metadata.selection.start, frame_metadata.selection.end, this,
- nullptr);
- touch_selection_controller_client_manager_->SetPageScaleFactor(
- frame_metadata.page_scale_factor);
-
- // Set parameters for adaptive handle orientation.
- gfx::SizeF viewport_size(scrollable_viewport_size_dip);
- viewport_size.Scale(frame_metadata.page_scale_factor);
- gfx::RectF viewport_rect(0.0f, frame_metadata.top_controls_height *
- frame_metadata.top_controls_shown_ratio,
- viewport_size.width(), viewport_size.height());
- touch_selection_controller_->OnViewportChanged(viewport_rect);
- }
-
- SetContentBackgroundColor(is_transparent
- ? SK_ColorTRANSPARENT
- : frame_metadata.root_background_color);
+ if (overscroll_controller_) {
+ overscroll_controller_->OnFrameMetadataUpdated(
+ metadata.page_scale_factor, metadata.device_scale_factor,
+ metadata.scrollable_viewport_size, metadata.root_layer_size,
+ metadata.root_scroll_offset, metadata.root_overflow_y_hidden);
+ }
- // ViewAndroid::content_offset() must be in CSS scale
+ UpdateTouchSelectionController(metadata.selection, metadata.page_scale_factor,
+ metadata.top_controls_height,
+ metadata.top_controls_shown_ratio,
+ scrollable_viewport_size_dip);
+ // ViewAndroid::content_offset() must be in dip
float top_content_offset_dip = IsUseZoomForDSFEnabled()
? top_content_offset / dip_scale
: top_content_offset;
- view_.UpdateFrameInfo({scrollable_viewport_size_dip, top_content_offset});
- bool controls_changed =
- features::IsSurfaceSynchronizationEnabled()
- ? false
- : UpdateControls(view_.GetDipScale(),
- frame_metadata.top_controls_height,
- frame_metadata.top_controls_shown_ratio,
- frame_metadata.bottom_controls_height,
- frame_metadata.bottom_controls_shown_ratio);
-
- 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.
- // TODO(fsamuel): This needs to be synchronized with RenderFrameMetadata when
- // surface synchronization is enabled.
+ view_.UpdateFrameInfo({scrollable_viewport_size_dip, top_content_offset_dip});
+ bool controls_changed = UpdateControls(
+ view_.GetDipScale(), metadata.top_controls_height,
+ metadata.top_controls_shown_ratio, metadata.bottom_controls_height,
+ metadata.bottom_controls_shown_ratio);
+
+ // All offsets and sizes except |top_shown_pix| are in dip.
gesture_listener_manager_->UpdateScrollInfo(
- root_scroll_offset_dip, frame_metadata.page_scale_factor,
- frame_metadata.min_page_scale_factor,
- frame_metadata.max_page_scale_factor, root_layer_size_dip,
- scrollable_viewport_size_dip, top_content_offset_dip, top_shown_pix,
- controls_changed);
+ root_scroll_offset_dip, metadata.page_scale_factor,
+ metadata.min_page_scale_factor, metadata.max_page_scale_factor,
+ root_layer_size_dip, scrollable_viewport_size_dip, top_content_offset_dip,
+ top_shown_pix, controls_changed);
+
+ SetContentBackgroundColor(is_transparent ? SK_ColorTRANSPARENT
+ : metadata.root_background_color);
+
+ page_scale_ = metadata.page_scale_factor;
+ min_page_scale_ = metadata.min_page_scale_factor;
+ max_page_scale_ = metadata.max_page_scale_factor;
EvictFrameIfNecessary();
}
+void RenderWidgetHostViewAndroid::UpdateTouchSelectionController(
+ const viz::Selection<gfx::SelectionBound>& selection,
+ float page_scale_factor,
+ float top_controls_height,
+ float top_controls_shown_ratio,
+ const gfx::SizeF& scrollable_viewport_size_dip) {
+ if (!touch_selection_controller_)
+ return;
+
+ DCHECK(touch_selection_controller_client_manager_);
+ touch_selection_controller_client_manager_->UpdateClientSelectionBounds(
+ selection.start, selection.end, this, nullptr);
+ touch_selection_controller_client_manager_->SetPageScaleFactor(
+ page_scale_factor);
+
+ // Set parameters for adaptive handle orientation.
+ gfx::SizeF viewport_size(scrollable_viewport_size_dip);
+ viewport_size.Scale(page_scale_factor);
+ gfx::RectF viewport_rect(0.0f, top_controls_height * top_controls_shown_ratio,
+ viewport_size.width(), viewport_size.height());
+ touch_selection_controller_->OnViewportChanged(viewport_rect);
+}
+
bool RenderWidgetHostViewAndroid::UpdateControls(
float dip_scale,
float top_controls_height,
@@ -1322,16 +1355,8 @@ bool RenderWidgetHostViewAndroid::UpdateControls(
void RenderWidgetHostViewAndroid::OnDidUpdateVisualPropertiesComplete(
const cc::RenderFrameMetadata& metadata) {
- if (delegated_frame_host_->GetLocalSurfaceIdAllocator()->UpdateFromChild(
- metadata.local_surface_id.value_or(viz::LocalSurfaceId()))) {
- // A synchronization event was initiated by the renderer so let's updated
- // the top/bottom bar controls now.
- UpdateControls(view_.GetDipScale(), metadata.top_controls_height,
- metadata.top_controls_shown_ratio,
- metadata.bottom_controls_height,
- metadata.bottom_controls_shown_ratio);
- }
- host()->SynchronizeVisualProperties();
+ SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
+ metadata.local_surface_id);
}
void RenderWidgetHostViewAndroid::ShowInternal() {
@@ -1344,12 +1369,29 @@ void RenderWidgetHostViewAndroid::ShowInternal() {
view_.GetLayer()->SetHideLayerAndSubtree(false);
- frame_evictor_->SetVisible(true);
-
if (overscroll_controller_)
overscroll_controller_->Enable();
- host()->WasShown(ui::LatencyInfo());
+ if (delegated_frame_host_ &&
+ delegated_frame_host_->IsPrimarySurfaceEvicted()) {
+ ui::WindowAndroidCompositor* compositor =
+ view_.GetWindowAndroid() ? view_.GetWindowAndroid()->GetCompositor()
+ : nullptr;
+ SynchronizeVisualProperties(
+ compositor && compositor->IsDrawingFirstVisibleFrame()
+ ? cc::DeadlinePolicy::UseSpecifiedDeadline(
+ ui::DelegatedFrameHostAndroid::FirstFrameTimeoutFrames())
+ : cc::DeadlinePolicy::UseDefaultDeadline(),
+ base::nullopt);
+ }
+
+ host()->WasShown(false /* record_presentation_time */);
+
+ if (delegated_frame_host_) {
+ delegated_frame_host_->WasShown(
+ local_surface_id_allocator_.GetCurrentLocalSurfaceId(),
+ GetCompositorViewportPixelSize());
+ }
if (view_.parent() && view_.GetWindowAndroid()) {
StartObservingRootWindow();
@@ -1373,7 +1415,8 @@ void RenderWidgetHostViewAndroid::HideInternal() {
if (hide_frontbuffer) {
view_.GetLayer()->SetHideLayerAndSubtree(true);
- frame_evictor_->SetVisible(false);
+ if (delegated_frame_host_)
+ delegated_frame_host_->WasHidden();
}
if (stop_observing_root_window) {
@@ -1387,8 +1430,6 @@ void RenderWidgetHostViewAndroid::HideInternal() {
if (overscroll_controller_)
overscroll_controller_->Disable();
- RunAckCallbacks();
-
// Inform the renderer that we are being hidden so it can reduce its resource
// utilization.
host()->WasHidden();
@@ -1509,10 +1550,6 @@ void RenderWidgetHostViewAndroid::RequestDisallowInterceptTouchEvent() {
view_.RequestDisallowInterceptTouchEvent();
}
-void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
- DestroyDelegatedContent();
-}
-
void RenderWidgetHostViewAndroid::TransformPointToRootSurface(
gfx::PointF* point) {
*point += gfx::Vector2d(
@@ -1548,6 +1585,8 @@ void RenderWidgetHostViewAndroid::GestureEventAck(
overscroll_controller_->OnGestureEventAck(event, ack_result);
mouse_wheel_phase_handler_.GestureEventAck(event, ack_result);
+ ForwardTouchpadPinchIfNecessary(event, ack_result);
+
if (!gesture_listener_manager_)
return;
gesture_listener_manager_->GestureEventAck(event, ack_result);
@@ -1650,7 +1689,7 @@ void RenderWidgetHostViewAndroid::SendKeyEvent(
event.GetType() == blink::WebInputEvent::kChar) {
latency_info.set_source_event_type(ui::SourceEventType::KEY_PRESS);
}
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT);
target_host->ForwardKeyboardEventWithLatencyInfo(event, latency_info);
}
@@ -1718,13 +1757,12 @@ void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
return;
ui::LatencyInfo latency_info(ui::SourceEventType::WHEEL);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT);
blink::WebMouseWheelEvent wheel_event(event);
bool should_route_events = ShouldRouteEvents();
- if (wheel_scroll_latching_enabled()) {
- mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
- wheel_event, should_route_events);
- }
+ mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
+ wheel_event, should_route_events);
+
if (should_route_events) {
host()->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(
this, &wheel_event, latency_info);
@@ -1771,28 +1809,26 @@ void RenderWidgetHostViewAndroid::SendGestureEvent(
ui::LatencyInfo latency_info =
ui::WebInputEventTraits::CreateLatencyInfoForWebGestureEvent(event);
- if (wheel_scroll_latching_enabled()) {
- if (event.SourceDevice() ==
- blink::WebGestureDevice::kWebGestureDeviceTouchscreen) {
- if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
- // If there is a current scroll going on and a new scroll that isn't
- // wheel based, send a synthetic wheel event with kPhaseEnded to cancel
- // the current scroll.
- mouse_wheel_phase_handler_.DispatchPendingWheelEndEvent();
- } else if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd) {
- // 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();
- }
-
- } else if (event.GetType() == blink::WebInputEvent::kGestureFlingStart &&
- event.SourceDevice() ==
- blink::WebGestureDevice::kWebGestureDeviceTouchpad) {
- // Ignore the pending wheel end event to avoid sending a wheel event with
- // kPhaseEnded before a GFS.
+ if (event.SourceDevice() ==
+ blink::WebGestureDevice::kWebGestureDeviceTouchscreen) {
+ if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
+ // If there is a current scroll going on and a new scroll that isn't
+ // wheel based, send a synthetic wheel event with kPhaseEnded to cancel
+ // the current scroll.
+ mouse_wheel_phase_handler_.DispatchPendingWheelEndEvent();
+ } else if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd) {
+ // 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();
}
+
+ } else if (event.GetType() == blink::WebInputEvent::kGestureFlingStart &&
+ event.SourceDevice() ==
+ blink::WebGestureDevice::kWebGestureDeviceTouchpad) {
+ // Ignore the pending wheel end event to avoid sending a wheel event with
+ // kPhaseEnded before a GFS.
+ mouse_wheel_phase_handler_.IgnorePendingWheelEndEvent();
}
if (ShouldRouteEvents()) {
blink::WebGestureEvent gesture_event(event);
@@ -1846,8 +1882,7 @@ void RenderWidgetHostViewAndroid::SetTextHandlesTemporarilyHidden(
handles_hidden_by_selection_ui_ == hide_handles)
return;
handles_hidden_by_selection_ui_ = hide_handles;
- touch_selection_controller_->SetTemporarilyHidden(
- handles_hidden_by_selection_ui_ || handles_hidden_by_stylus_);
+ SetTextHandlesHiddenInternal();
}
base::Optional<SkColor> RenderWidgetHostViewAndroid::GetCachedBackgroundColor()
@@ -1856,14 +1891,15 @@ base::Optional<SkColor> RenderWidgetHostViewAndroid::GetCachedBackgroundColor()
}
void RenderWidgetHostViewAndroid::SetIsInVR(bool is_in_vr) {
+ if (is_in_vr_ == is_in_vr)
+ return;
is_in_vr_ = is_in_vr;
- // TODO(crbug.com/779126): support touch selection handles in VR.
- if (is_in_vr) {
- touch_selection_controller_.reset();
- } else if (view_.parent()) {
- touch_selection_controller_ = CreateSelectionController(
- touch_selection_controller_client_manager_.get(), view_.parent());
- }
+ // TODO(crbug.com/851054): support touch selection handles in VR.
+ SetTextHandlesHiddenInternal();
+
+ gesture_provider_.UpdateConfig(ui::GetGestureProviderConfig(
+ is_in_vr_ ? ui::GestureProviderConfigType::CURRENT_PLATFORM_VR
+ : ui::GestureProviderConfigType::CURRENT_PLATFORM));
if (is_in_vr_ && controls_initialized_) {
// TODO(mthiesse, https://crbug.com/825765): See the TODO in
@@ -1899,9 +1935,9 @@ void RenderWidgetHostViewAndroid::DidStopFlinging() {
gesture_listener_manager_->DidStopFlinging();
}
-viz::FrameSinkId RenderWidgetHostViewAndroid::GetFrameSinkId() {
+const viz::FrameSinkId& RenderWidgetHostViewAndroid::GetFrameSinkId() const {
if (!delegated_frame_host_)
- return viz::FrameSinkId();
+ return viz::FrameSinkIdAllocator::InvalidFrameSinkId();
return delegated_frame_host_->GetFrameSinkId();
}
@@ -1920,7 +1956,6 @@ void RenderWidgetHostViewAndroid::UpdateNativeViewTree(
bool resize = false;
if (will_build_tree != has_view_tree) {
touch_selection_controller_.reset();
- RunAckCallbacks();
if (has_view_tree) {
view_.RemoveObserver(this);
view_.RemoveFromParent();
@@ -1950,8 +1985,12 @@ void RenderWidgetHostViewAndroid::UpdateNativeViewTree(
if (is_showing_ && view_.GetWindowAndroid())
StartObservingRootWindow();
- if (resize)
- SynchronizeVisualProperties();
+ if (resize) {
+ SynchronizeVisualProperties(
+ cc::DeadlinePolicy::UseSpecifiedDeadline(
+ ui::DelegatedFrameHostAndroid::ResizeTimeoutFrames()),
+ base::nullopt);
+ }
if (!touch_selection_controller_) {
ui::TouchSelectionControllerClient* client =
@@ -1970,11 +2009,12 @@ RenderWidgetHostViewAndroid::GetMouseWheelPhaseHandler() {
return &mouse_wheel_phase_handler_;
}
-void RenderWidgetHostViewAndroid::RunAckCallbacks() {
- while (!ack_callbacks_.empty()) {
- ack_callbacks_.front().Run();
- ack_callbacks_.pop();
- }
+void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
+ if (!delegated_frame_host_)
+ return;
+
+ delegated_frame_host_->EvictDelegatedFrame();
+ current_surface_size_.SetSize(0, 0);
}
TouchSelectionControllerClientManager*
@@ -1982,10 +2022,11 @@ RenderWidgetHostViewAndroid::GetTouchSelectionControllerClientManager() {
return touch_selection_controller_client_manager_.get();
}
-viz::LocalSurfaceId RenderWidgetHostViewAndroid::GetLocalSurfaceId() const {
- if (delegated_frame_host_)
- return delegated_frame_host_->GetLocalSurfaceId();
- return viz::LocalSurfaceId();
+const viz::LocalSurfaceId& RenderWidgetHostViewAndroid::GetLocalSurfaceId()
+ const {
+ if (!delegated_frame_host_)
+ return viz::ParentLocalSurfaceIdAllocator::InvalidLocalSurfaceId();
+ return local_surface_id_allocator_.GetCurrentLocalSurfaceId();
}
void RenderWidgetHostViewAndroid::OnRenderWidgetInit() {
@@ -2028,6 +2069,10 @@ void RenderWidgetHostViewAndroid::OnGestureEvent(
SendGestureEvent(web_gesture);
}
+bool RenderWidgetHostViewAndroid::RequiresDoubleTapGestureEvents() const {
+ return true;
+}
+
void RenderWidgetHostViewAndroid::OnSizeChanged() {
if (ime_adapter_android_)
ime_adapter_android_->UpdateAfterViewSizeChanged();
@@ -2037,7 +2082,10 @@ void RenderWidgetHostViewAndroid::OnSizeChanged() {
void RenderWidgetHostViewAndroid::OnPhysicalBackingSizeChanged() {
EvictFrameIfNecessary();
- SynchronizeVisualProperties();
+ SynchronizeVisualProperties(
+ cc::DeadlinePolicy::UseSpecifiedDeadline(
+ ui::DelegatedFrameHostAndroid::ResizeTimeoutFrames()),
+ base::nullopt);
}
void RenderWidgetHostViewAndroid::OnRootWindowVisibilityChanged(bool visible) {
@@ -2084,7 +2132,6 @@ void RenderWidgetHostViewAndroid::OnAttachCompositor() {
void RenderWidgetHostViewAndroid::OnDetachCompositor() {
DCHECK(view_.parent());
- RunAckCallbacks();
overscroll_controller_.reset();
if (using_browser_compositor_)
delegated_frame_host_->DetachFromCompositor();
@@ -2180,8 +2227,7 @@ void RenderWidgetHostViewAndroid::OnActivityStarted() {
}
void RenderWidgetHostViewAndroid::OnLostResources() {
- DestroyDelegatedContent();
- DCHECK(ack_callbacks_.empty());
+ EvictDelegatedFrame();
}
void RenderWidgetHostViewAndroid::SetTextHandlesHiddenForStylus(
@@ -2189,8 +2235,16 @@ void RenderWidgetHostViewAndroid::SetTextHandlesHiddenForStylus(
if (!touch_selection_controller_ || handles_hidden_by_stylus_ == hide_handles)
return;
handles_hidden_by_stylus_ = hide_handles;
+ SetTextHandlesHiddenInternal();
+}
+
+void RenderWidgetHostViewAndroid::SetTextHandlesHiddenInternal() {
+ if (!touch_selection_controller_)
+ return;
+ // TODO(crbug.com/851054): support touch selection handles in VR.
touch_selection_controller_->SetTemporarilyHidden(
- handles_hidden_by_stylus_ || handles_hidden_by_selection_ui_);
+ is_in_vr_ || handles_hidden_by_stylus_ ||
+ handles_hidden_by_selection_ui_);
}
void RenderWidgetHostViewAndroid::OnStylusSelectBegin(float x0,
@@ -2316,7 +2370,8 @@ void RenderWidgetHostViewAndroid::TakeFallbackContentFrom(
}
void RenderWidgetHostViewAndroid::OnSynchronizedDisplayPropertiesChanged() {
- SynchronizeVisualProperties();
+ SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
+ base::nullopt);
}
base::Optional<SkColor> RenderWidgetHostViewAndroid::GetBackgroundColor()
@@ -2325,10 +2380,21 @@ base::Optional<SkColor> RenderWidgetHostViewAndroid::GetBackgroundColor()
}
void RenderWidgetHostViewAndroid::DidNavigate() {
- RenderWidgetHostViewBase::DidNavigate();
+ if (!delegated_frame_host_) {
+ RenderWidgetHostViewBase::DidNavigate();
+ return;
+ }
- if (delegated_frame_host_)
- delegated_frame_host_->DidNavigate();
+ if (is_first_navigation_) {
+ SynchronizeVisualProperties(
+ cc::DeadlinePolicy::UseExistingDeadline(),
+ local_surface_id_allocator_.GetCurrentLocalSurfaceId());
+ } else {
+ SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
+ base::nullopt);
+ }
+ delegated_frame_host_->DidNavigate();
+ is_first_navigation_ = false;
}
viz::ScopedSurfaceIdAllocator
@@ -2341,7 +2407,6 @@ RenderWidgetHostViewAndroid::DidUpdateVisualProperties(
&RenderWidgetHostViewAndroid::OnDidUpdateVisualPropertiesComplete,
weak_ptr_factory_.GetWeakPtr(), metadata);
return viz::ScopedSurfaceIdAllocator(std::move(allocation_task));
- ;
}
} // namespace content
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 87b3d601b77..ae59220401e 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
@@ -18,10 +18,10 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process.h"
-#include "components/viz/client/frame_evictor.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/quads/selection.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"
#include "content/browser/renderer_host/input/stylus_text_selector.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
@@ -73,8 +73,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
public ui::TouchSelectionControllerClient,
public ui::ViewAndroidObserver,
public ui::WindowAndroidObserver,
- public viz::BeginFrameObserver,
- public viz::FrameEvictorClient {
+ public viz::BeginFrameObserver {
public:
RenderWidgetHostViewAndroid(RenderWidgetHostImpl* widget,
gfx::NativeView parent_native_view);
@@ -170,7 +169,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void OnDidNavigateMainFrameToNewPage() override;
void SetNeedsBeginFrames(bool needs_begin_frames) override;
void SetWantsAnimateOnlyBeginFrames() override;
- viz::FrameSinkId GetFrameSinkId() override;
+ const viz::FrameSinkId& GetFrameSinkId() const override;
bool TransformPointToLocalCoordSpaceLegacy(
const gfx::PointF& point,
const viz::SurfaceId& original_surface,
@@ -184,7 +183,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
viz::EventSource source = viz::EventSource::ANY) override;
TouchSelectionControllerClientManager*
GetTouchSelectionControllerClientManager() override;
- viz::LocalSurfaceId GetLocalSurfaceId() const override;
+ const viz::LocalSurfaceId& GetLocalSurfaceId() const override;
void OnRenderWidgetInit() override;
void TakeFallbackContentFrom(RenderWidgetHostView* view) override;
void OnSynchronizedDisplayPropertiesChanged() override;
@@ -207,6 +206,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
// ui::GestureProviderClient implementation.
void OnGestureEvent(const ui::GestureEventData& gesture) override;
+ bool RequiresDoubleTapGestureEvents() const override;
// ui::WindowAndroidObserver implementation.
void OnCompositingDidCommit() override {}
@@ -217,9 +217,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void OnActivityStopped() override;
void OnActivityStarted() override;
- // viz::FrameEvictor implementation
- void EvictDelegatedFrame() override;
-
// StylusTextSelectorClient implementation.
void OnStylusSelectBegin(float x0, float y0, float x1, float y1) override;
void OnStylusSelectUpdate(float x, float y) override;
@@ -240,12 +237,11 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
// DelegatedFrameHostAndroid::Client implementation.
void SetBeginFrameSource(viz::BeginFrameSource* begin_frame_source) override;
- void DidReceiveCompositorFrameAck() 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 DidPresentCompositorFrame(
+ uint32_t presentation_token,
+ const gfx::PresentationFeedback& feedback) override;
+ void DidReceiveCompositorFrameAck(
+ const std::vector<viz::ReturnedResource>& resources) override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
void OnFrameTokenChanged(uint32_t frame_token) override;
@@ -296,7 +292,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void SetDoubleTapSupportEnabled(bool enabled);
void SetMultiTouchZoomSupportEnabled(bool enabled);
- bool SynchronizeVisualProperties();
+ bool SynchronizeVisualProperties(const cc::DeadlinePolicy& deadline_policy,
+ const base::Optional<viz::LocalSurfaceId>&
+ child_allocated_local_surface_id);
bool HasValidFrame() const;
@@ -343,6 +341,10 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void GotFocus();
void LostFocus();
+ // RenderFrameMetadataProvider::Observer
+ void OnRenderFrameMetadataChangedBeforeActivation(
+ const cc::RenderFrameMetadata& metadata) override;
+
protected:
// RenderWidgetHostViewBase:
void UpdateBackgroundColor() override;
@@ -350,15 +352,20 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
private:
MouseWheelPhaseHandler* GetMouseWheelPhaseHandler() override;
- void RunAckCallbacks();
+ void EvictDelegatedFrame();
bool ShouldRouteEvents() const;
- void SendReclaimCompositorResources(bool is_swap_ack);
void OnFrameMetadataUpdated(
const viz::CompositorFrameMetadata& frame_metadata,
bool is_transparent);
+ void UpdateTouchSelectionController(
+ const viz::Selection<gfx::SelectionBound>& selection,
+ float page_scale_factor,
+ float top_controls_height,
+ float top_controls_shown_ratio,
+ const gfx::SizeF& scrollable_viewport_size_dip);
bool UpdateControls(float dip_scale,
float top_controls_height,
float top_controls_shown_ratio,
@@ -380,7 +387,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
const gfx::Size& dst_size_in_pixel,
base::OnceCallback<void(const SkBitmap&)> callback);
- void DestroyDelegatedContent();
+ void EvictDelegatedContent();
void OnLostResources();
enum BeginFrameRequestType {
@@ -389,7 +396,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
};
void AddBeginFrameRequest(BeginFrameRequestType request);
void ClearBeginFrameRequest(BeginFrameRequestType request);
- void AcknowledgeBeginFrame(const viz::BeginFrameAck& ack);
void StartObservingRootWindow();
void StopObservingRootWindow();
void SendBeginFramePaused();
@@ -414,6 +420,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void LostFocusInternal();
void SetTextHandlesHiddenForStylus(bool hide_handles);
+ void SetTextHandlesHiddenInternal();
// The begin frame source being observed. Null if none.
viz::BeginFrameSource* begin_frame_source_;
@@ -452,13 +459,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
// Manages the Compositor Frames received from the renderer.
std::unique_ptr<ui::DelegatedFrameHostAndroid> delegated_frame_host_;
- std::vector<viz::ReturnedResource> surface_returned_resources_;
-
// The most recent surface size that was pushed to the surface layer.
gfx::Size current_surface_size_;
- base::queue<base::Closure> ack_callbacks_;
-
// Used to control and render overscroll-related effects.
std::unique_ptr<OverscrollControllerAndroid> overscroll_controller_;
@@ -487,8 +490,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
SynchronousCompositorClient* synchronous_compositor_client_;
- std::unique_ptr<viz::FrameEvictor> frame_evictor_;
-
bool observing_root_window_;
bool controls_initialized_ = false;
@@ -512,6 +513,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
MouseWheelPhaseHandler mouse_wheel_phase_handler_;
uint32_t latest_capture_sequence_number_ = 0u;
+ viz::ParentLocalSurfaceIdAllocator local_surface_id_allocator_;
+ bool is_first_navigation_ = true;
+
base::WeakPtrFactory<RenderWidgetHostViewAndroid> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAndroid);
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 861122e9908..09168578786 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
@@ -56,7 +56,7 @@
#include "gpu/ipc/common/gpu_messages.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 "services/ui/public/interfaces/window_tree_constants.mojom.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/public/web/web_ime_text_span.h"
#include "ui/accessibility/platform/aura_window_properties.h"
@@ -98,6 +98,7 @@
#include "ui/gfx/skia_util.h"
#include "ui/touch_selection/touch_selection_controller.h"
#include "ui/wm/core/coordinate_conversion.h"
+#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_client.h"
#include "ui/wm/public/scoped_tooltip_disabler.h"
#include "ui/wm/public/tooltip_client.h"
@@ -364,7 +365,7 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(
is_guest_view_hack_(is_guest_view_hack),
device_scale_factor_(0.0f),
event_handler_(new RenderWidgetHostViewEventHandler(host(), this, this)),
- frame_sink_id_(base::FeatureList::IsEnabled(features::kMash)
+ frame_sink_id_(!features::IsAshInBrowserProcess()
? viz::FrameSinkId()
: is_guest_view_hack_
? AllocateFrameSinkIdForGuestViewHack()
@@ -655,16 +656,6 @@ void RenderWidgetHostViewAura::WasUnOccluded() {
bool has_saved_frame =
delegated_frame_host_ ? delegated_frame_host_->HasSavedFrame() : false;
- ui::LatencyInfo renderer_latency_info, browser_latency_info;
- if (has_saved_frame) {
- browser_latency_info.AddLatencyNumber(ui::TAB_SHOW_COMPONENT,
- host()->GetLatencyComponentId());
- browser_latency_info.set_trace_id(++tab_show_sequence_);
- } else {
- renderer_latency_info.AddLatencyNumber(ui::TAB_SHOW_COMPONENT,
- host()->GetLatencyComponentId());
- renderer_latency_info.set_trace_id(++tab_show_sequence_);
- }
// If the primary surface was evicted, we should create a new primary.
if (delegated_frame_host_ &&
@@ -673,9 +664,8 @@ void RenderWidgetHostViewAura::WasUnOccluded() {
base::nullopt);
}
- TRACE_EVENT_ASYNC_BEGIN0("latency", "TabSwitching::Latency",
- tab_show_sequence_);
- host()->WasShown(renderer_latency_info);
+ const bool renderer_should_record_presentation_time = !has_saved_frame;
+ host()->WasShown(renderer_should_record_presentation_time);
aura::Window* root = window_->GetRootWindow();
if (root) {
@@ -686,9 +676,12 @@ void RenderWidgetHostViewAura::WasUnOccluded() {
}
if (delegated_frame_host_) {
+ // If the frame for the renderer is already available, then the
+ // tab-switching time is the presentation time for the browser-compositor.
+ const bool record_presentation_time = has_saved_frame;
delegated_frame_host_->WasShown(window_->GetLocalSurfaceId(),
window_->bounds().size(),
- browser_latency_info);
+ record_presentation_time);
}
#if defined(OS_WIN)
@@ -831,12 +824,6 @@ void RenderWidgetHostViewAura::DisplayTooltipText(
}
}
-gfx::Size RenderWidgetHostViewAura::GetRequestedRendererSize() const {
- return delegated_frame_host_
- ? delegated_frame_host_->GetRequestedRendererSize()
- : RenderWidgetHostViewBase::GetRequestedRendererSize();
-}
-
uint32_t RenderWidgetHostViewAura::GetCaptureSequenceNumber() const {
return latest_capture_sequence_number_;
}
@@ -988,6 +975,8 @@ void RenderWidgetHostViewAura::GestureEventAck(
}
}
event_handler_->GestureEventAck(event, ack_result);
+
+ ForwardTouchpadPinchIfNecessary(event, ack_result);
}
void RenderWidgetHostViewAura::ProcessAckedTouchEvent(
@@ -1460,12 +1449,14 @@ bool RenderWidgetHostViewAura::IsTextEditCommandEnabled(
void RenderWidgetHostViewAura::SetTextEditCommandForNextKeyEvent(
ui::TextEditCommand command) {}
-const std::string& RenderWidgetHostViewAura::GetClientSourceInfo() const {
+ukm::SourceId RenderWidgetHostViewAura::GetClientSourceForMetrics() const {
RenderFrameHostImpl* frame = GetFocusedFrame();
if (frame) {
- return frame->GetLastCommittedURL().spec();
+ frame->GetRenderWidgetHost()
+ ->delegate()
+ ->GetUkmSourceIdForLastCommittedSource();
}
- return base::EmptyString();
+ return ukm::SourceId();
}
bool RenderWidgetHostViewAura::ShouldDoLearning() {
@@ -1519,7 +1510,7 @@ void RenderWidgetHostViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
}
gfx::NativeCursor RenderWidgetHostViewAura::GetCursor(const gfx::Point& point) {
- if (mouse_locked_)
+ if (IsMouseLocked())
return ui::CursorType::kNone;
return current_cursor_.GetNativeCursor();
}
@@ -1553,7 +1544,8 @@ void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged(
if (!window_->GetRootWindow())
return;
- SyncSurfaceProperties(cc::DeadlinePolicy::UseDefaultDeadline());
+ SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
+ window_->GetLocalSurfaceId());
device_scale_factor_ = new_device_scale_factor;
const display::Display display =
@@ -1605,6 +1597,11 @@ bool RenderWidgetHostViewAura::HasHitTestMask() const {
void RenderWidgetHostViewAura::GetHitTestMask(gfx::Path* mask) const {
}
+bool RenderWidgetHostViewAura::RequiresDoubleTapGestureEvents() const {
+ RenderViewHost* rvh = RenderViewHost::From(host());
+ return rvh && rvh->GetWebkitPreferences().double_tap_to_zoom_enabled;
+}
+
////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, ui::EventHandler implementation:
@@ -1703,7 +1700,7 @@ void RenderWidgetHostViewAura::FocusedNodeChanged(
void RenderWidgetHostViewAura::ScheduleEmbed(
ui::mojom::WindowTreeClientPtr client,
base::OnceCallback<void(const base::UnguessableToken&)> callback) {
- DCHECK(features::IsMashEnabled());
+ DCHECK(!features::IsAshInBrowserProcess());
aura::Env::GetInstance()->ScheduleEmbed(std::move(client),
std::move(callback));
}
@@ -1836,8 +1833,8 @@ void RenderWidgetHostViewAura::OnHostMovedInPixels(
////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, RenderFrameMetadataProvider::Observer
// implementation:
-void RenderWidgetHostViewAura::OnRenderFrameMetadataChanged() {
- RenderWidgetHostViewBase::OnRenderFrameMetadataChanged();
+void RenderWidgetHostViewAura::OnRenderFrameMetadataChangedAfterActivation() {
+ RenderWidgetHostViewBase::OnRenderFrameMetadataChangedAfterActivation();
const cc::RenderFrameMetadata& metadata =
host()->render_frame_metadata_provider()->LastRenderFrameMetadata();
SetContentBackgroundColor(metadata.root_background_color);
@@ -1925,7 +1922,7 @@ void RenderWidgetHostViewAura::CreateAuraWindow(aura::client::WindowType type) {
if (frame_sink_id_.is_valid())
window_->SetEmbedFrameSinkId(frame_sink_id_);
- if (!features::IsMashEnabled())
+ if (features::IsAshInBrowserProcess())
return;
// Embed the renderer into the Window.
@@ -2031,7 +2028,15 @@ bool RenderWidgetHostViewAura::SynchronizeVisualProperties(
DCHECK(window_);
window_->UpdateLocalSurfaceIdFromEmbeddedClient(
child_allocated_local_surface_id);
- return SyncSurfaceProperties(deadline_policy);
+ if (IsLocalSurfaceIdAllocationSuppressed())
+ return false;
+
+ if (delegated_frame_host_) {
+ delegated_frame_host_->EmbedSurface(window_->GetLocalSurfaceId(),
+ window_->bounds().size(),
+ deadline_policy);
+ }
+ return host()->SynchronizeVisualProperties();
}
ui::InputMethod* RenderWidgetHostViewAura::GetInputMethod() const {
@@ -2134,15 +2139,8 @@ void RenderWidgetHostViewAura::SnapToPhysicalPixelBoundary() {
// to avoid the web contents area looking blurry we translate the web contents
// in the +x, +y direction to land on the nearest pixel boundary. This may
// cause the bottom and right edges to be clipped slightly, but that's ok.
-#if defined(OS_CHROMEOS)
- aura::Window* snapped = window_->GetToplevelWindow();
-#else
- aura::Window* snapped = window_->GetRootWindow();
-#endif
-
- if (snapped && snapped != window_)
- ui::SnapLayerToPhysicalPixelBoundary(snapped->layer(), window_->layer());
-
+ // We want to snap it to the nearest ancestor.
+ wm::SnapWindowToPixelBoundary(window_);
has_snapped_to_boundary_ = true;
}
@@ -2159,32 +2157,17 @@ void RenderWidgetHostViewAura::InternalSetBounds(const gfx::Rect& rect) {
if (!in_bounds_changed_)
window_->SetBounds(rect);
- SyncSurfaceProperties(cc::DeadlinePolicy::UseDefaultDeadline());
+ SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
+ window_->GetLocalSurfaceId());
#if defined(OS_WIN)
UpdateLegacyWin();
- if (mouse_locked_)
+ if (IsMouseLocked())
UpdateMouseLockRegion();
#endif
}
-bool RenderWidgetHostViewAura::SyncSurfaceProperties(
- const cc::DeadlinePolicy& deadline_policy) {
- if (IsLocalSurfaceIdAllocationSuppressed())
- return false;
-
- if (delegated_frame_host_) {
- delegated_frame_host_->SynchronizeVisualProperties(
- window_->GetLocalSurfaceId(), window_->bounds().size(),
- deadline_policy);
- }
- // Note that |host_| will retrieve resize parameters from
- // |delegated_frame_host_|, so it must have SynchronizeVisualProperties called
- // after.
- return host()->SynchronizeVisualProperties();
-}
-
#if defined(OS_WIN)
void RenderWidgetHostViewAura::UpdateLegacyWin() {
if (legacy_window_destroyed_ || !GetHostWindowHWND())
@@ -2335,11 +2318,11 @@ void RenderWidgetHostViewAura::OnDidNavigateMainFrameToNewPage() {
ui::GestureRecognizer::Get()->CancelActiveTouches(window_);
}
-viz::FrameSinkId RenderWidgetHostViewAura::GetFrameSinkId() {
+const viz::FrameSinkId& RenderWidgetHostViewAura::GetFrameSinkId() const {
return frame_sink_id_;
}
-viz::LocalSurfaceId RenderWidgetHostViewAura::GetLocalSurfaceId() const {
+const viz::LocalSurfaceId& RenderWidgetHostViewAura::GetLocalSurfaceId() const {
return window_->GetLocalSurfaceId();
}
@@ -2360,7 +2343,7 @@ void RenderWidgetHostViewAura::OnUpdateTextInputStateCalled(
state->type != ui::TEXT_INPUT_TYPE_NONE &&
state->mode != ui::TEXT_INPUT_MODE_NONE &&
GetInputMethod()->GetTextInputClient() == this) {
- GetInputMethod()->ShowImeIfNeeded();
+ GetInputMethod()->ShowVirtualKeyboardIfEnabled();
}
if (auto* render_widget_host = updated_view->host()) {
@@ -2493,7 +2476,8 @@ void RenderWidgetHostViewAura::DidNavigate() {
// The first navigation does not need a new LocalSurfaceID. The renderer can
// use the ID that was already provided.
if (is_first_navigation_) {
- SyncSurfaceProperties(cc::DeadlinePolicy::UseExistingDeadline());
+ SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
+ window_->GetLocalSurfaceId());
} else {
SynchronizeVisualProperties(cc::DeadlinePolicy::UseExistingDeadline(),
base::nullopt);
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 d36135e491b..5f75e19c4a9 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
@@ -136,7 +136,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
void Destroy() override;
void SetTooltipText(const base::string16& tooltip_text) override;
void DisplayTooltipText(const base::string16& tooltip_text) override;
- gfx::Size GetRequestedRendererSize() const override;
uint32_t GetCaptureSequenceNumber() const override;
bool IsSurfaceAvailableForCopy() const override;
void CopyFromSurface(
@@ -182,8 +181,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
bool RequestRepaintForTesting() override;
void DidStopFlinging() override;
void OnDidNavigateMainFrameToNewPage() override;
- viz::FrameSinkId GetFrameSinkId() override;
- viz::LocalSurfaceId GetLocalSurfaceId() const override;
+ const viz::FrameSinkId& GetFrameSinkId() const override;
+ const viz::LocalSurfaceId& GetLocalSurfaceId() const override;
bool TransformPointToLocalCoordSpaceLegacy(
const gfx::PointF& point,
const viz::SurfaceId& original_surface,
@@ -240,7 +239,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;
+ ukm::SourceId GetClientSourceForMetrics() const override;
bool ShouldDoLearning() override;
// Overridden from display::DisplayObserver:
@@ -269,6 +268,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
void OnWindowTargetVisibilityChanged(bool visible) override;
bool HasHitTestMask() const override;
void GetHitTestMask(gfx::Path* mask) const override;
+ bool RequiresDoubleTapGestureEvents() const override;
// Overridden from ui::EventHandler:
void OnKeyEvent(ui::KeyEvent* event) override;
@@ -292,7 +292,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
const gfx::Point& new_origin_in_pixels) override;
// RenderFrameMetadataProvider::Observer
- void OnRenderFrameMetadataChanged() override;
+ void OnRenderFrameMetadataChangedAfterActivation() override;
#if defined(OS_WIN)
// Gets the HWND of the host window.
@@ -404,6 +404,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
VirtualKeyboardFocusEnsureCaretInRect);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
HitTestRegionListSubmitted);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraTest,
+ DiscardDelegatedFramesWithMemoryPressure);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraKeyboardTest,
KeyboardObserverDestroyed);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
@@ -429,6 +431,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
WebContentsViewReparent);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
TakeFallbackContent);
+ FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
+ DiscardDelegatedFrames);
class WindowObserver;
friend class WindowObserver;
@@ -464,9 +468,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
// space is required by the aura::Window.
void InternalSetBounds(const gfx::Rect& rect);
- // Handles propagation of surface properties when they are changed.
- bool SyncSurfaceProperties(const cc::DeadlinePolicy& deadline_policy);
-
#if defined(OS_WIN)
// Creates and/or updates the legacy dummy window which corresponds to
// the bounds of the webcontents. It is needed for accessibility and
@@ -660,7 +661,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
const viz::FrameSinkId frame_sink_id_;
std::unique_ptr<CursorManager> cursor_manager_;
- int tab_show_sequence_ = 0;
// Latest capture sequence number which is incremented when the caller
// requests surfaces be synchronized via
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 b84c96372ca..9aac9b4c740 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
@@ -213,8 +213,7 @@ class TestWindowObserver : public aura::WindowObserver {
class FakeWindowEventDispatcher : public aura::WindowEventDispatcher {
public:
FakeWindowEventDispatcher(aura::WindowTreeHost* host)
- : WindowEventDispatcher(host),
- processed_touch_event_count_(0) {}
+ : WindowEventDispatcher(host, true), processed_touch_event_count_(0) {}
void ProcessedTouchEvent(
uint32_t unique_event_id,
@@ -385,6 +384,20 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
lastWheelOrTouchEventLatencyInfo = ui::LatencyInfo(ui_latency);
}
+ void ForwardGestureEventWithLatencyInfo(
+ const blink::WebGestureEvent& gesture_event,
+ const ui::LatencyInfo& ui_latency) override {
+ RenderWidgetHostImpl::ForwardGestureEventWithLatencyInfo(gesture_event,
+ ui_latency);
+ last_forwarded_gesture_event_ = gesture_event;
+ }
+
+ base::Optional<WebGestureEvent> GetAndResetLastForwardedGestureEvent() {
+ base::Optional<WebGestureEvent> ret;
+ last_forwarded_gesture_event_.swap(ret);
+ return ret;
+ }
+
static MockRenderWidgetHostImpl* Create(RenderWidgetHostDelegate* delegate,
RenderProcessHost* process,
int32_t routing_id) {
@@ -429,8 +442,9 @@ class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
new_content_rendering_timeout_fired_ = true;
}
- bool new_content_rendering_timeout_fired_;
+ bool new_content_rendering_timeout_fired_ = false;
std::unique_ptr<MockWidgetImpl> widget_impl_;
+ base::Optional<WebGestureEvent> last_forwarded_gesture_event_;
};
class TestScopedKeyboardHook : public aura::ScopedKeyboardHook {
@@ -472,19 +486,14 @@ void TestScopedKeyboardHook::LockSpecificKey(ui::DomCode dom_code) {
locked_key_ = dom_code;
}
-enum WheelScrollingMode {
- kWheelScrollingModeNone,
- kWheelScrollLatching,
- kAsyncWheelEvents,
-};
-
class RenderWidgetHostViewAuraTest : public testing::Test {
public:
- RenderWidgetHostViewAuraTest(
- WheelScrollingMode wheel_scrolling_mode = kWheelScrollingModeNone)
- : wheel_scrolling_mode_(wheel_scrolling_mode),
- widget_host_uses_shutdown_to_destroy_(false),
- is_guest_view_hack_(false) {}
+ RenderWidgetHostViewAuraTest()
+ : widget_host_uses_shutdown_to_destroy_(false),
+ is_guest_view_hack_(false) {
+ ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
+ 0);
+ }
static void InstallDelegatedFrameHostClient(
RenderWidgetHostViewAura* view,
@@ -610,34 +619,10 @@ class RenderWidgetHostViewAuraTest : public testing::Test {
const ui::MotionEventAura& pointer_state() { return view_->pointer_state(); }
void SetFeatureList() {
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- feature_list_.InitWithFeatures({features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents},
- {});
- } else if (wheel_scrolling_mode_ == kWheelScrollLatching) {
- feature_list_.InitWithFeatures(
- {features::kTouchpadAndWheelScrollLatching},
- {features::kAsyncWheelEvents});
- } else if (wheel_scrolling_mode_ == kWheelScrollingModeNone) {
- feature_list_.InitWithFeatures({},
- {features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents});
- }
-
vsync_feature_list_.InitAndEnableFeature(
features::kVsyncAlignedInputEvents);
}
- void TimerBasedWheelEventPhaseInfo();
- void TimerBasedLatchingBreaksWithMouseMove();
- void TimerBasedLatchingBreaksWithModifiersChange();
- void TimerBasedLatchingBreaksWithDirectionChange();
- void TimerBasedLatchingBreaksWithAutoscrollStart();
- void TouchpadFlingStartResetsWheelPhaseState();
- void GSBWithTouchSourceStopsWheelScrollSequence();
-
- WheelScrollingMode wheel_scrolling_mode_;
-
protected:
BrowserContext* browser_context() { return browser_context_.get(); }
@@ -722,32 +707,6 @@ class RenderWidgetHostViewAuraSurfaceSynchronizationTest
base::test::ScopedFeatureList surface_synchronization_feature_list_;
};
-class RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest
- : public RenderWidgetHostViewAuraTest {
- public:
- RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest()
- : RenderWidgetHostViewAuraTest(kWheelScrollLatching) {}
- void SetUp() override {
- SetFeatureList();
- ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
- 0);
- RenderWidgetHostViewAuraTest::SetUpEnvironment();
- }
-};
-
-class RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest
- : public RenderWidgetHostViewAuraTest {
- public:
- RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest()
- : RenderWidgetHostViewAuraTest(kAsyncWheelEvents) {}
- void SetUp() override {
- SetFeatureList();
- ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
- 0);
- RenderWidgetHostViewAuraTest::SetUpEnvironment();
- }
-};
-
void InstallDelegatedFrameHostClient(
RenderWidgetHostViewAura* render_widget_host_view,
std::unique_ptr<DelegatedFrameHostClient> delegated_frame_host_client) {
@@ -795,11 +754,7 @@ class RenderWidgetHostViewGuestAuraTest : public RenderWidgetHostViewAuraTest {
class RenderWidgetHostViewAuraOverscrollTest
: public RenderWidgetHostViewAuraTest {
public:
- RenderWidgetHostViewAuraOverscrollTest(
- WheelScrollingMode wheel_scrolling_mode = kWheelScrollLatching)
- : RenderWidgetHostViewAuraTest(wheel_scrolling_mode),
- wheel_scroll_latching_enabled_(wheel_scrolling_mode !=
- kWheelScrollingModeNone) {}
+ RenderWidgetHostViewAuraOverscrollTest() : RenderWidgetHostViewAuraTest() {}
// We explicitly invoke SetUp to allow gesture debounce customization.
void SetUp() override {}
@@ -823,16 +778,14 @@ class RenderWidgetHostViewAuraOverscrollTest
void SendScrollBeginAckIfNeeded(
MockWidgetInputHandler::MessageVector& messages,
InputEventAckState ack_result) {
- if (wheel_scroll_latching_enabled_) {
- 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;
- }
+ 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;
}
}
}
@@ -887,17 +840,11 @@ class RenderWidgetHostViewAuraOverscrollTest
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,
- float dY,
- int modifiers,
- bool precise,
- WebMouseWheelEvent::Phase phase) {
+ void SimulateWheelEvent(float dX,
+ float dY,
+ int modifiers,
+ bool precise,
+ WebMouseWheelEvent::Phase phase) {
WebMouseWheelEvent wheel_event = SyntheticWebMouseWheelEventBuilder::Build(
0, 0, dX, dY, modifiers, precise);
wheel_event.phase = phase;
@@ -905,30 +852,6 @@ class RenderWidgetHostViewAuraOverscrollTest
base::RunLoop().RunUntilIdle();
}
- void SimulateWheelEventPossiblyIncludingPhase(
- float dX,
- float dY,
- int modifiers,
- bool precise,
- WebMouseWheelEvent::Phase phase) {
- if (wheel_scroll_latching_enabled_)
- SimulateWheelEventWithPhase(dX, dY, modifiers, precise, phase);
- else
- SimulateWheelEvent(dX, dY, modifiers, precise);
- }
-
- void SimulateWheelEventWithLatencyInfo(float dX,
- float dY,
- int modifiers,
- bool precise,
- const ui::LatencyInfo& ui_latency) {
- widget_host_->ForwardWheelEventWithLatencyInfo(
- SyntheticWebMouseWheelEventBuilder::Build(0, 0, dX, dY, modifiers,
- precise),
- ui_latency);
- base::RunLoop().RunUntilIdle();
- }
-
void SimulateMouseMove(int x, int y, int modifiers) {
SimulateMouseEvent(WebInputEvent::kMouseMove, x, y, modifiers, false);
}
@@ -946,12 +869,6 @@ class RenderWidgetHostViewAuraOverscrollTest
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);
@@ -1059,15 +976,26 @@ class RenderWidgetHostViewAuraOverscrollTest
touch_event_.ReleasePoint(index);
}
+ void PressAndSetTouchActionAuto() {
+ PressTouchPoint(0, 1);
+ SendTouchEvent();
+ widget_host_->input_router()->OnSetTouchAction(cc::kTouchActionAuto);
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("TouchStart", GetMessageNames(events));
+ }
+
+ void ReleaseAndResetDispatchedMessages() {
+ ReleaseTouchPoint(0);
+ SendTouchEvent();
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ }
+
MockWidgetInputHandler::MessageVector ExpectGestureScrollEndForWheelScrolling(
bool is_last) {
MockWidgetInputHandler::MessageVector events =
GetAndResetDispatchedMessages();
- if (!wheel_scroll_latching_enabled_) {
- // Already handled in |ExpectGestureScrollEventsAfterMouseWheelACK()|.
- EXPECT_EQ(0U, events.size());
- return events;
- }
if (is_last) {
// Scroll latching will have one GestureScrollEnd at the end.
EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
@@ -1085,8 +1013,6 @@ class RenderWidgetHostViewAuraOverscrollTest
MockWidgetInputHandler::MessageVector events =
GetAndResetDispatchedMessages();
std::string expected_events;
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- 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
@@ -1100,30 +1026,6 @@ class RenderWidgetHostViewAuraOverscrollTest
expected_events += "GestureScrollBegin GestureScrollUpdate ";
for (size_t i = 0; i < enqueued_wheel_event_count; ++i)
expected_events += "MouseWheel GestureScrollUpdate ";
- } else if (wheel_scrolling_mode_ == kWheelScrollLatching) {
- 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
- // events.
- // Expecting a GSU or GSB+GSU for ACKing the previous MouseWheel, plus an
- // additional MouseWheel if the queue is not empty. GSE will be delayed by
- // scroll latching.
- if (is_first_ack)
- expected_events += "GestureScrollBegin ";
- expected_events += "GestureScrollUpdate ";
- if (enqueued_wheel_event_count != 0)
- expected_events += "MouseWheel";
- } else {
- // The MWEQ must wait for ack of the sent event before sending the
- // next queued event.
- // Expecting a GSB+GSU+GSE for ACKing the previous MouseWheel, plus an
- // additional MouseWheel if the queue is not empty.
- expected_events +=
- "GestureScrollBegin GestureScrollUpdate GestureScrollEnd ";
- if (enqueued_wheel_event_count != 0)
- expected_events += "MouseWheel";
- }
EXPECT_EQ(base::TrimWhitespaceASCII(expected_events, base::TRIM_TRAILING),
GetMessageNames(events));
@@ -1157,60 +1059,16 @@ class RenderWidgetHostViewAuraOverscrollTest
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, 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", GetMessageNames(events));
- }
- }
-
- void WheelNotPreciseScrollEvent();
- void WheelScrollOverscrollToggle();
- void OverscrollMouseMoveCompletion();
- void WheelScrollEventOverscrolls();
- void WheelScrollConsumedDoNotOverscroll();
- void ScrollEventsOverscrollWithFling();
- void OverscrollDirectionChangeMouseWheel();
- void OverscrollStateResetsAfterScroll();
- void ScrollDeltasResetOnEnd();
- void ScrollEventsOverscrollWithZeroFling();
-
SyntheticWebTouchEvent touch_event_;
std::unique_ptr<TestOverscrollDelegate> overscroll_delegate_;
- bool wheel_scroll_latching_enabled_;
-
private:
base::test::ScopedFeatureList scoped_feature_list_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAuraOverscrollTest);
};
-class RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest
- : public RenderWidgetHostViewAuraOverscrollTest {
- public:
- RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest()
- : RenderWidgetHostViewAuraOverscrollTest(kWheelScrollingModeNone) {}
-};
-
-class RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest
- : public RenderWidgetHostViewAuraOverscrollTest {
- public:
- RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest()
- : RenderWidgetHostViewAuraOverscrollTest(kAsyncWheelEvents) {}
-};
-
class RenderWidgetHostViewAuraShutdownTest
: public RenderWidgetHostViewAuraTest {
public:
@@ -2001,11 +1859,7 @@ TEST_F(RenderWidgetHostViewAuraTest,
}
}
-void RenderWidgetHostViewAuraTest::TimerBasedWheelEventPhaseInfo() {
- // The test is valid only when wheel scroll latching is enabled.
- if (wheel_scrolling_mode_ == kWheelScrollingModeNone)
- return;
-
+TEST_F(RenderWidgetHostViewAuraTest, TimerBasedWheelEventPhaseInfo) {
view_->InitAsChild(nullptr);
view_->Show();
sink_->ClearMessages();
@@ -2049,16 +1903,9 @@ void RenderWidgetHostViewAuraTest::TimerBasedWheelEventPhaseInfo() {
events[0]->ToEvent()->Event()->web_event.get());
base::TimeTicks wheel_event_timestamp = wheel_event->TimeStamp();
EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, wheel_event->phase);
- if (wheel_scrolling_mode_ == kWheelScrollLatching) {
- events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- events = GetAndResetDispatchedMessages();
- gesture_event = static_cast<const WebGestureEvent*>(
- events[0]->ToEvent()->Event()->web_event.get());
- } else { // wheel_scrolling_mode_ == kAsyncWheelEvents.
+
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(2U, gesture_event->data.scroll_update.delta_y);
@@ -2085,23 +1932,11 @@ void RenderWidgetHostViewAuraTest::TimerBasedWheelEventPhaseInfo() {
EXPECT_EQ(WebInputEvent::kGestureScrollEnd, gesture_event->GetType());
EXPECT_TRUE(gesture_event->data.scroll_end.synthetic);
}
-TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
- TimerBasedWheelEventPhaseInfo) {
- TimerBasedWheelEventPhaseInfo();
-}
-TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest,
- TimerBasedWheelEventPhaseInfo) {
- TimerBasedWheelEventPhaseInfo();
-}
// Tests that latching breaks when the difference between location of the first
// wheel event in the sequence and the location of the current wheel event is
// larger than some maximum threshold.
-void RenderWidgetHostViewAuraTest::TimerBasedLatchingBreaksWithMouseMove() {
- // The test is valid only when wheel scroll latching is enabled.
- if (wheel_scrolling_mode_ == kWheelScrollingModeNone)
- return;
-
+TEST_F(RenderWidgetHostViewAuraTest, TimerBasedLatchingBreaksWithMouseMove) {
// Set the mouse_wheel_phase_handler_ timer timeout to a large value to make
// sure that the timer is still running when the wheel event with different
// location is sent.
@@ -2137,16 +1972,11 @@ void RenderWidgetHostViewAuraTest::TimerBasedLatchingBreaksWithMouseMove() {
view_->OnMouseEvent(&event2);
base::RunLoop().RunUntilIdle();
events = GetAndResetDispatchedMessages();
- if (wheel_scrolling_mode_ == kWheelScrollLatching)
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- else
- EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
+ EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
wheel_event = static_cast<const WebMouseWheelEvent*>(
events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, wheel_event->phase);
- if (wheel_scrolling_mode_ == kWheelScrollLatching)
- events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
events = GetAndResetDispatchedMessages();
// Send the third wheel event with a location outside of the slop region. The
@@ -2167,23 +1997,11 @@ void RenderWidgetHostViewAuraTest::TimerBasedLatchingBreaksWithMouseMove() {
events[2]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
}
-TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
- TimerBasedLatchingBreaksWithMouseMove) {
- TimerBasedLatchingBreaksWithMouseMove();
-}
-TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest,
- TimerBasedLatchingBreaksWithMouseMove) {
- TimerBasedLatchingBreaksWithMouseMove();
-}
// Tests that latching breaks when the current wheel event has different
// modifiers.
-void RenderWidgetHostViewAuraTest::
- TimerBasedLatchingBreaksWithModifiersChange() {
- // The test is valid only when wheel scroll latching is enabled.
- if (wheel_scrolling_mode_ == kWheelScrollingModeNone)
- return;
-
+TEST_F(RenderWidgetHostViewAuraTest,
+ TimerBasedLatchingBreaksWithModifiersChange) {
// Set the mouse_wheel_phase_handler_ timer timeout to a large value to make
// sure that the timer is still running when the wheel event with different
// modifiers is sent.
@@ -2216,16 +2034,11 @@ void RenderWidgetHostViewAuraTest::
view_->OnMouseEvent(&event2);
base::RunLoop().RunUntilIdle();
events = GetAndResetDispatchedMessages();
- if (wheel_scrolling_mode_ == kWheelScrollLatching)
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- else
- EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
+ EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
wheel_event = static_cast<const WebMouseWheelEvent*>(
events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, wheel_event->phase);
- if (wheel_scrolling_mode_ == kWheelScrollLatching)
- events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
events = GetAndResetDispatchedMessages();
// Send the third wheel event with a ctrl key down. The third wheel event will
@@ -2245,24 +2058,12 @@ void RenderWidgetHostViewAuraTest::
events[2]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
}
-TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
- TimerBasedLatchingBreaksWithModifiersChange) {
- TimerBasedLatchingBreaksWithModifiersChange();
-}
-TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest,
- TimerBasedLatchingBreaksWithModifiersChange) {
- TimerBasedLatchingBreaksWithModifiersChange();
-}
// Tests that latching breaks when the new wheel event goes a different
// direction from previous wheel events and the previous GSU events are not
// consumed.
-void RenderWidgetHostViewAuraTest::
- TimerBasedLatchingBreaksWithDirectionChange() {
- // The test is valid only when wheel scroll latching is enabled.
- if (wheel_scrolling_mode_ == kWheelScrollingModeNone)
- return;
-
+TEST_F(RenderWidgetHostViewAuraTest,
+ TimerBasedLatchingBreaksWithDirectionChange) {
// Set the mouse_wheel_phase_handler_ timer timeout to a large value to make
// sure that the timer is still running when the wheel event with different
// modifiers is sent.
@@ -2312,21 +2113,9 @@ void RenderWidgetHostViewAuraTest::
events[2]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
}
-TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
- TimerBasedLatchingBreaksWithDirectionChange) {
- TimerBasedLatchingBreaksWithDirectionChange();
-}
-TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest,
- TimerBasedLatchingBreaksWithDirectionChange) {
- TimerBasedLatchingBreaksWithDirectionChange();
-}
-
-void RenderWidgetHostViewAuraTest::
- TimerBasedLatchingBreaksWithAutoscrollStart() {
- // The test is valid only when wheel scroll latching is enabled.
- if (wheel_scrolling_mode_ == kWheelScrollingModeNone)
- return;
+TEST_F(RenderWidgetHostViewAuraTest,
+ TimerBasedLatchingBreaksWithAutoscrollStart) {
// Set the mouse_wheel_phase_handler_ timer timeout to a large value to make
// sure that the timer is still running when the Autoscroll starts.
view_->event_handler()->set_mouse_wheel_wheel_phase_handler_timeout(
@@ -2349,7 +2138,7 @@ void RenderWidgetHostViewAuraTest::
events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_TRUE(view_->GetMouseWheelPhaseHandler()->HasPendingWheelEndEvent());
+ EXPECT_TRUE(GetMouseWheelPhaseHandler()->HasPendingWheelEndEvent());
events = GetAndResetDispatchedMessages();
// Autoscroll start breaks wheel scroll latching sequence by sending the
@@ -2357,7 +2146,7 @@ void RenderWidgetHostViewAuraTest::
// immediately and a GSE will be sent. The next wheel event will start a new
// scrolling sequence.
view_->OnAutoscrollStart();
- EXPECT_FALSE(view_->GetMouseWheelPhaseHandler()->HasPendingWheelEndEvent());
+ EXPECT_FALSE(GetMouseWheelPhaseHandler()->HasPendingWheelEndEvent());
ui::MouseWheelEvent event2(gfx::Vector2d(0, 5), gfx::Point(2, 2),
gfx::Point(2, 2), ui::EventTimeForNow(), 0, 0);
view_->OnMouseEvent(&event2);
@@ -2373,18 +2162,10 @@ void RenderWidgetHostViewAuraTest::
events[2]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
}
-TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest,
- TimerBasedLatchingBreaksWithAutoscrollStart) {
- TimerBasedLatchingBreaksWithAutoscrollStart();
-}
// Tests that a gesture fling start with touchpad source resets wheel phase
// state.
-void RenderWidgetHostViewAuraTest::TouchpadFlingStartResetsWheelPhaseState() {
- // The test is valid only when wheel scroll latching is enabled.
- if (wheel_scrolling_mode_ == kWheelScrollingModeNone)
- return;
-
+TEST_F(RenderWidgetHostViewAuraTest, TouchpadFlingStartResetsWheelPhaseState) {
// Set the mouse_wheel_phase_handler_ timer timeout to a large value to make
// sure that the timer is still running when the touchpad fling start is sent.
view_->event_handler()->set_mouse_wheel_wheel_phase_handler_timeout(
@@ -2436,26 +2217,14 @@ void RenderWidgetHostViewAuraTest::TouchpadFlingStartResetsWheelPhaseState() {
view_->OnScrollEvent(&scroll1);
base::RunLoop().RunUntilIdle();
events = GetAndResetDispatchedMessages();
- if (wheel_scrolling_mode_ == kWheelScrollLatching)
- EXPECT_EQ(1U, events.size());
- else
- EXPECT_EQ(2U, events.size());
+ EXPECT_EQ(2U, events.size());
wheel_event = static_cast<const WebMouseWheelEvent*>(
events[0]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseChanged, wheel_event->phase);
- if (wheel_scrolling_mode_ == kWheelScrollLatching) {
- 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());
- events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
- } else { // wheel_scrolling_mode_ == kAsyncWheelEvents
- EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
- gesture_event = static_cast<const WebGestureEvent*>(
- events[1]->ToEvent()->Event()->web_event.get());
- events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
- }
+ EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
+ gesture_event = static_cast<const WebGestureEvent*>(
+ events[1]->ToEvent()->Event()->web_event.get());
+ events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
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);
@@ -2488,21 +2257,64 @@ void RenderWidgetHostViewAuraTest::TouchpadFlingStartResetsWheelPhaseState() {
events[2]->ToEvent()->Event()->web_event.get());
EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
}
-TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
- TouchpadFlingStartResetsWheelPhaseState) {
- TouchpadFlingStartResetsWheelPhaseState();
-}
-TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest,
- TouchpadFlingStartResetsWheelPhaseState) {
- TouchpadFlingStartResetsWheelPhaseState();
+
+// Tests that the touchpad scroll state in mouse wheel phase handler gets reset
+// when a mouse wheel event from an external mouse arrives.
+TEST_F(RenderWidgetHostViewAuraTest, MouseWheelScrollingAfterGFCWithoutGFS) {
+ // Set the mouse_wheel_phase_handler_ timer timeout to a large value to make
+ // sure that the timer is still running when we are checking for the pending
+ // wheel end event after sending ui::MouseWheelEvent.
+ view_->event_handler()->set_mouse_wheel_wheel_phase_handler_timeout(
+ TestTimeouts::action_max_timeout());
+
+ view_->InitAsChild(nullptr);
+ view_->Show();
+ sink_->ClearMessages();
+
+ // When the user puts their fingers down a GFC is received. This will change
+ // the touchpad scroll state in mouse wheel phase handler to may_begin.
+ EXPECT_EQ(
+ content::TOUCHPAD_SCROLL_STATE_UNKNOWN,
+ GetMouseWheelPhaseHandler()->touchpad_scroll_phase_state_for_test());
+ 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);
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ(
+ content::TOUCHPAD_SCROLL_MAY_BEGIN,
+ GetMouseWheelPhaseHandler()->touchpad_scroll_phase_state_for_test());
+ EXPECT_FALSE(GetMouseWheelPhaseHandler()->HasPendingWheelEndEvent());
+
+ // The user lifts their fingers without doing any touchpad scroll
+ // (ui::ScrollEevent), the touchpad scroll state must still be may_begin since
+ // without touchpad scrolling no GFS is recieved to reset the state.
+ EXPECT_EQ(
+ content::TOUCHPAD_SCROLL_MAY_BEGIN,
+ GetMouseWheelPhaseHandler()->touchpad_scroll_phase_state_for_test());
+
+ // The user starts scrolling by external mouse device.
+ ui::MouseWheelEvent wheel(gfx::Vector2d(0, 5), gfx::Point(2, 2),
+ gfx::Point(2, 2), ui::EventTimeForNow(), 0, 0);
+ view_->OnMouseEvent(&wheel);
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ const WebMouseWheelEvent* wheel_event =
+ static_cast<const WebMouseWheelEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get());
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ EXPECT_EQ(WebMouseWheelEvent::kPhaseBegan, wheel_event->phase);
+
+ // After arrival of the mouse wheel event, the touchpad scroll state must get
+ // reset and the timer based wheel scroll latching must be active.
+ EXPECT_EQ(
+ content::TOUCHPAD_SCROLL_STATE_UNKNOWN,
+ GetMouseWheelPhaseHandler()->touchpad_scroll_phase_state_for_test());
+ EXPECT_TRUE(GetMouseWheelPhaseHandler()->HasPendingWheelEndEvent());
}
-TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest,
+TEST_F(RenderWidgetHostViewAuraTest,
ScrollingWithExternalMouseBreaksTouchpadScrollLatching) {
- // The test is valid only when wheel scroll latching is enabled.
- if (wheel_scrolling_mode_ == kWheelScrollingModeNone)
- return;
-
// Set the mouse_wheel_phase_handler_ timer timeout to a large value to make
// sure that the timer is still running when we are checking for the pending
// wheel end event after sending ui::MouseWheelEvent.
@@ -2572,12 +2384,8 @@ TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest,
EXPECT_TRUE(GetMouseWheelPhaseHandler()->HasPendingWheelEndEvent());
}
-void RenderWidgetHostViewAuraTest::
- GSBWithTouchSourceStopsWheelScrollSequence() {
- // The test is valid only when wheel scroll latching is enabled.
- if (wheel_scrolling_mode_ == kWheelScrollingModeNone)
- return;
-
+TEST_F(RenderWidgetHostViewAuraTest,
+ GSBWithTouchSourceStopsWheelScrollSequence) {
// Set the mouse_wheel_phase_handler_ timer timeout to a large value to make
// sure that the timer is still running when the GSB event with touch source
// is sent.
@@ -2609,6 +2417,16 @@ void RenderWidgetHostViewAuraTest::
EXPECT_EQ(5U, gesture_event->data.scroll_update.delta_y);
events[1]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
+ ui::GestureEventDetails gesture_tap_down_details(ui::ET_GESTURE_TAP_DOWN);
+ gesture_tap_down_details.set_is_source_touch_event_set_non_blocking(true);
+ gesture_tap_down_details.set_device_type(
+ ui::GestureDeviceType::DEVICE_TOUCHSCREEN);
+ ui::GestureEvent gesture_tap_down(2, 2, 0, ui::EventTimeForNow(),
+ gesture_tap_down_details);
+ view_->OnGestureEvent(&gesture_tap_down);
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+
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);
@@ -2637,14 +2455,41 @@ void RenderWidgetHostViewAuraTest::
EXPECT_EQ(blink::kWebGestureDeviceTouchscreen, gesture_event->SourceDevice());
}
-TEST_F(RenderWidgetHostViewAuraWheelScrollLatchingEnabledTest,
- GSBWithTouchSourceStopsWheelScrollSequence) {
- GSBWithTouchSourceStopsWheelScrollSequence();
-}
+TEST_F(RenderWidgetHostViewAuraTest,
+ SyntheticFlingCancelAtTouchpadScrollBegin) {
+ ui::ScrollEvent scroll_event(ui::ET_SCROLL, gfx::Point(2, 2),
+ ui::EventTimeForNow(), 0, 0, 5, 0, 5, 2);
-TEST_F(RenderWidgetHostViewAuraAsyncWheelEventsEnabledTest,
- GSBWithTouchSourceStopsWheelScrollSequence) {
- GSBWithTouchSourceStopsWheelScrollSequence();
+ // Send the beginning scroll event. This should generate a synthetic fling
+ // cancel to cancel any ongoing flings before the start of this scroll.
+ view_->OnScrollEvent(&scroll_event);
+ base::RunLoop().RunUntilIdle();
+ base::Optional<WebGestureEvent> last_gesture =
+ widget_host_->GetAndResetLastForwardedGestureEvent();
+ ASSERT_TRUE(last_gesture);
+ EXPECT_EQ(WebInputEvent::kGestureFlingCancel, last_gesture->GetType());
+
+ // Consume the wheel to prevent gesture scrolls from interfering with the
+ // rest of the test.
+ MockWidgetInputHandler::MessageVector dispatched_events =
+ GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(dispatched_events));
+ dispatched_events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, dispatched_events.size());
+
+ // Send a scroll update. A synthetic fling cancel has already been sent for
+ // this sequence, so we should not generate another.
+ view_->OnScrollEvent(&scroll_event);
+ base::RunLoop().RunUntilIdle();
+ last_gesture = widget_host_->GetAndResetLastForwardedGestureEvent();
+ EXPECT_FALSE(last_gesture);
+
+ dispatched_events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(dispatched_events));
+ dispatched_events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
+ dispatched_events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, dispatched_events.size());
}
// Checks that touch-event state is maintained correctly for multiple touch
@@ -2659,6 +2504,8 @@ TEST_F(RenderWidgetHostViewAuraTest, MultiTouchPointsStates) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0));
view_->OnTouchEvent(&press0);
+ view_->GetFocusedWidget()->input_router()->OnSetTouchAction(
+ cc::kTouchActionAuto);
base::RunLoop().RunUntilIdle();
MockWidgetInputHandler::MessageVector events =
@@ -3188,7 +3035,7 @@ viz::CompositorFrame MakeDelegatedFrame(float scale_factor,
// This test verifies that returned resources do not require a pending ack.
TEST_F(RenderWidgetHostViewAuraTest, ReturnedResources) {
// TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
+ if (!features::IsAshInBrowserProcess())
return;
gfx::Size view_size(100, 100);
@@ -3219,9 +3066,12 @@ TEST_F(RenderWidgetHostViewAuraTest, ReturnedResources) {
// This test verifies that when the CompositorFrameSink changes, the old
// resources are not returned.
TEST_F(RenderWidgetHostViewAuraTest, TwoOutputSurfaces) {
- // TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
+ // TODO(jonross): Delete this test once Viz launches as it will be obsolete.
+ // https://crbug.com/844469
+ if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
+ !features::IsAshInBrowserProcess()) {
return;
+ }
viz::FakeSurfaceObserver manager_observer;
ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
@@ -3361,7 +3211,7 @@ TEST_F(RenderWidgetHostViewAuraTest, ZeroSizeStillGetsLocalSurfaceId) {
TEST_F(RenderWidgetHostViewAuraTest, BackgroundColorMatchesCompositorFrame) {
// TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
+ if (!features::IsAshInBrowserProcess())
return;
gfx::Size frame_size(100, 100);
@@ -3377,7 +3227,7 @@ TEST_F(RenderWidgetHostViewAuraTest, BackgroundColorMatchesCompositorFrame) {
cc::RenderFrameMetadata metadata;
metadata.root_background_color = SK_ColorRED;
view_->SetRenderFrameMetadata(metadata);
- view_->OnRenderFrameMetadataChanged();
+ view_->OnRenderFrameMetadataChangedAfterActivation();
ui::Layer* parent_layer = view_->GetNativeView()->layer();
EXPECT_EQ(gfx::Rect(0, 0, 100, 100), parent_layer->bounds());
@@ -3398,7 +3248,7 @@ TEST_F(RenderWidgetHostViewAuraTest, BackgroundColorOrder) {
cc::RenderFrameMetadata metadata;
metadata.root_background_color = SK_ColorWHITE;
view_->SetRenderFrameMetadata(metadata);
- view_->OnRenderFrameMetadataChanged();
+ view_->OnRenderFrameMetadataChangedAfterActivation();
ASSERT_TRUE(view_->GetBackgroundColor());
EXPECT_EQ(static_cast<unsigned>(SK_ColorWHITE), *view_->GetBackgroundColor());
@@ -3523,9 +3373,12 @@ TEST_F(RenderWidgetHostViewAuraTest, DISABLED_Resize) {
}
TEST_F(RenderWidgetHostViewAuraTest, OutputSurfaceIdChange) {
- // TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
+ // TODO(jonross): Delete this test once Viz launches as it will be obsolete.
+ // https://crbug.com/844469
+ if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
+ !features::IsAshInBrowserProcess()) {
return;
+ }
gfx::Rect view_rect(100, 100);
gfx::Size frame_size = view_rect.size();
@@ -3583,10 +3436,6 @@ TEST_F(RenderWidgetHostViewAuraTest, OutputSurfaceIdChange) {
// then the fallback is dropped.
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
DropFallbackWhenHidden) {
- // TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
- return;
-
view_->InitAsChild(nullptr);
aura::client::ParentWindowWithContext(
view_->GetNativeView(), parent_view_->GetNativeView()->GetRootWindow(),
@@ -3601,21 +3450,16 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
EXPECT_FALSE(view_->HasPrimarySurface());
// Submitting a CompositorFrame should not update the fallback SurfaceId
- view_->SubmitCompositorFrame(
- kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, gfx::Size(400, 400), gfx::Rect(400, 400)),
- base::nullopt);
+ viz::SurfaceId surface_id(view_->GetFrameSinkId(), kArbitraryLocalSurfaceId);
+ view_->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id, 1.f, gfx::Size(400, 400)));
EXPECT_FALSE(view_->HasPrimarySurface());
EXPECT_FALSE(view_->HasFallbackSurface());
}
// This test verifies that the primary SurfaceId is populated on resize and
-// the fallback SurfaceId is populated on SubmitCompositorFrame.
+// the fallback SurfaceId is populated in OnFirstSurfaceActivation.
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest, SurfaceChanges) {
- // TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
- return;
-
view_->InitAsChild(nullptr);
aura::client::ParentWindowWithContext(
view_->GetNativeView(), parent_view_->GetNativeView()->GetRootWindow(),
@@ -3637,12 +3481,14 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest, SurfaceChanges) {
EXPECT_EQ(gfx::Size(400, 400),
view_->delegated_frame_host_->CurrentFrameSizeInDipForTesting());
+ // Fallback SurfaceId should be updated in OnFirstSurfaceActivation.
// Submitting a CompositorFrame should update the fallback SurfaceId
- view_->SubmitCompositorFrame(
- kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, gfx::Size(400, 400), gfx::Rect(400, 400)),
- base::nullopt);
+ viz::SurfaceId surface_id(view_->GetFrameSinkId(),
+ view_->GetLocalSurfaceId());
+ view_->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id, 1.f, gfx::Size(400, 400)));
EXPECT_EQ(gfx::Size(400, 400), view_->window_->layer()->size());
+ EXPECT_EQ(surface_id, *view_->window_->layer()->GetFallbackSurfaceId());
}
// This test verifies that the primary SurfaceId is updated on device scale
@@ -3650,7 +3496,7 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest, SurfaceChanges) {
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
DeviceScaleFactorChanges) {
// TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
+ if (!features::IsAshInBrowserProcess())
return;
view_->InitAsChild(nullptr);
@@ -3677,9 +3523,12 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
// the current surface) does not crash,
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
CompositorFrameSinkChange) {
- // TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
+ // TODO(jonross): Delete this test once Viz launches as it will be obsolete.
+ // https://crbug.com/844469
+ if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
+ !features::IsAshInBrowserProcess()) {
return;
+ }
gfx::Rect view_rect(100, 100);
gfx::Size frame_size = view_rect.size();
@@ -3711,10 +3560,6 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
// RenderWidgetHostViewAuraTest.DiscardDelegatedFrame.
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
DiscardDelegatedFrames) {
- // TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
- return;
-
view_->InitAsChild(nullptr);
size_t max_renderer_frames =
@@ -3755,9 +3600,10 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
views[i]->Show();
ASSERT_TRUE(views[i]->HasPrimarySurface());
ASSERT_FALSE(views[i]->HasFallbackSurface());
- views[i]->SubmitCompositorFrame(
- views[i]->GetLocalSurfaceId(),
- MakeDelegatedFrame(1.f, frame_size, view_rect), base::nullopt);
+ viz::SurfaceId surface_id(views[i]->GetFrameSinkId(),
+ views[i]->GetLocalSurfaceId());
+ views[i]->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id, 1.f, frame_size));
ASSERT_TRUE(views[i]->HasPrimarySurface());
EXPECT_TRUE(views[i]->HasFallbackSurface());
views[i]->Hide();
@@ -3775,9 +3621,10 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
EXPECT_TRUE(views[1]->HasFallbackSurface());
// Swap a frame on it, it should evict the next LRU [1].
- views[0]->SubmitCompositorFrame(
- views[0]->GetLocalSurfaceId(),
- MakeDelegatedFrame(1.f, frame_size, view_rect), base::nullopt);
+ viz::SurfaceId surface_id0(views[0]->GetFrameSinkId(),
+ views[0]->GetLocalSurfaceId());
+ views[0]->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id0, 1.f, frame_size));
EXPECT_TRUE(views[0]->HasFallbackSurface());
EXPECT_FALSE(views[1]->HasFallbackSurface());
views[0]->Hide();
@@ -3785,9 +3632,10 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
// LRU renderer is [1], which is still hidden. Showing it and submitting a
// CompositorFrame to it should evict the next LRU [2].
views[1]->Show();
- views[1]->SubmitCompositorFrame(
- views[1]->GetLocalSurfaceId(),
- MakeDelegatedFrame(1.f, frame_size, view_rect), base::nullopt);
+ viz::SurfaceId surface_id1(views[1]->GetFrameSinkId(),
+ views[1]->GetLocalSurfaceId());
+ views[1]->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id1, 1.f, frame_size));
EXPECT_TRUE(views[0]->HasFallbackSurface());
EXPECT_TRUE(views[1]->HasFallbackSurface());
EXPECT_FALSE(views[2]->HasFallbackSurface());
@@ -3800,25 +3648,24 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
views[i]->Show();
// The renderers who don't have a frame should be waiting. The ones that
// have a frame should not.
- views[i]->SubmitCompositorFrame(
- views[i]->GetLocalSurfaceId(),
- MakeDelegatedFrame(1.f, frame_size, view_rect), base::nullopt);
+ viz::SurfaceId surface_id(views[i]->GetFrameSinkId(),
+ views[i]->GetLocalSurfaceId());
+ views[i]->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id, 1.f, frame_size));
EXPECT_TRUE(views[i]->HasFallbackSurface());
}
EXPECT_FALSE(views[0]->HasFallbackSurface());
// Swap a frame on [0], it should be evicted immediately.
- views[0]->SubmitCompositorFrame(
- views[0]->GetLocalSurfaceId(),
- MakeDelegatedFrame(1.f, frame_size, view_rect), base::nullopt);
+ views[0]->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id0, 1.f, frame_size));
EXPECT_FALSE(views[0]->HasFallbackSurface());
// Make [0] visible, and swap a frame on it. Nothing should be evicted
// although we're above the limit.
views[0]->Show();
- views[0]->SubmitCompositorFrame(
- views[0]->GetLocalSurfaceId(),
- MakeDelegatedFrame(1.f, frame_size, view_rect), base::nullopt);
+ views[0]->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id0, 1.f, frame_size));
for (size_t i = 0; i < renderer_count; ++i)
EXPECT_TRUE(views[i]->HasFallbackSurface()) << i;
@@ -3839,9 +3686,8 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
EXPECT_FALSE(views[1]->HasFallbackSurface());
// Show it, it should block until we give it a frame.
views[1]->Show();
- views[1]->SubmitCompositorFrame(
- views[1]->GetLocalSurfaceId(),
- MakeDelegatedFrame(1.f, size2, gfx::Rect(size2)), base::nullopt);
+ views[1]->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id1, 1.f, frame_size));
for (size_t i = 0; i < renderer_count; ++i) {
views[i]->Destroy();
@@ -3850,10 +3696,6 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
}
TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
- // TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
- return;
-
view_->InitAsChild(nullptr);
size_t max_renderer_frames =
@@ -3889,10 +3731,10 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
// occur because all frames are visible.
for (size_t i = 0; i < renderer_count; ++i) {
views[i]->Show();
- views[i]->SubmitCompositorFrame(
- i ? parent_local_surface_id_allocator_.GenerateId()
- : kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, frame_size, view_rect), base::nullopt);
+ viz::SurfaceId surface_id(views[i]->GetFrameSinkId(),
+ views[i]->GetLocalSurfaceId());
+ views[i]->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id, 1.f, frame_size));
EXPECT_TRUE(views[i]->HasFallbackSurface());
}
@@ -3902,9 +3744,10 @@ 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),
- base::nullopt);
+ viz::SurfaceId surface_id(views[0]->GetFrameSinkId(),
+ views[0]->GetLocalSurfaceId());
+ views[0]->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id, 1.f, frame_size));
EXPECT_TRUE(views[0]->HasFallbackSurface());
views[0]->GetDelegatedFrameHost()->LockResources();
views[0]->Hide();
@@ -3923,10 +3766,6 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithLocking) {
// Test that changing the memory pressure should delete saved frames. This test
// only applies to ChromeOS.
TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithMemoryPressure) {
- // TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
- return;
-
view_->InitAsChild(nullptr);
// The test logic below relies on having max_renderer_frames > 2. By default,
@@ -3967,9 +3806,10 @@ TEST_F(RenderWidgetHostViewAuraTest, DiscardDelegatedFramesWithMemoryPressure) {
// occur because all frames are visible.
for (size_t i = 0; i < renderer_count; ++i) {
views[i]->Show();
- views[i]->SubmitCompositorFrame(
- kArbitraryLocalSurfaceId,
- MakeDelegatedFrame(1.f, frame_size, view_rect), base::nullopt);
+ viz::SurfaceId surface_id(views[i]->GetFrameSinkId(),
+ kArbitraryLocalSurfaceId);
+ views[i]->delegated_frame_host_->OnFirstSurfaceActivation(
+ viz::SurfaceInfo(surface_id, 1.f, frame_size));
EXPECT_TRUE(views[i]->HasFallbackSurface());
}
@@ -4027,9 +3867,12 @@ TEST_F(RenderWidgetHostViewAuraTest, SourceEventTypeExistsInLatencyInfo) {
// SwapCompositorFrame and OnDidNotProduceFrame IPCs through DelegatedFrameHost
// and its CompositorFrameSinkSupport.
TEST_F(RenderWidgetHostViewAuraTest, ForwardsBeginFrameAcks) {
- // TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
+ // TODO(jonross): Delete this test once Viz launches as it will be obsolete.
+ // https://crbug.com/844469
+ if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
+ !features::IsAshInBrowserProcess()) {
return;
+ }
gfx::Rect view_rect(100, 100);
gfx::Size frame_size = view_rect.size();
@@ -4124,15 +3967,15 @@ TEST_F(RenderWidgetHostViewAuraTest, TouchEventPositionsArentRounded) {
}
// Tests that non-precise mouse-wheel events do not initiate overscroll.
-void RenderWidgetHostViewAuraOverscrollTest::WheelNotPreciseScrollEvent() {
+TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelNotPreciseScrollEvent) {
SetUpOverscrollEnvironment();
// Simulate wheel event. Does not cross start threshold.
- SimulateWheelEventPossiblyIncludingPhase(
- -5, 0, 0, false, WebMouseWheelEvent::kPhaseBegan); // sent directly
+ SimulateWheelEvent(-5, 0, 0, false,
+ WebMouseWheelEvent::kPhaseBegan); // sent directly
// Simulate wheel event. Crosses start threshold.
- SimulateWheelEventPossiblyIncludingPhase(
- -70, 1, 0, false, WebMouseWheelEvent::kPhaseChanged); // enqueued
+ SimulateWheelEvent(-70, 1, 0, false,
+ WebMouseWheelEvent::kPhaseChanged); // enqueued
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
MockWidgetInputHandler::MessageVector events =
@@ -4148,64 +3991,36 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelNotPreciseScrollEvent() {
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- ExpectGestureScrollEndForWheelScrolling(false);
- SendNotConsumedAcks(events);
- events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- }
-
SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
- } else if (wheel_scroll_latching_enabled_) {
- SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- SendNotConsumedAcks(events);
- ExpectGestureScrollEndForWheelScrolling(true);
- } else {
- ExpectGestureScrollEndForWheelScrolling(true);
- }
+ SimulateWheelEvent(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
}
-TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelNotPreciseScrollEvent) {
- WheelNotPreciseScrollEvent();
-}
-TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest,
- WheelNotPreciseScrollEvent) {
- WheelNotPreciseScrollEvent();
-}
-TEST_F(RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest,
- WheelNotPreciseScrollEvent) {
- WheelNotPreciseScrollEvent();
-}
-
// Tests that precise mouse-wheel events initiate overscroll and a mouse move
// will cancel it.
-void RenderWidgetHostViewAuraOverscrollTest::WheelScrollEventOverscrolls() {
+TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelScrollEventOverscrolls) {
SetUpOverscrollEnvironment();
// Simulate wheel events. Do not cross start threshold.
- SimulateWheelEventPossiblyIncludingPhase(
- -5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
- SimulateWheelEventPossiblyIncludingPhase(
- -10, 1, 0, true, WebMouseWheelEvent::kPhaseChanged); // enqueued
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(-5, 0, 0, true,
+ WebMouseWheelEvent::kPhaseBegan); // sent directly
+ SimulateWheelEvent(-10, 1, 0, true,
+ WebMouseWheelEvent::kPhaseChanged); // enqueued
+ SimulateWheelEvent(
-10, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(
-15, -1, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
// Simulate wheel events. Cross start threshold.
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(
-30, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(
-20, 6, 1, true,
WebMouseWheelEvent::kPhaseChanged); // enqueued, different modifiers
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -4222,22 +4037,9 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollEventOverscrolls() {
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) {
- ExpectGestureScrollEndForWheelScrolling(false);
- // Receive ACK for the second (coalesced) event as not processed. This will
- // start a back navigation. However, this will also cause the queued next
- // event to be sent to the renderer. But since overscroll navigation has
- // started, that event will also be included in the overscroll computation
- // 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.
- SendNotConsumedAcks(events);
- events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 1);
- }
SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
ExpectGestureScrollEndForWheelScrolling(false);
SendNotConsumedAcks(events);
- ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
EXPECT_EQ(OverscrollSource::TOUCHPAD, overscroll_source());
@@ -4256,40 +4058,29 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollEventOverscrolls() {
events = GetAndResetDispatchedMessages();
EXPECT_EQ("MouseMove", GetMessageNames(events));
}
-TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelScrollEventOverscrolls) {
- WheelScrollEventOverscrolls();
-}
-TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest,
- WheelScrollEventOverscrolls) {
- WheelScrollEventOverscrolls();
-}
-TEST_F(RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest,
- WheelScrollEventOverscrolls) {
- WheelScrollEventOverscrolls();
-}
// Tests that if some scroll events are consumed towards the start, then
// subsequent scrolls do not overscroll.
-void RenderWidgetHostViewAuraOverscrollTest::
- WheelScrollConsumedDoNotOverscroll() {
+TEST_F(RenderWidgetHostViewAuraOverscrollTest,
+ WheelScrollConsumedDoNotOverscroll) {
SetUpOverscrollEnvironment();
// Simulate wheel events. Do not cross start threshold.
- SimulateWheelEventPossiblyIncludingPhase(
- -5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
- SimulateWheelEventPossiblyIncludingPhase(
- -10, -1, 0, true, WebMouseWheelEvent::kPhaseChanged); // enqueued
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(-5, 0, 0, true,
+ WebMouseWheelEvent::kPhaseBegan); // sent directly
+ SimulateWheelEvent(-10, -1, 0, true,
+ WebMouseWheelEvent::kPhaseChanged); // enqueued
+ SimulateWheelEvent(
-10, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(
-15, -1, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
// Simulate wheel events. Cross start threshold.
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(
-30, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(
-20, 6, 1, true,
WebMouseWheelEvent::kPhaseChanged); // enqueued, different modifiers
@@ -4308,68 +4099,24 @@ void RenderWidgetHostViewAuraOverscrollTest::
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- 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.
- SendNotConsumedAcks(events);
- events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 1);
- }
- EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
- EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
-
- 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.
SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_CONSUMED);
- } else {
- 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);
+ SimulateWheelEvent(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
events = GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
- } else if (wheel_scroll_latching_enabled_) {
- SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- SendNotConsumedAcks(events);
- events = ExpectGestureScrollEndForWheelScrolling(true);
- } else {
- events = ExpectGestureScrollEndForWheelScrolling(true);
- }
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
}
-TEST_F(RenderWidgetHostViewAuraOverscrollTest,
- WheelScrollConsumedDoNotOverscroll) {
- WheelScrollConsumedDoNotOverscroll();
-}
-TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest,
- WheelScrollConsumedDoNotOverscroll) {
- WheelScrollConsumedDoNotOverscroll();
-}
-TEST_F(RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest,
- WheelScrollConsumedDoNotOverscroll) {
- WheelScrollConsumedDoNotOverscroll();
-}
// Tests that wheel-scrolling correctly turns overscroll on and off.
-void RenderWidgetHostViewAuraOverscrollTest::WheelScrollOverscrollToggle() {
+TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelScrollOverscrollToggle) {
SetUpOverscrollEnvironment();
// Send a wheel event. ACK the event as not processed. This should not
// initiate an overscroll gesture since it doesn't cross the threshold yet.
- SimulateWheelEventPossiblyIncludingPhase(10, 0, 0, true,
- WebMouseWheelEvent::kPhaseBegan);
+ SimulateWheelEvent(10, 0, 0, true, WebMouseWheelEvent::kPhaseBegan);
MockWidgetInputHandler::MessageVector events =
GetAndResetDispatchedMessages();
@@ -4387,16 +4134,8 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollOverscrollToggle() {
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
// Scroll some more so as to not overscroll.
- SimulateWheelEventPossiblyIncludingPhase(10, 0, 0, true,
- WebMouseWheelEvent::kPhaseChanged);
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- events = ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
- } else {
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- SendNotConsumedAcks(events);
- events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- }
+ SimulateWheelEvent(10, 0, 0, true, WebMouseWheelEvent::kPhaseChanged);
+ events = ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
ExpectGestureScrollEndForWheelScrolling(false);
@@ -4405,16 +4144,9 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollOverscrollToggle() {
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
// Scroll some more to initiate an overscroll.
- SimulateWheelEventPossiblyIncludingPhase(50, 0, 0, true,
- WebMouseWheelEvent::kPhaseChanged);
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- events = ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
- } else {
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- SendNotConsumedAcks(events);
- events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- }
+ SimulateWheelEvent(50, 0, 0, true, WebMouseWheelEvent::kPhaseChanged);
+
+ events = ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
ExpectGestureScrollEndForWheelScrolling(false);
@@ -4427,29 +4159,18 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollOverscrollToggle() {
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);
+ SimulateWheelEvent(-20, 0, 0, true, WebMouseWheelEvent::kPhaseChanged);
events = GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel", GetMessageNames(events));
- if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendNotConsumedAcks(events);
- ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
- }
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
// Continue to scroll in the reverse direction.
- SimulateWheelEventPossiblyIncludingPhase(-20, 0, 0, true,
- WebMouseWheelEvent::kPhaseChanged);
+ SimulateWheelEvent(-20, 0, 0, true, WebMouseWheelEvent::kPhaseChanged);
events = GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel", GetMessageNames(events));
- if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendNotConsumedAcks(events);
- ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
- }
-
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
@@ -4457,27 +4178,13 @@ 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(-65, 0, 0, true,
- WebMouseWheelEvent::kPhaseChanged);
+ SimulateWheelEvent(-65, 0, 0, true, WebMouseWheelEvent::kPhaseChanged);
events = GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel", GetMessageNames(events));
- if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendNotConsumedAcks(events);
- ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
- }
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
- } else if (wheel_scroll_latching_enabled_) {
- SimulateWheelEventWithPhase(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- SendNotConsumedAcks(events);
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
- }
+ SimulateWheelEvent(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel GestureScrollEnd", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
@@ -4486,26 +4193,15 @@ void RenderWidgetHostViewAuraOverscrollTest::WheelScrollOverscrollToggle() {
EXPECT_EQ(0.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
}
-TEST_F(RenderWidgetHostViewAuraOverscrollTest, WheelScrollOverscrollToggle) {
- WheelScrollOverscrollToggle();
-}
-TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest,
- WheelScrollOverscrollToggle) {
- WheelScrollOverscrollToggle();
-}
-TEST_F(RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest,
- WheelScrollOverscrollToggle) {
- WheelScrollOverscrollToggle();
-}
// Tests that a small fling after overscroll is initiated aborts the overscroll.
-void RenderWidgetHostViewAuraOverscrollTest::ScrollEventsOverscrollWithFling() {
+TEST_F(RenderWidgetHostViewAuraOverscrollTest,
+ ScrollEventsOverscrollWithFling) {
SetUpOverscrollEnvironment();
// Send a wheel event. ACK the event as not processed. This should not
// initiate an overscroll gesture since it doesn't cross the threshold yet.
- SimulateWheelEventPossiblyIncludingPhase(10, 0, 0, true,
- WebMouseWheelEvent::kPhaseBegan);
+ SimulateWheelEvent(10, 0, 0, true, WebMouseWheelEvent::kPhaseBegan);
MockWidgetInputHandler::MessageVector events =
GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel", GetMessageNames(events));
@@ -4521,32 +4217,18 @@ void RenderWidgetHostViewAuraOverscrollTest::ScrollEventsOverscrollWithFling() {
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
// Scroll some more so as to not overscroll.
- SimulateWheelEventPossiblyIncludingPhase(20, 0, 0, true,
- WebMouseWheelEvent::kPhaseChanged);
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
- } else {
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- SendNotConsumedAcks(events);
- events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- }
+ SimulateWheelEvent(20, 0, 0, true, WebMouseWheelEvent::kPhaseChanged);
+ ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
+
SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
// Scroll some more to initiate an overscroll.
- SimulateWheelEventPossiblyIncludingPhase(40, 0, 0, true,
- WebMouseWheelEvent::kPhaseChanged);
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
- } else {
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- SendNotConsumedAcks(events);
- events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- }
+ SimulateWheelEvent(40, 0, 0, true, WebMouseWheelEvent::kPhaseChanged);
+ ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
+
SendNotConsumedAcks(events);
ExpectGestureScrollEndForWheelScrolling(false);
@@ -4579,29 +4261,16 @@ void RenderWidgetHostViewAuraOverscrollTest::ScrollEventsOverscrollWithFling() {
}
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
}
-TEST_F(RenderWidgetHostViewAuraOverscrollTest,
- ScrollEventsOverscrollWithFling) {
- ScrollEventsOverscrollWithFling();
-}
-TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest,
- ScrollEventsOverscrollWithFling) {
- ScrollEventsOverscrollWithFling();
-}
-TEST_F(RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest,
- ScrollEventsOverscrollWithFling) {
- ScrollEventsOverscrollWithFling();
-}
// Same as ScrollEventsOverscrollWithFling, but with zero velocity. Checks that
// the zero-velocity fling does not reach the renderer.
-void RenderWidgetHostViewAuraOverscrollTest::
- ScrollEventsOverscrollWithZeroFling() {
+TEST_F(RenderWidgetHostViewAuraOverscrollTest,
+ ScrollEventsOverscrollWithZeroFling) {
SetUpOverscrollEnvironment();
// Send a wheel event. ACK the event as not processed. This should not
// initiate an overscroll gesture since it doesn't cross the threshold yet.
- SimulateWheelEventPossiblyIncludingPhase(10, 0, 0, true,
- WebMouseWheelEvent::kPhaseBegan);
+ SimulateWheelEvent(10, 0, 0, true, WebMouseWheelEvent::kPhaseBegan);
MockWidgetInputHandler::MessageVector events =
GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel", GetMessageNames(events));
@@ -4617,16 +4286,8 @@ void RenderWidgetHostViewAuraOverscrollTest::
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
// Scroll some more so as to not overscroll.
- SimulateWheelEventPossiblyIncludingPhase(20, 0, 0, true,
- WebMouseWheelEvent::kPhaseChanged);
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
- } else {
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- SendNotConsumedAcks(events);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- }
+ SimulateWheelEvent(20, 0, 0, true, WebMouseWheelEvent::kPhaseChanged);
+ ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
ExpectGestureScrollEndForWheelScrolling(false);
@@ -4635,16 +4296,8 @@ void RenderWidgetHostViewAuraOverscrollTest::
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
// Scroll some more to initiate an overscroll.
- SimulateWheelEventPossiblyIncludingPhase(40, 0, 0, true,
- WebMouseWheelEvent::kPhaseChanged);
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
- } else {
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- SendNotConsumedAcks(events);
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- }
+ SimulateWheelEvent(40, 0, 0, true, WebMouseWheelEvent::kPhaseChanged);
+ ExpectGestureScrollUpdateAfterNonBlockingMouseWheelACK(false);
SendNotConsumedAcks(events);
ExpectGestureScrollEndForWheelScrolling(false);
@@ -4678,18 +4331,6 @@ void RenderWidgetHostViewAuraOverscrollTest::
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
}
-TEST_F(RenderWidgetHostViewAuraOverscrollTest,
- ScrollEventsOverscrollWithZeroFling) {
- ScrollEventsOverscrollWithZeroFling();
-}
-TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest,
- ScrollEventsOverscrollWithZeroFling) {
- ScrollEventsOverscrollWithZeroFling();
-}
-TEST_F(RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest,
- ScrollEventsOverscrollWithZeroFling) {
- ScrollEventsOverscrollWithZeroFling();
-}
// Tests that a fling in the opposite direction of the overscroll cancels the
// overscroll instead of completing it.
@@ -4705,6 +4346,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
SetUpOverscrollEnvironment();
{
+ PressAndSetTouchActionAuto();
// Start and end a gesture in the same direction without processing the
// gesture events in the renderer. This should initiate and complete an
// overscroll.
@@ -4727,9 +4369,11 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
+ ReleaseAndResetDispatchedMessages();
}
{
+ PressAndSetTouchActionAuto();
// Start over, except instead of ending the gesture with ScrollEnd, end it
// with a FlingStart, with velocity in the reverse direction. This should
// initiate an overscroll, the overscroll mode should get reset after the
@@ -4762,6 +4406,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
base::TimeTicks::Now() + base::TimeDelta::FromMilliseconds(17);
widget_host_->ProgressFlingIfNeeded(progress_time);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
+ ReleaseAndResetDispatchedMessages();
}
}
@@ -4771,6 +4416,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
TEST_F(RenderWidgetHostViewAuraOverscrollTest, GestureScrollOverscrolls) {
SetUpOverscrollEnvironment();
+ PressAndSetTouchActionAuto();
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
MockWidgetInputHandler::MessageVector events =
@@ -4819,6 +4465,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, GestureScrollOverscrolls) {
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
+ ReleaseAndResetDispatchedMessages();
}
// Tests that when a cap is set for overscroll delta, extra overscroll delta is
@@ -4826,6 +4473,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, GestureScrollOverscrolls) {
TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDeltaCap) {
SetUpOverscrollEnvironment();
+ PressAndSetTouchActionAuto();
// Set overscroll cap and start scrolling.
overscroll_delegate()->set_delta_cap(50);
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
@@ -4884,6 +4532,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDeltaCap) {
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
+ ReleaseAndResetDispatchedMessages();
}
// Tests that if the page is scrolled because of a scroll-gesture, then that
@@ -4891,6 +4540,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDeltaCap) {
TEST_F(RenderWidgetHostViewAuraOverscrollTest, GestureScrollConsumed) {
SetUpOverscrollEnvironment();
+ PressAndSetTouchActionAuto();
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
SimulateGestureScrollUpdateEvent(10, 0, 0);
@@ -4916,6 +4566,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, GestureScrollConsumed) {
SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
+ ReleaseAndResetDispatchedMessages();
}
// Tests that the overscroll controller plays nice with touch-scrolls and the
@@ -4924,6 +4575,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
GestureScrollDebounceOverscrolls) {
SetUpOverscrollEnvironmentWithDebounce(100);
+ PressAndSetTouchActionAuto();
// Start scrolling. Receive ACK as it being processed.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
@@ -4944,7 +4596,9 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
MockWidgetInputHandler::MessageVector second_scroll_update_events =
GetAndResetDispatchedMessages();
EXPECT_EQ(0U, second_scroll_update_events.size());
+ ReleaseAndResetDispatchedMessages();
+ PressAndSetTouchActionAuto();
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
second_scroll_update_events = GetAndResetDispatchedMessages();
@@ -4993,6 +4647,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
EXPECT_EQ(65.f, overscroll_delta_x());
EXPECT_EQ(15.f, overscroll_delegate()->delta_x());
EXPECT_EQ(0.f, overscroll_delegate()->delta_y());
+ ReleaseAndResetDispatchedMessages();
}
// Tests that the gesture debounce timer plays nice with the overscroll
@@ -5001,6 +4656,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
GestureScrollDebounceTimerOverscroll) {
SetUpOverscrollEnvironmentWithDebounce(10);
+ PressAndSetTouchActionAuto();
// Start scrolling. Receive ACK as it being processed.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
@@ -5018,6 +4674,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
SimulateGestureEvent(WebInputEvent::kGestureScrollEnd,
blink::kWebGestureDeviceTouchscreen);
EXPECT_EQ(0U, GetAndResetDispatchedMessages().size());
+ ReleaseAndResetDispatchedMessages();
// Receive ACK for the scroll-update event.
SendNotConsumedAcks(events);
@@ -5052,6 +4709,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollWithTouchEvents) {
// The test sends an intermingled sequence of touch and gesture events.
PressTouchPoint(0, 1);
SendTouchEvent();
+ widget_host_->input_router()->OnSetTouchAction(cc::kTouchActionAuto);
MockWidgetInputHandler::MessageVector events =
GetAndResetDispatchedMessages();
EXPECT_EQ("TouchStart", GetMessageNames(events));
@@ -5172,6 +4830,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
SetUpOverscrollEnvironmentWithDebounce(10);
widget_host_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true));
+ PressAndSetTouchActionAuto();
// Start scrolling. Receive ACK as it being processed.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
@@ -5215,7 +4874,9 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->completed_mode());
events = GetAndResetDispatchedMessages();
EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
+ ReleaseAndResetDispatchedMessages();
+ PressAndSetTouchActionAuto();
// Start scrolling. Receive ACK as it being processed.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
@@ -5256,6 +4917,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
events = GetAndResetDispatchedMessages();
EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
+ ReleaseAndResetDispatchedMessages();
}
// Tests that after touchscreen overscroll is initiated, scrolling in the
@@ -5265,6 +4927,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDirectionChange) {
SetUpOverscrollEnvironmentWithDebounce(100);
+ PressAndSetTouchActionAuto();
// Start scrolling. Receive ACK as it being processed.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
@@ -5300,12 +4963,14 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollDirectionChange) {
EXPECT_EQ(0U, events.size());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
+ ReleaseAndResetDispatchedMessages();
}
TEST_F(RenderWidgetHostViewAuraOverscrollTest,
CompleteOverscrollOnGestureScrollEndAck) {
SetUpOverscrollEnvironment();
+ PressAndSetTouchActionAuto();
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
MockWidgetInputHandler::MessageVector events =
@@ -5332,12 +4997,14 @@ 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());
+ ReleaseAndResetDispatchedMessages();
}
TEST_F(RenderWidgetHostViewAuraOverscrollTest,
InterleavedScrollUpdateAckAndScrollEnd) {
SetUpOverscrollEnvironment();
+ PressAndSetTouchActionAuto();
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
SimulateGestureScrollUpdateEvent(30, -5, 0);
@@ -5368,19 +5035,19 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest,
EXPECT_EQ(2U, overscroll_delegate()->historical_modes().size());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->historical_modes().at(0));
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->historical_modes().at(1));
+ ReleaseAndResetDispatchedMessages();
}
// Tests that after touchpad overscroll is initiated, scrolling in the opposite
// direction ends the overscroll in the original direction without initiating
// overscroll in the opposite direction. The scroll-update events should still
// be consumed to prevent content scroll.
-void RenderWidgetHostViewAuraOverscrollTest::
- OverscrollDirectionChangeMouseWheel() {
+TEST_F(RenderWidgetHostViewAuraOverscrollTest,
+ OverscrollDirectionChangeMouseWheel) {
SetUpOverscrollEnvironment();
// Send wheel event and receive ack as not consumed.
- SimulateWheelEventPossiblyIncludingPhase(125, -5, 0, true,
- WebMouseWheelEvent::kPhaseBegan);
+ SimulateWheelEvent(125, -5, 0, true, WebMouseWheelEvent::kPhaseBegan);
MockWidgetInputHandler::MessageVector events =
GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel", GetMessageNames(events));
@@ -5400,15 +5067,10 @@ void RenderWidgetHostViewAuraOverscrollTest::
// Send another wheel event, but in the reverse direction. Although the
// overscroll controller is not triggering overscroll, it will consume the
// ScrollUpdate event to prevent content scroll.
- SimulateWheelEventPossiblyIncludingPhase(-260, 0, 0, true,
- WebMouseWheelEvent::kPhaseChanged);
+ SimulateWheelEvent(-260, 0, 0, true, WebMouseWheelEvent::kPhaseChanged);
events = GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel", GetMessageNames(events));
- if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendNotConsumedAcks(events);
- ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
- }
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
@@ -5419,48 +5081,31 @@ void RenderWidgetHostViewAuraOverscrollTest::
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- SimulateWheelEventPossiblyIncludingPhase(-20, 0, 0, true,
- WebMouseWheelEvent::kPhaseChanged);
+ SimulateWheelEvent(-20, 0, 0, true, WebMouseWheelEvent::kPhaseChanged);
events = GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel", GetMessageNames(events));
- if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- SendNotConsumedAcks(events);
- ExpectGestureScrollEventsAfterMouseWheelAckWhenOverscrolling();
- }
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
}
-TEST_F(RenderWidgetHostViewAuraOverscrollTest,
- OverscrollDirectionChangeMouseWheel) {
- OverscrollDirectionChangeMouseWheel();
-}
-TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest,
- OverscrollDirectionChangeMouseWheel) {
- OverscrollDirectionChangeMouseWheel();
-}
-TEST_F(RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest,
- OverscrollDirectionChangeMouseWheel) {
- OverscrollDirectionChangeMouseWheel();
-}
// Tests that mouse-move completes overscoll if it has passed activation
// threshold and aborts it otherwise.
-void RenderWidgetHostViewAuraOverscrollTest::OverscrollMouseMoveCompletion() {
+TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollMouseMoveCompletion) {
SetUpOverscrollEnvironment();
- SimulateWheelEventPossiblyIncludingPhase(
- -5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
- SimulateWheelEventPossiblyIncludingPhase(
- -10, 0, 0, true, WebMouseWheelEvent::kPhaseChanged); // enqueued
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(-5, 0, 0, true,
+ WebMouseWheelEvent::kPhaseBegan); // sent directly
+ SimulateWheelEvent(-10, 0, 0, true,
+ WebMouseWheelEvent::kPhaseChanged); // enqueued
+ SimulateWheelEvent(
-10, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(
-15, -1, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(
-30, -3, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
@@ -5479,14 +5124,6 @@ void RenderWidgetHostViewAuraOverscrollTest::OverscrollMouseMoveCompletion() {
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
- 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.
- ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- }
-
SendNotConsumedAcks(events);
ExpectGestureScrollEndForWheelScrolling(false);
@@ -5514,6 +5151,7 @@ void RenderWidgetHostViewAuraOverscrollTest::OverscrollMouseMoveCompletion() {
SendNotConsumedAcks(events);
// Now try with gestures.
+ PressAndSetTouchActionAuto();
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
blink::kWebGestureDeviceTouchscreen);
SendScrollBeginAckIfNeeded(INPUT_EVENT_ACK_STATE_CONSUMED);
@@ -5542,38 +5180,28 @@ void RenderWidgetHostViewAuraOverscrollTest::OverscrollMouseMoveCompletion() {
events = GetAndResetDispatchedMessages();
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
+ ReleaseAndResetDispatchedMessages();
// Move mouse some more. The mouse-move events should reach the renderer.
SimulateMouseMove(5, 10, 0);
events = GetAndResetDispatchedMessages();
EXPECT_EQ("MouseMove", GetMessageNames(events));
}
-TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollMouseMoveCompletion) {
- OverscrollMouseMoveCompletion();
-}
-TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest,
- OverscrollMouseMoveCompletion) {
- OverscrollMouseMoveCompletion();
-}
-TEST_F(RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest,
- OverscrollMouseMoveCompletion) {
- OverscrollMouseMoveCompletion();
-}
// Tests that if a page scrolled, then the overscroll controller's states are
// reset after the end of the scroll.
-void RenderWidgetHostViewAuraOverscrollTest::
- OverscrollStateResetsAfterScroll() {
+TEST_F(RenderWidgetHostViewAuraOverscrollTest,
+ OverscrollStateResetsAfterScroll) {
SetUpOverscrollEnvironment();
- SimulateWheelEventPossiblyIncludingPhase(
- 0, 5, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
- SimulateWheelEventPossiblyIncludingPhase(
- 0, 30, 0, true, WebMouseWheelEvent::kPhaseChanged); // enqueued
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(0, 5, 0, true,
+ WebMouseWheelEvent::kPhaseBegan); // sent directly
+ SimulateWheelEvent(0, 30, 0, true,
+ WebMouseWheelEvent::kPhaseChanged); // enqueued
+ SimulateWheelEvent(
0, 40, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(
0, 10, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
@@ -5589,13 +5217,6 @@ void RenderWidgetHostViewAuraOverscrollTest::
SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_TRUE(ScrollStateIsContentConsuming());
- if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- ExpectGestureScrollEndForWheelScrolling(false);
- // The second wheel event is not consumed.
- SendNotConsumedAcks(events);
-
- events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- }
SendScrollUpdateAck(events, INPUT_EVENT_ACK_STATE_CONSUMED);
EXPECT_TRUE(ScrollStateIsContentConsuming());
@@ -5619,11 +5240,11 @@ void RenderWidgetHostViewAuraOverscrollTest::
// consumed and have triggered a fling animation (as tracked by the router).
EXPECT_FALSE(parent_host_->input_router()->HasPendingEvents());
- SimulateWheelEventPossiblyIncludingPhase(
- -5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
- SimulateWheelEventPossiblyIncludingPhase(
- -60, 0, 0, true, WebMouseWheelEvent::kPhaseChanged); // enqueued
- SimulateWheelEventPossiblyIncludingPhase(
+ SimulateWheelEvent(-5, 0, 0, true,
+ WebMouseWheelEvent::kPhaseBegan); // sent directly
+ SimulateWheelEvent(-60, 0, 0, true,
+ WebMouseWheelEvent::kPhaseChanged); // enqueued
+ SimulateWheelEvent(
-100, 0, 0, true,
WebMouseWheelEvent::kPhaseChanged); // coalesced into previous event
@@ -5639,12 +5260,6 @@ void RenderWidgetHostViewAuraOverscrollTest::
EXPECT_TRUE(ScrollStateIsUnknown());
- if (wheel_scrolling_mode_ != kAsyncWheelEvents) {
- events = ExpectGestureScrollEndForWheelScrolling(false);
- SendNotConsumedAcks(events);
- events = ExpectGestureScrollEventsAfterMouseWheelACK(false, 0);
- }
-
SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_WEST, overscroll_mode());
@@ -5674,24 +5289,13 @@ void RenderWidgetHostViewAuraOverscrollTest::
events = GetAndResetDispatchedMessages();
EXPECT_EQ(0u, events.size());
}
-TEST_F(RenderWidgetHostViewAuraOverscrollTest,
- OverscrollStateResetsAfterScroll) {
- OverscrollStateResetsAfterScroll();
-}
-TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest,
- OverscrollStateResetsAfterScroll) {
- OverscrollStateResetsAfterScroll();
-}
-TEST_F(RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest,
- OverscrollStateResetsAfterScroll) {
- OverscrollStateResetsAfterScroll();
-}
// Tests that overscroll is reset when window loses focus. It should not affect
// subsequent overscrolls.
TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollResetsOnBlur) {
SetUpOverscrollEnvironment();
+ PressAndSetTouchActionAuto();
// Start an overscroll with gesture scroll. In the middle of the scroll, blur
// the host.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
@@ -5719,7 +5323,9 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollResetsOnBlur) {
blink::kWebGestureDeviceTouchscreen);
events = GetAndResetDispatchedMessages();
EXPECT_EQ("SetFocus GestureScrollEnd", GetMessageNames(events));
+ ReleaseAndResetDispatchedMessages();
+ PressAndSetTouchActionAuto();
// Start a scroll gesture again. This should correctly start the overscroll
// after the threshold.
SimulateGestureEvent(WebInputEvent::kGestureScrollBegin,
@@ -5742,6 +5348,7 @@ TEST_F(RenderWidgetHostViewAuraOverscrollTest, OverscrollResetsOnBlur) {
EXPECT_EQ(OVERSCROLL_NONE, overscroll_delegate()->current_mode());
EXPECT_EQ(OVERSCROLL_EAST, overscroll_delegate()->completed_mode());
EXPECT_EQ("GestureScrollEnd", GetMessageNames(events));
+ ReleaseAndResetDispatchedMessages();
}
#if defined(OS_CHROMEOS)
@@ -5900,13 +5507,20 @@ TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) {
base::RunLoop().RunUntilIdle();
events = GetAndResetDispatchedMessages();
+ // Since the modifiers has changed a wheel end event will be sent before
+ // dispatching the wheel event.
+ EXPECT_EQ(2u, events.size());
wheel_event = static_cast<const WebMouseWheelEvent*>(
events[0]->ToEvent()->Event()->web_event.get());
+ EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase);
+
// Check if scroll is caused when no modifier is applied to the
// mouse wheel event.
+ wheel_event = static_cast<const WebMouseWheelEvent*>(
+ events[1]->ToEvent()->Event()->web_event.get());
EXPECT_TRUE(WebInputEventTraits::CanCauseScroll(*wheel_event));
- events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
+ events[1]->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(),
@@ -5915,10 +5529,16 @@ TEST_F(RenderWidgetHostViewAuraTest, SetCanScrollForWebMouseWheelEvent) {
base::RunLoop().RunUntilIdle();
events = GetAndResetDispatchedMessages();
+ // Since the modifiers has changed a wheel end event will be sent before
+ // dispatching the wheel event.
+ EXPECT_EQ(2u, events.size());
wheel_event = static_cast<const WebMouseWheelEvent*>(
events[0]->ToEvent()->Event()->web_event.get());
+ EXPECT_EQ(WebMouseWheelEvent::kPhaseEnded, wheel_event->phase);
// Check if scroll is caused when ctrl-touchpad-scroll is generated
// from scroll event.
+ wheel_event = static_cast<const WebMouseWheelEvent*>(
+ events[1]->ToEvent()->Event()->web_event.get());
EXPECT_TRUE(WebInputEventTraits::CanCauseScroll(*wheel_event));
}
@@ -5955,11 +5575,13 @@ TEST_F(RenderWidgetHostViewAuraTest, CorrectNumberOfAcksAreDispatched) {
// Tests that the scroll deltas stored within the overscroll controller get
// reset at the end of the overscroll gesture even if the overscroll threshold
// isn't surpassed and the overscroll mode stays OVERSCROLL_NONE.
-void RenderWidgetHostViewAuraOverscrollTest::ScrollDeltasResetOnEnd() {
+TEST_F(RenderWidgetHostViewAuraOverscrollTest, ScrollDeltasResetOnEnd) {
SetUpOverscrollEnvironment();
+
+ PressAndSetTouchActionAuto();
// Wheel event scroll ending with mouse move.
- SimulateWheelEventPossiblyIncludingPhase(
- -30, -10, 0, true, WebMouseWheelEvent::kPhaseBegan); // sent directly
+ SimulateWheelEvent(-30, -10, 0, true,
+ WebMouseWheelEvent::kPhaseBegan); // sent directly
MockWidgetInputHandler::MessageVector events =
GetAndResetDispatchedMessages();
EXPECT_EQ("MouseWheel", GetMessageNames(events));
@@ -5977,8 +5599,7 @@ void RenderWidgetHostViewAuraOverscrollTest::ScrollDeltasResetOnEnd() {
// A wheel event with phase ended is sent before a GSB with touchscreen
// device.
- SimulateWheelEventPossiblyIncludingPhase(0, 0, 0, true,
- WebMouseWheelEvent::kPhaseEnded);
+ SimulateWheelEvent(0, 0, 0, true, WebMouseWheelEvent::kPhaseEnded);
events = GetAndResetDispatchedMessages();
SendNotConsumedAcks(events);
@@ -5999,11 +5620,11 @@ void RenderWidgetHostViewAuraOverscrollTest::ScrollDeltasResetOnEnd() {
EXPECT_EQ(0.f, overscroll_delta_y());
events = GetAndResetDispatchedMessages();
SendNotConsumedAcks(events);
+ ReleaseAndResetDispatchedMessages();
// 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);
+ SimulateWheelEvent(5, 0, 0, true, WebMouseWheelEvent::kPhaseBegan);
// ACK the MouseWheel event
events = GetAndResetDispatchedMessages();
SendNotConsumedAcks(events);
@@ -6012,17 +5633,10 @@ void RenderWidgetHostViewAuraOverscrollTest::ScrollDeltasResetOnEnd() {
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) {
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
- } else {
- events = GetAndResetDispatchedMessages();
- EXPECT_EQ("MouseWheel", GetMessageNames(events));
- SendNotConsumedAcks(events);
- events = GetAndResetDispatchedMessages();
- }
+ SimulateWheelEvent(10, -5, 0, true, WebMouseWheelEvent::kPhaseChanged);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
+
SendNotConsumedAcks(events);
EXPECT_EQ(OVERSCROLL_NONE, overscroll_mode());
EXPECT_EQ(OverscrollSource::NONE, overscroll_source());
@@ -6041,17 +5655,6 @@ void RenderWidgetHostViewAuraOverscrollTest::ScrollDeltasResetOnEnd() {
progress_time += base::TimeDelta::FromMilliseconds(17);
}
}
-TEST_F(RenderWidgetHostViewAuraOverscrollTest, ScrollDeltasResetOnEnd) {
- ScrollDeltasResetOnEnd();
-}
-TEST_F(RenderWidgetHostViewAuraOverscrollWithoutWheelScrollLatchingTest,
- ScrollDeltasResetOnEnd) {
- ScrollDeltasResetOnEnd();
-}
-TEST_F(RenderWidgetHostViewAuraOverScrollAsyncWheelEventsEnabledTest,
- ScrollDeltasResetOnEnd) {
- ScrollDeltasResetOnEnd();
-}
TEST_F(RenderWidgetHostViewAuraTest, ForwardMouseEvent) {
aura::Window* root = parent_view_->GetNativeView()->GetRootWindow();
@@ -6096,6 +5699,50 @@ TEST_F(RenderWidgetHostViewAuraTest, ForwardMouseEvent) {
view_ = nullptr;
}
+// Test that we elide touchpad pinch gesture steams consisting of only begin
+// and end events.
+TEST_F(RenderWidgetHostViewAuraTest, ElideEmptyTouchpadPinchSequence) {
+ ui::GestureEventDetails begin_details(ui::ET_GESTURE_PINCH_BEGIN);
+ begin_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHPAD);
+ ui::GestureEvent begin_event(0, 0, 0, ui::EventTimeForNow(), begin_details);
+
+ ui::GestureEventDetails update_details(ui::ET_GESTURE_PINCH_UPDATE);
+ update_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHPAD);
+ update_details.set_scale(1.23);
+ ui::GestureEvent update_event(0, 0, 0, ui::EventTimeForNow(), update_details);
+
+ ui::GestureEventDetails end_details(ui::ET_GESTURE_PINCH_END);
+ end_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHPAD);
+ ui::GestureEvent end_event(0, 0, 0, ui::EventTimeForNow(), end_details);
+
+ view_->OnGestureEvent(&begin_event);
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ GetAndResetDispatchedMessages();
+ // Since we don't know if we'll have GesturePinchUpdates at this point, the
+ // GesturePinchBegin should not be sent yet.
+ EXPECT_EQ(0U, events.size());
+
+ view_->OnGestureEvent(&update_event);
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+
+ // If the page consumes the update, then no GesturePinchUpdate is sent and
+ // we continue to postpone sending the GesturePinchBegin.
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
+ events = GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
+
+ view_->OnGestureEvent(&end_event);
+ base::RunLoop().RunUntilIdle();
+ events = GetAndResetDispatchedMessages();
+ // Since we have not sent any GesturePinchUpdates by the time we get to the
+ // end of the pinch, the GesturePinchBegin and GesturePinchEnd events should
+ // be elided.
+ EXPECT_EQ(0U, events.size());
+}
+
TEST_F(RenderWidgetHostViewAuraTest, GestureTapFromStylusHasPointerType) {
view_->InitAsFullscreen(parent_view_);
view_->Show();
@@ -6108,6 +5755,7 @@ TEST_F(RenderWidgetHostViewAuraTest, GestureTapFromStylusHasPointerType) {
// Simulate touch press and release to generate a GestureTap.
generator.EnterPenPointerMode();
generator.PressTouch();
+ widget_host_->input_router()->OnSetTouchAction(cc::kTouchActionAuto);
generator.ReleaseTouch();
base::RunLoop().RunUntilIdle();
MockWidgetInputHandler::MessageVector events =
@@ -6130,9 +5778,12 @@ TEST_F(RenderWidgetHostViewAuraTest, GestureTapFromStylusHasPointerType) {
// SubmitCompositorFrame becomes the active hit test region in the
// viz::HitTestManager.
TEST_F(RenderWidgetHostViewAuraTest, HitTestRegionListSubmitted) {
- // TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
+ // TODO(jonross): Delete this test once Viz launches as it will be obsolete.
+ // https://crbug.com/844469
+ if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
+ !features::IsAshInBrowserProcess()) {
return;
+ }
gfx::Rect view_rect(0, 0, 100, 100);
gfx::Size frame_size = view_rect.size();
@@ -6172,7 +5823,7 @@ TEST_F(RenderWidgetHostViewAuraTest, HitTestRegionListSubmitted) {
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
NewContentRenderingTimeout) {
// TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
+ if (!features::IsAshInBrowserProcess())
return;
constexpr base::TimeDelta kTimeout = base::TimeDelta::FromMicroseconds(10);
@@ -6187,8 +5838,8 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
viz::LocalSurfaceId id0 = view_->GetLocalSurfaceId();
EXPECT_TRUE(id0.is_valid());
- // No new LocalSurfaceId should be allocated for the first navigation but the
- // timer should fire.
+ // No new LocalSurfaceId should be allocated for the first navigation and the
+ // timer should not fire.
widget_host_->DidNavigate(1);
viz::LocalSurfaceId id1 = view_->GetLocalSurfaceId();
EXPECT_EQ(id0, id1);
@@ -6198,7 +5849,15 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
FROM_HERE, run_loop.QuitClosure(), 2 * kTimeout);
run_loop.Run();
}
- EXPECT_TRUE(widget_host_->new_content_rendering_timeout_fired());
+ if (base::FeatureList::IsEnabled(features::kEnableSurfaceSynchronization)) {
+ // When using surface sync, the timer should not fire, because the surface
+ // id did not change.
+ EXPECT_FALSE(widget_host_->new_content_rendering_timeout_fired());
+ } else {
+ // When not using surface sync, the timer will fire because the source id
+ // changed.
+ EXPECT_TRUE(widget_host_->new_content_rendering_timeout_fired());
+ }
widget_host_->reset_new_content_rendering_timeout_fired();
// Start the timer. Verify that a new LocalSurfaceId is allocated.
@@ -6242,7 +5901,7 @@ TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
TEST_F(RenderWidgetHostViewAuraSurfaceSynchronizationTest,
AllocateLocalSurfaceIdOnEviction) {
// TODO: fix for mash.
- if (base::FeatureList::IsEnabled(features::kMash))
+ if (!features::IsAshInBrowserProcess())
return;
view_->InitAsChild(nullptr);
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 1c52a5fd396..5561b7a1f38 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
@@ -27,7 +27,6 @@
#include "content/browser/renderer_host/render_widget_host_view_child_frame.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "content/common/content_switches_internal.h"
-#include "content/public/common/content_features.h"
#include "ui/base/layout.h"
#include "ui/base/ui_base_types.h"
#include "ui/display/screen.h"
@@ -52,8 +51,6 @@ RenderWidgetHostViewBase::RenderWidgetHostViewBase(RenderWidgetHost* host)
current_device_scale_factor_(0),
current_display_rotation_(display::Display::ROTATE_0),
text_input_manager_(nullptr),
- wheel_scroll_latching_enabled_(base::FeatureList::IsEnabled(
- features::kTouchpadAndWheelScrollLatching)),
web_contents_accessibility_(nullptr),
is_currently_scrolling_viewport_(false),
use_viz_hit_test_(features::IsVizHitTestingEnabled()),
@@ -64,7 +61,7 @@ RenderWidgetHostViewBase::RenderWidgetHostViewBase(RenderWidgetHost* host)
RenderWidgetHostViewBase::~RenderWidgetHostViewBase() {
DCHECK(!keyboard_locked_);
- DCHECK(!mouse_locked_);
+ DCHECK(!IsMouseLocked());
// We call this here to guarantee that observers are notified before we go
// away. However, some subclasses may wish to call this earlier in their
// shutdown process, e.g. to force removal from
@@ -116,7 +113,10 @@ bool RenderWidgetHostViewBase::OnMessageReceived(const IPC::Message& msg){
return false;
}
-void RenderWidgetHostViewBase::OnRenderFrameMetadataChanged() {
+void RenderWidgetHostViewBase::OnRenderFrameMetadataChangedBeforeActivation(
+ const cc::RenderFrameMetadata& metadata) {}
+
+void RenderWidgetHostViewBase::OnRenderFrameMetadataChangedAfterActivation() {
is_scroll_offset_at_top_ = host_->render_frame_metadata_provider()
->LastRenderFrameMetadata()
.is_scroll_offset_at_top;
@@ -221,6 +221,18 @@ base::string16 RenderWidgetHostViewBase::GetSelectedText() {
return GetTextInputManager()->GetTextSelection(this)->selected_text();
}
+base::string16 RenderWidgetHostViewBase::GetSurroundingText() {
+ if (!GetTextInputManager())
+ return base::string16();
+ return GetTextInputManager()->GetTextSelection(this)->text();
+}
+
+gfx::Range RenderWidgetHostViewBase::GetSelectedRange() {
+ if (!GetTextInputManager())
+ return gfx::Range();
+ return GetTextInputManager()->GetTextSelection(this)->range();
+}
+
void RenderWidgetHostViewBase::SetBackgroundColor(SkColor color) {
DCHECK(SkColorGetA(color) == SK_AlphaOPAQUE ||
SkColorGetA(color) == SK_AlphaTRANSPARENT);
@@ -243,7 +255,7 @@ base::Optional<SkColor> RenderWidgetHostViewBase::GetBackgroundColor() const {
}
bool RenderWidgetHostViewBase::IsMouseLocked() {
- return mouse_locked_;
+ return false;
}
bool RenderWidgetHostViewBase::LockKeyboard(
@@ -288,6 +300,52 @@ void RenderWidgetHostViewBase::GestureEventAck(
InputEventAckState ack_result) {
}
+void RenderWidgetHostViewBase::ForwardTouchpadPinchIfNecessary(
+ const blink::WebGestureEvent& event,
+ InputEventAckState ack_result) {
+ if (!blink::WebInputEvent::IsPinchGestureEventType(event.GetType()))
+ return;
+ if (event.SourceDevice() !=
+ blink::WebGestureDevice::kWebGestureDeviceTouchpad)
+ return;
+ if (!event.NeedsWheelEvent())
+ return;
+
+ switch (event.GetType()) {
+ case blink::WebInputEvent::kGesturePinchBegin:
+ // Don't send the begin event until we get the first unconsumed update, so
+ // that we elide pinch gesture steams consisting of only a begin and end.
+ pending_touchpad_pinch_begin_ = event;
+ pending_touchpad_pinch_begin_->SetNeedsWheelEvent(false);
+ break;
+ case blink::WebInputEvent::kGesturePinchUpdate:
+ if (ack_result != INPUT_EVENT_ACK_STATE_CONSUMED &&
+ !event.data.pinch_update.zoom_disabled) {
+ if (pending_touchpad_pinch_begin_) {
+ host()->ForwardGestureEvent(*pending_touchpad_pinch_begin_);
+ pending_touchpad_pinch_begin_.reset();
+ }
+ // Now that the synthetic wheel event has gone unconsumed, we have the
+ // pinch event actually change the page scale.
+ blink::WebGestureEvent pinch_event(event);
+ pinch_event.SetNeedsWheelEvent(false);
+ host()->ForwardGestureEvent(pinch_event);
+ }
+ break;
+ case blink::WebInputEvent::kGesturePinchEnd:
+ if (pending_touchpad_pinch_begin_) {
+ pending_touchpad_pinch_begin_.reset();
+ } else {
+ blink::WebGestureEvent pinch_end_event(event);
+ pinch_end_event.SetNeedsWheelEvent(false);
+ host()->ForwardGestureEvent(pinch_end_event);
+ }
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
void RenderWidgetHostViewBase::SetPopupType(blink::WebPopupType popup_type) {
popup_type_ = popup_type;
}
@@ -473,14 +531,6 @@ void RenderWidgetHostViewBase::OnFrameTokenChangedForView(
host()->DidProcessFrame(frame_token);
}
-viz::FrameSinkId RenderWidgetHostViewBase::GetFrameSinkId() {
- return viz::FrameSinkId();
-}
-
-viz::LocalSurfaceId RenderWidgetHostViewBase::GetLocalSurfaceId() const {
- return viz::LocalSurfaceId();
-}
-
viz::FrameSinkId RenderWidgetHostViewBase::FrameSinkIdAtPoint(
viz::SurfaceHittestDelegate* delegate,
const gfx::PointF& point,
@@ -495,6 +545,8 @@ viz::FrameSinkId RenderWidgetHostViewBase::FrameSinkIdAtPoint(
gfx::ConvertPointToPixel(device_scale_factor, point);
viz::SurfaceId surface_id = GetCurrentSurfaceId();
if (!surface_id.is_valid()) {
+ // Force a query of the renderer if we don't have a surface id yet.
+ *out_query_renderer = true;
return GetFrameSinkId();
}
viz::SurfaceHittest hittest(delegate,
@@ -518,6 +570,11 @@ viz::FrameSinkId RenderWidgetHostViewBase::FrameSinkIdAtPoint(
void RenderWidgetHostViewBase::ProcessMouseEvent(
const blink::WebMouseEvent& event,
const ui::LatencyInfo& latency) {
+ // TODO(crbug.com/814674): Figure out the reason |host| is null here in all
+ // Process* functions.
+ if (!host())
+ return;
+
PreProcessMouseEvent(event);
host()->ForwardMouseEventWithLatencyInfo(event, latency);
}
@@ -525,12 +582,17 @@ void RenderWidgetHostViewBase::ProcessMouseEvent(
void RenderWidgetHostViewBase::ProcessMouseWheelEvent(
const blink::WebMouseWheelEvent& event,
const ui::LatencyInfo& latency) {
+ if (!host())
+ return;
host()->ForwardWheelEventWithLatencyInfo(event, latency);
}
void RenderWidgetHostViewBase::ProcessTouchEvent(
const blink::WebTouchEvent& event,
const ui::LatencyInfo& latency) {
+ if (!host())
+ return;
+
PreProcessTouchEvent(event);
host()->ForwardTouchEventWithLatencyInfo(event, latency);
}
@@ -538,6 +600,8 @@ void RenderWidgetHostViewBase::ProcessTouchEvent(
void RenderWidgetHostViewBase::ProcessGestureEvent(
const blink::WebGestureEvent& event,
const ui::LatencyInfo& latency) {
+ if (!host())
+ return;
host()->ForwardGestureEventWithLatencyInfo(event, latency);
}
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 048fd7d3a8b..8ed6ffd3a28 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
@@ -116,6 +116,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
void WasOccluded() override {}
void SetIsInVR(bool is_in_vr) override;
base::string16 GetSelectedText() override;
+ base::string16 GetSurroundingText() override;
+ gfx::Range GetSelectedRange() override;
bool IsMouseLocked() override;
bool LockKeyboard(base::Optional<base::flat_set<ui::DomCode>> codes) override;
void SetBackgroundColor(SkColor color) override;
@@ -153,7 +155,9 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
bool OnMessageReceived(const IPC::Message& msg) override;
// RenderFrameMetadataProvider::Observer
- void OnRenderFrameMetadataChanged() override;
+ void OnRenderFrameMetadataChangedBeforeActivation(
+ const cc::RenderFrameMetadata& metadata) override;
+ void OnRenderFrameMetadataChangedAfterActivation() override;
void OnRenderFrameSubmission() override;
void OnLocalSurfaceIdChanged(
const cc::RenderFrameMetadata& metadata) override;
@@ -301,6 +305,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// the GestureRecognizer until invocation of ProcessAckedTouchEvent releases
// it to be consumed (when |ack_result| is NOT_CONSUMED OR NO_CONSUMER_EXISTS)
// or ignored (when |ack_result| is CONSUMED).
+ // |touch|'s coordinates are in the coordinate space of the view to which it
+ // was targeted.
virtual void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
InputEventAckState ack_result) {}
@@ -309,12 +315,11 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
virtual void DidStopFlinging() {}
// Returns the ID associated with the CompositorFrameSink of this view.
- // TODO(fsamuel): Return by const ref.
- virtual viz::FrameSinkId GetFrameSinkId();
+ virtual const viz::FrameSinkId& GetFrameSinkId() const = 0;
// Returns the LocalSurfaceId allocated by the parent client for this view.
// TODO(fsamuel): Return by const ref.
- virtual viz::LocalSurfaceId GetLocalSurfaceId() const;
+ virtual const viz::LocalSurfaceId& GetLocalSurfaceId() const = 0;
// When there are multiple RenderWidgetHostViews for a single page, input
// events need to be targeted to the correct one for handling. The following
@@ -532,10 +537,6 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
bool is_fullscreen() { return is_fullscreen_; }
- bool wheel_scroll_latching_enabled() {
- return wheel_scroll_latching_enabled_;
- }
-
void set_web_contents_accessibility(WebContentsAccessibility* wcax) {
web_contents_accessibility_ = wcax;
}
@@ -596,6 +597,13 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
ui::mojom::WindowTreeClientPtr GetWindowTreeClientFromRenderer();
#endif
+ // If |event| is a touchpad pinch event for which we've sent a synthetic
+ // wheel event, forward the |event| to the renderer, subject to |ack_result|
+ // which is the ACK result of the synthetic wheel.
+ virtual void ForwardTouchpadPinchIfNecessary(
+ const blink::WebGestureEvent& event,
+ InputEventAckState ack_result);
+
// The model object. Members will become private when
// RenderWidgetHostViewGuest is removed.
RenderWidgetHostImpl* host_;
@@ -610,13 +618,6 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// Indicates whether keyboard lock is active for this view.
bool keyboard_locked_ = false;
- // While the mouse is locked, the cursor is hidden from the user. Mouse events
- // are still generated. However, the position they report is the last known
- // mouse position just as mouse lock was entered; the movement they report
- // indicates what the change in position of the mouse would be had it not been
- // locked.
- bool mouse_locked_ = false;
-
// Indicates whether the scroll offset of the root layer is at top, i.e.,
// whether scroll_offset.y() == 0.
bool is_scroll_offset_at_top_ = true;
@@ -643,8 +644,6 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// |content_background_color|.
base::Optional<SkColor> default_background_color_;
- const bool wheel_scroll_latching_enabled_;
-
WebContentsAccessibility* web_contents_accessibility_;
bool is_currently_scrolling_viewport_;
@@ -701,6 +700,8 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
base::flat_map<int, int> pending_embeds_;
#endif
+ base::Optional<blink::WebGestureEvent> pending_touchpad_pinch_begin_;
+
base::WeakPtrFactory<RenderWidgetHostViewBase> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewBase);
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 801847175d3..f4540058c6a 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
@@ -152,13 +152,14 @@ class CommitBeforeSwapAckSentHelper
private:
// DidCommitProvisionalLoadInterceptor:
- void WillDispatchDidCommitProvisionalLoad(
+ bool WillDispatchDidCommitProvisionalLoad(
RenderFrameHost* render_frame_host,
::FrameHostMsg_DidCommitProvisionalLoad_Params* params,
service_manager::mojom::InterfaceProviderRequest*
interface_provider_request) override {
base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
frame_observer_->WaitForAnyFrameSubmission();
+ return true;
}
// Not owned.
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 2891bddd1be..08e68296f2a 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
@@ -16,6 +16,7 @@
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.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/surfaces/surface.h"
@@ -69,13 +70,11 @@ RenderWidgetHostViewChildFrame::RenderWidgetHostViewChildFrame(
frame_sink_id_(
base::checked_cast<uint32_t>(widget_host->GetProcess()->GetID()),
base::checked_cast<uint32_t>(widget_host->GetRoutingID())),
- current_surface_scale_factor_(1.f),
frame_connector_(nullptr),
enable_viz_(
base::FeatureList::IsEnabled(features::kVizDisplayCompositor)),
- scroll_bubbling_state_(NO_ACTIVE_GESTURE_SCROLL),
weak_factory_(this) {
- if (base::FeatureList::IsEnabled(features::kMash)) {
+ if (!features::IsAshInBrowserProcess()) {
// 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();
@@ -94,7 +93,7 @@ RenderWidgetHostViewChildFrame::~RenderWidgetHostViewChildFrame() {
if (frame_connector_)
DetachFromTouchSelectionClientManagerIfNecessary();
- if (!base::FeatureList::IsEnabled(features::kMash)) {
+ if (features::IsAshInBrowserProcess()) {
ResetCompositorFrameSinkSupport();
if (GetHostFrameSinkManager())
GetHostFrameSinkManager()->InvalidateFrameSinkId(frame_sink_id_);
@@ -134,7 +133,6 @@ void RenderWidgetHostViewChildFrame::SetFrameConnectorDelegate(
if (frame_connector_) {
SetParentFrameSinkId(viz::FrameSinkId());
- last_received_local_surface_id_ = viz::LocalSurfaceId();
// Unlocks the mouse if this RenderWidgetHostView holds the lock.
UnlockMouse();
@@ -149,7 +147,7 @@ void RenderWidgetHostViewChildFrame::SetFrameConnectorDelegate(
if (parent_view) {
DCHECK(parent_view->GetFrameSinkId().is_valid() ||
- base::FeatureList::IsEnabled(features::kMash));
+ !features::IsAshInBrowserProcess());
SetParentFrameSinkId(parent_view->GetFrameSinkId());
}
@@ -170,17 +168,19 @@ void RenderWidgetHostViewChildFrame::SetFrameConnectorDelegate(
}
#if defined(USE_AURA)
- if (features::IsMashEnabled()) {
+ if (!features::IsAshInBrowserProcess()) {
frame_connector_->EmbedRendererWindowTreeClientInParent(
GetWindowTreeClientFromRenderer());
}
#endif
+
+ SendSurfaceInfoToEmbedder();
}
#if defined(USE_AURA)
void RenderWidgetHostViewChildFrame::SetFrameSinkId(
const viz::FrameSinkId& frame_sink_id) {
- if (base::FeatureList::IsEnabled(features::kMash))
+ if (!features::IsAshInBrowserProcess())
frame_sink_id_ = frame_sink_id;
}
#endif // defined(USE_AURA)
@@ -258,7 +258,7 @@ void RenderWidgetHostViewChildFrame::Show() {
if (!CanBecomeVisible())
return;
- host()->WasShown(ui::LatencyInfo());
+ host()->WasShown(false /* record_presentation_time */);
if (frame_connector_)
frame_connector_->SetVisibilityForChildViews(true);
@@ -397,11 +397,6 @@ void RenderWidgetHostViewChildFrame::SetIsLoading(bool is_loading) {
// is a RenderWidgetHostViewChildFrame. In contrast, when there is no
// inner/outer WebContents, only subframe's RenderWidgetHostView can be a
// RenderWidgetHostViewChildFrame which do not get a SetIsLoading() call.
- if (GuestMode::IsCrossProcessFrameGuest(
- WebContents::FromRenderViewHost(RenderViewHost::From(host()))))
- return;
-
- NOTREACHED();
}
void RenderWidgetHostViewChildFrame::RenderProcessGone(
@@ -511,69 +506,56 @@ void RenderWidgetHostViewChildFrame::UpdateRenderThrottlingStatus() {
void RenderWidgetHostViewChildFrame::GestureEventAck(
const blink::WebGestureEvent& event,
InputEventAckState ack_result) {
- bool should_bubble =
+ if (!frame_connector_)
+ return;
+
+ if (blink::WebInputEvent::IsPinchGestureEventType(event.GetType()))
+ ProcessTouchpadPinchAckInRoot(event, ack_result);
+
+ const bool should_bubble =
ack_result == INPUT_EVENT_ACK_STATE_NOT_CONSUMED ||
ack_result == INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS ||
ack_result == INPUT_EVENT_ACK_STATE_CONSUMED_SHOULD_BUBBLE;
- 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
- // frame_connector_ decides to forward them for bubbling if the
- // GestureScrollBegin event is forwarded.
- if ((event.GetType() == blink::WebInputEvent::kGestureScrollBegin &&
- should_bubble) ||
- event.GetType() == blink::WebInputEvent::kGestureScrollUpdate ||
- event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
- event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
- frame_connector_->BubbleScrollEvent(event);
- }
- } else {
- // Consumption of the first GestureScrollUpdate determines whether to
- // bubble the sequence of GestureScrollUpdates.
- // If the child consumed some scroll, then stopped consuming once it could
- // no longer scroll, we don't want to bubble those unconsumed GSUs as we
- // want the user to start a new gesture in order to scroll the parent.
- // Unfortunately, this is only effective for touch scrolling as wheel
- // scrolling wraps GSUs in GSB/GSE pairs.
- if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) {
- DCHECK_EQ(NO_ACTIVE_GESTURE_SCROLL, scroll_bubbling_state_);
- scroll_bubbling_state_ = AWAITING_FIRST_UPDATE;
- } else if (scroll_bubbling_state_ == AWAITING_FIRST_UPDATE &&
- event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) {
- scroll_bubbling_state_ = (should_bubble ? BUBBLE : SCROLL_CHILD);
- } else if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
- event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
- scroll_bubbling_state_ = NO_ACTIVE_GESTURE_SCROLL;
- }
+ 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 consumed by the target frame and not forwarded,
- // because we don't know whether we will need to bubble scroll until we
- // receive a GestureScrollUpdate ACK. GestureScrollUpdates are forwarded
- // for bubbling if the first GSU has unused scroll extent,
- // while GestureScrollEnd is always forwarded and handled according to
- // current scroll state in the RenderWidgetHostInputEventRouter.
- if ((event.GetType() == blink::WebInputEvent::kGestureScrollUpdate &&
- scroll_bubbling_state_ == BUBBLE) ||
- event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
- event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
- frame_connector_->BubbleScrollEvent(event);
- }
+ // 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
+ // frame_connector_ decides to forward them for bubbling if the
+ // GestureScrollBegin event is forwarded.
+ if ((event.GetType() == blink::WebInputEvent::kGestureScrollBegin &&
+ should_bubble) ||
+ event.GetType() == blink::WebInputEvent::kGestureScrollUpdate ||
+ event.GetType() == blink::WebInputEvent::kGestureScrollEnd ||
+ event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
+ frame_connector_->BubbleScrollEvent(event);
}
}
+void RenderWidgetHostViewChildFrame::ProcessTouchpadPinchAckInRoot(
+ const blink::WebGestureEvent& event,
+ InputEventAckState ack_result) {
+ DCHECK(blink::WebInputEvent::IsPinchGestureEventType(event.GetType()));
+
+ frame_connector_->ForwardAckedTouchpadPinchGestureEvent(event, ack_result);
+}
+
+void RenderWidgetHostViewChildFrame::ForwardTouchpadPinchIfNecessary(
+ const blink::WebGestureEvent& event,
+ InputEventAckState ack_result) {
+ // ACKs of synthetic wheel events for touchpad pinch are processed in the
+ // root RWHV.
+ NOTREACHED();
+}
+
void RenderWidgetHostViewChildFrame::DidReceiveCompositorFrameAck(
const std::vector<viz::ReturnedResource>& resources) {
if (renderer_compositor_frame_sink_)
@@ -582,15 +564,11 @@ void RenderWidgetHostViewChildFrame::DidReceiveCompositorFrameAck(
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();
+ const gfx::PresentationFeedback& feedback) {
+ renderer_compositor_frame_sink_->DidPresentCompositorFrame(presentation_token,
+ feedback);
}
+
void RenderWidgetHostViewChildFrame::DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
ResetCompositorFrameSinkSupport();
@@ -602,7 +580,7 @@ void RenderWidgetHostViewChildFrame::DidCreateNewRendererCompositorFrameSink(
void RenderWidgetHostViewChildFrame::SetParentFrameSinkId(
const viz::FrameSinkId& parent_frame_sink_id) {
if (parent_frame_sink_id_ == parent_frame_sink_id ||
- base::FeatureList::IsEnabled(features::kMash))
+ !features::IsAshInBrowserProcess())
return;
auto* host_frame_sink_manager = GetHostFrameSinkManager();
@@ -623,18 +601,17 @@ void RenderWidgetHostViewChildFrame::SetParentFrameSinkId(
}
void RenderWidgetHostViewChildFrame::SendSurfaceInfoToEmbedder() {
- if (base::FeatureList::IsEnabled(features::kMash))
+ if (!features::IsAshInBrowserProcess())
return;
- viz::SurfaceId surface_id(frame_sink_id_, last_received_local_surface_id_);
- viz::SurfaceInfo surface_info(surface_id, current_surface_scale_factor_,
- current_surface_size_);
- SendSurfaceInfoToEmbedderImpl(surface_info);
+ if (!last_activated_surface_info_.is_valid())
+ return;
+ FirstSurfaceActivation(last_activated_surface_info_);
}
-void RenderWidgetHostViewChildFrame::SendSurfaceInfoToEmbedderImpl(
+void RenderWidgetHostViewChildFrame::FirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) {
if (frame_connector_)
- frame_connector_->SetChildFrameSurface(surface_info);
+ frame_connector_->FirstSurfaceActivation(surface_info);
}
void RenderWidgetHostViewChildFrame::SubmitCompositorFrame(
@@ -644,20 +621,8 @@ void RenderWidgetHostViewChildFrame::SubmitCompositorFrame(
DCHECK(!enable_viz_);
TRACE_EVENT0("content",
"RenderWidgetHostViewChildFrame::OnSwapCompositorFrame");
- current_surface_size_ = frame.size_in_pixels();
- current_surface_scale_factor_ = frame.device_scale_factor();
-
support_->SubmitCompositorFrame(local_surface_id, std::move(frame),
std::move(hit_test_region_list));
- has_frame_ = true;
-
- if (last_received_local_surface_id_ != local_surface_id ||
- HasEmbedderChanged()) {
- last_received_local_surface_id_ = local_surface_id;
- SendSurfaceInfoToEmbedder();
- }
-
- ProcessFrameSwappedCallbacks();
}
void RenderWidgetHostViewChildFrame::OnDidNotProduceFrame(
@@ -729,14 +694,15 @@ bool RenderWidgetHostViewChildFrame::IsMouseLocked() {
return host()->delegate()->HasMouseLock(host());
}
-viz::FrameSinkId RenderWidgetHostViewChildFrame::GetFrameSinkId() {
+const viz::FrameSinkId& RenderWidgetHostViewChildFrame::GetFrameSinkId() const {
return frame_sink_id_;
}
-viz::LocalSurfaceId RenderWidgetHostViewChildFrame::GetLocalSurfaceId() const {
+const viz::LocalSurfaceId& RenderWidgetHostViewChildFrame::GetLocalSurfaceId()
+ const {
if (frame_connector_)
return frame_connector_->local_surface_id();
- return viz::LocalSurfaceId();
+ return viz::ParentLocalSurfaceIdAllocator::InvalidLocalSurfaceId();
}
void RenderWidgetHostViewChildFrame::PreProcessTouchEvent(
@@ -760,7 +726,7 @@ viz::FrameSinkId RenderWidgetHostViewChildFrame::GetRootFrameSinkId() {
}
viz::SurfaceId RenderWidgetHostViewChildFrame::GetCurrentSurfaceId() const {
- return viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_);
+ return last_activated_surface_info_.id();
}
bool RenderWidgetHostViewChildFrame::HasSize() const {
@@ -771,12 +737,12 @@ gfx::PointF RenderWidgetHostViewChildFrame::TransformPointToRootCoordSpaceF(
const gfx::PointF& point) {
// LocalSurfaceId is not needed in Viz hit-test.
if (!frame_connector_ ||
- (!use_viz_hit_test_ && !last_received_local_surface_id_.is_valid())) {
+ (!use_viz_hit_test_ && !last_activated_surface_info_.is_valid())) {
return point;
}
return frame_connector_->TransformPointToRootCoordSpace(
- point, viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_));
+ point, last_activated_surface_info_.id());
}
bool RenderWidgetHostViewChildFrame::TransformPointToLocalCoordSpaceLegacy(
@@ -784,12 +750,11 @@ bool RenderWidgetHostViewChildFrame::TransformPointToLocalCoordSpaceLegacy(
const viz::SurfaceId& original_surface,
gfx::PointF* transformed_point) {
*transformed_point = point;
- if (!frame_connector_ || !last_received_local_surface_id_.is_valid())
+ if (!frame_connector_ || !last_activated_surface_info_.is_valid())
return false;
return frame_connector_->TransformPointToLocalCoordSpaceLegacy(
- point, original_surface,
- viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_),
+ point, original_surface, last_activated_surface_info_.id(),
transformed_point);
}
@@ -800,7 +765,7 @@ bool RenderWidgetHostViewChildFrame::TransformPointToCoordSpaceForView(
viz::EventSource source) {
// LocalSurfaceId is not needed in Viz hit-test.
if (!frame_connector_ ||
- (!use_viz_hit_test_ && !last_received_local_surface_id_.is_valid())) {
+ (!use_viz_hit_test_ && !last_activated_surface_info_.is_valid())) {
return false;
}
@@ -810,9 +775,8 @@ bool RenderWidgetHostViewChildFrame::TransformPointToCoordSpaceForView(
}
return frame_connector_->TransformPointToCoordSpaceForView(
- point, target_view,
- viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_),
- transformed_point, source);
+ point, target_view, last_activated_surface_info_.id(), transformed_point,
+ source);
}
gfx::PointF RenderWidgetHostViewChildFrame::TransformRootPointToViewCoordSpace(
@@ -903,14 +867,20 @@ void RenderWidgetHostViewChildFrame::CopyFromSurface(
std::move(callback)));
if (src_subrect.IsEmpty()) {
- request->set_area(gfx::Rect(current_surface_size_));
+ request->set_area(gfx::Rect(last_activated_surface_info_.size_in_pixels()));
} else {
// |src_subrect| is in DIP coordinates; convert to Surface coordinates.
- request->set_area(
- gfx::ScaleToRoundedRect(src_subrect, current_surface_scale_factor_));
+ request->set_area(gfx::ScaleToRoundedRect(
+ src_subrect, last_activated_surface_info_.device_scale_factor()));
}
if (!output_size.IsEmpty()) {
+ if (request->area().IsEmpty()) {
+ // Viz would normally return an empty result for an empty source area.
+ // However, this guard here is still necessary to protect against setting
+ // an illegal scaling ratio.
+ return;
+ }
request->set_result_selection(gfx::Rect(output_size));
request->SetScaleRatio(
gfx::Vector2d(request->area().width(), request->area().height()),
@@ -918,8 +888,7 @@ void RenderWidgetHostViewChildFrame::CopyFromSurface(
}
GetHostFrameSinkManager()->RequestCopyOfOutput(
- viz::SurfaceId(frame_sink_id_, last_received_local_surface_id_),
- std::move(request));
+ last_activated_surface_info_.id(), std::move(request));
}
void RenderWidgetHostViewChildFrame::ReclaimResources(
@@ -942,7 +911,10 @@ void RenderWidgetHostViewChildFrame::OnBeginFramePausedChanged(bool paused) {
void RenderWidgetHostViewChildFrame::OnFirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) {
- SendSurfaceInfoToEmbedderImpl(surface_info);
+ last_activated_surface_info_ = surface_info;
+ has_frame_ = true;
+ FirstSurfaceActivation(surface_info);
+ ProcessFrameSwappedCallbacks();
}
void RenderWidgetHostViewChildFrame::OnFrameTokenChanged(uint32_t frame_token) {
@@ -965,8 +937,9 @@ RenderWidgetHostViewChildFrame::GetTouchSelectionControllerClientManager() {
return root_view->GetTouchSelectionControllerClientManager();
}
-void RenderWidgetHostViewChildFrame::OnRenderFrameMetadataChanged() {
- RenderWidgetHostViewBase::OnRenderFrameMetadataChanged();
+void RenderWidgetHostViewChildFrame::
+ OnRenderFrameMetadataChangedAfterActivation() {
+ RenderWidgetHostViewBase::OnRenderFrameMetadataChangedAfterActivation();
if (selection_controller_client_) {
const cc::RenderFrameMetadata& metadata =
host()->render_frame_metadata_provider()->LastRenderFrameMetadata();
@@ -987,17 +960,20 @@ void RenderWidgetHostViewChildFrame::TakeFallbackContentFrom(
InputEventAckState RenderWidgetHostViewChildFrame::FilterInputEvent(
const blink::WebInputEvent& input_event) {
- // A child renderer should not receive touchscreen pinch events. Ideally, we
- // would DCHECK this, but since touchscreen pinch events may be targeted to
- // a child in order to have the child's TouchActionFilter filter them, we
- // may encounter https://crbug.com/771330 which would let the pinch events
- // through.
+ // A child renderer should never receive a GesturePinch event. Pinch events
+ // can still be targeted to a child, but they must be processed without
+ // sending the pinch event to the child (e.g. touchpad pinch synthesizes
+ // wheel events to send to the child renderer).
if (blink::WebInputEvent::IsPinchGestureEventType(input_event.GetType())) {
const blink::WebGestureEvent& gesture_event =
static_cast<const blink::WebGestureEvent&>(input_event);
+ // Touchscreen pinch events may be targeted to a child in order to have the
+ // child's TouchActionFilter filter them, but we may encounter
+ // https://crbug.com/771330 which would let the pinch events through.
if (gesture_event.SourceDevice() == blink::kWebGestureDeviceTouchscreen) {
return INPUT_EVENT_ACK_STATE_CONSUMED;
}
+ NOTREACHED();
}
if (input_event.GetType() == blink::WebInputEvent::kGestureFlingStart) {
@@ -1020,7 +996,7 @@ InputEventAckState RenderWidgetHostViewChildFrame::FilterInputEvent(
}
}
- if (wheel_scroll_latching_enabled() && is_scroll_sequence_bubbling_ &&
+ if (is_scroll_sequence_bubbling_ &&
(input_event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) &&
frame_connector_) {
// If we're bubbling, then to preserve latching behaviour, the child should
@@ -1034,20 +1010,6 @@ InputEventAckState RenderWidgetHostViewChildFrame::FilterInputEvent(
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
- // scroll events that would normally be processed by the child.
- // TODO(mcnee): With scroll-latching enabled, the child would not scroll
- // in this case. Remove this once scroll-latching lands. crbug.com/751782
- if (!wheel_scroll_latching_enabled() && frame_connector_ &&
- input_event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) {
- const blink::WebGestureEvent& gesture_event =
- static_cast<const blink::WebGestureEvent&>(input_event);
- return frame_connector_->GetRootRenderWidgetHostView()
- ->FilterChildGestureEvent(gesture_event);
- }
-
return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
}
@@ -1105,7 +1067,7 @@ RenderWidgetHostViewChildFrame::DidUpdateVisualProperties(
}
void RenderWidgetHostViewChildFrame::CreateCompositorFrameSinkSupport() {
- if (base::FeatureList::IsEnabled(features::kMash) || enable_viz_)
+ if (!features::IsAshInBrowserProcess() || enable_viz_)
return;
DCHECK(!support_);
@@ -1131,10 +1093,6 @@ void RenderWidgetHostViewChildFrame::ResetCompositorFrameSinkSupport() {
support_.reset();
}
-bool RenderWidgetHostViewChildFrame::HasEmbedderChanged() {
- return false;
-}
-
bool RenderWidgetHostViewChildFrame::GetSelectionRange(
gfx::Range* range) const {
if (!text_input_manager_ || !GetFocusedWidget())
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 07982e165bf..f5a326cdc98 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
@@ -143,8 +143,8 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
void DidStopFlinging() override;
bool LockMouse() override;
void UnlockMouse() override;
- viz::FrameSinkId GetFrameSinkId() override;
- viz::LocalSurfaceId GetLocalSurfaceId() const override;
+ const viz::FrameSinkId& GetFrameSinkId() const override;
+ const viz::LocalSurfaceId& GetLocalSurfaceId() const override;
void PreProcessTouchEvent(const blink::WebTouchEvent& event) override;
viz::FrameSinkId GetRootFrameSinkId() override;
viz::SurfaceId GetCurrentSurfaceId() const override;
@@ -165,7 +165,7 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
const gfx::PointF& point) override;
TouchSelectionControllerClientManager*
GetTouchSelectionControllerClientManager() override;
- void OnRenderFrameMetadataChanged() override;
+ void OnRenderFrameMetadataChangedAfterActivation() override;
bool IsRenderWidgetHostViewChildFrame() override;
@@ -195,11 +195,9 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
// 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 DidPresentCompositorFrame(
+ uint32_t presentation_token,
+ const gfx::PresentationFeedback& feedback) override;
void OnBeginFrame(const viz::BeginFrameArgs& args) override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
@@ -214,7 +212,9 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
}
// Returns the current surface scale factor.
- float current_surface_scale_factor() { return current_surface_scale_factor_; }
+ float current_surface_scale_factor() {
+ return last_activated_surface_info_.device_scale_factor();
+ }
// Returns the view into which this view is directly embedded. This can
// return nullptr when this view's associated child frame is not connected
@@ -269,9 +269,7 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
// Surface-related state.
std::unique_ptr<viz::CompositorFrameSinkSupport> support_;
- viz::LocalSurfaceId last_received_local_surface_id_;
- gfx::Size current_surface_size_;
- float current_surface_scale_factor_;
+ viz::SurfaceInfo last_activated_surface_info_;
gfx::Rect last_screen_rect_;
// frame_connector_ provides a platform abstraction. Messages
@@ -288,16 +286,15 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
FRIEND_TEST_ALL_PREFIXES(
SitePerProcessBrowserTest,
HiddenOOPIFWillNotGenerateCompositorFramesAfterNavigation);
+ FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest,
+ SubframeVisibleAfterRenderViewBecomesSwappedOut);
- virtual void SendSurfaceInfoToEmbedderImpl(
- const viz::SurfaceInfo& surface_info);
+ virtual void FirstSurfaceActivation(const viz::SurfaceInfo& surface_info);
void CreateCompositorFrameSinkSupport();
void ResetCompositorFrameSinkSupport();
void DetachFromTouchSelectionClientManagerIfNecessary();
- virtual bool HasEmbedderChanged();
-
// Returns false if the view cannot be shown. This is the case where the frame
// associated with this view or a cross process ancestor frame has been hidden
// using CSS.
@@ -306,6 +303,11 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
void OnDidUpdateVisualPropertiesComplete(
const cc::RenderFrameMetadata& metadata);
+ void ProcessTouchpadPinchAckInRoot(const blink::WebGestureEvent& event,
+ InputEventAckState ack_result);
+ void ForwardTouchpadPinchIfNecessary(const blink::WebGestureEvent& event,
+ InputEventAckState ack_result) override;
+
std::vector<base::OnceClosure> frame_swapped_callbacks_;
// The surface client ID of the parent RenderWidgetHostView. 0 if none.
@@ -324,17 +326,6 @@ class CONTENT_EXPORT RenderWidgetHostViewChildFrame
// 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()|
- // and can be removed once scroll-latching lands. crbug.com/526463
- enum ScrollBubblingState {
- NO_ACTIVE_GESTURE_SCROLL,
- AWAITING_FIRST_UPDATE,
- BUBBLE,
- SCROLL_CHILD,
- } scroll_bubbling_state_;
-
base::WeakPtrFactory<RenderWidgetHostViewChildFrame> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewChildFrame);
};
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 e6ee8ec9bc1..6c9a0a1bc04 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
@@ -6,6 +6,7 @@
#include "base/macros.h"
#include "base/run_loop.h"
+#include "base/test/test_timeouts.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -75,6 +76,13 @@ class RenderWidgetHostViewChildFrameTest : public ContentBrowserTest {
actual_frame_sink_id_.sink_id());
}
+ void GiveItSomeTime() {
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
+ run_loop.Run();
+ }
+
void set_expected_frame_sink_id(viz::FrameSinkId frame_sink_id) {
expected_frame_sink_id_ = frame_sink_id;
}
@@ -152,7 +160,7 @@ IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest,
IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest, ChildFrameSinkId) {
// Only when mus hosts viz do we expect a RenderFrameProxy to provide the
// FrameSinkId.
- if (!base::FeatureList::IsEnabled(features::kMash))
+ if (features::IsAshInBrowserProcess())
return;
GURL main_url(embedded_test_server()->GetURL("/site_per_process_main.html"));
@@ -182,4 +190,35 @@ IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest, ChildFrameSinkId) {
base::Unretained(this)));
}
+// Validate that OOPIFs receive presentation feedbacks.
+IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest,
+ PresentationFeedback) {
+ base::HistogramTester histogram_tester;
+ 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();
+ // Load cross-site page into iframe.
+ GURL cross_site_url(
+ embedded_test_server()->GetURL("foo.com", "/title2.html"));
+ NavigateFrameToURL(root->child_at(0), cross_site_url);
+
+ auto* child_rwh_impl =
+ root->child_at(0)->current_frame_host()->GetRenderWidgetHost();
+ // Hide the frame and make it visible again, to force it to record the
+ // tab-switch time, which is generated from presentation-feedback.
+ child_rwh_impl->WasHidden();
+ child_rwh_impl->WasShown(true /* record_presentation_time */);
+ // Force the child to submit a new frame.
+ ASSERT_TRUE(ExecuteScript(root->child_at(0)->current_frame_host(),
+ "document.write('Force a new frame.');"));
+ do {
+ FetchHistogramsFromChildProcesses();
+ GiveItSomeTime();
+ } while (histogram_tester.GetAllSamples("MPArch.RWH_TabSwitchPaintDuration")
+ .size() != 1);
+}
+
} // namespace content
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 c190e59907d..d888709145d 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
@@ -31,7 +31,6 @@
#include "content/common/frame_visual_properties.h"
#include "content/common/view_messages.h"
#include "content/public/browser/render_widget_host_view.h"
-#include "content/public/common/content_features.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"
@@ -58,7 +57,7 @@ class MockFrameConnectorDelegate : public FrameConnectorDelegate {
: FrameConnectorDelegate(use_zoom_for_device_scale_factor) {}
~MockFrameConnectorDelegate() override {}
- void SetChildFrameSurface(const viz::SurfaceInfo& surface_info) override {
+ void FirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override {
last_surface_info_ = surface_info;
}
@@ -141,12 +140,11 @@ class RenderWidgetHostViewChildFrameTest : public testing::Test {
}
viz::SurfaceId GetSurfaceId() const {
- return viz::SurfaceId(view_->frame_sink_id_,
- view_->last_received_local_surface_id_);
+ return view_->last_activated_surface_info_.id();
}
viz::LocalSurfaceId GetLocalSurfaceId() const {
- return view_->last_received_local_surface_id_;
+ return GetSurfaceId().local_surface_id();
}
protected:
@@ -197,44 +195,22 @@ TEST_F(RenderWidgetHostViewChildFrameTest, VisibilityTest) {
ASSERT_FALSE(view_->IsShowing());
}
-// Verify that SubmitCompositorFrame behavior is correct when a delegated
-// frame is received from a renderer process.
-TEST_F(RenderWidgetHostViewChildFrameTest, SwapCompositorFrame) {
- // TODO(jonross): Delete this test once Viz launches as it will be obsolete.
- // https://crbug.com/844469
- if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor) ||
- base::FeatureList::IsEnabled(features::kMash)) {
- return;
- }
-
+// Verify that RenderWidgetHostViewChildFrame passes the child's SurfaceId to
+// FrameConnectorDelegate to be sent to the embedding renderer.
+TEST_F(RenderWidgetHostViewChildFrameTest, PassesSurfaceId) {
gfx::Size view_size(100, 100);
gfx::Rect view_rect(view_size);
float scale_factor = 1.f;
- viz::LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create());
view_->SetSize(view_size);
view_->Show();
- view_->SubmitCompositorFrame(
- local_surface_id,
- CreateDelegatedFrame(scale_factor, view_size, view_rect), base::nullopt);
-
- viz::SurfaceId id = GetSurfaceId();
- if (id.is_valid()) {
-#if !defined(OS_ANDROID)
- ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
- viz::SurfaceManager* manager = factory->GetContextFactoryPrivate()
- ->GetFrameSinkManager()
- ->surface_manager();
- viz::Surface* surface = manager->GetSurfaceForId(id);
- EXPECT_TRUE(surface);
-#endif
+ viz::SurfaceId surface_id(view_->GetFrameSinkId(),
+ view_->GetLocalSurfaceId());
+ viz::SurfaceInfo surface_info(surface_id, scale_factor, view_size);
+ view_->OnFirstSurfaceActivation(surface_info);
- // Surface ID should have been passed to FrameConnectorDelegate to
- // be sent to the embedding renderer.
- EXPECT_EQ(viz::SurfaceInfo(id, scale_factor, view_size),
- test_frame_connector_->last_surface_info_);
- }
+ EXPECT_EQ(surface_info, test_frame_connector_->last_surface_info_);
}
// Tests that the viewport intersection rect is dispatched to the RenderWidget
@@ -261,29 +237,6 @@ TEST_F(RenderWidgetHostViewChildFrameTest, ViewportIntersectionUpdated) {
EXPECT_EQ(intersection_rect, std::get<1>(sent_rects));
}
-// Tests specific to non-scroll-latching behaviour.
-// TODO(mcnee): Remove once scroll-latching lands. crbug.com/526463
-class RenderWidgetHostViewChildFrameScrollLatchingDisabledTest
- : public RenderWidgetHostViewChildFrameTest {
- public:
- RenderWidgetHostViewChildFrameScrollLatchingDisabledTest() {}
-
- void SetUp() override {
- feature_list_.InitWithFeatures({},
- {features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents});
-
- RenderWidgetHostViewChildFrameTest::SetUp();
- DCHECK(!view_->wheel_scroll_latching_enabled());
- }
-
- private:
- base::test::ScopedFeatureList feature_list_;
-
- DISALLOW_COPY_AND_ASSIGN(
- RenderWidgetHostViewChildFrameScrollLatchingDisabledTest);
-};
-
class RenderWidgetHostViewChildFrameZoomForDSFTest
: public RenderWidgetHostViewChildFrameTest {
public:
@@ -297,26 +250,6 @@ class RenderWidgetHostViewChildFrameZoomForDSFTest
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.
-TEST_F(RenderWidgetHostViewChildFrameScrollLatchingDisabledTest,
- DoNotBubbleIfChildHasAlreadyScrolled) {
- blink::WebGestureEvent gesture_scroll(
- blink::WebGestureEvent::kGestureScrollBegin,
- blink::WebInputEvent::kNoModifiers,
- blink::WebInputEvent::GetStaticTimeStampForTests());
- view_->GestureEventAck(gesture_scroll, INPUT_EVENT_ACK_STATE_IGNORED);
-
- gesture_scroll.SetType(blink::WebGestureEvent::kGestureScrollUpdate);
- view_->GestureEventAck(gesture_scroll, INPUT_EVENT_ACK_STATE_CONSUMED);
- ASSERT_FALSE(test_frame_connector_->seen_bubbled_gsu_);
-
- view_->GestureEventAck(gesture_scroll,
- INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_FALSE(test_frame_connector_->seen_bubbled_gsu_);
-}
-
// Tests that moving the child around does not affect the physical backing size.
TEST_F(RenderWidgetHostViewChildFrameZoomForDSFTest,
CompositorViewportPixelSize) {
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.h b/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.h
index 0fd6933ba64..b2d9cecb8e2 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.h
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.h
@@ -15,6 +15,7 @@
#include "base/optional.h"
#include "content/browser/renderer_host/input/mouse_wheel_rails_filter_mac.h"
#include "content/common/edit_command.h"
+#include "content/common/render_widget_host_ns_view.mojom.h"
#import "ui/base/cocoa/command_dispatcher.h"
#import "ui/base/cocoa/tool_tip_base_view.h"
#include "ui/base/ime/ime_text_span.h"
@@ -26,7 +27,11 @@ class WebGestureEvent;
}
namespace content {
+namespace mojom {
class RenderWidgetHostNSViewClient;
+}
+
+class RenderWidgetHostNSViewLocalClient;
class RenderWidgetHostViewMac;
class RenderWidgetHostViewMacEditCommandHelper;
}
@@ -39,7 +44,7 @@ struct DidOverscrollParams;
@protocol RenderWidgetHostViewMacDelegate;
@protocol RenderWidgetHostNSViewClientOwner
-- (content::RenderWidgetHostNSViewClient*)renderWidgetHostNSViewClient;
+- (content::mojom::RenderWidgetHostNSViewClient*)renderWidgetHostNSViewClient;
@end
// This is the view that lives in the Cocoa view hierarchy. In Windows-land,
@@ -54,12 +59,24 @@ struct DidOverscrollParams;
@private
// The communications channel to the RenderWidgetHostViewMac. This pointer is
// always valid. When the original client disconnects, |client_| is changed to
- // point to |noopClient_|, to avoid having to preface every dereference with
+ // point to |dummyClient_|, to avoid having to preface every dereference with
// a nullptr check.
- content::RenderWidgetHostNSViewClient* client_;
+ content::mojom::RenderWidgetHostNSViewClient* client_;
+
+ // A separate client interface for the parts of the interface to
+ // RenderWidgetHostViewMac that cannot or should not be forwarded over mojo.
+ // This includes events (where the extra translation is unnecessary or loses
+ // information) and access to accessibility structures (only present in the
+ // browser process).
+ content::RenderWidgetHostNSViewLocalClient* localClient_;
+
+ // An implementation of the in-process interface that will translate and
+ // forward messages through |client_|.
+ std::unique_ptr<content::RenderWidgetHostNSViewLocalClient>
+ forwardingLocalClient_;
- // Dummy client that is always valid (see above).
- std::unique_ptr<content::RenderWidgetHostNSViewClient> noopClient_;
+ // Dummy client that is always valid (see above comments about client_).
+ content::mojom::RenderWidgetHostNSViewClientPtr dummyClient_;
// This ivar is the cocoa delegate of the NSResponder.
base::scoped_nsobject<NSObject<RenderWidgetHostViewMacDelegate>>
@@ -227,7 +244,8 @@ struct DidOverscrollParams;
- (void)unlockKeyboard;
// Methods previously marked as private.
-- (id)initWithClient:(content::RenderWidgetHostNSViewClient*)client;
+- (id)initWithClient:(content::mojom::RenderWidgetHostNSViewClient*)client
+ withLocalClient:(content::RenderWidgetHostNSViewLocalClient*)localClient;
- (void)setResponderDelegate:
(NSObject<RenderWidgetHostViewMacDelegate>*)delegate;
- (void)processedGestureScrollEvent:(const blink::WebGestureEvent&)event
diff --git a/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.mm b/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.mm
index d86576cc36a..8b84322baa8 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_cocoa.mm
@@ -20,6 +20,7 @@
#include "content/browser/renderer_host/render_widget_host_view_mac.h"
#import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h"
#import "content/public/browser/render_widget_host_view_mac_delegate.h"
+#include "ui/accessibility/platform/ax_platform_node.h"
#import "ui/base/clipboard/clipboard_util_mac.h"
#import "ui/base/cocoa/appkit_utils.h"
#include "ui/base/cocoa/cocoa_base_utils.h"
@@ -32,8 +33,10 @@
using content::BrowserAccessibility;
using content::BrowserAccessibilityManager;
using content::EditCommand;
+using content::InputEvent;
using content::NativeWebKeyboardEvent;
-using content::RenderWidgetHostNSViewClient;
+using content::mojom::RenderWidgetHostNSViewClient;
+using content::RenderWidgetHostNSViewLocalClient;
using content::RenderWidgetHostViewMacEditCommandHelper;
using content::WebGestureEventBuilder;
using content::WebMouseEventBuilder;
@@ -45,84 +48,76 @@ using blink::WebGestureEvent;
namespace {
-// No-op client used to avoid scattering of nullptr checks (see comments in
-// the client_ member of RenderWidgetHostViewCocoa).
-class NoopClient : public RenderWidgetHostNSViewClient {
+class ForwardingLocalClient : public RenderWidgetHostNSViewLocalClient {
public:
- NoopClient() {}
- ~NoopClient() override{};
+ explicit ForwardingLocalClient(RenderWidgetHostNSViewClient* client)
+ : client_(client) {}
- // RenderWidgetHostNSViewClient implementation:
+ private:
+ std::unique_ptr<InputEvent> TranslateEvent(
+ const blink::WebInputEvent& web_event) {
+ return std::make_unique<InputEvent>(web_event, ui::LatencyInfo());
+ }
+
+ // RenderWidgetHostNSViewLocalClient implementation.
BrowserAccessibilityManager* GetRootBrowserAccessibilityManager() override {
return nullptr;
}
- void OnNSViewSyncIsRenderViewHost(bool* is_render_view) override {}
- void OnNSViewRequestShutdown() override {}
- void OnNSViewIsFirstResponderChanged(bool is_first_responder) override {}
- void OnNSViewWindowIsKeyChanged(bool is_key) override {}
- void OnNSViewBoundsInWindowChanged(const gfx::Rect& view_bounds_in_window_dip,
- bool attached_to_window) override {}
- void OnNSViewWindowFrameInScreenChanged(
- const gfx::Rect& window_frame_in_screen_dip) override {}
- void OnNSViewDisplayChanged(const display::Display& display) override {}
- void OnNSViewBeginKeyboardEvent() override {}
- void OnNSViewEndKeyboardEvent() override {}
- void OnNSViewForwardKeyboardEvent(
- const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info) override {}
- void OnNSViewForwardKeyboardEventWithCommands(
+ void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event,
+ const ui::LatencyInfo& latency_info) override {
+ const blink::WebKeyboardEvent* web_event =
+ static_cast<const blink::WebKeyboardEvent*>(&key_event);
+ std::unique_ptr<InputEvent> input_event =
+ std::make_unique<InputEvent>(*web_event, latency_info);
+ client_->ForwardKeyboardEvent(std::move(input_event),
+ key_event.skip_in_browser);
+ }
+ void ForwardKeyboardEventWithCommands(
const NativeWebKeyboardEvent& key_event,
const ui::LatencyInfo& latency_info,
- const std::vector<EditCommand>& commands) override {}
- void OnNSViewRouteOrProcessMouseEvent(
- const blink::WebMouseEvent& web_event) override {}
- void OnNSViewRouteOrProcessWheelEvent(
- const blink::WebMouseWheelEvent& web_event) override {}
- void OnNSViewForwardMouseEvent(
- const blink::WebMouseEvent& web_event) override {}
- void OnNSViewForwardWheelEvent(
- const blink::WebMouseWheelEvent& web_event) override {}
- void OnNSViewGestureBegin(blink::WebGestureEvent begin_event,
- bool is_synthetically_injected) override {}
- void OnNSViewGestureUpdate(blink::WebGestureEvent update_event) override {}
- void OnNSViewGestureEnd(blink::WebGestureEvent end_event) override {}
- void OnNSViewSmartMagnify(
- const blink::WebGestureEvent& smart_magnify_event) override {}
- void OnNSViewImeSetComposition(
- const base::string16& text,
- const std::vector<ui::ImeTextSpan>& ime_text_spans,
- const gfx::Range& replacement_range,
- int selection_start,
- int selection_end) override {}
- void OnNSViewImeCommitText(const base::string16& text,
- const gfx::Range& replacement_range) override {}
- void OnNSViewImeFinishComposingText() override {}
- void OnNSViewImeCancelComposition() override {}
- void OnNSViewLookUpDictionaryOverlayAtPoint(
- const gfx::PointF& root_point) override {}
- void OnNSViewLookUpDictionaryOverlayFromRange(
- const gfx::Range& range) override {}
- void OnNSViewSyncGetCharacterIndexAtPoint(const gfx::PointF& root_point,
- uint32_t* index) override {}
- void OnNSViewSyncGetFirstRectForRange(const gfx::Range& requested_range,
- gfx::Rect* rect,
- gfx::Range* actual_range,
- bool* success) override {}
- void OnNSViewExecuteEditCommand(const std::string& command) override {}
- void OnNSViewUndo() override {}
- void OnNSViewRedo() override {}
- void OnNSViewCut() override {}
- void OnNSViewCopy() override {}
- void OnNSViewCopyToFindPboard() override {}
- void OnNSViewPaste() override {}
- void OnNSViewPasteAndMatchStyle() override {}
- void OnNSViewSelectAll() override {}
- void OnNSViewSpeakSelection() override {}
- void OnNSViewStopSpeaking() override {}
- void OnNSViewSyncIsSpeaking(bool* is_speaking) override {}
+ const std::vector<EditCommand>& commands) override {
+ const blink::WebKeyboardEvent* web_event =
+ static_cast<const blink::WebKeyboardEvent*>(&key_event);
+ std::unique_ptr<InputEvent> input_event =
+ std::make_unique<InputEvent>(*web_event, latency_info);
+ client_->ForwardKeyboardEventWithCommands(
+ std::move(input_event), key_event.skip_in_browser, commands);
+ }
+ void RouteOrProcessMouseEvent(
+ const blink::WebMouseEvent& web_event) override {
+ client_->RouteOrProcessMouseEvent(TranslateEvent(web_event));
+ }
+ void RouteOrProcessWheelEvent(
+ const blink::WebMouseWheelEvent& web_event) override {
+ client_->RouteOrProcessWheelEvent(TranslateEvent(web_event));
+ }
+ void ForwardMouseEvent(const blink::WebMouseEvent& web_event) override {
+ client_->ForwardMouseEvent(TranslateEvent(web_event));
+ }
+ void ForwardWheelEvent(const blink::WebMouseWheelEvent& web_event) override {
+ client_->ForwardWheelEvent(TranslateEvent(web_event));
+ }
+ void GestureBegin(blink::WebGestureEvent begin_event,
+ bool is_synthetically_injected) override {
+ // The gesture type is not yet known, but assign a type to avoid
+ // serialization asserts (the type will be stripped on the other side).
+ begin_event.SetType(blink::WebInputEvent::kGestureScrollBegin);
+ client_->GestureBegin(TranslateEvent(begin_event),
+ is_synthetically_injected);
+ }
+ void GestureUpdate(blink::WebGestureEvent update_event) override {
+ client_->GestureUpdate(TranslateEvent(update_event));
+ }
+ void GestureEnd(blink::WebGestureEvent end_event) override {
+ client_->GestureEnd(TranslateEvent(end_event));
+ }
+ void SmartMagnify(const blink::WebGestureEvent& web_event) override {
+ client_->SmartMagnify(TranslateEvent(web_event));
+ }
- private:
- DISALLOW_COPY_AND_ASSIGN(NoopClient);
+ RenderWidgetHostNSViewClient* client_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(ForwardingLocalClient);
};
// Whether a keyboard event has been reserved by OSX.
@@ -203,22 +198,27 @@ void ExtractUnderlines(NSAttributedString* string,
- (void)sendViewBoundsInWindowToClient;
- (void)sendWindowFrameInScreenToClient;
- (bool)clientIsDisconnected;
-- (bool)isKeyLocked:(int)keyCode;
@end
@implementation RenderWidgetHostViewCocoa
@synthesize markedRange = markedRange_;
@synthesize textInputType = textInputType_;
-- (id)initWithClient:(RenderWidgetHostNSViewClient*)client {
+- (id)initWithClient:(RenderWidgetHostNSViewClient*)client
+ withLocalClient:(RenderWidgetHostNSViewLocalClient*)localClient {
self = [super initWithFrame:NSZeroRect];
if (self) {
self.acceptsTouchEvents = YES;
editCommandHelper_.reset(new RenderWidgetHostViewMacEditCommandHelper);
editCommandHelper_->AddEditingSelectorsToClass([self class]);
- noopClient_ = std::make_unique<NoopClient>();
client_ = client;
+ if (localClient) {
+ localClient_ = localClient;
+ } else {
+ forwardingLocalClient_ = std::make_unique<ForwardingLocalClient>(client_);
+ localClient_ = forwardingLocalClient_.get();
+ }
canBeKeyView_ = YES;
isStylusEnteringProximity_ = false;
keyboardLockActive_ = false;
@@ -238,15 +238,6 @@ void ExtractUnderlines(NSAttributedString* string,
[[self window] makeFirstResponder:nil];
[NSApp updateWindows];
- // Debug key to check if the current input context still holds onto the view.
- NSTextInputContext* currentContext = [NSTextInputContext currentInputContext];
- auto* crashKey = base::debug::AllocateCrashKeyString(
- "text-input-context-client", base::debug::CrashKeySize::Size32);
- base::debug::ScopedCrashKeyString textInputContextCrashKey(
- crashKey, currentContext && [currentContext client] == self
- ? "text input still held on"
- : "text input no longer held on");
-
[super dealloc];
}
@@ -259,7 +250,7 @@ void ExtractUnderlines(NSAttributedString* string,
NSRect viewBoundsInView = [self bounds];
NSWindow* enclosingWindow = [self window];
if (!enclosingWindow) {
- client_->OnNSViewBoundsInWindowChanged(gfx::Rect(viewBoundsInView), false);
+ client_->OnBoundsInWindowChanged(gfx::Rect(viewBoundsInView), false);
return;
}
@@ -267,7 +258,7 @@ void ExtractUnderlines(NSAttributedString* string,
gfx::Rect gfxViewBoundsInWindow(viewBoundsInWindow);
gfxViewBoundsInWindow.set_y(NSHeight([enclosingWindow frame]) -
NSMaxY(viewBoundsInWindow));
- client_->OnNSViewBoundsInWindowChanged(gfxViewBoundsInWindow, true);
+ client_->OnBoundsInWindowChanged(gfxViewBoundsInWindow, true);
}
- (void)setTextSelectionText:(base::string16)text
@@ -299,7 +290,7 @@ void ExtractUnderlines(NSAttributedString* string,
NSWindow* enclosingWindow = [self window];
if (!enclosingWindow)
return;
- client_->OnNSViewWindowFrameInScreenChanged(
+ client_->OnWindowFrameInScreenChanged(
gfx::ScreenRectFromNSRect([enclosingWindow frame]));
}
@@ -371,7 +362,13 @@ void ExtractUnderlines(NSAttributedString* string,
}
- (void)setClientDisconnected {
- client_ = noopClient_.get();
+ // Set the client to be an abandoned message pipe, and set the localClient
+ // to forward messages to that client.
+ content::mojom::RenderWidgetHostNSViewClientRequest dummyClientRequest =
+ mojo::MakeRequest(&dummyClient_);
+ client_ = dummyClient_.get();
+ forwardingLocalClient_ = std::make_unique<ForwardingLocalClient>(client_);
+ localClient_ = forwardingLocalClient_.get();
// |responderDelegate_| may attempt to access the RenderWidgetHostViewMac
// through its internal pointers, so detach it here.
@@ -384,7 +381,7 @@ void ExtractUnderlines(NSAttributedString* string,
}
- (bool)clientIsDisconnected {
- return client_ == noopClient_.get();
+ return client_ == dummyClient_.get();
}
- (void)setShowingContextMenu:(BOOL)showing {
@@ -414,7 +411,7 @@ void ExtractUnderlines(NSAttributedString* string,
WebMouseEvent web_event = WebMouseEventBuilder::Build(event, self);
web_event.SetModifiers(web_event.GetModifiers() |
WebInputEvent::kRelativeMotionEvent);
- client_->OnNSViewForwardMouseEvent(web_event);
+ localClient_->ForwardMouseEvent(web_event);
}
- (BOOL)shouldIgnoreMouseEvent:(NSEvent*)theEvent {
@@ -482,6 +479,13 @@ void ExtractUnderlines(NSAttributedString* string,
if (subtype != NSTabletPointEventSubtype &&
subtype != NSTabletProximityEventSubtype) {
pointerType_ = blink::WebPointerProperties::PointerType::kMouse;
+ } else if (subtype == NSTabletProximityEventSubtype) {
+ isStylusEnteringProximity_ = [theEvent isEnteringProximity];
+ NSPointingDeviceType deviceType = [theEvent pointingDeviceType];
+ // For all tablet events, the pointer type will be pen or eraser.
+ pointerType_ = deviceType == NSEraserPointingDevice
+ ? blink::WebPointerProperties::PointerType::kEraser
+ : blink::WebPointerProperties::PointerType::kPen;
}
}
@@ -497,7 +501,7 @@ void ExtractUnderlines(NSAttributedString* string,
WebMouseEventBuilder::Build(theEvent, self, pointerType_);
exitEvent.SetType(WebInputEvent::kMouseLeave);
exitEvent.button = WebMouseEvent::Button::kNoButton;
- client_->OnNSViewForwardMouseEvent(exitEvent);
+ localClient_->ForwardMouseEvent(exitEvent);
}
mouseEventWasIgnored_ = YES;
return;
@@ -510,7 +514,7 @@ void ExtractUnderlines(NSAttributedString* string,
WebMouseEventBuilder::Build(theEvent, self, pointerType_);
enterEvent.SetType(WebInputEvent::kMouseMove);
enterEvent.button = WebMouseEvent::Button::kNoButton;
- client_->OnNSViewRouteOrProcessMouseEvent(enterEvent);
+ localClient_->RouteOrProcessMouseEvent(enterEvent);
}
mouseEventWasIgnored_ = NO;
@@ -540,7 +544,7 @@ void ExtractUnderlines(NSAttributedString* string,
WebMouseEvent event =
WebMouseEventBuilder::Build(theEvent, self, pointerType_);
- client_->OnNSViewRouteOrProcessMouseEvent(event);
+ localClient_->RouteOrProcessMouseEvent(event);
}
- (void)tabletEvent:(NSEvent*)theEvent {
@@ -565,7 +569,9 @@ void ExtractUnderlines(NSAttributedString* string,
lockedKeys_.reset();
}
-- (bool)isKeyLocked:(int)keyCode {
+// CommandDispatcherTarget implementation:
+- (BOOL)isKeyLocked:(NSEvent*)event {
+ int keyCode = [event keyCode];
// Note: We do not want to treat the ESC key as locked as that key is used
// to exit fullscreen and we don't want to prevent them from exiting.
ui::DomCode domCode = ui::KeycodeConverter::NativeKeycodeToDomCode(keyCode);
@@ -587,20 +593,6 @@ void ExtractUnderlines(NSAttributedString* string,
if (EventIsReservedBySystem(theEvent))
return NO;
- // If we return |NO| from this function, cocoa will send the key event to
- // the menu and only if the menu does not process the event to |keyDown:|. We
- // want to send the event to a renderer _before_ sending it to the menu, so
- // we need to return |YES| for all events that might be swallowed by the menu.
- // We do not return |YES| for every keypress because we don't get |keyDown:|
- // events for keys that we handle this way.
- NSUInteger modifierFlags = [theEvent modifierFlags];
- if ((modifierFlags & NSCommandKeyMask) == 0) {
- // Make sure the menu does not contain key equivalents that don't
- // contain cmd.
- DCHECK(![[NSApp mainMenu] performKeyEquivalent:theEvent]);
- return NO;
- }
-
// Command key combinations are sent via performKeyEquivalent rather than
// keyDown:. We just forward this on and if WebCore doesn't want to handle
// it, we let the WebContentsView figure out how to reinject it.
@@ -650,9 +642,6 @@ void ExtractUnderlines(NSAttributedString* string,
if (EventIsReservedBySystem(theEvent))
return;
- DCHECK(eventType != NSKeyDown ||
- !equiv == !(modifierFlags & NSCommandKeyMask));
-
if (eventType == NSFlagsChanged) {
// Ignore NSFlagsChanged events from the NumLock and Fn keys as
// Safari does in -[WebHTMLView flagsChanged:] (of "WebHTMLView.mm").
@@ -673,11 +662,11 @@ void ExtractUnderlines(NSAttributedString* string,
latency_info.set_source_event_type(ui::SourceEventType::KEY_PRESS);
}
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT);
// If KeyboardLock has been requested for this keyCode, then mark the event
// so it skips the pre-handler and is delivered straight to the website.
- if ([self isKeyLocked:keyCode])
+ if ([self isKeyLocked:theEvent])
event.skip_in_browser = true;
// Do not forward key up events unless preceded by a matching key down,
@@ -693,7 +682,7 @@ void ExtractUnderlines(NSAttributedString* string,
// Tell the client that we are beginning a keyboard event. This ensures that
// all event and Ime messages target the same RenderWidgetHost throughout this
// function call.
- client_->OnNSViewBeginKeyboardEvent();
+ client_->BeginKeyboardEvent();
bool shouldAutohideCursor = textInputType_ != ui::TEXT_INPUT_TYPE_NONE &&
eventType == NSKeyDown &&
@@ -701,7 +690,7 @@ void ExtractUnderlines(NSAttributedString* string,
// We only handle key down events and just simply forward other events.
if (eventType != NSKeyDown) {
- client_->OnNSViewForwardKeyboardEvent(event, latency_info);
+ localClient_->ForwardKeyboardEvent(event, latency_info);
// Possibly autohide the cursor.
if (shouldAutohideCursor) {
@@ -709,7 +698,7 @@ void ExtractUnderlines(NSAttributedString* string,
cursorHidden_ = YES;
}
- client_->OnNSViewEndKeyboardEvent();
+ client_->EndKeyboardEvent();
return;
}
@@ -759,7 +748,7 @@ void ExtractUnderlines(NSAttributedString* string,
NativeWebKeyboardEvent fakeEvent = event;
fakeEvent.windows_key_code = 0xE5; // VKEY_PROCESSKEY
fakeEvent.skip_in_browser = true;
- client_->OnNSViewForwardKeyboardEvent(fakeEvent, latency_info);
+ localClient_->ForwardKeyboardEvent(fakeEvent, latency_info);
// If this key event was handled by the input method, but
// -doCommandBySelector: (invoked by the call to -interpretKeyEvents: above)
// enqueued edit commands, then in order to let webkit handle them
@@ -770,8 +759,8 @@ void ExtractUnderlines(NSAttributedString* string,
if (hasEditCommands_ && !hasMarkedText_)
delayEventUntilAfterImeCompostion = YES;
} else {
- client_->OnNSViewForwardKeyboardEventWithCommands(event, latency_info,
- editCommands_);
+ localClient_->ForwardKeyboardEventWithCommands(event, latency_info,
+ editCommands_);
}
// Then send keypress and/or composition related events.
@@ -788,8 +777,7 @@ void ExtractUnderlines(NSAttributedString* string,
BOOL textInserted = NO;
if (textToBeInserted_.length() >
((hasMarkedText_ || oldHasMarkedText) ? 0u : 1u)) {
- client_->OnNSViewImeCommitText(textToBeInserted_,
- gfx::Range::InvalidRange());
+ client_->ImeCommitText(textToBeInserted_, gfx::Range::InvalidRange());
textInserted = YES;
}
@@ -800,15 +788,15 @@ void ExtractUnderlines(NSAttributedString* string,
// composition node in WebKit.
// When marked text is available, |markedTextSelectedRange_| will be the
// range being selected inside the marked text.
- client_->OnNSViewImeSetComposition(markedText_, ime_text_spans_,
- setMarkedTextReplacementRange_,
- markedTextSelectedRange_.location,
- NSMaxRange(markedTextSelectedRange_));
+ client_->ImeSetComposition(markedText_, ime_text_spans_,
+ setMarkedTextReplacementRange_,
+ markedTextSelectedRange_.location,
+ NSMaxRange(markedTextSelectedRange_));
} else if (oldHasMarkedText && !hasMarkedText_ && !textInserted) {
if (unmarkTextCalled_) {
- client_->OnNSViewImeFinishComposingText();
+ client_->ImeFinishComposingText();
} else {
- client_->OnNSViewImeCancelComposition();
+ client_->ImeCancelCompositionFromCocoa();
}
}
@@ -830,8 +818,8 @@ void ExtractUnderlines(NSAttributedString* string,
fakeEvent.skip_in_browser = true;
ui::LatencyInfo fake_event_latency_info = latency_info;
fake_event_latency_info.set_source_event_type(ui::SourceEventType::OTHER);
- client_->OnNSViewForwardKeyboardEvent(fakeEvent, fake_event_latency_info);
- client_->OnNSViewForwardKeyboardEventWithCommands(
+ localClient_->ForwardKeyboardEvent(fakeEvent, fake_event_latency_info);
+ localClient_->ForwardKeyboardEventWithCommands(
event, fake_event_latency_info, editCommands_);
}
@@ -845,7 +833,7 @@ void ExtractUnderlines(NSAttributedString* string,
event.text[0] = textToBeInserted_[0];
event.text[1] = 0;
event.skip_in_browser = true;
- client_->OnNSViewForwardKeyboardEvent(event, latency_info);
+ localClient_->ForwardKeyboardEvent(event, latency_info);
} else if ((!textInserted || delayEventUntilAfterImeCompostion) &&
event.text[0] != '\0' &&
((modifierFlags & kCtrlCmdKeyMask) ||
@@ -855,7 +843,7 @@ void ExtractUnderlines(NSAttributedString* string,
// cases, unless the key event generated any other command.
event.SetType(blink::WebInputEvent::kChar);
event.skip_in_browser = true;
- client_->OnNSViewForwardKeyboardEvent(event, latency_info);
+ localClient_->ForwardKeyboardEvent(event, latency_info);
}
}
@@ -865,7 +853,7 @@ void ExtractUnderlines(NSAttributedString* string,
cursorHidden_ = YES;
}
- client_->OnNSViewEndKeyboardEvent();
+ client_->EndKeyboardEvent();
}
- (BOOL)suppressNextKeyUpForTesting:(int)keyCode {
@@ -886,7 +874,7 @@ void ExtractUnderlines(NSAttributedString* string,
// History-swiping is not possible if the logic reaches this point.
WebMouseWheelEvent webEvent = WebMouseWheelEventBuilder::Build(event, self);
webEvent.rails_mode = mouseWheelFilter_.UpdateRailsMode(webEvent);
- client_->OnNSViewForwardWheelEvent(webEvent);
+ localClient_->ForwardWheelEvent(webEvent);
if (endWheelMonitor_) {
[NSEvent removeMonitor:endWheelMonitor_];
@@ -900,7 +888,7 @@ void ExtractUnderlines(NSAttributedString* string,
WebGestureEvent gestureBeginEvent(WebGestureEventBuilder::Build(event, self));
- client_->OnNSViewGestureBegin(gestureBeginEvent, isSyntheticallyInjected);
+ localClient_->GestureBegin(gestureBeginEvent, isSyntheticallyInjected);
}
- (void)handleEndGestureWithEvent:(NSEvent*)event {
@@ -915,7 +903,8 @@ void ExtractUnderlines(NSAttributedString* string,
endEvent.SetType(WebInputEvent::kGesturePinchEnd);
endEvent.SetSourceDevice(
blink::WebGestureDevice::kWebGestureDeviceTouchpad);
- client_->OnNSViewGestureEnd(endEvent);
+ endEvent.SetNeedsWheelEvent(true);
+ localClient_->GestureEnd(endEvent);
}
}
@@ -970,11 +959,11 @@ void ExtractUnderlines(NSAttributedString* string,
- (void)smartMagnifyWithEvent:(NSEvent*)event {
const WebGestureEvent& smartMagnifyEvent =
WebGestureEventBuilder::Build(event, self);
- client_->OnNSViewSmartMagnify(smartMagnifyEvent);
+ localClient_->SmartMagnify(smartMagnifyEvent);
}
- (void)showLookUpDictionaryOverlayFromRange:(NSRange)range {
- client_->OnNSViewLookUpDictionaryOverlayFromRange(gfx::Range(range));
+ client_->LookUpDictionaryOverlayFromRange(gfx::Range(range));
}
// This is invoked only on 10.8 or newer when the user taps a word using
@@ -982,7 +971,7 @@ void ExtractUnderlines(NSAttributedString* string,
- (void)quickLookWithEvent:(NSEvent*)event {
NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
gfx::PointF rootPoint(point.x, NSHeight([self frame]) - point.y);
- client_->OnNSViewLookUpDictionaryOverlayAtPoint(rootPoint);
+ client_->LookUpDictionaryOverlayAtPoint(rootPoint);
}
// This method handles 2 different types of hardware events.
@@ -1052,7 +1041,7 @@ void ExtractUnderlines(NSAttributedString* string,
// This is responsible for content scrolling!
WebMouseWheelEvent webEvent = WebMouseWheelEventBuilder::Build(event, self);
webEvent.rails_mode = mouseWheelFilter_.UpdateRailsMode(webEvent);
- client_->OnNSViewRouteOrProcessWheelEvent(webEvent);
+ localClient_->RouteOrProcessWheelEvent(webEvent);
}
// Called repeatedly during a pinch gesture, with incremental change values.
@@ -1085,7 +1074,7 @@ void ExtractUnderlines(NSAttributedString* string,
}
WebGestureEvent updateEvent = WebGestureEventBuilder::Build(event, self);
- client_->OnNSViewGestureUpdate(updateEvent);
+ localClient_->GestureUpdate(updateEvent);
}
- (void)viewWillMoveToWindow:(NSWindow*)newWindow {
@@ -1148,7 +1137,7 @@ void ExtractUnderlines(NSAttributedString* string,
// nil. Do that call here to avoid sending bogus display info to the client.
display::Display display =
display::Screen::GetScreen()->GetDisplayNearestView(self);
- client_->OnNSViewDisplayChanged(display);
+ client_->OnDisplayChanged(display);
}
// This will be called when the NSView's NSWindow moves from one NSScreen to
@@ -1211,7 +1200,7 @@ void ExtractUnderlines(NSAttributedString* string,
if ([responderDelegate_ respondsToSelector:@selector(windowDidBecomeKey)])
[responderDelegate_ windowDidBecomeKey];
if ([self window].isKeyWindow && [[self window] firstResponder] == self)
- client_->OnNSViewWindowIsKeyChanged(true);
+ client_->OnWindowIsKeyChanged(true);
}
- (void)windowDidResignKey:(NSNotification*)notification {
@@ -1226,7 +1215,7 @@ void ExtractUnderlines(NSAttributedString* string,
return;
if ([[self window] firstResponder] == self)
- client_->OnNSViewWindowIsKeyChanged(false);
+ client_->OnWindowIsKeyChanged(false);
}
- (BOOL)becomeFirstResponder {
@@ -1235,7 +1224,7 @@ void ExtractUnderlines(NSAttributedString* string,
if ([responderDelegate_ respondsToSelector:@selector(becomeFirstResponder)])
[responderDelegate_ becomeFirstResponder];
- client_->OnNSViewIsFirstResponderChanged(true);
+ client_->OnFirstResponderChanged(true);
// Cancel any onging composition text which was left before we lost focus.
// TODO(suzhe): We should do it in -resignFirstResponder: method, but
@@ -1259,10 +1248,10 @@ void ExtractUnderlines(NSAttributedString* string,
if ([responderDelegate_ respondsToSelector:@selector(resignFirstResponder)])
[responderDelegate_ resignFirstResponder];
- client_->OnNSViewIsFirstResponderChanged(false);
+ client_->OnFirstResponderChanged(false);
if (closeOnDeactivate_) {
[self setHidden:YES];
- client_->OnNSViewRequestShutdown();
+ client_->RequestShutdown();
}
// We should cancel any onging composition whenever RWH's Blur() method gets
@@ -1285,10 +1274,10 @@ void ExtractUnderlines(NSAttributedString* string,
}
bool is_render_view = false;
- client_->OnNSViewSyncIsRenderViewHost(&is_render_view);
+ client_->SyncIsRenderViewHost(&is_render_view);
bool is_speaking = false;
- client_->OnNSViewSyncIsSpeaking(&is_speaking);
+ client_->SyncIsSpeaking(&is_speaking);
SEL action = [item action];
@@ -1333,7 +1322,7 @@ void ExtractUnderlines(NSAttributedString* string,
- (id)accessibilityAttributeValue:(NSString*)attribute {
BrowserAccessibilityManager* manager =
- client_->GetRootBrowserAccessibilityManager();
+ localClient_->GetRootBrowserAccessibilityManager();
// Contents specifies document view of RenderWidgetHostViewCocoa provided by
// BrowserAccessibilityManager. Children includes all subviews in addition to
@@ -1359,7 +1348,7 @@ void ExtractUnderlines(NSAttributedString* string,
- (id)accessibilityHitTest:(NSPoint)point {
BrowserAccessibilityManager* manager =
- client_->GetRootBrowserAccessibilityManager();
+ localClient_->GetRootBrowserAccessibilityManager();
if (!manager)
return self;
NSPoint pointInWindow =
@@ -1374,13 +1363,13 @@ void ExtractUnderlines(NSAttributedString* string,
- (BOOL)accessibilityIsIgnored {
BrowserAccessibilityManager* manager =
- client_->GetRootBrowserAccessibilityManager();
+ localClient_->GetRootBrowserAccessibilityManager();
return !manager;
}
- (NSUInteger)accessibilityGetIndexOf:(id)child {
BrowserAccessibilityManager* manager =
- client_->GetRootBrowserAccessibilityManager();
+ localClient_->GetRootBrowserAccessibilityManager();
// Only child is root.
if (manager && ToBrowserAccessibilityCocoa(manager->GetRoot()) == child) {
return 0;
@@ -1390,8 +1379,18 @@ void ExtractUnderlines(NSAttributedString* string,
}
- (id)accessibilityFocusedUIElement {
+ // If content is overlayed with a focused popup from native UI code, this
+ // getter must return the current menu item as the focused element, rather
+ // than the focus within the content. An example of this occurs with the
+ // Autofill feature, where focus is actually still in the textbox although
+ // the UX acts as if focus is in the popup.
+ gfx::NativeViewAccessible popup_focus_override =
+ ui::AXPlatformNode::GetPopupFocusOverride();
+ if (popup_focus_override)
+ return popup_focus_override;
+
BrowserAccessibilityManager* manager =
- client_->GetRootBrowserAccessibilityManager();
+ localClient_->GetRootBrowserAccessibilityManager();
if (manager) {
BrowserAccessibility* focused_item = manager->GetFocus();
DCHECK(focused_item);
@@ -1488,7 +1487,7 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
gfx::PointF rootPoint(thePoint.x, thePoint.y);
uint32_t index = UINT32_MAX;
- client_->OnNSViewSyncGetCharacterIndexAtPoint(rootPoint, &index);
+ client_->SyncGetCharacterIndexAtPoint(rootPoint, &index);
// |index| could be WTF::notFound (-1) and its value is different from
// NSNotFound so we need to convert it.
if (index == UINT32_MAX)
@@ -1504,8 +1503,9 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
bool success = false;
if (actualRange)
gfxActualRange = gfx::Range(*actualRange);
- client_->OnNSViewSyncGetFirstRectForRange(gfx::Range(theRange), &gfxRect,
- &gfxActualRange, &success);
+ client_->SyncGetFirstRectForRange(gfx::Range(theRange), gfxRect,
+ gfxActualRange, &gfxRect, &gfxActualRange,
+ &success);
if (!success) {
// The call to cancelComposition comes from https://crrev.com/350261.
[self cancelComposition];
@@ -1629,7 +1629,7 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
// If we are handling a key down event, then FinishComposingText() will be
// called in keyEvent: method.
if (!handlingKeyDown_) {
- client_->OnNSViewImeFinishComposingText();
+ client_->ImeFinishComposingText();
} else {
unmarkTextCalled_ = YES;
}
@@ -1672,9 +1672,9 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
if (handlingKeyDown_) {
setMarkedTextReplacementRange_ = gfx::Range(replacementRange);
} else {
- client_->OnNSViewImeSetComposition(
- markedText_, ime_text_spans_, gfx::Range(replacementRange),
- newSelRange.location, NSMaxRange(newSelRange));
+ client_->ImeSetComposition(markedText_, ime_text_spans_,
+ gfx::Range(replacementRange),
+ newSelRange.location, NSMaxRange(newSelRange));
}
}
@@ -1700,7 +1700,7 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
base::CompareCase::INSENSITIVE_ASCII))
editCommands_.push_back(EditCommand(command, ""));
} else {
- client_->OnNSViewExecuteEditCommand(command);
+ client_->ExecuteEditCommand(command);
}
}
@@ -1726,8 +1726,8 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
textToBeInserted_.append(base::SysNSStringToUTF16(im_text));
} else {
gfx::Range replacement_range(replacementRange);
- client_->OnNSViewImeCommitText(base::SysNSStringToUTF16(im_text),
- replacement_range);
+ client_->ImeCommitText(base::SysNSStringToUTF16(im_text),
+ replacement_range);
}
// Inserting text will delete all marked text automatically.
@@ -1744,8 +1744,7 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
[self sendWindowFrameInScreenToClient];
[self sendViewBoundsInWindowToClient];
[self updateScreenProperties];
- client_->OnNSViewIsFirstResponderChanged([[self window] firstResponder] ==
- self);
+ client_->OnFirstResponderChanged([[self window] firstResponder] == self);
// If we switch windows (or are removed from the view hierarchy), cancel any
// open mouse-downs.
@@ -1753,37 +1752,37 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
WebMouseEvent event(WebInputEvent::kMouseUp, WebInputEvent::kNoModifiers,
ui::EventTimeForNow());
event.button = WebMouseEvent::Button::kLeft;
- client_->OnNSViewForwardMouseEvent(event);
+ localClient_->ForwardMouseEvent(event);
hasOpenMouseDown_ = NO;
}
}
- (void)undo:(id)sender {
- client_->OnNSViewUndo();
+ client_->Undo();
}
- (void)redo:(id)sender {
- client_->OnNSViewRedo();
+ client_->Redo();
}
- (void)cut:(id)sender {
- client_->OnNSViewCut();
+ client_->Cut();
}
- (void)copy:(id)sender {
- client_->OnNSViewCopy();
+ client_->Copy();
}
- (void)copyToFindPboard:(id)sender {
- client_->OnNSViewCopyToFindPboard();
+ client_->CopyToFindPboard();
}
- (void)paste:(id)sender {
- client_->OnNSViewPaste();
+ client_->Paste();
}
- (void)pasteAndMatchStyle:(id)sender {
- client_->OnNSViewPasteAndMatchStyle();
+ client_->PasteAndMatchStyle();
}
- (void)selectAll:(id)sender {
@@ -1794,15 +1793,15 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
// menu handler, neither is true.
// Explicitly call SelectAll() here to make sure the renderer returns
// selection results.
- client_->OnNSViewSelectAll();
+ client_->SelectAll();
}
- (void)startSpeaking:(id)sender {
- client_->OnNSViewSpeakSelection();
+ client_->StartSpeaking();
}
- (void)stopSpeaking:(id)sender {
- client_->OnNSViewStopSpeaking();
+ client_->StopSpeaking();
}
- (void)cancelComposition {
@@ -1821,7 +1820,7 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
if (!hasMarkedText_)
return;
- client_->OnNSViewImeFinishComposingText();
+ client_->ImeFinishComposingText();
[self cancelComposition];
}
@@ -1881,7 +1880,7 @@ extern NSString* NSTextInputReplacementRangeAttributeName;
- (void)popupWindowWillClose:(NSNotification*)notification {
[self setHidden:YES];
- client_->OnNSViewRequestShutdown();
+ client_->RequestShutdown();
}
@end
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 af9912a5f02..940d9c10766 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
@@ -368,14 +368,12 @@ void RenderWidgetHostViewEventHandler::OnMouseEvent(ui::MouseEvent* event) {
if (mouse_wheel_event.delta_x != 0 || mouse_wheel_event.delta_y != 0) {
bool should_route_event = ShouldRouteEvent(event);
- if (host_view_->wheel_scroll_latching_enabled()) {
- // End the touchpad scrolling sequence (if such exists) before handling
- // a ui::ET_MOUSEWHEEL event.
- mouse_wheel_phase_handler_.SendWheelEndForTouchpadScrollingIfNeeded();
+ // End the touchpad scrolling sequence (if such exists) before handling
+ // a ui::ET_MOUSEWHEEL event.
+ mouse_wheel_phase_handler_.SendWheelEndForTouchpadScrollingIfNeeded();
- mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
- mouse_wheel_event, should_route_event);
- }
+ mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
+ mouse_wheel_event, should_route_event);
if (should_route_event) {
host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(
host_view_, &mouse_wheel_event, *event->latency());
@@ -435,25 +433,29 @@ void RenderWidgetHostViewEventHandler::OnScrollEvent(ui::ScrollEvent* event) {
if (event->finger_count() != 2)
return;
#endif
- blink::WebGestureEvent gesture_event = ui::MakeWebGestureEventFlingCancel();
- // Coordinates need to be transferred to the fling cancel gesture only
- // for Surface-targeting to ensure that it is targeted to the correct
- // RenderWidgetHost.
- gesture_event.SetPositionInWidget(event->location_f());
blink::WebMouseWheelEvent mouse_wheel_event = ui::MakeWebMouseWheelEvent(
*event, base::Bind(&GetScreenLocationFromEvent));
- if (host_view_->wheel_scroll_latching_enabled()) {
- mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
- mouse_wheel_event, should_route_event);
+ mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
+ mouse_wheel_event, should_route_event);
+
+ base::Optional<blink::WebGestureEvent> maybe_synthetic_fling_cancel;
+ if (mouse_wheel_event.phase == blink::WebMouseWheelEvent::kPhaseBegan) {
+ maybe_synthetic_fling_cancel =
+ ui::MakeWebGestureEventFlingCancel(mouse_wheel_event);
}
+
if (should_route_event) {
- host_->delegate()->GetInputEventRouter()->RouteGestureEvent(
- host_view_, &gesture_event,
- ui::LatencyInfo(ui::SourceEventType::WHEEL));
+ if (maybe_synthetic_fling_cancel) {
+ host_->delegate()->GetInputEventRouter()->RouteGestureEvent(
+ host_view_, &*maybe_synthetic_fling_cancel,
+ ui::LatencyInfo(ui::SourceEventType::WHEEL));
+ }
host_->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(
host_view_, &mouse_wheel_event, *event->latency());
} else {
- host_->ForwardGestureEvent(gesture_event);
+ if (maybe_synthetic_fling_cancel) {
+ host_->ForwardGestureEvent(*maybe_synthetic_fling_cancel);
+ }
host_->ForwardWheelEventWithLatencyInfo(mouse_wheel_event,
*event->latency());
}
@@ -749,73 +751,75 @@ void RenderWidgetHostViewEventHandler::HandleMouseEventWhileLocked(
ProcessMouseWheelEvent(mouse_wheel_event, *event->latency());
}
}
- return;
- }
-
- gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint());
-
- // If we receive non client mouse messages while we are in the locked state
- // it probably means that the mouse left the borders of our window and
- // 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)
- MoveCursorToCenter();
- return;
- }
+ } else {
+ gfx::Point center(gfx::Rect(window_->bounds().size()).CenterPoint());
+
+ // If we receive non client mouse messages while we are in the locked state
+ // it probably means that the mouse left the borders of our window and
+ // 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)
+ MoveCursorToCenter();
+ return;
+ }
- blink::WebMouseEvent mouse_event =
- ui::MakeWebMouseEvent(*event, base::Bind(&GetScreenLocationFromEvent));
-
- bool is_move_to_center_event =
- (event->type() == ui::ET_MOUSE_MOVED ||
- event->type() == ui::ET_MOUSE_DRAGGED) &&
- mouse_event.PositionInWidget().x == center.x() &&
- mouse_event.PositionInWidget().y == center.y();
-
- // For fractional scale factors, the conversion from pixels to dip and
- // vice versa could result in off by 1 or 2 errors which hurts us because
- // we want to avoid sending the artificial move to center event to the
- // renderer. Sending the move to center to the renderer cause the cursor
- // to bounce around the center of the screen leading to the lock operation
- // not working correctly.
- // Workaround is to treat a mouse move or drag event off by at most 2 px
- // from the center as a move to center event.
- if (synthetic_move_sent_ &&
- IsFractionalScaleFactor(host_view_->current_device_scale_factor())) {
- if (event->type() == ui::ET_MOUSE_MOVED ||
- event->type() == ui::ET_MOUSE_DRAGGED) {
- if ((std::abs(mouse_event.PositionInWidget().x - center.x()) <= 2) &&
- (std::abs(mouse_event.PositionInWidget().y - center.y()) <= 2)) {
- is_move_to_center_event = true;
+ blink::WebMouseEvent mouse_event =
+ ui::MakeWebMouseEvent(*event, base::Bind(&GetScreenLocationFromEvent));
+
+ bool is_move_to_center_event =
+ (event->type() == ui::ET_MOUSE_MOVED ||
+ event->type() == ui::ET_MOUSE_DRAGGED) &&
+ mouse_event.PositionInWidget().x == center.x() &&
+ mouse_event.PositionInWidget().y == center.y();
+
+ // For fractional scale factors, the conversion from pixels to dip and
+ // vice versa could result in off by 1 or 2 errors which hurts us because
+ // we want to avoid sending the artificial move to center event to the
+ // renderer. Sending the move to center to the renderer cause the cursor
+ // to bounce around the center of the screen leading to the lock operation
+ // not working correctly.
+ // Workaround is to treat a mouse move or drag event off by at most 2 px
+ // from the center as a move to center event.
+ if (synthetic_move_sent_ &&
+ IsFractionalScaleFactor(host_view_->current_device_scale_factor())) {
+ if (event->type() == ui::ET_MOUSE_MOVED ||
+ event->type() == ui::ET_MOUSE_DRAGGED) {
+ if ((std::abs(mouse_event.PositionInWidget().x - center.x()) <= 2) &&
+ (std::abs(mouse_event.PositionInWidget().y - center.y()) <= 2)) {
+ is_move_to_center_event = true;
+ }
}
}
- }
- ModifyEventMovementAndCoords(*event, &mouse_event);
+ ModifyEventMovementAndCoords(*event, &mouse_event);
- bool should_not_forward = is_move_to_center_event && synthetic_move_sent_;
- if (should_not_forward) {
- synthetic_move_sent_ = false;
- } else {
- // Check if the mouse has reached the border and needs to be centered.
- if (ShouldMoveToCenter())
- MoveCursorToCenter();
- bool is_selection_popup = NeedsInputGrab(popup_child_host_view_);
- // Forward event to renderer.
- if (CanRendererHandleEvent(event, mouse_locked_, is_selection_popup) &&
- !(event->flags() & ui::EF_FROM_TOUCH)) {
- if (ShouldRouteEvent(event)) {
- host_->delegate()->GetInputEventRouter()->RouteMouseEvent(
- host_view_, &mouse_event, *event->latency());
- } else {
- ProcessMouseEvent(mouse_event, *event->latency());
+ bool should_not_forward = is_move_to_center_event && synthetic_move_sent_;
+ if (should_not_forward) {
+ synthetic_move_sent_ = false;
+ } else {
+ // Check if the mouse has reached the border and needs to be centered.
+ if (ShouldMoveToCenter())
+ MoveCursorToCenter();
+ bool is_selection_popup = NeedsInputGrab(popup_child_host_view_);
+ // Forward event to renderer.
+ if (CanRendererHandleEvent(event, mouse_locked_, is_selection_popup) &&
+ !(event->flags() & ui::EF_FROM_TOUCH)) {
+ if (ShouldRouteEvent(event)) {
+ host_->delegate()->GetInputEventRouter()->RouteMouseEvent(
+ host_view_, &mouse_event, *event->latency());
+ } else {
+ ProcessMouseEvent(mouse_event, *event->latency());
+ }
+ // Ensure that we get keyboard focus on mouse down as a plugin window
+ // may have grabbed keyboard focus.
+ if (event->type() == ui::ET_MOUSE_PRESSED)
+ SetKeyboardFocus();
}
- // Ensure that we get keyboard focus on mouse down as a plugin window
- // may have grabbed keyboard focus.
- if (event->type() == ui::ET_MOUSE_PRESSED)
- SetKeyboardFocus();
}
}
+ if (!ShouldGenerateAppCommand(event))
+ event->SetHandled();
}
void RenderWidgetHostViewEventHandler::ModifyEventMovementAndCoords(
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 2e4f30a6017..5db1ce0507a 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
@@ -179,6 +179,8 @@ class CONTENT_EXPORT RenderWidgetHostViewEventHandler
FRIEND_TEST_ALL_PREFIXES(
RenderWidgetHostViewAuraTest,
KeyEventRoutingKeyboardLockAndChildPopupWithoutInputGrab);
+ friend class MockPointerLockRenderWidgetHostView;
+
// Returns true if the |event| passed in can be forwarded to the renderer.
bool CanRendererHandleEvent(const ui::MouseEvent* event,
bool mouse_locked,
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 7a4fdcecf33..052bcb2791c 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
@@ -21,21 +21,14 @@
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/browser/renderer_host/text_input_manager.h"
#include "content/common/content_export.h"
+#include "content/common/render_widget_host_ns_view.mojom.h"
#include "ipc/ipc_sender.h"
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
+#include "ui/accelerated_widget_mac/ca_transaction_observer.h"
#include "ui/accelerated_widget_mac/display_link_mac.h"
#include "ui/base/cocoa/remote_layer_api.h"
#include "ui/events/gesture_detection/filtered_gesture_provider.h"
-namespace content {
-class CursorManager;
-class RenderWidgetHost;
-class RenderWidgetHostNSViewBridge;
-class RenderWidgetHostViewMac;
-class WebContents;
-class WebCursor;
-}
-
namespace ui {
enum class DomCode;
class ScopedPasswordInputEnabler;
@@ -47,6 +40,13 @@ class ScopedPasswordInputEnabler;
namespace content {
+class CursorManager;
+class RenderWidgetHost;
+class RenderWidgetHostNSViewBridgeLocal;
+class RenderWidgetHostViewMac;
+class WebContents;
+class WebCursor;
+
///////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewMac
//
@@ -65,9 +65,11 @@ namespace content {
// RenderWidgetHostView class hierarchy described in render_widget_host_view.h.
class CONTENT_EXPORT RenderWidgetHostViewMac
: public RenderWidgetHostViewBase,
- public RenderWidgetHostNSViewClient,
+ public RenderWidgetHostNSViewLocalClient,
+ public mojom::RenderWidgetHostNSViewClient,
public BrowserCompositorMacClient,
public TextInputManager::Observer,
+ public ui::CATransactionCoordinator::PreCommitObserver,
public ui::GestureProviderClient,
public ui::AcceleratedWidgetMacNSView,
public IPC::Sender {
@@ -104,6 +106,7 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
void WasUnOccluded() override;
void WasOccluded() override;
gfx::Rect GetViewBounds() const override;
+ bool IsMouseLocked() override;
void SetActive(bool active) override;
void ShowDefinitionForSelection() override;
void SpeakSelection() override;
@@ -150,10 +153,9 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
BrowserAccessibilityManager* CreateBrowserAccessibilityManager(
BrowserAccessibilityDelegate* delegate, bool for_root_frame) override;
gfx::Point AccessibilityOriginInScreen(const gfx::Rect& bounds) override;
- gfx::AcceleratedWidget AccessibilityGetAcceleratedWidget() override;
+ gfx::NativeViewAccessible AccessibilityGetNativeViewAccessible() override;
base::Optional<SkColor> GetBackgroundColor() const override;
- bool ShouldContinueToPauseForFrame() override;
void SetParentUiLayer(ui::Layer* parent_ui_layer) override;
void TransformPointToRootSurface(gfx::PointF* point) override;
gfx::Rect GetBoundsInRootWindow() override;
@@ -166,6 +168,7 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
bool LockKeyboard(base::Optional<base::flat_set<ui::DomCode>> codes) override;
void UnlockKeyboard() override;
bool IsKeyboardLocked() override;
+ base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
void GestureEventAck(const blink::WebGestureEvent& event,
InputEventAckState ack_result) override;
void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
@@ -176,8 +179,8 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
std::unique_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget()
override;
- viz::FrameSinkId GetFrameSinkId() override;
- viz::LocalSurfaceId GetLocalSurfaceId() const override;
+ const viz::FrameSinkId& GetFrameSinkId() const override;
+ const viz::LocalSurfaceId& GetLocalSurfaceId() const 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
@@ -220,11 +223,15 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
void OnTextSelectionChanged(TextInputManager* text_input_manager,
RenderWidgetHostViewBase* updated_view) override;
+ // ui::CATransactionCoordinator::PreCommitObserver implementation
+ bool ShouldWaitInPreCommit() override;
+ base::TimeDelta PreCommitTimeout() override;
+
// ui::GestureProviderClient implementation.
void OnGestureEvent(const ui::GestureEventData& gesture) override;
// RenderFrameMetadataProvider::Observer
- void OnRenderFrameMetadataChanged() override;
+ void OnRenderFrameMetadataChangedAfterActivation() override;
// IPC::Sender implementation.
bool Send(IPC::Message* message) override;
@@ -292,74 +299,94 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// RenderWidgetHostImpl as well.
void UpdateNSViewAndDisplayProperties();
- void PauseForPendingResizeOrRepaintsAndDraw();
-
- // RenderWidgetHostNSViewClient implementation.
+ // RenderWidgetHostNSViewLocalClient implementation.
BrowserAccessibilityManager* GetRootBrowserAccessibilityManager() override;
- void OnNSViewSyncIsRenderViewHost(bool* is_render_view) override;
- void OnNSViewRequestShutdown() override;
- void OnNSViewIsFirstResponderChanged(bool is_first_responder) override;
- void OnNSViewWindowIsKeyChanged(bool is_key) override;
- void OnNSViewBoundsInWindowChanged(const gfx::Rect& view_bounds_in_window_dip,
- bool attached_to_window) override;
- void OnNSViewWindowFrameInScreenChanged(
- const gfx::Rect& window_frame_in_screen_dip) override;
- void OnNSViewDisplayChanged(const display::Display& display) override;
- void OnNSViewBeginKeyboardEvent() override;
- void OnNSViewEndKeyboardEvent() override;
- void OnNSViewForwardKeyboardEvent(
- const NativeWebKeyboardEvent& key_event,
- const ui::LatencyInfo& latency_info) override;
- void OnNSViewForwardKeyboardEventWithCommands(
+ void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event,
+ const ui::LatencyInfo& latency_info) override;
+ void ForwardKeyboardEventWithCommands(
const NativeWebKeyboardEvent& key_event,
const ui::LatencyInfo& latency_info,
const std::vector<EditCommand>& commands) override;
- void OnNSViewRouteOrProcessMouseEvent(
- const blink::WebMouseEvent& web_event) override;
- void OnNSViewRouteOrProcessWheelEvent(
- const blink::WebMouseWheelEvent& web_event) override;
- void OnNSViewForwardMouseEvent(
- const blink::WebMouseEvent& web_event) override;
- void OnNSViewForwardWheelEvent(
+ void RouteOrProcessMouseEvent(const blink::WebMouseEvent& web_event) override;
+ void RouteOrProcessWheelEvent(
const blink::WebMouseWheelEvent& web_event) override;
- void OnNSViewGestureBegin(blink::WebGestureEvent begin_event,
- bool is_synthetically_injected) override;
- void OnNSViewGestureUpdate(blink::WebGestureEvent update_event) override;
- void OnNSViewGestureEnd(blink::WebGestureEvent end_event) override;
- void OnNSViewSmartMagnify(
- const blink::WebGestureEvent& smart_magnify_event) override;
- void OnNSViewImeSetComposition(
- const base::string16& text,
- const std::vector<ui::ImeTextSpan>& ime_text_spans,
- const gfx::Range& replacement_range,
- int selection_start,
- int selection_end) override;
- void OnNSViewImeCommitText(const base::string16& text,
- const gfx::Range& replacement_range) override;
- void OnNSViewImeFinishComposingText() override;
- void OnNSViewImeCancelComposition() override;
- void OnNSViewLookUpDictionaryOverlayAtPoint(
- const gfx::PointF& root_point) override;
- void OnNSViewLookUpDictionaryOverlayFromRange(
- const gfx::Range& range) override;
- void OnNSViewSyncGetCharacterIndexAtPoint(const gfx::PointF& root_point,
- uint32_t* index) override;
- void OnNSViewSyncGetFirstRectForRange(const gfx::Range& requested_range,
- gfx::Rect* rect,
- gfx::Range* actual_range,
- bool* success) override;
- void OnNSViewExecuteEditCommand(const std::string& command) override;
- void OnNSViewUndo() override;
- void OnNSViewRedo() override;
- void OnNSViewCut() override;
- void OnNSViewCopy() override;
- void OnNSViewCopyToFindPboard() override;
- void OnNSViewPaste() override;
- void OnNSViewPasteAndMatchStyle() override;
- void OnNSViewSelectAll() override;
- void OnNSViewSpeakSelection() override;
- void OnNSViewStopSpeaking() override;
- void OnNSViewSyncIsSpeaking(bool* is_speaking) override;
+ void ForwardMouseEvent(const blink::WebMouseEvent& web_event) override;
+ void ForwardWheelEvent(const blink::WebMouseWheelEvent& web_event) override;
+ void GestureBegin(blink::WebGestureEvent begin_event,
+ bool is_synthetically_injected) override;
+ void GestureUpdate(blink::WebGestureEvent update_event) override;
+ void GestureEnd(blink::WebGestureEvent end_event) override;
+ void SmartMagnify(const blink::WebGestureEvent& smart_magnify_event) override;
+
+ // mojom::RenderWidgetHostNSViewClient implementation.
+ void SyncIsRenderViewHost(SyncIsRenderViewHostCallback callback) override;
+ bool SyncIsRenderViewHost(bool* is_render_view) override;
+ void RequestShutdown() override;
+ void OnFirstResponderChanged(bool is_first_responder) override;
+ void OnWindowIsKeyChanged(bool is_key) override;
+ void OnBoundsInWindowChanged(const gfx::Rect& view_bounds_in_window_dip,
+ bool attached_to_window) override;
+ void OnWindowFrameInScreenChanged(
+ const gfx::Rect& window_frame_in_screen_dip) override;
+ void OnDisplayChanged(const display::Display& display) override;
+ void BeginKeyboardEvent() override;
+ void EndKeyboardEvent() override;
+
+ void ForwardKeyboardEvent(std::unique_ptr<InputEvent> event,
+ bool skip_in_browser) override;
+ void ForwardKeyboardEventWithCommands(
+ std::unique_ptr<InputEvent> event,
+ bool skip_in_browser,
+ const std::vector<EditCommand>& commands) override;
+ void RouteOrProcessMouseEvent(std::unique_ptr<InputEvent> event) override;
+ void RouteOrProcessWheelEvent(std::unique_ptr<InputEvent> event) override;
+ void ForwardMouseEvent(std::unique_ptr<InputEvent> event) override;
+ void ForwardWheelEvent(std::unique_ptr<InputEvent> event) override;
+ void GestureBegin(std::unique_ptr<InputEvent> event,
+ bool is_synthetically_injected) override;
+ void GestureUpdate(std::unique_ptr<InputEvent> event) override;
+ void GestureEnd(std::unique_ptr<InputEvent> event) override;
+ void SmartMagnify(std::unique_ptr<InputEvent> event) override;
+ void ImeSetComposition(const base::string16& text,
+ const std::vector<ui::ImeTextSpan>& ime_text_spans,
+ const gfx::Range& replacement_range,
+ int selection_start,
+ int selection_end) override;
+ void ImeCommitText(const base::string16& text,
+ const gfx::Range& replacement_range) override;
+ void ImeFinishComposingText() override;
+ void ImeCancelCompositionFromCocoa() override;
+ void LookUpDictionaryOverlayAtPoint(const gfx::PointF& root_point) override;
+ void LookUpDictionaryOverlayFromRange(const gfx::Range& range) override;
+ void SyncGetCharacterIndexAtPoint(
+ const gfx::PointF& root_point,
+ SyncGetCharacterIndexAtPointCallback callback) override;
+ bool SyncGetCharacterIndexAtPoint(const gfx::PointF& root_point,
+ uint32_t* index) override;
+ void SyncGetFirstRectForRange(
+ const gfx::Range& requested_range,
+ const gfx::Rect& rect,
+ const gfx::Range& actual_range,
+ SyncGetFirstRectForRangeCallback callback) override;
+ bool SyncGetFirstRectForRange(const gfx::Range& requested_range,
+ const gfx::Rect& rect,
+ const gfx::Range& actual_range,
+ gfx::Rect* out_rect,
+ gfx::Range* out_actual_range,
+ bool* out_success) override;
+ void ExecuteEditCommand(const std::string& command) override;
+ void Undo() override;
+ void Redo() override;
+ void Cut() override;
+ void Copy() override;
+ void CopyToFindPboard() override;
+ void Paste() override;
+ void PasteAndMatchStyle() override;
+ void SelectAll() override;
+ void StartSpeaking() override;
+ void StopSpeaking() override;
+ bool SyncIsSpeaking(bool* is_speaking) override;
+ void SyncIsSpeaking(SyncIsSpeakingCallback callback) override;
// BrowserCompositorMacClient implementation.
SkColor BrowserCompositorMacGetGutterColor() const override;
@@ -367,10 +394,11 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
void OnFrameTokenChanged(uint32_t frame_token) override;
void DidReceiveFirstFrameAfterNavigation() override;
void DestroyCompositorForShutdown() override;
- bool SynchronizeVisualProperties() override;
+ bool SynchronizeVisualProperties(
+ const base::Optional<viz::LocalSurfaceId>&
+ child_allocated_local_surface_id) override;
// AcceleratedWidgetMacNSView implementation.
- NSView* AcceleratedWidgetGetNSView() const override;
void AcceleratedWidgetCALayerParamsUpdated() override;
void SetShowingContextMenu(bool showing) override;
@@ -423,6 +451,7 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
private:
friend class RenderWidgetHostViewMacTest;
+ friend class MockPointerLockRenderWidgetHostView;
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewMacTest, GetPageTextForSpeech);
// Allocate a new FrameSinkId if this object is the platform view of a
@@ -465,8 +494,15 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
using SpeechCallback = base::OnceCallback<void(const base::string16&)>;
void GetPageTextForSpeech(SpeechCallback callback);
- // Interface through which the NSView is to be manipulated.
- std::unique_ptr<RenderWidgetHostNSViewBridge> ns_view_bridge_;
+ // Interface through which the NSView is to be manipulated. This points either
+ // to |ns_view_bridge_local_| or to (to-be-added) |ns_view_bridge_remote_|.
+ mojom::RenderWidgetHostNSViewBridge* ns_view_bridge_ = nullptr;
+
+ // If |ns_view_bridge_| is hosted in this process, then this will be non-null,
+ // and may be used to query the actual RenderWidgetHostViewCocoa that is being
+ // used for |this|. Any functionality that uses |new_view_bridge_local_| will
+ // not work when the RenderWidgetHostViewCocoa is hosted in an app process.
+ std::unique_ptr<RenderWidgetHostNSViewBridgeLocal> ns_view_bridge_local_;
// State tracked by Show/Hide/IsShowing.
bool is_visible_ = false;
@@ -492,9 +528,6 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// Indicates if the page is loading.
bool is_loading_;
- // Whether it's allowed to pause waiting for a new frame.
- bool allow_pause_for_resize_or_repaint_;
-
// True when this view acts as a platform view hack for a
// RenderWidgetHostViewGuest.
bool is_guest_view_hack_;
@@ -524,8 +557,6 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// AcceleratedWidgetCALayerParamsUpdated).
SkColor last_frame_root_background_color_ = SK_ColorTRANSPARENT;
- int tab_show_sequence_ = 0;
-
std::unique_ptr<CursorManager> cursor_manager_;
// Used to track active password input sessions.
@@ -564,6 +595,13 @@ class CONTENT_EXPORT RenderWidgetHostViewMac
// Tracks whether keyboard lock is active.
bool is_keyboard_locked_ = false;
+ // While the mouse is locked, the cursor is hidden from the user. Mouse events
+ // are still generated. However, the position they report is the last known
+ // mouse position just as mouse lock was entered; the movement they report
+ // indicates what the change in position of the mouse would be had it not been
+ // locked.
+ bool mouse_locked_ = false;
+
// Latest capture sequence number which is incremented when the caller
// requests surfaces be synchronized via
// EnsureSurfaceSynchronizedForLayoutTest().
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 8b012bcb8f7..0703dd02c90 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
@@ -27,7 +27,7 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_helper.h"
#include "content/browser/renderer_host/render_widget_host_input_event_router.h"
-#import "content/browser/renderer_host/render_widget_host_ns_view_bridge.h"
+#import "content/browser/renderer_host/render_widget_host_ns_view_bridge_local.h"
#import "content/browser/renderer_host/render_widget_host_view_cocoa.h"
#import "content/browser/renderer_host/text_input_client_mac.h"
#import "content/browser/renderer_host/ui_events_helper.h"
@@ -51,6 +51,7 @@
#include "ui/display/screen.h"
#include "ui/events/gesture_detection/gesture_provider_config_helper.h"
#include "ui/events/keycodes/dom/dom_code.h"
+#include "ui/events/keycodes/dom/dom_keyboard_layout_map.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/mac/coordinate_conversion.h"
@@ -59,6 +60,10 @@ using blink::WebMouseEvent;
using blink::WebGestureEvent;
using blink::WebTouchEvent;
+namespace {
+constexpr auto kContentPaintTimeout = base::TimeDelta::FromMilliseconds(167);
+} // namespace
+
namespace content {
////////////////////////////////////////////////////////////////////////////////
@@ -98,17 +103,28 @@ void RenderWidgetHostViewMac::DestroyCompositorForShutdown() {
Destroy();
}
-bool RenderWidgetHostViewMac::SynchronizeVisualProperties() {
+bool RenderWidgetHostViewMac::SynchronizeVisualProperties(
+ const base::Optional<viz::LocalSurfaceId>&
+ child_allocated_local_surface_id) {
+ if (child_allocated_local_surface_id) {
+ browser_compositor_->UpdateRendererLocalSurfaceIdFromChild(
+ *child_allocated_local_surface_id);
+ } else {
+ browser_compositor_->AllocateNewRendererLocalSurfaceId();
+ }
+
+ if (auto* host = browser_compositor_->GetDelegatedFrameHost()) {
+ host->EmbedSurface(browser_compositor_->GetRendererLocalSurfaceId(),
+ browser_compositor_->GetRendererSize(),
+ cc::DeadlinePolicy::UseDefaultDeadline());
+ }
+
return host()->SynchronizeVisualProperties();
}
////////////////////////////////////////////////////////////////////////////////
// AcceleratedWidgetMacNSView, public:
-NSView* RenderWidgetHostViewMac::AcceleratedWidgetGetNSView() const {
- return cocoa_view();
-}
-
void RenderWidgetHostViewMac::AcceleratedWidgetCALayerParamsUpdated() {
// Set the background color for the root layer from the frame that just
// swapped. See RenderWidgetHostViewAura for more details. Note that this is
@@ -135,14 +151,15 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget,
page_at_minimum_scale_(true),
mouse_wheel_phase_handler_(this),
is_loading_(false),
- allow_pause_for_resize_or_repaint_(true),
is_guest_view_hack_(is_guest_view_hack),
gesture_provider_(ui::GetGestureProviderConfig(
ui::GestureProviderConfigType::CURRENT_PLATFORM),
this),
weak_factory_(this) {
// The NSView is on the other side of |ns_view_bridge_|.
- ns_view_bridge_ = RenderWidgetHostNSViewBridge::Create(this);
+ ns_view_bridge_local_ =
+ std::make_unique<RenderWidgetHostNSViewBridgeLocal>(this, this);
+ ns_view_bridge_ = ns_view_bridge_local_.get();
// Guess that the initial screen we will be on is the screen of the current
// window (since that's the best guess that we have, and is usually right).
@@ -154,9 +171,9 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget,
? AllocateFrameSinkIdForGuestViewHack()
: host()->GetFrameSinkId();
- browser_compositor_.reset(
- new BrowserCompositorMac(this, this, host()->is_hidden(),
- [cocoa_view() window], display_, frame_sink_id));
+ browser_compositor_.reset(new BrowserCompositorMac(
+ this, this, host()->is_hidden(), display_, frame_sink_id));
+ DCHECK(![cocoa_view() window]);
if (!is_guest_view_hack_)
host()->SetView(this);
@@ -193,13 +210,17 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget,
// startup raciness and decrease latency.
needs_begin_frames_ = needs_begin_frames;
UpdateNeedsBeginFramesInternal();
+ if (features::IsViewsBrowserCocoa())
+ ui::CATransactionCoordinator::Get().AddPreCommitObserver(this);
}
RenderWidgetHostViewMac::~RenderWidgetHostViewMac() {
+ if (features::IsViewsBrowserCocoa())
+ ui::CATransactionCoordinator::Get().RemovePreCommitObserver(this);
}
void RenderWidgetHostViewMac::SetParentUiLayer(ui::Layer* parent_ui_layer) {
- if (!display_only_using_parent_ui_layer_) {
+ if (parent_ui_layer && !display_only_using_parent_ui_layer_) {
// The first time that we display using a parent ui::Layer, permanently
// switch from drawing using Cocoa to only drawing using ui::Views. Erase
// the existing content being drawn by Cocoa (which may have been set due
@@ -214,7 +235,9 @@ void RenderWidgetHostViewMac::SetParentUiLayer(ui::Layer* parent_ui_layer) {
}
RenderWidgetHostViewCocoa* RenderWidgetHostViewMac::cocoa_view() const {
- return ns_view_bridge_->GetRenderWidgetHostViewCocoa();
+ if (ns_view_bridge_local_)
+ return ns_view_bridge_local_->GetRenderWidgetHostViewCocoa();
+ return nullptr;
}
void RenderWidgetHostViewMac::SetDelegate(
@@ -223,7 +246,8 @@ void RenderWidgetHostViewMac::SetDelegate(
}
void RenderWidgetHostViewMac::SetAllowPauseForResizeOrRepaint(bool allow) {
- allow_pause_for_resize_or_repaint_ = allow;
+ // TODO: Remove SetAllowPauseForResizeOrRepaint and SetAllowOtherViews, since
+ // they aren't used anymore.
}
ui::TextInputType RenderWidgetHostViewMac::GetTextInputType() {
@@ -326,6 +350,9 @@ void RenderWidgetHostViewMac::UpdateNSViewAndDisplayProperties() {
}
}
+ if (features::IsViewsBrowserCocoa())
+ ui::CATransactionCoordinator::Get().Synchronize();
+
// During auto-resize it is the responsibility of the caller to ensure that
// the NSView and RenderWidgetHostImpl are kept in sync.
if (host()->auto_resize_enabled())
@@ -353,32 +380,44 @@ void RenderWidgetHostViewMac::GetScreenInfo(ScreenInfo* screen_info) const {
void RenderWidgetHostViewMac::Show() {
is_visible_ = true;
ns_view_bridge_->SetVisible(is_visible_);
+ browser_compositor_->SetViewVisible(is_visible_);
browser_compositor_->SetRenderWidgetHostIsHidden(false);
- ui::LatencyInfo renderer_latency_info;
- renderer_latency_info.AddLatencyNumber(ui::TAB_SHOW_COMPONENT,
- host()->GetLatencyComponentId());
- renderer_latency_info.set_trace_id(++tab_show_sequence_);
- host()->WasShown(renderer_latency_info);
- TRACE_EVENT_ASYNC_BEGIN0("latency", "TabSwitching::Latency",
- tab_show_sequence_);
-
- // If there is not a frame being currently drawn, kick one, so that the below
- // pause will have a frame to wait on.
- host()->RequestRepaintForTesting();
- PauseForPendingResizeOrRepaintsAndDraw();
+ WasUnOccluded();
}
void RenderWidgetHostViewMac::Hide() {
is_visible_ = false;
ns_view_bridge_->SetVisible(is_visible_);
+ browser_compositor_->SetViewVisible(is_visible_);
host()->WasHidden();
browser_compositor_->SetRenderWidgetHostIsHidden(true);
}
void RenderWidgetHostViewMac::WasUnOccluded() {
browser_compositor_->SetRenderWidgetHostIsHidden(false);
- host()->WasShown(ui::LatencyInfo());
+
+ DelegatedFrameHost* delegated_frame_host =
+ browser_compositor_->GetDelegatedFrameHost();
+
+ bool has_saved_frame =
+ delegated_frame_host ? delegated_frame_host->HasSavedFrame() : false;
+
+ // If the primary surface was evicted, we should create a new primary.
+ if (delegated_frame_host && delegated_frame_host->IsPrimarySurfaceEvicted())
+ SynchronizeVisualProperties(base::nullopt);
+
+ const bool renderer_should_record_presentation_time = !has_saved_frame;
+ host()->WasShown(renderer_should_record_presentation_time);
+
+ if (delegated_frame_host) {
+ // If the frame for the renderer is already available, then the
+ // tab-switching time is the presentation time for the browser-compositor.
+ const bool record_presentation_time = has_saved_frame;
+ delegated_frame_host->WasShown(
+ browser_compositor_->GetRendererLocalSurfaceId(),
+ browser_compositor_->GetRendererSize(), record_presentation_time);
+ }
}
void RenderWidgetHostViewMac::WasOccluded() {
@@ -426,6 +465,10 @@ gfx::Rect RenderWidgetHostViewMac::GetViewBounds() const {
window_frame_in_screen_dip_.OffsetFromOrigin();
}
+bool RenderWidgetHostViewMac::IsMouseLocked() {
+ return mouse_locked_;
+}
+
void RenderWidgetHostViewMac::UpdateCursor(const WebCursor& cursor) {
GetCursorManager()->UpdateCursor(this, cursor);
}
@@ -548,6 +591,17 @@ void RenderWidgetHostViewMac::OnTextSelectionChanged(
return;
ns_view_bridge_->SetTextSelection(selection->text(), selection->offset(),
selection->range());
+ if (host() && host()->delegate())
+ host()->delegate()->DidChangeTextSelection(selection->text(),
+ selection->range());
+}
+
+bool RenderWidgetHostViewMac::ShouldWaitInPreCommit() {
+ return browser_compositor_->ShouldContinueToPauseForFrame();
+}
+
+base::TimeDelta RenderWidgetHostViewMac::PreCommitTimeout() {
+ return kContentPaintTimeout;
}
void RenderWidgetHostViewMac::OnGestureEvent(
@@ -566,12 +620,12 @@ void RenderWidgetHostViewMac::OnGestureEvent(
}
}
-void RenderWidgetHostViewMac::OnRenderFrameMetadataChanged() {
+void RenderWidgetHostViewMac::OnRenderFrameMetadataChangedAfterActivation() {
last_frame_root_background_color_ = host()
->render_frame_metadata_provider()
->LastRenderFrameMetadata()
.root_background_color;
- RenderWidgetHostViewBase::OnRenderFrameMetadataChanged();
+ RenderWidgetHostViewBase::OnRenderFrameMetadataChangedAfterActivation();
}
void RenderWidgetHostViewMac::RenderProcessGone(base::TerminationStatus status,
@@ -589,7 +643,8 @@ void RenderWidgetHostViewMac::Destroy() {
// Destroy the brige to the NSView. Note that the NSView on the other side
// of |ns_view_bridge_| may outlive us due to other retains.
- ns_view_bridge_.reset();
+ ns_view_bridge_ = nullptr;
+ ns_view_bridge_local_.reset();
// Delete the delegated frame state, which will reach back into
// host().
@@ -731,7 +786,7 @@ void RenderWidgetHostViewMac::CopyFromSurface(
void RenderWidgetHostViewMac::EnsureSurfaceSynchronizedForLayoutTest() {
++latest_capture_sequence_number_;
- SynchronizeVisualProperties();
+ SynchronizeVisualProperties(base::nullopt);
}
void RenderWidgetHostViewMac::SetNeedsBeginFrames(bool needs_begin_frames) {
@@ -746,7 +801,7 @@ void RenderWidgetHostViewMac::UpdateNeedsBeginFramesInternal() {
void RenderWidgetHostViewMac::OnDidUpdateVisualPropertiesComplete(
const cc::RenderFrameMetadata& metadata) {
browser_compositor_->SynchronizeVisualProperties(
- metadata.viewport_size_in_pixels,
+ metadata.device_scale_factor, metadata.viewport_size_in_pixels,
metadata.local_surface_id.value_or(viz::LocalSurfaceId()));
}
@@ -940,14 +995,6 @@ bool RenderWidgetHostViewMac::GetCachedFirstRectForCharacterRange(
return true;
}
-bool RenderWidgetHostViewMac::ShouldContinueToPauseForFrame() {
- // Only pause for frames when drawing through a separate ui::Compositor.
- if (display_only_using_parent_ui_layer_)
- return false;
-
- return browser_compositor_->ShouldContinueToPauseForFrame();
-}
-
void RenderWidgetHostViewMac::FocusedNodeChanged(
bool is_editable_node,
const gfx::Rect& node_bounds_in_screen) {
@@ -998,8 +1045,7 @@ bool RenderWidgetHostViewMac::RequestRepaintForTesting() {
}
void RenderWidgetHostViewMac::TransformPointToRootSurface(gfx::PointF* point) {
- if (display_only_using_parent_ui_layer_)
- *point += view_bounds_in_window_dip_.OffsetFromOrigin();
+ browser_compositor_->TransformPointToRootSurface(point);
}
gfx::Rect RenderWidgetHostViewMac::GetBoundsInRootWindow() {
@@ -1033,8 +1079,14 @@ void RenderWidgetHostViewMac::UnlockMouse() {
bool RenderWidgetHostViewMac::LockKeyboard(
base::Optional<base::flat_set<ui::DomCode>> dom_codes) {
+ base::Optional<std::vector<uint32_t>> uint_dom_codes;
+ if (dom_codes) {
+ uint_dom_codes.emplace();
+ for (const auto& dom_code : *dom_codes)
+ uint_dom_codes->push_back(static_cast<uint32_t>(dom_code));
+ }
is_keyboard_locked_ = true;
- ns_view_bridge_->LockKeyboard(std::move(dom_codes));
+ ns_view_bridge_->LockKeyboard(uint_dom_codes);
return true;
}
@@ -1050,8 +1102,15 @@ bool RenderWidgetHostViewMac::IsKeyboardLocked() {
return is_keyboard_locked_;
}
+base::flat_map<std::string, std::string>
+RenderWidgetHostViewMac::GetKeyboardLayoutMap() {
+ return ui::GenerateDomKeyboardLayoutMap();
+}
+
void RenderWidgetHostViewMac::GestureEventAck(const WebGestureEvent& event,
InputEventAckState ack_result) {
+ ForwardTouchpadPinchIfNecessary(event, ack_result);
+
bool consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED;
switch (event.GetType()) {
case WebInputEvent::kGestureScrollBegin:
@@ -1095,11 +1154,11 @@ RenderWidgetHostViewMac::CreateSyntheticGestureTarget() {
new SyntheticGestureTargetMac(host, cocoa_view()));
}
-viz::LocalSurfaceId RenderWidgetHostViewMac::GetLocalSurfaceId() const {
+const viz::LocalSurfaceId& RenderWidgetHostViewMac::GetLocalSurfaceId() const {
return browser_compositor_->GetRendererLocalSurfaceId();
}
-viz::FrameSinkId RenderWidgetHostViewMac::GetFrameSinkId() {
+const viz::FrameSinkId& RenderWidgetHostViewMac::GetFrameSinkId() const {
return browser_compositor_->GetDelegatedFrameHost()->frame_sink_id();
}
@@ -1267,9 +1326,9 @@ gfx::Point RenderWidgetHostViewMac::AccessibilityOriginInScreen(
return gfx::Point(originInScreen.x, originInScreen.y);
}
-gfx::AcceleratedWidget
-RenderWidgetHostViewMac::AccessibilityGetAcceleratedWidget() {
- return browser_compositor_->GetAcceleratedWidget();
+gfx::NativeViewAccessible
+RenderWidgetHostViewMac::AccessibilityGetNativeViewAccessible() {
+ return cocoa_view();
}
void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
@@ -1281,22 +1340,6 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
password_input_enabler_.reset();
}
-void RenderWidgetHostViewMac::PauseForPendingResizeOrRepaintsAndDraw() {
- if (!host() || !browser_compositor_ || host()->is_hidden()) {
- return;
- }
-
- // Pausing for one view prevents others from receiving frames.
- // This may lead to large delays, causing overlaps. See crbug.com/352020.
- if (!allow_pause_for_resize_or_repaint_)
- return;
-
- // Wait for a frame of the right size to come in.
- browser_compositor_->BeginPauseForFrame(host()->auto_resize_enabled());
- host()->PauseForPendingResizeOrRepaints();
- browser_compositor_->EndPauseForFrame();
-}
-
// static
viz::FrameSinkId
RenderWidgetHostViewMac::AllocateFrameSinkIdForGuestViewHack() {
@@ -1310,19 +1353,27 @@ MouseWheelPhaseHandler* RenderWidgetHostViewMac::GetMouseWheelPhaseHandler() {
}
///////////////////////////////////////////////////////////////////////////////
-// RenderWidgetHostNSViewClient implementation:
+// RenderWidgetHostNSViewLocalClient and mojom::RenderWidgetHostNSViewClient
+// implementation:
BrowserAccessibilityManager*
RenderWidgetHostViewMac::GetRootBrowserAccessibilityManager() {
return host()->GetRootBrowserAccessibilityManager();
}
-void RenderWidgetHostViewMac::OnNSViewSyncIsRenderViewHost(
- bool* is_render_view) {
+bool RenderWidgetHostViewMac::SyncIsRenderViewHost(bool* is_render_view) {
*is_render_view = RenderViewHost::From(host()) != nullptr;
+ return true;
}
-void RenderWidgetHostViewMac::OnNSViewRequestShutdown() {
+void RenderWidgetHostViewMac::SyncIsRenderViewHost(
+ SyncIsRenderViewHostCallback callback) {
+ bool is_render_view;
+ SyncIsRenderViewHost(&is_render_view);
+ std::move(callback).Run(is_render_view);
+}
+
+void RenderWidgetHostViewMac::RequestShutdown() {
if (!weak_factory_.HasWeakPtrs()) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&RenderWidgetHostViewMac::ShutdownHost,
@@ -1330,8 +1381,7 @@ void RenderWidgetHostViewMac::OnNSViewRequestShutdown() {
}
}
-void RenderWidgetHostViewMac::OnNSViewIsFirstResponderChanged(
- bool is_first_responder) {
+void RenderWidgetHostViewMac::OnFirstResponderChanged(bool is_first_responder) {
if (is_first_responder_ == is_first_responder)
return;
is_first_responder_ = is_first_responder;
@@ -1344,11 +1394,11 @@ void RenderWidgetHostViewMac::OnNSViewIsFirstResponderChanged(
}
}
-void RenderWidgetHostViewMac::OnNSViewWindowIsKeyChanged(bool is_key) {
+void RenderWidgetHostViewMac::OnWindowIsKeyChanged(bool is_key) {
SetActive(is_key);
}
-void RenderWidgetHostViewMac::OnNSViewBoundsInWindowChanged(
+void RenderWidgetHostViewMac::OnBoundsInWindowChanged(
const gfx::Rect& view_bounds_in_window_dip,
bool attached_to_window) {
bool view_size_changed =
@@ -1365,17 +1415,11 @@ void RenderWidgetHostViewMac::OnNSViewBoundsInWindowChanged(
view_bounds_in_window_dip_.set_size(view_bounds_in_window_dip.size());
}
- if (view_size_changed) {
+ if (view_size_changed)
UpdateNSViewAndDisplayProperties();
- // Wait for the frame that WasResize might have requested. If the view is
- // being made visible at a new size, then this call will have no effect
- // because the view widget is still hidden, and the pause call in WasShown
- // will have this effect for us.
- PauseForPendingResizeOrRepaintsAndDraw();
- }
}
-void RenderWidgetHostViewMac::OnNSViewWindowFrameInScreenChanged(
+void RenderWidgetHostViewMac::OnWindowFrameInScreenChanged(
const gfx::Rect& window_frame_in_screen_dip) {
if (window_frame_in_screen_dip_ == window_frame_in_screen_dip)
return;
@@ -1387,13 +1431,13 @@ void RenderWidgetHostViewMac::OnNSViewWindowFrameInScreenChanged(
host()->SendScreenRects();
}
-void RenderWidgetHostViewMac::OnNSViewDisplayChanged(
+void RenderWidgetHostViewMac::OnDisplayChanged(
const display::Display& display) {
display_ = display;
UpdateNSViewAndDisplayProperties();
}
-void RenderWidgetHostViewMac::OnNSViewBeginKeyboardEvent() {
+void RenderWidgetHostViewMac::BeginKeyboardEvent() {
DCHECK(!in_keyboard_event_);
in_keyboard_event_ = true;
RenderWidgetHostImpl* widget_host = host();
@@ -1407,13 +1451,13 @@ void RenderWidgetHostViewMac::OnNSViewBeginKeyboardEvent() {
}
}
-void RenderWidgetHostViewMac::OnNSViewEndKeyboardEvent() {
+void RenderWidgetHostViewMac::EndKeyboardEvent() {
in_keyboard_event_ = false;
keyboard_event_widget_process_id_ = 0;
keyboard_event_widget_routing_id_ = 0;
}
-void RenderWidgetHostViewMac::OnNSViewForwardKeyboardEvent(
+void RenderWidgetHostViewMac::ForwardKeyboardEvent(
const NativeWebKeyboardEvent& key_event,
const ui::LatencyInfo& latency_info) {
if (auto* widget_host = GetWidgetForKeyboardEvent()) {
@@ -1421,7 +1465,7 @@ void RenderWidgetHostViewMac::OnNSViewForwardKeyboardEvent(
}
}
-void RenderWidgetHostViewMac::OnNSViewForwardKeyboardEventWithCommands(
+void RenderWidgetHostViewMac::ForwardKeyboardEventWithCommands(
const NativeWebKeyboardEvent& key_event,
const ui::LatencyInfo& latency_info,
const std::vector<EditCommand>& commands) {
@@ -1431,11 +1475,11 @@ void RenderWidgetHostViewMac::OnNSViewForwardKeyboardEventWithCommands(
}
}
-void RenderWidgetHostViewMac::OnNSViewRouteOrProcessMouseEvent(
+void RenderWidgetHostViewMac::RouteOrProcessMouseEvent(
const blink::WebMouseEvent& const_web_event) {
blink::WebMouseEvent web_event = const_web_event;
ui::LatencyInfo latency_info(ui::SourceEventType::OTHER);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0);
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT);
if (ShouldRouteEvent(web_event)) {
host()->delegate()->GetInputEventRouter()->RouteMouseEvent(this, &web_event,
latency_info);
@@ -1444,20 +1488,18 @@ void RenderWidgetHostViewMac::OnNSViewRouteOrProcessMouseEvent(
}
}
-void RenderWidgetHostViewMac::OnNSViewRouteOrProcessWheelEvent(
+void RenderWidgetHostViewMac::RouteOrProcessWheelEvent(
const blink::WebMouseWheelEvent& const_web_event) {
blink::WebMouseWheelEvent web_event = const_web_event;
ui::LatencyInfo latency_info(ui::SourceEventType::WHEEL);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0);
- if (wheel_scroll_latching_enabled()) {
- mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
- web_event, ShouldRouteEvent(web_event));
- if (web_event.phase == blink::WebMouseWheelEvent::kPhaseEnded) {
- // A wheel end event is scheduled and will get dispatched if momentum
- // phase doesn't start in 100ms. Don't sent the wheel end event
- // immediately.
- return;
- }
+ latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT);
+ mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
+ web_event, ShouldRouteEvent(web_event));
+ if (web_event.phase == blink::WebMouseWheelEvent::kPhaseEnded) {
+ // A wheel end event is scheduled and will get dispatched if momentum
+ // phase doesn't start in 100ms. Don't sent the wheel end event
+ // immediately.
+ return;
}
if (ShouldRouteEvent(web_event)) {
host()->delegate()->GetInputEventRouter()->RouteMouseWheelEvent(
@@ -1467,7 +1509,7 @@ void RenderWidgetHostViewMac::OnNSViewRouteOrProcessWheelEvent(
}
}
-void RenderWidgetHostViewMac::OnNSViewForwardMouseEvent(
+void RenderWidgetHostViewMac::ForwardMouseEvent(
const blink::WebMouseEvent& web_event) {
if (host())
host()->ForwardMouseEvent(web_event);
@@ -1476,23 +1518,16 @@ void RenderWidgetHostViewMac::OnNSViewForwardMouseEvent(
ns_view_bridge_->SetTooltipText(base::string16());
}
-void RenderWidgetHostViewMac::OnNSViewForwardWheelEvent(
+void RenderWidgetHostViewMac::ForwardWheelEvent(
const blink::WebMouseWheelEvent& const_web_event) {
blink::WebMouseWheelEvent web_event = const_web_event;
- if (wheel_scroll_latching_enabled()) {
- mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(web_event,
- false);
- } else {
- ui::LatencyInfo latency_info(ui::SourceEventType::WHEEL);
- latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0);
- host()->ForwardWheelEventWithLatencyInfo(web_event, latency_info);
- }
+ mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(web_event,
+ false);
}
-void RenderWidgetHostViewMac::OnNSViewGestureBegin(
- blink::WebGestureEvent begin_event,
- bool is_synthetically_injected) {
- gesture_begin_event_.reset(new WebGestureEvent(begin_event));
+void RenderWidgetHostViewMac::GestureBegin(blink::WebGestureEvent begin_event,
+ bool is_synthetically_injected) {
+ gesture_begin_event_ = std::make_unique<WebGestureEvent>(begin_event);
// If the page is at the minimum zoom level, require a threshold be reached
// before the pinch has an effect. Synthetic pinches are not subject to this
@@ -1503,7 +1538,7 @@ void RenderWidgetHostViewMac::OnNSViewGestureBegin(
}
}
-void RenderWidgetHostViewMac::OnNSViewGestureUpdate(
+void RenderWidgetHostViewMac::GestureUpdate(
blink::WebGestureEvent update_event) {
// If, due to nesting of multiple gestures (e.g, from multiple touch
// devices), the beginning of the gesture has been lost, skip the remainder
@@ -1519,15 +1554,14 @@ void RenderWidgetHostViewMac::OnNSViewGestureUpdate(
// Send a GesturePinchBegin event if none has been sent yet.
if (!gesture_begin_pinch_sent_) {
- if (wheel_scroll_latching_enabled()) {
- // Before starting a pinch sequence, send the pending wheel end event to
- // finish scrolling.
- mouse_wheel_phase_handler_.DispatchPendingWheelEndEvent();
- }
+ // Before starting a pinch sequence, send the pending wheel end event to
+ // finish scrolling.
+ mouse_wheel_phase_handler_.DispatchPendingWheelEndEvent();
WebGestureEvent begin_event(*gesture_begin_event_);
begin_event.SetType(WebInputEvent::kGesturePinchBegin);
begin_event.SetSourceDevice(
blink::WebGestureDevice::kWebGestureDeviceTouchpad);
+ begin_event.SetNeedsWheelEvent(true);
SendGesturePinchEvent(&begin_event);
gesture_begin_pinch_sent_ = YES;
}
@@ -1538,8 +1572,7 @@ void RenderWidgetHostViewMac::OnNSViewGestureUpdate(
SendGesturePinchEvent(&update_event);
}
-void RenderWidgetHostViewMac::OnNSViewGestureEnd(
- blink::WebGestureEvent end_event) {
+void RenderWidgetHostViewMac::GestureEnd(blink::WebGestureEvent end_event) {
gesture_begin_event_.reset();
if (gesture_begin_pinch_sent_) {
SendGesturePinchEvent(&end_event);
@@ -1547,12 +1580,12 @@ void RenderWidgetHostViewMac::OnNSViewGestureEnd(
}
}
-void RenderWidgetHostViewMac::OnNSViewSmartMagnify(
+void RenderWidgetHostViewMac::SmartMagnify(
const blink::WebGestureEvent& smart_magnify_event) {
host()->ForwardGestureEvent(smart_magnify_event);
}
-void RenderWidgetHostViewMac::OnNSViewImeSetComposition(
+void RenderWidgetHostViewMac::ImeSetComposition(
const base::string16& text,
const std::vector<ui::ImeTextSpan>& ime_text_spans,
const gfx::Range& replacement_range,
@@ -1564,7 +1597,7 @@ void RenderWidgetHostViewMac::OnNSViewImeSetComposition(
}
}
-void RenderWidgetHostViewMac::OnNSViewImeCommitText(
+void RenderWidgetHostViewMac::ImeCommitText(
const base::string16& text,
const gfx::Range& replacement_range) {
if (auto* widget_host = GetWidgetForIme()) {
@@ -1573,19 +1606,19 @@ void RenderWidgetHostViewMac::OnNSViewImeCommitText(
}
}
-void RenderWidgetHostViewMac::OnNSViewImeFinishComposingText() {
+void RenderWidgetHostViewMac::ImeFinishComposingText() {
if (auto* widget_host = GetWidgetForIme()) {
widget_host->ImeFinishComposingText(false);
}
}
-void RenderWidgetHostViewMac::OnNSViewImeCancelComposition() {
+void RenderWidgetHostViewMac::ImeCancelCompositionFromCocoa() {
if (auto* widget_host = GetWidgetForIme()) {
widget_host->ImeCancelComposition();
}
}
-void RenderWidgetHostViewMac::OnNSViewLookUpDictionaryOverlayFromRange(
+void RenderWidgetHostViewMac::LookUpDictionaryOverlayFromRange(
const gfx::Range& range) {
content::RenderWidgetHostViewBase* focused_view =
GetFocusedViewForTextSelection();
@@ -1606,7 +1639,7 @@ void RenderWidgetHostViewMac::OnNSViewLookUpDictionaryOverlayFromRange(
target_widget_routing_id));
}
-void RenderWidgetHostViewMac::OnNSViewLookUpDictionaryOverlayAtPoint(
+void RenderWidgetHostViewMac::LookUpDictionaryOverlayAtPoint(
const gfx::PointF& root_point) {
if (!host() || !host()->delegate() ||
!host()->delegate()->GetInputEventRouter())
@@ -1628,34 +1661,47 @@ void RenderWidgetHostViewMac::OnNSViewLookUpDictionaryOverlayAtPoint(
target_widget_routing_id));
}
-void RenderWidgetHostViewMac::OnNSViewSyncGetCharacterIndexAtPoint(
+bool RenderWidgetHostViewMac::SyncGetCharacterIndexAtPoint(
const gfx::PointF& root_point,
uint32_t* index) {
*index = UINT32_MAX;
if (!host() || !host()->delegate() ||
!host()->delegate()->GetInputEventRouter())
- return;
+ return true;
gfx::PointF transformed_point;
RenderWidgetHostImpl* widget_host =
host()->delegate()->GetInputEventRouter()->GetRenderWidgetHostAtPoint(
this, root_point, &transformed_point);
if (!widget_host)
- return;
+ return true;
*index = TextInputClientMac::GetInstance()->GetCharacterIndexAtPoint(
widget_host, gfx::ToFlooredPoint(transformed_point));
+ return true;
+}
+
+void RenderWidgetHostViewMac::SyncGetCharacterIndexAtPoint(
+ const gfx::PointF& root_point,
+ SyncGetCharacterIndexAtPointCallback callback) {
+ uint32_t index;
+ SyncGetCharacterIndexAtPoint(root_point, &index);
+ std::move(callback).Run(index);
}
-void RenderWidgetHostViewMac::OnNSViewSyncGetFirstRectForRange(
+bool RenderWidgetHostViewMac::SyncGetFirstRectForRange(
const gfx::Range& requested_range,
+ const gfx::Rect& in_rect,
+ const gfx::Range& in_actual_range,
gfx::Rect* rect,
gfx::Range* actual_range,
bool* success) {
+ *rect = in_rect;
+ *actual_range = in_actual_range;
if (!GetFocusedWidget()) {
*success = false;
- return;
+ return true;
}
*success = true;
if (!GetCachedFirstRectForCharacterRange(requested_range, rect,
@@ -1665,68 +1711,88 @@ void RenderWidgetHostViewMac::OnNSViewSyncGetFirstRectForRange(
// TODO(thakis): Pipe |actualRange| through TextInputClientMac machinery.
*actual_range = requested_range;
}
+ return true;
}
-void RenderWidgetHostViewMac::OnNSViewExecuteEditCommand(
- const std::string& command) {
+void RenderWidgetHostViewMac::SyncGetFirstRectForRange(
+ const gfx::Range& requested_range,
+ const gfx::Rect& rect,
+ const gfx::Range& actual_range,
+ SyncGetFirstRectForRangeCallback callback) {
+ gfx::Rect out_rect;
+ gfx::Range out_actual_range;
+ bool success;
+ SyncGetFirstRectForRange(requested_range, rect, actual_range, &out_rect,
+ &out_actual_range, &success);
+ std::move(callback).Run(out_rect, out_actual_range, success);
+}
+
+void RenderWidgetHostViewMac::ExecuteEditCommand(const std::string& command) {
if (host()->delegate()) {
host()->delegate()->ExecuteEditCommand(command, base::nullopt);
}
}
-void RenderWidgetHostViewMac::OnNSViewUndo() {
+void RenderWidgetHostViewMac::Undo() {
WebContents* web_contents = GetWebContents();
if (web_contents)
web_contents->Undo();
}
-void RenderWidgetHostViewMac::OnNSViewRedo() {
+void RenderWidgetHostViewMac::Redo() {
WebContents* web_contents = GetWebContents();
if (web_contents)
web_contents->Redo();
}
-void RenderWidgetHostViewMac::OnNSViewCut() {
+void RenderWidgetHostViewMac::Cut() {
if (auto* delegate = GetFocusedRenderWidgetHostDelegate()) {
delegate->Cut();
}
}
-void RenderWidgetHostViewMac::OnNSViewCopy() {
+void RenderWidgetHostViewMac::Copy() {
if (auto* delegate = GetFocusedRenderWidgetHostDelegate()) {
delegate->Copy();
}
}
-void RenderWidgetHostViewMac::OnNSViewCopyToFindPboard() {
+void RenderWidgetHostViewMac::CopyToFindPboard() {
WebContents* web_contents = GetWebContents();
if (web_contents)
web_contents->CopyToFindPboard();
}
-void RenderWidgetHostViewMac::OnNSViewPaste() {
+void RenderWidgetHostViewMac::Paste() {
if (auto* delegate = GetFocusedRenderWidgetHostDelegate()) {
delegate->Paste();
}
}
-void RenderWidgetHostViewMac::OnNSViewPasteAndMatchStyle() {
+void RenderWidgetHostViewMac::PasteAndMatchStyle() {
WebContents* web_contents = GetWebContents();
if (web_contents)
web_contents->PasteAndMatchStyle();
}
-void RenderWidgetHostViewMac::OnNSViewSelectAll() {
+void RenderWidgetHostViewMac::SelectAll() {
if (auto* delegate = GetFocusedRenderWidgetHostDelegate()) {
delegate->SelectAll();
}
}
-void RenderWidgetHostViewMac::OnNSViewSyncIsSpeaking(bool* is_speaking) {
+bool RenderWidgetHostViewMac::SyncIsSpeaking(bool* is_speaking) {
*is_speaking = ui::TextServicesContextMenu::IsSpeaking();
+ return true;
}
-void RenderWidgetHostViewMac::OnNSViewSpeakSelection() {
+void RenderWidgetHostViewMac::SyncIsSpeaking(SyncIsSpeakingCallback callback) {
+ bool is_speaking;
+ SyncIsSpeaking(&is_speaking);
+ std::move(callback).Run(is_speaking);
+}
+
+void RenderWidgetHostViewMac::StartSpeaking() {
RenderWidgetHostView* target = this;
WebContents* web_contents = GetWebContents();
if (web_contents) {
@@ -1743,10 +1809,152 @@ void RenderWidgetHostViewMac::OnNSViewSpeakSelection() {
target->SpeakSelection();
}
-void RenderWidgetHostViewMac::OnNSViewStopSpeaking() {
+void RenderWidgetHostViewMac::StopSpeaking() {
ui::TextServicesContextMenu::StopSpeaking();
}
+///////////////////////////////////////////////////////////////////////////////
+// mojom::RenderWidgetHostNSViewClient functions that translate events and
+// forward them to the RenderWidgetHostNSViewLocalClient implementation:
+
+void RenderWidgetHostViewMac::ForwardKeyboardEvent(
+ std::unique_ptr<InputEvent> input_event,
+ bool skip_in_browser) {
+ if (!input_event || !input_event->web_event ||
+ !blink::WebInputEvent::IsKeyboardEventType(
+ input_event->web_event->GetType())) {
+ DLOG(ERROR) << "Absent or non-KeyboardEventType event.";
+ return;
+ }
+ const blink::WebKeyboardEvent& keyboard_event =
+ static_cast<const blink::WebKeyboardEvent&>(*input_event->web_event);
+ NativeWebKeyboardEvent native_event(keyboard_event, nil);
+ native_event.skip_in_browser = skip_in_browser;
+ ForwardKeyboardEvent(native_event, input_event->latency_info);
+}
+
+void RenderWidgetHostViewMac::ForwardKeyboardEventWithCommands(
+ std::unique_ptr<InputEvent> input_event,
+ bool skip_in_browser,
+ const std::vector<EditCommand>& commands) {
+ if (!input_event || !input_event->web_event ||
+ !blink::WebInputEvent::IsKeyboardEventType(
+ input_event->web_event->GetType())) {
+ DLOG(ERROR) << "Absent or non-KeyboardEventType event.";
+ return;
+ }
+ const blink::WebKeyboardEvent& keyboard_event =
+ static_cast<const blink::WebKeyboardEvent&>(*input_event->web_event);
+ NativeWebKeyboardEvent native_event(keyboard_event, nil);
+ native_event.skip_in_browser = skip_in_browser;
+ ForwardKeyboardEventWithCommands(native_event, input_event->latency_info,
+ commands);
+}
+void RenderWidgetHostViewMac::RouteOrProcessMouseEvent(
+ std::unique_ptr<InputEvent> input_event) {
+ if (!input_event || !input_event->web_event ||
+ !blink::WebInputEvent::IsMouseEventType(
+ input_event->web_event->GetType())) {
+ DLOG(ERROR) << "Absent or non-MouseEventType event.";
+ return;
+ }
+ const blink::WebMouseEvent& mouse_event =
+ static_cast<const blink::WebMouseEvent&>(*input_event->web_event);
+ RouteOrProcessMouseEvent(mouse_event);
+}
+
+void RenderWidgetHostViewMac::RouteOrProcessWheelEvent(
+ std::unique_ptr<InputEvent> input_event) {
+ if (!input_event || !input_event->web_event ||
+ input_event->web_event->GetType() != blink::WebInputEvent::kMouseWheel) {
+ DLOG(ERROR) << "Absent or non-MouseWheel event.";
+ return;
+ }
+ const blink::WebMouseWheelEvent& wheel_event =
+ static_cast<const blink::WebMouseWheelEvent&>(*input_event->web_event);
+ RouteOrProcessWheelEvent(wheel_event);
+}
+
+void RenderWidgetHostViewMac::ForwardMouseEvent(
+ std::unique_ptr<InputEvent> input_event) {
+ if (!input_event || !input_event->web_event ||
+ !blink::WebInputEvent::IsMouseEventType(
+ input_event->web_event->GetType())) {
+ DLOG(ERROR) << "Absent or non-MouseEventType event.";
+ return;
+ }
+ const blink::WebMouseEvent& mouse_event =
+ static_cast<const blink::WebMouseEvent&>(*input_event->web_event);
+ ForwardMouseEvent(mouse_event);
+}
+
+void RenderWidgetHostViewMac::ForwardWheelEvent(
+ std::unique_ptr<InputEvent> input_event) {
+ if (!input_event || !input_event->web_event ||
+ input_event->web_event->GetType() != blink::WebInputEvent::kMouseWheel) {
+ DLOG(ERROR) << "Absent or non-MouseWheel event.";
+ return;
+ }
+ const blink::WebMouseWheelEvent& wheel_event =
+ static_cast<const blink::WebMouseWheelEvent&>(*input_event->web_event);
+ ForwardWheelEvent(wheel_event);
+}
+
+void RenderWidgetHostViewMac::GestureBegin(
+ std::unique_ptr<InputEvent> input_event,
+ bool is_synthetically_injected) {
+ if (!input_event || !input_event->web_event ||
+ !blink::WebInputEvent::IsGestureEventType(
+ input_event->web_event->GetType())) {
+ DLOG(ERROR) << "Absent or non-GestureEventType event.";
+ return;
+ }
+ blink::WebGestureEvent gesture_event =
+ *static_cast<const blink::WebGestureEvent*>(input_event->web_event.get());
+ // Strip the gesture type, because it is not known.
+ gesture_event.SetType(blink::WebInputEvent::kUndefined);
+ GestureBegin(gesture_event, is_synthetically_injected);
+}
+
+void RenderWidgetHostViewMac::GestureUpdate(
+ std::unique_ptr<InputEvent> input_event) {
+ if (!input_event || !input_event->web_event ||
+ !blink::WebInputEvent::IsGestureEventType(
+ input_event->web_event->GetType())) {
+ DLOG(ERROR) << "Absent or non-GestureEventType event.";
+ return;
+ }
+ const blink::WebGestureEvent& gesture_event =
+ static_cast<const blink::WebGestureEvent&>(*input_event->web_event);
+ GestureUpdate(gesture_event);
+}
+
+void RenderWidgetHostViewMac::GestureEnd(
+ std::unique_ptr<InputEvent> input_event) {
+ if (!input_event || !input_event->web_event ||
+ !blink::WebInputEvent::IsGestureEventType(
+ input_event->web_event->GetType())) {
+ DLOG(ERROR) << "Absent or non-GestureEventType event.";
+ return;
+ }
+ blink::WebGestureEvent gesture_event =
+ *static_cast<const blink::WebGestureEvent*>(input_event->web_event.get());
+ GestureEnd(gesture_event);
+}
+
+void RenderWidgetHostViewMac::SmartMagnify(
+ std::unique_ptr<InputEvent> input_event) {
+ if (!input_event || !input_event->web_event ||
+ !blink::WebInputEvent::IsGestureEventType(
+ input_event->web_event->GetType())) {
+ DLOG(ERROR) << "Absent or non-GestureEventType event.";
+ return;
+ }
+ const blink::WebGestureEvent& gesture_event =
+ static_cast<const blink::WebGestureEvent&>(*input_event->web_event);
+ SmartMagnify(gesture_event);
+}
+
void RenderWidgetHostViewMac::OnGotStringForDictionaryOverlay(
int32_t target_widget_process_id,
int32_t target_widget_routing_id,
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 f4e2439c495..3f089d75a05 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
@@ -138,10 +138,10 @@ void EditCommandImp(id self, SEL _cmd, id sender) {
std::string command([command_name_ns UTF8String]);
// Forward the edit command string down the pipeline.
- RenderWidgetHostNSViewClient* client = [(
+ mojom::RenderWidgetHostNSViewClient* client = [(
id<RenderWidgetHostNSViewClientOwner>)self renderWidgetHostNSViewClient];
DCHECK(client);
- client->OnNSViewExecuteEditCommand(command);
+ client->ExecuteEditCommand(command);
}
} // namespace
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 701da35330e..26c6b9e09d3 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
@@ -53,7 +53,7 @@ using content::RenderWidgetHostViewMac;
return self;
}
-- (content::RenderWidgetHostNSViewClient*)renderWidgetHostNSViewClient {
+- (content::mojom::RenderWidgetHostNSViewClient*)renderWidgetHostNSViewClient {
return rwhvm_;
}
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 fbca43e1919..4fceb1ab71c 100644
--- a/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/chromium/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -17,7 +17,7 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -165,10 +165,13 @@ NSEvent* MockTabletEventWithParams(CGEventType type,
NSEvent* MockMouseEventWithParams(CGEventType mouse_type,
CGPoint location,
CGMouseButton button,
- CGEventMouseSubtype subtype) {
+ CGEventMouseSubtype subtype,
+ bool is_entering_proximity = false) {
CGEventRef cg_event =
CGEventCreateMouseEvent(NULL, mouse_type, location, button);
CGEventSetIntegerValueField(cg_event, kCGMouseEventSubtype, subtype);
+ CGEventSetIntegerValueField(cg_event, kCGTabletProximityEventEnterProximity,
+ is_entering_proximity);
NSEvent* event = [NSEvent eventWithCGEvent:cg_event];
CFRelease(cg_event);
return event;
@@ -341,24 +344,13 @@ NSEvent* MockScrollWheelEventWithoutPhase(int32_t delta) {
return MockScrollWheelEventWithMomentumPhase(@selector(phaseNone), delta);
}
-enum WheelScrollingMode {
- kWheelScrollingModeNone,
- kWheelScrollLatching,
- kAsyncWheelEvents,
-};
-
} // namespace
class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness {
public:
- RenderWidgetHostViewMacTest(
- WheelScrollingMode wheel_scrolling_mode = kWheelScrollingModeNone)
- : rwhv_mac_(nullptr),
- wheel_scrolling_mode_(wheel_scrolling_mode),
- scroll_latching_(wheel_scrolling_mode_ != kWheelScrollingModeNone) {
+ RenderWidgetHostViewMacTest() : rwhv_mac_(nullptr) {
mock_clock_.Advance(base::TimeDelta::FromMilliseconds(100));
ui::SetEventTickClockForTesting(&mock_clock_);
- SetFeatureList();
vsync_feature_list_.InitAndEnableFeature(
features::kVsyncAlignedInputEvents);
@@ -413,29 +405,6 @@ class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness {
return base::UTF16ToUTF8(rwhv_mac_->GetTextSelection()->selected_text());
}
- void SetFeatureList() {
- if (wheel_scrolling_mode_ == kAsyncWheelEvents) {
- feature_list_.InitWithFeatures({features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents},
- {});
- } else if (wheel_scrolling_mode_ == kWheelScrollLatching) {
- feature_list_.InitWithFeatures(
- {features::kTouchpadAndWheelScrollLatching},
- {features::kAsyncWheelEvents});
- } else if (wheel_scrolling_mode_ == kWheelScrollingModeNone) {
- feature_list_.InitWithFeatures({},
- {features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents});
- }
- }
-
- void IgnoreEmptyUnhandledWheelEventWithWheelGestures();
- void ScrollWheelEndEventDelivery();
- void TimerBasedPhaseInfo();
- void WheelWithPhaseEndedIsNotForwardedImmediately();
- void WheelWithMomentumPhaseBeganStopsTheWheelEndDispatchTimer();
- void WheelWithPhaseBeganDispatchesThePendingWheelEnd();
-
MockRenderWidgetHostDelegate delegate_;
std::unique_ptr<TestBrowserContext> browser_context_;
@@ -444,15 +413,11 @@ class RenderWidgetHostViewMacTest : public RenderViewHostImplTestHarness {
RenderWidgetHostViewMac* rwhv_mac_ = nullptr;
base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa_;
- WheelScrollingMode wheel_scrolling_mode_;
- bool scroll_latching_;
-
private:
// This class isn't derived from PlatformTest.
base::mac::ScopedNSAutoreleasePool pool_;
base::test::ScopedFeatureList vsync_feature_list_;
- base::test::ScopedFeatureList feature_list_;
base::SimpleTestTickClock mock_clock_;
@@ -845,9 +810,8 @@ TEST_F(RenderWidgetHostViewMacTest, LastWheelEventLatencyInfoExists) {
// properly in scrollWheel function.
NSEvent* wheelEvent1 = MockScrollWheelEventWithPhase(@selector(phaseBegan),3);
[rwhv_mac_->cocoa_view() scrollWheel:wheelEvent1];
- ui::LatencyInfo::LatencyComponent ui_component1;
ASSERT_TRUE(host_->lastWheelEventLatencyInfo.FindLatency(
- ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, &ui_component1));
+ ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr));
// Send a wheel event with phaseEnded.
// Verifies that ui::INPUT_EVENT_LATENCY_UI_COMPONENT is added
@@ -855,9 +819,8 @@ TEST_F(RenderWidgetHostViewMacTest, LastWheelEventLatencyInfoExists) {
// in scrollWheel.
NSEvent* wheelEvent2 = MockScrollWheelEventWithPhase(@selector(phaseEnded),0);
[rwhv_mac_->cocoa_view() scrollWheel:wheelEvent2];
- ui::LatencyInfo::LatencyComponent ui_component2;
ASSERT_TRUE(host_->lastWheelEventLatencyInfo.FindLatency(
- ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, &ui_component2));
+ ui::INPUT_EVENT_LATENCY_UI_COMPONENT, nullptr));
}
TEST_F(RenderWidgetHostViewMacTest, SourceEventTypeExistsInLatencyInfo) {
@@ -871,7 +834,7 @@ TEST_F(RenderWidgetHostViewMacTest, SourceEventTypeExistsInLatencyInfo) {
ui::SourceEventType::WHEEL);
}
-void RenderWidgetHostViewMacTest::ScrollWheelEndEventDelivery() {
+TEST_F(RenderWidgetHostViewMacTest, ScrollWheelEndEventDelivery) {
// Send an initial wheel event with NSEventPhaseBegan to the view.
NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 0);
[rwhv_mac_->cocoa_view() scrollWheel:event1];
@@ -891,17 +854,10 @@ void RenderWidgetHostViewMacTest::ScrollWheelEndEventDelivery() {
[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, events.size());
- } else {
- ASSERT_EQ(1U, events.size());
- }
-}
-TEST_F(RenderWidgetHostViewMacTest, ScrollWheelEndEventDelivery) {
- ScrollWheelEndEventDelivery();
+ // 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, events.size());
}
TEST_F(RenderWidgetHostViewMacTest, PointerEventWithEraserType) {
@@ -944,6 +900,36 @@ TEST_F(RenderWidgetHostViewMacTest, PointerEventWithPenType) {
GetPointerType(events));
}
+TEST_F(RenderWidgetHostViewMacTest, PointerEventWithPenTypeNoTabletEvent) {
+ // Send a NSEvent of a mouse type with a subtype of
+ // NSTabletProximityEventSubtype, which indicates the input device is a pen.
+ NSEvent* event =
+ MockMouseEventWithParams(kCGEventMouseMoved, {6, 9}, kCGMouseButtonLeft,
+ kCGEventMouseSubtypeTabletProximity, true);
+ [rwhv_mac_->cocoa_view() mouseEvent:event];
+ base::RunLoop().RunUntilIdle();
+ MockWidgetInputHandler::MessageVector events =
+ host_->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseLeave", GetMessageNames(events));
+ EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
+ GetPointerType(events));
+ events.clear();
+
+ event = cocoa_test_event_utils::EnterEvent();
+ [rwhv_mac_->cocoa_view() mouseEntered:event];
+ base::RunLoop().RunUntilIdle();
+ events = host_->GetAndResetDispatchedMessages();
+ ASSERT_EQ("MouseMove MouseMove", GetMessageNames(events));
+ EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
+ static_cast<const blink::WebMouseEvent*>(
+ events[0]->ToEvent()->Event()->web_event.get())
+ ->pointer_type);
+ EXPECT_EQ(blink::WebPointerProperties::PointerType::kPen,
+ static_cast<const blink::WebMouseEvent*>(
+ events[1]->ToEvent()->Event()->web_event.get())
+ ->pointer_type);
+}
+
TEST_F(RenderWidgetHostViewMacTest, PointerEventWithMouseType) {
// Send a NSEvent of a mouse type.
NSEvent* event =
@@ -973,8 +959,8 @@ TEST_F(RenderWidgetHostViewMacTest, SendMouseMoveOnShowingContextMenu) {
ASSERT_EQ("MouseMove", GetMessageNames(events));
}
-void RenderWidgetHostViewMacTest::
- IgnoreEmptyUnhandledWheelEventWithWheelGestures() {
+TEST_F(RenderWidgetHostViewMacTest,
+ IgnoreEmptyUnhandledWheelEventWithWheelGestures) {
// Add a delegate to the view.
base::scoped_nsobject<MockRenderWidgetHostViewMacDelegate> view_delegate(
[[MockRenderWidgetHostViewMacDelegate alloc] init]);
@@ -996,16 +982,10 @@ void RenderWidgetHostViewMacTest::
base::RunLoop().RunUntilIdle();
events = host_->GetAndResetDispatchedMessages();
- if (scroll_latching_) {
- // GestureEventQueue allows multiple in-flight events.
- ASSERT_EQ("GestureScrollBegin GestureScrollUpdate",
- GetMessageNames(events));
- events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
- } else {
- // GestureEventQueue allows multiple in-flight events.
- ASSERT_EQ("GestureScrollBegin GestureScrollUpdate GestureScrollEnd",
- GetMessageNames(events));
- }
+ // GestureEventQueue allows multiple in-flight events.
+ ASSERT_EQ("GestureScrollBegin GestureScrollUpdate", GetMessageNames(events));
+ events[0]->ToEvent()->CallCallback(INPUT_EVENT_ACK_STATE_CONSUMED);
+
events.clear();
// Check that the view delegate got an unhandled wheel event.
@@ -1027,10 +1007,6 @@ void RenderWidgetHostViewMacTest::
// Delete the view while |view_delegate| is still in scope.
rwhv_cocoa_.reset();
}
-TEST_F(RenderWidgetHostViewMacTest,
- IgnoreEmptyUnhandledWheelEventWithWheelGestures) {
- IgnoreEmptyUnhandledWheelEventWithWheelGestures();
-}
// Tests that when view initiated shutdown happens (i.e. RWHView is deleted
// before RWH), we clean up properly and don't leak the RWHVGuest.
@@ -1122,46 +1098,10 @@ TEST_F(RenderWidgetHostViewMacTest, Background) {
EXPECT_TRUE(std::get<0>(sent_background));
}
-class RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest
- : public RenderWidgetHostViewMacTest {
- public:
- RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest()
- : RenderWidgetHostViewMacTest(kWheelScrollLatching) {}
-};
-
-class RenderWidgetHostViewMacWithAsyncWheelEventsEnabledTest
- : public RenderWidgetHostViewMacTest {
- public:
- RenderWidgetHostViewMacWithAsyncWheelEventsEnabledTest()
- : RenderWidgetHostViewMacTest(kAsyncWheelEvents) {}
-};
-
-TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
- IgnoreEmptyUnhandledWheelEventWithWheelGestures) {
- IgnoreEmptyUnhandledWheelEventWithWheelGestures();
-}
-TEST_F(RenderWidgetHostViewMacWithAsyncWheelEventsEnabledTest,
- IgnoreEmptyUnhandledWheelEventWithWheelGestures) {
- IgnoreEmptyUnhandledWheelEventWithWheelGestures();
-}
-
-TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
- ScrollWheelEndEventDelivery) {
- ScrollWheelEndEventDelivery();
-}
-TEST_F(RenderWidgetHostViewMacWithAsyncWheelEventsEnabledTest,
- ScrollWheelEndEventDelivery) {
- 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.
-void RenderWidgetHostViewMacTest::TimerBasedPhaseInfo() {
- // The test is valid only when wheel scroll latching is enabled.
- if (!scroll_latching_)
- return;
-
+TEST_F(RenderWidgetHostViewMacTest, TimerBasedPhaseInfo) {
rwhv_mac_->set_mouse_wheel_wheel_phase_handler_timeout(
base::TimeDelta::FromMilliseconds(100));
@@ -1197,24 +1137,11 @@ void RenderWidgetHostViewMacTest::TimerBasedPhaseInfo() {
events[1]->ToEvent()->Event()->web_event.get())
->data.scroll_end.synthetic);
}
-TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
- TimerBasedPhaseInfo) {
- TimerBasedPhaseInfo();
-}
-TEST_F(RenderWidgetHostViewMacWithAsyncWheelEventsEnabledTest,
- TimerBasedPhaseInfo) {
- TimerBasedPhaseInfo();
-}
-
-// 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.
-void RenderWidgetHostViewMacTest::
- WheelWithPhaseEndedIsNotForwardedImmediately() {
- // The test is valid only when wheel scroll latching is enabled.
- if (!scroll_latching_)
- return;
+// With wheel scroll latching wheel end events are not sent immediately, instead
+// we start a timer to see if momentum phase of the scroll starts or not.
+TEST_F(RenderWidgetHostViewMacTest,
+ WheelWithPhaseEndedIsNotForwardedImmediately) {
// Initialize the view associated with a MockRenderWidgetHostImpl, rather than
// the MockRenderProcessHost that is set up by the test harness which mocks
// out |OnMessageReceived()|.
@@ -1244,9 +1171,8 @@ void RenderWidgetHostViewMacTest::
// in-flight events.
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
- // start.
+ // Send a wheel event with phaseEnded. The event will be dropped and the
+ // mouse_wheel_end_dispatch_timer_ will start.
NSEvent* wheelEvent2 =
MockScrollWheelEventWithPhase(@selector(phaseEnded), 0);
[view->cocoa_view() scrollWheel:wheelEvent2];
@@ -1268,21 +1194,9 @@ void RenderWidgetHostViewMacTest::
kMaximumTimeBetweenPhaseEndedAndMomentumPhaseBegan);
run_loop.Run();
}
-TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
- WheelWithPhaseEndedIsNotForwardedImmediately) {
- WheelWithPhaseEndedIsNotForwardedImmediately();
-}
-TEST_F(RenderWidgetHostViewMacWithAsyncWheelEventsEnabledTest,
- WheelWithPhaseEndedIsNotForwardedImmediately) {
- WheelWithPhaseEndedIsNotForwardedImmediately();
-}
-
-void RenderWidgetHostViewMacTest::
- WheelWithMomentumPhaseBeganStopsTheWheelEndDispatchTimer() {
- // The test is valid only when wheel scroll latching is enabled.
- if (!scroll_latching_)
- return;
+TEST_F(RenderWidgetHostViewMacTest,
+ WheelWithMomentumPhaseBeganStopsTheWheelEndDispatchTimer) {
// Initialize the view associated with a MockRenderWidgetHostImpl, rather than
// the MockRenderProcessHost that is set up by the test harness which mocks
// out |OnMessageReceived()|.
@@ -1313,9 +1227,8 @@ void RenderWidgetHostViewMacTest::
// in-flight events.
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
- // start.
+ // Send a wheel event with phaseEnded. The event will be dropped and the
+ // mouse_wheel_end_dispatch_timer_ will start.
NSEvent* wheelEvent2 =
MockScrollWheelEventWithPhase(@selector(phaseEnded), 0);
[view->cocoa_view() scrollWheel:wheelEvent2];
@@ -1332,29 +1245,14 @@ void RenderWidgetHostViewMacTest::
[view->cocoa_view() scrollWheel:wheelEvent3];
base::RunLoop().RunUntilIdle();
events = host->GetAndResetDispatchedMessages();
- if (wheel_scrolling_mode_ == kAsyncWheelEvents)
- ASSERT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
- else
- ASSERT_EQ("MouseWheel", GetMessageNames(events));
+ ASSERT_EQ("MouseWheel GestureScrollUpdate", GetMessageNames(events));
DCHECK(!view->HasPendingWheelEndEventForTesting());
host->ShutdownAndDestroyWidget(true);
}
-TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
- WheelWithMomentumPhaseBeganStopsTheWheelEndDispatchTimer) {
- WheelWithMomentumPhaseBeganStopsTheWheelEndDispatchTimer();
-}
-TEST_F(RenderWidgetHostViewMacWithAsyncWheelEventsEnabledTest,
- WheelWithMomentumPhaseBeganStopsTheWheelEndDispatchTimer) {
- WheelWithMomentumPhaseBeganStopsTheWheelEndDispatchTimer();
-}
-
-void RenderWidgetHostViewMacTest::
- WheelWithPhaseBeganDispatchesThePendingWheelEnd() {
- // The test is valid only when wheel scroll latching is enabled.
- if (!scroll_latching_)
- return;
+TEST_F(RenderWidgetHostViewMacTest,
+ WheelWithPhaseBeganDispatchesThePendingWheelEnd) {
// Initialize the view associated with a MockRenderWidgetHostImpl, rather than
// the MockRenderProcessHost that is set up by the test harness which mocks
// out |OnMessageReceived()|.
@@ -1385,9 +1283,8 @@ void RenderWidgetHostViewMacTest::
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
- // start.
+ // Send a wheel event with phaseEnded. The event will be dropped and the
+ // mouse_wheel_end_dispatch_timer_ will start.
NSEvent* wheelEvent2 =
MockScrollWheelEventWithPhase(@selector(phaseEnded), 0);
[view->cocoa_view() scrollWheel:wheelEvent2];
@@ -1410,30 +1307,11 @@ void RenderWidgetHostViewMacTest::
host->ShutdownAndDestroyWidget(true);
}
-TEST_F(RenderWidgetHostViewMacWithWheelScrollLatchingEnabledTest,
- WheelWithPhaseBeganDispatchesThePendingWheelEnd) {
- WheelWithPhaseBeganDispatchesThePendingWheelEnd();
-}
-TEST_F(RenderWidgetHostViewMacWithAsyncWheelEventsEnabledTest,
- WheelWithPhaseBeganDispatchesThePendingWheelEnd) {
- WheelWithPhaseBeganDispatchesThePendingWheelEnd();
-}
class RenderWidgetHostViewMacPinchTest : public RenderWidgetHostViewMacTest {
public:
RenderWidgetHostViewMacPinchTest() = default;
- 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() {
#if defined(MAC_OS_X_VERSION_10_11) && \
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11
@@ -1480,23 +1358,37 @@ TEST_F(RenderWidgetHostViewMacPinchTest, PinchThresholding) {
[rwhv_cocoa_ magnifyWithEvent:pinchUpdateEvents[0]];
base::RunLoop().RunUntilIdle();
events = host_->GetAndResetDispatchedMessages();
- EXPECT_EQ("GesturePinchBegin GesturePinchUpdate", GetMessageNames(events));
- EXPECT_TRUE(ZoomDisabledForPinchUpdateMessage(events));
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+
+ // After acking the synthetic mouse wheel, no GesturePinch events are
+ // produced.
+ events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
// The second update event crosses the threshold of 0.4, and so zoom is no
// longer disabled.
[rwhv_cocoa_ magnifyWithEvent:pinchUpdateEvents[1]];
base::RunLoop().RunUntilIdle();
events = host_->GetAndResetDispatchedMessages();
- EXPECT_EQ("GesturePinchUpdate", GetMessageNames(events));
- EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage(events));
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+
+ // Now acking the synthetic mouse wheel does produce GesturePinch events.
+ events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("GesturePinchBegin GesturePinchUpdate", GetMessageNames(events));
// The third update still has zoom enabled.
[rwhv_cocoa_ magnifyWithEvent:pinchUpdateEvents[2]];
base::RunLoop().RunUntilIdle();
events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ events = host_->GetAndResetDispatchedMessages();
EXPECT_EQ("GesturePinchUpdate", GetMessageNames(events));
- EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage(events));
SendEndPinchEvent();
base::RunLoop().RunUntilIdle();
@@ -1521,8 +1413,11 @@ TEST_F(RenderWidgetHostViewMacPinchTest, PinchThresholding) {
[rwhv_cocoa_ magnifyWithEvent:pinchUpdateEvent];
base::RunLoop().RunUntilIdle();
events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+ events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ events = host_->GetAndResetDispatchedMessages();
EXPECT_EQ("GesturePinchBegin GesturePinchUpdate", GetMessageNames(events));
- EXPECT_FALSE(ZoomDisabledForPinchUpdateMessage(events));
SendEndPinchEvent();
base::RunLoop().RunUntilIdle();
@@ -1551,13 +1446,19 @@ TEST_F(RenderWidgetHostViewMacPinchTest, PinchThresholding) {
[rwhv_cocoa_ magnifyWithEvent:pinchUpdateEvent];
base::RunLoop().RunUntilIdle();
events = host_->GetAndResetDispatchedMessages();
- EXPECT_EQ("GesturePinchBegin GesturePinchUpdate", GetMessageNames(events));
- EXPECT_TRUE(ZoomDisabledForPinchUpdateMessage(events));
+ EXPECT_EQ("MouseWheel", GetMessageNames(events));
+
+ events[0]->ToEvent()->CallCallback(
+ INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
+ events = host_->GetAndResetDispatchedMessages();
+ EXPECT_EQ(0U, events.size());
+ // Since no GesturePinchBegin was sent by the time we reach the pinch end,
+ // the GesturePinchBegin and GesturePinchEnd are elided.
SendEndPinchEvent();
base::RunLoop().RunUntilIdle();
events = host_->GetAndResetDispatchedMessages();
- EXPECT_EQ("GesturePinchEnd", GetMessageNames(events));
+ EXPECT_EQ(0U, events.size());
}
}
diff --git a/chromium/content/browser/renderer_host/render_widget_targeter.cc b/chromium/content/browser/renderer_host/render_widget_targeter.cc
index f25502b308e..4a5acc5f53b 100644
--- a/chromium/content/browser/renderer_host/render_widget_targeter.cc
+++ b/chromium/content/browser/renderer_host/render_widget_targeter.cc
@@ -54,8 +54,8 @@ class TracingUmaTracker {
metric_name_(metric_name),
tracing_category_(tracing_category) {
TRACE_EVENT_ASYNC_BEGIN0(
- tracing_category_.c_str(), metric_name_.c_str(),
- TRACE_ID_WITH_SCOPE(metric_name_.c_str(), TRACE_ID_LOCAL(id_)));
+ tracing_category_, metric_name_,
+ TRACE_ID_WITH_SCOPE(metric_name_, TRACE_ID_LOCAL(id_)));
}
~TracingUmaTracker() = default;
TracingUmaTracker(TracingUmaTracker&& tracker) = default;
@@ -63,17 +63,19 @@ class TracingUmaTracker {
void Stop() {
TRACE_EVENT_ASYNC_END0(
- tracing_category_.c_str(), metric_name_.c_str(),
- TRACE_ID_WITH_SCOPE(metric_name_.c_str(), TRACE_ID_LOCAL(id_)));
- UmaHistogramTimes(metric_name_.c_str(),
- base::TimeTicks::Now() - start_time_);
+ tracing_category_, metric_name_,
+ TRACE_ID_WITH_SCOPE(metric_name_, TRACE_ID_LOCAL(id_)));
+ UmaHistogramTimes(metric_name_, base::TimeTicks::Now() - start_time_);
}
private:
const int id_;
const base::TimeTicks start_time_;
- std::string metric_name_;
- std::string tracing_category_;
+
+ // These variables must be string literals and live for the duration
+ // of the program since tracing stores pointers.
+ const char* metric_name_;
+ const char* tracing_category_;
static int next_id_;
diff --git a/chromium/content/browser/renderer_host/ui_events_helper.cc b/chromium/content/browser/renderer_host/ui_events_helper.cc
index 8b3330f22c9..6ea4ed53dbe 100644
--- a/chromium/content/browser/renderer_host/ui_events_helper.cc
+++ b/chromium/content/browser/renderer_host/ui_events_helper.cc
@@ -65,7 +65,8 @@ bool MakeUITouchEventsFromWebTouchEvents(
int flags = ui::WebEventModifiersToEventFlags(touch.GetModifiers());
base::TimeTicks timestamp = touch.TimeStamp();
- for (unsigned i = 0; i < touch.touches_length; ++i) {
+ unsigned count = 0;
+ for (unsigned i = 0; i < blink::WebTouchEvent::kTouchesLengthCap; ++i) {
const blink::WebTouchPoint& point = touch.touches[i];
if (WebTouchPointStateToEventType(point.state) != type)
continue;
@@ -84,6 +85,8 @@ bool MakeUITouchEventsFromWebTouchEvents(
uievent->set_root_location_f(location);
uievent->set_latency(touch_with_latency.latency);
list->push_back(std::move(uievent));
+ if (++count >= touch.touches_length)
+ break;
}
return true;
}
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 a27dfea1f3e..99612d10417 100644
--- a/chromium/content/browser/renderer_host/web_database_host_impl.cc
+++ b/chromium/content/browser/renderer_host/web_database_host_impl.cc
@@ -91,8 +91,8 @@ void WebDatabaseHostImpl::OpenFile(const base::string16& vfs_file_name,
// open handles to them in the database tracker to make sure they're
// around for as long as needed.
if (vfs_file_name.empty()) {
- file = VfsBackend::OpenTempFileInDirectory(db_tracker_->DatabaseDirectory(),
- desired_flags);
+ file = VfsBackend::OpenTempFileInDirectory(
+ db_tracker_->database_directory(), desired_flags);
} else if (DatabaseUtil::CrackVfsFileName(vfs_file_name, &origin_identifier,
&database_name, nullptr) &&
!db_tracker_->IsDatabaseScheduledForDeletion(origin_identifier,
diff --git a/chromium/content/browser/renderer_interface_binders.cc b/chromium/content/browser/renderer_interface_binders.cc
index e306536aa57..896f1b27ded 100644
--- a/chromium/content/browser/renderer_interface_binders.cc
+++ b/chromium/content/browser/renderer_interface_binders.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "content/browser/background_fetch/background_fetch_service_impl.h"
+#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/cookie_store/cookie_store_context.h"
#include "content/browser/locks/lock_manager.h"
#include "content/browser/notifications/platform_notification_context_impl.h"
@@ -28,7 +29,7 @@
#include "services/network/restricted_cookie_manager.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/connector.h"
-#include "services/shape_detection/public/mojom/barcodedetection.mojom.h"
+#include "services/shape_detection/public/mojom/barcodedetection_provider.mojom.h"
#include "services/shape_detection/public/mojom/constants.mojom.h"
#include "services/shape_detection/public/mojom/facedetection_provider.mojom.h"
#include "services/shape_detection/public/mojom/textdetection.mojom.h"
@@ -94,22 +95,15 @@ void ForwardServiceRequest(const char* service_name,
connector->BindInterface(service_name, std::move(request));
}
-void GetRestrictedCookieManagerForWorker(
+void GetRestrictedCookieManager(
network::mojom::RestrictedCookieManagerRequest request,
RenderProcessHost* render_process_host,
const url::Origin& origin) {
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableExperimentalWebPlatformFeatures)) {
- return;
- }
-
StoragePartition* storage_partition =
render_process_host->GetStoragePartition();
network::mojom::NetworkContext* network_context =
storage_partition->GetNetworkContext();
- uint32_t render_process_id = render_process_host->GetID();
- network_context->GetRestrictedCookieManager(
- std::move(request), render_process_id, MSG_ROUTING_NONE);
+ network_context->GetRestrictedCookieManager(std::move(request), origin);
}
// Register renderer-exposed interfaces. Each registered interface binder is
@@ -120,7 +114,7 @@ void GetRestrictedCookieManagerForWorker(
// override binders registered here.
void RendererInterfaceBinders::InitializeParameterizedBinderRegistry() {
parameterized_binder_registry_.AddInterface(base::Bind(
- &ForwardServiceRequest<shape_detection::mojom::BarcodeDetection>,
+ &ForwardServiceRequest<shape_detection::mojom::BarcodeDetectionProvider>,
shape_detection::mojom::kServiceName));
parameterized_binder_registry_.AddInterface(base::Bind(
&ForwardServiceRequest<shape_detection::mojom::FaceDetectionProvider>,
@@ -174,12 +168,12 @@ void RendererInterfaceBinders::InitializeParameterizedBinderRegistry() {
RenderProcessHost* host, const url::Origin& origin) {
static_cast<StoragePartitionImpl*>(host->GetStoragePartition())
->GetPlatformNotificationContext()
- ->CreateService(host->GetID(), origin, std::move(request));
+ ->CreateService(origin, std::move(request));
}));
parameterized_binder_registry_.AddInterface(
base::BindRepeating(&BackgroundFetchServiceImpl::Create));
parameterized_binder_registry_.AddInterface(
- base::BindRepeating(GetRestrictedCookieManagerForWorker));
+ base::BindRepeating(GetRestrictedCookieManager));
parameterized_binder_registry_.AddInterface(
base::BindRepeating(&QuotaDispatcherHost::CreateForWorker));
parameterized_binder_registry_.AddInterface(base::BindRepeating(
@@ -201,7 +195,7 @@ void RendererInterfaceBinders::CreateWebSocket(
RenderProcessHost* host,
const url::Origin& origin) {
WebSocketManager::CreateWebSocket(host->GetID(), MSG_ROUTING_NONE, origin,
- std::move(request));
+ nullptr, std::move(request));
}
} // namespace
diff --git a/chromium/content/browser/resources/gpu/OWNERS b/chromium/content/browser/resources/gpu/OWNERS
index 2aa356651f1..ea5131efe74 100644
--- a/chromium/content/browser/resources/gpu/OWNERS
+++ b/chromium/content/browser/resources/gpu/OWNERS
@@ -1,3 +1,4 @@
nduca@chromium.org
kbr@chromium.org
-zmo@chromium.org \ No newline at end of file
+zmo@chromium.org
+backer@chromium.org
diff --git a/chromium/content/browser/resources/gpu/info_view.js b/chromium/content/browser/resources/gpu/info_view.js
index 41a64405b78..122f2e874be 100644
--- a/chromium/content/browser/resources/gpu/info_view.js
+++ b/chromium/content/browser/resources/gpu/info_view.js
@@ -230,6 +230,7 @@ cr.define('gpu', function() {
'texture_sharing': 'Texture Sharing',
'video_decode': 'Video Decode',
'rasterization': 'Rasterization',
+ 'oop_rasterization': 'Out-of-process Rasterization',
'multiple_raster_threads': 'Multiple Raster Threads',
'native_gpu_memory_buffers': 'Native GpuMemoryBuffers',
'protected_video_decode': 'Hardware Protected Video Decode',
diff --git a/chromium/content/browser/resources/histograms/histograms_internals.html b/chromium/content/browser/resources/histograms/histograms_internals.html
index 5fd6ebfb75b..16a224365a4 100644
--- a/chromium/content/browser/resources/histograms/histograms_internals.html
+++ b/chromium/content/browser/resources/histograms/histograms_internals.html
@@ -9,7 +9,7 @@
<script src="chrome://resources/js/promise_resolver.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="histograms_internals.js"></script>
- <title>📊 About Histograms</title>
+ <title>Histograms</title>
</head>
<p>Stats accumulated from browser startup to previous page load; reload to get stats as of this page load.
</p>
diff --git a/chromium/content/browser/resources/media/peer_connection_update_table.js b/chromium/content/browser/resources/media/peer_connection_update_table.js
index 09998a6bf7d..83416e5109b 100644
--- a/chromium/content/browser/resources/media/peer_connection_update_table.js
+++ b/chromium/content/browser/resources/media/peer_connection_update_table.js
@@ -122,14 +122,6 @@ var PeerConnectionUpdateTable = (function() {
update.type === 'addIceCandidateFailed') {
valueContainer.parentElement.classList.add('update-log-failure');
}
- // Highlight legacy streams API usage.
- if (update.type === 'addStream' || update.type === 'removeStream') {
- valueContainer.parentElement.classList.add(
- 'update-log-legacy-api-usage');
- valueContainer.parentElement.title = update.type + ' is no longer ' +
- 'part of the WebRTC API and may be removed in future versions. ' +
- 'Use the addTrack/removeTrack APIs instead.';
- }
var value = update.value;
// map internal names and values to names and events from the
diff --git a/chromium/content/browser/resources/process/process_internals.html b/chromium/content/browser/resources/process/process_internals.html
index 9e5acb2d80a..9b63631e817 100644
--- a/chromium/content/browser/resources/process/process_internals.html
+++ b/chromium/content/browser/resources/process/process_internals.html
@@ -12,5 +12,5 @@
<title>Process Model Internals</title>
</head>
<div id="site-isolation-mode">Site Isolation mode: <span id='isolation-mode'>unknown</span></div>
-<div id="isolated-origins-container">Isolated origins: <span id='isolated-origins'></span></div>
+<div id="isolated-origins-container">Number of isolated origins: <span id='isolated-origins'></span></div>
</html>
diff --git a/chromium/content/browser/resources/process/process_internals.js b/chromium/content/browser/resources/process/process_internals.js
index a745e29b6ec..155847443a7 100644
--- a/chromium/content/browser/resources/process/process_internals.js
+++ b/chromium/content/browser/resources/process/process_internals.js
@@ -24,9 +24,8 @@ document.addEventListener('DOMContentLoaded', function() {
uiHandler.getIsolationMode().then((response) => {
document.getElementById('isolation-mode').innerText = response.mode;
});
- uiHandler.getIsolatedOrigins().then((response) => {
- document.getElementById('isolated-origins').innerText =
- response.isolatedOrigins.join(', ');
+ uiHandler.getIsolatedOriginsSize().then((response) => {
+ document.getElementById('isolated-origins').innerText = response.size;
});
});
diff --git a/chromium/content/browser/resources/service_worker/serviceworker_internals.js b/chromium/content/browser/resources/service_worker/serviceworker_internals.js
index 810676ab9d1..a1a697b8584 100644
--- a/chromium/content/browser/resources/service_worker/serviceworker_internals.js
+++ b/chromium/content/browser/resources/service_worker/serviceworker_internals.js
@@ -198,8 +198,6 @@ cr.define('serviceworker', function() {
function onErrorReported(partition_id,
version_id,
- process_id,
- thread_id,
error_info) {
outputLogMessage(partition_id,
version_id,
@@ -208,8 +206,6 @@ cr.define('serviceworker', function() {
function onConsoleMessageReported(partition_id,
version_id,
- process_id,
- thread_id,
message) {
outputLogMessage(partition_id,
version_id,
diff --git a/chromium/content/browser/sandbox_ipc_linux.cc b/chromium/content/browser/sandbox_ipc_linux.cc
index 3206764895c..a893d1b8f09 100644
--- a/chromium/content/browser/sandbox_ipc_linux.cc
+++ b/chromium/content/browser/sandbox_ipc_linux.cc
@@ -21,69 +21,15 @@
#include "base/posix/unix_domain_socket.h"
#include "base/process/launch.h"
#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/public/common/content_switches.h"
#include "sandbox/linux/services/libc_interceptor.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"
-#include "ui/gfx/font_fallback_linux.h"
-#include "ui/gfx/font_render_params.h"
namespace content {
-namespace {
-
-SandboxIPCHandler::TestObserver* g_test_observer = nullptr;
-
-// Converts gfx::FontRenderParams::Hinting to WebFontRenderStyle::hintStyle.
-// Returns an int for serialization, but the underlying Blink type is a char.
-int ConvertHinting(gfx::FontRenderParams::Hinting hinting) {
- switch (hinting) {
- case gfx::FontRenderParams::HINTING_NONE:
- return 0;
- case gfx::FontRenderParams::HINTING_SLIGHT:
- return 1;
- case gfx::FontRenderParams::HINTING_MEDIUM:
- return 2;
- case gfx::FontRenderParams::HINTING_FULL:
- return 3;
- }
- NOTREACHED() << "Unexpected hinting value " << hinting;
- return 0;
-}
-
-// Converts gfx::FontRenderParams::SubpixelRendering to
-// WebFontRenderStyle::useSubpixelRendering. Returns an int for serialization,
-// but the underlying Blink type is a char.
-int ConvertSubpixelRendering(
- gfx::FontRenderParams::SubpixelRendering rendering) {
- switch (rendering) {
- case gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE:
- return 0;
- case gfx::FontRenderParams::SUBPIXEL_RENDERING_RGB:
- return 1;
- case gfx::FontRenderParams::SUBPIXEL_RENDERING_BGR:
- return 1;
- case gfx::FontRenderParams::SUBPIXEL_RENDERING_VRGB:
- return 1;
- case gfx::FontRenderParams::SUBPIXEL_RENDERING_VBGR:
- return 1;
- }
- NOTREACHED() << "Unexpected subpixel rendering value " << rendering;
- return 0;
-}
-
-} // namespace
+const size_t kMaxSandboxIPCMessagePayloadSize = 64;
// static
-void SandboxIPCHandler::SetObserverForTests(
- SandboxIPCHandler::TestObserver* observer) {
- g_test_observer = observer;
-}
-
SandboxIPCHandler::SandboxIPCHandler(int lifeline_fd, int browser_socket)
: lifeline_fd_(lifeline_fd), browser_socket_(browser_socket) {}
@@ -136,17 +82,22 @@ void SandboxIPCHandler::HandleRequestFromChild(int fd) {
// A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength
// bytes long (this is the largest message type).
+ // The size limit used to be FontConfigIPC::kMaxFontFamilyLength which was
+ // 2048, but we do not receive FontConfig IPC here anymore. The only payloads
+ // here are service_manager::SandboxLinux::METHOD_MAKE_SHARED_MEMORY_SEGMENT
+ // and HandleLocalTime from libc_interceptor for which
+ // kMaxSandboxIPCMessagePayloadSize set to 64 should be plenty.
// 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC
// error for a maximum length message.
- char buf[FontConfigIPC::kMaxFontFamilyLength + 128];
+ char buf[kMaxSandboxIPCMessagePayloadSize + 128];
const ssize_t len =
base::UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds);
if (len == -1) {
// TODO: should send an error reply, or the sender might block forever.
if (errno == EMSGSIZE) {
- NOTREACHED()
- << "Sandbox host message is larger than kMaxFontFamilyLength";
+ NOTREACHED() << "Sandbox host message is larger than "
+ "kMaxSandboxIPCMessagePayloadSize";
} else {
PLOG(ERROR) << "Recvmsg failed";
NOTREACHED();
@@ -168,164 +119,12 @@ void SandboxIPCHandler::HandleRequestFromChild(int fd) {
if (sandbox::HandleInterceptedCall(kind, fd, iter, fds))
return;
- if (kind == FontConfigIPC::METHOD_MATCH) {
- HandleFontMatchRequest(fd, iter, fds);
- } else if (kind == FontConfigIPC::METHOD_OPEN) {
- HandleFontOpenRequest(fd, iter, fds);
- } else if (kind ==
- service_manager::SandboxLinux::METHOD_GET_FALLBACK_FONT_FOR_CHAR) {
- HandleGetFallbackFontForChar(fd, iter, fds);
- } else if (kind ==
- service_manager::SandboxLinux::METHOD_GET_STYLE_FOR_STRIKE) {
- HandleGetStyleForStrike(fd, iter, fds);
- } else if (kind ==
- service_manager::SandboxLinux::METHOD_MAKE_SHARED_MEMORY_SEGMENT) {
+ if (kind ==
+ service_manager::SandboxLinux::METHOD_MAKE_SHARED_MEMORY_SEGMENT) {
HandleMakeSharedMemorySegment(fd, iter, fds);
- } else if (kind ==
- service_manager::SandboxLinux::METHOD_MATCH_WITH_FALLBACK) {
- HandleMatchWithFallback(fd, iter, fds);
- }
-}
-
-int SandboxIPCHandler::FindOrAddPath(const SkString& path) {
- int count = paths_.size();
- for (int i = 0; i < count; ++i) {
- if (path == paths_[i])
- return i;
- }
- paths_.emplace_back(path);
- return count;
-}
-
-void SandboxIPCHandler::HandleFontMatchRequest(
- int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD>& fds) {
- SkFontStyle requested_style;
- std::string family;
- if (!iter.ReadString(&family) ||
- !skia::ReadSkFontStyle(&iter, &requested_style))
- return;
-
- SkFontConfigInterface::FontIdentity result_identity;
- SkString result_family;
- SkFontStyle result_style;
- SkFontConfigInterface* fc =
- SkFontConfigInterface::GetSingletonDirectInterface();
- const bool r =
- fc->matchFamilyName(family.c_str(), requested_style, &result_identity,
- &result_family, &result_style);
-
- base::Pickle reply;
- if (!r) {
- reply.WriteBool(false);
- } else {
- // Stash away the returned path, so we can give it an ID (index)
- // which will later be given to us in a request to open the file.
- int index = FindOrAddPath(result_identity.fString);
- result_identity.fID = static_cast<uint32_t>(index);
-
- reply.WriteBool(true);
- skia::WriteSkString(&reply, result_family);
- skia::WriteSkFontIdentity(&reply, result_identity);
- skia::WriteSkFontStyle(&reply, result_style);
- }
- SendRendererReply(fds, reply, -1);
-}
-
-void SandboxIPCHandler::HandleFontOpenRequest(
- int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD>& fds) {
- uint32_t index;
- if (!iter.ReadUInt32(&index))
- return;
- if (index >= static_cast<uint32_t>(paths_.size()))
- return;
- if (g_test_observer) {
- g_test_observer->OnFontOpen(index);
- }
- const int result_fd = open(paths_[index].c_str(), O_RDONLY);
-
- base::Pickle reply;
- reply.WriteBool(result_fd != -1);
-
- // The receiver will have its own access to the file, so we will close it
- // after this send.
- SendRendererReply(fds, reply, result_fd);
-
- if (result_fd >= 0) {
- int err = IGNORE_EINTR(close(result_fd));
- DCHECK(!err);
- }
-}
-
-void SandboxIPCHandler::HandleGetFallbackFontForChar(
- int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD>& fds) {
- // The other side of this call is
- // content/common/child_process_sandbox_support_impl_linux.cc
-
- UChar32 c;
- if (!iter.ReadInt(&c))
return;
-
- std::string preferred_locale;
- if (!iter.ReadString(&preferred_locale))
- return;
-
- auto fallback_font = gfx::GetFallbackFontForChar(c, preferred_locale);
- int fontconfig_interface_id =
- FindOrAddPath(SkString(fallback_font.filename.data()));
-
- if (g_test_observer) {
- g_test_observer->OnGetFallbackFontForChar(c, fallback_font.name,
- fontconfig_interface_id);
}
- base::Pickle reply;
- reply.WriteString(fallback_font.name);
- reply.WriteString(fallback_font.filename);
- reply.WriteInt(fontconfig_interface_id);
- reply.WriteInt(fallback_font.ttc_index);
- reply.WriteBool(fallback_font.is_bold);
- reply.WriteBool(fallback_font.is_italic);
- SendRendererReply(fds, reply, -1);
-}
-
-void SandboxIPCHandler::HandleGetStyleForStrike(
- int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD>& fds) {
- std::string family;
- bool bold;
- bool italic;
- uint16_t pixel_size;
-
- if (!iter.ReadString(&family) || !iter.ReadBool(&bold) ||
- !iter.ReadBool(&italic) || !iter.ReadUInt16(&pixel_size)) {
- return;
- }
-
- gfx::FontRenderParamsQuery query;
- query.families.push_back(family);
- query.pixel_size = pixel_size;
- query.style = italic ? gfx::Font::ITALIC : 0;
- query.weight = bold ? gfx::Font::Weight::BOLD : gfx::Font::Weight::NORMAL;
- const gfx::FontRenderParams params = gfx::GetFontRenderParams(query, nullptr);
-
- // These are passed as ints since they're interpreted as tri-state chars in
- // Blink.
- base::Pickle reply;
- reply.WriteInt(params.use_bitmaps);
- reply.WriteInt(params.autohinter);
- reply.WriteInt(params.hinting != gfx::FontRenderParams::HINTING_NONE);
- reply.WriteInt(ConvertHinting(params.hinting));
- reply.WriteInt(params.antialiasing);
- reply.WriteInt(ConvertSubpixelRendering(params.subpixel_rendering));
- reply.WriteInt(params.subpixel_positioning);
-
- SendRendererReply(fds, reply, -1);
+ NOTREACHED();
}
void SandboxIPCHandler::HandleMakeSharedMemorySegment(
@@ -347,34 +146,6 @@ void SandboxIPCHandler::HandleMakeSharedMemorySegment(
SendRendererReply(fds, reply, shm_fd);
}
-void SandboxIPCHandler::HandleMatchWithFallback(
- int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD>& fds) {
- std::string face;
- bool is_bold;
- bool is_italic;
- uint32_t charset;
- uint32_t fallback_family;
-
- if (!iter.ReadString(&face) || face.empty() || !iter.ReadBool(&is_bold) ||
- !iter.ReadBool(&is_italic) || !iter.ReadUInt32(&charset) ||
- !iter.ReadUInt32(&fallback_family)) {
- return;
- }
-
- int font_fd = MatchFontFaceWithFallback(face, is_bold, is_italic, charset,
- fallback_family);
-
- base::Pickle reply;
- SendRendererReply(fds, reply, font_fd);
-
- if (font_fd >= 0) {
- if (IGNORE_EINTR(close(font_fd)) < 0)
- PLOG(ERROR) << "close";
- }
-}
-
void SandboxIPCHandler::SendRendererReply(
const std::vector<base::ScopedFD>& fds,
const base::Pickle& reply,
diff --git a/chromium/content/browser/sandbox_ipc_linux.h b/chromium/content/browser/sandbox_ipc_linux.h
index 06c2c604397..684a6aa0825 100644
--- a/chromium/content/browser/sandbox_ipc_linux.h
+++ b/chromium/content/browser/sandbox_ipc_linux.h
@@ -18,8 +18,6 @@
#include "content/common/content_export.h"
#include "third_party/icu/source/common/unicode/uchar.h"
-class SkString;
-
namespace content {
class SandboxIPCHandler : public base::DelegateSimpleThread::Delegate {
@@ -32,55 +30,19 @@ class SandboxIPCHandler : public base::DelegateSimpleThread::Delegate {
void Run() override;
- class TestObserver {
- public:
- virtual void OnGetFallbackFontForChar(UChar32 c,
- std::string name,
- int id) = 0;
- virtual void OnFontOpen(int id) = 0;
- };
- CONTENT_EXPORT static void SetObserverForTests(TestObserver* observer);
-
private:
- int FindOrAddPath(const SkString& path);
-
void HandleRequestFromChild(int fd);
- void HandleFontMatchRequest(int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD>& fds);
-
- void HandleFontOpenRequest(int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD>& fds);
-
- void HandleGetFallbackFontForChar(int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD>& fds);
-
- void HandleGetStyleForStrike(int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD>& fds);
-
- void HandleLocaltime(int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD>& fds);
-
void HandleMakeSharedMemorySegment(int fd,
base::PickleIterator iter,
const std::vector<base::ScopedFD>& fds);
- void HandleMatchWithFallback(int fd,
- base::PickleIterator iter,
- const std::vector<base::ScopedFD>& fds);
-
void SendRendererReply(const std::vector<base::ScopedFD>& fds,
const base::Pickle& reply,
int reply_fd);
const int lifeline_fd_;
const int browser_socket_;
- std::vector<SkString> paths_;
DISALLOW_COPY_AND_ASSIGN(SandboxIPCHandler);
};
diff --git a/chromium/content/browser/sandbox_parameters_mac.mm b/chromium/content/browser/sandbox_parameters_mac.mm
index e9415b0de5f..a9227b8e010 100644
--- a/chromium/content/browser/sandbox_parameters_mac.mm
+++ b/chromium/content/browser/sandbox_parameters_mac.mm
@@ -10,6 +10,7 @@
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/mac/bundle_locations.h"
+#include "base/mac/foundation_util.h"
#include "base/mac/mac_util.h"
#include "base/numerics/checked_math.h"
#include "base/strings/stringprintf.h"
@@ -63,8 +64,8 @@ void SetupCommonSandboxParameters(sandbox::SeatbeltExecClient* client) {
CHECK(client->SetParameter(service_manager::SandboxMac::kSandboxBundlePath,
bundle_path));
- NSBundle* bundle = base::mac::OuterBundle();
- std::string bundle_id = base::SysNSStringToUTF8([bundle bundleIdentifier]);
+ std::string bundle_id = base::mac::BaseBundleID();
+ DCHECK(!bundle_id.empty()) << "base::mac::OuterBundle is unset";
CHECK(client->SetParameter(
service_manager::SandboxMac::kSandboxChromeBundleId, bundle_id));
diff --git a/chromium/content/browser/screen_orientation/screen_orientation_delegate_android.cc b/chromium/content/browser/screen_orientation/screen_orientation_delegate_android.cc
index 4e828cd1a16..7f88ed37799 100644
--- a/chromium/content/browser/screen_orientation/screen_orientation_delegate_android.cc
+++ b/chromium/content/browser/screen_orientation/screen_orientation_delegate_android.cc
@@ -4,9 +4,8 @@
#include "content/browser/screen_orientation/screen_orientation_delegate_android.h"
-#include "content/browser/android/content_view_core.h"
#include "content/browser/screen_orientation/screen_orientation_provider.h"
-#include "jni/ScreenOrientationProvider_jni.h"
+#include "jni/ScreenOrientationProviderImpl_jni.h"
#include "ui/android/window_android.h"
#include "ui/gfx/native_widget_types.h"
@@ -29,7 +28,7 @@ void ScreenOrientationDelegateAndroid::Lock(
WebContents* web_contents,
blink::WebScreenOrientationLockType lock_orientation) {
gfx::NativeWindow window = web_contents->GetTopLevelNativeWindow();
- Java_ScreenOrientationProvider_lockOrientation(
+ Java_ScreenOrientationProviderImpl_lockOrientation(
base::android::AttachCurrentThread(),
window ? window->GetJavaObject() : nullptr,
lock_orientation);
@@ -39,13 +38,13 @@ bool ScreenOrientationDelegateAndroid::ScreenOrientationProviderSupported() {
// TODO(MLamouri): Consider moving isOrientationLockEnabled to a separate
// function, so reported error messages can differentiate between the device
// never supporting orientation or currently not support orientation.
- return Java_ScreenOrientationProvider_isOrientationLockEnabled(
+ return Java_ScreenOrientationProviderImpl_isOrientationLockEnabled(
base::android::AttachCurrentThread());
}
void ScreenOrientationDelegateAndroid::Unlock(WebContents* web_contents) {
gfx::NativeWindow window = web_contents->GetTopLevelNativeWindow();
- Java_ScreenOrientationProvider_unlockOrientation(
+ Java_ScreenOrientationProviderImpl_unlockOrientation(
base::android::AttachCurrentThread(),
window ? window->GetJavaObject() : nullptr);
}
diff --git a/chromium/content/browser/security_exploit_browsertest.cc b/chromium/content/browser/security_exploit_browsertest.cc
index 9c298b18244..e3b04edb5a3 100644
--- a/chromium/content/browser/security_exploit_browsertest.cc
+++ b/chromium/content/browser/security_exploit_browsertest.cc
@@ -129,7 +129,6 @@ network::ResourceRequest CreateXHRRequest(const char* url) {
request.plugin_child_id = -1;
request.resource_type = RESOURCE_TYPE_XHR;
request.appcache_host_id = kAppCacheNoHostId;
- request.download_to_file = false;
request.should_reset_appcache = false;
request.is_main_frame = true;
request.transition_type = ui::PAGE_TRANSITION_LINK;
@@ -185,28 +184,44 @@ class SecurityExploitBrowserTest : public ContentBrowserTest {
static void CreateLoaderAndStartOnIOThread(
scoped_refptr<ResourceMessageFilter> filter,
+ network::mojom::URLLoaderRequest request,
int route_id,
int request_id,
- const network::ResourceRequest& request) {
- network::mojom::URLLoaderPtr loader;
- network::TestURLLoaderClient client;
+ const network::ResourceRequest& resource_request,
+ network::mojom::URLLoaderClientPtrInfo client) {
filter->CreateLoaderAndStart(
- mojo::MakeRequest(&loader), route_id, request_id,
- network::mojom::kURLLoadOptionNone, request,
- client.CreateInterfacePtr(),
+ std::move(request), route_id, request_id,
+ network::mojom::kURLLoadOptionNone, resource_request,
+ network::mojom::URLLoaderClientPtr(std::move(client)),
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
}
- static void CreateLoaderAndStart(RenderProcessHost* process,
- int route_id,
- int request_id,
- const network::ResourceRequest& request) {
+ static void CreateLoaderAndStart(
+ RenderProcessHost* process,
+ int route_id,
+ int request_id,
+ const network::ResourceRequest& resource_request) {
+ network::mojom::URLLoaderPtr loader;
+ network::TestURLLoaderClient client;
+ CreateLoaderAndStart(process, mojo::MakeRequest(&loader), route_id,
+ request_id, resource_request,
+ client.CreateInterfacePtr().PassInterface());
+ }
+
+ static void CreateLoaderAndStart(
+ RenderProcessHost* process,
+ network::mojom::URLLoaderRequest request,
+ int route_id,
+ int request_id,
+ const network::ResourceRequest& resource_request,
+ network::mojom::URLLoaderClientPtrInfo client) {
RenderProcessHostImpl* impl = static_cast<RenderProcessHostImpl*>(process);
auto filter = impl->resource_message_filter_;
process->GetChannel()->ipc_task_runner()->PostTask(
FROM_HERE, base::BindOnce(CreateLoaderAndStartOnIOThread, filter,
- route_id, request_id, request));
+ std::move(request), route_id, request_id,
+ resource_request, std::move(client)));
}
void TryCreateDuplicateRequestIds(Shell* shell, bool block_loaders) {
@@ -228,11 +243,16 @@ class SecurityExploitBrowserTest : public ContentBrowserTest {
// Use the same request id twice.
RenderProcessHostKillWaiter kill_waiter(rfh->GetProcess());
-
- CreateLoaderAndStart(rfh->GetProcess(), rfh->GetRoutingID(),
- kRequestIdNotPreviouslyUsed, request);
- CreateLoaderAndStart(rfh->GetProcess(), rfh->GetRoutingID(),
- kRequestIdNotPreviouslyUsed, request);
+ // We need to keep loader and client to keep the requests alive.
+ network::mojom::URLLoaderPtr loader1, loader2;
+ network::TestURLLoaderClient client1, client2;
+
+ CreateLoaderAndStart(rfh->GetProcess(), mojo::MakeRequest(&loader1),
+ rfh->GetRoutingID(), kRequestIdNotPreviouslyUsed,
+ request, client1.CreateInterfacePtr().PassInterface());
+ CreateLoaderAndStart(rfh->GetProcess(), mojo::MakeRequest(&loader2),
+ rfh->GetRoutingID(), kRequestIdNotPreviouslyUsed,
+ request, client2.CreateInterfacePtr().PassInterface());
EXPECT_EQ(bad_message::RDH_INVALID_REQUEST_ID, kill_waiter.Wait());
}
@@ -508,10 +528,12 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) {
// Renderer process should not be able to create multiple requests with the same
// id.
-// Disabled due to flakiness on all operating systems: crbug.com/799516
-IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, DISABLED_InvalidRequestId) {
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidRequestId) {
// Existing loader in pending_loaders_.
TryCreateDuplicateRequestIds(shell(), false);
+}
+
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidBlockedRequestId) {
// Existing loader in blocked_loaders_map_.
TryCreateDuplicateRequestIds(shell(), true);
}
@@ -526,9 +548,11 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, MismatchedOriginOnCommit) {
->GetFrameTree()
->root();
- // Setup an URL which will never commit, allowing this test to send its own,
- // malformed, commit message.
- GURL url(embedded_test_server()->GetURL("/hung"));
+ // Navigate to a new URL, with an interceptor that replaces the origin with
+ // one that does not match params.url.
+ GURL url(embedded_test_server()->GetURL("/title2.html"));
+ PwnCommitIPC(shell()->web_contents(), url, url,
+ url::Origin::Create(GURL("http://bar.com/")));
// Use LoadURL, as the test shouldn't wait for navigation commit.
NavigationController& controller = shell()->web_contents()->GetController();
@@ -539,30 +563,12 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, MismatchedOriginOnCommit) {
RenderProcessHostKillWaiter kill_waiter(
root->current_frame_host()->GetProcess());
- // Create commit params with different origins in params.url and
- // params.origin.
- std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params =
- std::make_unique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
- params->nav_entry_id = 0;
- params->did_create_new_entry = false;
- params->url = url;
- params->transition = ui::PAGE_TRANSITION_LINK;
- params->should_update_history = false;
- params->gesture = NavigationGestureAuto;
- params->method = "GET";
- params->page_state = PageState::CreateFromURL(url);
- params->origin = url::Origin::Create(GURL("http://bar.com/"));
-
- service_manager::mojom::InterfaceProviderPtr interface_provider;
- static_cast<mojom::FrameHost*>(root->current_frame_host())
- ->DidCommitProvisionalLoad(std::move(params),
- mojo::MakeRequest(&interface_provider));
-
// When the IPC message is received and validation fails, the process is
// terminated. However, the notification for that should be processed in a
// separate task of the message loop, so ensure that the process is still
// considered alive.
- EXPECT_TRUE(root->current_frame_host()->GetProcess()->HasConnection());
+ EXPECT_TRUE(
+ root->current_frame_host()->GetProcess()->IsInitializedAndNotDead());
EXPECT_EQ(bad_message::RFH_INVALID_ORIGIN_ON_COMMIT, kill_waiter.Wait());
}
@@ -585,14 +591,15 @@ class ScopedInterfaceProviderRequestReplacer
~ScopedInterfaceProviderRequestReplacer() override = default;
protected:
- void WillDispatchDidCommitProvisionalLoad(
+ bool WillDispatchDidCommitProvisionalLoad(
RenderFrameHost* render_frame_host,
::FrameHostMsg_DidCommitProvisionalLoad_Params* params,
service_manager::mojom::InterfaceProviderRequest*
interface_provider_request) override {
- ASSERT_TRUE(interface_provider_request_override_.has_value());
+ CHECK(interface_provider_request_override_.has_value());
*interface_provider_request =
std::move(interface_provider_request_override_).value();
+ return true;
}
private:
diff --git a/chromium/content/browser/service_manager/common_browser_interfaces.cc b/chromium/content/browser/service_manager/common_browser_interfaces.cc
index af1a24e735b..ea58b9e3599 100644
--- a/chromium/content/browser/service_manager/common_browser_interfaces.cc
+++ b/chromium/content/browser/service_manager/common_browser_interfaces.cc
@@ -4,6 +4,7 @@
#include "content/browser/service_manager/common_browser_interfaces.h"
+#include <map>
#include <memory>
#include <utility>
@@ -15,10 +16,15 @@
#include "build/build_config.h"
#include "components/discardable_memory/service/discardable_shared_memory_manager.h"
#include "content/browser/browser_main_loop.h"
+#include "content/browser/gpu/gpu_client_impl.h"
+#include "content/common/child_process_host_impl.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/common/connection_filter.h"
#include "content/public/common/service_manager_connection.h"
+#include "content/public/common/service_names.mojom.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "services/service_manager/public/cpp/binder_registry.h"
+#include "services/ui/public/interfaces/gpu.mojom.h"
#include "ui/base/ui_base_features.h"
#if defined(OS_WIN)
@@ -44,7 +50,7 @@ class ConnectionFilterImpl : public ConnectionFilter {
#elif defined(OS_MACOSX)
registry_.AddInterface(base::BindRepeating(&FontLoaderDispatcher::Create));
#endif
- if (!features::IsMashEnabled()) {
+ if (features::IsAshInBrowserProcess()) {
// For mus, the mojom::discardable_memory::DiscardableSharedMemoryManager
// is exposed from ui::Service. So we don't need bind the interface here.
auto* browser_main_loop = BrowserMainLoop::GetInstance();
@@ -57,9 +63,13 @@ class ConnectionFilterImpl : public ConnectionFilter {
}
}
}
+ if (features::IsAshInBrowserProcess()) {
+ registry_.AddInterface(base::BindRepeating(
+ &ConnectionFilterImpl::BindGpuRequest, base::Unretained(this)));
+ }
}
- ~ConnectionFilterImpl() override {}
+ ~ConnectionFilterImpl() override { DCHECK_CURRENTLY_ON(BrowserThread::IO); }
private:
template <typename Interface>
@@ -72,9 +82,44 @@ class ConnectionFilterImpl : public ConnectionFilter {
const std::string& interface_name,
mojo::ScopedMessagePipeHandle* interface_pipe,
service_manager::Connector* connector) override {
+ // Ignore ui::mojom::Gpu interface request from Renderer process.
+ // The request will be handled in RenderProcessHostImpl.
+ if (source_info.identity.name() == mojom::kRendererServiceName &&
+ interface_name == ui::mojom::Gpu::Name_)
+ return;
+
registry_.TryBindInterface(interface_name, interface_pipe, source_info);
}
+ void BindGpuRequest(ui::mojom::GpuRequest request,
+ const service_manager::BindSourceInfo& source_info) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ // Only allow one connection per service to avoid possible race condition.
+ // So Reset the current connection if there is one.
+ gpu_clients_.erase(source_info.identity);
+
+ const int gpu_client_id =
+ ChildProcessHostImpl::GenerateChildProcessUniqueId();
+ const uint64_t gpu_client_tracing_id =
+ ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(
+ gpu_client_id);
+ auto gpu_client = std::make_unique<GpuClientImpl>(
+ gpu_client_id, gpu_client_tracing_id,
+ BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ gpu_client->SetConnectionErrorHandler(
+ base::BindOnce(&ConnectionFilterImpl::OnGpuConnectionClosed,
+ base::Unretained(this), source_info.identity));
+ gpu_client->Add(std::move(request));
+ gpu_clients_.emplace(source_info.identity, std::move(gpu_client));
+ }
+
+ void OnGpuConnectionClosed(const service_manager::Identity& service_identity,
+ GpuClient* client) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ gpu_clients_.erase(service_identity);
+ }
+
template <typename Interface>
static void BindOnTaskRunner(
const scoped_refptr<base::TaskRunner>& task_runner,
@@ -88,6 +133,8 @@ class ConnectionFilterImpl : public ConnectionFilter {
service_manager::BinderRegistryWithArgs<
const service_manager::BindSourceInfo&>
registry_;
+ std::map<service_manager::Identity, std::unique_ptr<GpuClientImpl>>
+ gpu_clients_;
DISALLOW_COPY_AND_ASSIGN(ConnectionFilterImpl);
};
diff --git a/chromium/content/browser/service_manager/service_manager_context.cc b/chromium/content/browser/service_manager/service_manager_context.cc
index 6df4527d9a4..2daaf7231c0 100644
--- a/chromium/content/browser/service_manager/service_manager_context.cc
+++ b/chromium/content/browser/service_manager/service_manager_context.cc
@@ -11,17 +11,21 @@
#include "base/bind.h"
#include "base/command_line.h"
+#include "base/deferred_sequenced_task_runner.h"
#include "base/feature_list.h"
#include "base/json/json_reader.h"
#include "base/lazy_instance.h"
#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
+#include "base/no_destructor.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/app/strings/grit/content_strings.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/child_process_launcher.h"
#include "content/browser/gpu/gpu_process_host.h"
@@ -45,8 +49,8 @@
#include "media/media_buildflags.h"
#include "media/mojo/buildflags.h"
#include "media/mojo/interfaces/constants.mojom.h"
-#include "mojo/edk/embedder/embedder.h"
-#include "mojo/edk/embedder/incoming_broker_client_invitation.h"
+#include "mojo/public/cpp/platform/platform_channel.h"
+#include "mojo/public/cpp/system/invitation.h"
#include "services/audio/public/mojom/constants.mojom.h"
#include "services/audio/service_factory.h"
#include "services/catalog/manifest_provider.h"
@@ -91,6 +95,11 @@
#include "ui/aura/env.h"
#endif
+#if defined(OS_LINUX)
+#include "components/services/font/font_service_app.h"
+#include "components/services/font/public/interfaces/constants.mojom.h"
+#endif
+
namespace content {
namespace {
@@ -106,13 +115,12 @@ void DestroyConnectorOnIOThread() { g_io_thread_connector.Get().reset(); }
// Launch a process for a service once its sandbox type is known.
void StartServiceInUtilityProcess(
const std::string& service_name,
- const base::string16& process_name,
+ const ContentBrowserClient::ProcessNameCallback& process_name_callback,
base::Optional<std::string> process_group,
service_manager::mojom::ServiceRequest request,
service_manager::mojom::PIDReceiverPtr pid_receiver,
service_manager::mojom::ConnectResult query_result,
const std::string& sandbox_string) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_manager::SandboxType sandbox_type =
service_manager::UtilitySandboxTypeFromString(sandbox_string);
@@ -128,7 +136,10 @@ void StartServiceInUtilityProcess(
} else {
// Start a new process for this service.
UtilityProcessHost* impl = new UtilityProcessHost(nullptr, nullptr);
+ base::string16 process_name = process_name_callback.Run();
+ DCHECK(!process_name.empty());
impl->SetName(process_name);
+ impl->SetMetricsName(service_name);
impl->SetServiceIdentity(service_manager::Identity(service_name));
impl->SetSandboxType(sandbox_type);
impl->Start();
@@ -155,16 +166,15 @@ void StartServiceInUtilityProcess(
// Determine a sandbox type for a service and launch a process for it.
void QueryAndStartServiceInUtilityProcess(
const std::string& service_name,
- const base::string16& process_name,
+ const ContentBrowserClient::ProcessNameCallback& process_name_callback,
base::Optional<std::string> process_group,
service_manager::mojom::ServiceRequest request,
service_manager::mojom::PIDReceiverPtr pid_receiver) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
ServiceManagerContext::GetConnectorForIOThread()->QueryService(
service_manager::Identity(service_name),
- base::BindOnce(&StartServiceInUtilityProcess, service_name, process_name,
- std::move(process_group), std::move(request),
- std::move(pid_receiver)));
+ base::BindOnce(&StartServiceInUtilityProcess, service_name,
+ process_name_callback, std::move(process_group),
+ std::move(request), std::move(pid_receiver)));
}
// Request service_manager::mojom::ServiceFactory from GPU process host. Must be
@@ -173,7 +183,6 @@ void StartServiceInGpuProcess(
const std::string& service_name,
service_manager::mojom::ServiceRequest request,
service_manager::mojom::PIDReceiverPtr pid_receiver) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
GpuProcessHost* process_host = GpuProcessHost::Get();
if (!process_host) {
DLOG(ERROR) << "GPU process host not available.";
@@ -247,8 +256,20 @@ class NullServiceProcessLauncherFactory
private:
std::unique_ptr<service_manager::ServiceProcessLauncher> Create(
const base::FilePath& service_path) override {
- LOG(ERROR) << "Attempting to run unsupported native service: "
- << service_path.value();
+ // There are innocuous races where browser code may attempt to connect
+ // to a specific renderer instance through the Service Manager after that
+ // renderer has been terminated. These result in this code path being hit
+ // fairly regularly and the resulting log spam causes confusion. We suppress
+ // this message only for "content_renderer".
+ const base::FilePath::StringType kRendererServiceFilename =
+ base::FilePath().AppendASCII(mojom::kRendererServiceName).value();
+ const base::FilePath::StringType service_executable =
+ service_path.BaseName().value();
+ if (service_executable.find(kRendererServiceFilename) ==
+ base::FilePath::StringType::npos) {
+ LOG(ERROR) << "Attempting to run unsupported native service: "
+ << service_path.value();
+ }
return nullptr;
}
@@ -274,15 +295,6 @@ class ServiceBinaryLauncherFactory
DISALLOW_COPY_AND_ASSIGN(ServiceBinaryLauncherFactory);
};
-// Helper to invoke GetGeolocationRequestContext on the currently-set
-// ContentBrowserClient.
-void GetGeolocationRequestContextFromContentClient(
- base::OnceCallback<void(scoped_refptr<net::URLRequestContextGetter>)>
- callback) {
- GetContentClient()->browser()->GetGeolocationRequestContext(
- std::move(callback));
-}
-
bool ShouldEnableVizService() {
#if defined(USE_AURA)
// aura::Env can be null in tests.
@@ -301,31 +313,49 @@ std::unique_ptr<service_manager::Service> CreateNetworkService() {
return std::make_unique<network::NetworkService>(std::move(registry));
}
+bool AudioServiceOutOfProcess() {
+ // Returns true iff kAudioServiceOutOfProcess feature is enabled and if the
+ // embedder does not provide its own in-process AudioManager.
+ return base::FeatureList::IsEnabled(features::kAudioServiceOutOfProcess) &&
+ !GetContentClient()->browser()->OverridesAudioManager();
+}
+
} // namespace
// State which lives on the IO thread and drives the ServiceManager.
class ServiceManagerContext::InProcessServiceManagerContext
: public base::RefCountedThreadSafe<InProcessServiceManagerContext> {
public:
- InProcessServiceManagerContext() {}
+ InProcessServiceManagerContext(scoped_refptr<base::SingleThreadTaskRunner>
+ service_manager_thread_task_runner)
+ : service_manager_thread_task_runner_(
+ service_manager_thread_task_runner) {}
void Start(
service_manager::mojom::ServicePtrInfo packaged_services_service_info,
std::unique_ptr<BuiltinManifestProvider> manifest_provider) {
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)
- ->PostTask(
- FROM_HERE,
- base::BindOnce(&InProcessServiceManagerContext::StartOnIOThread,
- this, std::move(manifest_provider),
- std::move(packaged_services_service_info)));
+ service_manager_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &InProcessServiceManagerContext::StartOnServiceManagerThread, this,
+ std::move(manifest_provider),
+ std::move(packaged_services_service_info),
+ base::ThreadTaskRunnerHandle::Get()));
}
void ShutDown() {
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)
- ->PostTask(
- FROM_HERE,
- base::BindOnce(&InProcessServiceManagerContext::ShutDownOnIOThread,
- this));
+ service_manager_thread_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &InProcessServiceManagerContext::ShutDownOnServiceManagerThread,
+ this));
+ }
+
+ void StartServices(std::vector<service_manager::Identity> identities) {
+ service_manager_thread_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&InProcessServiceManagerContext ::
+ StartServicesOnServiceManagerThread,
+ this, std::move(identities)));
}
private:
@@ -333,9 +363,10 @@ class ServiceManagerContext::InProcessServiceManagerContext
~InProcessServiceManagerContext() {}
- void StartOnIOThread(
+ void StartOnServiceManagerThread(
std::unique_ptr<BuiltinManifestProvider> manifest_provider,
- service_manager::mojom::ServicePtrInfo packaged_services_service_info) {
+ service_manager::mojom::ServicePtrInfo packaged_services_service_info,
+ scoped_refptr<base::SequencedTaskRunner> ui_thread_task_runner) {
manifest_provider_ = std::move(manifest_provider);
std::unique_ptr<service_manager::ServiceProcessLauncherFactory>
service_process_launcher_factory;
@@ -358,12 +389,15 @@ class ServiceManagerContext::InProcessServiceManagerContext
service_manager::mojom::kRootUserID),
std::move(packaged_services_service), nullptr);
service_manager_->SetInstanceQuitCallback(
- base::Bind(&OnInstanceQuitOnIOThread));
+ base::Bind(&OnInstanceQuitOnServiceManagerThread,
+ std::move(ui_thread_task_runner)));
}
- static void OnInstanceQuitOnIOThread(const service_manager::Identity& id) {
- BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)
- ->PostTask(FROM_HERE, base::BindOnce(&OnInstanceQuit, id));
+ static void OnInstanceQuitOnServiceManagerThread(
+ scoped_refptr<base::SequencedTaskRunner> ui_thread_task_runner,
+ const service_manager::Identity& id) {
+ ui_thread_task_runner->PostTask(FROM_HERE,
+ base::BindOnce(&OnInstanceQuit, id));
}
static void OnInstanceQuit(const service_manager::Identity& id) {
@@ -377,25 +411,43 @@ class ServiceManagerContext::InProcessServiceManagerContext
}
}
- void ShutDownOnIOThread() {
+ void ShutDownOnServiceManagerThread() {
service_manager_.reset();
manifest_provider_.reset();
}
+ void StartServicesOnServiceManagerThread(
+ std::vector<service_manager::Identity> identities) {
+ if (!service_manager_)
+ return;
+
+ for (const auto& identity : identities)
+ service_manager_->StartService(identity);
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner>
+ service_manager_thread_task_runner_;
std::unique_ptr<BuiltinManifestProvider> manifest_provider_;
std::unique_ptr<service_manager::ServiceManager> service_manager_;
DISALLOW_COPY_AND_ASSIGN(InProcessServiceManagerContext);
};
-ServiceManagerContext::ServiceManagerContext() {
+ServiceManagerContext::ServiceManagerContext(
+ scoped_refptr<base::SingleThreadTaskRunner>
+ service_manager_thread_task_runner)
+ : service_manager_thread_task_runner_(
+ std::move(service_manager_thread_task_runner)) {
+ // The |service_manager_thread_task_runner_| must have been created before
+ // starting the ServiceManager.
+ DCHECK(service_manager_thread_task_runner_);
service_manager::mojom::ServiceRequest packaged_services_request;
if (service_manager::ServiceManagerIsRemote()) {
- auto invitation =
- mojo::edk::IncomingBrokerClientInvitation::AcceptFromCommandLine(
- mojo::edk::TransportProtocol::kLegacy);
+ auto endpoint = mojo::PlatformChannel::RecoverPassedEndpointFromCommandLine(
+ *base::CommandLine::ForCurrentProcess());
+ auto invitation = mojo::IncomingInvitation::Accept(std::move(endpoint));
packaged_services_request =
- service_manager::GetServiceRequestFromCommandLine(invitation.get());
+ service_manager::GetServiceRequestFromCommandLine(&invitation);
} else {
std::unique_ptr<BuiltinManifestProvider> manifest_provider =
std::make_unique<BuiltinManifestProvider>();
@@ -423,7 +475,8 @@ ServiceManagerContext::ServiceManagerContext() {
manifest_provider->AddServiceManifest(manifest.name,
manifest.resource_id);
}
- in_process_context_ = new InProcessServiceManagerContext;
+ in_process_context_ =
+ new InProcessServiceManagerContext(service_manager_thread_task_runner_);
service_manager::mojom::ServicePtr packaged_services_service;
packaged_services_request = mojo::MakeRequest(&packaged_services_service);
@@ -431,14 +484,14 @@ ServiceManagerContext::ServiceManagerContext() {
std::move(manifest_provider));
}
- packaged_services_connection_ = ServiceManagerConnection::Create(
- std::move(packaged_services_request),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO));
+ packaged_services_connection_ =
+ ServiceManagerConnection::Create(std::move(packaged_services_request),
+ service_manager_thread_task_runner_);
service_manager::mojom::ServicePtr root_browser_service;
- ServiceManagerConnection::SetForProcess(ServiceManagerConnection::Create(
- mojo::MakeRequest(&root_browser_service),
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)));
+ ServiceManagerConnection::SetForProcess(
+ ServiceManagerConnection::Create(mojo::MakeRequest(&root_browser_service),
+ service_manager_thread_task_runner_));
auto* browser_connection = ServiceManagerConnection::GetForProcess();
service_manager::mojom::PIDReceiverPtr pid_receiver;
@@ -467,9 +520,10 @@ ServiceManagerContext::ServiceManagerContext() {
// ContentNfcDelegate.java respectively for comments on those parameters.
device_info.factory = base::Bind(
&device::CreateDeviceService, device_blocking_task_runner,
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
- base::BindRepeating(&GetGeolocationRequestContextFromContentClient),
+ service_manager_thread_task_runner_,
+ GetContentClient()->browser()->GetSystemSharedURLLoaderFactory(),
GetContentClient()->browser()->GetGeolocationApiKey(),
+ GetContentClient()->browser()->ShouldUseGmsCoreGeolocationProvider(),
base::Bind(&WakeLockContextHost::GetNativeViewForContext),
base::Bind(&ContentBrowserClient::OverrideSystemLocationProvider,
base::Unretained(GetContentClient()->browser())),
@@ -477,8 +531,8 @@ ServiceManagerContext::ServiceManagerContext() {
#else
device_info.factory = base::Bind(
&device::CreateDeviceService, device_blocking_task_runner,
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
- base::BindRepeating(&GetGeolocationRequestContextFromContentClient),
+ service_manager_thread_task_runner_,
+ GetContentClient()->browser()->GetSystemSharedURLLoaderFactory(),
GetContentClient()->browser()->GetGeolocationApiKey(),
base::Bind(&ContentBrowserClient::OverrideSystemLocationProvider,
base::Unretained(GetContentClient()->browser())));
@@ -512,7 +566,9 @@ ServiceManagerContext::ServiceManagerContext() {
#else
base::CreateSingleThreadTaskRunnerWithTraits(
#endif
- base::TaskTraits(base::MayBlock(), base::TaskPriority::BACKGROUND));
+ base::TaskTraits({base::MayBlock(), base::WithBaseSyncPrimitives(),
+ base::TaskPriority::BACKGROUND}),
+ base::SingleThreadTaskRunnerThreadMode::DEDICATED);
packaged_services_connection_->AddEmbeddedService(
video_capture::mojom::kServiceName, video_capture_info);
}
@@ -542,7 +598,20 @@ ServiceManagerContext::ServiceManagerContext() {
&out_of_process_services);
out_of_process_services[data_decoder::mojom::kServiceName] =
- base::ASCIIToUTF16("Data Decoder Service");
+ base::BindRepeating(&base::ASCIIToUTF16, "Data Decoder Service");
+
+#if defined(OS_LINUX)
+ {
+ service_manager::EmbeddedServiceInfo font_service_info;
+ font_service_info.factory =
+ base::BindRepeating(font_service::FontServiceApp::CreateService);
+ font_service_info.task_runner = base::CreateSequencedTaskRunnerWithTraits(
+ base::TaskTraits({base::MayBlock(), base::WithBaseSyncPrimitives(),
+ base::TaskPriority::USER_BLOCKING}));
+ packaged_services_connection_->AddEmbeddedService(
+ font_service::mojom::kServiceName, font_service_info);
+ }
+#endif
bool network_service_enabled =
base::FeatureList::IsEnabled(network::features::kNetworkService);
@@ -554,65 +623,59 @@ ServiceManagerContext::ServiceManagerContext() {
if (network_service_in_process) {
service_manager::EmbeddedServiceInfo network_service_info;
network_service_info.factory = base::BindRepeating(CreateNetworkService);
- network_service_info.task_runner =
- BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+ network_service_info.task_runner = service_manager_thread_task_runner_;
packaged_services_connection_->AddEmbeddedService(
mojom::kNetworkServiceName, network_service_info);
} else {
out_of_process_services[mojom::kNetworkServiceName] =
- base::ASCIIToUTF16("Network Service");
+ base::BindRepeating(&base::ASCIIToUTF16, "Network Service");
}
- } else {
- // Create the in-process NetworkService object so that its getter is
- // available on the IO thread.
- GetNetworkService();
}
- if (BrowserMainLoop* bml = BrowserMainLoop::GetInstance()) {
- if (bml->AudioServiceOutOfProcess()) {
- DCHECK(base::FeatureList::IsEnabled(features::kAudioServiceAudioStreams));
- out_of_process_services[audio::mojom::kServiceName] =
- base::ASCIIToUTF16("Audio Service");
- } else {
- service_manager::EmbeddedServiceInfo info;
- info.factory = base::BindRepeating(
- [](BrowserMainLoop* bml)
- -> std::unique_ptr<service_manager::Service> {
- return audio::CreateEmbeddedService(bml->audio_manager());
- },
- bml);
- info.task_runner = bml->audio_service_runner();
- DCHECK(info.task_runner);
- packaged_services_connection_->AddEmbeddedService(
- audio::mojom::kServiceName, info);
- }
+ if (AudioServiceOutOfProcess()) {
+ DCHECK(base::FeatureList::IsEnabled(features::kAudioServiceAudioStreams));
+ out_of_process_services[audio::mojom::kServiceName] =
+ base::BindRepeating(&base::ASCIIToUTF16, "Audio Service");
+ } else {
+ service_manager::EmbeddedServiceInfo info;
+ // TODO(hanxi): Removes BrowserMainLoop::GetAudioManager().
+ // https://crbug.com/853254.
+ info.factory =
+ base::BindRepeating([]() -> std::unique_ptr<service_manager::Service> {
+ return audio::CreateEmbeddedService(
+ BrowserMainLoop::GetAudioManager());
+ });
+ info.task_runner = GetAudioServiceRunner();
+ DCHECK(info.task_runner);
+ packaged_services_connection_->AddEmbeddedService(
+ audio::mojom::kServiceName, info);
}
if (features::IsVideoCaptureServiceEnabledForOutOfProcess()) {
out_of_process_services[video_capture::mojom::kServiceName] =
- base::ASCIIToUTF16("Video Capture Service");
+ base::BindRepeating(&base::ASCIIToUTF16, "Video Capture Service");
}
#if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_UTILITY_PROCESS)
out_of_process_services[media::mojom::kMediaServiceName] =
- base::ASCIIToUTF16("Media Service");
+ base::BindRepeating(&base::ASCIIToUTF16, "Media Service");
#endif
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
- out_of_process_services[media::mojom::kCdmServiceName] =
- base::ASCIIToUTF16("Content Decryption Module Service");
+ out_of_process_services[media::mojom::kCdmServiceName] = base::BindRepeating(
+ &base::ASCIIToUTF16, "Content Decryption Module Service");
#endif
if (ShouldEnableVizService()) {
out_of_process_services[viz::mojom::kVizServiceName] =
- base::ASCIIToUTF16("Visuals Service");
+ base::BindRepeating(&base::ASCIIToUTF16, "Visuals Service");
}
for (const auto& service : out_of_process_services) {
packaged_services_connection_->AddServiceRequestHandlerWithPID(
service.first,
base::BindRepeating(&QueryAndStartServiceInUtilityProcess,
- service.first, service.second.process_name,
+ service.first, service.second.process_name_callback,
service.second.process_group));
}
@@ -629,15 +692,8 @@ ServiceManagerContext::ServiceManagerContext() {
packaged_services_connection_->Start();
- RegisterCommonBrowserInterfaces(browser_connection);
- browser_connection->Start();
-
- if (network_service_enabled && !network_service_in_process) {
- // Start the network service process as soon as possible, since it is
- // critical to start up performance.
- browser_connection->GetConnector()->StartService(
- mojom::kNetworkServiceName);
- }
+ in_process_context_->StartServices(
+ GetContentClient()->browser()->GetStartupServices());
}
ServiceManagerContext::~ServiceManagerContext() {
@@ -649,8 +705,8 @@ ServiceManagerContext::~ServiceManagerContext() {
in_process_context_->ShutDown();
if (ServiceManagerConnection::GetForProcess())
ServiceManagerConnection::DestroyForProcess();
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::BindOnce(&DestroyConnectorOnIOThread));
+ service_manager_thread_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&DestroyConnectorOnIOThread));
}
// static
@@ -668,4 +724,36 @@ bool ServiceManagerContext::HasValidProcessForProcessGroup(
return iter->second->GetData().handle != base::kNullProcessHandle;
}
+// static
+void ServiceManagerContext::StartBrowserConnection() {
+ auto* browser_connection = ServiceManagerConnection::GetForProcess();
+ RegisterCommonBrowserInterfaces(browser_connection);
+ browser_connection->Start();
+
+ bool network_service_enabled =
+ base::FeatureList::IsEnabled(network::features::kNetworkService);
+ bool network_service_in_process =
+ base::FeatureList::IsEnabled(features::kNetworkServiceInProcess) ||
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kSingleProcess);
+ if (!network_service_enabled) {
+ // Create the in-process NetworkService object so that its getter is
+ // available on the IO thread.
+ GetNetworkService();
+ } else if (!network_service_in_process) {
+ // Start the network service process as soon as possible, since it is
+ // critical to start up performance.
+ browser_connection->GetConnector()->StartService(
+ mojom::kNetworkServiceName);
+ }
+}
+
+// static
+base::DeferredSequencedTaskRunner*
+ServiceManagerContext::GetAudioServiceRunner() {
+ static base::NoDestructor<scoped_refptr<base::DeferredSequencedTaskRunner>>
+ instance(new base::DeferredSequencedTaskRunner);
+ return (*instance).get();
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_manager/service_manager_context.h b/chromium/content/browser/service_manager/service_manager_context.h
index b31926acae7..eebd74a0c5e 100644
--- a/chromium/content/browser/service_manager/service_manager_context.h
+++ b/chromium/content/browser/service_manager/service_manager_context.h
@@ -11,8 +11,13 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "content/common/content_export.h"
+namespace base {
+class DeferredSequencedTaskRunner;
+}
+
namespace service_manager {
class Connector;
}
@@ -26,7 +31,9 @@ class ServiceManagerConnection;
// launched from an external one.
class CONTENT_EXPORT ServiceManagerContext {
public:
- ServiceManagerContext();
+ explicit ServiceManagerContext(scoped_refptr<base::SingleThreadTaskRunner>
+ service_manager_thread_task_runner);
+
~ServiceManagerContext();
// Returns a service_manager::Connector that can be used on the IO thread.
@@ -37,9 +44,17 @@ class CONTENT_EXPORT ServiceManagerContext {
static bool HasValidProcessForProcessGroup(
const std::string& process_group_name);
+ // Starts the browser connction to the ServiceManager. It must be called after
+ // the BrowserMainLoop starts.
+ static void StartBrowserConnection();
+
+ static base::DeferredSequencedTaskRunner* GetAudioServiceRunner();
+
private:
class InProcessServiceManagerContext;
+ scoped_refptr<base::SingleThreadTaskRunner>
+ service_manager_thread_task_runner_;
scoped_refptr<InProcessServiceManagerContext> in_process_context_;
std::unique_ptr<ServiceManagerConnection> packaged_services_connection_;
diff --git a/chromium/content/browser/service_worker/OWNERS b/chromium/content/browser/service_worker/OWNERS
index a0d918100a0..f7f81753511 100644
--- a/chromium/content/browser/service_worker/OWNERS
+++ b/chromium/content/browser/service_worker/OWNERS
@@ -5,11 +5,13 @@
# //content/browser/resources/service_worker/
# //content/common/service_worker/
# //content/renderer/service_worker/
+# //third_party/blink/common/service_worker/
+# //third_party/blink/public/common/service_worker/
# //third_party/blink/public/mojom/service_worker/
-# //third_party/blink/public/web/modules/serviceworker/
-# //third_party/blink/public/platform/modules/serviceworker/
+# //third_party/blink/public/platform/modules/service_worker/
+# //third_party/blink/public/web/modules/service_worker/
# //third_party/WebKit/LayoutTests/external/wpt/service-workers/
-# //third_party/blink/renderer/modules/serviceworkers/
+# //third_party/blink/renderer/modules/service_worker/
falken@chromium.org
horo@chromium.org
diff --git a/chromium/content/browser/service_worker/README.md b/chromium/content/browser/service_worker/README.md
new file mode 100644
index 00000000000..55d7fb79b43
--- /dev/null
+++ b/chromium/content/browser/service_worker/README.md
@@ -0,0 +1,44 @@
+# Service workers
+[content/browser/service_worker]: /content/browser/service_worker
+[content/renderer/service_worker]: /content/renderer/service_worker
+[content/renderer/service_worker]: /content/renderer/service_worker
+[content/common/service_worker]: /content/common/service_worker
+[third_party/blink/common/service_worker]: /third_party/blink/common/service_worker
+[third_party/blink/public/common/service_worker]: /third_party/blink/public/common/service_worker
+[third_party/blink/public/mojom/service_worker]: /third_party/blink/public/mojom/service_worker
+[third_party/blink/public/platform/modules/service_worker]: /third_party/blink/public/platform/modules/service_worker
+[third_party/blink/public/web/modules/service_worker]: /third_party/blink/public/web/modules/service_worker
+[third_party/blink/renderer/modules/service_worker]: /third_party/blink/renderer/modules/service_worker
+[Blink Public API]: /third_party/blink/public
+[Onion Soup]: https://docs.google.com/document/d/1K1nO8G9dO9kNSmtVz2gJ2GG9gQOTgm65sJlV3Fga4jE/edit?usp=sharing
+
+This is Chromium's implementation of [service
+workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API). See the
+[Service Worker specification](https://w3c.github.io/ServiceWorker/).
+
+## Directory structure
+
+- [content/browser/service_worker]: Browser process code, including stored
+ registration data, the inception of starting a service worker, and controlling
+ navigations. The browser process has host objects of most live renderer
+ entities that deal with service workers, and the bulk of work is performed by
+ these host objects.
+- [content/renderer/service_worker]: Renderer process code. This should move to
+ third_party/blink per [Onion Soup].
+- [content/common/service_worker]: Common process code.
+- [third_party/blink/common/service_worker]: Common process code. Contains the
+ implementation of third_party/blink/public/common/service_worker.
+- [third_party/blink/public/common/service_worker]: Header files for common
+ process code that can be used by both inside Blink and outside Blink.
+- [third_party/blink/public/mojom/service_worker]: Mojom files for common
+ process code that can be used by both Blink and content.
+- [third_party/blink/public/platform/modules/service_worker]: [Blink Public API]
+ header files. This should be removed per [Onion Soup].
+- [third_party/blink/public/web/modules/service_worker]: More [Blink Public API]
+ header files. This should be removed per [Onion Soup].
+- [third_party/blink/renderer/modules/service_worker]: Renderer process code in
+ Blink. This is the closest code to the web-exposed Service Worker API.
+
+## Other documentation
+
+- [Service Worker Security FAQ](/docs/security/service-worker-security-faq.md)
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance.cc b/chromium/content/browser/service_worker/embedded_worker_instance.cc
index eef43481a14..7e3365820e3 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_instance.cc
@@ -13,6 +13,7 @@
#include "base/trace_event/trace_event.h"
#include "content/browser/bad_message.h"
#include "content/browser/devtools/service_worker_devtools_manager.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
#include "content/browser/service_worker/embedded_worker_status.h"
#include "content/browser/service_worker/service_worker_content_settings_proxy_impl.h"
@@ -21,18 +22,17 @@
#include "content/common/content_switches_internal.h"
#include "content/common/renderer.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/common/service_worker/service_worker_utils.h"
#include "content/common/url_loader_factory_bundle.mojom.h"
#include "content/common/url_schemes.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/render_process_host.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_message.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/web/web_console_message.h"
#include "url/gurl.h"
@@ -79,7 +79,7 @@ void NotifyWorkerVersionDoomedOnUI(int worker_process_id, int worker_route_id) {
}
using SetupProcessCallback = base::OnceCallback<void(
- ServiceWorkerStatusCode,
+ blink::ServiceWorkerStatusCode,
mojom::EmbeddedWorkerStartParamsPtr,
std::unique_ptr<ServiceWorkerProcessManager::AllocatedProcessInfo>,
std::unique_ptr<EmbeddedWorkerInstance::DevToolsProxy>,
@@ -106,7 +106,8 @@ void SetupOnUIThread(base::WeakPtr<ServiceWorkerProcessManager> process_manager,
if (!process_manager) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT,
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort,
std::move(params), std::move(process_info),
std::move(devtools_proxy), std::move(factory_bundle),
nullptr /* cache_storage */));
@@ -114,10 +115,11 @@ void SetupOnUIThread(base::WeakPtr<ServiceWorkerProcessManager> process_manager,
}
// Get a process.
- ServiceWorkerStatusCode status = process_manager->AllocateWorkerProcess(
- params->embedded_worker_id, params->scope, params->script_url,
- can_use_existing_process, process_info.get());
- if (status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode status =
+ process_manager->AllocateWorkerProcess(
+ params->embedded_worker_id, params->scope, params->script_url,
+ can_use_existing_process, process_info.get());
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(std::move(callback), status, std::move(params),
@@ -128,7 +130,8 @@ void SetupOnUIThread(base::WeakPtr<ServiceWorkerProcessManager> process_manager,
const int process_id = process_info->process_id;
RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
// TODO(falken): This CHECK should no longer fail, so turn to a DCHECK it if
- // crash reports agree. Consider also checking for rph->HasConnection().
+ // crash reports agree. Consider also checking for
+ // rph->IsInitializedAndNotDead().
CHECK(rph);
// Create cache storage now as an optimization, so the service worker can use
@@ -153,11 +156,24 @@ void SetupOnUIThread(base::WeakPtr<ServiceWorkerProcessManager> process_manager,
}
// S13nServiceWorker:
+ // Create a default loader for network fallback.
+ // The factory from RPH::CreateURLLoaderFactory() doesn't support
+ // reconnection to the network service after a crash, but it's probably OK
+ // since it's used for a single service worker startup until installation
+ // finishes (with the exception of https://crbug.com/719052).
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ network::mojom::URLLoaderFactoryPtrInfo default_factory_info;
+ rph->CreateURLLoaderFactory(mojo::MakeRequest(&default_factory_info));
+ factory_bundle = std::make_unique<URLLoaderFactoryBundleInfo>();
+ factory_bundle->default_factory_info() = std::move(default_factory_info);
+ }
+
+ // S13nServiceWorker:
// Create the loader factories for non-http(s) URLs, for example
// chrome-extension:// URLs. For performance, only do this step when the main
// script URL is non-http(s). We assume an http(s) service worker cannot
// importScripts a non-http(s) URL.
- if (ServiceWorkerUtils::IsServicificationEnabled() &&
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled() &&
!params->script_url.SchemeIsHTTPOrHTTPS()) {
ContentBrowserClient::NonNetworkURLLoaderFactoryMap factories;
GetContentClient()
@@ -165,7 +181,6 @@ void SetupOnUIThread(base::WeakPtr<ServiceWorkerProcessManager> process_manager,
->RegisterNonNetworkSubresourceURLLoaderFactories(
rph->GetID(), MSG_ROUTING_NONE, &factories);
- factory_bundle = std::make_unique<URLLoaderFactoryBundleInfo>();
for (auto& pair : factories) {
const std::string& scheme = pair.first;
std::unique_ptr<network::mojom::URLLoaderFactory> factory =
@@ -198,13 +213,10 @@ void SetupOnUIThread(base::WeakPtr<ServiceWorkerProcessManager> process_manager,
devtools_proxy = std::make_unique<EmbeddedWorkerInstance::DevToolsProxy>(
process_id, routing_id);
- // Set EmbeddedWorkerSettings for content settings only readable from the UI
- // thread.
- // TODO(bengr): Support changes to the data saver setting while the worker is
- // running.
- params->data_saver_enabled =
- GetContentClient()->browser()->IsDataSaverEnabled(
- process_manager->browser_context());
+ // TODO(crbug.com/862854): Support changes to RendererPreferences while the
+ // worker is running.
+ GetContentClient()->browser()->UpdateRendererPreferencesForWorker(
+ process_manager->browser_context(), &params->renderer_preferences);
// Continue to OnSetupCompleted on the IO thread.
BrowserThread::PostTask(
@@ -225,8 +237,7 @@ bool HasSentStartWorker(EmbeddedWorkerInstance::StartingPhase phase) {
case EmbeddedWorkerInstance::SCRIPT_READ_FINISHED:
case EmbeddedWorkerInstance::SCRIPT_STREAMING:
case EmbeddedWorkerInstance::SCRIPT_LOADED:
- case EmbeddedWorkerInstance::SCRIPT_EVALUATED:
- case EmbeddedWorkerInstance::THREAD_STARTED:
+ case EmbeddedWorkerInstance::SCRIPT_EVALUATION:
return true;
case EmbeddedWorkerInstance::STARTING_PHASE_MAX_VALUE:
NOTREACHED();
@@ -337,12 +348,15 @@ class EmbeddedWorkerInstance::StartTask {
StartTask(EmbeddedWorkerInstance* instance,
const GURL& script_url,
- mojom::EmbeddedWorkerInstanceClientRequest request)
+ mojom::EmbeddedWorkerInstanceClientRequest request,
+ base::TimeTicks start_time)
: instance_(instance),
request_(std::move(request)),
state_(ProcessAllocationState::NOT_ALLOCATED),
is_installed_(false),
started_during_browser_startup_(false),
+ skip_recording_startup_time_(instance_->devtools_attached()),
+ start_time_(start_time),
weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("ServiceWorker",
@@ -352,6 +366,11 @@ class EmbeddedWorkerInstance::StartTask {
~StartTask() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (did_send_start_) {
+ TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker",
+ "INITIALIZING_ON_RENDERER", this);
+ }
+
TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker",
"EmbeddedWorkerInstance::Start", this);
@@ -375,7 +394,7 @@ class EmbeddedWorkerInstance::StartTask {
break;
}
- // Don't have to abort |start_callback_| here. The caller of
+ // Don't have to abort |sent_start_callback_| here. The caller of
// EmbeddedWorkerInstance::Start(), that is, ServiceWorkerVersion does not
// expect it when the start worker sequence is canceled by Stop() because
// the callback, ServiceWorkerVersion::OnStartSentAndScriptEvaluated(),
@@ -383,9 +402,11 @@ class EmbeddedWorkerInstance::StartTask {
// is stopped, the version attempts to restart the worker if there are
// requests in the queue. See ServiceWorkerVersion::OnStoppedInternal() for
// details.
- // TODO(nhiroki): Reconsider this bizarre layering.
+ // TODO(crbug.com/859912): Reconsider this bizarre layering.
}
+ base::TimeTicks start_time() const { return start_time_; }
+
void set_start_worker_sent_time(base::TimeTicks time) {
start_worker_sent_time_ = time;
}
@@ -393,24 +414,31 @@ class EmbeddedWorkerInstance::StartTask {
return start_worker_sent_time_;
}
+ void set_skip_recording_startup_time() {
+ skip_recording_startup_time_ = true;
+ }
+ bool skip_recording_startup_time() const {
+ return skip_recording_startup_time_;
+ }
+
void Start(mojom::EmbeddedWorkerStartParamsPtr params,
- StatusCallback callback) {
+ StatusCallback sent_start_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(instance_->context_);
+ base::WeakPtr<ServiceWorkerContextCore> context = instance_->context_;
state_ = ProcessAllocationState::ALLOCATING;
- start_callback_ = std::move(callback);
+ sent_start_callback_ = std::move(sent_start_callback);
is_installed_ = params->is_installed;
if (!GetContentClient()->browser()->IsBrowserStartupComplete())
started_during_browser_startup_ = true;
bool can_use_existing_process =
- instance_->context_->GetVersionFailureCount(
- params->service_worker_version_id) < kMaxSameProcessFailureCount;
+ context->GetVersionFailureCount(params->service_worker_version_id) <
+ kMaxSameProcessFailureCount;
DCHECK_EQ(params->embedded_worker_id, instance_->embedded_worker_id_);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "ALLOCATING_PROCESS",
this);
- base::WeakPtr<ServiceWorkerContextCore> context = instance_->context_;
base::WeakPtr<ServiceWorkerProcessManager> process_manager =
context->process_manager()->AsWeakPtr();
@@ -425,24 +453,12 @@ class EmbeddedWorkerInstance::StartTask {
weak_factory_.GetWeakPtr(), process_manager)));
}
- static void RunStartCallback(StartTask* task,
- ServiceWorkerStatusCode status) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker", "INITIALIZING_ON_RENDERER",
- task, "Status",
- ServiceWorkerStatusToString(status));
- StatusCallback callback = std::move(task->start_callback_);
- task->start_callback_.Reset();
- std::move(callback).Run(status);
- // |task| may be destroyed.
- }
-
bool is_installed() const { return is_installed_; }
private:
void OnSetupCompleted(
base::WeakPtr<ServiceWorkerProcessManager> process_manager,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
mojom::EmbeddedWorkerStartParamsPtr params,
std::unique_ptr<ServiceWorkerProcessManager::AllocatedProcessInfo>
process_info,
@@ -452,7 +468,7 @@ class EmbeddedWorkerInstance::StartTask {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::unique_ptr<WorkerProcessHandle> process_handle;
- if (status == SERVICE_WORKER_OK) {
+ if (status == blink::ServiceWorkerStatusCode::kOk) {
// If we allocated a process, WorkerProcessHandle has to be created before
// returning to ensure the process is eventually released.
process_handle = std::make_unique<WorkerProcessHandle>(
@@ -460,16 +476,14 @@ class EmbeddedWorkerInstance::StartTask {
process_info->process_id);
if (!instance_->context_)
- status = SERVICE_WORKER_ERROR_ABORT;
+ status = blink::ServiceWorkerStatusCode::kErrorAbort;
}
- if (status != SERVICE_WORKER_OK) {
- TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker", "ALLOCATING_PROCESS",
- this, "Error",
- ServiceWorkerStatusToString(status));
- StatusCallback callback = std::move(start_callback_);
- start_callback_.Reset();
- instance_->OnStartFailed(std::move(callback), status);
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
+ TRACE_EVENT_NESTABLE_ASYNC_END1(
+ "ServiceWorker", "ALLOCATING_PROCESS", this, "Error",
+ blink::ServiceWorkerStatusToString(status));
+ instance_->OnSetupFailed(std::move(sent_start_callback_), status);
// |this| may be destroyed.
return;
}
@@ -497,32 +511,20 @@ class EmbeddedWorkerInstance::StartTask {
// S13nServiceWorker: Build the URLLoaderFactory for loading new scripts.
scoped_refptr<network::SharedURLLoaderFactory> factory_for_new_scripts;
- if (ServiceWorkerUtils::IsServicificationEnabled()) {
- if (factory_bundle) {
- network::mojom::URLLoaderFactoryPtr network_factory_ptr;
- // The factory from CloneNetworkFactory() doesn't support reconnection
- // to the network service after a crash, but it's probably OK since it's
- // used for a single service worker startup until installation finishes
- // (with the exception of https://crbug.com/719052).
- instance_->context_->loader_factory_getter()->CloneNetworkFactory(
- mojo::MakeRequest(&network_factory_ptr));
- scoped_refptr<URLLoaderFactoryBundle> factory =
- base::MakeRefCounted<URLLoaderFactoryBundle>(
- std::move(factory_bundle));
- factory->SetDefaultFactory(std::move(network_factory_ptr));
- factory_for_new_scripts = std::move(factory);
- } else {
- factory_for_new_scripts =
- instance_->context_->loader_factory_getter()->GetNetworkFactory();
- }
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ DCHECK(factory_bundle);
+ factory_for_new_scripts = base::MakeRefCounted<URLLoaderFactoryBundle>(
+ std::move(factory_bundle));
}
instance_->SendStartWorker(std::move(params),
std::move(factory_for_new_scripts),
std::move(cache_storage));
+ std::move(sent_start_callback_).Run(blink::ServiceWorkerStatusCode::kOk);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker",
"INITIALIZING_ON_RENDERER", this);
+ did_send_start_ = true;
// |this|'s work is done here, but |instance_| still uses its state until
// startup is complete.
}
@@ -533,12 +535,15 @@ class EmbeddedWorkerInstance::StartTask {
// Ownership is transferred by a PostTask() call after process allocation.
mojom::EmbeddedWorkerInstanceClientRequest request_;
- StatusCallback start_callback_;
+ StatusCallback sent_start_callback_;
+ bool did_send_start_ = false;
ProcessAllocationState state_;
// Used for UMA.
bool is_installed_;
bool started_during_browser_startup_;
+ bool skip_recording_startup_time_;
+ base::TimeTicks start_time_;
base::TimeTicks start_worker_sent_time_;
base::WeakPtrFactory<StartTask> weak_factory_;
@@ -551,8 +556,6 @@ EmbeddedWorkerInstance::~EmbeddedWorkerInstance() {
DCHECK(status_ == EmbeddedWorkerStatus::STOPPING ||
status_ == EmbeddedWorkerStatus::STOPPED)
<< static_cast<int>(status_);
- for (auto& observer : listener_list_)
- observer.OnDestroyed();
devtools_proxy_.reset();
if (registry_->GetWorker(embedded_worker_id_))
registry_->RemoveWorker(process_id(), embedded_worker_id_);
@@ -560,25 +563,19 @@ EmbeddedWorkerInstance::~EmbeddedWorkerInstance() {
}
void EmbeddedWorkerInstance::Start(mojom::EmbeddedWorkerStartParamsPtr params,
- ProviderInfoGetter provider_info_getter,
StatusCallback callback) {
+ DCHECK(context_);
restart_count_++;
- if (!context_) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT);
- // |this| may be destroyed by the callback.
- return;
- }
DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, status_);
DCHECK(!params->pause_after_download || !params->is_installed);
DCHECK_NE(blink::mojom::kInvalidServiceWorkerVersionId,
params->service_worker_version_id);
- step_time_ = base::TimeTicks::Now();
+ auto start_time = base::TimeTicks::Now();
status_ = EmbeddedWorkerStatus::STARTING;
starting_phase_ = ALLOCATING_PROCESS;
network_accessed_for_script_ = false;
- provider_info_getter_ = std::move(provider_info_getter);
for (auto& observer : listener_list_)
observer.OnStarting();
@@ -593,7 +590,7 @@ void EmbeddedWorkerInstance::Start(mojom::EmbeddedWorkerStartParamsPtr params,
client_.set_connection_error_handler(
base::BindOnce(&EmbeddedWorkerInstance::Detach, base::Unretained(this)));
inflight_start_task_.reset(
- new StartTask(this, params->script_url, std::move(request)));
+ new StartTask(this, params->script_url, std::move(request), start_time));
inflight_start_task_->Start(std::move(params), std::move(callback));
}
@@ -684,11 +681,8 @@ void EmbeddedWorkerInstance::OnRegisteredToDevToolsManager(
DCHECK(!devtools_proxy_);
devtools_proxy_ = std::move(devtools_proxy);
}
- if (wait_for_debugger) {
- // We don't measure the start time when wait_for_debugger flag is set. So
- // we set the NULL time here.
- step_time_ = base::TimeTicks();
- }
+ if (wait_for_debugger)
+ inflight_start_task_->set_skip_recording_startup_time();
for (auto& observer : listener_list_)
observer.OnRegisteredToDevToolsManager();
}
@@ -698,7 +692,7 @@ void EmbeddedWorkerInstance::SendStartWorker(
scoped_refptr<network::SharedURLLoaderFactory> factory,
blink::mojom::CacheStoragePtrInfo cache_storage) {
DCHECK(context_);
- DCHECK(params->dispatcher_request.is_pending());
+ DCHECK(params->service_worker_request.is_pending());
DCHECK(params->controller_request.is_pending());
DCHECK(!instance_host_binding_.is_bound());
instance_host_binding_.Bind(mojo::MakeRequest(&params->instance_host));
@@ -710,27 +704,24 @@ void EmbeddedWorkerInstance::SendStartWorker(
const bool is_script_streaming = !params->installed_scripts_info.is_null();
inflight_start_task_->set_start_worker_sent_time(base::TimeTicks::Now());
+
+ // The host must be alive as long as |params->provider_info| is alive.
+ DCHECK(owner_version_->provider_host());
params->provider_info =
- std::move(provider_info_getter_).Run(process_id(), std::move(factory));
+ owner_version_->provider_host()->CompleteStartWorkerPreparation(
+ process_id(), std::move(factory), std::move(params->provider_info));
params->provider_info->cache_storage = std::move(cache_storage);
+
client_->StartWorker(std::move(params));
registry_->BindWorkerToProcess(process_id(), embedded_worker_id());
- if (!step_time_.is_null()) {
- base::TimeDelta duration = UpdateStepTime();
- if (inflight_start_task_->is_installed()) {
- ServiceWorkerMetrics::RecordTimeToSendStartWorker(duration,
- start_situation_);
- }
- }
-
starting_phase_ = is_script_streaming ? SCRIPT_STREAMING : SENT_START_WORKER;
for (auto& observer : listener_list_)
observer.OnStartWorkerMessageSent();
}
void EmbeddedWorkerInstance::RequestTermination() {
- if (!ServiceWorkerUtils::IsServicificationEnabled()) {
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled()) {
mojo::ReportBadMessage(
"Invalid termination request: RequestTermination() was called but "
"S13nServiceWorker is not enabled");
@@ -772,45 +763,15 @@ void EmbeddedWorkerInstance::OnScriptReadFinished() {
}
void EmbeddedWorkerInstance::OnScriptLoaded() {
- using LoadSource = ServiceWorkerMetrics::LoadSource;
-
if (!inflight_start_task_)
return;
- LoadSource source;
- if (network_accessed_for_script_) {
- DCHECK(!inflight_start_task_->is_installed());
- source = LoadSource::NETWORK;
- } else if (inflight_start_task_->is_installed()) {
- source = LoadSource::SERVICE_WORKER_STORAGE;
- } else {
- source = LoadSource::HTTP_CACHE;
- }
-
- // Don't record the time when script streaming is enabled because
- // OnScriptLoaded is called at the different timing.
- if (starting_phase_ != SCRIPT_STREAMING && !step_time_.is_null()) {
- base::TimeDelta duration = UpdateStepTime();
- ServiceWorkerMetrics::RecordTimeToLoad(duration, source, start_situation_);
- }
// Renderer side has started to launch the worker thread.
starting_phase_ = SCRIPT_LOADED;
- for (auto& observer : listener_list_)
- observer.OnScriptLoaded();
+ owner_version_->OnMainScriptLoaded();
// |this| may be destroyed by the callback.
}
-void EmbeddedWorkerInstance::OnURLJobCreatedForMainScript() {
- if (!inflight_start_task_)
- return;
-
- if (!step_time_.is_null()) {
- base::TimeDelta duration = UpdateStepTime();
- if (inflight_start_task_->is_installed())
- ServiceWorkerMetrics::RecordTimeToURLJob(duration, start_situation_);
- }
-}
-
void EmbeddedWorkerInstance::OnWorkerVersionInstalled() {
if (devtools_proxy_)
devtools_proxy_->NotifyWorkerVersionInstalled();
@@ -821,72 +782,61 @@ void EmbeddedWorkerInstance::OnWorkerVersionDoomed() {
devtools_proxy_->NotifyWorkerVersionDoomed();
}
-void EmbeddedWorkerInstance::OnThreadStarted(int thread_id) {
- if (!context_ || !inflight_start_task_)
- return;
-
- starting_phase_ = THREAD_STARTED;
- if (!step_time_.is_null()) {
- base::TimeDelta duration = UpdateStepTime();
- if (inflight_start_task_->is_installed())
- ServiceWorkerMetrics::RecordTimeToStartThread(duration, start_situation_);
- }
-
- thread_id_ = thread_id;
- for (auto& observer : listener_list_)
- observer.OnThreadStarted();
-}
-
-void EmbeddedWorkerInstance::OnScriptLoadFailed() {
+void EmbeddedWorkerInstance::OnScriptEvaluationStart() {
if (!inflight_start_task_)
return;
- // starting_phase_ may be SCRIPT_READ_FINISHED in case of reading from cache.
+ starting_phase_ = SCRIPT_EVALUATION;
for (auto& observer : listener_list_)
- observer.OnScriptLoadFailed();
+ observer.OnScriptEvaluationStart();
}
-void EmbeddedWorkerInstance::OnScriptEvaluated(bool success) {
- if (!inflight_start_task_)
+void EmbeddedWorkerInstance::OnStarted(
+ blink::mojom::ServiceWorkerStartStatus start_status,
+ int thread_id,
+ mojom::EmbeddedWorkerStartTimingPtr start_timing) {
+ if (!(start_timing->start_worker_received_time <=
+ start_timing->script_evaluation_start_time &&
+ start_timing->script_evaluation_start_time <=
+ start_timing->script_evaluation_end_time)) {
+ mojo::ReportBadMessage("EWI_BAD_START_TIMING");
return;
-
- DCHECK_EQ(EmbeddedWorkerStatus::STARTING, status_);
-
- // Renderer side has completed evaluating the loaded worker script.
- starting_phase_ = SCRIPT_EVALUATED;
- if (!step_time_.is_null()) {
- base::TimeDelta duration = UpdateStepTime();
- if (success && inflight_start_task_->is_installed())
- ServiceWorkerMetrics::RecordTimeToEvaluateScript(duration,
- start_situation_);
}
- base::WeakPtr<EmbeddedWorkerInstance> weak_this = weak_factory_.GetWeakPtr();
- StartTask::RunStartCallback(
- inflight_start_task_.get(),
- success ? SERVICE_WORKER_OK
- : SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED);
- // |this| may be destroyed by the callback.
-}
-
-void EmbeddedWorkerInstance::OnStarted(
- mojom::EmbeddedWorkerStartTimingPtr start_timing) {
if (!registry_->OnWorkerStarted(process_id(), embedded_worker_id_))
return;
- // Stop is requested before OnStarted is sent back from the worker.
+ // Stop was requested before OnStarted was sent back from the worker. Just
+ // pretend startup didn't happen, so observers don't try to use the running
+ // worker as it will stop soon.
if (status_ == EmbeddedWorkerStatus::STOPPING)
return;
- if (inflight_start_task_->is_installed()) {
- ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming(
- std::move(start_timing), inflight_start_task_->start_worker_sent_time(),
- start_situation_);
+ if (inflight_start_task_->is_installed() &&
+ !inflight_start_task_->skip_recording_startup_time()) {
+ ServiceWorkerMetrics::StartTimes times;
+ times.local_start = inflight_start_task_->start_time();
+ times.local_start_worker_sent =
+ inflight_start_task_->start_worker_sent_time();
+ times.remote_start_worker_received =
+ start_timing->start_worker_received_time;
+ times.remote_script_evaluation_start =
+ start_timing->script_evaluation_start_time;
+ times.remote_script_evaluation_end =
+ start_timing->script_evaluation_end_time;
+ times.local_end = base::TimeTicks::Now();
+
+ ServiceWorkerMetrics::RecordStartWorkerTiming(times, start_situation_);
}
+
DCHECK_EQ(EmbeddedWorkerStatus::STARTING, status_);
status_ = EmbeddedWorkerStatus::RUNNING;
+ thread_id_ = thread_id;
inflight_start_task_.reset();
- for (auto& observer : listener_list_)
- observer.OnStarted();
+ for (auto& observer : listener_list_) {
+ observer.OnStarted(start_status);
+ // |this| may be destroyed here. Fortunately we know there is only one
+ // observer in production code.
+ }
}
void EmbeddedWorkerInstance::OnStopped() {
@@ -959,8 +909,11 @@ void EmbeddedWorkerInstance::RemoveObserver(Listener* listener) {
void EmbeddedWorkerInstance::SetDevToolsAttached(bool attached) {
devtools_attached_ = attached;
- if (attached)
- registry_->OnDevToolsAttached(embedded_worker_id_);
+ if (!attached)
+ return;
+ if (inflight_start_task_)
+ inflight_start_task_->set_skip_recording_startup_time();
+ registry_->OnDevToolsAttached(embedded_worker_id_);
}
void EmbeddedWorkerInstance::OnNetworkAccessedForScriptLoad() {
@@ -980,8 +933,9 @@ void EmbeddedWorkerInstance::ReleaseProcess() {
thread_id_ = kInvalidEmbeddedWorkerThreadId;
}
-void EmbeddedWorkerInstance::OnStartFailed(StatusCallback callback,
- ServiceWorkerStatusCode status) {
+void EmbeddedWorkerInstance::OnSetupFailed(
+ StatusCallback callback,
+ blink::ServiceWorkerStatusCode status) {
EmbeddedWorkerStatus old_status = status_;
ReleaseProcess();
base::WeakPtr<EmbeddedWorkerInstance> weak_this = weak_factory_.GetWeakPtr();
@@ -992,15 +946,6 @@ void EmbeddedWorkerInstance::OnStartFailed(StatusCallback callback,
}
}
-base::TimeDelta EmbeddedWorkerInstance::UpdateStepTime() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DCHECK(!step_time_.is_null());
- base::TimeTicks now = base::TimeTicks::Now();
- base::TimeDelta duration = now - step_time_;
- step_time_ = now;
- return duration;
-}
-
void EmbeddedWorkerInstance::AddMessageToConsole(
blink::WebConsoleMessage::Level level,
const std::string& message) {
@@ -1040,16 +985,14 @@ std::string EmbeddedWorkerInstance::StartingPhaseToString(StartingPhase phase) {
return "Script downloading";
case SCRIPT_LOADED:
return "Script loaded";
- case SCRIPT_EVALUATED:
- return "Script evaluated";
- case THREAD_STARTED:
- return "Thread started";
case SCRIPT_READ_STARTED:
return "Script read started";
case SCRIPT_READ_FINISHED:
return "Script read finished";
case SCRIPT_STREAMING:
return "Script streaming";
+ case SCRIPT_EVALUATION:
+ return "Script evaluation";
case STARTING_PHASE_MAX_VALUE:
NOTREACHED();
}
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance.h b/chromium/content/browser/service_worker/embedded_worker_instance.h
index 2546eb0d4ae..4f034cdf345 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance.h
+++ b/chromium/content/browser/service_worker/embedded_worker_instance.h
@@ -26,9 +26,9 @@
#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 "content/common/service_worker/service_worker.mojom.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom.h"
#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h"
@@ -41,6 +41,11 @@ class ServiceWorkerContentSettingsProxyImpl;
class ServiceWorkerContextCore;
class ServiceWorkerVersion;
+namespace service_worker_new_script_loader_unittest {
+class ServiceWorkerNewScriptLoaderTest;
+FORWARD_DECLARE_TEST(ServiceWorkerNewScriptLoaderTest, AccessedNetwork);
+} // namespace service_worker_new_script_loader_unittest
+
// This gives an interface to control one EmbeddedWorker instance, which
// may be 'in-waiting' or running in one of the child processes added by
// AddProcessReference().
@@ -50,7 +55,8 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
: public mojom::EmbeddedWorkerInstanceHost {
public:
class DevToolsProxy;
- using StatusCallback = base::OnceCallback<void(ServiceWorkerStatusCode)>;
+ using StatusCallback =
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)>;
// This enum is used in UMA histograms. Append-only.
enum StartingPhase {
@@ -60,23 +66,20 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
SENT_START_WORKER = 3,
SCRIPT_DOWNLOADING = 4,
SCRIPT_LOADED = 5,
- SCRIPT_EVALUATED = 6,
- // THREAD_STARTED happens after SCRIPT_LOADED and before SCRIPT_EVALUATED
- THREAD_STARTED = 7,
+ // SCRIPT_EVALUATED = 6, // Obsolete
+ // THREAD_STARTED = 7, // Obsolete
// Script read happens after SENT_START_WORKER and before SCRIPT_LOADED
// (installed scripts only)
SCRIPT_READ_STARTED = 8,
SCRIPT_READ_FINISHED = 9,
SCRIPT_STREAMING = 10,
- // Add new values here.
+ SCRIPT_EVALUATION = 11,
+ // Add new values here and update enums.xml.
STARTING_PHASE_MAX_VALUE,
};
- using ProviderInfoGetter =
- base::OnceCallback<mojom::ServiceWorkerProviderInfoForStartWorkerPtr(
- int /* process_id */,
- scoped_refptr<network::SharedURLLoaderFactory>)>;
-
+ // DEPRECATED, only for use by ServiceWorkerVersion.
+ // TODO(crbug.com/855852): Remove this interface.
class Listener {
public:
virtual ~Listener() {}
@@ -85,8 +88,8 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
virtual void OnProcessAllocated() {}
virtual void OnRegisteredToDevToolsManager() {}
virtual void OnStartWorkerMessageSent() {}
- virtual void OnThreadStarted() {}
- virtual void OnStarted() {}
+ virtual void OnScriptEvaluationStart() {}
+ virtual void OnStarted(blink::mojom::ServiceWorkerStartStatus status) {}
// Called when status changed to STOPPING. The renderer has been sent a Stop
// IPC message and OnStopped() will be called upon successful completion.
@@ -104,8 +107,6 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
// worker died. When this is called, status is STOPPED.
virtual void OnDetached(EmbeddedWorkerStatus old_status) {}
- virtual void OnScriptLoaded() {}
- virtual void OnScriptLoadFailed() {}
virtual void OnReportException(const base::string16& error_message,
int line_number,
int column_number,
@@ -115,26 +116,21 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
const base::string16& message,
int line_number,
const GURL& source_url) {}
- // The instance is being deleted, so it's not safe to call any methods that
- // may result in a virtual method call.
- virtual void OnDestroyed() {}
};
~EmbeddedWorkerInstance() override;
// Starts the worker. It is invalid to call this when the worker is not in
- // STOPPED status. |callback| is invoked after the worker script has been
- // started and evaluated, or when an error occurs.
- // |params| should be populated with service worker version info needed
- // to start the worker. If the worker is already installed,
- // |installed_scripts_info| holds information about its scripts; otherwise,
- // it is null.
- // |provider_info_getter| is called when this instance
- // allocates a process and is ready to send a StartWorker message.
- void Start(
- mojom::EmbeddedWorkerStartParamsPtr params,
- ProviderInfoGetter provider_info_getter,
- StatusCallback callback);
+ // STOPPED status.
+ //
+ // |sent_start_callback| is invoked once the Start IPC is sent, or if an error
+ // prevented that from happening. The callback is not invoked in some cases,
+ // e.g., when Stop() is called and aborts the start procedure. Note that when
+ // the callback is invoked with kOk status, the service worker has not yet
+ // finished starting. Observe OnStarted()/OnStopped() for when start completed
+ // or failed.
+ void Start(mojom::EmbeddedWorkerStartParamsPtr params,
+ StatusCallback sent_start_callback);
// Stops the worker. It is invalid to call this when the worker is not in
// STARTING or RUNNING status.
@@ -165,6 +161,8 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
int thread_id() const { return thread_id_; }
int worker_devtools_agent_route_id() const;
+ // DEPRECATED, only for use by ServiceWorkerVersion.
+ // TODO(crbug.com/855852): Remove the Listener interface.
void AddObserver(Listener* listener);
void RemoveObserver(Listener* listener);
@@ -195,10 +193,6 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
// Called when the worker is doomed.
void OnWorkerVersionDoomed();
- // Called when the net::URLRequestJob to load the service worker script
- // created. Not called for import scripts.
- void OnURLJobCreatedForMainScript();
-
// Add message to the devtools console.
void AddMessageToConsole(blink::WebConsoleMessage::Level level,
const std::string& message);
@@ -224,6 +218,9 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerInstanceTest, StartAndStop);
FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerInstanceTest, DetachDuringStart);
FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerInstanceTest, StopDuringStart);
+ FRIEND_TEST_ALL_PREFIXES(service_worker_new_script_loader_unittest::
+ ServiceWorkerNewScriptLoaderTest,
+ AccessedNetwork);
// Constructor is called via EmbeddedWorkerRegistry::CreateWorker().
// This instance holds a ref of |registry|.
@@ -260,15 +257,12 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
void CountFeature(blink::mojom::WebFeature feature) override;
void OnReadyForInspection() override;
void OnScriptLoaded() override;
- // Notifies the corresponding provider host that the thread has started and is
- // ready to receive messages.
- void OnThreadStarted(int thread_id) override;
- void OnScriptLoadFailed() override;
- // Fires the callback passed to Start().
- void OnScriptEvaluated(bool success) override;
+ void OnScriptEvaluationStart() override;
// Changes the internal worker status from STARTING to RUNNING.
- void OnStarted(mojom::EmbeddedWorkerStartTimingPtr start_timing) override;
- // Resets the embedded worker instance to the initial state. This will change
+ void OnStarted(blink::mojom::ServiceWorkerStartStatus status,
+ int thread_id,
+ mojom::EmbeddedWorkerStartTimingPtr start_timing) override;
+ // Resets the embedded worker instance to the initial state. Changes
// the internal status from STARTING or RUNNING to STOPPED.
void OnStopped() override;
void OnReportException(const base::string16& error_message,
@@ -287,11 +281,8 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
// Called back from StartTask when the startup sequence failed. Calls
// ReleaseProcess() and invokes |callback| with |status|. May destroy |this|.
- void OnStartFailed(StatusCallback callback, ServiceWorkerStatusCode status);
-
- // Returns the time elapsed since |step_time_| and updates |step_time_|
- // to the current time.
- base::TimeDelta UpdateStepTime();
+ void OnSetupFailed(StatusCallback callback,
+ blink::ServiceWorkerStatusCode status);
base::WeakPtr<ServiceWorkerContextCore> context_;
scoped_refptr<EmbeddedWorkerRegistry> registry_;
@@ -316,9 +307,6 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
// Binding for EmbeddedWorkerInstanceHost, runs on IO thread.
mojo::AssociatedBinding<EmbeddedWorkerInstanceHost> instance_host_binding_;
- // This is set at Start and used on SendStartWorker.
- ProviderInfoGetter provider_info_getter_;
-
// Whether devtools is attached or not.
bool devtools_attached_;
@@ -335,9 +323,6 @@ class CONTENT_EXPORT EmbeddedWorkerInstance
ServiceWorkerMetrics::StartSituation start_situation_ =
ServiceWorkerMetrics::StartSituation::UNKNOWN;
- // Used for UMA. The start time of the current start sequence step.
- base::TimeTicks step_time_;
-
std::unique_ptr<ServiceWorkerContentSettingsProxyImpl> content_settings_;
base::WeakPtrFactory<EmbeddedWorkerInstance> weak_factory_;
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 9389f539804..5dac55e4405 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -22,7 +22,7 @@
#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/service_worker_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker.mojom.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -31,75 +31,28 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
namespace content {
namespace {
-void SaveStatusAndCall(ServiceWorkerStatusCode* out,
- base::OnceClosure callback,
- ServiceWorkerStatusCode status) {
- *out = status;
- std::move(callback).Run();
+EmbeddedWorkerInstance::StatusCallback ReceiveStatus(
+ base::Optional<blink::ServiceWorkerStatusCode>* out_status,
+ base::OnceClosure quit) {
+ return base::BindOnce(
+ [](base::Optional<blink::ServiceWorkerStatusCode>* out_status,
+ base::OnceClosure quit, blink::ServiceWorkerStatusCode status) {
+ *out_status = status;
+ std::move(quit).Run();
+ },
+ out_status, std::move(quit));
}
} // namespace
-class ProviderHostEndpoints : public mojom::ServiceWorkerContainerHost {
- public:
- ProviderHostEndpoints() : binding_(this) {}
-
- ~ProviderHostEndpoints() override {}
-
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr CreateProviderInfoPtr() {
- DCHECK(!binding_.is_bound());
- DCHECK(!client_.is_bound());
- // Just keep the endpoints.
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info =
- mojom::ServiceWorkerProviderInfoForStartWorker::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;
- }
-
- 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 EnsureControllerServiceWorker(
- mojom::ControllerServiceWorkerRequest request,
- mojom::ControllerServiceWorkerPurpose purpose) override {
- NOTIMPLEMENTED();
- }
- void CloneForWorker(
- mojom::ServiceWorkerContainerHostRequest request) override {
- NOTIMPLEMENTED();
- }
- void Ping(PingCallback callback) override { NOTIMPLEMENTED(); }
-
- mojom::ServiceWorkerContainerAssociatedPtr client_;
- mojo::AssociatedBinding<mojom::ServiceWorkerContainerHost> binding_;
-
- DISALLOW_COPY_AND_ASSIGN(ProviderHostEndpoints);
-};
-
-class EmbeddedWorkerInstanceTest : public testing::Test,
+class EmbeddedWorkerInstanceTest : public testing::TestWithParam<bool>,
public EmbeddedWorkerInstance::Listener {
protected:
EmbeddedWorkerInstanceTest()
@@ -115,13 +68,15 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
struct EventLog {
EventType type;
- EmbeddedWorkerStatus status;
+ base::Optional<EmbeddedWorkerStatus> status;
+ base::Optional<blink::mojom::ServiceWorkerStartStatus> start_status;
};
- void RecordEvent(
- EventType type,
- EmbeddedWorkerStatus status = EmbeddedWorkerStatus::STOPPED) {
- EventLog log = {type, status};
+ void RecordEvent(EventType type,
+ base::Optional<EmbeddedWorkerStatus> status = base::nullopt,
+ base::Optional<blink::mojom::ServiceWorkerStartStatus>
+ start_status = base::nullopt) {
+ EventLog log = {type, status, start_status};
events_.push_back(log);
}
@@ -129,7 +84,9 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
void OnStartWorkerMessageSent() override {
RecordEvent(START_WORKER_MESSAGE_SENT);
}
- void OnStarted() override { RecordEvent(STARTED); }
+ void OnStarted(blink::mojom::ServiceWorkerStartStatus status) override {
+ RecordEvent(STARTED, base::nullopt, status);
+ }
void OnStopped(EmbeddedWorkerStatus old_status) override {
RecordEvent(STOPPED, old_status);
}
@@ -138,6 +95,13 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
}
void SetUp() override {
+ if (GetParam()) {
+ scoped_feature_list_.InitAndEnableFeature(
+ blink::features::kServiceWorkerServicification);
+ } else {
+ scoped_feature_list_.InitAndDisableFeature(
+ blink::features::kServiceWorkerServicification);
+ }
helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
}
@@ -166,51 +130,58 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
return pair;
}
- ServiceWorkerStatusCode StartWorker(EmbeddedWorkerInstance* worker,
- int id, const GURL& pattern,
- const GURL& url) {
- ServiceWorkerStatusCode status;
- base::RunLoop run_loop;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(id, pattern, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
- run_loop.Run();
- return status;
+ // Calls worker->Start() and runs until the start IPC is sent.
+ //
+ // Expects success. For failure cases, call Start() manually.
+ void StartWorkerUntilStartSent(EmbeddedWorkerInstance* worker,
+ mojom::EmbeddedWorkerStartParamsPtr params) {
+ base::Optional<blink::ServiceWorkerStatusCode> status;
+ base::RunLoop loop;
+ worker->Start(std::move(params),
+ ReceiveStatus(&status, loop.QuitClosure()));
+ loop.Run();
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
+ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
+ }
+
+ // Calls worker->Start() and runs until startup finishes.
+ //
+ // Expects success. For failure cases, call Start() manually.
+ void StartWorker(EmbeddedWorkerInstance* worker,
+ mojom::EmbeddedWorkerStartParamsPtr params) {
+ StartWorkerUntilStartSent(worker, std::move(params));
+ // TODO(falken): Listen for OnStarted() instead of this.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
}
- mojom::EmbeddedWorkerStartParamsPtr
- CreateStartParams(int version_id, const GURL& scope, const GURL& script_url) {
+ mojom::EmbeddedWorkerStartParamsPtr CreateStartParams(
+ scoped_refptr<ServiceWorkerVersion> version) {
auto params = mojom::EmbeddedWorkerStartParams::New();
- params->service_worker_version_id = version_id;
- params->scope = scope;
- params->script_url = script_url;
+ params->service_worker_version_id = version->version_id();
+ params->scope = version->scope();
+ params->script_url = version->script_url();
params->pause_after_download = false;
params->is_installed = false;
- params->dispatcher_request = CreateEventDispatcher();
+ params->service_worker_request = CreateServiceWorker();
params->controller_request = CreateController();
params->installed_scripts_info = GetInstalledScriptsInfoPtr();
+ params->provider_info = CreateProviderInfo(std::move(version));
return params;
}
mojom::ServiceWorkerProviderInfoForStartWorkerPtr CreateProviderInfo(
- int /* process_id */,
- scoped_refptr<network::SharedURLLoaderFactory>) {
- provider_host_endpoints_.emplace_back(
- std::make_unique<ProviderHostEndpoints>());
- return provider_host_endpoints_.back()->CreateProviderInfoPtr();
- }
-
- EmbeddedWorkerInstance::ProviderInfoGetter CreateProviderInfoGetter() {
- return base::BindOnce(&EmbeddedWorkerInstanceTest::CreateProviderInfo,
- base::Unretained(this));
+ scoped_refptr<ServiceWorkerVersion> version) {
+ auto provider_info = mojom::ServiceWorkerProviderInfoForStartWorker::New();
+ version->provider_host_ = ServiceWorkerProviderHost::PreCreateForController(
+ context()->AsWeakPtr(), version, &provider_info);
+ return provider_info;
}
- mojom::ServiceWorkerEventDispatcherRequest CreateEventDispatcher() {
- dispatchers_.emplace_back();
- return mojo::MakeRequest(&dispatchers_.back());
+ mojom::ServiceWorkerRequest CreateServiceWorker() {
+ service_workers_.emplace_back();
+ return mojo::MakeRequest(&service_workers_.back());
}
mojom::ControllerServiceWorkerRequest CreateController() {
@@ -241,8 +212,6 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
return context()->embedded_worker_registry();
}
- IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); }
-
std::vector<std::unique_ptr<
EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient>>*
mock_instance_clients() {
@@ -250,17 +219,17 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
}
// Mojo endpoints.
- std::vector<mojom::ServiceWorkerEventDispatcherPtr> dispatchers_;
+ std::vector<mojom::ServiceWorkerPtr> service_workers_;
std::vector<mojom::ControllerServiceWorkerPtr> controllers_;
std::vector<blink::mojom::ServiceWorkerInstalledScriptsManagerPtr>
installed_scripts_managers_;
std::vector<blink::mojom::ServiceWorkerInstalledScriptsManagerHostRequest>
installed_scripts_manager_host_requests_;
- std::vector<std::unique_ptr<ProviderHostEndpoints>> provider_host_endpoints_;
TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
std::vector<EventLog> events_;
+ base::test::ScopedFeatureList scoped_feature_list_;
private:
DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceTest);
@@ -279,7 +248,7 @@ class StalledInStartWorkerHelper : public EmbeddedWorkerTestHelper {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
@@ -293,7 +262,7 @@ class StalledInStartWorkerHelper : public EmbeddedWorkerTestHelper {
}
EmbeddedWorkerTestHelper::OnStartWorker(
embedded_worker_id, service_worker_version_id, scope, script_url,
- pause_after_download, std::move(dispatcher_request),
+ pause_after_download, std::move(service_worker_request),
std::move(controller_request), std::move(instance_host),
std::move(provider_info), std::move(installed_scripts_info));
}
@@ -320,28 +289,18 @@ class StalledInStartWorkerHelper : public EmbeddedWorkerTestHelper {
instance_host_ptr_map_;
};
-TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) {
+TEST_P(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(pair.second.get());
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
worker->AddObserver(this);
// Start should succeed.
- ServiceWorkerStatusCode status;
- base::RunLoop run_loop;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(service_worker_version_id, pattern, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
- EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
- run_loop.Run();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ StartWorker(worker.get(), CreateStartParams(pair.second));
// The 'WorkerStarted' message should have been sent by
// EmbeddedWorkerTestHelper.
@@ -362,12 +321,14 @@ TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) {
EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
EXPECT_EQ(STARTED, events_[2].type);
+ EXPECT_EQ(blink::mojom::ServiceWorkerStartStatus::kNormalCompletion,
+ events_[2].start_status.value());
EXPECT_EQ(STOPPED, events_[3].type);
}
// Test that a worker that failed twice will use a new render process
// on the next attempt.
-TEST_F(EmbeddedWorkerInstanceTest, ForceNewProcess) {
+TEST_P(EmbeddedWorkerInstanceTest, ForceNewProcess) {
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
@@ -379,16 +340,7 @@ TEST_F(EmbeddedWorkerInstanceTest, ForceNewProcess) {
{
// Start once normally.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
- base::RunLoop run_loop;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(service_worker_version_id, pattern, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
+ StartWorker(worker.get(), CreateStartParams(pair.second));
// The worker should be using the default render process.
EXPECT_EQ(helper_->mock_render_process_id(), worker->process_id());
@@ -397,25 +349,16 @@ TEST_F(EmbeddedWorkerInstanceTest, ForceNewProcess) {
}
// Fail twice.
- context()->UpdateVersionFailureCount(service_worker_version_id,
- SERVICE_WORKER_ERROR_FAILED);
- context()->UpdateVersionFailureCount(service_worker_version_id,
- SERVICE_WORKER_ERROR_FAILED);
+ context()->UpdateVersionFailureCount(
+ service_worker_version_id, blink::ServiceWorkerStatusCode::kErrorFailed);
+ context()->UpdateVersionFailureCount(
+ service_worker_version_id, blink::ServiceWorkerStatusCode::kErrorFailed);
{
// Start again.
- ServiceWorkerStatusCode status;
base::RunLoop run_loop;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(service_worker_version_id, pattern, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
- EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
- run_loop.Run();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ StartWorker(worker.get(), CreateStartParams(pair.second));
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
// The worker should be using the new render process.
EXPECT_EQ(helper_->new_render_process_id(), worker->process_id());
worker->Stop();
@@ -423,20 +366,17 @@ TEST_F(EmbeddedWorkerInstanceTest, ForceNewProcess) {
}
}
-TEST_F(EmbeddedWorkerInstanceTest, StopWhenDevToolsAttached) {
+TEST_P(EmbeddedWorkerInstanceTest, StopWhenDevToolsAttached) {
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());
// 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());
+ StartWorker(worker.get(), CreateStartParams(pair.second));
EXPECT_EQ(helper_->mock_render_process_id(), worker->process_id());
worker->StopIfNotAttachedToDevTools();
EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, worker->status());
@@ -448,9 +388,7 @@ TEST_F(EmbeddedWorkerInstanceTest, StopWhenDevToolsAttached) {
// Set devtools_attached to true, and do the same.
worker->SetDevToolsAttached(true);
- EXPECT_EQ(SERVICE_WORKER_OK,
- StartWorker(worker.get(), service_worker_version_id, pattern, url));
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
+ StartWorker(worker.get(), CreateStartParams(pair.second));
EXPECT_EQ(helper_->mock_render_process_id(), worker->process_id());
worker->StopIfNotAttachedToDevTools();
base::RunLoop().RunUntilIdle();
@@ -467,7 +405,7 @@ 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) {
+TEST_P(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) {
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
@@ -480,35 +418,11 @@ TEST_F(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) {
std::unique_ptr<EmbeddedWorkerInstance> worker2 =
embedded_worker_registry()->CreateWorker(pair2.second.get());
- 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();
- {
- // Start worker1.
- ServiceWorkerStatusCode status;
- base::RunLoop run_loop;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id1, pattern, url);
- worker1->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
- }
-
- {
- // Start worker2.
- ServiceWorkerStatusCode status;
- base::RunLoop run_loop;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id2, pattern, url);
- worker2->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
- }
+ // Start workers.
+ StartWorker(worker1.get(), CreateStartParams(pair1.second));
+ StartWorker(worker2.get(), CreateStartParams(pair2.second));
// The two workers share the same process.
EXPECT_EQ(worker1->process_id(), worker2->process_id());
@@ -528,59 +442,45 @@ TEST_F(EmbeddedWorkerInstanceTest, RemoveWorkerInSharedProcess) {
worker2->Stop();
}
-TEST_F(EmbeddedWorkerInstanceTest, DetachDuringProcessAllocation) {
+TEST_P(EmbeddedWorkerInstanceTest, DetachDuringProcessAllocation) {
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(pair.second.get());
worker->AddObserver(this);
// Run the start worker sequence and detach during process allocation.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, scope, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, base::DoNothing::Once<>()));
+ base::Optional<blink::ServiceWorkerStatusCode> status;
+ mojom::EmbeddedWorkerStartParamsPtr params = CreateStartParams(pair.second);
+ worker->Start(std::move(params), ReceiveStatus(&status, base::DoNothing()));
worker->Detach();
base::RunLoop().RunUntilIdle();
+ // The start callback should not be aborted by detach (see a comment on the
+ // dtor of EmbeddedWorkerInstance::StartTask).
+ EXPECT_FALSE(status);
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, worker->process_id());
- // The start callback should not be aborted by detach (see a comment on the
- // dtor of EmbeddedWorkerInstance::StartTask).
- EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status);
-
// "PROCESS_ALLOCATED" event should not be recorded.
ASSERT_EQ(1u, events_.size());
EXPECT_EQ(DETACHED, events_[0].type);
- EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status);
+ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status.value());
}
-TEST_F(EmbeddedWorkerInstanceTest, DetachAfterSendingStartWorkerMessage) {
+TEST_P(EmbeddedWorkerInstanceTest, DetachAfterSendingStartWorkerMessage) {
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(pair.second.get());
worker->AddObserver(this);
- // Run the start worker sequence until a start worker message is sent.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, scope, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, base::DoNothing::Once<>()));
- base::RunLoop().RunUntilIdle();
-
+ StartWorkerUntilStartSent(worker.get(), CreateStartParams(pair.second));
ASSERT_EQ(2u, events_.size());
EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
@@ -592,34 +492,26 @@ TEST_F(EmbeddedWorkerInstanceTest, DetachAfterSendingStartWorkerMessage) {
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, worker->process_id());
- // The start callback should not be aborted by detach (see a comment on the
- // dtor of EmbeddedWorkerInstance::StartTask).
- EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status);
-
// "STARTED" event should not be recorded.
ASSERT_EQ(1u, events_.size());
EXPECT_EQ(DETACHED, events_[0].type);
- EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status);
+ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status.value());
}
-TEST_F(EmbeddedWorkerInstanceTest, StopDuringProcessAllocation) {
+TEST_P(EmbeddedWorkerInstanceTest, StopDuringProcessAllocation) {
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(pair.second.get());
worker->AddObserver(this);
// Stop the start worker sequence before a process is allocated.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, scope, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, base::DoNothing::Once<>()));
+ worker->Start(CreateStartParams(pair.second),
+ ReceiveStatus(&status, base::DoNothing()));
worker->Stop();
base::RunLoop().RunUntilIdle();
@@ -628,24 +520,17 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringProcessAllocation) {
// The start callback should not be aborted by stop (see a comment on the dtor
// of EmbeddedWorkerInstance::StartTask).
- EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status);
+ EXPECT_FALSE(status);
// "PROCESS_ALLOCATED" event should not be recorded.
ASSERT_EQ(1u, events_.size());
EXPECT_EQ(STOPPED, events_[0].type);
- EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status);
+ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[0].status.value());
events_.clear();
// Restart the worker.
- status = SERVICE_WORKER_ERROR_MAX_VALUE;
- std::unique_ptr<base::RunLoop> run_loop(new base::RunLoop);
- params = CreateStartParams(version_id, scope, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, run_loop->QuitClosure()));
- run_loop->Run();
-
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ StartWorker(worker.get(), CreateStartParams(pair.second));
+
ASSERT_EQ(3u, events_.size());
EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
@@ -672,7 +557,7 @@ class DontReceiveResumeAfterDownloadInstanceClient
bool* const was_resume_after_download_called_;
};
-TEST_F(EmbeddedWorkerInstanceTest, StopDuringPausedAfterDownload) {
+TEST_P(EmbeddedWorkerInstanceTest, StopDuringPausedAfterDownload) {
const GURL scope("http://example.com/");
const GURL url("http://example.com/worker.js");
@@ -682,21 +567,17 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringPausedAfterDownload) {
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(pair.second.get());
worker->AddObserver(this);
// Run the start worker sequence until pause after download.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
-
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, scope, url);
+ mojom::EmbeddedWorkerStartParamsPtr params = CreateStartParams(pair.second);
params->pause_after_download = true;
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, base::DoNothing::Once<>()));
+ base::Optional<blink::ServiceWorkerStatusCode> status;
+ worker->Start(std::move(params), ReceiveStatus(&status, base::DoNothing()));
base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
// Make the worker stopping and attempt to send a resume after download
// message.
@@ -709,26 +590,17 @@ TEST_F(EmbeddedWorkerInstanceTest, StopDuringPausedAfterDownload) {
EXPECT_FALSE(was_resume_after_download_called);
}
-TEST_F(EmbeddedWorkerInstanceTest, StopAfterSendingStartWorkerMessage) {
+TEST_P(EmbeddedWorkerInstanceTest, StopAfterSendingStartWorkerMessage) {
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(pair.second.get());
worker->AddObserver(this);
- // Run the start worker sequence until a start worker message is sent.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, scope, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, base::DoNothing::Once<>()));
- base::RunLoop().RunUntilIdle();
-
+ StartWorkerUntilStartSent(worker.get(), CreateStartParams(pair.second));
ASSERT_EQ(2u, events_.size());
EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
@@ -740,30 +612,18 @@ TEST_F(EmbeddedWorkerInstanceTest, StopAfterSendingStartWorkerMessage) {
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, worker->process_id());
- // The start callback should not be aborted by stop (see a comment on the dtor
- // of EmbeddedWorkerInstance::StartTask).
- EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status);
-
// "STARTED" event should not be recorded.
ASSERT_EQ(1u, events_.size());
EXPECT_EQ(STOPPED, events_[0].type);
- EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, events_[0].status);
+ EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, events_[0].status.value());
events_.clear();
// Restart the worker.
static_cast<StalledInStartWorkerHelper*>(helper_.get())
->set_force_stall_in_start(false);
- status = SERVICE_WORKER_ERROR_MAX_VALUE;
- std::unique_ptr<base::RunLoop> run_loop(new base::RunLoop);
-
- params = CreateStartParams(version_id, scope, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, run_loop->QuitClosure()));
- run_loop->Run();
+ StartWorker(worker.get(), CreateStartParams(pair.second));
// The worker should be started.
- EXPECT_EQ(SERVICE_WORKER_OK, status);
ASSERT_EQ(3u, events_.size());
EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
@@ -773,25 +633,18 @@ TEST_F(EmbeddedWorkerInstanceTest, StopAfterSendingStartWorkerMessage) {
worker->Stop();
}
-TEST_F(EmbeddedWorkerInstanceTest, Detach) {
+TEST_P(EmbeddedWorkerInstanceTest, Detach) {
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(pair.second.get());
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
worker->AddObserver(this);
// Start the worker.
base::RunLoop run_loop;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, pattern, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
- run_loop.Run();
+ StartWorker(worker.get(), CreateStartParams(pair.second));
// Detach.
int process_id = worker->process_id();
@@ -806,7 +659,7 @@ TEST_F(EmbeddedWorkerInstanceTest, Detach) {
}
// Test for when sending the start IPC failed.
-TEST_F(EmbeddedWorkerInstanceTest, FailToSendStartIPC) {
+TEST_P(EmbeddedWorkerInstanceTest, FailToSendStartIPC) {
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
@@ -814,24 +667,28 @@ TEST_F(EmbeddedWorkerInstanceTest, FailToSendStartIPC) {
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(pair.second.get());
worker->AddObserver(this);
- // Attempt to start the worker.
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, pattern, url);
- worker->Start(std::move(params), CreateProviderInfoGetter(),
- base::DoNothing());
- base::RunLoop().RunUntilIdle();
+ // Attempt to start the worker. From the browser process's point of view, the
+ // start IPC was sent.
+ base::Optional<blink::ServiceWorkerStatusCode> status;
+ base::RunLoop loop;
+ worker->Start(CreateStartParams(pair.second),
+ ReceiveStatus(&status, loop.QuitClosure()));
+ loop.Run();
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
+ // But the renderer should not receive the message and the binding is broken.
// Worker should handle the failure of binding on the remote side as detach.
+ base::RunLoop().RunUntilIdle();
+
ASSERT_EQ(3u, events_.size());
EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
EXPECT_EQ(DETACHED, events_[2].type);
- EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[2].status);
+ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[2].status.value());
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
}
@@ -848,7 +705,7 @@ class FailEmbeddedWorkerInstanceClientImpl
}
};
-TEST_F(EmbeddedWorkerInstanceTest, RemoveRemoteInterface) {
+TEST_P(EmbeddedWorkerInstanceTest, RemoveRemoteInterface) {
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
@@ -859,24 +716,25 @@ TEST_F(EmbeddedWorkerInstanceTest, RemoveRemoteInterface) {
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(pair.second.get());
worker->AddObserver(this);
// Attempt to start the worker.
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, pattern, url);
- worker->Start(std::move(params), CreateProviderInfoGetter(),
- base::DoNothing());
- base::RunLoop().RunUntilIdle();
+ base::Optional<blink::ServiceWorkerStatusCode> status;
+ base::RunLoop loop;
+ worker->Start(CreateStartParams(pair.second),
+ ReceiveStatus(&status, loop.QuitClosure()));
+ loop.Run();
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
// Worker should handle the sudden shutdown as detach.
+ base::RunLoop().RunUntilIdle();
ASSERT_EQ(3u, events_.size());
EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
EXPECT_EQ(DETACHED, events_[2].type);
- EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[2].status);
+ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, events_[2].status.value());
}
class StoreMessageInstanceClient
@@ -901,7 +759,7 @@ class StoreMessageInstanceClient
messages_;
};
-TEST_F(EmbeddedWorkerInstanceTest, AddMessageToConsole) {
+TEST_P(EmbeddedWorkerInstanceTest, AddMessageToConsole) {
const GURL pattern("http://example.com/");
const GURL url("http://example.com/worker.js");
std::unique_ptr<StoreMessageInstanceClient> instance_client =
@@ -911,7 +769,6 @@ TEST_F(EmbeddedWorkerInstanceTest, AddMessageToConsole) {
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(pair.second.get());
worker->AddObserver(this);
@@ -920,12 +777,13 @@ TEST_F(EmbeddedWorkerInstanceTest, AddMessageToConsole) {
// cause a crash.
std::pair<blink::WebConsoleMessage::Level, std::string> test_message =
std::make_pair(blink::WebConsoleMessage::kLevelVerbose, "");
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, pattern, url);
- worker->Start(std::move(params), CreateProviderInfoGetter(),
- base::DoNothing());
+ base::Optional<blink::ServiceWorkerStatusCode> status;
+ worker->Start(CreateStartParams(pair.second),
+ ReceiveStatus(&status, base::DoNothing()));
worker->AddMessageToConsole(test_message.first, test_message.second);
base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
// Messages sent before sending StartWorker message won't be dispatched.
ASSERT_EQ(0UL, instance_client_rawptr->message().size());
@@ -933,7 +791,6 @@ TEST_F(EmbeddedWorkerInstanceTest, AddMessageToConsole) {
EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
EXPECT_EQ(STARTED, events_[2].type);
- EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
worker->AddMessageToConsole(test_message.first, test_message.second);
base::RunLoop().RunUntilIdle();
@@ -961,7 +818,7 @@ class RecordCacheStorageHelper : public EmbeddedWorkerTestHelper {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
@@ -970,7 +827,7 @@ class RecordCacheStorageHelper : public EmbeddedWorkerTestHelper {
had_cache_storage_ = !!provider_info->cache_storage;
EmbeddedWorkerTestHelper::OnStartWorker(
embedded_worker_id, service_worker_version_id, scope, script_url,
- pause_after_download, std::move(dispatcher_request),
+ pause_after_download, std::move(service_worker_request),
std::move(controller_request), std::move(instance_host),
std::move(provider_info), std::move(installed_scripts_info));
}
@@ -983,7 +840,7 @@ class RecordCacheStorageHelper : public EmbeddedWorkerTestHelper {
// Test that the worker is given a CacheStoragePtr during startup, when
// |pause_after_download| is false.
-TEST_F(EmbeddedWorkerInstanceTest, CacheStorageOptimization) {
+TEST_P(EmbeddedWorkerInstanceTest, CacheStorageOptimization) {
const GURL scope("http://example.com/");
const GURL url("http://example.com/worker.js");
auto helper = std::make_unique<RecordCacheStorageHelper>();
@@ -991,22 +848,13 @@ TEST_F(EmbeddedWorkerInstanceTest, CacheStorageOptimization) {
helper_ = std::move(helper);
RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url);
- const int64_t version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
embedded_worker_registry()->CreateWorker(pair.second.get());
// First, test a worker without pause after download.
{
// Start the worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
- base::RunLoop run_loop;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, scope, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ StartWorker(worker.get(), CreateStartParams(pair.second));
// Cache storage should have been sent.
EXPECT_TRUE(helper_rawptr->had_cache_storage());
@@ -1019,19 +867,16 @@ TEST_F(EmbeddedWorkerInstanceTest, CacheStorageOptimization) {
// Second, test a worker with pause after download.
{
// Start the worker until paused.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, scope, url);
+ mojom::EmbeddedWorkerStartParamsPtr params = CreateStartParams(pair.second);
params->pause_after_download = true;
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, base::DoNothing::Once<>()));
+ worker->Start(std::move(params), base::DoNothing());
base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
// Finish starting.
worker->ResumeAfterDownload();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
// Cache storage should not have been sent.
EXPECT_FALSE(helper_rawptr->had_cache_storage());
@@ -1044,7 +889,7 @@ TEST_F(EmbeddedWorkerInstanceTest, CacheStorageOptimization) {
// Test that the worker is not given a CacheStoragePtr during startup when
// the feature is disabled.
-TEST_F(EmbeddedWorkerInstanceTest, CacheStorageOptimizationIsDisabled) {
+TEST_P(EmbeddedWorkerInstanceTest, CacheStorageOptimizationIsDisabled) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndDisableFeature(
blink::features::kEagerCacheStorageSetupForServiceWorkers);
@@ -1056,22 +901,14 @@ TEST_F(EmbeddedWorkerInstanceTest, CacheStorageOptimizationIsDisabled) {
helper_ = std::move(helper);
RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url);
- const int64_t version_id = pair.second->version_id();
std::unique_ptr<EmbeddedWorkerInstance> worker =
embedded_worker_registry()->CreateWorker(pair.second.get());
// First, test a worker without pause after download.
{
// Start the worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
- base::RunLoop run_loop;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, scope, url);
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ mojom::EmbeddedWorkerStartParamsPtr params = CreateStartParams(pair.second);
+ StartWorker(worker.get(), std::move(params));
// Cache storage should not have been sent.
EXPECT_FALSE(helper_rawptr->had_cache_storage());
@@ -1084,19 +921,16 @@ TEST_F(EmbeddedWorkerInstanceTest, CacheStorageOptimizationIsDisabled) {
// Second, test a worker with pause after download.
{
// Start the worker until paused.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
- mojom::EmbeddedWorkerStartParamsPtr params =
- CreateStartParams(version_id, scope, url);
+ mojom::EmbeddedWorkerStartParamsPtr params = CreateStartParams(pair.second);
params->pause_after_download = true;
- worker->Start(
- std::move(params), CreateProviderInfoGetter(),
- base::BindOnce(&SaveStatusAndCall, &status, base::DoNothing::Once<>()));
+ worker->Start(std::move(params), base::DoNothing());
base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
// Finish starting.
worker->ResumeAfterDownload();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, worker->status());
// Cache storage should not have been sent.
EXPECT_FALSE(helper_rawptr->had_cache_storage());
@@ -1107,4 +941,47 @@ TEST_F(EmbeddedWorkerInstanceTest, CacheStorageOptimizationIsDisabled) {
}
}
+// Starts the worker with kAbruptCompletion status.
+class AbruptCompletionHelper : public EmbeddedWorkerTestHelper {
+ public:
+ AbruptCompletionHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
+ ~AbruptCompletionHelper() override = default;
+
+ void OnResumeAfterDownload(int embedded_worker_id) override {
+ SimulateScriptEvaluationStart(embedded_worker_id);
+ SimulateWorkerStarted(
+ embedded_worker_id,
+ blink::mojom::ServiceWorkerStartStatus::kAbruptCompletion,
+ GetNextThreadId());
+ }
+};
+
+// Tests that kAbruptCompletion is the OnStarted() status when the
+// renderer reports abrupt completion.
+TEST_P(EmbeddedWorkerInstanceTest, AbruptCompletion) {
+ const GURL scope("http://example.com/");
+ const GURL url("http://example.com/worker.js");
+ helper_ = std::make_unique<AbruptCompletionHelper>();
+
+ RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url);
+ std::unique_ptr<EmbeddedWorkerInstance> worker =
+ embedded_worker_registry()->CreateWorker(pair.second.get());
+ EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status());
+ worker->AddObserver(this);
+
+ StartWorker(worker.get(), CreateStartParams(pair.second));
+
+ ASSERT_EQ(3u, events_.size());
+ EXPECT_EQ(PROCESS_ALLOCATED, events_[0].type);
+ EXPECT_EQ(START_WORKER_MESSAGE_SENT, events_[1].type);
+ EXPECT_EQ(STARTED, events_[2].type);
+ EXPECT_EQ(blink::mojom::ServiceWorkerStartStatus::kAbruptCompletion,
+ events_[2].start_status.value());
+ worker->Stop();
+}
+
+INSTANTIATE_TEST_CASE_P(IsServiceWorkerServicificationEnabled,
+ EmbeddedWorkerInstanceTest,
+ ::testing::Bool(););
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/embedded_worker_registry.h b/chromium/content/browser/service_worker/embedded_worker_registry.h
index c4e25c4b695..20825f66eef 100644
--- a/chromium/content/browser/service_worker/embedded_worker_registry.h
+++ b/chromium/content/browser/service_worker/embedded_worker_registry.h
@@ -17,7 +17,7 @@
#include "base/strings/string16.h"
#include "content/browser/service_worker/service_worker_lifetime_tracker.h"
#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
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 4db8a45e0d1..4942766b0e6 100644
--- a/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -20,48 +20,31 @@
#include "content/browser/service_worker/embedded_worker_status.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_dispatcher_host.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/common/background_fetch/background_fetch_types.h"
#include "content/common/renderer.mojom.h"
-#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker.mojom.h"
#include "content/common/service_worker/service_worker_messages.h"
-#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/common/push_event_payload.h"
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "mojo/public/cpp/bindings/associated_binding_set.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "net/http/http_util.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "storage/common/blob_storage/blob_handle.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
namespace content {
namespace {
-class MockServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost {
- public:
- MockServiceWorkerDispatcherHost(int process_id, IPC::Sender* sender)
- : ServiceWorkerDispatcherHost(process_id), sender_(sender) {}
-
- bool Send(IPC::Message* message) override { return sender_->Send(message); }
-
- protected:
- ~MockServiceWorkerDispatcherHost() override {}
-
- private:
- IPC::Sender* sender_;
-
- DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerDispatcherHost);
-};
-
void OnFetchEventCommon(
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback) {
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) {
response_callback->OnResponse(
ServiceWorkerResponse(
std::make_unique<std::vector<GURL>>(), 200, "OK",
@@ -81,6 +64,51 @@ void OnFetchEventCommon(
} // namespace
+// A URLLoaderFactory that returns 200 OK with a simple body to any request.
+class EmbeddedWorkerTestHelper::MockNetworkURLLoaderFactory final
+ : public network::mojom::URLLoaderFactory {
+ public:
+ MockNetworkURLLoaderFactory() = default;
+
+ // network::mojom::URLLoaderFactory implementation.
+ void CreateLoaderAndStart(network::mojom::URLLoaderRequest request,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const network::ResourceRequest& url_request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag&
+ traffic_annotation) override {
+ 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()));
+ network::ResourceResponseHead response;
+ response.headers = info.headers;
+ response.headers->GetMimeType(&response.mime_type);
+ client->OnReceiveResponse(response);
+
+ 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(network::mojom::URLLoaderFactoryRequest request) override {
+ bindings_.AddBinding(this, std::move(request));
+ }
+
+ private:
+ mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+ DISALLOW_COPY_AND_ASSIGN(MockNetworkURLLoaderFactory);
+};
+
EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::
MockEmbeddedWorkerInstanceClient(
base::WeakPtr<EmbeddedWorkerTestHelper> helper)
@@ -99,7 +127,6 @@ void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::StartWorker(
EmbeddedWorkerInstance* worker =
helper_->registry()->GetWorker(params->embedded_worker_id);
ASSERT_TRUE(worker);
- EXPECT_EQ(EmbeddedWorkerStatus::STARTING, worker->status());
helper_->OnStartWorkerStub(std::move(params));
}
@@ -151,23 +178,22 @@ void EmbeddedWorkerTestHelper::MockEmbeddedWorkerInstanceClient::Bind(
client->binding_.Bind(std::move(request));
}
-class EmbeddedWorkerTestHelper::MockServiceWorkerEventDispatcher
- : public mojom::ServiceWorkerEventDispatcher {
+class EmbeddedWorkerTestHelper::MockServiceWorker
+ : public mojom::ServiceWorker {
public:
static void Create(const base::WeakPtr<EmbeddedWorkerTestHelper>& helper,
int embedded_worker_id,
- mojom::ServiceWorkerEventDispatcherRequest request) {
- mojo::MakeStrongBinding(std::make_unique<MockServiceWorkerEventDispatcher>(
- helper, embedded_worker_id),
- std::move(request));
+ mojom::ServiceWorkerRequest request) {
+ mojo::MakeStrongBinding(
+ std::make_unique<MockServiceWorker>(helper, embedded_worker_id),
+ std::move(request));
}
- MockServiceWorkerEventDispatcher(
- const base::WeakPtr<EmbeddedWorkerTestHelper>& helper,
- int embedded_worker_id)
+ MockServiceWorker(const base::WeakPtr<EmbeddedWorkerTestHelper>& helper,
+ int embedded_worker_id)
: helper_(helper), embedded_worker_id_(embedded_worker_id) {}
- ~MockServiceWorkerEventDispatcher() override {}
+ ~MockServiceWorker() override {}
void InitializeGlobalScope(
blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
@@ -246,7 +272,7 @@ class EmbeddedWorkerTestHelper::MockServiceWorkerEventDispatcher
}
void DispatchFetchEvent(
- mojom::DispatchFetchEventParamsPtr params,
+ blink::mojom::DispatchFetchEventParamsPtr params,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback) override {
if (!helper_)
@@ -294,7 +320,6 @@ class EmbeddedWorkerTestHelper::MockServiceWorkerEventDispatcher
}
void DispatchAbortPaymentEvent(
- int payment_request_id,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchAbortPaymentEventCallback callback) override {
if (!helper_)
@@ -304,7 +329,6 @@ class EmbeddedWorkerTestHelper::MockServiceWorkerEventDispatcher
}
void DispatchCanMakePaymentEvent(
- int payment_request_id,
payments::mojom::CanMakePaymentEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchCanMakePaymentEventCallback callback) override {
@@ -316,7 +340,6 @@ class EmbeddedWorkerTestHelper::MockServiceWorkerEventDispatcher
}
void DispatchPaymentRequestEvent(
- int payment_request_id,
payments::mojom::PaymentRequestEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchPaymentRequestEventCallback callback) override {
@@ -400,6 +423,8 @@ class EmbeddedWorkerTestHelper::MockRendererInterface : public mojom::Renderer {
void SetProcessBackgrounded(bool backgrounded) override { NOTREACHED(); }
void SetSchedulerKeepActive(bool keep_active) override { NOTREACHED(); }
void ProcessPurgeAndSuspend() override { NOTREACHED(); }
+ void SetIsLockedToSite() override { NOTREACHED(); }
+ void EnableV8LowMemoryMode() override { NOTREACHED(); }
base::WeakPtr<EmbeddedWorkerTestHelper> helper_;
mojo::AssociatedBindingSet<mojom::Renderer> bindings_;
@@ -407,11 +432,6 @@ class EmbeddedWorkerTestHelper::MockRendererInterface : public mojom::Renderer {
EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
const base::FilePath& user_data_directory)
- : EmbeddedWorkerTestHelper(user_data_directory, nullptr) {}
-
-EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
- const base::FilePath& user_data_directory,
- scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter)
: browser_context_(std::make_unique<TestBrowserContext>()),
render_process_host_(
std::make_unique<MockRenderProcessHost>(browser_context_.get())),
@@ -423,7 +443,8 @@ EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
next_thread_id_(0),
mock_render_process_id_(render_process_host_->GetID()),
new_mock_render_process_id_(new_render_process_host_->GetID()),
- url_loader_factory_getter_(std::move(url_loader_factory_getter)),
+ url_loader_factory_getter_(
+ base::MakeRefCounted<URLLoaderFactoryGetter>()),
weak_factory_(this) {
scoped_refptr<base::SequencedTaskRunner> database_task_runner =
base::ThreadTaskRunnerHandle::Get();
@@ -432,8 +453,6 @@ EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
url_loader_factory_getter_.get());
wrapper_->process_manager()->SetProcessIdForTest(mock_render_process_id());
wrapper_->process_manager()->SetNewProcessIdForTest(new_render_process_id());
- EnsureDispatcherHostForProcess(mock_render_process_id());
- EnsureDispatcherHostForProcess(new_render_process_id());
// Install a mocked mojom::Renderer interface to catch requests to
// establish Mojo connection for EWInstanceClient.
@@ -455,23 +474,27 @@ EmbeddedWorkerTestHelper::EmbeddedWorkerTestHelper(
new_renderer_interface_ptr.get()));
new_render_process_host_->OverrideRendererInterfaceForTesting(
std::move(new_renderer_interface_ptr));
-}
-EmbeddedWorkerTestHelper::~EmbeddedWorkerTestHelper() {
- if (wrapper_.get())
- wrapper_->Shutdown();
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ default_network_loader_factory_ =
+ std::make_unique<MockNetworkURLLoaderFactory>();
+ SetNetworkFactory(default_network_loader_factory_.get());
+ }
}
-bool EmbeddedWorkerTestHelper::Send(IPC::Message* message) {
- OnMessageReceived(*message);
- delete message;
- return true;
-}
+void EmbeddedWorkerTestHelper::SetNetworkFactory(
+ network::mojom::URLLoaderFactory* factory) {
+ if (!factory)
+ factory = default_network_loader_factory_.get();
-bool EmbeddedWorkerTestHelper::OnMessageReceived(const IPC::Message& message) {
- sink_.OnMessageReceived(message);
+ url_loader_factory_getter_->SetNetworkFactoryForTesting(factory);
+ render_process_host_->OverrideURLLoaderFactory(factory);
+ new_render_process_host_->OverrideURLLoaderFactory(factory);
+}
- return false;
+EmbeddedWorkerTestHelper::~EmbeddedWorkerTestHelper() {
+ if (wrapper_.get())
+ wrapper_->Shutdown();
}
void EmbeddedWorkerTestHelper::RegisterMockInstanceClient(
@@ -479,21 +502,6 @@ void EmbeddedWorkerTestHelper::RegisterMockInstanceClient(
mock_instance_clients_.push_back(std::move(client));
}
-void EmbeddedWorkerTestHelper::RegisterDispatcherHost(
- int process_id,
- scoped_refptr<ServiceWorkerDispatcherHost> dispatcher_host) {
- dispatcher_hosts_[process_id] = std::move(dispatcher_host);
-}
-
-void EmbeddedWorkerTestHelper::EnsureDispatcherHostForProcess(int process_id) {
- if (context()->GetDispatcherHost(process_id))
- return;
- auto dispatcher_host =
- base::MakeRefCounted<MockServiceWorkerDispatcherHost>(process_id, this);
- dispatcher_host->Init(wrapper_.get());
- RegisterDispatcherHost(process_id, std::move(dispatcher_host));
-}
-
ServiceWorkerContextCore* EmbeddedWorkerTestHelper::context() {
return wrapper_->context();
}
@@ -503,11 +511,6 @@ void EmbeddedWorkerTestHelper::ShutdownContext() {
wrapper_ = nullptr;
}
-ServiceWorkerDispatcherHost*
-EmbeddedWorkerTestHelper::GetDispatcherHostForProcess(int process_id) {
- return dispatcher_hosts_[process_id].get();
-}
-
// static
net::HttpResponseInfo EmbeddedWorkerTestHelper::CreateHttpResponseInfo() {
net::HttpResponseInfo info;
@@ -526,15 +529,15 @@ void EmbeddedWorkerTestHelper::OnStartWorker(
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
blink::mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info) {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
ASSERT_TRUE(worker);
- MockServiceWorkerEventDispatcher::Create(AsWeakPtr(), embedded_worker_id,
- std::move(dispatcher_request));
+ MockServiceWorker::Create(AsWeakPtr(), embedded_worker_id,
+ std::move(service_worker_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(
@@ -561,9 +564,11 @@ void EmbeddedWorkerTestHelper::DidSimulateWorkerScriptCached(
}
void EmbeddedWorkerTestHelper::OnResumeAfterDownload(int embedded_worker_id) {
- SimulateWorkerThreadStarted(GetNextThreadId(), embedded_worker_id);
- SimulateWorkerScriptEvaluated(embedded_worker_id, true /* success */);
- SimulateWorkerStarted(embedded_worker_id);
+ SimulateScriptEvaluationStart(embedded_worker_id);
+ SimulateWorkerStarted(
+ embedded_worker_id,
+ blink::mojom::ServiceWorkerStartStatus::kNormalCompletion,
+ GetNextThreadId());
}
void EmbeddedWorkerTestHelper::OnStopWorker(int embedded_worker_id) {
@@ -572,8 +577,7 @@ void EmbeddedWorkerTestHelper::OnStopWorker(int embedded_worker_id) {
}
void EmbeddedWorkerTestHelper::OnActivateEvent(
- mojom::ServiceWorkerEventDispatcher::DispatchActivateEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchActivateEventCallback callback) {
dispatched_events()->push_back(Event::Activate);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
@@ -583,8 +587,7 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchAbortEventCallback callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
@@ -592,8 +595,7 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent(
void EmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent(
const std::string& developer_id,
mojom::BackgroundFetchState state,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchClickEventCallback callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
@@ -602,8 +604,7 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchFailEventCallback callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
@@ -612,8 +613,7 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchedEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::DispatchBackgroundFetchedEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchedEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
@@ -621,23 +621,20 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchedEvent(
void EmbeddedWorkerTestHelper::OnCookieChangeEvent(
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
- mojom::ServiceWorkerEventDispatcher::DispatchCookieChangeEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchCookieChangeEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnExtendableMessageEvent(
mojom::ExtendableMessageEventPtr event,
- mojom::ServiceWorkerEventDispatcher::DispatchExtendableMessageEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnInstallEvent(
- mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchInstallEventCallback callback) {
dispatched_events()->push_back(Event::Install);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
true /* has_fetch_handler */, base::Time::Now());
@@ -646,17 +643,16 @@ void EmbeddedWorkerTestHelper::OnInstallEvent(
void EmbeddedWorkerTestHelper::OnFetchEvent(
int /* embedded_worker_id */,
const network::ResourceRequest& /* request */,
- mojom::FetchEventPreloadHandlePtr /* preload_handle */,
+ blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback) {
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) {
// TODO(falken): In-line common into here.
OnFetchEventCommon(std::move(response_callback), std::move(finish_callback));
}
void EmbeddedWorkerTestHelper::OnPushEvent(
const PushEventPayload& payload,
- mojom::ServiceWorkerEventDispatcher::DispatchPushEventCallback callback) {
+ mojom::ServiceWorker::DispatchPushEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
@@ -666,8 +662,7 @@ void EmbeddedWorkerTestHelper::OnNotificationClickEvent(
const PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
- mojom::ServiceWorkerEventDispatcher::DispatchNotificationClickEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchNotificationClickEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
@@ -675,16 +670,14 @@ void EmbeddedWorkerTestHelper::OnNotificationClickEvent(
void EmbeddedWorkerTestHelper::OnNotificationCloseEvent(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
- mojom::ServiceWorkerEventDispatcher::DispatchNotificationCloseEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback) {
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
}
void EmbeddedWorkerTestHelper::OnAbortPaymentEvent(
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchAbortPaymentEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback) {
response_callback->OnResponseForAbortPayment(true, base::Time::Now());
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
@@ -693,15 +686,12 @@ void EmbeddedWorkerTestHelper::OnAbortPaymentEvent(
void EmbeddedWorkerTestHelper::OnCanMakePaymentEvent(
payments::mojom::CanMakePaymentEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchCanMakePaymentEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) {
bool can_make_payment = false;
for (const auto& method_data : event_data->method_data) {
- for (const auto& method : method_data->supported_methods) {
- if (method == "test-method") {
- can_make_payment = true;
- break;
- }
+ if (method_data->supported_method == "test-method") {
+ can_make_payment = true;
+ break;
}
}
response_callback->OnResponseForCanMakePayment(can_make_payment,
@@ -713,8 +703,7 @@ void EmbeddedWorkerTestHelper::OnCanMakePaymentEvent(
void EmbeddedWorkerTestHelper::OnPaymentRequestEvent(
payments::mojom::PaymentRequestEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchPaymentRequestEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback) {
response_callback->OnResponseForPaymentRequest(
payments::mojom::PaymentHandlerResponse::New(), base::Time::Now());
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
@@ -768,34 +757,25 @@ void EmbeddedWorkerTestHelper::SimulateWorkerScriptLoaded(
base::RunLoop().RunUntilIdle();
}
-void EmbeddedWorkerTestHelper::SimulateWorkerThreadStarted(
- int thread_id,
+void EmbeddedWorkerTestHelper::SimulateScriptEvaluationStart(
int embedded_worker_id) {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
ASSERT_TRUE(worker);
ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]);
embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]
- ->OnThreadStarted(thread_id);
+ ->OnScriptEvaluationStart();
base::RunLoop().RunUntilIdle();
}
-void EmbeddedWorkerTestHelper::SimulateWorkerScriptEvaluated(
+void EmbeddedWorkerTestHelper::SimulateWorkerStarted(
int embedded_worker_id,
- bool success) {
- EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
- ASSERT_TRUE(worker);
- ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]);
- embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]
- ->OnScriptEvaluated(success);
- base::RunLoop().RunUntilIdle();
-}
-
-void EmbeddedWorkerTestHelper::SimulateWorkerStarted(int embedded_worker_id) {
+ blink::mojom::ServiceWorkerStartStatus status,
+ int thread_id) {
EmbeddedWorkerInstance* worker = registry()->GetWorker(embedded_worker_id);
ASSERT_TRUE(worker);
ASSERT_TRUE(embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]);
embedded_worker_id_instance_host_ptr_map_[embedded_worker_id]->OnStarted(
- mojom::EmbeddedWorkerStartTiming::New());
+ status, thread_id, mojom::EmbeddedWorkerStartTiming::New());
base::RunLoop().RunUntilIdle();
}
@@ -840,14 +820,13 @@ void EmbeddedWorkerTestHelper::OnStartWorkerStub(
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,
- std::move(params->dispatcher_request),
+ std::move(params->service_worker_request),
std::move(params->controller_request),
std::move(params->instance_host), std::move(params->provider_info),
std::move(params->installed_scripts_info)));
@@ -870,8 +849,7 @@ void EmbeddedWorkerTestHelper::OnStopWorkerStub(int embedded_worker_id) {
}
void EmbeddedWorkerTestHelper::OnActivateEventStub(
- mojom::ServiceWorkerEventDispatcher::DispatchActivateEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchActivateEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnActivateEvent,
AsWeakPtr(), std::move(callback)));
@@ -881,8 +859,7 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEventStub(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchAbortEventCallback callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEvent,
@@ -893,8 +870,7 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchAbortEventStub(
void EmbeddedWorkerTestHelper::OnBackgroundFetchClickEventStub(
const std::string& developer_id,
mojom::BackgroundFetchState state,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchClickEventCallback callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchClickEvent,
@@ -905,8 +881,7 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchFailEventStub(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchFailEventCallback callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchFailEvent,
@@ -918,8 +893,7 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchedEventStub(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::DispatchBackgroundFetchedEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchBackgroundFetchedEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnBackgroundFetchedEvent,
@@ -930,8 +904,7 @@ void EmbeddedWorkerTestHelper::OnBackgroundFetchedEventStub(
void EmbeddedWorkerTestHelper::OnCookieChangeEventStub(
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
- mojom::ServiceWorkerEventDispatcher::DispatchCookieChangeEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchCookieChangeEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnCookieChangeEvent,
@@ -940,8 +913,7 @@ void EmbeddedWorkerTestHelper::OnCookieChangeEventStub(
void EmbeddedWorkerTestHelper::OnExtendableMessageEventStub(
mojom::ExtendableMessageEventPtr event,
- mojom::ServiceWorkerEventDispatcher::DispatchExtendableMessageEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnExtendableMessageEvent,
@@ -949,8 +921,7 @@ void EmbeddedWorkerTestHelper::OnExtendableMessageEventStub(
}
void EmbeddedWorkerTestHelper::OnInstallEventStub(
- mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchInstallEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnInstallEvent,
AsWeakPtr(), std::move(callback)));
@@ -959,10 +930,9 @@ void EmbeddedWorkerTestHelper::OnInstallEventStub(
void EmbeddedWorkerTestHelper::OnFetchEventStub(
int embedded_worker_id,
const network::ResourceRequest& request,
- mojom::FetchEventPreloadHandlePtr preload_handle,
+ blink::mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback) {
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnFetchEvent, AsWeakPtr(),
@@ -975,8 +945,7 @@ void EmbeddedWorkerTestHelper::OnNotificationClickEventStub(
const PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
- mojom::ServiceWorkerEventDispatcher::DispatchNotificationClickEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchNotificationClickEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnNotificationClickEvent,
@@ -987,8 +956,7 @@ void EmbeddedWorkerTestHelper::OnNotificationClickEventStub(
void EmbeddedWorkerTestHelper::OnNotificationCloseEventStub(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
- mojom::ServiceWorkerEventDispatcher::DispatchNotificationCloseEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnNotificationCloseEvent,
@@ -998,7 +966,7 @@ void EmbeddedWorkerTestHelper::OnNotificationCloseEventStub(
void EmbeddedWorkerTestHelper::OnPushEventStub(
const PushEventPayload& payload,
- mojom::ServiceWorkerEventDispatcher::DispatchPushEventCallback callback) {
+ mojom::ServiceWorker::DispatchPushEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnPushEvent,
AsWeakPtr(), payload, std::move(callback)));
@@ -1006,8 +974,7 @@ void EmbeddedWorkerTestHelper::OnPushEventStub(
void EmbeddedWorkerTestHelper::OnAbortPaymentEventStub(
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchAbortPaymentEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&EmbeddedWorkerTestHelper::OnAbortPaymentEvent,
AsWeakPtr(), std::move(response_callback),
@@ -1017,8 +984,7 @@ void EmbeddedWorkerTestHelper::OnAbortPaymentEventStub(
void EmbeddedWorkerTestHelper::OnCanMakePaymentEventStub(
payments::mojom::CanMakePaymentEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchCanMakePaymentEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnCanMakePaymentEvent,
@@ -1029,8 +995,7 @@ void EmbeddedWorkerTestHelper::OnCanMakePaymentEventStub(
void EmbeddedWorkerTestHelper::OnPaymentRequestEventStub(
payments::mojom::PaymentRequestEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchPaymentRequestEventCallback
- callback) {
+ mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&EmbeddedWorkerTestHelper::OnPaymentRequestEvent,
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 609a99102b0..9204ee99207 100644
--- a/chromium/content/browser/service_worker/embedded_worker_test_helper.h
+++ b/chromium/content/browser/service_worker/embedded_worker_test_helper.h
@@ -20,15 +20,14 @@
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/browser/url_loader_factory_getter.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 "ipc/ipc_listener.h"
-#include "ipc/ipc_test_sink.h"
+#include "content/common/service_worker/service_worker.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/cookies/cookie_change_dispatcher.h"
#include "net/http/http_response_info.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom.h"
#include "url/gurl.h"
@@ -42,7 +41,6 @@ class EmbeddedWorkerTestHelper;
class MockRenderProcessHost;
class ServiceWorkerContextCore;
class ServiceWorkerContextWrapper;
-class ServiceWorkerDispatcherHost;
class TestBrowserContext;
struct PlatformNotificationData;
struct PushEventPayload;
@@ -61,8 +59,7 @@ struct PushEventPayload;
// methods to add their own logic/verification code.
//
// See embedded_worker_instance_unittest.cc for example usages.
-class EmbeddedWorkerTestHelper : public IPC::Sender,
- public IPC::Listener {
+class EmbeddedWorkerTestHelper {
public:
enum class Event { Install, Activate };
@@ -102,40 +99,16 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
EmbeddedWorkerTestHelper(
const base::FilePath& user_data_directory,
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter);
- ~EmbeddedWorkerTestHelper() override;
-
- // IPC::Sender implementation.
- bool Send(IPC::Message* message) override;
-
- // IPC::Listener implementation.
- bool OnMessageReceived(const IPC::Message& msg) override;
+ virtual ~EmbeddedWorkerTestHelper();
// Registers a Mojo endpoint object derived from
// MockEmbeddedWorkerInstanceClient.
void RegisterMockInstanceClient(
std::unique_ptr<MockEmbeddedWorkerInstanceClient> client);
- // Registers the dispatcher host for the process to a map managed by this test
- // helper. If there is a existing dispatcher host, it'll replace the existing
- // dispatcher host with the given one. When replacing, this should be called
- // before ServiceWorkerDispatcherHost::Init to allow the old dispatcher host
- // to destruct and remove itself from ServiceWorkerContextCore, since Init
- // adds to context core. If |dispatcher_host| is nullptr, this method just
- // removes the existing dispatcher host from the map.
- void RegisterDispatcherHost(
- int process_id,
- scoped_refptr<ServiceWorkerDispatcherHost> dispatcher_host);
-
- // Creates and registers a basic dispatcher host for the process if one
- // registered isn't already.
- void EnsureDispatcherHostForProcess(int process_id);
-
template <typename MockType, typename... Args>
MockType* CreateAndRegisterMockInstanceClient(Args&&... args);
- // IPC sink for EmbeddedWorker messages.
- IPC::TestSink* ipc_sink() { return &sink_; }
-
std::vector<Event>* dispatched_events() { return &events_; }
std::vector<std::unique_ptr<MockEmbeddedWorkerInstanceClient>>*
@@ -159,8 +132,6 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
TestBrowserContext* browser_context() { return browser_context_.get(); }
- ServiceWorkerDispatcherHost* GetDispatcherHostForProcess(int process_id);
-
base::WeakPtr<EmbeddedWorkerTestHelper> AsWeakPtr() {
return weak_factory_.GetWeakPtr();
}
@@ -171,17 +142,21 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
return url_loader_factory_getter_.get();
}
+ // Overrides the network URLLoaderFactory for subsequent requests. Passing a
+ // null pointer will restore the default behavior.
+ void SetNetworkFactory(network::mojom::URLLoaderFactory* factory);
+
protected:
// StartWorker IPC handler routed through MockEmbeddedWorkerInstanceClient.
// This simulates behaviors in the renderer process. Binds
- // |dispatcher_request| to MockServiceWorkerEventDispatcher by default.
+ // |service_worker_request| to MockServiceWorker by default.
virtual 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::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
@@ -195,88 +170,75 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
// On*Event handlers. By default they just return success via
// SimulateSendReplyToBrowser.
virtual void OnActivateEvent(
- mojom::ServiceWorkerEventDispatcher::DispatchActivateEventCallback
- callback);
+ mojom::ServiceWorker::DispatchActivateEventCallback callback);
virtual void OnBackgroundFetchAbortEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchAbortEventCallback callback);
+ mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback);
virtual void OnBackgroundFetchClickEvent(
const std::string& developer_id,
mojom::BackgroundFetchState state,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchClickEventCallback callback);
+ mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback);
virtual void OnBackgroundFetchFailEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchFailEventCallback callback);
+ mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback);
virtual void OnBackgroundFetchedEvent(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchedEventCallback callback);
+ mojom::ServiceWorker::DispatchBackgroundFetchedEventCallback callback);
virtual void OnCookieChangeEvent(
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
- mojom::ServiceWorkerEventDispatcher::DispatchCookieChangeEventCallback
- callback);
+ mojom::ServiceWorker::DispatchCookieChangeEventCallback callback);
virtual void OnExtendableMessageEvent(
mojom::ExtendableMessageEventPtr event,
- mojom::ServiceWorkerEventDispatcher::
- DispatchExtendableMessageEventCallback callback);
+ mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback);
virtual void OnInstallEvent(
- mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
- callback);
+ mojom::ServiceWorker::DispatchInstallEventCallback callback);
virtual void OnFetchEvent(
int embedded_worker_id,
const network::ResourceRequest& request,
- mojom::FetchEventPreloadHandlePtr preload_handle,
+ blink::mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback);
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback);
virtual void OnNotificationClickEvent(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
- mojom::ServiceWorkerEventDispatcher::
- DispatchNotificationClickEventCallback callback);
+ mojom::ServiceWorker::DispatchNotificationClickEventCallback callback);
virtual void OnNotificationCloseEvent(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
- mojom::ServiceWorkerEventDispatcher::
- DispatchNotificationCloseEventCallback callback);
+ mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback);
virtual void OnPushEvent(
const PushEventPayload& payload,
- mojom::ServiceWorkerEventDispatcher::DispatchPushEventCallback callback);
+ mojom::ServiceWorker::DispatchPushEventCallback callback);
virtual void OnAbortPaymentEvent(
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchAbortPaymentEventCallback
- callback);
+ mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback);
virtual void OnCanMakePaymentEvent(
payments::mojom::CanMakePaymentEventDataPtr data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchCanMakePaymentEventCallback
- callback);
+ mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback);
virtual void OnPaymentRequestEvent(
payments::mojom::PaymentRequestEventDataPtr data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchPaymentRequestEventCallback
- callback);
+ mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback);
// These functions simulate making Mojo calls to the browser.
void SimulateWorkerReadyForInspection(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);
- void SimulateWorkerStarted(int embedded_worker_id);
+ void SimulateScriptEvaluationStart(int embedded_worker_id);
+ void SimulateWorkerStarted(int embedded_worker_id,
+ blink::mojom::ServiceWorkerStartStatus status,
+ int thread_id);
void SimulateWorkerStopped(int embedded_worker_id);
EmbeddedWorkerRegistry* registry();
@@ -287,7 +249,8 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
}
private:
- class MockServiceWorkerEventDispatcher;
+ class MockNetworkURLLoaderFactory;
+ class MockServiceWorker;
class MockRendererInterface;
void DidSimulateWorkerScriptCached(int embedded_worker_id,
@@ -301,79 +264,65 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
void OnResumeAfterDownloadStub(int embedded_worker_id);
void OnStopWorkerStub(int embedded_worker_id);
void OnActivateEventStub(
- mojom::ServiceWorkerEventDispatcher::DispatchActivateEventCallback
- callback);
+ mojom::ServiceWorker::DispatchActivateEventCallback callback);
void OnBackgroundFetchAbortEventStub(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchAbortEventCallback callback);
+ mojom::ServiceWorker::DispatchBackgroundFetchAbortEventCallback callback);
void OnBackgroundFetchClickEventStub(
const std::string& developer_id,
mojom::BackgroundFetchState state,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchClickEventCallback callback);
+ mojom::ServiceWorker::DispatchBackgroundFetchClickEventCallback callback);
void OnBackgroundFetchFailEventStub(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchFailEventCallback callback);
+ mojom::ServiceWorker::DispatchBackgroundFetchFailEventCallback callback);
void OnBackgroundFetchedEventStub(
const std::string& developer_id,
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
- mojom::ServiceWorkerEventDispatcher::
- DispatchBackgroundFetchedEventCallback callback);
+ mojom::ServiceWorker::DispatchBackgroundFetchedEventCallback callback);
void OnCookieChangeEventStub(
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
- mojom::ServiceWorkerEventDispatcher::DispatchCookieChangeEventCallback
- callback);
+ mojom::ServiceWorker::DispatchCookieChangeEventCallback callback);
void OnExtendableMessageEventStub(
mojom::ExtendableMessageEventPtr event,
- mojom::ServiceWorkerEventDispatcher::
- DispatchExtendableMessageEventCallback callback);
+ mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback);
void OnInstallEventStub(
- mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
- callback);
+ mojom::ServiceWorker::DispatchInstallEventCallback callback);
void OnFetchEventStub(
int embedded_worker_id,
const network::ResourceRequest& request,
- mojom::FetchEventPreloadHandlePtr preload_handle,
+ blink::mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback);
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback);
void OnNotificationClickEventStub(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
int action_index,
const base::Optional<base::string16>& reply,
- mojom::ServiceWorkerEventDispatcher::
- DispatchNotificationClickEventCallback callback);
+ mojom::ServiceWorker::DispatchNotificationClickEventCallback callback);
void OnNotificationCloseEventStub(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
- mojom::ServiceWorkerEventDispatcher::
- DispatchNotificationCloseEventCallback callback);
+ mojom::ServiceWorker::DispatchNotificationCloseEventCallback callback);
void OnPushEventStub(
const PushEventPayload& payload,
- mojom::ServiceWorkerEventDispatcher::DispatchPushEventCallback callback);
+ mojom::ServiceWorker::DispatchPushEventCallback callback);
void OnAbortPaymentEventStub(
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchAbortPaymentEventCallback
- callback);
+ mojom::ServiceWorker::DispatchAbortPaymentEventCallback callback);
void OnCanMakePaymentEventStub(
payments::mojom::CanMakePaymentEventDataPtr data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchCanMakePaymentEventCallback
- callback);
+ mojom::ServiceWorker::DispatchCanMakePaymentEventCallback callback);
void OnPaymentRequestEventStub(
payments::mojom::PaymentRequestEventDataPtr data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchPaymentRequestEventCallback
- callback);
+ mojom::ServiceWorker::DispatchPaymentRequestEventCallback callback);
std::unique_ptr<TestBrowserContext> browser_context_;
std::unique_ptr<MockRenderProcessHost> render_process_host_;
@@ -381,8 +330,6 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
scoped_refptr<ServiceWorkerContextWrapper> wrapper_;
- IPC::TestSink sink_;
-
std::unique_ptr<MockRendererInterface> mock_renderer_interface_;
std::vector<std::unique_ptr<MockEmbeddedWorkerInstanceClient>>
mock_instance_clients_;
@@ -392,9 +339,6 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
int mock_render_process_id_;
int new_mock_render_process_id_;
- std::map<int /* process_id */, scoped_refptr<ServiceWorkerDispatcherHost>>
- dispatcher_hosts_;
-
std::map<int, int64_t> embedded_worker_id_service_worker_version_id_map_;
std::map<
@@ -417,6 +361,7 @@ class EmbeddedWorkerTestHelper : public IPC::Sender,
std::vector<Event> events_;
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter_;
+ std::unique_ptr<MockNetworkURLLoaderFactory> default_network_loader_factory_;
base::WeakPtrFactory<EmbeddedWorkerTestHelper> weak_factory_;
diff --git a/chromium/content/browser/service_worker/service_worker_browsertest.cc b/chromium/content/browser/service_worker/service_worker_browsertest.cc
index c12bec86b88..d8275ba30f8 100644
--- a/chromium/content/browser/service_worker/service_worker_browsertest.cc
+++ b/chromium/content/browser/service_worker/service_worker_browsertest.cc
@@ -43,13 +43,10 @@
#include "content/browser/service_worker/service_worker_fetch_dispatcher.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_type_converters.h"
#include "content/browser/service_worker/service_worker_version.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_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"
@@ -82,12 +79,14 @@
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/url_request/url_request_filter.h"
-#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_test_job.h"
#include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_data_snapshot.h"
#include "storage/browser/blob/blob_reader.h"
#include "storage/browser/blob/blob_storage_context.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_type_converters.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
@@ -104,7 +103,7 @@ const int kV8CacheTimeStampDataSize =
sizeof(uint32_t) + sizeof(uint32_t) + sizeof(double);
struct FetchResult {
- ServiceWorkerStatusCode status;
+ blink::ServiceWorkerStatusCode status;
ServiceWorkerFetchDispatcher::FetchEventResult result;
ServiceWorkerResponse response;
std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
@@ -156,8 +155,8 @@ base::OnceClosure CreatePrepareReceiver(bool* is_prepared) {
void ReceiveFindRegistrationStatus(
BrowserThread::ID run_quit_thread,
base::OnceClosure quit,
- ServiceWorkerStatusCode* out_status,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode* out_status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
*out_status = status;
if (!quit.is_null())
@@ -167,7 +166,7 @@ void ReceiveFindRegistrationStatus(
ServiceWorkerStorage::FindRegistrationCallback CreateFindRegistrationReceiver(
BrowserThread::ID run_quit_thread,
base::OnceClosure quit,
- ServiceWorkerStatusCode* status) {
+ blink::ServiceWorkerStatusCode* status) {
return base::BindOnce(&ReceiveFindRegistrationStatus, run_quit_thread,
std::move(quit), status);
}
@@ -206,6 +205,8 @@ class WorkerActivatedObserver
const ServiceWorkerVersion* version = context_->GetLiveVersion(version_id);
if (version->status() == ServiceWorkerVersion::ACTIVATED) {
context_->RemoveObserver(this);
+ version_id_ = version_id;
+ registration_id_ = version->registration_id();
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&WorkerActivatedObserver::Quit, this));
@@ -213,12 +214,18 @@ class WorkerActivatedObserver
}
void Wait() { run_loop_.Run(); }
+ int64_t registration_id() { return registration_id_; }
+ int64_t version_id() { return version_id_; }
+
private:
friend class base::RefCountedThreadSafe<WorkerActivatedObserver>;
~WorkerActivatedObserver() override {}
void InitOnIOThread() { context_->AddObserver(this); }
void Quit() { run_loop_.Quit(); }
+ int64_t registration_id_ = blink::mojom::kInvalidServiceWorkerRegistrationId;
+ int64_t version_id_ = blink::mojom::kInvalidServiceWorkerVersionId;
+
base::RunLoop run_loop_;
ServiceWorkerContextWrapper* context_;
DISALLOW_COPY_AND_ASSIGN(WorkerActivatedObserver);
@@ -290,52 +297,6 @@ VerifySaveDataNotInAccessControlRequestHeader(
return std::move(http_response);
}
-// The ImportsBustMemcache test requires that the imported script
-// would naturally be cached in blink's memcache, but the embedded
-// test server doesn't produce headers that allow the blink's memcache
-// to do that. This interceptor injects headers that give the import
-// an experiration far in the future.
-class LongLivedResourceInterceptor : public net::URLRequestInterceptor {
- public:
- explicit LongLivedResourceInterceptor(const std::string& body)
- : body_(body) {}
- ~LongLivedResourceInterceptor() override {}
-
- // net::URLRequestInterceptor implementation
- net::URLRequestJob* MaybeInterceptRequest(
- net::URLRequest* request,
- net::NetworkDelegate* network_delegate) const override {
- const char kHeaders[] =
- "HTTP/1.1 200 OK\n"
- "Content-Type: text/javascript\n"
- "Expires: Thu, 1 Jan 2100 20:00:00 GMT\n"
- "\n";
- std::string headers(kHeaders, arraysize(kHeaders));
- return new net::URLRequestTestJob(
- request, network_delegate, headers, body_, true);
- }
-
- private:
- std::string body_;
- DISALLOW_COPY_AND_ASSIGN(LongLivedResourceInterceptor);
-};
-
-void CreateLongLivedResourceInterceptors(
- const GURL& worker_url, const GURL& import_url) {
- ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
- std::unique_ptr<net::URLRequestInterceptor> interceptor;
-
- interceptor.reset(new LongLivedResourceInterceptor(
- "importScripts('long_lived_import.js');"));
- net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
- worker_url, std::move(interceptor));
-
- interceptor.reset(new LongLivedResourceInterceptor(
- "// the imported script does nothing"));
- net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
- import_url, std::move(interceptor));
-}
-
void CountScriptResources(
ServiceWorkerContextWrapper* wrapper,
const GURL& scope,
@@ -437,6 +398,24 @@ net::HttpResponseInfo CreateHttpResponseInfo() {
return info;
}
+// Returns a unique script for each request, to test service worker update.
+std::unique_ptr<net::test_server::HttpResponse> RequestHandlerForUpdateWorker(
+ const net::test_server::HttpRequest& request) {
+ static int counter = 0;
+
+ if (request.relative_url != "/service_worker/update_worker.js")
+ return std::unique_ptr<net::test_server::HttpResponse>();
+
+ auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
+ http_response->set_code(net::HTTP_OK);
+ http_response->set_content(
+ base::StringPrintf("// empty script. counter = %d\n", counter++));
+ http_response->set_content_type("text/javascript");
+ // Use a large max-age to test the browser cache.
+ http_response->AddCustomHeader("Cache-Control", "max-age=31536000");
+ return http_response;
+}
+
const char kNavigationPreloadAbortError[] =
"NetworkError: The service worker navigation preload request was cancelled "
"before 'preloadResponse' settled. If you intend to use 'preloadResponse', "
@@ -546,8 +525,6 @@ class ConsoleMessageContextObserver
// ServiceWorkerContextCoreObserver overrides.
void OnReportConsoleMessage(int64_t version_id,
- int process_id,
- int thread_id,
const ConsoleMessage& console_message) override {
messages_.push_back(console_message.message);
if (messages_.size() == expected_message_count_) {
@@ -588,25 +565,28 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
~ServiceWorkerVersionBrowserTest() override {}
void TearDownOnIOThread() override {
+ // Ensure that these resources are released while the IO thread still
+ // exists.
registration_ = nullptr;
version_ = nullptr;
+ blob_context_ = nullptr;
remote_endpoints_.clear();
}
void InstallTestHelper(const std::string& worker_url,
- ServiceWorkerStatusCode expected_status) {
+ blink::ServiceWorkerStatusCode expected_status) {
RunOnIOThread(base::BindOnce(&self::SetUpRegistrationOnIOThread,
base::Unretained(this), worker_url));
// Dispatch install on a worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop install_run_loop;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&self::InstallOnIOThread, base::Unretained(this),
install_run_loop.QuitClosure(), &status));
install_run_loop.Run();
- ASSERT_EQ(expected_status, status);
+ ASSERT_EQ(expected_status, status.value());
// Stop the worker.
base::RunLoop stop_run_loop;
@@ -617,17 +597,16 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
stop_run_loop.Run();
}
- void ActivateTestHelper(
- const std::string& worker_url,
- ServiceWorkerStatusCode expected_status) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ void ActivateTestHelper(const std::string& worker_url,
+ blink::ServiceWorkerStatusCode expected_status) {
+ base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop run_loop;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&self::ActivateOnIOThread, base::Unretained(this),
run_loop.QuitClosure(), &status));
run_loop.Run();
- ASSERT_EQ(expected_status, status);
+ ASSERT_EQ(expected_status, status.value());
}
void FetchOnRegisteredWorker(
@@ -638,7 +617,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
shell()->web_contents()->GetBrowserContext());
bool prepare_result = false;
FetchResult fetch_result;
- fetch_result.status = SERVICE_WORKER_ERROR_FAILED;
+ fetch_result.status = blink::ServiceWorkerStatusCode::kErrorFailed;
base::RunLoop fetch_run_loop;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -650,7 +629,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
*result = fetch_result.result;
*response = fetch_result.response;
*blob_data_handle = std::move(fetch_result.blob_data_handle);
- ASSERT_EQ(SERVICE_WORKER_OK, fetch_result.status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, fetch_result.status);
}
void SetUpRegistrationOnIOThread(const std::string& worker_url) {
@@ -711,16 +690,16 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
registration_->ActivateWaitingVersionWhenReady();
}
- void StartWorker(ServiceWorkerStatusCode expected_status) {
+ void StartWorker(blink::ServiceWorkerStatusCode expected_status) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop start_run_loop;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&self::StartOnIOThread, base::Unretained(this),
start_run_loop.QuitClosure(), &status));
start_run_loop.Run();
- ASSERT_EQ(expected_status, status);
+ ASSERT_EQ(expected_status, status.value());
}
void StopWorker() {
@@ -734,27 +713,42 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
}
void StoreRegistration(int64_t version_id,
- ServiceWorkerStatusCode expected_status) {
+ blink::ServiceWorkerStatusCode expected_status) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop store_run_loop;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&self::StoreOnIOThread, base::Unretained(this),
store_run_loop.QuitClosure(), &status, version_id));
store_run_loop.Run();
- ASSERT_EQ(expected_status, status);
+ ASSERT_EQ(expected_status, status.value());
RunOnIOThread(
base::BindOnce(&self::NotifyDoneInstallingRegistrationOnIOThread,
- base::Unretained(this), status));
+ base::Unretained(this), status.value()));
+ }
+
+ void UpdateRegistration(int64_t registration_id,
+ blink::ServiceWorkerStatusCode* out_status,
+ bool* out_update_found) {
+ base::RunLoop update_run_loop;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(
+ &self::UpdateOnIOThread, base::Unretained(this), registration_id,
+ base::BindOnce(
+ &self::ReceiveUpdateResultOnIOThread, base::Unretained(this),
+ update_run_loop.QuitClosure(), out_status, out_update_found)));
+ update_run_loop.Run();
}
void FindRegistrationForId(int64_t id,
const GURL& origin,
- ServiceWorkerStatusCode expected_status) {
+ blink::ServiceWorkerStatusCode expected_status) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
base::RunLoop run_loop;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -766,7 +760,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
}
void FindRegistrationForIdOnIOThread(base::OnceClosure done,
- ServiceWorkerStatusCode* result,
+ blink::ServiceWorkerStatusCode* result,
int64_t id,
const GURL& origin) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -777,7 +771,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
}
void NotifyDoneInstallingRegistrationOnIOThread(
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
wrapper()->context()->storage()->NotifyDoneInstallingRegistration(
registration_.get(), version_.get(), status);
@@ -789,15 +783,16 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
}
void StartOnIOThread(const base::Closure& done,
- ServiceWorkerStatusCode* result) {
+ base::Optional<blink::ServiceWorkerStatusCode>* result) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
version_->SetMainScriptHttpResponseInfo(CreateHttpResponseInfo());
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiver(BrowserThread::UI, done, result));
}
- void InstallOnIOThread(const base::Closure& done,
- ServiceWorkerStatusCode* result) {
+ void InstallOnIOThread(
+ const base::RepeatingClosure& done,
+ base::Optional<blink::ServiceWorkerStatusCode>* result) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
version_->RunAfterStartWorker(
ServiceWorkerMetrics::EventType::INSTALL,
@@ -807,22 +802,22 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
void DispatchInstallEventOnIOThread(
const base::Closure& done,
- ServiceWorkerStatusCode* result,
- ServiceWorkerStatusCode start_worker_status) {
+ base::Optional<blink::ServiceWorkerStatusCode>* result,
+ blink::ServiceWorkerStatusCode start_worker_status) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
- ASSERT_EQ(SERVICE_WORKER_OK, start_worker_status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, start_worker_status);
version_->SetStatus(ServiceWorkerVersion::INSTALLING);
int request_id =
version_->StartRequest(ServiceWorkerMetrics::EventType::INSTALL,
CreateReceiver(BrowserThread::UI, done, result));
- version_->event_dispatcher()->DispatchInstallEvent(
+ version_->endpoint()->DispatchInstallEvent(
base::BindOnce(&self::ReceiveInstallEventOnIOThread,
base::Unretained(this), done, result, request_id));
}
void ReceiveInstallEventOnIOThread(
const base::Closure& done,
- ServiceWorkerStatusCode* out_result,
+ base::Optional<blink::ServiceWorkerStatusCode>* out_result,
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
bool has_fetch_handler,
@@ -835,13 +830,13 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
? ServiceWorkerVersion::FetchHandlerExistence::EXISTS
: ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST);
- *out_result = mojo::ConvertTo<ServiceWorkerStatusCode>(status);
+ *out_result = mojo::ConvertTo<blink::ServiceWorkerStatusCode>(status);
if (!done.is_null())
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done);
}
void StoreOnIOThread(const base::Closure& done,
- ServiceWorkerStatusCode* result,
+ base::Optional<blink::ServiceWorkerStatusCode>* result,
int64_t version_id) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
ServiceWorkerVersion* version =
@@ -851,8 +846,9 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
CreateReceiver(BrowserThread::UI, done, result));
}
- void ActivateOnIOThread(const base::Closure& done,
- ServiceWorkerStatusCode* result) {
+ void ActivateOnIOThread(
+ const base::RepeatingClosure& done,
+ base::Optional<blink::ServiceWorkerStatusCode>* result) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
version_->RunAfterStartWorker(
ServiceWorkerMetrics::EventType::ACTIVATE,
@@ -862,19 +858,45 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
void DispatchActivateEventOnIOThread(
const base::Closure& done,
- ServiceWorkerStatusCode* result,
- ServiceWorkerStatusCode start_worker_status) {
+ base::Optional<blink::ServiceWorkerStatusCode>* result,
+ blink::ServiceWorkerStatusCode start_worker_status) {
ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
- ASSERT_EQ(SERVICE_WORKER_OK, start_worker_status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, start_worker_status);
version_->SetStatus(ServiceWorkerVersion::ACTIVATING);
registration_->SetActiveVersion(version_.get());
int request_id =
version_->StartRequest(ServiceWorkerMetrics::EventType::INSTALL,
CreateReceiver(BrowserThread::UI, done, result));
- version_->event_dispatcher()->DispatchActivateEvent(
+ version_->endpoint()->DispatchActivateEvent(
version_->CreateSimpleEventCallback(request_id));
}
+ void UpdateOnIOThread(int registration_id,
+ ServiceWorkerContextCore::UpdateCallback callback) {
+ ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ ServiceWorkerRegistration* registration =
+ wrapper()->context()->GetLiveRegistration(registration_id);
+ ASSERT_TRUE(registration);
+ wrapper()->context()->UpdateServiceWorker(
+ registration, false /* force_bypass_cache */,
+ false /* skip_script_comparison */, std::move(callback));
+ }
+
+ void ReceiveUpdateResultOnIOThread(const base::RepeatingClosure& done_on_ui,
+ blink::ServiceWorkerStatusCode* out_status,
+ bool* out_update_found,
+ blink::ServiceWorkerStatusCode status,
+ const std::string& status_message,
+ int64_t registration_id) {
+ ServiceWorkerRegistration* registration =
+ wrapper()->context()->GetLiveRegistration(registration_id);
+ DCHECK(registration);
+
+ *out_status = status;
+ *out_update_found = !!registration->installing_version();
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done_on_ui);
+ }
+
void FetchOnIOThread(const base::Closure& done,
bool* prepare_result,
FetchResult* result) {
@@ -897,6 +919,40 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
fetch_dispatcher_->Run();
}
+ base::Time GetLastUpdateCheck(int64_t registration_id) {
+ base::Time last_update_time;
+ base::RunLoop time_run_loop;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&self::GetLastUpdateCheckOnIOThread,
+ base::Unretained(this), registration_id,
+ &last_update_time, time_run_loop.QuitClosure()));
+ time_run_loop.Run();
+ return last_update_time;
+ }
+
+ void GetLastUpdateCheckOnIOThread(int64_t registration_id,
+ base::Time* out_time,
+ const base::RepeatingClosure& done_on_ui) {
+ ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ ServiceWorkerRegistration* registration =
+ wrapper()->context()->GetLiveRegistration(registration_id);
+ ASSERT_TRUE(registration);
+ *out_time = registration->last_update_check();
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done_on_ui);
+ }
+
+ void SetLastUpdateCheckOnIOThread(int64_t registration_id,
+ base::Time last_update_time,
+ const base::RepeatingClosure& done_on_ui) {
+ ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ ServiceWorkerRegistration* registration =
+ wrapper()->context()->GetLiveRegistration(registration_id);
+ ASSERT_TRUE(registration);
+ registration->set_last_update_check(last_update_time);
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done_on_ui);
+ }
+
// Contrary to the style guide, the output parameter of this function comes
// before input parameters so Bind can be used on it to create a FetchCallback
// to pass to DispatchFetchEvent.
@@ -904,7 +960,7 @@ class ServiceWorkerVersionBrowserTest : public ServiceWorkerBrowserTest {
const base::Closure& quit,
ChromeBlobStorageContext* blob_context,
FetchResult* out_result,
- ServiceWorkerStatusCode actual_status,
+ blink::ServiceWorkerStatusCode actual_status,
ServiceWorkerFetchDispatcher::FetchEventResult actual_result,
const ServiceWorkerResponse& actual_response,
blink::mojom::ServiceWorkerStreamHandlePtr /* stream */,
@@ -954,14 +1010,14 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, StartAndStop) {
"/service_worker/worker.js"));
// Start a worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop start_run_loop;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&self::StartOnIOThread, base::Unretained(this),
start_run_loop.QuitClosure(), &status));
start_run_loop.Run();
- ASSERT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
// Stop the worker.
base::RunLoop stop_run_loop;
@@ -981,18 +1037,18 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
base::Unretained(this),
"/service_worker/worker.js"));
// Start a worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop start_run_loop;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&self::StartOnIOThread, base::Unretained(this),
start_run_loop.QuitClosure(), &status));
start_run_loop.Run();
- ASSERT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
// Expect no PageVisits count.
EXPECT_EQ(nullptr, base::StatisticsRecorder::FindHistogram(
- "Blink.UseCounter.Features_Legacy"));
+ "Blink.UseCounter.Features"));
// Stop the worker.
base::RunLoop stop_run_loop;
@@ -1003,7 +1059,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
stop_run_loop.Run();
// Expect no PageVisits count.
EXPECT_EQ(nullptr, base::StatisticsRecorder::FindHistogram(
- "Blink.UseCounter.Features_Legacy"));
+ "Blink.UseCounter.Features"));
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, StartNotFound) {
@@ -1013,7 +1069,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, StartNotFound) {
"/service_worker/nonexistent.js"));
// Start a worker for nonexistent URL.
- StartWorker(SERVICE_WORKER_ERROR_NETWORK);
+ StartWorker(blink::ServiceWorkerStatusCode::kErrorNetwork);
}
#if defined(ANDROID)
@@ -1040,10 +1096,11 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
version_->script_cache_map()->SetResources(records);
// Store the registration.
- StoreRegistration(version_->version_id(), SERVICE_WORKER_OK);
+ StoreRegistration(version_->version_id(),
+ blink::ServiceWorkerStatusCode::kOk);
// Start the worker. We'll fail to read the resource.
- StartWorker(SERVICE_WORKER_ERROR_DISK_CACHE);
+ StartWorker(blink::ServiceWorkerStatusCode::kErrorDiskCache);
EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version_->status());
// The registration should be deleted from storage since the broken worker was
@@ -1052,15 +1109,17 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
base::Unretained(this), registration_->id()));
FindRegistrationForId(registration_->id(),
registration_->pattern().GetOrigin(),
- SERVICE_WORKER_ERROR_NOT_FOUND);
+ blink::ServiceWorkerStatusCode::kErrorNotFound);
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
ReadResourceFailure_WaitingWorker) {
StartServerAndNavigateToSetup();
// Create a registration and active version.
- InstallTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK);
- ActivateTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK);
+ InstallTestHelper("/service_worker/worker.js",
+ blink::ServiceWorkerStatusCode::kOk);
+ ActivateTestHelper("/service_worker/worker.js",
+ blink::ServiceWorkerStatusCode::kOk);
ASSERT_TRUE(registration_->active_version());
// Give the version a controllee.
@@ -1079,12 +1138,12 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
ServiceWorkerDatabase::ResourceRecord(31, version_->script_url(), 100)};
registration_->waiting_version()->script_cache_map()->SetResources(records);
StoreRegistration(registration_->waiting_version()->version_id(),
- SERVICE_WORKER_OK);
+ blink::ServiceWorkerStatusCode::kOk);
// Start the broken worker. We'll fail to read from disk and the worker should
// be doomed.
StopWorker(); // in case it's already running
- StartWorker(SERVICE_WORKER_ERROR_DISK_CACHE);
+ StartWorker(blink::ServiceWorkerStatusCode::kErrorDiskCache);
EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version_->status());
// The registration should still be in storage since the waiting worker was
@@ -1093,25 +1152,27 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
base::Unretained(this), registration_->id()));
FindRegistrationForId(registration_->id(),
registration_->pattern().GetOrigin(),
- SERVICE_WORKER_OK);
+ blink::ServiceWorkerStatusCode::kOk);
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, Install) {
StartServerAndNavigateToSetup();
- InstallTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK);
+ InstallTestHelper("/service_worker/worker.js",
+ blink::ServiceWorkerStatusCode::kOk);
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
InstallWithWaitUntil_Fulfilled) {
StartServerAndNavigateToSetup();
InstallTestHelper("/service_worker/worker_install_fulfilled.js",
- SERVICE_WORKER_OK);
+ blink::ServiceWorkerStatusCode::kOk);
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
InstallWithFetchHandler) {
StartServerAndNavigateToSetup();
- InstallTestHelper("/service_worker/fetch_event.js", SERVICE_WORKER_OK);
+ InstallTestHelper("/service_worker/fetch_event.js",
+ blink::ServiceWorkerStatusCode::kOk);
EXPECT_EQ(ServiceWorkerVersion::FetchHandlerExistence::EXISTS,
version_->fetch_handler_existence());
}
@@ -1119,7 +1180,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
InstallWithoutFetchHandler) {
StartServerAndNavigateToSetup();
- InstallTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK);
+ InstallTestHelper("/service_worker/worker.js",
+ blink::ServiceWorkerStatusCode::kOk);
EXPECT_EQ(ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST,
version_->fetch_handler_existence());
}
@@ -1131,30 +1193,35 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
embedded_test_server()->RegisterRequestHandler(
base::Bind(&VerifyServiceWorkerHeaderInRequest));
StartServerAndNavigateToSetup();
- InstallTestHelper("/service_worker/generated_sw.js", SERVICE_WORKER_OK);
+ InstallTestHelper("/service_worker/generated_sw.js",
+ blink::ServiceWorkerStatusCode::kOk);
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
Activate_NoEventListener) {
StartServerAndNavigateToSetup();
- InstallTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK);
- ActivateTestHelper("/service_worker/worker.js", SERVICE_WORKER_OK);
+ InstallTestHelper("/service_worker/worker.js",
+ blink::ServiceWorkerStatusCode::kOk);
+ ActivateTestHelper("/service_worker/worker.js",
+ blink::ServiceWorkerStatusCode::kOk);
ASSERT_EQ(ServiceWorkerVersion::ACTIVATING, version_->status());
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, Activate_Rejected) {
StartServerAndNavigateToSetup();
InstallTestHelper("/service_worker/worker_activate_rejected.js",
- SERVICE_WORKER_OK);
- ActivateTestHelper("/service_worker/worker_activate_rejected.js",
- SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED);
+ blink::ServiceWorkerStatusCode::kOk);
+ ActivateTestHelper(
+ "/service_worker/worker_activate_rejected.js",
+ blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected);
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
InstallWithWaitUntil_Rejected) {
StartServerAndNavigateToSetup();
- InstallTestHelper("/service_worker/worker_install_rejected.js",
- SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED);
+ InstallTestHelper(
+ "/service_worker/worker_install_rejected.js",
+ blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected);
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
@@ -1170,14 +1237,15 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
&console_listener));
// Dispatch install on a worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop install_run_loop;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&self::InstallOnIOThread, base::Unretained(this),
install_run_loop.QuitClosure(), &status));
install_run_loop.Run();
- ASSERT_EQ(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected,
+ status.value());
const base::string16 expected =
base::ASCIIToUTF16("Rejecting oninstall event");
@@ -1193,7 +1261,7 @@ class WaitForLoaded : public EmbeddedWorkerInstance::Listener {
public:
explicit WaitForLoaded(const base::Closure& quit) : quit_(quit) {}
- void OnThreadStarted() override {
+ void OnScriptEvaluationStart() override {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, quit_);
}
@@ -1209,7 +1277,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutStartingWorker) {
"/service_worker/while_true_worker.js"));
// Start a worker, waiting until the script is loaded.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop start_run_loop;
base::RunLoop load_run_loop;
WaitForLoaded wait_for_load(load_run_loop.QuitClosure());
@@ -1226,7 +1294,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutStartingWorker) {
&wait_for_load));
// The script has loaded but start has not completed yet.
- ASSERT_EQ(SERVICE_WORKER_ERROR_FAILED, status);
+ ASSERT_FALSE(status);
EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version_->running_status());
// Simulate execution timeout. Use a delay to prevent killing the worker
@@ -1236,7 +1304,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutStartingWorker) {
base::TimeDelta::FromMilliseconds(100));
start_run_loop.Run();
- EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout, status.value());
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutWorkerInEvent) {
@@ -1246,14 +1314,14 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutWorkerInEvent) {
"/service_worker/while_true_in_install_worker.js"));
// Start a worker.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
base::RunLoop start_run_loop;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&self::StartOnIOThread, base::Unretained(this),
start_run_loop.QuitClosure(), &status));
start_run_loop.Run();
- ASSERT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
// Dispatch an event.
base::RunLoop install_run_loop;
@@ -1271,7 +1339,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutWorkerInEvent) {
// Terminating a worker, even one in an infinite loop, is treated as if
// waitUntil was rejected in the renderer code.
- EXPECT_EQ(SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected,
+ status.value());
}
IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchEvent_Response) {
@@ -1279,8 +1348,10 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchEvent_Response) {
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);
+ InstallTestHelper("/service_worker/fetch_event.js",
+ blink::ServiceWorkerStatusCode::kOk);
+ ActivateTestHelper("/service_worker/fetch_event.js",
+ blink::ServiceWorkerStatusCode::kOk);
FetchOnRegisteredWorker(&result, &response, &blob_data_handle);
ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse,
@@ -1307,9 +1378,9 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
const base::Time start_time(base::Time::Now());
InstallTestHelper("/service_worker/fetch_event_response_via_cache.js",
- SERVICE_WORKER_OK);
+ blink::ServiceWorkerStatusCode::kOk);
ActivateTestHelper("/service_worker/fetch_event_response_via_cache.js",
- SERVICE_WORKER_OK);
+ blink::ServiceWorkerStatusCode::kOk);
FetchOnRegisteredWorker(&result, &response1, &blob_data_handle);
ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse,
@@ -1337,9 +1408,9 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
ServiceWorkerResponse response;
std::unique_ptr<storage::BlobDataHandle> blob_data_handle;
InstallTestHelper("/service_worker/fetch_event_rejected.js",
- SERVICE_WORKER_OK);
+ blink::ServiceWorkerStatusCode::kOk);
ActivateTestHelper("/service_worker/fetch_event_rejected.js",
- SERVICE_WORKER_OK);
+ blink::ServiceWorkerStatusCode::kOk);
ConsoleListener console_listener;
RunOnIOThread(base::BindOnce(&EmbeddedWorkerInstance::AddObserver,
@@ -1366,6 +1437,82 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
ASSERT_FALSE(blob_data_handle);
}
+// Tests that the browser cache is bypassed on update checks after 24 hours
+// elapsed since the last update check that accessed network.
+//
+// Due to the nature of what this is testing, this test depends on the system
+// clock being reasonable during the test. So it might break on daylight savings
+// leap or something:
+// https://groups.google.com/a/chromium.org/d/msg/chromium-dev/C3EvKPrb0XM/4Jv02SpNYncJ
+IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
+ UpdateBypassesCacheAfter24Hours) {
+ const char kScope[] = "/service_worker/handle_fetch.html";
+ const char kWorkerUrl[] = "/service_worker/update_worker.js";
+
+ // Tell the server to return a new script for each `update_worker.js` request.
+ embedded_test_server()->RegisterRequestHandler(
+ base::BindRepeating(&RequestHandlerForUpdateWorker));
+ StartServerAndNavigateToSetup();
+
+ // Register a service worker.
+
+ // Make options. Set to kAll so updating exercises the browser cache.
+ blink::mojom::ServiceWorkerRegistrationOptions options(
+ embedded_test_server()->GetURL(kScope),
+ blink::mojom::ServiceWorkerUpdateViaCache::kAll);
+
+ // Register and wait for activation.
+ auto observer = base::MakeRefCounted<WorkerActivatedObserver>(wrapper());
+ observer->Init();
+ public_context()->RegisterServiceWorker(
+ embedded_test_server()->GetURL(kWorkerUrl), options,
+ base::BindOnce(&ExpectResultAndRun, true, base::DoNothing()));
+ observer->Wait();
+ int64_t registration_id = observer->registration_id();
+
+ // The registration's last update time should be non-null.
+ base::Time last_update_time = GetLastUpdateCheck(registration_id);
+ EXPECT_NE(base::Time(), last_update_time);
+
+ // Try to update. The request should hit the browser cache so no update should
+ // be found.
+ {
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
+ bool update_found = true;
+ UpdateRegistration(registration_id, &status, &update_found);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
+ EXPECT_FALSE(update_found);
+ }
+ // The last update time should be unchanged.
+ EXPECT_EQ(last_update_time, GetLastUpdateCheck(registration_id));
+
+ // Set the last update time far in the past.
+ {
+ last_update_time = base::Time::Now() - base::TimeDelta::FromHours(24);
+ base::RunLoop time_run_loop;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&self::SetLastUpdateCheckOnIOThread,
+ base::Unretained(this), registration_id,
+ last_update_time, time_run_loop.QuitClosure()));
+ time_run_loop.Run();
+ }
+
+ // Try to update again. The browser cache should be bypassed so the update
+ // should be found.
+ {
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
+ bool update_found = false;
+ UpdateRegistration(registration_id, &status, &update_found);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
+ EXPECT_TRUE(update_found);
+ }
+ // The last update time should be bumped.
+ EXPECT_LT(last_update_time, GetLastUpdateCheck(registration_id));
+}
+
class MockContentBrowserClient : public TestContentBrowserClient {
public:
MockContentBrowserClient()
@@ -1398,7 +1545,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchWithSaveData) {
ContentBrowserClient* old_client =
SetBrowserClientForTesting(&content_browser_client);
shell()->web_contents()->GetRenderViewHost()->OnWebkitPreferencesChanged();
- InstallTestHelper("/service_worker/fetch_in_install.js", SERVICE_WORKER_OK);
+ InstallTestHelper("/service_worker/fetch_in_install.js",
+ blink::ServiceWorkerStatusCode::kOk);
SetBrowserClientForTesting(old_client);
}
@@ -1412,7 +1560,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest,
ContentBrowserClient* old_client =
SetBrowserClientForTesting(&content_browser_client);
shell()->web_contents()->GetRenderViewHost()->OnWebkitPreferencesChanged();
- InstallTestHelper("/service_worker/generated_sw.js", SERVICE_WORKER_OK);
+ InstallTestHelper("/service_worker/generated_sw.js",
+ blink::ServiceWorkerStatusCode::kOk);
SetBrowserClientForTesting(old_client);
}
@@ -1423,7 +1572,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchWithoutSaveData) {
MockContentBrowserClient content_browser_client;
ContentBrowserClient* old_client =
SetBrowserClientForTesting(&content_browser_client);
- InstallTestHelper("/service_worker/fetch_in_install.js", SERVICE_WORKER_OK);
+ InstallTestHelper("/service_worker/fetch_in_install.js",
+ blink::ServiceWorkerStatusCode::kOk);
SetBrowserClientForTesting(old_client);
}
@@ -2038,6 +2188,19 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest, NetworkError) {
IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest,
CanceledByInterceptor) {
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ // This is a test for a ResourceDispatcherHost interceptor cancelling the
+ // Navigation Preload request. The analogue for the
+ // NetworkService/ServiceWorker*Loader code path would be throttles, but
+ // these don't see Navigation Preload (crbug.com/825717) and there is no
+ // plan to allow them to, so just skip this test.
+
+ // This has to be called so the EmbeddedTestServer IO Thread is created,
+ // otherwise we crash on destruction.
+ embedded_test_server()->StartAcceptingConnections();
+ return;
+ }
+
content::ResourceDispatcherHost::Get()->RegisterInterceptor(
kNavigationPreloadHeaderName, "",
base::Bind(&CancellingInterceptorCallback));
@@ -2294,6 +2457,20 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest,
// correctly.
IN_PROC_BROWSER_TEST_F(ServiceWorkerNavigationPreloadTest,
RespondWithNavigationPreloadWithMimeSniffing) {
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ // When S13nSW/NetworkService is enabled, we don't do MIME sniffing
+ // (https://crbug.com/771118), so just skip this test. Also, this test was
+ // meant to test an internal quirk of MimeSniffingResourceHandler, which
+ // might not make sense in the NetworkService implementation anyway. If we
+ // want a behavior test for MIME sniffing for navigation preload, it can be
+ // an end-to-end layout test instead.
+
+ // This has to be called so the EmbeddedTestServer IO Thread is created,
+ // otherwise we crash on destruction.
+ embedded_test_server()->StartAcceptingConnections();
+ return;
+ }
+
const char kPageUrl[] = "/service_worker/navigation_preload.html";
const char kWorkerUrl[] = "/service_worker/navigation_preload.js";
const char kPage[] = "<title>PASS</title>Hello world.";
@@ -2405,15 +2582,9 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, ImportsBustMemcache) {
StartServerAndNavigateToSetup();
const char kScopeUrl[] = "/service_worker/imports_bust_memcache_scope/";
const char kPageUrl[] = "/service_worker/imports_bust_memcache.html";
- const char kScriptUrl[] = "/service_worker/worker_with_one_import.js";
- const char kImportUrl[] = "/service_worker/long_lived_import.js";
const base::string16 kOKTitle(base::ASCIIToUTF16("OK"));
const base::string16 kFailTitle(base::ASCIIToUTF16("FAIL"));
- RunOnIOThread(base::BindOnce(&CreateLongLivedResourceInterceptors,
- embedded_test_server()->GetURL(kScriptUrl),
- embedded_test_server()->GetURL(kImportUrl)));
-
TitleWatcher title_watcher(shell()->web_contents(), kOKTitle);
title_watcher.AlsoWaitForTitle(kFailTitle);
NavigateToURL(shell(), embedded_test_server()->GetURL(kPageUrl));
@@ -2429,8 +2600,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, ImportsBustMemcache) {
EXPECT_EQ(kExpectedNumResources, num_resources);
}
-// A listener that waits for the version to stop.
-class StopObserver : public ServiceWorkerVersion::Listener {
+// An observer that waits for the version to stop.
+class StopObserver : public ServiceWorkerVersion::Observer {
public:
explicit StopObserver(const base::Closure& quit_closure)
: quit_closure_(quit_closure) {}
@@ -2450,19 +2621,19 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, RendererCrash) {
RunOnIOThread(base::BindOnce(&self::SetUpRegistrationOnIOThread,
base::Unretained(this),
"/service_worker/worker.js"));
- StartWorker(SERVICE_WORKER_OK);
+ StartWorker(blink::ServiceWorkerStatusCode::kOk);
// Crash the renderer process. The version should stop.
base::RunLoop run_loop;
StopObserver observer(run_loop.QuitClosure());
- RunOnIOThread(base::BindOnce(&ServiceWorkerVersion::AddListener,
+ RunOnIOThread(base::BindOnce(&ServiceWorkerVersion::AddObserver,
base::Unretained(version_.get()), &observer));
shell()->web_contents()->GetMainFrame()->GetProcess()->Shutdown(
content::RESULT_CODE_KILLED);
run_loop.Run();
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
- RunOnIOThread(base::BindOnce(&ServiceWorkerVersion::RemoveListener,
+ RunOnIOThread(base::BindOnce(&ServiceWorkerVersion::RemoveObserver,
base::Unretained(version_.get()), &observer));
}
@@ -2471,7 +2642,7 @@ class ServiceWorkerBlackBoxBrowserTest : public ServiceWorkerBrowserTest {
using self = ServiceWorkerBlackBoxBrowserTest;
void FindRegistrationOnIO(const GURL& document_url,
- ServiceWorkerStatusCode* status,
+ blink::ServiceWorkerStatusCode* status,
const base::Closure& continuation) {
wrapper()->FindReadyRegistrationForDocument(
document_url,
@@ -2480,13 +2651,13 @@ class ServiceWorkerBlackBoxBrowserTest : public ServiceWorkerBrowserTest {
}
void FindRegistrationOnIO2(
- ServiceWorkerStatusCode* out_status,
+ blink::ServiceWorkerStatusCode* out_status,
const base::Closure& continuation,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
*out_status = status;
if (!registration.get())
- EXPECT_NE(SERVICE_WORKER_OK, status);
+ EXPECT_NE(blink::ServiceWorkerStatusCode::kOk, status);
continuation.Run();
}
};
@@ -2570,12 +2741,13 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBlackBoxBrowserTest, Registration) {
// Should not be able to find it.
{
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
RunOnIOThread(base::Bind(
&ServiceWorkerBlackBoxBrowserTest::FindRegistrationOnIO,
base::Unretained(this),
embedded_test_server()->GetURL("/service_worker/empty.html"), &status));
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound, status);
}
}
@@ -2626,7 +2798,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerSitePerProcessTest,
class ServiceWorkerVersionBrowserV8CacheTest
: public ServiceWorkerVersionBrowserTest,
- public ServiceWorkerVersion::Listener {
+ public ServiceWorkerVersion::Observer {
public:
using self = ServiceWorkerVersionBrowserV8CacheTest;
ServiceWorkerVersionBrowserV8CacheTest() {
@@ -2635,18 +2807,18 @@ class ServiceWorkerVersionBrowserV8CacheTest
}
~ServiceWorkerVersionBrowserV8CacheTest() override {
if (version_)
- version_->RemoveListener(this);
+ version_->RemoveObserver(this);
}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(switches::kV8CacheOptions, "code");
}
void SetUpRegistrationAndListenerOnIOThread(const std::string& worker_url) {
SetUpRegistrationOnIOThread(worker_url);
- version_->AddListener(this);
+ version_->AddObserver(this);
}
protected:
- // ServiceWorkerVersion::Listener overrides
+ // ServiceWorkerVersion::Observer overrides
void OnCachedMetadataUpdated(ServiceWorkerVersion* version,
size_t size) override {
metadata_size_ = size;
@@ -2671,7 +2843,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8CacheTest, Restart) {
cache_updated_closure_ = cached_metadata_run_loop.QuitClosure();
// Start a worker.
- StartWorker(SERVICE_WORKER_OK);
+ StartWorker(blink::ServiceWorkerStatusCode::kOk);
// Wait for the metadata to be stored. This run loop should finish when
// OnCachedMetadataUpdated() is called.
@@ -2688,14 +2860,14 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8CacheTest, Restart) {
base::RunLoop cached_metadata_run_loop;
cache_updated_closure_ = cached_metadata_run_loop.QuitClosure();
// Restart the worker.
- StartWorker(SERVICE_WORKER_OK);
+ StartWorker(blink::ServiceWorkerStatusCode::kOk);
// Wait for the matadata to be stored. This run loop should finish when
// OnCachedMetadataUpdated() is called.
cached_metadata_run_loop.Run();
}
// The V8 code cache should be stored to the storage. It must have size
- // greater than 12 bytes.
+ // greater than 16 bytes.
EXPECT_GT(static_cast<int>(metadata_size_), kV8CacheTimeStampDataSize);
// Stop the worker.
@@ -2704,7 +2876,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8CacheTest, Restart) {
class ServiceWorkerVersionBrowserV8FullCodeCacheTest
: public ServiceWorkerVersionBrowserTest,
- public ServiceWorkerVersion::Listener {
+ public ServiceWorkerVersion::Observer {
public:
using self = ServiceWorkerVersionBrowserV8FullCodeCacheTest;
ServiceWorkerVersionBrowserV8FullCodeCacheTest() {
@@ -2713,15 +2885,15 @@ class ServiceWorkerVersionBrowserV8FullCodeCacheTest
}
~ServiceWorkerVersionBrowserV8FullCodeCacheTest() override {
if (version_)
- version_->RemoveListener(this);
+ version_->RemoveObserver(this);
}
void SetUpRegistrationAndListenerOnIOThread(const std::string& worker_url) {
SetUpRegistrationOnIOThread(worker_url);
- version_->AddListener(this);
+ version_->AddObserver(this);
}
protected:
- // ServiceWorkerVersion::Listener overrides
+ // ServiceWorkerVersion::Observer overrides
void OnCachedMetadataUpdated(ServiceWorkerVersion* version,
size_t size) override {
metadata_size_ = size;
@@ -2746,14 +2918,14 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserV8FullCodeCacheTest,
cache_updated_closure_ = cached_metadata_run_loop.QuitClosure();
// Start a worker.
- StartWorker(SERVICE_WORKER_OK);
+ StartWorker(blink::ServiceWorkerStatusCode::kOk);
// Wait for the metadata to be stored. This run loop should finish when
// OnCachedMetadataUpdated() is called.
cached_metadata_run_loop.Run();
// The V8 code cache should be stored to the storage. It must have size
- // greater than 12 bytes.
+ // greater than 16 bytes.
EXPECT_GT(static_cast<int>(metadata_size_), kV8CacheTimeStampDataSize);
// Stop the worker.
@@ -2928,7 +3100,7 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerV8CodeCacheForCacheStorageTest,
WaitUntilSideDataSizeIs(0);
// Second load: The V8 code cache should be stored in CacheStorage. It must
- // have size greater than 12 bytes.
+ // have size greater than 16 bytes.
NavigateToTestPage();
WaitUntilSideDataSizeIsBiggerThan(kV8CacheTimeStampDataSize);
}
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 947d1166e58..c2252ec96fa 100644
--- a/chromium/content/browser/service_worker/service_worker_client_utils.cc
+++ b/chromium/content/browser/service_worker/service_worker_client_utils.cc
@@ -549,14 +549,14 @@ void DidNavigate(const base::WeakPtr<ServiceWorkerContextCore>& context,
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT,
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort,
nullptr /* client_info */);
return;
}
if (render_process_id == ChildProcessHost::kInvalidUniqueID &&
render_frame_id == MSG_ROUTING_NONE) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_FAILED,
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorFailed,
nullptr /* client_info */);
return;
}
@@ -575,13 +575,15 @@ void DidNavigate(const base::WeakPtr<ServiceWorkerContextCore>& context,
base::BindOnce(&GetWindowClientInfoOnUI, provider_host->process_id(),
provider_host->route_id(), provider_host->create_time(),
provider_host->client_uuid()),
- base::BindOnce(std::move(callback), SERVICE_WORKER_OK));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kOk));
return;
}
// If here, it means that no provider_host was found, in which case, the
// renderer should still be informed that the window was opened.
- std::move(callback).Run(SERVICE_WORKER_OK, nullptr /* client_info */);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kOk,
+ nullptr /* client_info */);
}
} // namespace service_worker_client_utils
diff --git a/chromium/content/browser/service_worker/service_worker_client_utils.h b/chromium/content/browser/service_worker/service_worker_client_utils.h
index 93ac4aba752..e927d202c5d 100644
--- a/chromium/content/browser/service_worker/service_worker_client_utils.h
+++ b/chromium/content/browser/service_worker/service_worker_client_utils.h
@@ -10,7 +10,7 @@
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
class GURL;
@@ -24,7 +24,7 @@ class ServiceWorkerVersion;
namespace service_worker_client_utils {
using NavigationCallback = base::OnceCallback<void(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
blink::mojom::ServiceWorkerClientInfoPtr client_info)>;
using ClientCallback = base::OnceCallback<void(
blink::mojom::ServiceWorkerClientInfoPtr client_info)>;
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 46f20d354a1..8e6f44affb4 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_core.cc
@@ -23,7 +23,6 @@
#include "content/browser/service_worker/embedded_worker_status.h"
#include "content/browser/service_worker/service_worker_context_core_observer.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_info.h"
#include "content/browser/service_worker/service_worker_job_coordinator.h"
#include "content/browser/service_worker/service_worker_process_manager.h"
@@ -35,6 +34,7 @@
#include "content/browser/url_loader_factory_getter.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/common/child_process_host.h"
#include "ipc/ipc_message.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
@@ -69,8 +69,8 @@ void CheckFetchHandlerOfInstalledServiceWorker(
void SuccessCollectorCallback(base::OnceClosure done_closure,
bool* overall_success,
- ServiceWorkerStatusCode status) {
- if (status != ServiceWorkerStatusCode::SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode status) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
*overall_success = false;
}
std::move(done_closure).Run();
@@ -78,12 +78,12 @@ void SuccessCollectorCallback(base::OnceClosure done_closure,
void SuccessReportingCallback(
const bool* success,
- base::OnceCallback<void(ServiceWorkerStatusCode)> callback) {
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)> callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
bool result = *success;
- std::move(callback).Run(
- result ? ServiceWorkerStatusCode::SERVICE_WORKER_OK
- : ServiceWorkerStatusCode::SERVICE_WORKER_ERROR_FAILED);
+ std::move(callback).Run(result
+ ? blink::ServiceWorkerStatusCode::kOk
+ : blink::ServiceWorkerStatusCode::kErrorFailed);
}
bool IsSameOriginClientProviderHost(const GURL& origin,
@@ -127,7 +127,7 @@ class ClearAllServiceWorkersHelper
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
- void OnResult(ServiceWorkerStatusCode) {
+ void OnResult(blink::ServiceWorkerStatusCode) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// We do nothing in this method. We use this class to wait for all callbacks
// to be called using the refcount.
@@ -135,9 +135,9 @@ class ClearAllServiceWorkersHelper
void DidGetAllRegistrations(
const base::WeakPtr<ServiceWorkerContextCore>& context,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
- if (!context || status != SERVICE_WORKER_OK)
+ if (!context || status != blink::ServiceWorkerStatusCode::kOk)
return;
// Make a copy of live versions map because StopWorker() removes the version
// from it when we were starting up and don't have a process yet.
@@ -299,7 +299,6 @@ ServiceWorkerContextCore::ServiceWorkerContextCore(
ServiceWorkerContextCore* old_context,
ServiceWorkerContextWrapper* wrapper)
: wrapper_(wrapper),
- dispatcher_hosts_(std::move(old_context->dispatcher_hosts_)),
providers_(old_context->providers_.release()),
provider_by_uuid_(old_context->provider_by_uuid_.release()),
loader_factory_getter_(old_context->loader_factory_getter()),
@@ -321,41 +320,18 @@ ServiceWorkerContextCore::ServiceWorkerContextCore(
ServiceWorkerContextCore::~ServiceWorkerContextCore() {
DCHECK(storage_);
for (const auto& it : live_versions_)
- it.second->RemoveListener(this);
+ it.second->RemoveObserver(this);
weak_factory_.InvalidateWeakPtrs();
}
-void ServiceWorkerContextCore::AddDispatcherHost(
- int process_id,
- content::ServiceWorkerDispatcherHost* dispatcher_host) {
- DCHECK(dispatcher_hosts_.find(process_id) == dispatcher_hosts_.end());
- dispatcher_hosts_[process_id] = dispatcher_host;
-}
-
-ServiceWorkerDispatcherHost* ServiceWorkerContextCore::GetDispatcherHost(
- int process_id) {
- auto it = dispatcher_hosts_.find(process_id);
- if (it == dispatcher_hosts_.end())
- return nullptr;
- return it->second;
-}
-
-void ServiceWorkerContextCore::RemoveDispatcherHost(int process_id) {
- DCHECK(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);
-}
-
void ServiceWorkerContextCore::AddProviderHost(
std::unique_ptr<ServiceWorkerProviderHost> host) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
int process_id = host->process_id();
int provider_id = host->provider_id();
+ // Precreated hosts are stored in the same map regardless of process.
+ if (ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id))
+ process_id = ChildProcessHost::kInvalidUniqueID;
ProviderMap* map = GetProviderMapForProcess(process_id);
if (!map) {
providers_->AddWithID(std::make_unique<ProviderMap>(), process_id);
@@ -364,22 +340,13 @@ void ServiceWorkerContextCore::AddProviderHost(
map->AddWithID(std::move(host), provider_id);
}
-std::unique_ptr<ServiceWorkerProviderHost>
-ServiceWorkerContextCore::ReleaseProviderHost(int process_id, int provider_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- ProviderMap* map = GetProviderMapForProcess(process_id);
- if (!map || !map->Lookup(provider_id))
- return nullptr;
- std::unique_ptr<ServiceWorkerProviderHost> host =
- map->Replace(provider_id, nullptr);
- map->Remove(provider_id);
- return host;
-}
-
ServiceWorkerProviderHost* ServiceWorkerContextCore::GetProviderHost(
int process_id,
int provider_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Precreated hosts are stored in the same map regardless of process.
+ if (ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id))
+ process_id = ChildProcessHost::kInvalidUniqueID;
ProviderMap* map = GetProviderMapForProcess(process_id);
if (!map)
return nullptr;
@@ -389,6 +356,9 @@ ServiceWorkerProviderHost* ServiceWorkerContextCore::GetProviderHost(
void ServiceWorkerContextCore::RemoveProviderHost(
int process_id, int provider_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Precreated hosts are stored in the same map regardless of process.
+ if (ServiceWorkerUtils::IsBrowserAssignedProviderId(provider_id))
+ process_id = ChildProcessHost::kInvalidUniqueID;
ProviderMap* map = GetProviderMapForProcess(process_id);
DCHECK(map);
map->Remove(provider_id);
@@ -399,6 +369,10 @@ void ServiceWorkerContextCore::RemoveAllProviderHostsForProcess(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (providers_->Lookup(process_id))
providers_->Remove(process_id);
+ // This function is used to prevent <process_id, provider_id> collisions when
+ // a render process host is reused with the same process id. Don't bother
+ // removing the providers in this process with browser-assigned ids, which
+ // live in a different map, since they have unique ids.
}
std::unique_ptr<ServiceWorkerContextCore::ProviderHostIterator>
@@ -514,11 +488,11 @@ void ServiceWorkerContextCore::DeleteForOrigin(const GURL& origin,
}
void ServiceWorkerContextCore::DidGetRegistrationsForDeleteForOrigin(
- base::OnceCallback<void(ServiceWorkerStatusCode)> callback,
- ServiceWorkerStatusCode status,
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)> callback,
+ blink::ServiceWorkerStatusCode status,
const std::vector<scoped_refptr<ServiceWorkerRegistration>>&
registrations) {
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(status);
return;
}
@@ -551,10 +525,10 @@ ServiceWorkerContextCore::GetProviderMapForProcess(int process_id) {
void ServiceWorkerContextCore::RegistrationComplete(
const GURL& pattern,
ServiceWorkerContextCore::RegistrationCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
ServiceWorkerRegistration* registration) {
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
DCHECK(!registration);
std::move(callback).Run(status, status_message,
blink::mojom::kInvalidServiceWorkerRegistrationId);
@@ -572,10 +546,10 @@ void ServiceWorkerContextCore::RegistrationComplete(
void ServiceWorkerContextCore::UpdateComplete(
ServiceWorkerContextCore::UpdateCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
ServiceWorkerRegistration* registration) {
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
DCHECK(!registration);
std::move(callback).Run(status, status_message,
blink::mojom::kInvalidServiceWorkerRegistrationId);
@@ -590,9 +564,9 @@ void ServiceWorkerContextCore::UnregistrationComplete(
const GURL& pattern,
ServiceWorkerContextCore::UnregistrationCallback callback,
int64_t registration_id,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
std::move(callback).Run(status);
- if (status == SERVICE_WORKER_OK) {
+ if (status == blink::ServiceWorkerStatusCode::kOk) {
observer_list_->Notify(
FROM_HERE, &ServiceWorkerContextCoreObserver::OnRegistrationDeleted,
registration_id, pattern);
@@ -628,7 +602,7 @@ void ServiceWorkerContextCore::AddLiveVersion(ServiceWorkerVersion* version) {
// the version ID conflict. Otherwise change CHECK to DCHECK.
CHECK(!GetLiveVersion(version->version_id()));
live_versions_[version->version_id()] = version;
- version->AddListener(this);
+ version->AddObserver(this);
ServiceWorkerVersionInfo version_info = version->GetInfo();
observer_list_->Notify(FROM_HERE,
&ServiceWorkerContextCoreObserver::OnNewLiveVersion,
@@ -712,9 +686,9 @@ void ServiceWorkerContextCore::CheckHasServiceWorker(
void ServiceWorkerContextCore::UpdateVersionFailureCount(
int64_t version_id,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
// Don't count these, they aren't start worker failures.
- if (status == SERVICE_WORKER_ERROR_DISALLOWED)
+ if (status == blink::ServiceWorkerStatusCode::kErrorDisallowed)
return;
auto it = failure_counts_.find(version_id);
@@ -723,7 +697,7 @@ void ServiceWorkerContextCore::UpdateVersionFailureCount(
status);
}
- if (status == SERVICE_WORKER_OK) {
+ if (status == blink::ServiceWorkerStatusCode::kOk) {
if (it != failure_counts_.end())
failure_counts_.erase(it);
return;
@@ -810,8 +784,7 @@ void ServiceWorkerContextCore::OnErrorReported(
const GURL& source_url) {
observer_list_->Notify(
FROM_HERE, &ServiceWorkerContextCoreObserver::OnErrorReported,
- version->version_id(), version->embedded_worker()->process_id(),
- version->embedded_worker()->thread_id(),
+ version->version_id(),
ServiceWorkerContextCoreObserver::ErrorInfo(error_message, line_number,
column_number, source_url));
}
@@ -825,8 +798,7 @@ void ServiceWorkerContextCore::OnReportConsoleMessage(
const GURL& source_url) {
observer_list_->Notify(
FROM_HERE, &ServiceWorkerContextCoreObserver::OnReportConsoleMessage,
- version->version_id(), version->embedded_worker()->process_id(),
- version->embedded_worker()->thread_id(),
+ version->version_id(),
ServiceWorkerContextCoreObserver::ConsoleMessage(
source_identifier, message_level, message, line_number, source_url));
}
@@ -855,9 +827,9 @@ ServiceWorkerProcessManager* ServiceWorkerContextCore::process_manager() {
void ServiceWorkerContextCore::DidFindRegistrationForCheckHasServiceWorker(
const GURL& other_url,
ServiceWorkerContext::CheckHasServiceWorkerCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(ServiceWorkerCapability::NO_SERVICE_WORKER);
return;
}
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 5168ea6801c..9a299aa9eb2 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core.h
+++ b/chromium/content/browser/service_worker/service_worker_context_core.h
@@ -43,7 +43,6 @@ namespace content {
class EmbeddedWorkerRegistry;
class ServiceWorkerContextCoreObserver;
class ServiceWorkerContextWrapper;
-class ServiceWorkerDispatcherHost;
class ServiceWorkerJobCoordinator;
class ServiceWorkerProviderHost;
class ServiceWorkerRegistration;
@@ -56,21 +55,22 @@ class URLLoaderFactoryGetter;
// is the root of the containment hierarchy for service worker data
// associated with a particular partition.
class CONTENT_EXPORT ServiceWorkerContextCore
- : public ServiceWorkerVersion::Listener {
+ : public ServiceWorkerVersion::Observer {
public:
using BoolCallback = base::OnceCallback<void(bool)>;
using StatusCallback =
- base::OnceCallback<void(ServiceWorkerStatusCode status)>;
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode status)>;
using RegistrationCallback =
- base::OnceCallback<void(ServiceWorkerStatusCode status,
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id)>;
using UpdateCallback =
- base::OnceCallback<void(ServiceWorkerStatusCode status,
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id)>;
using UnregistrationCallback =
- base::OnceCallback<void(ServiceWorkerStatusCode status)>;
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode status)>;
+ // TODO(falken): Change these to just use std::map.
using ProviderMap = base::IDMap<std::unique_ptr<ServiceWorkerProviderHost>>;
using ProcessToProviderMap = base::IDMap<std::unique_ptr<ProviderMap>>;
@@ -81,6 +81,8 @@ class CONTENT_EXPORT ServiceWorkerContextCore
static const base::FilePath::CharType kServiceWorkerDirectory[];
// Iterates over ServiceWorkerProviderHost objects in a ProcessToProviderMap.
+ // TODO(falken): This can just iterate over the simple map
+ // |providers_by_uuid_| for simplicity.
class CONTENT_EXPORT ProviderHostIterator {
public:
~ProviderHostIterator();
@@ -129,7 +131,7 @@ class CONTENT_EXPORT ServiceWorkerContextCore
void OnStorageWiped();
- // ServiceWorkerVersion::Listener overrides.
+ // ServiceWorkerVersion::Observer overrides.
void OnRunningStateChanged(ServiceWorkerVersion* version) override;
void OnVersionStateChanged(ServiceWorkerVersion* version) override;
void OnDevToolsRoutingIdChanged(ServiceWorkerVersion* version) override;
@@ -161,20 +163,13 @@ class CONTENT_EXPORT ServiceWorkerContextCore
return job_coordinator_.get();
}
- // Maintains DispatcherHosts to exchange service worker related messages
- // through them. The DispatcherHosts are not owned by this class.
- void AddDispatcherHost(int process_id,
- ServiceWorkerDispatcherHost* dispatcher_host);
- ServiceWorkerDispatcherHost* GetDispatcherHost(int process_id);
- void RemoveDispatcherHost(int process_id);
-
// The context class owns the set of ProviderHosts.
+ //
+ // For browser-assigned provider ids, the |process_id| parameter is ignored,
+ // since they have unique ids.
void AddProviderHost(
std::unique_ptr<ServiceWorkerProviderHost> provider_host);
ServiceWorkerProviderHost* GetProviderHost(int process_id, int provider_id);
- std::unique_ptr<ServiceWorkerProviderHost> ReleaseProviderHost(
- int process_id,
- int provider_id);
void RemoveProviderHost(int process_id, int provider_id);
void RemoveAllProviderHostsForProcess(int process_id);
@@ -211,14 +206,16 @@ class CONTENT_EXPORT ServiceWorkerContextCore
UnregistrationCallback callback);
// 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.
+ // blink::ServiceWorkerStatusCode::kOk if all succeed, or
+ // SERVICE_WORKER_FAILED if any did not succeed.
void DeleteForOrigin(const GURL& origin, StatusCallback callback);
// Updates the service worker. If |force_bypass_cache| is true or 24 hours
// have passed since the last update, bypasses the browser cache.
void UpdateServiceWorker(ServiceWorkerRegistration* registration,
bool force_bypass_cache);
+ // |callback| is called when the promise for
+ // ServiceWorkerRegistration.update() would be resolved.
void UpdateServiceWorker(ServiceWorkerRegistration* registration,
bool force_bypass_cache,
bool skip_script_comparison,
@@ -275,7 +272,7 @@ class CONTENT_EXPORT ServiceWorkerContextCore
const ServiceWorkerContext::CheckHasServiceWorkerCallback callback);
void UpdateVersionFailureCount(int64_t version_id,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// Returns the count of consecutive start worker failures for the given
// version. The count resets to zero when the worker successfully starts.
int GetVersionFailureCount(int64_t version_id);
@@ -300,37 +297,37 @@ class CONTENT_EXPORT ServiceWorkerContextCore
struct FailureInfo {
int count;
- ServiceWorkerStatusCode last_failure;
+ blink::ServiceWorkerStatusCode last_failure;
};
ProviderMap* GetProviderMapForProcess(int process_id);
void RegistrationComplete(const GURL& pattern,
RegistrationCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
ServiceWorkerRegistration* registration);
void UpdateComplete(UpdateCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
ServiceWorkerRegistration* registration);
void UnregistrationComplete(const GURL& pattern,
UnregistrationCallback callback,
int64_t registration_id,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void DidGetRegistrationsForDeleteForOrigin(
- base::OnceCallback<void(ServiceWorkerStatusCode)> callback,
- ServiceWorkerStatusCode status,
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)> callback,
+ blink::ServiceWorkerStatusCode status,
const std::vector<scoped_refptr<ServiceWorkerRegistration>>&
registrations);
void DidFindRegistrationForCheckHasServiceWorker(
const GURL& other_url,
ServiceWorkerContext::CheckHasServiceWorkerCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void OnRegistrationFinishedForCheckHasServiceWorker(
ServiceWorkerContext::CheckHasServiceWorkerCallback callback,
@@ -340,10 +337,13 @@ class CONTENT_EXPORT ServiceWorkerContextCore
// because the Wrapper::Shutdown call that hops threads to destroy |this| uses
// Bind() to hold a reference to |wrapper_| until |this| is fully destroyed.
ServiceWorkerContextWrapper* wrapper_;
- std::map<int /* process_id */, ServiceWorkerDispatcherHost*>
- dispatcher_hosts_;
+
+ // |providers_| owns the provider hosts. Hosts with browser-assigned provider
+ // ids (unique over all processes), are kept in the map for process id -1.
std::unique_ptr<ProcessToProviderMap> providers_;
+ // |provider_by_uuid_| contains raw pointers to hosts owned by |providers_|.
std::unique_ptr<ProviderByClientUUIDMap> provider_by_uuid_;
+
std::unique_ptr<ServiceWorkerStorage> storage_;
scoped_refptr<EmbeddedWorkerRegistry> embedded_worker_registry_;
std::unique_ptr<ServiceWorkerJobCoordinator> job_coordinator_;
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 99966ec319b..0787d0ed5c3 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
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CONTEXT_CORE_OBSERVER_H_
#include <stdint.h>
+#include <string>
#include "base/callback.h"
#include "base/strings/string16.h"
@@ -71,13 +72,8 @@ class ServiceWorkerContextCoreObserver {
int64_t version_id,
base::Time script_response_time,
base::Time script_last_modified) {}
- virtual void OnErrorReported(int64_t version_id,
- int process_id,
- int thread_id,
- const ErrorInfo& info) {}
+ virtual void OnErrorReported(int64_t version_id, const ErrorInfo& info) {}
virtual void OnReportConsoleMessage(int64_t version_id,
- int process_id,
- int thread_id,
const ConsoleMessage& message) {}
virtual void OnControlleeAdded(int64_t version_id,
const std::string& uuid,
diff --git a/chromium/content/browser/service_worker/service_worker_context_core_unittest.cc b/chromium/content/browser/service_worker/service_worker_context_core_unittest.cc
index 42658be8ceb..b3606460b8e 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_core_unittest.cc
@@ -38,23 +38,26 @@ TEST_F(ServiceWorkerContextCoreTest, FailureInfo) {
const int64_t kVersionId = 55; // dummy value
EXPECT_EQ(0, context()->GetVersionFailureCount(kVersionId));
- context()->UpdateVersionFailureCount(kVersionId, SERVICE_WORKER_OK);
context()->UpdateVersionFailureCount(kVersionId,
- SERVICE_WORKER_ERROR_DISALLOWED);
+ blink::ServiceWorkerStatusCode::kOk);
+ context()->UpdateVersionFailureCount(
+ kVersionId, blink::ServiceWorkerStatusCode::kErrorDisallowed);
EXPECT_EQ(0, context()->GetVersionFailureCount(kVersionId));
- context()->UpdateVersionFailureCount(kVersionId,
- SERVICE_WORKER_ERROR_NETWORK);
+ context()->UpdateVersionFailureCount(
+ kVersionId, blink::ServiceWorkerStatusCode::kErrorNetwork);
EXPECT_EQ(1, context()->GetVersionFailureCount(kVersionId));
- EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNetwork,
context()->failure_counts_[kVersionId].last_failure);
- context()->UpdateVersionFailureCount(kVersionId, SERVICE_WORKER_ERROR_ABORT);
+ context()->UpdateVersionFailureCount(
+ kVersionId, blink::ServiceWorkerStatusCode::kErrorAbort);
EXPECT_EQ(2, context()->GetVersionFailureCount(kVersionId));
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
context()->failure_counts_[kVersionId].last_failure);
- context()->UpdateVersionFailureCount(kVersionId, SERVICE_WORKER_OK);
+ context()->UpdateVersionFailureCount(kVersionId,
+ blink::ServiceWorkerStatusCode::kOk);
EXPECT_EQ(0, context()->GetVersionFailureCount(kVersionId));
EXPECT_FALSE(base::ContainsKey(context()->failure_counts_, kVersionId));
}
diff --git a/chromium/content/browser/service_worker/service_worker_context_request_handler.cc b/chromium/content/browser/service_worker/service_worker_context_request_handler.cc
index 4722982af26..1fcb4c80b49 100644
--- a/chromium/content/browser/service_worker/service_worker_context_request_handler.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_request_handler.cc
@@ -158,8 +158,6 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJobImpl(
if (resource_id != kInvalidServiceWorkerResourceId) {
if (ServiceWorkerVersion::IsInstalled(version_->status())) {
// An installed worker is loading a stored script.
- if (is_main_script)
- version_->embedded_worker()->OnURLJobCreatedForMainScript();
*out_status = CreateJobStatus::READ_JOB;
} else {
// A new worker is loading a stored script. The script was already
@@ -212,7 +210,6 @@ net::URLRequestJob* ServiceWorkerContextRequestHandler::MaybeCreateJobImpl(
incumbent_resource_id =
stored_version->script_cache_map()->LookupResourceId(request->url());
}
- version_->embedded_worker()->OnURLJobCreatedForMainScript();
}
*out_status = incumbent_resource_id == kInvalidServiceWorkerResourceId
? CreateJobStatus::WRITE_JOB
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 9c653a1e5e2..cdf3aa4bb4c 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
@@ -9,7 +9,7 @@
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
@@ -94,13 +94,9 @@ class ServiceWorkerContextRequestHandlerTest : public testing::Test {
ServiceWorkerContextCore* context() const { return helper_->context(); }
void SetUpProvider() {
- std::unique_ptr<ServiceWorkerProviderHost> host =
- CreateProviderHostForServiceWorkerContext(
- helper_->mock_render_process_id(),
- true /* is_parent_frame_secure */, version_.get(),
- context()->AsWeakPtr(), &remote_endpoint_);
- provider_host_ = host->AsWeakPtr();
- context()->AddProviderHost(std::move(host));
+ provider_host_ = CreateProviderHostForServiceWorkerContext(
+ helper_->mock_render_process_id(), true /* is_parent_frame_secure */,
+ version_.get(), context()->AsWeakPtr(), &remote_endpoint_);
}
std::unique_ptr<net::URLRequest> CreateRequest(const GURL& url) {
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 df64683c72e..f7c92935136 100644
--- a/chromium/content/browser/service_worker/service_worker_context_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_unittest.cc
@@ -33,10 +33,11 @@ namespace {
void SaveResponseCallback(bool* called,
int64_t* store_registration_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id) {
- EXPECT_EQ(SERVICE_WORKER_OK, status) << ServiceWorkerStatusToString(status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status)
+ << blink::ServiceWorkerStatusToString(status);
*called = true;
*store_registration_id = registration_id;
}
@@ -47,7 +48,7 @@ ServiceWorkerContextCore::RegistrationCallback MakeRegisteredCallback(
return base::BindOnce(&SaveResponseCallback, called, store_registration_id);
}
-void CallCompletedCallback(bool* called, ServiceWorkerStatusCode) {
+void CallCompletedCallback(bool* called, blink::ServiceWorkerStatusCode) {
*called = true;
}
@@ -57,13 +58,13 @@ ServiceWorkerContextCore::UnregistrationCallback MakeUnregisteredCallback(
}
void ExpectRegisteredWorkers(
- ServiceWorkerStatusCode expect_status,
+ blink::ServiceWorkerStatusCode expect_status,
bool expect_waiting,
bool expect_active,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
ASSERT_EQ(expect_status, status);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
EXPECT_FALSE(registration.get());
return;
}
@@ -89,8 +90,7 @@ class RejectInstallTestHelper : public EmbeddedWorkerTestHelper {
RejectInstallTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
void OnInstallEvent(
- mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
- callback) override {
+ mojom::ServiceWorker::DispatchInstallEventCallback callback) override {
dispatched_events()->push_back(Event::Install);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::REJECTED,
true /* has_fetch_handler */, base::Time::Now());
@@ -102,8 +102,7 @@ class RejectActivateTestHelper : public EmbeddedWorkerTestHelper {
RejectActivateTestHelper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
void OnActivateEvent(
- mojom::ServiceWorkerEventDispatcher::DispatchActivateEventCallback
- callback) override {
+ mojom::ServiceWorker::DispatchActivateEventCallback callback) override {
dispatched_events()->push_back(Event::Activate);
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::REJECTED,
base::Time::Now());
@@ -247,7 +246,8 @@ TEST_F(ServiceWorkerContextTest, Register) {
context()->storage()->FindRegistrationForId(
registration_id, pattern.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_OK,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kOk,
false /* expect_waiting */, true /* expect_active */));
base::RunLoop().RunUntilIdle();
}
@@ -296,7 +296,8 @@ TEST_F(ServiceWorkerContextTest, Register_RejectInstall) {
context()->storage()->FindRegistrationForId(
registration_id, pattern.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_ERROR_NOT_FOUND,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kErrorNotFound,
false /* expect_waiting */, false /* expect_active */));
base::RunLoop().RunUntilIdle();
}
@@ -347,7 +348,8 @@ TEST_F(ServiceWorkerContextTest, Register_RejectActivate) {
context()->storage()->FindRegistrationForId(
registration_id, pattern.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_OK,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kOk,
false /* expect_waiting */, true /* expect_active */));
base::RunLoop().RunUntilIdle();
}
@@ -379,7 +381,8 @@ TEST_F(ServiceWorkerContextTest, Unregister) {
context()->storage()->FindRegistrationForId(
registration_id, pattern.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_ERROR_NOT_FOUND,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kErrorNotFound,
false /* expect_waiting */, false /* expect_active */));
base::RunLoop().RunUntilIdle();
@@ -473,20 +476,24 @@ TEST_F(ServiceWorkerContextTest, UnregisterMultiple) {
context()->storage()->FindRegistrationForId(
registration_id1, origin1_p1.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_ERROR_NOT_FOUND,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kErrorNotFound,
false /* expect_waiting */, false /* expect_active */));
context()->storage()->FindRegistrationForId(
registration_id2, origin1_p2.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_ERROR_NOT_FOUND,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kErrorNotFound,
false /* expect_waiting */, false /* expect_active */));
context()->storage()->FindRegistrationForId(
registration_id3, origin2_p1.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_OK,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kOk,
false /* expect_waiting */, true /* expect_active */));
context()->storage()->FindRegistrationForId(
registration_id4, origin3_p1.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_OK,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kOk,
false /* expect_waiting */, true /* expect_active */));
base::RunLoop().RunUntilIdle();
@@ -665,12 +672,8 @@ TEST_F(ServiceWorkerContextTest, ProviderHostIterator) {
registration.get(),
GURL("https://another-origin.example.net/test/script_url"),
1L /* version_id */, helper_->context()->AsWeakPtr());
- // CreateProviderHostForServiceWorkerContext calls
- // ServiceWorkerProviderHost::CompleteStartWorkerPreparation, which requires a
- // dispatcher host.
- helper_->EnsureDispatcherHostForProcess(kRenderProcessId2);
remote_endpoints.emplace_back();
- std::unique_ptr<ServiceWorkerProviderHost> host4 =
+ base::WeakPtr<ServiceWorkerProviderHost> host4 =
CreateProviderHostForServiceWorkerContext(
kRenderProcessId2, true /* is_parent_frame_secure */, version.get(),
context()->AsWeakPtr(), &remote_endpoints.back());
@@ -684,7 +687,9 @@ TEST_F(ServiceWorkerContextTest, ProviderHostIterator) {
context()->AddProviderHost(std::move(host1));
context()->AddProviderHost(std::move(host2));
context()->AddProviderHost(std::move(host3));
- context()->AddProviderHost(std::move(host4));
+ // host4 is already included because CreateProviderHostForServiceWorkerContext
+ // adds it.
+ DCHECK(context()->GetProviderHost(host4->process_id(), host4->provider_id()));
// Iterate over the client provider hosts that belong to kOrigin1.
std::set<ServiceWorkerProviderHost*> results;
@@ -750,7 +755,8 @@ TEST_P(ServiceWorkerContextRecoveryTest, DeleteAndStartOver) {
context()->storage()->FindRegistrationForId(
registration_id, pattern.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_OK,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kOk,
false /* expect_waiting */, true /* expect_active */));
content::RunAllTasksUntilIdle();
@@ -760,7 +766,8 @@ TEST_P(ServiceWorkerContextRecoveryTest, DeleteAndStartOver) {
// operation should be aborted.
context()->storage()->FindRegistrationForId(
registration_id, pattern.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_ERROR_ABORT,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kErrorAbort,
false /* expect_waiting */, true /* expect_active */));
content::RunAllTasksUntilIdle();
@@ -768,7 +775,8 @@ TEST_P(ServiceWorkerContextRecoveryTest, DeleteAndStartOver) {
// registration should not be found.
context()->storage()->FindRegistrationForId(
registration_id, pattern.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_ERROR_NOT_FOUND,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kErrorNotFound,
false /* expect_waiting */, true /* expect_active */));
content::RunAllTasksUntilIdle();
@@ -782,7 +790,8 @@ TEST_P(ServiceWorkerContextRecoveryTest, DeleteAndStartOver) {
context()->storage()->FindRegistrationForId(
registration_id, pattern.GetOrigin(),
- base::BindOnce(&ExpectRegisteredWorkers, SERVICE_WORKER_OK,
+ base::BindOnce(&ExpectRegisteredWorkers,
+ blink::ServiceWorkerStatusCode::kOk,
false /* expect_waiting */, true /* expect_active */));
content::RunAllTasksUntilIdle();
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 e4d1f2758c4..5bb4c8f5527 100644
--- a/chromium/content/browser/service_worker/service_worker_context_watcher.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_watcher.cc
@@ -64,7 +64,7 @@ void ServiceWorkerContextWatcher::GetStoredRegistrationsOnIOThread() {
}
void ServiceWorkerContextWatcher::OnStoredRegistrationsOnIOThread(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (is_stopped_)
@@ -297,8 +297,6 @@ void ServiceWorkerContextWatcher::OnMainScriptHttpResponseInfoSet(
}
void ServiceWorkerContextWatcher::OnErrorReported(int64_t version_id,
- int process_id,
- int thread_id,
const ErrorInfo& info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId;
@@ -314,8 +312,6 @@ void ServiceWorkerContextWatcher::OnErrorReported(int64_t version_id,
void ServiceWorkerContextWatcher::OnReportConsoleMessage(
int64_t version_id,
- int process_id,
- int thread_id,
const ConsoleMessage& message) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (message.message_level != CONSOLE_MESSAGE_LEVEL_ERROR)
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 68f86f49e37..1eb56b76459 100644
--- a/chromium/content/browser/service_worker/service_worker_context_watcher.h
+++ b/chromium/content/browser/service_worker/service_worker_context_watcher.h
@@ -7,6 +7,8 @@
#include <stdint.h>
+#include <memory>
+#include <string>
#include <unordered_map>
#include <vector>
@@ -52,7 +54,7 @@ class CONTENT_EXPORT ServiceWorkerContextWatcher
void GetStoredRegistrationsOnIOThread();
void OnStoredRegistrationsOnIOThread(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations);
void StopOnIOThread();
@@ -96,12 +98,8 @@ class CONTENT_EXPORT ServiceWorkerContextWatcher
base::Time script_response_time,
base::Time script_last_modified) override;
void OnErrorReported(int64_t version_id,
- int process_id,
- int thread_id,
const ErrorInfo& info) override;
void OnReportConsoleMessage(int64_t version_id,
- int process_id,
- int thread_id,
const ConsoleMessage& message) override;
void OnControlleeAdded(int64_t version_id,
const std::string& uuid,
diff --git a/chromium/content/browser/service_worker/service_worker_context_watcher_unittest.cc b/chromium/content/browser/service_worker/service_worker_context_watcher_unittest.cc
index 3bc8afdbd8a..5ba18ee124c 100644
--- a/chromium/content/browser/service_worker/service_worker_context_watcher_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_watcher_unittest.cc
@@ -18,16 +18,16 @@ namespace content {
namespace {
void DidRegisterServiceWorker(int64_t* registration_id_out,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id) {
ASSERT_TRUE(registration_id_out);
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
*registration_id_out = registration_id;
}
-void DidUnregisterServiceWorker(ServiceWorkerStatusCode* status_out,
- ServiceWorkerStatusCode status) {
+void DidUnregisterServiceWorker(blink::ServiceWorkerStatusCode* status_out,
+ blink::ServiceWorkerStatusCode status) {
ASSERT_TRUE(status_out);
*status_out = status;
}
@@ -151,8 +151,9 @@ class ServiceWorkerContextWatcherTest : public testing::Test {
return registration_id;
}
- ServiceWorkerStatusCode UnregisterServiceWorker(const GURL& scope) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ blink::ServiceWorkerStatusCode UnregisterServiceWorker(const GURL& scope) {
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
context()->UnregisterServiceWorker(
scope, base::BindOnce(&DidUnregisterServiceWorker, &status));
base::RunLoop().RunUntilIdle();
@@ -163,8 +164,7 @@ class ServiceWorkerContextWatcherTest : public testing::Test {
scoped_refptr<ServiceWorkerContextWatcher> watcher,
int64_t version_id,
const ServiceWorkerContextCoreObserver::ErrorInfo& error_info) {
- watcher->OnErrorReported(version_id, 0 /* process_id */, 0 /* thread_id */,
- error_info);
+ watcher->OnErrorReported(version_id, error_info);
}
private:
@@ -297,7 +297,8 @@ TEST_F(ServiceWorkerContextWatcherTest, UnregisteredServiceWorker) {
watcher_callback.registrations().at(registration_id_2).pattern);
ASSERT_EQ(2u, watcher_callback.versions().size());
- ASSERT_EQ(SERVICE_WORKER_OK, UnregisterServiceWorker(scope_1));
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ UnregisterServiceWorker(scope_1));
ASSERT_EQ(1u, watcher_callback.registrations().size());
EXPECT_EQ(scope_2,
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 b91bad88fcd..9927359ee1b 100644
--- a/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -24,7 +24,6 @@
#include "content/browser/service_worker/service_worker_quota_client.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/storage_partition_impl.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
@@ -32,6 +31,7 @@
#include "net/base/url_util.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/quota/special_storage_policy.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
namespace content {
@@ -43,7 +43,7 @@ base::LazyInstance<HeaderNameSet>::DestructorAtExit g_excluded_header_name_set =
LAZY_INSTANCE_INITIALIZER;
void WorkerStarted(ServiceWorkerContextWrapper::StatusCallback callback,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(callback), status));
@@ -51,10 +51,10 @@ void WorkerStarted(ServiceWorkerContextWrapper::StatusCallback callback,
void StartActiveWorkerOnIO(
ServiceWorkerContextWrapper::StatusCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status == SERVICE_WORKER_OK) {
+ if (status == blink::ServiceWorkerStatusCode::kOk) {
// Pass the reference of |registration| to WorkerStarted callback to prevent
// it from being deleted while starting the worker. If the refcount of
// |registration| is 1, it will be deleted after WorkerStarted is called.
@@ -65,26 +65,27 @@ void StartActiveWorkerOnIO(
}
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_NOT_FOUND));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorNotFound));
}
void SkipWaitingWorkerOnIO(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK || !registration->waiting_version())
+ if (status != blink::ServiceWorkerStatusCode::kOk ||
+ !registration->waiting_version())
return;
registration->waiting_version()->set_skip_waiting(true);
registration->ActivateWaitingVersionWhenReady();
}
-void DidStartActiveWorker(
- scoped_refptr<ServiceWorkerVersion> version,
- ServiceWorkerContext::StartActiveWorkerCallback info_callback,
- base::OnceClosure error_callback,
- ServiceWorkerStatusCode start_worker_status) {
- if (start_worker_status != SERVICE_WORKER_OK) {
+void DidStartWorker(scoped_refptr<ServiceWorkerVersion> version,
+ ServiceWorkerContext::StartWorkerCallback info_callback,
+ base::OnceClosure error_callback,
+ blink::ServiceWorkerStatusCode start_worker_status) {
+ if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) {
std::move(error_callback).Run();
return;
}
@@ -92,51 +93,63 @@ void DidStartActiveWorker(
std::move(info_callback).Run(instance->process_id(), instance->thread_id());
}
-void FoundReadyRegistrationForStartActiveWorker(
- ServiceWorkerContext::StartActiveWorkerCallback info_callback,
+void FoundRegistrationForStartWorker(
+ ServiceWorkerContext::StartWorkerCallback info_callback,
base::OnceClosure failure_callback,
- ServiceWorkerStatusCode service_worker_status,
- scoped_refptr<ServiceWorkerRegistration> service_worker_registration) {
+ blink::ServiceWorkerStatusCode service_worker_status,
+ scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (service_worker_status == SERVICE_WORKER_OK) {
- // Note: There might be a remote possibility that
- // |service_worker_registration|'s active version might change
- // between here and DidStartActiveWorker, so
- // bind |active_version| to RunAfterStartWorker.
- scoped_refptr<ServiceWorkerVersion> active_version =
- service_worker_registration->active_version();
- DCHECK(active_version.get());
- active_version->RunAfterStartWorker(
- ServiceWorkerMetrics::EventType::EXTERNAL_REQUEST,
- base::BindOnce(&DidStartActiveWorker, active_version,
- std::move(info_callback), std::move(failure_callback)));
- } else {
+ if (service_worker_status != blink::ServiceWorkerStatusCode::kOk) {
std::move(failure_callback).Run();
+ return;
}
+
+ ServiceWorkerVersion* version_ptr = registration->active_version()
+ ? registration->active_version()
+ : registration->installing_version();
+ // Since FindRegistrationForPattern returned
+ // blink::ServiceWorkerStatusCode::kOk, there must be either: -
+ // an active version, which optionally might have activated from a waiting
+ // version (as DidFindRegistrationForFindImpl will activate any waiting
+ // version).
+ // - or an installing version.
+ DCHECK(version_ptr);
+
+ // Note: There might be a remote possibility that |registration|'s |version|
+ // might change between here and DidStartWorker, so bind |version| to
+ // RunAfterStartWorker.
+ scoped_refptr<ServiceWorkerVersion> version =
+ base::WrapRefCounted(version_ptr);
+ version->RunAfterStartWorker(
+ ServiceWorkerMetrics::EventType::EXTERNAL_REQUEST,
+ base::BindOnce(&DidStartWorker, version, std::move(info_callback),
+ std::move(failure_callback)));
}
void StatusCodeToBoolCallbackAdapter(
ServiceWorkerContext::ResultCallback callback,
- ServiceWorkerStatusCode code) {
- std::move(callback).Run(code == ServiceWorkerStatusCode::SERVICE_WORKER_OK);
+ blink::ServiceWorkerStatusCode code) {
+ std::move(callback).Run(code == blink::ServiceWorkerStatusCode::kOk);
}
void FinishRegistrationOnIO(ServiceWorkerContext::ResultCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), status == SERVICE_WORKER_OK));
+ base::BindOnce(std::move(callback),
+ status == blink::ServiceWorkerStatusCode::kOk));
}
void FinishUnregistrationOnIO(ServiceWorkerContext::ResultCallback callback,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), status == SERVICE_WORKER_OK));
+ base::BindOnce(std::move(callback),
+ status == blink::ServiceWorkerStatusCode::kOk));
}
} // namespace
@@ -410,15 +423,15 @@ void ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest(
context_core_->ClearAllServiceWorkersForTest(std::move(callback));
}
-void ServiceWorkerContextWrapper::StartActiveWorkerForPattern(
+void ServiceWorkerContextWrapper::StartWorkerForPattern(
const GURL& pattern,
- StartActiveWorkerCallback info_callback,
+ StartWorkerCallback info_callback,
base::OnceClosure failure_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- FindReadyRegistrationForPattern(
+ FindRegistrationForPattern(
pattern,
- base::BindOnce(&FoundReadyRegistrationForStartActiveWorker,
- std::move(info_callback), std::move(failure_callback)));
+ base::BindOnce(&FoundRegistrationForStartWorker, std::move(info_callback),
+ std::move(failure_callback)));
}
void ServiceWorkerContextWrapper::StartServiceWorkerForNavigationHint(
@@ -542,7 +555,8 @@ void ServiceWorkerContextWrapper::FindReadyRegistrationForDocument(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
// FindRegistrationForDocument() can run the callback synchronously.
- std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT, nullptr);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort,
+ nullptr);
return;
}
context_core_->storage()->FindRegistrationForDocument(
@@ -556,17 +570,16 @@ void ServiceWorkerContextWrapper::FindReadyRegistrationForPattern(
const GURL& scope,
FindRegistrationCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (!context_core_) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback),
- SERVICE_WORKER_ERROR_ABORT, nullptr));
- return;
- }
- context_core_->storage()->FindRegistrationForPattern(
- net::SimplifyUrlForRequest(scope),
- base::BindOnce(
- &ServiceWorkerContextWrapper::DidFindRegistrationForFindReady, this,
- std::move(callback)));
+ FindRegistrationForPatternImpl(scope, false /* include_installing_version */,
+ std::move(callback));
+}
+
+void ServiceWorkerContextWrapper::FindRegistrationForPattern(
+ const GURL& scope,
+ FindRegistrationCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ FindRegistrationForPatternImpl(scope, true /* include_installing_version */,
+ std::move(callback));
}
void ServiceWorkerContextWrapper::FindReadyRegistrationForId(
@@ -576,7 +589,8 @@ void ServiceWorkerContextWrapper::FindReadyRegistrationForId(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
// FindRegistrationForId() can run the callback synchronously.
- std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT, nullptr);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort,
+ nullptr);
return;
}
context_core_->storage()->FindRegistrationForId(
@@ -592,7 +606,8 @@ void ServiceWorkerContextWrapper::FindReadyRegistrationForIdOnly(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
// FindRegistrationForIdOnly() can run the callback synchronously.
- std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT, nullptr);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort,
+ nullptr);
return;
}
context_core_->storage()->FindRegistrationForIdOnly(
@@ -608,7 +623,8 @@ void ServiceWorkerContextWrapper::GetAllRegistrations(
if (!context_core_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT,
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort,
std::vector<ServiceWorkerRegistrationInfo>()));
return;
}
@@ -624,7 +640,7 @@ void ServiceWorkerContextWrapper::GetRegistrationUserData(
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), std::vector<std::string>(),
- SERVICE_WORKER_ERROR_ABORT));
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
context_core_->storage()->GetUserData(registration_id, keys,
@@ -640,7 +656,7 @@ void ServiceWorkerContextWrapper::GetRegistrationUserDataByKeyPrefix(
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), std::vector<std::string>(),
- SERVICE_WORKER_ERROR_ABORT));
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
context_core_->storage()->GetUserDataByKeyPrefix(registration_id, key_prefix,
@@ -656,7 +672,7 @@ void ServiceWorkerContextWrapper::GetRegistrationUserKeysAndDataByKeyPrefix(
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback),
base::flat_map<std::string, std::string>(),
- SERVICE_WORKER_ERROR_ABORT));
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
context_core_->storage()->GetUserKeysAndDataByKeyPrefix(
@@ -671,8 +687,8 @@ void ServiceWorkerContextWrapper::StoreRegistrationUserData(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
+ FROM_HERE, base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
context_core_->storage()->StoreUserData(registration_id, origin.GetOrigin(),
@@ -686,8 +702,8 @@ void ServiceWorkerContextWrapper::ClearRegistrationUserData(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
+ FROM_HERE, base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
context_core_->storage()->ClearUserData(registration_id, keys,
@@ -701,8 +717,8 @@ void ServiceWorkerContextWrapper::ClearRegistrationUserDataByKeyPrefixes(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!context_core_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
+ FROM_HERE, base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
context_core_->storage()->ClearUserDataByKeyPrefixes(
@@ -718,7 +734,7 @@ void ServiceWorkerContextWrapper::GetUserDataForAllRegistrations(
FROM_HERE,
base::BindOnce(std::move(callback),
std::vector<std::pair<int64_t, std::string>>(),
- SERVICE_WORKER_ERROR_ABORT));
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
context_core_->storage()->GetUserDataForAllRegistrations(key,
@@ -734,7 +750,7 @@ void ServiceWorkerContextWrapper::GetUserDataForAllRegistrationsByKeyPrefix(
FROM_HERE,
base::BindOnce(std::move(callback),
std::vector<std::pair<int64_t, std::string>>(),
- SERVICE_WORKER_ERROR_ABORT));
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
context_core_->storage()->GetUserDataForAllRegistrationsByKeyPrefix(
@@ -753,7 +769,8 @@ void ServiceWorkerContextWrapper::StartServiceWorker(const GURL& pattern,
if (!context_core_) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
context_core_->storage()->FindRegistrationForPattern(
@@ -863,18 +880,38 @@ void ServiceWorkerContextWrapper::InitInternal(
this);
}
+void ServiceWorkerContextWrapper::FindRegistrationForPatternImpl(
+ const GURL& scope,
+ bool include_installing_version,
+ FindRegistrationCallback callback) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (!context_core_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort, nullptr));
+ return;
+ }
+ context_core_->storage()->FindRegistrationForPattern(
+ net::SimplifyUrlForRequest(scope),
+ base::BindOnce(
+ &ServiceWorkerContextWrapper::DidFindRegistrationForFindImpl, this,
+ include_installing_version, std::move(callback)));
+}
+
void ServiceWorkerContextWrapper::ShutdownOnIO() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
resource_context_ = nullptr;
context_core_.reset();
}
-void ServiceWorkerContextWrapper::DidFindRegistrationForFindReady(
+void ServiceWorkerContextWrapper::DidFindRegistrationForFindImpl(
+ bool include_installing_version,
FindRegistrationCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(status, nullptr);
return;
}
@@ -886,21 +923,38 @@ void ServiceWorkerContextWrapper::DidFindRegistrationForFindReady(
scoped_refptr<ServiceWorkerVersion> active_version =
registration->active_version();
- if (!active_version) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_NOT_FOUND, nullptr);
+ if (active_version) {
+ if (active_version->status() == ServiceWorkerVersion::ACTIVATING) {
+ // Wait until the version is activated.
+ active_version->RegisterStatusChangeCallback(base::BindOnce(
+ &ServiceWorkerContextWrapper::OnStatusChangedForFindReadyRegistration,
+ this, std::move(callback), std::move(registration)));
+ return;
+ }
+ DCHECK_EQ(ServiceWorkerVersion::ACTIVATED, active_version->status());
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kOk,
+ std::move(registration));
return;
}
- if (active_version->status() == ServiceWorkerVersion::ACTIVATING) {
- // Wait until the version is activated.
- active_version->RegisterStatusChangeCallback(base::BindOnce(
- &ServiceWorkerContextWrapper::OnStatusChangedForFindReadyRegistration,
- this, std::move(callback), std::move(registration)));
+ if (include_installing_version && registration->installing_version()) {
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kOk,
+ std::move(registration));
return;
}
- DCHECK_EQ(ServiceWorkerVersion::ACTIVATED, active_version->status());
- std::move(callback).Run(SERVICE_WORKER_OK, std::move(registration));
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorNotFound,
+ nullptr);
+}
+
+void ServiceWorkerContextWrapper::DidFindRegistrationForFindReady(
+ FindRegistrationCallback callback,
+ blink::ServiceWorkerStatusCode status,
+ scoped_refptr<ServiceWorkerRegistration> registration) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DidFindRegistrationForFindImpl(false /* include_installing_version */,
+ std::move(callback), status,
+ std::move(registration));
}
void ServiceWorkerContextWrapper::OnStatusChangedForFindReadyRegistration(
@@ -911,16 +965,17 @@ void ServiceWorkerContextWrapper::OnStatusChangedForFindReadyRegistration(
registration->active_version();
if (!active_version ||
active_version->status() != ServiceWorkerVersion::ACTIVATED) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_NOT_FOUND, nullptr);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorNotFound,
+ nullptr);
return;
}
- std::move(callback).Run(SERVICE_WORKER_OK, registration);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kOk, registration);
}
void ServiceWorkerContextWrapper::DidDeleteAndStartOver(
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
context_core_.reset();
return;
}
@@ -931,7 +986,7 @@ void ServiceWorkerContextWrapper::DidDeleteAndStartOver(
void ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins(
GetUsageInfoCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::vector<ServiceWorkerUsageInfo> usage_infos;
@@ -963,11 +1018,11 @@ void ServiceWorkerContextWrapper::DidCheckHasServiceWorker(
}
void ServiceWorkerContextWrapper::DidFindRegistrationForUpdate(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- if (status != SERVICE_WORKER_OK)
+ if (status != blink::ServiceWorkerStatusCode::kOk)
return;
if (!context_core_)
return;
@@ -1022,13 +1077,13 @@ void ServiceWorkerContextWrapper::StartServiceWorkerForNavigationHintOnIO(
void ServiceWorkerContextWrapper::DidFindRegistrationForNavigationHint(
StartServiceWorkerForNavigationHintCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
TRACE_EVENT1("ServiceWorker", "DidFindRegistrationForNavigationHint",
- "status", ServiceWorkerStatusToString(status));
+ "status", blink::ServiceWorkerStatusToString(status));
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!registration) {
- DCHECK_NE(status, SERVICE_WORKER_OK);
+ DCHECK_NE(status, blink::ServiceWorkerStatusCode::kOk);
std::move(callback).Run(StartServiceWorkerForNavigationHintResult::
NO_SERVICE_WORKER_REGISTRATION);
return;
@@ -1061,12 +1116,13 @@ void ServiceWorkerContextWrapper::DidFindRegistrationForNavigationHint(
void ServiceWorkerContextWrapper::DidStartServiceWorkerForNavigationHint(
const GURL& pattern,
StartServiceWorkerForNavigationHintCallback callback,
- ServiceWorkerStatusCode code) {
+ blink::ServiceWorkerStatusCode code) {
TRACE_EVENT2("ServiceWorker", "DidStartServiceWorkerForNavigationHint", "url",
- pattern.spec(), "code", ServiceWorkerStatusToString(code));
+ pattern.spec(), "code",
+ blink::ServiceWorkerStatusToString(code));
DCHECK_CURRENTLY_ON(BrowserThread::IO);
std::move(callback).Run(
- code == SERVICE_WORKER_OK
+ code == blink::ServiceWorkerStatusCode::kOk
? StartServiceWorkerForNavigationHintResult::STARTED
: StartServiceWorkerForNavigationHintResult::FAILED);
}
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 e06300d2141..f1b9b94c5cc 100644
--- a/chromium/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/chromium/content/browser/service_worker/service_worker_context_wrapper.h
@@ -48,7 +48,8 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
public ServiceWorkerContextCoreObserver,
public base::RefCountedThreadSafe<ServiceWorkerContextWrapper> {
public:
- using StatusCallback = base::OnceCallback<void(ServiceWorkerStatusCode)>;
+ using StatusCallback =
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)>;
using BoolCallback = base::OnceCallback<void(bool)>;
using FindRegistrationCallback =
ServiceWorkerStorage::FindRegistrationCallback;
@@ -123,9 +124,9 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
const GURL& other_url,
CheckHasServiceWorkerCallback callback) override;
void ClearAllServiceWorkersForTest(base::OnceClosure callback) override;
- void StartActiveWorkerForPattern(const GURL& pattern,
- StartActiveWorkerCallback info_callback,
- base::OnceClosure failure_callback) override;
+ void StartWorkerForPattern(const GURL& pattern,
+ StartWorkerCallback info_callback,
+ base::OnceClosure failure_callback) override;
void StartServiceWorkerForNavigationHint(
const GURL& document_url,
StartServiceWorkerForNavigationHintCallback callback) override;
@@ -175,6 +176,12 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
void FindReadyRegistrationForPattern(const GURL& scope,
FindRegistrationCallback callback);
+ // Similar to FindReadyRegistrationForPattern, but in the case no waiting or
+ // active worker is found (i.e., there is only an installing worker),
+ // |callback| is called without waiting for the worker to reach active.
+ void FindRegistrationForPattern(const GURL& scope,
+ FindRegistrationCallback callback);
+
// Returns the registration for |registration_id|. It is guaranteed that the
// returned registration has the activated worker.
//
@@ -289,26 +296,37 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
URLLoaderFactoryGetter* url_loader_factory_getter);
void ShutdownOnIO();
+ // If |include_installing_version| is true, |callback| is called if there is
+ // an installing version with no waiting or active version.
+ void FindRegistrationForPatternImpl(const GURL& scope,
+ bool include_installing_version,
+ FindRegistrationCallback callback);
+
void DidFindRegistrationForFindReady(
FindRegistrationCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
+ scoped_refptr<ServiceWorkerRegistration> registration);
+ void DidFindRegistrationForFindImpl(
+ bool include_installing_version,
+ FindRegistrationCallback callback,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void OnStatusChangedForFindReadyRegistration(
FindRegistrationCallback callback,
scoped_refptr<ServiceWorkerRegistration> registration);
- void DidDeleteAndStartOver(ServiceWorkerStatusCode status);
+ void DidDeleteAndStartOver(blink::ServiceWorkerStatusCode status);
void DidGetAllRegistrationsForGetAllOrigins(
GetUsageInfoCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<ServiceWorkerRegistrationInfo>& registrations);
void DidCheckHasServiceWorker(CheckHasServiceWorkerCallback callback,
content::ServiceWorkerCapability status);
void DidFindRegistrationForUpdate(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<content::ServiceWorkerRegistration> registration);
void CountExternalRequests(const GURL& url,
@@ -320,13 +338,13 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
void DidFindRegistrationForNavigationHint(
StartServiceWorkerForNavigationHintCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void DidStartServiceWorkerForNavigationHint(
const GURL& pattern,
StartServiceWorkerForNavigationHintCallback callback,
- ServiceWorkerStatusCode code);
+ blink::ServiceWorkerStatusCode code);
void RecordStartServiceWorkerForNavigationHintResult(
StartServiceWorkerForNavigationHintCallback callback,
diff --git a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc
index d2dcaa67d40..dc214676e02 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
@@ -30,6 +30,7 @@
#include "net/url_request/url_request.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "services/network/public/cpp/resource_response_info.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "ui/base/page_transition_types.h"
#if BUILDFLAG(ENABLE_OFFLINE_PAGES)
@@ -95,6 +96,7 @@ ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler(
provider_host,
blob_storage_context,
resource_type),
+ resource_type_(resource_type),
is_main_resource_load_(
ServiceWorkerUtils::IsMainResourceType(resource_type)),
is_main_frame_load_(resource_type == RESOURCE_TYPE_MAIN_FRAME),
@@ -112,19 +114,42 @@ ServiceWorkerControlleeRequestHandler::ServiceWorkerControlleeRequestHandler(
ServiceWorkerControlleeRequestHandler::
~ServiceWorkerControlleeRequestHandler() {
- // Navigation triggers an update to occur shortly after the page and
- // its initial subresources load.
- if (provider_host_ && provider_host_->active_version()) {
- if (is_main_resource_load_ && !force_update_started_)
- provider_host_->active_version()->ScheduleUpdate();
- else
- provider_host_->active_version()->DeferScheduledUpdate();
- }
+ MaybeScheduleUpdate();
if (is_main_resource_load_ && provider_host_)
provider_host_->SetAllowAssociation(true);
}
+void ServiceWorkerControlleeRequestHandler::MaybeScheduleUpdate() {
+ if (!provider_host_ || !provider_host_->active_version())
+ return;
+
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ // For subresources: S13nServiceWorker doesn't come here.
+ DCHECK(is_main_resource_load_);
+
+ // For navigations, the update logic is taken care of
+ // during navigation and waits for the HintToUpdateServiceWorker message.
+ if (IsResourceTypeFrame(resource_type_))
+ return;
+
+ // Continue to the common non-S13nServiceWorker code for triggering update
+ // for shared workers. The renderer doesn't yet send a
+ // HintToUpdateServiceWorker message.
+ // TODO(falken): Make the renderer send the message for shared worker,
+ // to simplify the code.
+ }
+
+ // If DevTools forced an update, there is no need to update again.
+ if (force_update_started_)
+ return;
+
+ if (is_main_resource_load_)
+ provider_host_->active_version()->ScheduleUpdate();
+ else
+ provider_host_->active_version()->DeferScheduledUpdate();
+}
+
net::URLRequestJob* ServiceWorkerControlleeRequestHandler::MaybeCreateJob(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
@@ -198,7 +223,7 @@ void ServiceWorkerControlleeRequestHandler::MaybeCreateLoader(
const network::ResourceRequest& resource_request,
ResourceContext* resource_context,
LoaderCallback callback) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
DCHECK(is_main_resource_load_);
ClearJob();
@@ -244,7 +269,7 @@ void ServiceWorkerControlleeRequestHandler::MaybeCreateLoader(
base::Optional<SubresourceLoaderParams>
ServiceWorkerControlleeRequestHandler::MaybeCreateSubresourceLoaderParams() {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
// We didn't create URLLoader for this request.
if (!url_job_)
@@ -258,22 +283,23 @@ ServiceWorkerControlleeRequestHandler::MaybeCreateSubresourceLoaderParams() {
// Otherwise let's send the controller service worker information along
// with the navigation commit.
- // Note that |controller_info->endpoint| could be null if the controller
- // service worker isn't starting up or running, e.g. in no-fetch worker
- // cases. In that case the renderer frame won't get the controller pointer
- // upon the navigation commit, and subresource loading will not be intercepted
- // at least until the frame gets a new controller ptr by SetController.
SubresourceLoaderParams params;
auto controller_info = mojom::ControllerServiceWorkerInfo::New();
+ controller_info->mode = provider_host_->GetControllerMode();
+ // Note that |controller_info->endpoint| is null if the controller has no
+ // fetch event handler. In that case the renderer frame won't get the
+ // controller pointer upon the navigation commit, and subresource loading will
+ // not be intercepted. (It might get intercepted later if the controller
+ // changes due to skipWaiting() so SetController is sent.)
controller_info->endpoint =
provider_host_->GetControllerServiceWorkerPtr().PassInterface();
controller_info->client_id = provider_host_->client_uuid();
- base::WeakPtr<ServiceWorkerHandle> handle =
- provider_host_->GetOrCreateServiceWorkerHandle(
+ base::WeakPtr<ServiceWorkerObjectHost> object_host =
+ provider_host_->GetOrCreateServiceWorkerObjectHost(
provider_host_->controller());
- if (handle) {
- params.controller_service_worker_handle = handle;
- controller_info->object_info = handle->CreateIncompleteObjectInfo();
+ if (object_host) {
+ params.controller_service_worker_object_host = object_host;
+ controller_info->object_info = object_host->CreateIncompleteObjectInfo();
}
params.controller_service_worker_info = std::move(controller_info);
return base::Optional<SubresourceLoaderParams>(std::move(params));
@@ -307,7 +333,7 @@ void ServiceWorkerControlleeRequestHandler::PrepareForMainResource(
void ServiceWorkerControlleeRequestHandler::
DidLookupRegistrationForMainResource(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
// The job may have been canceled before this was invoked.
if (JobWasCanceled())
@@ -318,16 +344,34 @@ void ServiceWorkerControlleeRequestHandler::
if (provider_host_ && !need_to_update)
provider_host_->SetAllowAssociation(true);
- if (status != SERVICE_WORKER_OK || !provider_host_ || !context_) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
url_job_->FallbackToNetwork();
TRACE_EVENT_ASYNC_END1(
"ServiceWorker",
"ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Status", status);
+ url_job_.get(), "Status", blink::ServiceWorkerStatusToString(status));
return;
}
DCHECK(registration.get());
+ if (!provider_host_) {
+ url_job_->FallbackToNetwork();
+ TRACE_EVENT_ASYNC_END1(
+ "ServiceWorker",
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
+ url_job_.get(), "Info", "No Provider");
+ return;
+ }
+
+ if (!context_) {
+ url_job_->FallbackToNetwork();
+ TRACE_EVENT_ASYNC_END1(
+ "ServiceWorker",
+ "ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
+ url_job_.get(), "Info", "No Context");
+ return;
+ }
+
if (!GetContentClient()->browser()->AllowServiceWorker(
registration->pattern(), provider_host_->topmost_frame_url(),
resource_context_, provider_host_->web_contents_getter())) {
@@ -335,7 +379,8 @@ void ServiceWorkerControlleeRequestHandler::
TRACE_EVENT_ASYNC_END2(
"ServiceWorker",
"ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Status", status, "Info", "ServiceWorker is blocked");
+ url_job_.get(), "Status", blink::ServiceWorkerStatusToString(status),
+ "Info", "ServiceWorker is blocked");
return;
}
@@ -373,17 +418,20 @@ void ServiceWorkerControlleeRequestHandler::
if (active_version.get() &&
active_version->status() == ServiceWorkerVersion::ACTIVATING) {
provider_host_->SetAllowAssociation(false);
- registration->active_version()->RegisterStatusChangeCallback(base::BindOnce(
- &self::OnVersionStatusChanged, weak_factory_.GetWeakPtr(),
- base::RetainedRef(registration), base::RetainedRef(active_version)));
+ active_version->RegisterStatusChangeCallback(base::BindOnce(
+ &self::OnVersionStatusChanged, weak_factory_.GetWeakPtr(), registration,
+ active_version));
TRACE_EVENT_ASYNC_END2(
"ServiceWorker",
"ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Status", status, "Info",
- "Wait until finished SW activation");
+ url_job_.get(), "Status", blink::ServiceWorkerStatusToString(status),
+ "Info", "Wait until finished SW activation");
return;
}
+ // TODO(falken): Factor out the rest of this function and
+ // OnVersionStatusChanged into the same function.
+
// A registration exists, so associate it. Note that the controller is only
// set if there's an active version. If there's no active version, we should
// still associate so the provider host can use .ready.
@@ -396,7 +444,8 @@ void ServiceWorkerControlleeRequestHandler::
TRACE_EVENT_ASYNC_END2(
"ServiceWorker",
"ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Status", status, "Info",
+ url_job_.get(), "Status", blink::ServiceWorkerStatusToString(status),
+ "Info",
"ServiceWorkerVersion is not available, so falling back to network");
return;
}
@@ -406,20 +455,25 @@ void ServiceWorkerControlleeRequestHandler::
ServiceWorkerMetrics::CountControlledPageLoad(
active_version->site_for_uma(), stripped_url_, is_main_frame_load_);
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled() &&
+ IsResourceTypeFrame(resource_type_)) {
+ provider_host_->AddServiceWorkerToUpdate(active_version);
+ }
bool is_forwarded =
MaybeForwardToServiceWorker(url_job_.get(), active_version.get());
TRACE_EVENT_ASYNC_END2(
"ServiceWorker",
"ServiceWorkerControlleeRequestHandler::PrepareForMainResource",
- url_job_.get(), "Status", status, "Info",
+ url_job_.get(), "Status", blink::ServiceWorkerStatusToString(status),
+ "Info",
(is_forwarded) ? "Forwarded to the ServiceWorker"
: "Skipped the ServiceWorker which has no fetch handler");
}
void ServiceWorkerControlleeRequestHandler::OnVersionStatusChanged(
- ServiceWorkerRegistration* registration,
- ServiceWorkerVersion* version) {
+ scoped_refptr<ServiceWorkerRegistration> registration,
+ scoped_refptr<ServiceWorkerVersion> version) {
// The job may have been canceled before this was invoked.
if (JobWasCanceled())
return;
@@ -438,15 +492,19 @@ void ServiceWorkerControlleeRequestHandler::OnVersionStatusChanged(
ServiceWorkerMetrics::CountControlledPageLoad(
version->site_for_uma(), stripped_url_, is_main_frame_load_);
- provider_host_->AssociateRegistration(registration,
+ provider_host_->AssociateRegistration(registration.get(),
false /* notify_controllerchange */);
- MaybeForwardToServiceWorker(url_job_.get(), version);
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled() &&
+ IsResourceTypeFrame(resource_type_)) {
+ provider_host_->AddServiceWorkerToUpdate(version);
+ }
+ MaybeForwardToServiceWorker(url_job_.get(), version.get());
}
void ServiceWorkerControlleeRequestHandler::DidUpdateRegistration(
const scoped_refptr<ServiceWorkerRegistration>& original_registration,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id) {
DCHECK(force_update_started_);
@@ -459,7 +517,7 @@ void ServiceWorkerControlleeRequestHandler::DidUpdateRegistration(
url_job_->FallbackToNetwork();
return;
}
- if (status != SERVICE_WORKER_OK ||
+ if (status != blink::ServiceWorkerStatusCode::kOk ||
!original_registration->installing_version()) {
// Update failed. Look up the registration again since the original
// registration was possibly unregistered in the meantime.
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 f5b750685e3..ed148bea249 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
@@ -40,7 +40,7 @@ class ServiceWorkerVersion;
// A request handler derivative used to handle requests from
// controlled documents.
// Note that in IsServicificationEnabled cases this is used only for
-// main resource fetch during navigation.
+// main resource fetch during navigation or shared worker creation.
class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
: public ServiceWorkerRequestHandler,
public ServiceWorkerURLJobWrapper::Delegate {
@@ -94,15 +94,15 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
// For main resource case.
void PrepareForMainResource(const GURL& url, const GURL& site_for_cookies);
void DidLookupRegistrationForMainResource(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void OnVersionStatusChanged(
- ServiceWorkerRegistration* registration,
- ServiceWorkerVersion* version);
+ scoped_refptr<ServiceWorkerRegistration> registration,
+ scoped_refptr<ServiceWorkerVersion> version);
void DidUpdateRegistration(
const scoped_refptr<ServiceWorkerRegistration>& original_registration,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id);
void OnUpdatedVersionStatusChanged(
@@ -130,6 +130,11 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler
bool JobWasCanceled() const;
+ // Schedules a service worker update to occur shortly after the page and its
+ // initial subresources load, if this handler was for a navigation.
+ void MaybeScheduleUpdate();
+
+ const ResourceType resource_type_;
const bool is_main_resource_load_;
const bool is_main_frame_load_;
std::unique_ptr<ServiceWorkerURLJobWrapper> url_job_;
diff --git a/chromium/content/browser/service_worker/service_worker_database.cc b/chromium/content/browser/service_worker/service_worker_database.cc
index c34711b2eb7..c7610f12b60 100644
--- a/chromium/content/browser/service_worker/service_worker_database.cc
+++ b/chromium/content/browser/service_worker/service_worker_database.cc
@@ -1226,12 +1226,8 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DestroyDatabase() {
return STATUS_OK;
}
- // Directly delete the database instead of calling leveldb::DestroyDB()
- // because the API does not delete the directory if there are unrelated files.
- // (https://code.google.com/p/chromium/issues/detail?id=468926#c24)
- Status status = base::DeleteFile(path_, true /* recursive */)
- ? STATUS_OK
- : STATUS_ERROR_FAILED;
+ Status status = LevelDBStatusToServiceWorkerDBStatus(
+ leveldb_chrome::DeleteDB(path_, leveldb_env::Options()));
ServiceWorkerMetrics::RecordDestroyDatabaseResult(status);
return status;
}
@@ -1246,12 +1242,11 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::LazyOpen(
if (IsOpen())
return STATUS_OK;
- if (!create_if_missing) {
+ if (!create_if_missing &&
+ (IsDatabaseInMemory() ||
+ !leveldb_chrome::PossiblyValidDB(path_, leveldb::Env::Default()))) {
// Avoid opening a database if it does not exist at the |path_|.
- if (IsDatabaseInMemory() || !base::PathExists(path_) ||
- base::IsDirectoryEmpty(path_)) {
- return STATUS_ERROR_NOT_FOUND;
- }
+ return STATUS_ERROR_NOT_FOUND;
}
leveldb_env::Options options;
diff --git a/chromium/content/browser/service_worker/service_worker_database.h b/chromium/content/browser/service_worker/service_worker_database.h
index c320569785c..c99a3d88f66 100644
--- a/chromium/content/browser/service_worker/service_worker_database.h
+++ b/chromium/content/browser/service_worker/service_worker_database.h
@@ -21,9 +21,9 @@
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"
#include "url/origin.h"
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 0f7a0bbd637..93a89c2faac 100644
--- a/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -6,175 +6,112 @@
#include <utility>
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
-#include "content/browser/bad_message.h"
-#include "content/browser/service_worker/embedded_worker_status.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_handle.h"
-#include "content/browser/service_worker/service_worker_navigation_handle_core.h"
-#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/common/service_worker/service_worker_messages.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_frame_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"
-#include "content/public/common/content_client.h"
-#include "content/public/common/origin_util.h"
-#include "ipc/ipc_message_macros.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_error.h"
-#include "url/gurl.h"
-
-using blink::MessagePortChannel;
-using blink::WebServiceWorkerError;
namespace content {
-namespace {
-
-const uint32_t kServiceWorkerFilteredMessageClasses[] = {
- ServiceWorkerMsgStart,
-};
-
-} // namespace
-
-ServiceWorkerDispatcherHost::ServiceWorkerDispatcherHost(int render_process_id)
- : BrowserMessageFilter(kServiceWorkerFilteredMessageClasses,
- arraysize(kServiceWorkerFilteredMessageClasses)),
- BrowserAssociatedInterface<mojom::ServiceWorkerDispatcherHost>(this,
- this),
- render_process_id_(render_process_id),
- weak_ptr_factory_(this) {}
+ServiceWorkerDispatcherHost::ServiceWorkerDispatcherHost(
+ scoped_refptr<ServiceWorkerContextWrapper> context_wrapper,
+ int render_process_id)
+ : render_process_id_(render_process_id), context_wrapper_(context_wrapper) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+}
ServiceWorkerDispatcherHost::~ServiceWorkerDispatcherHost() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (GetContext() && phase_ == Phase::kAddedToContext)
- GetContext()->RemoveDispatcherHost(render_process_id_);
-}
-
-void ServiceWorkerDispatcherHost::Init(
- ServiceWorkerContextWrapper* context_wrapper) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&ServiceWorkerDispatcherHost::Init, this,
- base::RetainedRef(context_wrapper)));
- return;
- }
-
- // Just speculating that maybe we were destructed before Init() was called on
- // the IO thread in order to try to fix https://crbug.com/750267.
- if (phase_ != Phase::kInitial)
- return;
-
- context_wrapper_ = context_wrapper;
- if (!GetContext())
- return;
- GetContext()->AddDispatcherHost(render_process_id_, this);
- phase_ = Phase::kAddedToContext;
}
-void ServiceWorkerDispatcherHost::OnFilterRemoved() {
+void ServiceWorkerDispatcherHost::AddBinding(
+ mojom::ServiceWorkerDispatcherHostAssociatedRequest request) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- // Don't wait until the destructor to teardown since a new dispatcher host
- // for this process might be created before then.
- if (GetContext() && phase_ == Phase::kAddedToContext) {
- GetContext()->RemoveDispatcherHost(render_process_id_);
- weak_ptr_factory_.InvalidateWeakPtrs();
- }
- phase_ = Phase::kRemovedFromContext;
- context_wrapper_ = nullptr;
-}
-
-void ServiceWorkerDispatcherHost::OnDestruct() const {
- // Destruct on the IO thread since |context_wrapper_| should only be accessed
- // on the IO thread.
- BrowserThread::DeleteOnIOThread::Destruct(this);
+ bindings_.AddBinding(this, std::move(request));
}
-bool ServiceWorkerDispatcherHost::OnMessageReceived(
- const IPC::Message& message) {
- return false;
-}
-
-base::WeakPtr<ServiceWorkerDispatcherHost>
-ServiceWorkerDispatcherHost::AsWeakPtr() {
- return weak_ptr_factory_.GetWeakPtr();
+void ServiceWorkerDispatcherHost::RenderProcessExited(
+ RenderProcessHost* host,
+ const ChildProcessTerminationInfo& info) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // TODO(crbug.com/736203) 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 |this| is reused for
+ // another new renderer process due to reuse of the RenderProcessHost.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(
+ &ServiceWorkerDispatcherHost::RemoveAllProviderHostsForProcess,
+ base::Unretained(this)));
}
void ServiceWorkerDispatcherHost::OnProviderCreated(
- ServiceWorkerProviderHostInfo info) {
+ mojom::ServiceWorkerProviderHostInfoPtr info) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
TRACE_EVENT0("ServiceWorker",
"ServiceWorkerDispatcherHost::OnProviderCreated");
- if (!GetContext())
- return;
- if (GetContext()->GetProviderHost(render_process_id_, info.provider_id)) {
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_PROVIDER_CREATED_DUPLICATE_ID);
+ ServiceWorkerContextCore* context = context_wrapper_->context();
+ if (!context)
return;
- }
// Provider hosts for navigations are precreated on the browser process with a
// browser-assigned id. The renderer process calls OnProviderCreated once it
// creates the provider.
- if (ServiceWorkerUtils::IsBrowserAssignedProviderId(info.provider_id)) {
- if (info.type != blink::mojom::ServiceWorkerProviderType::kForWindow) {
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_NOT_WINDOW);
+ if (ServiceWorkerUtils::IsBrowserAssignedProviderId(info->provider_id)) {
+ if (info->type != blink::mojom::ServiceWorkerProviderType::kForWindow) {
+ bindings_.ReportBadMessage(
+ "SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_NOT_WINDOW");
return;
}
// Retrieve the provider host pre-created for the navigation.
- std::unique_ptr<ServiceWorkerProviderHost> provider_host =
- GetContext()->ReleaseProviderHost(ChildProcessHost::kInvalidUniqueID,
- info.provider_id);
+ ServiceWorkerProviderHost* provider_host = context->GetProviderHost(
+ ChildProcessHost::kInvalidUniqueID, info->provider_id);
// If no host is found, create one.
// TODO(crbug.com/789111#c14): This is probably not right, see bug.
if (!provider_host) {
- GetContext()->AddProviderHost(ServiceWorkerProviderHost::Create(
- render_process_id_, std::move(info), GetContext()->AsWeakPtr(),
- AsWeakPtr()));
+ context->AddProviderHost(ServiceWorkerProviderHost::Create(
+ render_process_id_, std::move(info), context->AsWeakPtr()));
return;
}
// Otherwise, complete initialization of the pre-created host.
+ if (provider_host->process_id() != ChildProcessHost::kInvalidUniqueID) {
+ bindings_.ReportBadMessage("SWDH_PRECREATED_PROVIDER_RESUED");
+ return;
+ }
provider_host->CompleteNavigationInitialized(render_process_id_,
- std::move(info), AsWeakPtr());
- GetContext()->AddProviderHost(std::move(provider_host));
+ std::move(info));
return;
}
// Provider hosts for service workers don't call OnProviderCreated. They are
// precreated and ServiceWorkerProviderHost::CompleteStartWorkerPreparation is
// called during the startup sequence once a process is allocated.
- if (info.type == blink::mojom::ServiceWorkerProviderType::kForServiceWorker) {
- bad_message::ReceivedBadMessage(
- this, bad_message::SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_SERVICE_WORKER);
+ if (info->type ==
+ blink::mojom::ServiceWorkerProviderType::kForServiceWorker) {
+ bindings_.ReportBadMessage(
+ "SWDH_PROVIDER_CREATED_ILLEGAL_TYPE_SERVICE_WORKER");
return;
}
- GetContext()->AddProviderHost(ServiceWorkerProviderHost::Create(
- render_process_id_, std::move(info), GetContext()->AsWeakPtr(),
- AsWeakPtr()));
+ if (context->GetProviderHost(render_process_id_, info->provider_id)) {
+ bindings_.ReportBadMessage("SWDH_PROVIDER_CREATED_DUPLICATE_ID");
+ return;
+ }
+ context->AddProviderHost(ServiceWorkerProviderHost::Create(
+ render_process_id_, std::move(info), context->AsWeakPtr()));
}
-ServiceWorkerContextCore* ServiceWorkerDispatcherHost::GetContext() {
+void ServiceWorkerDispatcherHost::RemoveAllProviderHostsForProcess() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!context_wrapper_.get())
- return nullptr;
- return context_wrapper_->context();
+ if (context_wrapper_->context()) {
+ context_wrapper_->context()->RemoveAllProviderHostsForProcess(
+ render_process_id_);
+ }
}
} // namespace content
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 0a096b2d367..ede12c7f019 100644
--- a/chromium/content/browser/service_worker/service_worker_dispatcher_host.h
+++ b/chromium/content/browser/service_worker/service_worker_dispatcher_host.h
@@ -7,25 +7,16 @@
#include <stdint.h>
-#include <memory>
-#include <vector>
-
#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/optional.h"
-#include "base/strings/string16.h"
-#include "content/browser/service_worker/service_worker_registration_status.h"
-#include "content/common/service_worker/service_worker.mojom.h"
-#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
+#include "content/common/content_export.h"
+#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/public/browser/browser_associated_interface.h"
-#include "content/public/browser/browser_message_filter.h"
-#include "mojo/public/cpp/bindings/strong_associated_binding_set.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host_observer.h"
+#include "mojo/public/cpp/bindings/associated_binding_set.h"
namespace content {
-class ServiceWorkerContextCore;
class ServiceWorkerContextWrapper;
namespace service_worker_dispatcher_host_unittest {
@@ -34,47 +25,31 @@ class TestingServiceWorkerDispatcherHost;
FORWARD_DECLARE_TEST(ServiceWorkerDispatcherHostTest,
ProviderCreatedAndDestroyed);
FORWARD_DECLARE_TEST(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash);
-FORWARD_DECLARE_TEST(BackgroundSyncManagerTest,
- RegisterWithoutLiveSWRegistration);
} // namespace service_worker_dispatcher_host_unittest
-// ServiceWorkerDispatcherHost is the browser-side endpoint for several IPC
-// messages for service workers. There is a 1:1 correspondence between
-// renderer processes and ServiceWorkerDispatcherHosts. Currently
-// ServiceWorkerDispatcherHost sends the legacy IPC message
-// ServiceWorkerMsg_ServiceWorkerStateChanged to its corresponding
-// ServiceWorkerDispatcher on the renderer and receives Mojo IPC messages from
-// any ServiceWorkerNetworkProvider on the renderer.
-//
-// ServiceWorkerDispatcherHost is created on the UI thread in
-// RenderProcessHostImpl::Init() via CreateMessageFilters(), but initialization,
-// destruction, and IPC message handling occur on the IO thread. It lives as
-// long as the renderer process lives. Therefore much tracking of renderer
-// processes in browser-side service worker code is built on
-// ServiceWorkerDispatcherHost lifetime.
+// ServiceWorkerDispatcherHost is a browser-side endpoint for the renderer to
+// notify the browser a service worker provider is created.
+// Unless otherwise noted, all methods are called on the IO thread.
//
-// This class is bound with mojom::ServiceWorkerDispatcherHost. All
-// InterfacePtrs on the same render process are bound to the same
-// content::ServiceWorkerDispatcherHost. This can be overridden only for
-// testing.
-//
-// TODO(leonhsl): This class no longer needs to be a BrowserMessageFilter
-// because we are already in a pure Mojo world.
+// In order to keep ordering with navigation IPCs to avoid potential races,
+// currently mojom::ServiceWorkerDispatcherHost interface is associated with the
+// legacy IPC channel.
+// TODO(leonhsl): Remove this class once we can understand how to move
+// OnProviderCreated() to an isolated message pipe.
class CONTENT_EXPORT ServiceWorkerDispatcherHost
- : public BrowserMessageFilter,
- public BrowserAssociatedInterface<mojom::ServiceWorkerDispatcherHost>,
- public mojom::ServiceWorkerDispatcherHost {
+ : public mojom::ServiceWorkerDispatcherHost,
+ public RenderProcessHostObserver {
public:
- explicit ServiceWorkerDispatcherHost(int render_process_id);
-
- void Init(ServiceWorkerContextWrapper* context_wrapper);
+ // Called on the UI thread.
+ ServiceWorkerDispatcherHost(
+ scoped_refptr<ServiceWorkerContextWrapper> context_wrapper,
+ int render_process_id);
- // BrowserMessageFilter implementation
- void OnFilterRemoved() override;
- void OnDestruct() const override;
- bool OnMessageReceived(const IPC::Message& message) override;
+ void AddBinding(mojom::ServiceWorkerDispatcherHostAssociatedRequest request);
- base::WeakPtr<ServiceWorkerDispatcherHost> AsWeakPtr();
+ // Called on the UI thread.
+ void RenderProcessExited(RenderProcessHost* host,
+ const ChildProcessTerminationInfo& info) override;
protected:
~ServiceWorkerDispatcherHost() override;
@@ -92,26 +67,16 @@ class CONTENT_EXPORT ServiceWorkerDispatcherHost
FRIEND_TEST_ALL_PREFIXES(
service_worker_dispatcher_host_unittest::ServiceWorkerDispatcherHostTest,
CleanupOnRendererCrash);
- FRIEND_TEST_ALL_PREFIXES(
- service_worker_dispatcher_host_unittest::BackgroundSyncManagerTest,
- RegisterWithoutLiveSWRegistration);
-
- enum class ProviderStatus { OK, NO_CONTEXT, DEAD_HOST, NO_HOST, NO_URL };
- // Debugging for https://crbug.com/750267
- enum class Phase { kInitial, kAddedToContext, kRemovedFromContext };
// mojom::ServiceWorkerDispatcherHost implementation
- void OnProviderCreated(ServiceWorkerProviderHostInfo info) override;
+ void OnProviderCreated(mojom::ServiceWorkerProviderHostInfoPtr info) override;
- ServiceWorkerContextCore* GetContext();
+ void RemoveAllProviderHostsForProcess();
const int render_process_id_;
// Only accessed on the IO thread.
- Phase phase_ = Phase::kInitial;
- // Only accessed on the IO thread.
scoped_refptr<ServiceWorkerContextWrapper> context_wrapper_;
-
- base::WeakPtrFactory<ServiceWorkerDispatcherHost> weak_ptr_factory_;
+ mojo::AssociatedBindingSet<mojom::ServiceWorkerDispatcherHost> bindings_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcherHost);
};
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 1505284dc5f..fae15052435 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
@@ -18,14 +18,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_context_wrapper.h"
-#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_object_host.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/browser/child_process_termination_info.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "mojo/core/embedder/embedder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
@@ -35,8 +37,8 @@ namespace content {
namespace service_worker_dispatcher_host_unittest {
static void SaveStatusCallback(bool* called,
- ServiceWorkerStatusCode* out,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode* out,
+ blink::ServiceWorkerStatusCode status) {
*called = true;
*out = status;
}
@@ -46,22 +48,6 @@ struct RemoteProviderInfo {
mojom::ServiceWorkerContainerAssociatedRequest client_request;
};
-RemoteProviderInfo SetupProviderHostInfoPtrs(
- ServiceWorkerProviderHostInfo* host_info) {
- RemoteProviderInfo remote_info;
- mojom::ServiceWorkerContainerAssociatedPtr browser_side_client_ptr;
- remote_info.client_request =
- 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());
- EXPECT_TRUE(remote_info.host_ptr.is_bound());
- EXPECT_TRUE(remote_info.client_request.is_pending());
- return remote_info;
-}
-
std::unique_ptr<ServiceWorkerNavigationHandleCore> CreateNavigationHandleCore(
ServiceWorkerContextWrapper* context_wrapper) {
std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core;
@@ -83,27 +69,6 @@ std::unique_ptr<ServiceWorkerNavigationHandleCore> CreateNavigationHandleCore(
return navigation_handle_core;
}
-class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost {
- public:
- TestingServiceWorkerDispatcherHost(int process_id,
- EmbeddedWorkerTestHelper* helper)
- : ServiceWorkerDispatcherHost(process_id),
- bad_messages_received_count_(0),
- helper_(helper) {}
-
- bool Send(IPC::Message* message) override { return helper_->Send(message); }
-
- IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); }
-
- void ShutdownForBadMessage() override { ++bad_messages_received_count_; }
-
- int bad_messages_received_count_;
-
- protected:
- EmbeddedWorkerTestHelper* helper_;
- ~TestingServiceWorkerDispatcherHost() override {}
-};
-
class ServiceWorkerDispatcherHostTest : public testing::Test {
protected:
ServiceWorkerDispatcherHostTest()
@@ -111,14 +76,20 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
void SetUp() override {
Initialize(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));
+ mojo::core::SetDefaultProcessErrorCallback(base::BindRepeating(
+ &ServiceWorkerDispatcherHostTest::OnMojoError, base::Unretained(this)));
}
void TearDown() override {
version_ = nullptr;
registration_ = nullptr;
helper_.reset();
+ mojo::core::SetDefaultProcessErrorCallback(
+ mojo::core::ProcessErrorCallback());
}
+ void OnMojoError(const std::string& error) { bad_messages_.push_back(error); }
+
ServiceWorkerContextCore* context() { return helper_->context(); }
ServiceWorkerContextWrapper* context_wrapper() {
return helper_->context_wrapper();
@@ -128,10 +99,8 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
helper_.reset(helper.release());
// Replace the default dispatcher host.
int process_id = helper_->mock_render_process_id();
- dispatcher_host_ =
- new TestingServiceWorkerDispatcherHost(process_id, helper_.get());
- helper_->RegisterDispatcherHost(process_id, nullptr);
- dispatcher_host_->Init(context_wrapper());
+ dispatcher_host_.reset(
+ new ServiceWorkerDispatcherHost(context_wrapper(), process_id));
}
void SetUpRegistration(const GURL& scope, const GURL& script_url) {
@@ -155,95 +124,151 @@ class ServiceWorkerDispatcherHostTest : public testing::Test {
context()->storage()->LazyInitializeForTest(base::DoNothing());
base::RunLoop().RunUntilIdle();
bool called = false;
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
context()->storage()->StoreRegistration(
registration_.get(), version_.get(),
base::BindOnce(&SaveStatusCallback, &called, &status));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
}
- void SendProviderCreated(blink::mojom::ServiceWorkerProviderType type,
- const GURL& pattern) {
- const int64_t kProviderId = 99;
- ServiceWorkerProviderHostInfo info(kProviderId, MSG_ROUTING_NONE, type,
- true /* is_parent_frame_secure */);
- remote_endpoint_.BindWithProviderHostInfo(&info);
-
- dispatcher_host_->OnProviderCreated(std::move(info));
- provider_host_ = context()->GetProviderHost(
- helper_->mock_render_process_id(), kProviderId);
+ RemoteProviderInfo SendProviderCreated(
+ mojom::ServiceWorkerProviderHostInfoPtr host_info) {
+ DCHECK(!host_info->host_request.is_pending());
+ DCHECK(!host_info->client_ptr_info.is_valid());
+
+ RemoteProviderInfo remote_info;
+ mojom::ServiceWorkerContainerAssociatedPtrInfo client;
+ remote_info.client_request = mojo::MakeRequest(&client);
+ host_info->host_request = mojo::MakeRequest(&remote_info.host_ptr);
+ host_info->client_ptr_info = std::move(client);
+
+ mojom::ServiceWorkerDispatcherHostAssociatedPtr ptr;
+ dispatcher_host_->AddBinding(
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&ptr));
+ ptr->OnProviderCreated(std::move(host_info));
+ base::RunLoop().RunUntilIdle();
+ return remote_info;
}
TestBrowserThreadBundle browser_thread_bundle_;
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
- scoped_refptr<TestingServiceWorkerDispatcherHost> dispatcher_host_;
+ std::unique_ptr<ServiceWorkerDispatcherHost, BrowserThread::DeleteOnIOThread>
+ dispatcher_host_;
scoped_refptr<ServiceWorkerRegistration> registration_;
scoped_refptr<ServiceWorkerVersion> version_;
- ServiceWorkerProviderHost* provider_host_;
- ServiceWorkerRemoteProviderEndpoint remote_endpoint_;
+ std::vector<std::string> bad_messages_;
};
-TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedAndDestroyed) {
+TEST_F(ServiceWorkerDispatcherHostTest, ProviderCreatedForNavigation) {
int process_id = helper_->mock_render_process_id();
- std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core;
+ // Prepare the navigation handle to create provider host.
+ std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core =
+ CreateNavigationHandleCore(helper_->context_wrapper());
+ base::WeakPtr<ServiceWorkerProviderHost> host =
+ ServiceWorkerProviderHost::PreCreateNavigationHost(
+ context()->AsWeakPtr(), true /* are_ancestors_secure */,
+ base::RepeatingCallback<WebContents*(void)>());
+ int provider_id = host->provider_id();
+ mojom::ServiceWorkerProviderHostInfoPtr host_info =
+ CreateProviderHostInfoForWindow(provider_id, 1 /* route_id */);
+ EXPECT_TRUE(context()->GetProviderHost(ChildProcessHost::kInvalidUniqueID,
+ provider_id));
+ EXPECT_TRUE(context()->GetProviderHost(process_id, provider_id));
+ navigation_handle_core->DidPreCreateProviderHost(provider_id);
+ RemoteProviderInfo remote_provider =
+ SendProviderCreated(std::move(host_info));
+
+ // Releasing the interface pointer destroys the host.
+ remote_provider.host_ptr.reset();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(context()->GetProviderHost(ChildProcessHost::kInvalidUniqueID,
+ provider_id));
+ EXPECT_FALSE(context()->GetProviderHost(process_id, provider_id));
+}
+
+// Two with the same browser-assigned ID should be seen as a bad message.
+TEST_F(ServiceWorkerDispatcherHostTest, ReusedProviderCreatedForNavigation) {
+ int process_id = helper_->mock_render_process_id();
- // Prepare the first navigation handle to create provider host.
- const int kProviderId1 = -2;
- navigation_handle_core =
+ std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core =
CreateNavigationHandleCore(helper_->context_wrapper());
- ASSERT_TRUE(navigation_handle_core);
- base::WeakPtr<ServiceWorkerProviderHost> host1 =
+ base::WeakPtr<ServiceWorkerProviderHost> host =
ServiceWorkerProviderHost::PreCreateNavigationHost(
context()->AsWeakPtr(), true /* are_ancestors_secure */,
base::RepeatingCallback<WebContents*(void)>());
- EXPECT_EQ(kProviderId1, host1->provider_id());
- ServiceWorkerProviderHostInfo host_info_1(
- host1->provider_id(), 1 /* route_id */, host1->provider_type(),
- host1->is_parent_frame_secure());
- ServiceWorkerProviderHostInfo host_info_1_copy(
- host1->provider_id(), 1 /* route_id */, host1->provider_type(),
- host1->is_parent_frame_secure());
- RemoteProviderInfo remote_info_1 = SetupProviderHostInfoPtrs(&host_info_1);
- navigation_handle_core->DidPreCreateProviderHost(host1->provider_id());
-
- dispatcher_host_->OnProviderCreated(std::move(host_info_1));
- EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId1));
-
- // Two with the same ID should be seen as a bad message.
- dispatcher_host_->OnProviderCreated(std::move(host_info_1_copy));
- EXPECT_EQ(1, dispatcher_host_->bad_messages_received_count_);
-
- // Releasing the interface pointer destroys the counterpart.
- remote_info_1.host_ptr.reset();
+ int provider_id = host->provider_id();
+ EXPECT_EQ(provider_id, host->provider_id());
+ mojom::ServiceWorkerProviderHostInfoPtr host_info =
+ CreateProviderHostInfoForWindow(provider_id, 1 /* route_id */);
+ EXPECT_TRUE(context()->GetProviderHost(ChildProcessHost::kInvalidUniqueID,
+ provider_id));
+ EXPECT_TRUE(context()->GetProviderHost(process_id, provider_id));
+ navigation_handle_core->DidPreCreateProviderHost(provider_id);
+ RemoteProviderInfo remote_provider =
+ SendProviderCreated(std::move(host_info));
+
+ host_info = CreateProviderHostInfoForWindow(provider_id, 2 /* route_id */);
+ RemoteProviderInfo remote_provider2 =
+ SendProviderCreated(std::move(host_info));
+
+ ASSERT_EQ(1u, bad_messages_.size());
+ EXPECT_EQ("SWDH_PRECREATED_PROVIDER_RESUED", bad_messages_[0]);
+
+ // Releasing the interface pointer destroys the host.
+ remote_provider.host_ptr.reset();
base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId1));
+ EXPECT_FALSE(context()->GetProviderHost(ChildProcessHost::kInvalidUniqueID,
+ provider_id));
+ EXPECT_FALSE(context()->GetProviderHost(process_id, provider_id));
+}
- // Prepare another navigation handle to create another provider host.
- const int kProviderId2 = -3;
- navigation_handle_core =
+TEST_F(ServiceWorkerDispatcherHostTest,
+ RendererDiesWithProviderCreatedForNavigation) {
+ int process_id = helper_->mock_render_process_id();
+
+ // Prepare a navigation handle to create a provider host.
+ std::unique_ptr<ServiceWorkerNavigationHandleCore> navigation_handle_core =
CreateNavigationHandleCore(helper_->context_wrapper());
- ASSERT_TRUE(navigation_handle_core);
- base::WeakPtr<ServiceWorkerProviderHost> host2 =
+ base::WeakPtr<ServiceWorkerProviderHost> host =
ServiceWorkerProviderHost::PreCreateNavigationHost(
context()->AsWeakPtr(), true /* are_ancestors_secure */,
base::RepeatingCallback<WebContents*(void)>());
- EXPECT_EQ(kProviderId2, host2->provider_id());
- ServiceWorkerProviderHostInfo host_info_2(
- host2->provider_id(), 2 /* route_id */, host2->provider_type(),
- host2->is_parent_frame_secure());
- RemoteProviderInfo remote_info_2 = SetupProviderHostInfoPtrs(&host_info_2);
- navigation_handle_core->DidPreCreateProviderHost(host2->provider_id());
-
- // Deletion of the dispatcher_host should cause providers for that
- // process to get deleted as well.
- dispatcher_host_->OnProviderCreated(std::move(host_info_2));
- EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId2));
- EXPECT_TRUE(dispatcher_host_->HasOneRef());
- dispatcher_host_ = nullptr;
- EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId2));
+ int provider_id = host->provider_id();
+ mojom::ServiceWorkerProviderHostInfoPtr host_info =
+ CreateProviderHostInfoForWindow(provider_id, 2 /* route_id */);
+ navigation_handle_core->DidPreCreateProviderHost(provider_id);
+ RemoteProviderInfo remote_provider =
+ SendProviderCreated(std::move(host_info));
+ EXPECT_TRUE(context()->GetProviderHost(process_id, provider_id));
+
+ // Simulate that the corresponding renderer process died.
+ dispatcher_host_->RenderProcessExited(nullptr /* host */,
+ ChildProcessTerminationInfo());
+ base::RunLoop().RunUntilIdle();
+ // The host still exists but is removed when the Mojo connection is
+ // destroyed.
+ EXPECT_TRUE(context()->GetProviderHost(process_id, provider_id));
+ // Releasing the interface pointer destroys the host.
+ remote_provider.host_ptr.reset();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(context()->GetProviderHost(process_id, provider_id));
+}
+
+// Two with the same renderer-assigned ID should be seen as a bad message.
+TEST_F(ServiceWorkerDispatcherHostTest, DuplicateProvider) {
+ const int kProviderId = 99;
+ RemoteProviderInfo remote_provider_1 = SendProviderCreated(
+ CreateProviderHostInfoForWindow(kProviderId, 1 /* route_id */));
+
+ EXPECT_TRUE(bad_messages_.empty());
+ RemoteProviderInfo remote_provider_2 = SendProviderCreated(
+ CreateProviderHostInfoForWindow(kProviderId, 1 /* route_id */));
+ ASSERT_EQ(1u, bad_messages_.size());
+ EXPECT_EQ("SWDH_PROVIDER_CREATED_DUPLICATE_ID", bad_messages_[0]);
}
TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
@@ -251,53 +276,48 @@ TEST_F(ServiceWorkerDispatcherHostTest, CleanupOnRendererCrash) {
GURL script_url = GURL("https://www.example.com/service_worker.js");
int process_id = helper_->mock_render_process_id();
- SendProviderCreated(blink::mojom::ServiceWorkerProviderType::kForWindow,
- pattern);
+ const int64_t kProviderId = 99;
+ mojom::ServiceWorkerProviderHostInfoPtr host_info_1 =
+ CreateProviderHostInfoForWindow(kProviderId, MSG_ROUTING_NONE);
+ RemoteProviderInfo remote_provider_1 =
+ SendProviderCreated(std::move(host_info_1));
+ ServiceWorkerProviderHost* provider_host = context()->GetProviderHost(
+ helper_->mock_render_process_id(), kProviderId);
SetUpRegistration(pattern, script_url);
- int64_t provider_id = provider_host_->provider_id();
+ EXPECT_EQ(kProviderId, provider_host->provider_id());
// Start up the worker.
bool called = false;
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_ABORT;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorAbort;
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
base::BindOnce(&SaveStatusCallback, &called, &status));
base::RunLoop().RunUntilIdle();
-
EXPECT_TRUE(called);
- EXPECT_EQ(SERVICE_WORKER_OK, status);
-
- EXPECT_TRUE(context()->GetProviderHost(process_id, provider_id));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
+ EXPECT_TRUE(context()->GetProviderHost(process_id, kProviderId));
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
- // Simulate the render process crashing.
- dispatcher_host_->OnFilterRemoved();
-
+ // Simulate that the corresponding renderer process died.
+ dispatcher_host_->RenderProcessExited(nullptr /* host */,
+ ChildProcessTerminationInfo());
+ base::RunLoop().RunUntilIdle();
// The dispatcher host should have removed the provider host.
- EXPECT_FALSE(context()->GetProviderHost(process_id, provider_id));
-
+ EXPECT_FALSE(context()->GetProviderHost(process_id, kProviderId));
// The EmbeddedWorkerInstance should still think it is running, since it will
// clean itself up when its Mojo connection to the renderer breaks.
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
- // We should be able to hook up a new dispatcher host although the old object
- // is not yet destroyed. This is what the browser does when reusing a crashed
- // render process.
- auto new_dispatcher_host =
- base::MakeRefCounted<TestingServiceWorkerDispatcherHost>(process_id,
- helper_.get());
- new_dispatcher_host->Init(context_wrapper());
-
- // 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
+ // Simulate that the browser process reused the dispatcher host due to reuse
+ // of the RenderProcessHost for another new renderer process, then the new
+ // renderer process creates a provider with the same |kProviderId|. Since the
+ // dispatcher host already 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));
- EXPECT_EQ(0, new_dispatcher_host->bad_messages_received_count_);
+ mojom::ServiceWorkerProviderHostInfoPtr host_info_2 =
+ CreateProviderHostInfoForWindow(kProviderId, MSG_ROUTING_NONE);
+ RemoteProviderInfo remote_provider_2 =
+ SendProviderCreated(std::move(host_info_2));
+ EXPECT_TRUE(bad_messages_.empty());
}
} // namespace service_worker_dispatcher_host_unittest
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 740ca70679f..dcc36e82bc0 100644
--- a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -24,11 +24,9 @@
#include "content/browser/service_worker/service_worker_metrics.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_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker.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_types.h"
-#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_features.h"
@@ -40,6 +38,9 @@
#include "net/log/net_log_event_type.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request.h"
+#include "services/network/throttling/throttling_controller.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
@@ -53,12 +54,14 @@ class DelegatingURLLoader final : public network::mojom::URLLoader {
: binding_(this), loader_(std::move(loader)) {}
~DelegatingURLLoader() override {}
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override {
DCHECK(!modified_request_headers.has_value())
<< "Redirect with modified headers was not supported yet. "
"crbug.com/845683";
- loader_->FollowRedirect(base::nullopt);
+ loader_->FollowRedirect(base::nullopt, base::nullopt);
}
void ProceedWithResponse() override { NOTREACHED(); }
@@ -166,9 +169,6 @@ class DelegatingURLLoaderClient final : public network::mojom::URLLoaderClient {
MaybeRunDevToolsCallbacks();
}
- void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {
- client_->OnDataDownloaded(data_length, encoded_length);
- }
void OnUploadProgress(int64_t current_position,
int64_t total_size,
OnUploadProgressCallback ack_callback) override {
@@ -181,10 +181,8 @@ class DelegatingURLLoaderClient final : public network::mojom::URLLoaderClient {
void OnTransferSizeUpdated(int32_t transfer_size_diff) override {
client_->OnTransferSizeUpdated(transfer_size_diff);
}
- void OnReceiveResponse(
- const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override {
- client_->OnReceiveResponse(head, std::move(downloaded_file));
+ void OnReceiveResponse(const network::ResourceResponseHead& head) override {
+ client_->OnReceiveResponse(head);
DCHECK(on_response_);
std::move(on_response_).Run();
if (!devtools_enabled_)
@@ -286,28 +284,29 @@ EventType ResourceTypeToEventType(ResourceType resource_type) {
}
std::unique_ptr<base::Value> NetLogServiceWorkerStatusCallback(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
net::NetLogCaptureMode) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
- dict->SetString("status", ServiceWorkerStatusToString(status));
+ dict->SetString("status", blink::ServiceWorkerStatusToString(status));
return std::move(dict);
}
std::unique_ptr<base::Value> NetLogFetchEventCallback(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
ServiceWorkerFetchDispatcher::FetchEventResult result,
net::NetLogCaptureMode) {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
- dict->SetString("status", ServiceWorkerStatusToString(status));
+ dict->SetString("status", blink::ServiceWorkerStatusToString(status));
dict->SetBoolean(
"has_response",
result == ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse);
return std::move(dict);
}
-void EndNetLogEventWithServiceWorkerStatus(const net::NetLogWithSource& net_log,
- net::NetLogEventType type,
- ServiceWorkerStatusCode status) {
+void EndNetLogEventWithServiceWorkerStatus(
+ const net::NetLogWithSource& net_log,
+ net::NetLogEventType type,
+ blink::ServiceWorkerStatusCode status) {
net_log.EndEvent(type,
base::Bind(&NetLogServiceWorkerStatusCallback, status));
}
@@ -392,14 +391,6 @@ class ServiceWorkerFetchDispatcher::ResponseCallback
nullptr /* body_as_stream */, std::move(body_as_blob),
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,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
@@ -503,7 +494,7 @@ ServiceWorkerFetchDispatcher::ServiceWorkerFetchDispatcher(
did_complete_(false),
weak_factory_(this) {
#if DCHECK_IS_ON()
- if (ServiceWorkerUtils::IsServicificationEnabled()) {
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
DCHECK((request_body_blob_uuid_.empty() && request_body_blob_size_ == 0 &&
!request_body_blob_ && client_id_.empty()));
}
@@ -546,7 +537,7 @@ void ServiceWorkerFetchDispatcher::StartWorker() {
// before we could finish activation.
if (version_->status() != ServiceWorkerVersion::ACTIVATED) {
DCHECK_EQ(ServiceWorkerVersion::REDUNDANT, version_->status());
- DidFail(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED);
+ DidFail(blink::ServiceWorkerStatusCode::kErrorActivateWorkerFailed);
return;
}
@@ -563,8 +554,8 @@ void ServiceWorkerFetchDispatcher::StartWorker() {
}
void ServiceWorkerFetchDispatcher::DidStartWorker(
- ServiceWorkerStatusCode status) {
- if (status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode status) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
EndNetLogEventWithServiceWorkerStatus(
net_log_, net::NetLogEventType::SERVICE_WORKER_START_WORKER, status);
DidFail(status);
@@ -609,18 +600,18 @@ void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
}
// Dispatch the fetch event.
- auto params = mojom::DispatchFetchEventParams::New();
+ auto params = blink::mojom::DispatchFetchEventParams::New();
params->request = *request_;
params->request_body_blob_uuid = request_body_blob_uuid_;
params->request_body_blob_size = request_body_blob_size_;
params->request_body_blob = request_body_blob_.PassInterface();
params->client_id = client_id_;
params->preload_handle = std::move(preload_handle_);
- // |event_dispatcher| is owned by |version_|. So it is safe to pass the
+ // |endpoint()| 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(
+ version_->endpoint()->DispatchFetchEvent(
std::move(params), std::move(response_callback_ptr),
base::BindOnce(&ServiceWorkerFetchDispatcher::OnFetchEventFinished,
base::Unretained(version_.get()), event_finish_id,
@@ -629,14 +620,15 @@ void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
void ServiceWorkerFetchDispatcher::DidFailToDispatch(
std::unique_ptr<ResponseCallback> response_callback,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
EndNetLogEventWithServiceWorkerStatus(
net_log_, net::NetLogEventType::SERVICE_WORKER_FETCH_EVENT, status);
DidFail(status);
}
-void ServiceWorkerFetchDispatcher::DidFail(ServiceWorkerStatusCode status) {
- DCHECK_NE(SERVICE_WORKER_OK, status);
+void ServiceWorkerFetchDispatcher::DidFail(
+ blink::ServiceWorkerStatusCode status) {
+ DCHECK_NE(blink::ServiceWorkerStatusCode::kOk, status);
Complete(status, FetchEventResult::kShouldFallback, ServiceWorkerResponse(),
nullptr /* body_as_stream */, nullptr /* body_as_blob */);
}
@@ -648,12 +640,12 @@ void ServiceWorkerFetchDispatcher::DidFinish(
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
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));
+ Complete(blink::ServiceWorkerStatusCode::kOk, fetch_result, response,
+ std::move(body_as_stream), std::move(body_as_blob));
}
void ServiceWorkerFetchDispatcher::Complete(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
@@ -723,6 +715,9 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
request.is_main_frame = original_info->IsMainFrame();
request.enable_load_timing = original_info->is_load_timing_enabled();
request.report_raw_headers = original_info->ShouldReportRawHeaders();
+ request.throttling_profile_id =
+ network::ThrottlingController::GetProfileIDForNetLogSource(
+ original_request->net_log().source().id);
DCHECK(net::HttpUtil::IsValidHeaderValue(
version_->navigation_preload_state().header));
@@ -735,7 +730,7 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
const int request_id = ResourceDispatcherHostImpl::Get()->MakeRequestID();
DCHECK_LT(request_id, -1);
- preload_handle_ = mojom::FetchEventPreloadHandle::New();
+ preload_handle_ = blink::mojom::FetchEventPreloadHandle::New();
network::mojom::URLLoaderClientPtr url_loader_client_ptr;
preload_handle_->url_loader_client_request =
mojo::MakeRequest(&url_loader_client_ptr);
@@ -795,7 +790,7 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreloadWithURLLoader(
"Service-Worker-Navigation-Preload",
version_->navigation_preload_state().header);
- preload_handle_ = mojom::FetchEventPreloadHandle::New();
+ preload_handle_ = blink::mojom::FetchEventPreloadHandle::New();
// Create the DelegatingURLLoaderClient, which becomes the
// URLLoaderClient for the navigation preload network request.
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 f2ac45ac5ca..29c19dca1fe 100644
--- a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
+++ b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -15,14 +15,14 @@
#include "base/time/time.h"
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/common/content_export.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.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/resource_type.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/log/net_log_with_source.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
@@ -47,7 +47,7 @@ class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
};
using FetchCallback =
- base::OnceCallback<void(ServiceWorkerStatusCode,
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode,
FetchEventResult,
const ServiceWorkerResponse&,
blink::mojom::ServiceWorkerStreamHandlePtr,
@@ -80,9 +80,9 @@ class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
base::OnceClosure on_response);
// Dispatches a fetch event to the |version| given in ctor, and fires
- // |fetch_callback| (also given in ctor) when finishes. It runs
- // |prepare_callback| as an intermediate step once the version is activated
- // and running.
+ // |fetch_callback_| (also given in ctor) once a response is received from the
+ // service worker. It runs |prepare_callback_| as an intermediate step once
+ // the version is activated and running.
void Run();
private:
@@ -91,22 +91,26 @@ class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
void DidWaitForActivation();
void StartWorker();
- void DidStartWorker(ServiceWorkerStatusCode status);
+ void DidStartWorker(blink::ServiceWorkerStatusCode status);
void DispatchFetchEvent();
void DidFailToDispatch(std::unique_ptr<ResponseCallback> callback,
- ServiceWorkerStatusCode status);
- void DidFail(ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
+ void DidFail(blink::ServiceWorkerStatusCode status);
void DidFinish(int request_id,
FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
blink::mojom::BlobPtr body_as_blob);
- void Complete(ServiceWorkerStatusCode status,
+ void Complete(blink::ServiceWorkerStatusCode status,
FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
blink::mojom::BlobPtr body_as_blob);
+ // The fetch event stays open until all respondWith() and waitUntil() promises
+ // are settled. This function is called once the renderer signals that
+ // happened. |fetch_callback_| can run before this, once respondWith() is
+ // settled.
static void OnFetchEventFinished(
ServiceWorkerVersion* version,
int event_finish_id,
@@ -137,7 +141,7 @@ class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
// |preload_handle_| holds the URLLoader and URLLoaderClient for the service
// worker to receive the navigation preload response. It's passed to the
// service worker along with the fetch event.
- mojom::FetchEventPreloadHandlePtr preload_handle_;
+ blink::mojom::FetchEventPreloadHandlePtr preload_handle_;
base::WeakPtrFactory<ServiceWorkerFetchDispatcher> weak_factory_;
diff --git a/chromium/content/browser/service_worker/service_worker_installed_script_loader.cc b/chromium/content/browser/service_worker/service_worker_installed_script_loader.cc
index 09bba617925..4bd65c56647 100644
--- a/chromium/content/browser/service_worker/service_worker_installed_script_loader.cc
+++ b/chromium/content/browser/service_worker/service_worker_installed_script_loader.cc
@@ -81,7 +81,15 @@ void ServiceWorkerInstalledScriptLoader::OnHttpInfoRead(
if (options_ & network::mojom::kURLLoadOptionSendSSLInfoWithResponse)
head.ssl_info = info->ssl_info;
- client_->OnReceiveResponse(head, nullptr /* downloaded_file */);
+ client_->OnReceiveResponse(head);
+
+ if (info->metadata) {
+ const uint8_t* data =
+ reinterpret_cast<const uint8_t*>(info->metadata->data());
+ client_->OnReceiveCachedMetadata(
+ std::vector<uint8_t>(data, data + info->metadata->size()));
+ }
+
client_->OnStartLoadingResponseBody(std::move(body_handle_));
// We continue in OnFinished().
}
@@ -111,6 +119,8 @@ void ServiceWorkerInstalledScriptLoader::OnFinished(FinishedReason reason) {
}
void ServiceWorkerInstalledScriptLoader::FollowRedirect(
+ const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
// This class never returns a redirect response to its client, so should never
// be asked to follow one.
diff --git a/chromium/content/browser/service_worker/service_worker_installed_script_loader.h b/chromium/content/browser/service_worker/service_worker_installed_script_loader.h
index 89a412e2270..f006e3b17d6 100644
--- a/chromium/content/browser/service_worker/service_worker_installed_script_loader.h
+++ b/chromium/content/browser/service_worker/service_worker_installed_script_loader.h
@@ -48,7 +48,9 @@ class CONTENT_EXPORT ServiceWorkerInstalledScriptLoader
ServiceWorkerInstalledScriptReader::FinishedReason reason) override;
// network::mojom::URLLoader overrides:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
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 c7dd5fee1e2..7e35d7ae938 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
@@ -166,7 +166,8 @@ void ServiceWorkerInstalledScriptsSender::Abort(
case ServiceWorkerInstalledScriptReader::FinishedReason::kNoHttpInfoError:
case ServiceWorkerInstalledScriptReader::FinishedReason::
kResponseReaderError:
- owner_->SetStartWorkerStatusCode(SERVICE_WORKER_ERROR_DISK_CACHE);
+ owner_->SetStartWorkerStatusCode(
+ blink::ServiceWorkerStatusCode::kErrorDiskCache);
// Abort the worker by deleting from the registration since the data was
// corrupted.
if (owner_->context()) {
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 4a441aaf7e2..db4c5af12d0 100644
--- a/chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
@@ -7,7 +7,7 @@
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
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 5fba22499c9..3b93dc19aa0 100644
--- a/chromium/content/browser/service_worker/service_worker_internals_ui.cc
+++ b/chromium/content/browser/service_worker/service_worker_internals_ui.cc
@@ -50,7 +50,7 @@ using GetRegistrationsCallback =
void OperationCompleteCallback(WeakPtr<ServiceWorkerInternalsUI> internals,
int callback_id,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::BindOnce(OperationCompleteCallback, internals,
@@ -206,7 +206,7 @@ std::unique_ptr<ListValue> GetVersionListValue(
void DidGetStoredRegistrationsOnIOThread(
scoped_refptr<ServiceWorkerContextWrapper> context,
const GetRegistrationsCallback& callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BrowserThread::PostTask(
@@ -268,15 +268,11 @@ class ServiceWorkerInternalsUI::PartitionObserver
Value(base::Int64ToString(version_id)));
}
void OnErrorReported(int64_t version_id,
- int process_id,
- int thread_id,
const ErrorInfo& info) override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::vector<std::unique_ptr<const Value>> args;
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);
@@ -287,15 +283,11 @@ class ServiceWorkerInternalsUI::PartitionObserver
ConvertToRawPtrVector(args));
}
void OnReportConsoleMessage(int64_t version_id,
- int process_id,
- int thread_id,
const ConsoleMessage& message) override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::vector<std::unique_ptr<const Value>> args;
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);
@@ -328,6 +320,8 @@ ServiceWorkerInternalsUI::ServiceWorkerInternalsUI(WebUI* web_ui)
: WebUIController(web_ui), next_partition_id_(0) {
WebUIDataSource* source =
WebUIDataSource::Create(kChromeUIServiceWorkerInternalsHost);
+ source->OverrideContentSecurityPolicyScriptSrc(
+ "script-src chrome://resources 'self' 'unsafe-eval';");
source->SetJsonPath("strings.js");
source->AddResourcePath("serviceworker_internals.js",
IDR_SERVICE_WORKER_INTERNALS_JS);
@@ -496,7 +490,7 @@ void ServiceWorkerInternalsUI::StopWorker(const ListValue* args) {
return;
}
- base::OnceCallback<void(ServiceWorkerStatusCode)> callback =
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)> callback =
base::BindOnce(OperationCompleteCallback, AsWeakPtr(), callback_id);
StopWorkerWithId(context, version_id, std::move(callback));
}
@@ -514,18 +508,18 @@ void ServiceWorkerInternalsUI::InspectWorker(const ListValue* args) {
&devtools_agent_route_id)) {
return;
}
- base::Callback<void(ServiceWorkerStatusCode)> callback =
- base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id);
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)> callback =
+ base::BindOnce(OperationCompleteCallback, AsWeakPtr(), callback_id);
scoped_refptr<ServiceWorkerDevToolsAgentHost> agent_host(
ServiceWorkerDevToolsManager::GetInstance()
->GetDevToolsAgentHostForWorker(process_host_id,
devtools_agent_route_id));
if (!agent_host.get()) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_NOT_FOUND);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorNotFound);
return;
}
agent_host->Inspect();
- std::move(callback).Run(SERVICE_WORKER_OK);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kOk);
}
void ServiceWorkerInternalsUI::Unregister(const ListValue* args) {
@@ -543,8 +537,8 @@ void ServiceWorkerInternalsUI::Unregister(const ListValue* args) {
return;
}
- base::Callback<void(ServiceWorkerStatusCode)> callback =
- base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id);
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)> callback =
+ base::BindOnce(OperationCompleteCallback, AsWeakPtr(), callback_id);
UnregisterWithScope(context, GURL(scope_string), std::move(callback));
}
@@ -562,8 +556,8 @@ void ServiceWorkerInternalsUI::StartWorker(const ListValue* args) {
!cmd_args->GetString("scope", &scope_string)) {
return;
}
- base::Callback<void(ServiceWorkerStatusCode)> callback =
- base::Bind(OperationCompleteCallback, AsWeakPtr(), callback_id);
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)> callback =
+ base::BindOnce(OperationCompleteCallback, AsWeakPtr(), callback_id);
context->StartServiceWorker(GURL(scope_string), std::move(callback));
}
@@ -583,13 +577,14 @@ void ServiceWorkerInternalsUI::StopWorkerWithId(
scoped_refptr<ServiceWorkerVersion> version =
context->GetLiveVersion(version_id);
if (!version.get()) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_NOT_FOUND);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorNotFound);
return;
}
// ServiceWorkerVersion::StopWorker() takes a base::OnceClosure for argument,
- // so bind SERVICE_WORKER_OK to callback here.
- version->StopWorker(base::BindOnce(std::move(callback), SERVICE_WORKER_OK));
+ // so bind blink::ServiceWorkerStatusCode::kOk to callback here.
+ version->StopWorker(
+ base::BindOnce(std::move(callback), blink::ServiceWorkerStatusCode::kOk));
}
void ServiceWorkerInternalsUI::UnregisterWithScope(
@@ -606,7 +601,7 @@ void ServiceWorkerInternalsUI::UnregisterWithScope(
}
if (!context->context()) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort);
return;
}
diff --git a/chromium/content/browser/service_worker/service_worker_internals_ui.h b/chromium/content/browser/service_worker/service_worker_internals_ui.h
index b9237da3b73..38dafe15874 100644
--- a/chromium/content/browser/service_worker/service_worker_internals_ui.h
+++ b/chromium/content/browser/service_worker/service_worker_internals_ui.h
@@ -12,8 +12,8 @@
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/public/browser/web_ui_controller.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace base {
class ListValue;
@@ -28,15 +28,16 @@ class ServiceWorkerInternalsUI
: public WebUIController,
public base::SupportsWeakPtr<ServiceWorkerInternalsUI> {
public:
- using StatusCallback = base::OnceCallback<void(ServiceWorkerStatusCode)>;
+ using StatusCallback =
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)>;
explicit ServiceWorkerInternalsUI(WebUI* web_ui);
+ ~ServiceWorkerInternalsUI() override;
private:
class OperationProxy;
class PartitionObserver;
- ~ServiceWorkerInternalsUI() override;
void AddContextFromStoragePartition(StoragePartition* partition);
void RemoveObserverFromStoragePartition(StoragePartition* partition);
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 f39721041ba..724ffb5a524 100644
--- a/chromium/content/browser/service_worker/service_worker_job_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_job_unittest.cc
@@ -18,8 +18,8 @@
#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_disk_cache.h"
-#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_object_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_registration_object_host.h"
#include "content/browser/service_worker/service_worker_registration_status.h"
@@ -49,10 +49,10 @@ namespace content {
namespace {
void SaveRegistrationCallback(
- ServiceWorkerStatusCode expected_status,
+ blink::ServiceWorkerStatusCode expected_status,
bool* called,
scoped_refptr<ServiceWorkerRegistration>* registration_out,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
ServiceWorkerRegistration* registration) {
EXPECT_EQ(expected_status, status);
@@ -61,10 +61,10 @@ void SaveRegistrationCallback(
}
void SaveFoundRegistrationCallback(
- ServiceWorkerStatusCode expected_status,
+ blink::ServiceWorkerStatusCode expected_status,
bool* called,
scoped_refptr<ServiceWorkerRegistration>* registration,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> result) {
EXPECT_EQ(expected_status, status);
*called = true;
@@ -77,7 +77,7 @@ void SaveFoundRegistrationCallback(
// 'called' is useful for making sure a sychronous callback is or
// isn't called.
ServiceWorkerRegisterJob::RegistrationCallback SaveRegistration(
- ServiceWorkerStatusCode expected_status,
+ blink::ServiceWorkerStatusCode expected_status,
bool* called,
scoped_refptr<ServiceWorkerRegistration>* registration) {
*called = false;
@@ -86,7 +86,7 @@ ServiceWorkerRegisterJob::RegistrationCallback SaveRegistration(
}
ServiceWorkerStorage::FindRegistrationCallback SaveFoundRegistration(
- ServiceWorkerStatusCode expected_status,
+ blink::ServiceWorkerStatusCode expected_status,
bool* called,
scoped_refptr<ServiceWorkerRegistration>* registration) {
*called = false;
@@ -94,16 +94,16 @@ ServiceWorkerStorage::FindRegistrationCallback SaveFoundRegistration(
registration);
}
-void SaveUnregistrationCallback(ServiceWorkerStatusCode expected_status,
+void SaveUnregistrationCallback(blink::ServiceWorkerStatusCode expected_status,
bool* called,
int64_t registration_id,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
EXPECT_EQ(expected_status, status);
*called = true;
}
ServiceWorkerUnregisterJob::UnregistrationCallback SaveUnregistration(
- ServiceWorkerStatusCode expected_status,
+ blink::ServiceWorkerStatusCode expected_status,
bool* called) {
*called = false;
return base::BindOnce(&SaveUnregistrationCallback, expected_status, called);
@@ -133,13 +133,15 @@ class ServiceWorkerJobTest : public testing::Test {
scoped_refptr<ServiceWorkerRegistration> RunRegisterJob(
const GURL& script_url,
const blink::mojom::ServiceWorkerRegistrationOptions& options,
- ServiceWorkerStatusCode expected_status = SERVICE_WORKER_OK);
- void RunUnregisterJob(
- const GURL& pattern,
- ServiceWorkerStatusCode expected_status = SERVICE_WORKER_OK);
+ blink::ServiceWorkerStatusCode expected_status =
+ blink::ServiceWorkerStatusCode::kOk);
+ void RunUnregisterJob(const GURL& pattern,
+ blink::ServiceWorkerStatusCode expected_status =
+ blink::ServiceWorkerStatusCode::kOk);
scoped_refptr<ServiceWorkerRegistration> FindRegistrationForPattern(
const GURL& pattern,
- ServiceWorkerStatusCode expected_status = SERVICE_WORKER_OK);
+ blink::ServiceWorkerStatusCode expected_status =
+ blink::ServiceWorkerStatusCode::kOk);
ServiceWorkerProviderHost* CreateControllee();
TestBrowserThreadBundle browser_thread_bundle_;
@@ -150,7 +152,7 @@ class ServiceWorkerJobTest : public testing::Test {
scoped_refptr<ServiceWorkerRegistration> ServiceWorkerJobTest::RunRegisterJob(
const GURL& script_url,
const blink::mojom::ServiceWorkerRegistrationOptions& options,
- ServiceWorkerStatusCode expected_status) {
+ blink::ServiceWorkerStatusCode expected_status) {
scoped_refptr<ServiceWorkerRegistration> registration;
bool called;
job_coordinator()->Register(
@@ -164,7 +166,7 @@ scoped_refptr<ServiceWorkerRegistration> ServiceWorkerJobTest::RunRegisterJob(
void ServiceWorkerJobTest::RunUnregisterJob(
const GURL& pattern,
- ServiceWorkerStatusCode expected_status) {
+ blink::ServiceWorkerStatusCode expected_status) {
bool called;
job_coordinator()->Unregister(pattern,
SaveUnregistration(expected_status, &called));
@@ -176,7 +178,7 @@ void ServiceWorkerJobTest::RunUnregisterJob(
scoped_refptr<ServiceWorkerRegistration>
ServiceWorkerJobTest::FindRegistrationForPattern(
const GURL& pattern,
- ServiceWorkerStatusCode expected_status) {
+ blink::ServiceWorkerStatusCode expected_status) {
bool called;
scoped_refptr<ServiceWorkerRegistration> registration;
storage()->FindRegistrationForPattern(
@@ -211,11 +213,13 @@ TEST_F(ServiceWorkerJobTest, SameDocumentSameRegistration) {
scoped_refptr<ServiceWorkerRegistration> registration1;
storage()->FindRegistrationForDocument(
GURL("https://www.example.com/"),
- SaveFoundRegistration(SERVICE_WORKER_OK, &called, &registration1));
+ SaveFoundRegistration(blink::ServiceWorkerStatusCode::kOk, &called,
+ &registration1));
scoped_refptr<ServiceWorkerRegistration> registration2;
storage()->FindRegistrationForDocument(
GURL("https://www.example.com/"),
- SaveFoundRegistration(SERVICE_WORKER_OK, &called, &registration2));
+ SaveFoundRegistration(blink::ServiceWorkerStatusCode::kOk, &called,
+ &registration2));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
ASSERT_TRUE(registration1.get());
@@ -236,14 +240,16 @@ TEST_F(ServiceWorkerJobTest, SameMatchSameRegistration) {
scoped_refptr<ServiceWorkerRegistration> registration1;
storage()->FindRegistrationForDocument(
GURL("https://www.example.com/one"),
- SaveFoundRegistration(SERVICE_WORKER_OK, &called, &registration1));
+ SaveFoundRegistration(blink::ServiceWorkerStatusCode::kOk, &called,
+ &registration1));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
scoped_refptr<ServiceWorkerRegistration> registration2;
storage()->FindRegistrationForDocument(
GURL("https://www.example.com/two"),
- SaveFoundRegistration(SERVICE_WORKER_OK, &called, &registration2));
+ SaveFoundRegistration(blink::ServiceWorkerStatusCode::kOk, &called,
+ &registration2));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
ASSERT_EQ(registration1, original_registration);
@@ -257,7 +263,8 @@ TEST_F(ServiceWorkerJobTest, DifferentMatchDifferentRegistration) {
scoped_refptr<ServiceWorkerRegistration> original_registration1;
job_coordinator()->Register(
GURL("https://www.example.com/service_worker.js"), options1,
- SaveRegistration(SERVICE_WORKER_OK, &called1, &original_registration1));
+ SaveRegistration(blink::ServiceWorkerStatusCode::kOk, &called1,
+ &original_registration1));
bool called2;
blink::mojom::ServiceWorkerRegistrationOptions options2;
@@ -265,7 +272,8 @@ TEST_F(ServiceWorkerJobTest, DifferentMatchDifferentRegistration) {
scoped_refptr<ServiceWorkerRegistration> original_registration2;
job_coordinator()->Register(
GURL("https://www.example.com/service_worker.js"), options2,
- SaveRegistration(SERVICE_WORKER_OK, &called2, &original_registration2));
+ SaveRegistration(blink::ServiceWorkerStatusCode::kOk, &called2,
+ &original_registration2));
EXPECT_FALSE(called1);
EXPECT_FALSE(called2);
@@ -276,11 +284,13 @@ TEST_F(ServiceWorkerJobTest, DifferentMatchDifferentRegistration) {
scoped_refptr<ServiceWorkerRegistration> registration1;
storage()->FindRegistrationForDocument(
GURL("https://www.example.com/one/"),
- SaveFoundRegistration(SERVICE_WORKER_OK, &called1, &registration1));
+ SaveFoundRegistration(blink::ServiceWorkerStatusCode::kOk, &called1,
+ &registration1));
scoped_refptr<ServiceWorkerRegistration> registration2;
storage()->FindRegistrationForDocument(
GURL("https://www.example.com/two/"),
- SaveFoundRegistration(SERVICE_WORKER_OK, &called2, &registration2));
+ SaveFoundRegistration(blink::ServiceWorkerStatusCode::kOk, &called2,
+ &registration2));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called2);
@@ -316,23 +326,23 @@ TEST_F(ServiceWorkerJobTest, Unregister) {
// One ServiceWorkerRegistrationObjectHost should have been created for the
// new registration.
EXPECT_EQ(1UL, provider_host->registration_object_hosts_.size());
- // One ServiceWorkerHandle should have been created for the new service
+ // One ServiceWorkerObjectHost should have been created for the new service
// worker.
- EXPECT_EQ(1UL, provider_host->handles_.size());
+ EXPECT_EQ(1UL, provider_host->service_worker_object_hosts_.size());
RunUnregisterJob(options.scope);
- // The service worker registration object host and service worker handle have
- // been destroyed together with |provider_host| by the above unregistration.
- // Then |registration| and |version| should be the last one reference to the
- // corresponding instance.
+ // The service worker registration object host and service worker object host
+ // have been destroyed together with |provider_host| by the above
+ // unregistration. Then |registration| and |version| should be the last one
+ // reference to the corresponding instance.
EXPECT_TRUE(registration->HasOneRef());
EXPECT_TRUE(version->HasOneRef());
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version->running_status());
EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version->status());
- registration =
- FindRegistrationForPattern(options.scope, SERVICE_WORKER_ERROR_NOT_FOUND);
+ registration = FindRegistrationForPattern(
+ options.scope, blink::ServiceWorkerStatusCode::kErrorNotFound);
EXPECT_FALSE(registration);
}
@@ -340,7 +350,7 @@ TEST_F(ServiceWorkerJobTest, Unregister) {
TEST_F(ServiceWorkerJobTest, Unregister_NothingRegistered) {
GURL pattern("https://www.example.com/");
- RunUnregisterJob(pattern, SERVICE_WORKER_ERROR_NOT_FOUND);
+ RunUnregisterJob(pattern, blink::ServiceWorkerStatusCode::kErrorNotFound);
}
// Make sure registering a new script creates a new version and shares an
@@ -386,8 +396,8 @@ TEST_F(ServiceWorkerJobTest, RegisterDuplicateScript) {
old_registration->active_version()->provider_host();
ASSERT_NE(nullptr, provider_host);
- // Clear all service worker handles.
- provider_host->handles_.clear();
+ // Clear all service worker object hosts.
+ provider_host->service_worker_object_hosts_.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();
@@ -433,8 +443,8 @@ TEST_F(ServiceWorkerJobTest, RegisterWithDifferentUpdateViaCache) {
old_registration->active_version()->provider_host();
ASSERT_NE(nullptr, provider_host);
- // Clear all service worker handles.
- provider_host->handles_.clear();
+ // Clear all service worker object hosts.
+ provider_host->service_worker_object_hosts_.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();
@@ -473,7 +483,7 @@ class FailToStartWorkerTestHelper : public EmbeddedWorkerTestHelper {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
@@ -493,7 +503,7 @@ TEST_F(ServiceWorkerJobTest, Register_FailToStartWorker) {
options.scope = GURL("https://www.example.com/");
scoped_refptr<ServiceWorkerRegistration> registration =
RunRegisterJob(GURL("https://www.example.com/service_worker.js"), options,
- SERVICE_WORKER_ERROR_START_WORKER_FAILED);
+ blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed);
ASSERT_EQ(scoped_refptr<ServiceWorkerRegistration>(nullptr), registration);
}
@@ -509,12 +519,13 @@ TEST_F(ServiceWorkerJobTest, ParallelRegUnreg) {
scoped_refptr<ServiceWorkerRegistration> registration;
job_coordinator()->Register(
script_url, options,
- SaveRegistration(SERVICE_WORKER_OK, &registration_called, &registration));
+ SaveRegistration(blink::ServiceWorkerStatusCode::kOk,
+ &registration_called, &registration));
bool unregistration_called = false;
job_coordinator()->Unregister(
- options.scope,
- SaveUnregistration(SERVICE_WORKER_OK, &unregistration_called));
+ options.scope, SaveUnregistration(blink::ServiceWorkerStatusCode::kOk,
+ &unregistration_called));
ASSERT_FALSE(registration_called);
ASSERT_FALSE(unregistration_called);
@@ -522,8 +533,8 @@ TEST_F(ServiceWorkerJobTest, ParallelRegUnreg) {
ASSERT_TRUE(registration_called);
ASSERT_TRUE(unregistration_called);
- registration =
- FindRegistrationForPattern(options.scope, SERVICE_WORKER_ERROR_NOT_FOUND);
+ registration = FindRegistrationForPattern(
+ options.scope, blink::ServiceWorkerStatusCode::kErrorNotFound);
ASSERT_EQ(scoped_refptr<ServiceWorkerRegistration>(), registration);
}
@@ -541,8 +552,8 @@ TEST_F(ServiceWorkerJobTest, ParallelRegNewScript) {
script_url1,
blink::mojom::ServiceWorkerRegistrationOptions(
pattern, blink::mojom::ServiceWorkerUpdateViaCache::kNone),
- SaveRegistration(SERVICE_WORKER_OK, &registration1_called,
- &registration1));
+ SaveRegistration(blink::ServiceWorkerStatusCode::kOk,
+ &registration1_called, &registration1));
GURL script_url2("https://www.example.com/service_worker2.js");
bool registration2_called = false;
@@ -551,8 +562,8 @@ TEST_F(ServiceWorkerJobTest, ParallelRegNewScript) {
script_url2,
blink::mojom::ServiceWorkerRegistrationOptions(
pattern, blink::mojom::ServiceWorkerUpdateViaCache::kAll),
- SaveRegistration(SERVICE_WORKER_OK, &registration2_called,
- &registration2));
+ SaveRegistration(blink::ServiceWorkerStatusCode::kOk,
+ &registration2_called, &registration2));
ASSERT_FALSE(registration1_called);
ASSERT_FALSE(registration2_called);
@@ -578,15 +589,15 @@ TEST_F(ServiceWorkerJobTest, ParallelRegSameScript) {
scoped_refptr<ServiceWorkerRegistration> registration1;
job_coordinator()->Register(
script_url, options,
- SaveRegistration(SERVICE_WORKER_OK, &registration1_called,
- &registration1));
+ SaveRegistration(blink::ServiceWorkerStatusCode::kOk,
+ &registration1_called, &registration1));
bool registration2_called = false;
scoped_refptr<ServiceWorkerRegistration> registration2;
job_coordinator()->Register(
script_url, options,
- SaveRegistration(SERVICE_WORKER_OK, &registration2_called,
- &registration2));
+ SaveRegistration(blink::ServiceWorkerStatusCode::kOk,
+ &registration2_called, &registration2));
ASSERT_FALSE(registration1_called);
ASSERT_FALSE(registration2_called);
@@ -610,13 +621,13 @@ TEST_F(ServiceWorkerJobTest, ParallelUnreg) {
bool unregistration1_called = false;
job_coordinator()->Unregister(
pattern,
- SaveUnregistration(SERVICE_WORKER_ERROR_NOT_FOUND,
+ SaveUnregistration(blink::ServiceWorkerStatusCode::kErrorNotFound,
&unregistration1_called));
bool unregistration2_called = false;
job_coordinator()->Unregister(
pattern,
- SaveUnregistration(SERVICE_WORKER_ERROR_NOT_FOUND,
+ SaveUnregistration(blink::ServiceWorkerStatusCode::kErrorNotFound,
&unregistration2_called));
ASSERT_FALSE(unregistration1_called);
@@ -629,7 +640,8 @@ TEST_F(ServiceWorkerJobTest, ParallelUnreg) {
// but we can make sure they can exist simultaneously without
// crashing.
scoped_refptr<ServiceWorkerRegistration> registration =
- FindRegistrationForPattern(pattern, SERVICE_WORKER_ERROR_NOT_FOUND);
+ FindRegistrationForPattern(
+ pattern, blink::ServiceWorkerStatusCode::kErrorNotFound);
ASSERT_EQ(scoped_refptr<ServiceWorkerRegistration>(), registration);
}
@@ -647,15 +659,15 @@ TEST_F(ServiceWorkerJobTest, AbortAll_Register) {
scoped_refptr<ServiceWorkerRegistration> registration1;
job_coordinator()->Register(
script_url1, options1,
- SaveRegistration(SERVICE_WORKER_ERROR_ABORT, &registration_called1,
- &registration1));
+ SaveRegistration(blink::ServiceWorkerStatusCode::kErrorAbort,
+ &registration_called1, &registration1));
bool registration_called2 = false;
scoped_refptr<ServiceWorkerRegistration> registration2;
job_coordinator()->Register(
script_url2, options2,
- SaveRegistration(SERVICE_WORKER_ERROR_ABORT, &registration_called2,
- &registration2));
+ SaveRegistration(blink::ServiceWorkerStatusCode::kErrorAbort,
+ &registration_called2, &registration2));
ASSERT_FALSE(registration_called1);
ASSERT_FALSE(registration_called2);
@@ -667,13 +679,15 @@ TEST_F(ServiceWorkerJobTest, AbortAll_Register) {
bool find_called1 = false;
storage()->FindRegistrationForPattern(
- options1.scope, SaveFoundRegistration(SERVICE_WORKER_ERROR_NOT_FOUND,
- &find_called1, &registration1));
+ options1.scope,
+ SaveFoundRegistration(blink::ServiceWorkerStatusCode::kErrorNotFound,
+ &find_called1, &registration1));
bool find_called2 = false;
storage()->FindRegistrationForPattern(
- options2.scope, SaveFoundRegistration(SERVICE_WORKER_ERROR_NOT_FOUND,
- &find_called2, &registration2));
+ options2.scope,
+ SaveFoundRegistration(blink::ServiceWorkerStatusCode::kErrorNotFound,
+ &find_called2, &registration2));
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(find_called1);
@@ -689,15 +703,13 @@ TEST_F(ServiceWorkerJobTest, AbortAll_Unregister) {
bool unregistration_called1 = false;
scoped_refptr<ServiceWorkerRegistration> registration1;
job_coordinator()->Unregister(
- pattern1,
- SaveUnregistration(SERVICE_WORKER_ERROR_ABORT,
- &unregistration_called1));
+ pattern1, SaveUnregistration(blink::ServiceWorkerStatusCode::kErrorAbort,
+ &unregistration_called1));
bool unregistration_called2 = false;
job_coordinator()->Unregister(
- pattern2,
- SaveUnregistration(SERVICE_WORKER_ERROR_ABORT,
- &unregistration_called2));
+ pattern2, SaveUnregistration(blink::ServiceWorkerStatusCode::kErrorAbort,
+ &unregistration_called2));
ASSERT_FALSE(unregistration_called1);
ASSERT_FALSE(unregistration_called2);
@@ -717,13 +729,14 @@ TEST_F(ServiceWorkerJobTest, AbortAll_RegUnreg) {
scoped_refptr<ServiceWorkerRegistration> registration;
job_coordinator()->Register(
script_url, options,
- SaveRegistration(SERVICE_WORKER_ERROR_ABORT, &registration_called,
- &registration));
+ SaveRegistration(blink::ServiceWorkerStatusCode::kErrorAbort,
+ &registration_called, &registration));
bool unregistration_called = false;
job_coordinator()->Unregister(
options.scope,
- SaveUnregistration(SERVICE_WORKER_ERROR_ABORT, &unregistration_called));
+ SaveUnregistration(blink::ServiceWorkerStatusCode::kErrorAbort,
+ &unregistration_called));
ASSERT_FALSE(registration_called);
ASSERT_FALSE(unregistration_called);
@@ -733,8 +746,8 @@ TEST_F(ServiceWorkerJobTest, AbortAll_RegUnreg) {
ASSERT_TRUE(registration_called);
ASSERT_TRUE(unregistration_called);
- registration =
- FindRegistrationForPattern(options.scope, SERVICE_WORKER_ERROR_NOT_FOUND);
+ registration = FindRegistrationForPattern(
+ options.scope, blink::ServiceWorkerStatusCode::kErrorNotFound);
EXPECT_EQ(scoped_refptr<ServiceWorkerRegistration>(), registration);
}
@@ -753,11 +766,11 @@ TEST_F(ServiceWorkerJobTest, UnregisterWaitingSetsRedundant) {
// waiting worker until Update is implemented.
scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
registration.get(), script_url, 1L, helper_->context()->AsWeakPtr());
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
version->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- ASSERT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
version->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
@@ -877,10 +890,9 @@ void WriteStringResponse(ServiceWorkerStorage* storage,
WriteResponse(storage, id, headers, body_buffer.get(), body.length());
}
-class UpdateJobTestHelper
- : public EmbeddedWorkerTestHelper,
- public ServiceWorkerRegistration::Listener,
- public ServiceWorkerVersion::Listener {
+class UpdateJobTestHelper : public EmbeddedWorkerTestHelper,
+ public ServiceWorkerRegistration::Listener,
+ public ServiceWorkerVersion::Observer {
public:
struct AttributeChangeLogEntry {
int64_t registration_id;
@@ -898,7 +910,7 @@ class UpdateJobTestHelper
if (observed_registration_.get())
observed_registration_->RemoveListener(this);
for (auto& version : observed_versions_)
- version->RemoveListener(this);
+ version->RemoveObserver(this);
}
ServiceWorkerStorage* storage() { return context()->storage(); }
@@ -918,7 +930,8 @@ class UpdateJobTestHelper
bool called = false;
job_coordinator()->Register(
test_origin.Resolve(kScript), options,
- SaveRegistration(SERVICE_WORKER_OK, &called, &registration));
+ SaveRegistration(blink::ServiceWorkerStatusCode::kOk, &called,
+ &registration));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
EXPECT_TRUE(registration.get());
@@ -936,7 +949,7 @@ class UpdateJobTestHelper
const GURL& scope,
const GURL& script,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
@@ -952,7 +965,7 @@ class UpdateJobTestHelper
ASSERT_TRUE(version);
observed_versions_.push_back(base::WrapRefCounted(version));
- version->AddListener(this);
+ version->AddObserver(this);
// Simulate network access.
base::TimeDelta time_since_last_check =
@@ -998,7 +1011,7 @@ class UpdateJobTestHelper
started_workers_.insert(embedded_worker_id);
EmbeddedWorkerTestHelper::OnStartWorker(
embedded_worker_id, version_id, scope, script, pause_after_download,
- std::move(dispatcher_request), std::move(controller_request),
+ std::move(service_worker_request), std::move(controller_request),
std::move(instance_host), std::move(provider_info),
std::move(installed_scripts_info));
}
@@ -1014,12 +1027,15 @@ class UpdateJobTestHelper
}
void OnResumeAfterDownload(int embedded_worker_id) override {
- if (!force_start_worker_failure_) {
- EmbeddedWorkerTestHelper::OnResumeAfterDownload(embedded_worker_id);
- } else {
- SimulateWorkerThreadStarted(GetNextThreadId(), embedded_worker_id);
- SimulateWorkerScriptEvaluated(embedded_worker_id, false);
+ if (force_start_worker_failure_) {
+ SimulateScriptEvaluationStart(embedded_worker_id);
+ SimulateWorkerStarted(
+ embedded_worker_id,
+ blink::mojom::ServiceWorkerStartStatus::kAbruptCompletion,
+ GetNextThreadId());
+ return;
}
+ EmbeddedWorkerTestHelper::OnResumeAfterDownload(embedded_worker_id);
}
// ServiceWorkerRegistration::Listener overrides
@@ -1042,7 +1058,7 @@ class UpdateJobTestHelper
update_found_ = true;
}
- // ServiceWorkerVersion::Listener overrides
+ // ServiceWorkerVersion::Observer overrides
void OnVersionStateChanged(ServiceWorkerVersion* version) override {
StateChangeLogEntry entry;
entry.version_id = version->version_id();
@@ -1073,7 +1089,7 @@ class EvictIncumbentVersionHelper : public UpdateJobTestHelper {
const GURL& scope,
const GURL& script,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
@@ -1092,7 +1108,7 @@ class EvictIncumbentVersionHelper : public UpdateJobTestHelper {
}
UpdateJobTestHelper::OnStartWorker(
embedded_worker_id, version_id, scope, script, pause_after_download,
- std::move(dispatcher_request), std::move(controller_request),
+ std::move(service_worker_request), std::move(controller_request),
std::move(instance_host), std::move(provider_info),
std::move(installed_scripts_info));
}
@@ -1354,8 +1370,9 @@ TEST_F(ServiceWorkerJobTest, Update_UninstallingRegistration) {
ServiceWorkerProviderHost* host = CreateControllee();
ServiceWorkerVersion* active_version = registration->active_version();
active_version->AddControllee(host);
- job_coordinator()->Unregister(GURL("https://www.example.com/one/"),
- SaveUnregistration(SERVICE_WORKER_OK, &called));
+ job_coordinator()->Unregister(
+ GURL("https://www.example.com/one/"),
+ SaveUnregistration(blink::ServiceWorkerStatusCode::kOk, &called));
// Update should abort after it starts and sees uninstalling.
job_coordinator()->Update(registration.get(), false);
@@ -1449,9 +1466,11 @@ TEST_F(ServiceWorkerJobTest, RegisterAndUnregisterWhileUninstalling) {
// Unregister the registration (but it's still live).
RunUnregisterJob(options.scope);
// Now it's not found in the storage.
- RunUnregisterJob(options.scope, SERVICE_WORKER_ERROR_NOT_FOUND);
+ RunUnregisterJob(options.scope,
+ blink::ServiceWorkerStatusCode::kErrorNotFound);
- FindRegistrationForPattern(options.scope, SERVICE_WORKER_ERROR_NOT_FOUND);
+ FindRegistrationForPattern(options.scope,
+ blink::ServiceWorkerStatusCode::kErrorNotFound);
EXPECT_TRUE(registration->is_uninstalling());
EXPECT_EQ(old_version, registration->active_version());
@@ -1591,8 +1610,7 @@ class EventCallbackHelper : public EmbeddedWorkerTestHelper {
blink::mojom::ServiceWorkerEventStatus::COMPLETED) {}
void OnInstallEvent(
- mojom::ServiceWorkerEventDispatcher::DispatchInstallEventCallback
- callback) override {
+ mojom::ServiceWorker::DispatchInstallEventCallback callback) override {
if (!install_callback_.is_null())
install_callback_.Run();
std::move(callback).Run(install_event_result_, has_fetch_handler_,
@@ -1600,8 +1618,7 @@ class EventCallbackHelper : public EmbeddedWorkerTestHelper {
}
void OnActivateEvent(
- mojom::ServiceWorkerEventDispatcher::DispatchActivateEventCallback
- callback) override {
+ mojom::ServiceWorker::DispatchActivateEventCallback callback) override {
std::move(callback).Run(activate_event_result_, base::Time::Now());
}
@@ -1702,7 +1719,8 @@ TEST_F(ServiceWorkerJobTest, RemoveControlleeDuringRejectedInstall) {
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, old_version->running_status());
EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, old_version->status());
- FindRegistrationForPattern(options.scope, SERVICE_WORKER_ERROR_NOT_FOUND);
+ FindRegistrationForPattern(options.scope,
+ blink::ServiceWorkerStatusCode::kErrorNotFound);
}
TEST_F(ServiceWorkerJobTest, RemoveControlleeDuringInstall_RejectActivate) {
@@ -1740,7 +1758,8 @@ TEST_F(ServiceWorkerJobTest, RemoveControlleeDuringInstall_RejectActivate) {
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, old_version->running_status());
EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, old_version->status());
- FindRegistrationForPattern(options.scope, SERVICE_WORKER_OK);
+ FindRegistrationForPattern(options.scope,
+ blink::ServiceWorkerStatusCode::kOk);
}
TEST_F(ServiceWorkerJobTest, HasFetchHandler) {
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 9b42bdbfa73..c8a912123f0 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
@@ -4,7 +4,7 @@
#include "content/browser/service_worker/service_worker_lifetime_tracker.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/time/tick_clock.h"
#include "content/public/test/test_utils.h"
diff --git a/chromium/content/browser/service_worker/service_worker_metrics.cc b/chromium/content/browser/service_worker/service_worker_metrics.cc
index f5fc5073da2..40bd68cfec9 100644
--- a/chromium/content/browser/service_worker/service_worker_metrics.cc
+++ b/chromium/content/browser/service_worker/service_worker_metrics.cc
@@ -16,6 +16,7 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
#include "net/url_request/url_request.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
@@ -28,18 +29,30 @@ std::string StartSituationToSuffix(
switch (situation) {
case ServiceWorkerMetrics::StartSituation::UNKNOWN:
NOTREACHED();
- return "_Unknown";
+ return ".Unknown";
case ServiceWorkerMetrics::StartSituation::DURING_STARTUP:
- return "_DuringStartup";
+ return ".DuringStartup";
case ServiceWorkerMetrics::StartSituation::NEW_PROCESS:
- return "_NewProcess";
+ return ".NewProcess";
case ServiceWorkerMetrics::StartSituation::EXISTING_UNREADY_PROCESS:
- return "_ExistingUnreadyProcess";
+ return ".ExistingUnreadyProcess";
case ServiceWorkerMetrics::StartSituation::EXISTING_READY_PROCESS:
- return "_ExistingReadyProcess";
+ return ".ExistingReadyProcess";
}
NOTREACHED() << static_cast<int>(situation);
- return "_Unknown";
+ return ".Unknown";
+}
+
+// TODO(falken): Remove this when the associated UMA are removed.
+std::string StartSituationToDeprecatedSuffix(
+ ServiceWorkerMetrics::StartSituation situation) {
+ // Don't change this returned string. It is written (in hashed form) into
+ // logs.
+ std::string suffix = StartSituationToSuffix(situation);
+ // Replace '.' separator with '_'.
+ DCHECK(suffix.length() > 1 && suffix[0] == '.');
+ suffix[0] = '_';
+ return suffix;
}
std::string EventTypeToSuffix(ServiceWorkerMetrics::EventType event_type) {
@@ -160,27 +173,6 @@ std::string GetWorkerPreparationSuffix(
return "_UNKNOWN";
}
-std::string GetSiteSuffix(ServiceWorkerMetrics::Site site) {
- switch (site) {
- case ServiceWorkerMetrics::Site::OTHER:
- case ServiceWorkerMetrics::Site::WITH_FETCH_HANDLER:
- case ServiceWorkerMetrics::Site::WITHOUT_FETCH_HANDLER:
- return "";
- case ServiceWorkerMetrics::Site::NEW_TAB_PAGE:
- return ".ntp";
- case ServiceWorkerMetrics::Site::PLUS:
- return ".plus";
- case ServiceWorkerMetrics::Site::INBOX:
- return ".inbox";
- case ServiceWorkerMetrics::Site::DOCS:
- return ".docs";
- case ServiceWorkerMetrics::Site::NUM_TYPES:
- NOTREACHED() << static_cast<int>(site);
- }
- NOTREACHED();
- return "";
-}
-
// Use this for histograms with dynamically generated names, which
// otherwise can't use the UMA_HISTOGRAM macro without code duplication.
void RecordSuffixedTimeHistogram(const std::string& name,
@@ -224,72 +216,22 @@ void RecordURLMetricOnUI(const std::string& metric_name, const GURL& url) {
GetContentClient()->browser()->RecordURLMetric(metric_name, url);
}
-enum EventHandledRatioType {
- EVENT_HANDLED_NONE,
- EVENT_HANDLED_SOME,
- EVENT_HANDLED_ALL,
- NUM_EVENT_HANDLED_RATIO_TYPE,
-};
-
} // namespace
using ScopedEventRecorder = ServiceWorkerMetrics::ScopedEventRecorder;
-ScopedEventRecorder::ScopedEventRecorder(
- ServiceWorkerMetrics::EventType start_worker_purpose)
- : start_worker_purpose_(start_worker_purpose) {}
+ScopedEventRecorder::ScopedEventRecorder() = default;
ScopedEventRecorder::~ScopedEventRecorder() {
- for (const auto& ev : event_stats_) {
- RecordEventHandledRatio(ev.first, ev.second.handled_events,
- ev.second.fired_events);
- }
- if (start_worker_purpose_ == EventType::NAVIGATION_HINT) {
- bool frame_fetch_event_fired =
- event_stats_[EventType::FETCH_MAIN_FRAME].fired_events ||
- event_stats_[EventType::FETCH_SUB_FRAME].fired_events;
- UMA_HISTOGRAM_BOOLEAN("ServiceWorker.StartHintPrecision",
- frame_fetch_event_fired);
- }
+ UMA_HISTOGRAM_BOOLEAN("ServiceWorker.StartHintPrecision",
+ frame_fetch_event_fired_);
}
void ScopedEventRecorder::RecordEventHandledStatus(
- ServiceWorkerMetrics::EventType event,
- bool handled) {
- event_stats_[event].fired_events++;
- if (handled)
- event_stats_[event].handled_events++;
-}
-
-void ScopedEventRecorder::RecordEventHandledRatio(
- ServiceWorkerMetrics::EventType event,
- size_t handled_events,
- size_t fired_events) {
- if (!fired_events)
- return;
- EventHandledRatioType type = EVENT_HANDLED_SOME;
- if (fired_events == handled_events)
- type = EVENT_HANDLED_ALL;
- else if (handled_events == 0)
- type = EVENT_HANDLED_NONE;
-
- // For now Fetch and Foreign Fetch are the only types that are recorded.
- switch (event) {
- case EventType::FETCH_MAIN_FRAME:
- case EventType::FETCH_SUB_FRAME:
- case EventType::FETCH_SHARED_WORKER:
- case EventType::FETCH_SUB_RESOURCE:
- UMA_HISTOGRAM_ENUMERATION("ServiceWorker.EventHandledRatioType.Fetch",
- type, NUM_EVENT_HANDLED_RATIO_TYPE);
- break;
- case EventType::FOREIGN_FETCH:
- UMA_HISTOGRAM_ENUMERATION(
- "ServiceWorker.EventHandledRatioType.ForeignFetch", type,
- NUM_EVENT_HANDLED_RATIO_TYPE);
- break;
- default:
- // Do nothing.
- break;
+ ServiceWorkerMetrics::EventType event) {
+ if (event == EventType::FETCH_MAIN_FRAME ||
+ event == EventType::FETCH_SUB_FRAME) {
+ frame_fetch_event_fired_ = true;
}
}
@@ -478,23 +420,23 @@ void ServiceWorkerMetrics::CountControlledPageLoad(Site site,
}
void ServiceWorkerMetrics::RecordStartWorkerStatus(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
EventType purpose,
bool is_installed) {
if (!is_installed) {
- UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartNewWorker.Status", status,
- SERVICE_WORKER_ERROR_MAX_VALUE);
+ UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartNewWorker.Status", status);
return;
}
- UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.Status", status,
- SERVICE_WORKER_ERROR_MAX_VALUE);
- RecordHistogramEnum(std::string("ServiceWorker.StartWorker.StatusByPurpose") +
- EventTypeToSuffix(purpose),
- status, SERVICE_WORKER_ERROR_MAX_VALUE);
+ UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.Status", status);
+ RecordHistogramEnum(
+ std::string("ServiceWorker.StartWorker.StatusByPurpose") +
+ EventTypeToSuffix(purpose),
+ static_cast<uint32_t>(status),
+ static_cast<uint32_t>(blink::ServiceWorkerStatusCode::kMaxValue));
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.Purpose", purpose,
EventType::NUM_TYPES);
- if (status == SERVICE_WORKER_ERROR_TIMEOUT) {
+ if (status == blink::ServiceWorkerStatusCode::kErrorTimeout) {
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.Timeout.StartPurpose",
purpose, EventType::NUM_TYPES);
}
@@ -513,12 +455,13 @@ void ServiceWorkerMetrics::RecordStartWorkerTime(base::TimeDelta time,
EventType purpose) {
if (is_installed) {
UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.StartWorker.Time", time);
- RecordSuffixedMediumTimeHistogram("ServiceWorker.StartWorker.Time",
- StartSituationToSuffix(start_situation),
- time);
RecordSuffixedMediumTimeHistogram(
"ServiceWorker.StartWorker.Time",
- StartSituationToSuffix(start_situation) + EventTypeToSuffix(purpose),
+ StartSituationToDeprecatedSuffix(start_situation), time);
+ RecordSuffixedMediumTimeHistogram(
+ "ServiceWorker.StartWorker.Time",
+ StartSituationToDeprecatedSuffix(start_situation) +
+ EventTypeToSuffix(purpose),
time);
} else {
UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.StartNewWorker.Time", time);
@@ -562,6 +505,11 @@ void ServiceWorkerMetrics::RecordActivatedWorkerPreparationForMainFrame(
static_cast<int>(WorkerPreparationType::NUM_TYPES));
}
+ // Don't record .Time if S13nServiceWorker is enabled.
+ // https://crbug.com/852664
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
+ return;
+
// Record the preparation time.
UMA_HISTOGRAM_MEDIUM_TIMES(
"ServiceWorker.ActivatedWorkerPreparationForMainFrame.Time", time);
@@ -598,33 +546,28 @@ void ServiceWorkerMetrics::RecordStopWorkerTime(base::TimeDelta time) {
}
void ServiceWorkerMetrics::RecordActivateEventStatus(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
bool is_shutdown) {
- UMA_HISTOGRAM_ENUMERATION("ServiceWorker.ActivateEventStatus", status,
- SERVICE_WORKER_ERROR_MAX_VALUE);
+ UMA_HISTOGRAM_ENUMERATION("ServiceWorker.ActivateEventStatus", status);
if (is_shutdown) {
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.ActivateEventStatus_InShutdown",
- status, SERVICE_WORKER_ERROR_MAX_VALUE);
+ status);
} else {
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.ActivateEventStatus_NotInShutdown",
- status, SERVICE_WORKER_ERROR_MAX_VALUE);
+ status);
}
}
void ServiceWorkerMetrics::RecordInstallEventStatus(
- ServiceWorkerStatusCode status) {
- UMA_HISTOGRAM_ENUMERATION("ServiceWorker.InstallEventStatus", status,
- SERVICE_WORKER_ERROR_MAX_VALUE);
+ blink::ServiceWorkerStatusCode status) {
+ UMA_HISTOGRAM_ENUMERATION("ServiceWorker.InstallEventStatus", status);
}
void ServiceWorkerMetrics::RecordEventDispatchingDelay(EventType event_type,
- base::TimeDelta time,
- Site site_for_metrics) {
+ base::TimeDelta time) {
const std::string name = "ServiceWorker.EventDispatchingDelay";
UMA_HISTOGRAM_TIMES(name, time);
- const std::string event_type_suffix = EventTypeToSuffix(event_type);
- const std::string site_suffix = GetSiteSuffix(site_for_metrics);
- RecordSuffixedTimeHistogram(name, event_type_suffix + site_suffix, time);
+ RecordSuffixedTimeHistogram(name, EventTypeToSuffix(event_type), time);
}
void ServiceWorkerMetrics::RecordEventTimeout(EventType event) {
@@ -736,13 +679,13 @@ void ServiceWorkerMetrics::RecordEventDuration(EventType event,
void ServiceWorkerMetrics::RecordFetchEventStatus(
bool is_main_resource,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
if (is_main_resource) {
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.FetchEvent.MainResource.Status",
- status, SERVICE_WORKER_ERROR_MAX_VALUE);
+ status);
} else {
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.FetchEvent.Subresource.Status",
- status, SERVICE_WORKER_ERROR_MAX_VALUE);
+ status);
}
}
@@ -781,133 +724,77 @@ void ServiceWorkerMetrics::RecordProcessCreated(bool is_new_process) {
is_new_process);
}
-void ServiceWorkerMetrics::RecordTimeToSendStartWorker(
- base::TimeDelta duration,
- StartSituation situation) {
- std::string name = "EmbeddedWorkerInstance.Start.TimeToSendStartWorker";
- UMA_HISTOGRAM_MEDIUM_TIMES(name, duration);
- RecordSuffixedMediumTimeHistogram(name, StartSituationToSuffix(situation),
- duration);
-}
-
-void ServiceWorkerMetrics::RecordTimeToURLJob(base::TimeDelta duration,
- StartSituation situation) {
- std::string name = "EmbeddedWorkerInstance.Start.TimeToURLJob";
- UMA_HISTOGRAM_MEDIUM_TIMES(name, duration);
- RecordSuffixedMediumTimeHistogram(name, StartSituationToSuffix(situation),
- duration);
-}
-
-void ServiceWorkerMetrics::RecordTimeToLoad(base::TimeDelta duration,
- LoadSource source,
- StartSituation situation) {
- std::string name;
- switch (source) {
- case LoadSource::NETWORK:
- name = "EmbeddedWorkerInstance.Start.TimeToLoad.Network";
- UMA_HISTOGRAM_MEDIUM_TIMES(name, duration);
- RecordSuffixedMediumTimeHistogram(name, StartSituationToSuffix(situation),
- duration);
- break;
- case LoadSource::HTTP_CACHE:
- name = "EmbeddedWorkerInstance.Start.TimeToLoad.HttpCache";
- UMA_HISTOGRAM_MEDIUM_TIMES(name, duration);
- RecordSuffixedMediumTimeHistogram(name, StartSituationToSuffix(situation),
- duration);
- break;
- case LoadSource::SERVICE_WORKER_STORAGE:
- name = "EmbeddedWorkerInstance.Start.TimeToLoad.InstalledScript";
- UMA_HISTOGRAM_MEDIUM_TIMES(name, duration);
- RecordSuffixedMediumTimeHistogram(name, StartSituationToSuffix(situation),
- duration);
- break;
- default:
- NOTREACHED() << static_cast<int>(source);
- }
-}
-
-void ServiceWorkerMetrics::RecordTimeToStartThread(base::TimeDelta duration,
+void ServiceWorkerMetrics::RecordStartWorkerTiming(const StartTimes& times,
StartSituation situation) {
- std::string name = "EmbeddedWorkerInstance.Start.TimeToStartThread";
- UMA_HISTOGRAM_MEDIUM_TIMES(name, duration);
- RecordSuffixedMediumTimeHistogram(name, StartSituationToSuffix(situation),
- duration);
-}
-
-void ServiceWorkerMetrics::RecordTimeToEvaluateScript(
- base::TimeDelta duration,
- StartSituation situation) {
- std::string name = "EmbeddedWorkerInstance.Start.TimeToEvaluateScript";
- UMA_HISTOGRAM_MEDIUM_TIMES(name, duration);
- RecordSuffixedMediumTimeHistogram(name, StartSituationToSuffix(situation),
- duration);
-}
-
-void ServiceWorkerMetrics::RecordStartMessageLatencyType(
- CrossProcessTimeDelta type) {
- UMA_HISTOGRAM_ENUMERATION(
- "EmbeddedWorkerInstance.Start.StartMessageLatency.Type", type,
- CrossProcessTimeDelta::NUM_TYPES);
-}
-
-void ServiceWorkerMetrics::RecordWaitedForRendererSetup(bool waited) {
- UMA_HISTOGRAM_BOOLEAN("EmbeddedWorkerInstance.Start.WaitedForRendererSetup",
- waited);
-}
-
-void ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming(
- mojom::EmbeddedWorkerStartTimingPtr start_timing,
- base::TimeTicks start_worker_sent_time,
- StartSituation situation) {
+ // Bail if the timings across processes weren't consistent.
if (!base::TimeTicks::IsHighResolution() ||
!base::TimeTicks::IsConsistentAcrossProcesses()) {
- RecordStartMessageLatencyType(CrossProcessTimeDelta::INACCURATE_CLOCK);
+ RecordStartWorkerTimingClockConsistency(
+ CrossProcessTimeDelta::INACCURATE_CLOCK);
return;
}
- if (start_timing->start_worker_received_time < start_worker_sent_time) {
- RecordStartMessageLatencyType(CrossProcessTimeDelta::NEGATIVE);
+ if (times.remote_start_worker_received < times.local_start_worker_sent ||
+ times.local_end < times.remote_script_evaluation_end) {
+ RecordStartWorkerTimingClockConsistency(CrossProcessTimeDelta::NEGATIVE);
return;
}
+ RecordStartWorkerTimingClockConsistency(CrossProcessTimeDelta::NORMAL);
- RecordStartMessageLatencyType(CrossProcessTimeDelta::NORMAL);
+ // Total duration.
+ UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.StartTiming.Duration",
+ times.local_end - times.local_start);
+ RecordSuffixedMediumTimeHistogram("ServiceWorker.StartTiming.Duration",
+ StartSituationToSuffix(situation),
+ times.local_end - times.local_start);
- const base::TimeDelta start_worker_message_latency =
- start_timing->start_worker_received_time - start_worker_sent_time;
- UMA_HISTOGRAM_MEDIUM_TIMES("EmbeddedWorkerInstance.Start.StartMessageLatency",
- start_worker_message_latency);
- RecordSuffixedMediumTimeHistogram(
- "EmbeddedWorkerInstance.Start.StartMessageLatency",
- StartSituationToSuffix(situation), start_worker_message_latency);
+ // SentStartWorker milestone.
+ UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.StartTiming.StartToSentStartWorker",
+ times.local_start_worker_sent - times.local_start);
- if (start_worker_sent_time < start_timing->blink_initialized_time) {
- RecordWaitedForRendererSetup(true);
- UMA_HISTOGRAM_MEDIUM_TIMES(
- "EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time",
- (start_timing->blink_initialized_time - start_worker_sent_time));
- } else {
- RecordWaitedForRendererSetup(false);
- }
+ // ReceivedStartWorker milestone.
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "ServiceWorker.StartTiming.StartToReceivedStartWorker",
+ times.remote_start_worker_received - times.local_start);
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "ServiceWorker.StartTiming.SentStartWorkerToReceivedStartWorker",
+ times.remote_start_worker_received - times.local_start_worker_sent);
+
+ // ScriptEvaluationStart milestone.
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "ServiceWorker.StartTiming.StartToScriptEvaluationStart",
+ times.remote_script_evaluation_start - times.local_start);
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "ServiceWorker.StartTiming.ReceivedStartWorkerToScriptEvaluationStart",
+ times.remote_script_evaluation_start -
+ times.remote_start_worker_received);
+
+ // ScriptEvaluationEnd milestone.
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "ServiceWorker.StartTiming.StartToScriptEvaluationEnd",
+ times.remote_script_evaluation_end - times.local_start);
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "ServiceWorker.StartTiming.ScriptEvaluationStartToScriptEvaluationEnd",
+ times.remote_script_evaluation_end -
+ times.remote_script_evaluation_start);
+
+ // End milestone.
+ UMA_HISTOGRAM_MEDIUM_TIMES(
+ "ServiceWorker.StartTiming.ScriptEvaluationEndToEnd",
+ times.local_end - times.remote_script_evaluation_end);
}
-const char* ServiceWorkerMetrics::LoadSourceToString(LoadSource source) {
- switch (source) {
- case LoadSource::NETWORK:
- return "Network";
- case LoadSource::HTTP_CACHE:
- return "HTTP cache";
- case LoadSource::SERVICE_WORKER_STORAGE:
- return "Service worker storage";
- }
- NOTREACHED() << static_cast<int>(source);
- return nullptr;
+void ServiceWorkerMetrics::RecordStartWorkerTimingClockConsistency(
+ CrossProcessTimeDelta type) {
+ UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartTiming.ClockConsistency", type,
+ CrossProcessTimeDelta::NUM_TYPES);
}
void ServiceWorkerMetrics::RecordStartStatusAfterFailure(
int failure_count,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_GT(failure_count, 0);
- if (status == SERVICE_WORKER_OK) {
+ if (status == blink::ServiceWorkerStatusCode::kOk) {
UMA_HISTOGRAM_COUNTS_1000("ServiceWorker.StartWorker.FailureStreakEnded",
failure_count);
} else if (failure_count < std::numeric_limits<int>::max()) {
@@ -917,13 +804,13 @@ void ServiceWorkerMetrics::RecordStartStatusAfterFailure(
if (failure_count == 1) {
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.AfterFailureStreak_1",
- status, SERVICE_WORKER_ERROR_MAX_VALUE);
+ status);
} else if (failure_count == 2) {
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.AfterFailureStreak_2",
- status, SERVICE_WORKER_ERROR_MAX_VALUE);
+ status);
} else if (failure_count == 3) {
UMA_HISTOGRAM_ENUMERATION("ServiceWorker.StartWorker.AfterFailureStreak_3",
- status, SERVICE_WORKER_ERROR_MAX_VALUE);
+ status);
}
}
diff --git a/chromium/content/browser/service_worker/service_worker_metrics.h b/chromium/content/browser/service_worker/service_worker_metrics.h
index 5c3c51296be..d4a4a6bea09 100644
--- a/chromium/content/browser/service_worker/service_worker_metrics.h
+++ b/chromium/content/browser/service_worker/service_worker_metrics.h
@@ -54,27 +54,71 @@ class ServiceWorkerMetrics {
// Used for UMA. Append-only.
enum URLRequestJobResult {
- REQUEST_JOB_FALLBACK_RESPONSE,
- REQUEST_JOB_FALLBACK_FOR_CORS,
- REQUEST_JOB_HEADERS_ONLY_RESPONSE,
- REQUEST_JOB_STREAM_RESPONSE,
- REQUEST_JOB_BLOB_RESPONSE,
- REQUEST_JOB_ERROR_RESPONSE_STATUS_ZERO,
- REQUEST_JOB_ERROR_BAD_BLOB,
- REQUEST_JOB_ERROR_NO_PROVIDER_HOST,
- REQUEST_JOB_ERROR_NO_ACTIVE_VERSION,
- REQUEST_JOB_ERROR_NO_REQUEST,
- REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH,
- REQUEST_JOB_ERROR_BLOB_READ,
- REQUEST_JOB_ERROR_STREAM_ABORTED,
- REQUEST_JOB_ERROR_KILLED,
- REQUEST_JOB_ERROR_KILLED_WITH_BLOB,
- REQUEST_JOB_ERROR_KILLED_WITH_STREAM,
- REQUEST_JOB_ERROR_DESTROYED,
- REQUEST_JOB_ERROR_DESTROYED_WITH_BLOB,
- REQUEST_JOB_ERROR_DESTROYED_WITH_STREAM,
- REQUEST_JOB_ERROR_BAD_DELEGATE,
- REQUEST_JOB_ERROR_REQUEST_BODY_BLOB_FAILED,
+ // The service worker fell back to network.
+ REQUEST_JOB_FALLBACK_RESPONSE = 0,
+
+ // The service worker fell back to network and CORS check is needed.
+ REQUEST_JOB_FALLBACK_FOR_CORS = 1,
+
+ // The service worker responded with headers only (no body).
+ REQUEST_JOB_HEADERS_ONLY_RESPONSE = 2,
+
+ // The service worker responded with a stream body.
+ REQUEST_JOB_STREAM_RESPONSE = 3,
+
+ // The service worker responded with a blob body.
+ REQUEST_JOB_BLOB_RESPONSE = 4,
+
+ // The renderer responded with network error (see
+ // RecordStatusZeroResponseError() for error reasons).
+ REQUEST_JOB_ERROR_RESPONSE_STATUS_ZERO = 5,
+
+ // The renderer returned a response blob that could not be read.
+ REQUEST_JOB_ERROR_BAD_BLOB = 6,
+
+ // The provider host for the request was destroyed before the request
+ // could start.
+ REQUEST_JOB_ERROR_NO_PROVIDER_HOST = 7,
+
+ // The service worker assigned to the request could not be found, when
+ // the request tried to start.
+ REQUEST_JOB_ERROR_NO_ACTIVE_VERSION = 8,
+
+ // Obsolete.
+ // REQUEST_JOB_ERROR_NO_REQUEST = 9,
+
+ // An error occurred attempting to dispatch the event to the service worker.
+ REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH = 10,
+
+ // An error occurred while reading the blob response.
+ REQUEST_JOB_ERROR_BLOB_READ = 11,
+
+ // The connection to the stream response was destroyed before all the data
+ // was read.
+ REQUEST_JOB_ERROR_STREAM_ABORTED = 12,
+
+ // The request job destructed before it finished.
+ REQUEST_JOB_ERROR_KILLED = 13,
+
+ // The request job destructed before it finished. It was reading
+ // a blob response.
+ REQUEST_JOB_ERROR_KILLED_WITH_BLOB = 14,
+
+ // The request job was destructed before it finished. It was reading
+ // a stream response.
+ REQUEST_JOB_ERROR_KILLED_WITH_STREAM = 15,
+
+ // Obsolete.
+ // REQUEST_JOB_ERROR_DESTROYED = 16,
+ // REQUEST_JOB_ERROR_DESTROYED_WITH_BLOB = 17,
+ // REQUEST_JOB_ERROR_DESTROYED_WITH_STREAM = 18,
+
+ // The request job delegate behaved incorrectly.
+ REQUEST_JOB_ERROR_BAD_DELEGATE = 19,
+
+ // The browser failed to construct the request body.
+ REQUEST_JOB_ERROR_REQUEST_BODY_BLOB_FAILED = 20,
+
NUM_REQUEST_JOB_RESULT_TYPES,
};
@@ -203,29 +247,39 @@ class ServiceWorkerMetrics {
NUM_TYPES
};
- // Not used for UMA.
- enum class LoadSource { NETWORK, HTTP_CACHE, SERVICE_WORKER_STORAGE };
+ // These are prefixed with "local" or "remote" to indicate whether the browser
+ // process or renderer process recorded the timing (browser is local).
+ struct StartTimes {
+ // The browser started the service worker startup sequence.
+ base::TimeTicks local_start;
+
+ // The browser sent the start worker IPC to the renderer.
+ base::TimeTicks local_start_worker_sent;
+
+ // The renderer received the start worker IPC.
+ base::TimeTicks remote_start_worker_received;
+
+ // The renderer started script evaluation on the worker thread.
+ base::TimeTicks remote_script_evaluation_start;
+ // The renderer finished script evaluation on the worker thread.
+ base::TimeTicks remote_script_evaluation_end;
+
+ // The browser received the worker started IPC.
+ base::TimeTicks local_end;
+ };
+
+ // Records worker activities. Currently this only records
+ // StartHintPrecision histogram.
class ScopedEventRecorder {
public:
- explicit ScopedEventRecorder(EventType start_worker_purpose);
+ ScopedEventRecorder();
~ScopedEventRecorder();
- void RecordEventHandledStatus(EventType event, bool handled);
+ void RecordEventHandledStatus(EventType event);
private:
- struct EventStat {
- size_t fired_events = 0;
- size_t handled_events = 0;
- };
-
- // Records how much of dispatched events are handled.
- static void RecordEventHandledRatio(EventType event,
- size_t handled_events,
- size_t fired_events);
-
- std::map<EventType, EventStat> event_stats_;
- const EventType start_worker_purpose_;
+ bool frame_fetch_event_fired_ = false;
DISALLOW_COPY_AND_ASSIGN(ScopedEventRecorder);
};
@@ -266,7 +320,7 @@ class ServiceWorkerMetrics {
// Records the result of trying to start a worker. |is_installed| indicates
// whether the version has been installed.
- static void RecordStartWorkerStatus(ServiceWorkerStatusCode status,
+ static void RecordStartWorkerStatus(blink::ServiceWorkerStatusCode status,
EventType purpose,
bool is_installed);
@@ -276,6 +330,8 @@ class ServiceWorkerMetrics {
// Records the time taken to successfully start a worker. |is_installed|
// indicates whether the version has been installed.
+ //
+ // TODO(crbug.com/855952): Replace this with RecordStartWorkerTiming().
static void RecordStartWorkerTime(base::TimeDelta time,
bool is_installed,
StartSituation start_situation,
@@ -296,9 +352,9 @@ class ServiceWorkerMetrics {
// Records the time taken to successfully stop a worker.
static void RecordStopWorkerTime(base::TimeDelta time);
- static void RecordActivateEventStatus(ServiceWorkerStatusCode status,
+ static void RecordActivateEventStatus(blink::ServiceWorkerStatusCode status,
bool is_shutdown);
- static void RecordInstallEventStatus(ServiceWorkerStatusCode status);
+ static void RecordInstallEventStatus(blink::ServiceWorkerStatusCode status);
// Records how often a dispatched event times out.
static void RecordEventTimeout(EventType event);
@@ -312,12 +368,11 @@ class ServiceWorkerMetrics {
// process to a Service Worker and executing the event handler in the Service
// Worker.
static void RecordEventDispatchingDelay(EventType event,
- base::TimeDelta time,
- Site site_for_metrics);
+ base::TimeDelta time);
// Records the result of dispatching a fetch event to a service worker.
static void RecordFetchEventStatus(bool is_main_resource,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// Records result of a ServiceWorkerURLRequestJob that was forwarded to
// the service worker.
@@ -334,37 +389,18 @@ class ServiceWorkerMetrics {
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
- // previous event ended).
- static void RecordTimeBetweenEvents(base::TimeDelta time);
-
- // The following record steps of EmbeddedWorkerInstance's start sequence.
static void RecordProcessCreated(bool is_new_process);
- static void RecordTimeToSendStartWorker(base::TimeDelta duration,
- StartSituation start_situation);
- static void RecordTimeToURLJob(base::TimeDelta duration,
- StartSituation start_situation);
- static void RecordTimeToLoad(base::TimeDelta duration,
- LoadSource source,
- StartSituation start_situation);
- static void RecordTimeToStartThread(base::TimeDelta duration,
- StartSituation start_situation);
- static void RecordTimeToEvaluateScript(base::TimeDelta duration,
- StartSituation start_situation);
- static void RecordStartMessageLatencyType(CrossProcessTimeDelta type);
- static void RecordWaitedForRendererSetup(bool waited);
- CONTENT_EXPORT static void RecordEmbeddedWorkerStartTiming(
- mojom::EmbeddedWorkerStartTimingPtr start_timing,
- base::TimeTicks start_worker_sent_time,
- StartSituation start_situation);
-
- static const char* LoadSourceToString(LoadSource source);
+
+ CONTENT_EXPORT static void RecordStartWorkerTiming(const StartTimes& times,
+ StartSituation situation);
+ static void RecordStartWorkerTimingClockConsistency(
+ CrossProcessTimeDelta type);
// Records the result of a start attempt that occurred after the worker had
// failed |failure_count| consecutive times.
- static void RecordStartStatusAfterFailure(int failure_count,
- ServiceWorkerStatusCode status);
+ static void RecordStartStatusAfterFailure(
+ int failure_count,
+ blink::ServiceWorkerStatusCode status);
// Records the size of Service-Worker-Navigation-Preload header when the
// navigation preload request is to be sent.
diff --git a/chromium/content/browser/service_worker/service_worker_metrics_unittest.cc b/chromium/content/browser/service_worker/service_worker_metrics_unittest.cc
index 40437a34074..4a1afc8dbfc 100644
--- a/chromium/content/browser/service_worker/service_worker_metrics_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_metrics_unittest.cc
@@ -4,14 +4,15 @@
#include "content/browser/service_worker/service_worker_metrics.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "content/browser/service_worker/embedded_worker_status.h"
#include "content/test/test_content_browser_client.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
-namespace {
+namespace service_worker_metrics_unittest {
const std::string kNavigationPreloadSuffix = "_NavigationPreloadEnabled";
const std::string kStartWorkerDuringStartupSuffix = "_StartWorkerDuringStartup";
const std::string kWorkerStartOccurred = "_WorkerStartOccurred";
@@ -65,7 +66,10 @@ void ExpectNoNavPreloadWorkerStartOccurredUMA(
0);
}
-} // namespace
+base::TimeTicks AdvanceTime(base::TimeTicks* time, int milliseconds) {
+ *time += base::TimeDelta::FromMilliseconds(milliseconds);
+ return *time;
+}
using CrossProcessTimeDelta = ServiceWorkerMetrics::CrossProcessTimeDelta;
using StartSituation = ServiceWorkerMetrics::StartSituation;
@@ -93,11 +97,15 @@ TEST(ServiceWorkerMetricsTest, ActivatedWorkerPreparation) {
kPreparationType, static_cast<int>(WorkerPreparationType::STARTING), 1);
histogram_tester.ExpectTotalCount(
kPreparationType + kNavigationPreloadSuffix, 0);
- histogram_tester.ExpectTimeBucketCount(kPreparationTime, time, 1);
- histogram_tester.ExpectTimeBucketCount(kPreparationTime + "_StartingWorker",
- time, 1);
- histogram_tester.ExpectTotalCount(
- kPreparationTime + kNavigationPreloadSuffix, 0);
+
+ // We don't record .Time histograms when S13nServiceWorker is enabled.
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ histogram_tester.ExpectTimeBucketCount(kPreparationTime, time, 1);
+ histogram_tester.ExpectTimeBucketCount(
+ kPreparationTime + "_StartingWorker", time, 1);
+ histogram_tester.ExpectTotalCount(
+ kPreparationTime + kNavigationPreloadSuffix, 0);
+ }
}
{
@@ -112,11 +120,16 @@ TEST(ServiceWorkerMetricsTest, ActivatedWorkerPreparation) {
histogram_tester.ExpectUniqueSample(
kPreparationType + kNavigationPreloadSuffix,
static_cast<int>(WorkerPreparationType::START_DURING_STARTUP), 1);
- histogram_tester.ExpectTimeBucketCount(kPreparationTime, time, 1);
- histogram_tester.ExpectTimeBucketCount(
- kPreparationTime + kNavigationPreloadSuffix, time, 1);
- histogram_tester.ExpectTotalCount(
- kPreparationTime + kWorkerStartOccurred + kNavigationPreloadSuffix, 1);
+
+ // We don't record .Time histograms when S13nServiceWorker is enabled.
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ histogram_tester.ExpectTimeBucketCount(kPreparationTime, time, 1);
+ histogram_tester.ExpectTimeBucketCount(
+ kPreparationTime + kNavigationPreloadSuffix, time, 1);
+ histogram_tester.ExpectTotalCount(
+ kPreparationTime + kWorkerStartOccurred + kNavigationPreloadSuffix,
+ 1);
+ }
}
{
@@ -136,12 +149,16 @@ TEST(ServiceWorkerMetricsTest, ActivatedWorkerPreparation) {
static_cast<int>(
WorkerPreparationType::START_IN_EXISTING_READY_PROCESS),
1);
- histogram_tester.ExpectTimeBucketCount(kPreparationTime, time, 1);
- histogram_tester.ExpectTimeBucketCount(
- kPreparationTime + kNavigationPreloadSuffix, time, 1);
- histogram_tester.ExpectTimeBucketCount(
- kPreparationTime + kWorkerStartOccurred + kNavigationPreloadSuffix,
- time, 1);
+
+ // We don't record .Time histograms when S13nServiceWorker is enabled.
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ histogram_tester.ExpectTimeBucketCount(kPreparationTime, time, 1);
+ histogram_tester.ExpectTimeBucketCount(
+ kPreparationTime + kNavigationPreloadSuffix, time, 1);
+ histogram_tester.ExpectTimeBucketCount(
+ kPreparationTime + kWorkerStartOccurred + kNavigationPreloadSuffix,
+ time, 1);
+ }
}
// Suffixed metric test.
@@ -391,106 +408,152 @@ TEST(ServiceWorkerMetricsTest, NavigationPreloadResponse_BrowserStartup) {
}
TEST(ServiceWorkerMetricsTest, EmbeddedWorkerStartTiming) {
- base::TimeTicks start_worker_sent_time = base::TimeTicks::Now();
- const base::TimeDelta latency = base::TimeDelta::FromMilliseconds(33);
- auto start_timing = mojom::EmbeddedWorkerStartTiming::New();
- start_timing->blink_initialized_time = start_worker_sent_time;
- start_timing->start_worker_received_time = start_worker_sent_time + latency;
+ ServiceWorkerMetrics::StartTimes times;
+ auto current = base::TimeTicks::Now();
+ times.local_start = current;
+ times.local_start_worker_sent = AdvanceTime(&current, 11);
+ times.remote_start_worker_received = AdvanceTime(&current, 33);
+ times.remote_script_evaluation_start = AdvanceTime(&current, 55);
+ times.remote_script_evaluation_end = AdvanceTime(&current, 77);
+ times.local_end = AdvanceTime(&current, 22);
+
StartSituation start_situation = StartSituation::EXISTING_READY_PROCESS;
base::HistogramTester histogram_tester;
- ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming(
- std::move(start_timing), start_worker_sent_time, start_situation);
- histogram_tester.ExpectUniqueSample(
- "EmbeddedWorkerInstance.Start.StartMessageLatency.Type",
- static_cast<int>(CrossProcessTimeDelta::NORMAL), 1);
+ ServiceWorkerMetrics::RecordStartWorkerTiming(times, start_situation);
+
+ // Total duration.
+ histogram_tester.ExpectTimeBucketCount("ServiceWorker.StartTiming.Duration",
+ times.local_end - times.local_start,
+ 1);
histogram_tester.ExpectTimeBucketCount(
- "EmbeddedWorkerInstance.Start.StartMessageLatency", latency, 1);
+ "ServiceWorker.StartTiming.Duration.ExistingReadyProcess",
+ times.local_end - times.local_start, 1);
+
+ // SentStartWorker milestone.
histogram_tester.ExpectTimeBucketCount(
- "EmbeddedWorkerInstance.Start.StartMessageLatency_ExistingReadyProcess",
- latency, 1);
+ "ServiceWorker.StartTiming.StartToSentStartWorker",
+ times.local_start_worker_sent - times.local_start, 1);
+
+ // ReceivedStartWorker milestone.
+ histogram_tester.ExpectTimeBucketCount(
+ "ServiceWorker.StartTiming.StartToReceivedStartWorker",
+ times.remote_start_worker_received - times.local_start, 1);
+ histogram_tester.ExpectTimeBucketCount(
+ "ServiceWorker.StartTiming.SentStartWorkerToReceivedStartWorker",
+ times.remote_start_worker_received - times.local_start_worker_sent, 1);
+
+ // ScriptEvaluationStart milestone.
+ histogram_tester.ExpectTimeBucketCount(
+ "ServiceWorker.StartTiming.StartToScriptEvaluationStart",
+ times.remote_script_evaluation_start - times.local_start, 1);
+ histogram_tester.ExpectTimeBucketCount(
+ "ServiceWorker.StartTiming.ReceivedStartWorkerToScriptEvaluationStart",
+ times.remote_script_evaluation_start - times.remote_start_worker_received,
+ 1);
+
+ // ScriptEvaluationEnd milestone.
+ histogram_tester.ExpectTimeBucketCount(
+ "ServiceWorker.StartTiming.StartToScriptEvaluationEnd",
+ times.remote_script_evaluation_end - times.local_start, 1);
+ histogram_tester.ExpectTimeBucketCount(
+ "ServiceWorker.StartTiming.ScriptEvaluationStartToScriptEvaluationEnd",
+ times.remote_script_evaluation_end - times.remote_script_evaluation_start,
+ 1);
+
+ // End milestone.
+ histogram_tester.ExpectTimeBucketCount(
+ "ServiceWorker.StartTiming.ScriptEvaluationEndToEnd",
+ times.local_end - times.remote_script_evaluation_end, 1);
+
+ // Clock consistency.
histogram_tester.ExpectUniqueSample(
- "EmbeddedWorkerInstance.Start.WaitedForRendererSetup", false, 1);
- histogram_tester.ExpectTotalCount(
- "EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time", 0);
+ "ServiceWorker.StartTiming.ClockConsistency",
+ CrossProcessTimeDelta::NORMAL, 1);
}
TEST(ServiceWorkerMetricsTest, EmbeddedWorkerStartTiming_BrowserStartup) {
- base::TimeTicks start_worker_sent_time = base::TimeTicks::Now();
- const base::TimeDelta latency = base::TimeDelta::FromMilliseconds(66);
- auto start_timing = mojom::EmbeddedWorkerStartTiming::New();
- start_timing->blink_initialized_time = start_worker_sent_time;
- start_timing->start_worker_received_time = start_worker_sent_time + latency;
+ ServiceWorkerMetrics::StartTimes times;
+ auto current = base::TimeTicks::Now();
+ times.local_start = current;
+ times.local_start_worker_sent = AdvanceTime(&current, 11);
+ times.remote_start_worker_received = AdvanceTime(&current, 66);
+ times.remote_script_evaluation_start = AdvanceTime(&current, 55);
+ times.remote_script_evaluation_end = AdvanceTime(&current, 77);
+ times.local_end = AdvanceTime(&current, 22);
+
StartSituation start_situation = StartSituation::DURING_STARTUP;
base::HistogramTester histogram_tester;
- ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming(
- std::move(start_timing), start_worker_sent_time, start_situation);
- histogram_tester.ExpectUniqueSample(
- "EmbeddedWorkerInstance.Start.StartMessageLatency.Type",
- static_cast<int>(CrossProcessTimeDelta::NORMAL), 1);
- histogram_tester.ExpectTimeBucketCount(
- "EmbeddedWorkerInstance.Start.StartMessageLatency", latency, 1);
+ ServiceWorkerMetrics::RecordStartWorkerTiming(times, start_situation);
+
+ // Total duration.
+ histogram_tester.ExpectTimeBucketCount("ServiceWorker.StartTiming.Duration",
+ times.local_end - times.local_start,
+ 1);
histogram_tester.ExpectTimeBucketCount(
- "EmbeddedWorkerInstance.Start.StartMessageLatency_DuringStartup", latency,
- 1);
- histogram_tester.ExpectUniqueSample(
- "EmbeddedWorkerInstance.Start.WaitedForRendererSetup", false, 1);
- histogram_tester.ExpectTotalCount(
- "EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time", 0);
+ "ServiceWorker.StartTiming.Duration.DuringStartup",
+ times.local_end - times.local_start, 1);
}
-TEST(ServiceWorkerMetricsTest, EmbeddedWorkerStartTiming_WaitForRenderer) {
- base::TimeTicks start_worker_sent_time = base::TimeTicks::Now();
- const base::TimeDelta latency = base::TimeDelta::FromMilliseconds(777);
- const base::TimeDelta renderer_setup = base::TimeDelta::FromMilliseconds(333);
- auto start_timing = mojom::EmbeddedWorkerStartTiming::New();
- start_timing->blink_initialized_time =
- start_worker_sent_time + renderer_setup;
- start_timing->start_worker_received_time = start_worker_sent_time + latency;
- StartSituation start_situation = StartSituation::NEW_PROCESS;
+TEST(ServiceWorkerMetricsTest,
+ EmbeddedWorkerStartTiming_NegativeLatencyForStartIPC) {
+ ServiceWorkerMetrics::StartTimes times;
+ auto current = base::TimeTicks::Now();
+ times.local_start = current;
+ times.local_start_worker_sent = AdvanceTime(&current, 11);
+ // Go back in time.
+ times.remote_start_worker_received = AdvanceTime(&current, -777);
+ times.remote_script_evaluation_start = AdvanceTime(&current, 55);
+ times.remote_script_evaluation_end = AdvanceTime(&current, 77);
+ times.local_end = AdvanceTime(&current, 22);
+
+ StartSituation start_situation = StartSituation::EXISTING_READY_PROCESS;
base::HistogramTester histogram_tester;
- ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming(
- std::move(start_timing), start_worker_sent_time, start_situation);
- histogram_tester.ExpectUniqueSample(
- "EmbeddedWorkerInstance.Start.StartMessageLatency.Type",
- static_cast<int>(CrossProcessTimeDelta::NORMAL), 1);
- histogram_tester.ExpectTimeBucketCount(
- "EmbeddedWorkerInstance.Start.StartMessageLatency", latency, 1);
- histogram_tester.ExpectTimeBucketCount(
- "EmbeddedWorkerInstance.Start.StartMessageLatency_NewProcess", latency,
- 1);
+ ServiceWorkerMetrics::RecordStartWorkerTiming(times, start_situation);
+
+ // Duration and breakdowns should not be logged.
+ histogram_tester.ExpectTotalCount("ServiceWorker.StartTiming.Duration", 0);
+ // Just test one arbitrarily chosen breakdown metric.
+ histogram_tester.ExpectTotalCount(
+ "ServiceWorker.StartTiming.StartToScriptEvaluationStart", 0);
+
+ // Clock consistency.
histogram_tester.ExpectUniqueSample(
- "EmbeddedWorkerInstance.Start.WaitedForRendererSetup", true, 1);
- histogram_tester.ExpectTimeBucketCount(
- "EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time",
- renderer_setup, 1);
+ "ServiceWorker.StartTiming.ClockConsistency",
+ CrossProcessTimeDelta::NEGATIVE, 1);
}
-TEST(ServiceWorkerMetricsTest, EmbeddedWorkerStartTiming_NegativeLatency) {
- base::TimeTicks start_worker_sent_time = base::TimeTicks::Now();
- const base::TimeDelta latency = base::TimeDelta::FromMilliseconds(777);
- auto start_timing = mojom::EmbeddedWorkerStartTiming::New();
- start_timing->blink_initialized_time = start_worker_sent_time;
- start_timing->start_worker_received_time = start_worker_sent_time - latency;
+TEST(ServiceWorkerMetricsTest,
+ EmbeddedWorkerStartTiming_NegativeLatencyForStartedIPC) {
+ ServiceWorkerMetrics::StartTimes times;
+ auto current = base::TimeTicks::Now();
+ times.local_start = current;
+ times.local_start_worker_sent = AdvanceTime(&current, 11);
+ times.remote_start_worker_received = AdvanceTime(&current, 777);
+ times.remote_script_evaluation_start = AdvanceTime(&current, 55);
+ times.remote_script_evaluation_end = AdvanceTime(&current, 77);
+ // Go back in time.
+ times.local_end = AdvanceTime(&current, -123);
+
StartSituation start_situation = StartSituation::EXISTING_READY_PROCESS;
base::HistogramTester histogram_tester;
- ServiceWorkerMetrics::RecordEmbeddedWorkerStartTiming(
- std::move(start_timing), start_worker_sent_time, start_situation);
- histogram_tester.ExpectUniqueSample(
- "EmbeddedWorkerInstance.Start.StartMessageLatency.Type",
- static_cast<int>(CrossProcessTimeDelta::NEGATIVE), 1);
- histogram_tester.ExpectTotalCount(
- "EmbeddedWorkerInstance.Start.StartMessageLatency", 0);
+ ServiceWorkerMetrics::RecordStartWorkerTiming(times, start_situation);
+
+ // Duration and breakdowns should not be logged.
+ histogram_tester.ExpectTotalCount("ServiceWorker.StartTiming.Duration", 0);
+ // Just test one arbitrarily chosen breakdown metric.
histogram_tester.ExpectTotalCount(
- "EmbeddedWorkerInstance.Start.StartMessageLatency_ExistingReadyProcess",
+ "ServiceWorker.StartTiming.ScriptEvaluationStartToScriptEvaluationEnd",
0);
- histogram_tester.ExpectTotalCount(
- "EmbeddedWorkerInstance.Start.WaitedForRendererSetup", 0);
- histogram_tester.ExpectTotalCount(
- "EmbeddedWorkerInstance.Start.WaitedForRendererSetup.Time", 0);
+
+ // Clock consistency.
+ histogram_tester.ExpectUniqueSample(
+ "ServiceWorker.StartTiming.ClockConsistency",
+ CrossProcessTimeDelta::NEGATIVE, 1);
}
+} // namespace service_worker_metrics_unittest
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc b/chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc
index 686fa1312a9..c27a6b691bd 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc
+++ b/chromium/content/browser/service_worker/service_worker_navigation_handle_core.cc
@@ -31,13 +31,21 @@ ServiceWorkerNavigationHandleCore::~ServiceWorkerNavigationHandleCore() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (provider_id_ == kInvalidServiceWorkerProviderId)
return;
- // Remove the provider host if it was never completed (navigation failed).
ServiceWorkerContextCore* context = context_wrapper_->context();
- if (!context || !context->GetProviderHost(ChildProcessHost::kInvalidUniqueID,
- provider_id_)) {
+ if (!context)
+ return;
+ ServiceWorkerProviderHost* host = context->GetProviderHost(
+ ChildProcessHost::kInvalidUniqueID, provider_id_);
+ if (!host)
return;
- }
- context->RemoveProviderHost(ChildProcessHost::kInvalidUniqueID, provider_id_);
+ // Remove the provider host if it was never completed (navigation failed).
+ // TODO(falken): ServiceWorkerNavigationHandleCore should just own a Mojo
+ // pointer tied to the lifetime of ServiceWorkerProviderHost, and send the
+ // Mojo pointer to the renderer on navigation commit. If the handle core dies
+ // before that, the provider host would be destroyed by Mojo connection error.
+ if (!host->is_execution_ready())
+ context->RemoveProviderHost(ChildProcessHost::kInvalidUniqueID,
+ provider_id_);
}
void ServiceWorkerNavigationHandleCore::DidPreCreateProviderHost(
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader.cc b/chromium/content/browser/service_worker/service_worker_navigation_loader.cc
index a5e6d0f8e73..24fa5a697bc 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader.cc
+++ b/chromium/content/browser/service_worker/service_worker_navigation_loader.cc
@@ -4,9 +4,11 @@
#include "content/browser/service_worker/service_worker_navigation_loader.h"
+#include <sstream>
#include <utility>
#include "base/optional.h"
+#include "base/trace_event/trace_event.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"
@@ -21,6 +23,17 @@ namespace content {
namespace {
+std::string ComposeFetchEventResultString(
+ ServiceWorkerFetchDispatcher::FetchEventResult result,
+ const ServiceWorkerResponse& response) {
+ if (result == ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback)
+ return "Fallback to network";
+ std::stringstream stream;
+ stream << "Got response (status_code: " << response.status_code
+ << " status_text: '" << response.status_text << "')";
+ return stream.str();
+}
+
bool BodyHasNoDataPipeGetters(const network::ResourceRequestBody* body) {
if (!body)
return true;
@@ -81,6 +94,11 @@ ServiceWorkerNavigationLoader::ServiceWorkerNavigationLoader(
url_loader_factory_getter_(std::move(url_loader_factory_getter)),
binding_(this),
weak_factory_(this) {
+ TRACE_EVENT_WITH_FLOW1(
+ "ServiceWorker",
+ "ServiceWorkerNavigationLoader::ServiceWorkerNavigationloader", this,
+ TRACE_EVENT_FLAG_FLOW_OUT, "url", resource_request_.url.spec());
+
DCHECK(ServiceWorkerUtils::IsMainResourceType(
static_cast<ResourceType>(resource_request.resource_type)));
@@ -88,10 +106,21 @@ ServiceWorkerNavigationLoader::ServiceWorkerNavigationLoader(
response_head_.load_timing.request_start_time = base::Time::Now();
}
-ServiceWorkerNavigationLoader::~ServiceWorkerNavigationLoader() = default;
+ServiceWorkerNavigationLoader::~ServiceWorkerNavigationLoader() {
+ TRACE_EVENT_WITH_FLOW0(
+ "ServiceWorker",
+ "ServiceWorkerNavigationLoader::~ServiceWorkerNavigationloader", this,
+ TRACE_EVENT_FLAG_FLOW_IN);
+};
void ServiceWorkerNavigationLoader::FallbackToNetwork() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ TRACE_EVENT_WITH_FLOW0(
+ "ServiceWorker", "ServiceWorkerNavigationLoader::FallbackToNetwork", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
response_type_ = ResponseType::FALLBACK_TO_NETWORK;
+ status_ = Status::kCompleted;
// This could be called multiple times in some cases because we simply
// call this synchronously here and don't wait for a separate async
// StartRequest cue like what URLRequestJob case does.
@@ -100,12 +129,10 @@ void ServiceWorkerNavigationLoader::FallbackToNetwork() {
std::move(loader_callback_).Run({});
}
-void ServiceWorkerNavigationLoader::FallbackToNetworkOrRenderer() {
- // TODO(kinuko): Implement this. Now we always fallback to network.
- FallbackToNetwork();
-}
-
void ServiceWorkerNavigationLoader::ForwardToServiceWorker() {
+ TRACE_EVENT_WITH_FLOW0(
+ "ServiceWorker", "ServiceWorkerNavigationLoader::ForwardToServiceWorker",
+ this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
response_type_ = ResponseType::FORWARD_TO_SERVICE_WORKER;
StartRequest();
}
@@ -114,22 +141,6 @@ bool ServiceWorkerNavigationLoader::ShouldFallbackToNetwork() {
return response_type_ == ResponseType::FALLBACK_TO_NETWORK;
}
-void ServiceWorkerNavigationLoader::FailDueToLostController() {
- NOTIMPLEMENTED();
-}
-
-void ServiceWorkerNavigationLoader::Cancel() {
- status_ = Status::kCancelled;
- weak_factory_.InvalidateWeakPtrs();
- fetch_dispatcher_.reset();
- stream_waiter_.reset();
-
- url_loader_client_->OnComplete(
- network::URLLoaderCompletionStatus(net::ERR_ABORTED));
- url_loader_client_.reset();
- DeleteIfNeeded();
-}
-
bool ServiceWorkerNavigationLoader::WasCanceled() const {
return status_ == Status::kCancelled;
}
@@ -139,11 +150,20 @@ void ServiceWorkerNavigationLoader::DetachedFromRequest() {
DeleteIfNeeded();
}
+base::WeakPtr<ServiceWorkerNavigationLoader>
+ServiceWorkerNavigationLoader::AsWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
void ServiceWorkerNavigationLoader::StartRequest() {
DCHECK_EQ(ResponseType::FORWARD_TO_SERVICE_WORKER, response_type_);
DCHECK_EQ(Status::kNotStarted, status_);
status_ = Status::kStarted;
+ TRACE_EVENT_WITH_FLOW0("ServiceWorker",
+ "ServiceWorkerNavigationLoader::StartRequest", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
ServiceWorkerMetrics::URLRequestJobResult result =
ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
ServiceWorkerVersion* active_worker =
@@ -176,7 +196,8 @@ void ServiceWorkerNavigationLoader::StartRequest() {
net::NetLogWithSource() /* TODO(scottmg): net log? */,
base::BindOnce(&ServiceWorkerNavigationLoader::DidPrepareFetchEvent,
weak_factory_.GetWeakPtr(),
- base::WrapRefCounted(active_worker)),
+ base::WrapRefCounted(active_worker),
+ active_worker->running_status()),
base::BindOnce(&ServiceWorkerNavigationLoader::DidDispatchFetchEvent,
weak_factory_.GetWeakPtr()));
did_navigation_preload_ =
@@ -192,12 +213,21 @@ void ServiceWorkerNavigationLoader::StartRequest() {
void ServiceWorkerNavigationLoader::CommitResponseHeaders() {
DCHECK_EQ(Status::kStarted, status_);
DCHECK(url_loader_client_.is_bound());
+ TRACE_EVENT_WITH_FLOW2(
+ "ServiceWorker", "ServiceWorkerNavigationLoader::CommitResponseHeaders",
+ this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+ "response_code", response_head_.headers->response_code(), "status_text",
+ response_head_.headers->GetStatusText());
status_ = Status::kSentHeader;
- url_loader_client_->OnReceiveResponse(response_head_,
- nullptr /* downloaded_file */);
+ url_loader_client_->OnReceiveResponse(response_head_);
}
void ServiceWorkerNavigationLoader::CommitCompleted(int error_code) {
+ TRACE_EVENT_WITH_FLOW1("ServiceWorker",
+ "ServiceWorkerNavigationLoader::CommitCompleted", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+ "error_code", net::ErrorToString(error_code));
+
DCHECK_LT(status_, Status::kCompleted);
DCHECK(url_loader_client_.is_bound());
status_ = Status::kCompleted;
@@ -210,6 +240,11 @@ void ServiceWorkerNavigationLoader::CommitCompleted(int error_code) {
}
void ServiceWorkerNavigationLoader::ReturnNetworkError() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ TRACE_EVENT_WITH_FLOW0(
+ "ServiceWorker", "ServiceWorkerNavigationLoader::ReturnNetworkError",
+ this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+
DCHECK(!url_loader_client_.is_bound());
DCHECK(loader_callback_);
std::move(loader_callback_)
@@ -218,17 +253,44 @@ void ServiceWorkerNavigationLoader::ReturnNetworkError() {
}
void ServiceWorkerNavigationLoader::DidPrepareFetchEvent(
- scoped_refptr<ServiceWorkerVersion> version) {
+ scoped_refptr<ServiceWorkerVersion> version,
+ EmbeddedWorkerStatus initial_worker_status) {
+ TRACE_EVENT_WITH_FLOW1(
+ "ServiceWorker", "ServiceWorkerNavigationLoader::DidPrepareFetchEvent",
+ this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+ "initial_worker_status",
+ EmbeddedWorkerInstance::StatusToString(initial_worker_status));
+
response_head_.service_worker_ready_time = base::TimeTicks::Now();
+
+ // Note that we don't record worker preparation time in S13nServiceWorker
+ // path for now. If we want to measure worker preparation time we can
+ // calculate it from response_head_.service_worker_ready_time and
+ // response_head_.load_timing.request_start.
+ // https://crbug.com/852664
+ ServiceWorkerMetrics::RecordActivatedWorkerPreparationForMainFrame(
+ base::TimeDelta(), initial_worker_status,
+ version->embedded_worker()->start_situation(), did_navigation_preload_,
+ resource_request_.url);
}
void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
blink::mojom::BlobPtr body_as_blob,
scoped_refptr<ServiceWorkerVersion> version) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+ TRACE_EVENT_WITH_FLOW2(
+ "ServiceWorker", "ServiceWorkerNavigationLoader::DidDispatchFetchEvent",
+ this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "status",
+ blink::ServiceWorkerStatusToString(status), "result",
+ ComposeFetchEventResultString(fetch_result, response));
+ ServiceWorkerMetrics::RecordFetchEventStatus(true /* is_main_resource */,
+ status);
+
ServiceWorkerMetrics::URLRequestJobResult result =
ServiceWorkerMetrics::REQUEST_JOB_ERROR_BAD_DELEGATE;
if (!delegate_->RequestStillValid(&result)) {
@@ -236,7 +298,7 @@ void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
return;
}
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
delegate_->MainResourceLoadFailed();
FallbackToNetwork();
return;
@@ -244,7 +306,6 @@ void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
if (fetch_result ==
ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback) {
- // TODO(kinuko): Check if this needs to fallback to the renderer.
FallbackToNetwork();
return;
}
@@ -259,15 +320,6 @@ void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
return;
}
- // Get SSLInfo from the ServiceWorker script's HttpResponseInfo to show HTTPS
- // padlock.
- // TODO(horo): When we support mixed-content (HTTP) no-cors requests from a
- // ServiceWorker, we have to check the security level of the responses.
- const net::HttpResponseInfo* main_script_http_info =
- version->GetMainScriptHttpResponseInfo();
- DCHECK(main_script_http_info);
- ssl_info_ = main_script_http_info->ssl_info;
-
std::move(loader_callback_)
.Run(base::BindOnce(&ServiceWorkerNavigationLoader::StartResponse,
weak_factory_.GetWeakPtr(), response, version,
@@ -284,8 +336,9 @@ void ServiceWorkerNavigationLoader::StartResponse(
DCHECK(!binding_.is_bound());
DCHECK(!url_loader_client_.is_bound());
binding_.Bind(std::move(request));
- binding_.set_connection_error_handler(base::BindOnce(
- &ServiceWorkerNavigationLoader::Cancel, base::Unretained(this)));
+ binding_.set_connection_error_handler(
+ base::BindOnce(&ServiceWorkerNavigationLoader::OnConnectionClosed,
+ base::Unretained(this)));
url_loader_client_ = std::move(client);
ServiceWorkerLoaderHelpers::SaveResponseInfo(response, &response_head_);
@@ -296,15 +349,26 @@ void ServiceWorkerNavigationLoader::StartResponse(
response_head_.did_service_worker_navigation_preload =
did_navigation_preload_;
response_head_.load_timing.receive_headers_end = base::TimeTicks::Now();
- response_head_.ssl_info = ssl_info_;
+
+ // Make the navigated page inherit the SSLInfo from its controller service
+ // worker's script. This affects the HTTPS padlock, etc, shown by the
+ // browser. See https://crbug.com/392409 for details about this design.
+ // TODO(horo): When we support mixed-content (HTTP) no-cors requests from a
+ // ServiceWorker, we have to check the security level of the responses.
+ response_head_.ssl_info = version->GetMainScriptHttpResponseInfo()->ssl_info;
// Handle a redirect response. ComputeRedirectInfo returns non-null redirect
// info if the given response is a redirect.
base::Optional<net::RedirectInfo> redirect_info =
ServiceWorkerLoaderHelpers::ComputeRedirectInfo(
resource_request_, response_head_,
- ssl_info_ && ssl_info_->token_binding_negotiated);
+ response_head_.ssl_info->token_binding_negotiated);
if (redirect_info) {
+ TRACE_EVENT_WITH_FLOW2(
+ "ServiceWorker", "ServiceWorkerNavigationLoader::StartResponse", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result",
+ "redirect", "redirect url", redirect_info->new_url.spec());
+
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
@@ -318,6 +382,10 @@ void ServiceWorkerNavigationLoader::StartResponse(
// Handle a stream response body.
if (!body_as_stream.is_null() && body_as_stream->stream.is_valid()) {
+ TRACE_EVENT_WITH_FLOW1("ServiceWorker",
+ "ServiceWorkerNavigationLoader::StartResponse", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+ "result", "stream response");
stream_waiter_ = std::make_unique<StreamWaiter>(
this, std::move(version), std::move(body_as_stream->callback_request));
url_loader_client_->OnStartLoadingResponseBody(
@@ -339,11 +407,21 @@ void ServiceWorkerNavigationLoader::StartResponse(
CommitCompleted(error);
return;
}
+ TRACE_EVENT_WITH_FLOW1("ServiceWorker",
+ "ServiceWorkerNavigationLoader::StartResponse", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+ "result", "blob response");
+
url_loader_client_->OnStartLoadingResponseBody(std::move(data_pipe));
// We continue in OnBlobReadingComplete().
return;
}
+ TRACE_EVENT_WITH_FLOW1("ServiceWorker",
+ "ServiceWorkerNavigationLoader::StartResponse", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+ "result", "no body");
+
// The response has no body.
CommitCompleted(net::OK);
}
@@ -360,6 +438,8 @@ void ServiceWorkerNavigationLoader::StartErrorResponse(
// URLLoader implementation----------------------------------------
void ServiceWorkerNavigationLoader::FollowRedirect(
+ const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
NOTIMPLEMENTED();
}
@@ -384,6 +464,23 @@ void ServiceWorkerNavigationLoader::OnBlobReadingComplete(int net_error) {
body_as_blob_.reset();
}
+void ServiceWorkerNavigationLoader::OnConnectionClosed() {
+ weak_factory_.InvalidateWeakPtrs();
+ fetch_dispatcher_.reset();
+ stream_waiter_.reset();
+ binding_.Close();
+
+ // Cancel the request if this loader hasn't yet responded to it.
+ if (status_ != Status::kCompleted && status_ != Status::kCancelled) {
+ status_ = Status::kCancelled;
+ url_loader_client_->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_ABORTED));
+ }
+ url_loader_client_.reset();
+
+ DeleteIfNeeded();
+}
+
void ServiceWorkerNavigationLoader::DeleteIfNeeded() {
if (!binding_.is_bound() && detached_from_request_)
delete this;
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader.h b/chromium/content/browser/service_worker/service_worker_navigation_loader.h
index 3aef0461d18..b39480174a3 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader.h
+++ b/chromium/content/browser/service_worker/service_worker_navigation_loader.h
@@ -11,16 +11,17 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/loader/navigation_loader_interceptor.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"
#include "content/browser/url_loader_factory_getter.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "services/network/public/mojom/url_loader.mojom.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_stream_handle.mojom.h"
@@ -84,11 +85,8 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
// Called via URLJobWrapper.
void FallbackToNetwork();
- void FallbackToNetworkOrRenderer();
void ForwardToServiceWorker();
bool ShouldFallbackToNetwork();
- void FailDueToLostController();
- void Cancel();
bool WasCanceled() const;
// The navigation request that was holding this job is
@@ -98,14 +96,17 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
// endpoint is held by the client.
void DetachedFromRequest();
+ base::WeakPtr<ServiceWorkerNavigationLoader> AsWeakPtr();
+
private:
class StreamWaiter;
// For FORWARD_TO_SERVICE_WORKER case.
void StartRequest();
- void DidPrepareFetchEvent(scoped_refptr<ServiceWorkerVersion> version);
+ void DidPrepareFetchEvent(scoped_refptr<ServiceWorkerVersion> version,
+ EmbeddedWorkerStatus initial_worker_status);
void DidDispatchFetchEvent(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
@@ -139,7 +140,9 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
void ReturnNetworkError();
// network::mojom::URLLoader:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
@@ -149,6 +152,7 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
void OnBlobReadingComplete(int net_error);
+ void OnConnectionClosed();
void DeleteIfNeeded();
ResponseType response_type_ = ResponseType::NOT_DETERMINED;
@@ -164,7 +168,6 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
bool did_navigation_preload_ = false;
network::ResourceResponseHead response_head_;
- base::Optional<net::SSLInfo> ssl_info_;
// Pointer to the URLLoaderClient (i.e. NavigationURLLoader).
network::mojom::URLLoaderClientPtr url_loader_client_;
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc b/chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
index 362281ad037..3b22bc42d71 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
@@ -5,6 +5,7 @@
#include "content/browser/service_worker/service_worker_navigation_loader.h"
#include "base/run_loop.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "content/browser/loader/navigation_loader_interceptor.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
@@ -12,13 +13,13 @@
#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.mojom.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/common/single_request_url_loader_factory.h"
+#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/data_pipe_utils.h"
-#include "net/http/http_util.h"
#include "net/ssl/ssl_info.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
@@ -53,7 +54,8 @@ void ReceiveRequestHandler(
// 1. ServiceWorkerNavigationLoader asks ServiceWorkerFetchDispatcher to start
// navigation preload.
// 2. ServiceWorkerFetchDispatcher starts the network request which is mocked
-// by MockNetworkURLLoaderFactory. The response is sent to
+// by EmbeddedWorkerTestHelper's default network loader factory. The
+// response is sent to
// ServiceWorkerFetchDispatcher::DelegatingURLLoaderClient.
// 3. DelegatingURLLoaderClient sends the response to the |preload_handle|
// that was passed to Helper::OnFetchEvent().
@@ -68,10 +70,9 @@ class NavigationPreloadLoaderClient final
: public network::mojom::URLLoaderClient {
public:
NavigationPreloadLoaderClient(
- mojom::FetchEventPreloadHandlePtr preload_handle,
+ blink::mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback)
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
: url_loader_(std::move(preload_handle->url_loader)),
binding_(this, std::move(preload_handle->url_loader_client_request)),
response_callback_(std::move(response_callback)),
@@ -84,8 +85,7 @@ class NavigationPreloadLoaderClient final
// network::mojom::URLLoaderClient implementation
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override {
+ const network::ResourceResponseHead& response_head) override {
response_head_ = response_head;
}
void OnStartLoadingResponseBody(
@@ -126,8 +126,6 @@ class NavigationPreloadLoaderClient final
void OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head) override {}
- void OnDataDownloaded(int64_t data_length,
- int64_t encoded_data_length) override {}
void OnUploadProgress(int64_t current_position,
int64_t total_size,
OnUploadProgressCallback ack_callback) override {}
@@ -145,72 +143,16 @@ class NavigationPreloadLoaderClient final
// Callbacks that complete Helper::OnFetchEvent().
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_;
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback_;
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_;
DISALLOW_COPY_AND_ASSIGN(NavigationPreloadLoaderClient);
};
-// A URLLoaderFactory that returns 200 OK with a simple body to any request.
-//
-// ServiceWorkerNavigationLoaderTest sets the network factory for
-// ServiceWorkerContextCore to MockNetworkURLLoaderFactory. So far, it's only
-// used for navigation preload in these tests.
-class MockNetworkURLLoaderFactory final
- : public network::mojom::URLLoaderFactory {
- public:
- MockNetworkURLLoaderFactory() = default;
-
- // network::mojom::URLLoaderFactory implementation.
- void CreateLoaderAndStart(network::mojom::URLLoaderRequest request,
- int32_t routing_id,
- int32_t request_id,
- uint32_t options,
- const network::ResourceRequest& url_request,
- network::mojom::URLLoaderClientPtr client,
- const net::MutableNetworkTrafficAnnotationTag&
- traffic_annotation) override {
- 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()));
- network::ResourceResponseHead response;
- response.headers = info.headers;
- response.headers->GetMimeType(&response.mime_type);
- client->OnReceiveResponse(response, 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(network::mojom::URLLoaderFactoryRequest request) override {
- bindings_.AddBinding(this, std::move(request));
- }
-
- private:
- mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
- DISALLOW_COPY_AND_ASSIGN(MockNetworkURLLoaderFactory);
-};
-
// Helper simulates a service worker handling fetch events. The response can be
// customized via RespondWith* functions.
class Helper : public EmbeddedWorkerTestHelper {
public:
- Helper()
- : EmbeddedWorkerTestHelper(
- base::FilePath(),
- base::MakeRefCounted<URLLoaderFactoryGetter>()) {
- url_loader_factory_getter()->SetNetworkFactoryForTesting(
- &mock_url_loader_factory_);
- }
+ Helper() : EmbeddedWorkerTestHelper(base::FilePath()) {}
~Helper() override = default;
// Tells this helper to respond to fetch events with the specified blob.
@@ -287,10 +229,10 @@ class Helper : public EmbeddedWorkerTestHelper {
void OnFetchEvent(
int embedded_worker_id,
const network::ResourceRequest& request,
- mojom::FetchEventPreloadHandlePtr preload_handle,
+ blink::mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback) override {
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
+ override {
// Basic checks on DispatchFetchEvent parameters.
EXPECT_TRUE(ServiceWorkerUtils::IsMainResourceType(
static_cast<ResourceType>(request.resource_type)));
@@ -375,7 +317,7 @@ class Helper : public EmbeddedWorkerTestHelper {
SimulateWorkerStopped(embedded_worker_id);
// Finish the event by calling |finish_callback|.
// This is the Mojo callback for
- // mojom::ServiceWorkerEventDispatcher::DispatchFetchEvent().
+ // mojom::ServiceWorker::DispatchFetchEvent().
// If this is not called, Mojo will complain. In production code,
// ServiceWorkerContextClient would call this when it aborts all
// callbacks after an unexpected stop.
@@ -444,13 +386,11 @@ class Helper : public EmbeddedWorkerTestHelper {
blink::mojom::ServiceWorkerStreamHandlePtr stream_handle_;
// For ResponseMode::kEarlyResponse.
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback_;
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_;
// For ResponseMode::kRedirect.
GURL redirected_url_;
- MockNetworkURLLoaderFactory mock_url_loader_factory_;
DISALLOW_COPY_AND_ASSIGN(Helper);
};
@@ -471,6 +411,9 @@ CreateResponseInfoFromServiceWorker() {
return head;
}
+const char kHistogramMainResourceFetchEvent[] =
+ "ServiceWorker.FetchEvent.MainResource.Status";
+
// ServiceWorkerNavigationLoaderTest is for testing the handling of requests
// by a service worker via ServiceWorkerNavigationLoader.
//
@@ -487,12 +430,12 @@ class ServiceWorkerNavigationLoaderTest
public ServiceWorkerNavigationLoader::Delegate {
public:
ServiceWorkerNavigationLoaderTest()
- : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
- helper_(std::make_unique<Helper>()) {}
+ : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
~ServiceWorkerNavigationLoaderTest() override = default;
void SetUp() override {
feature_list_.InitAndEnableFeature(network::features::kNetworkService);
+ helper_ = std::make_unique<Helper>();
// Create an active service worker.
storage()->LazyInitializeForTest(base::DoNothing());
@@ -517,11 +460,11 @@ class ServiceWorkerNavigationLoaderTest
// Make the registration findable via storage functions.
registration_->set_last_update_check(base::Time::Now());
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
storage()->StoreRegistration(registration_.get(), version_.get(),
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- ASSERT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
}
ServiceWorkerStorage* storage() { return helper_->context()->storage(); }
@@ -620,6 +563,8 @@ class ServiceWorkerNavigationLoaderTest
};
TEST_F(ServiceWorkerNavigationLoaderTest, Basic) {
+ base::HistogramTester histogram_tester;
+
// Perform the request
LoaderResult result = StartRequest(CreateRequest());
EXPECT_EQ(LoaderResult::kHandledRequest, result);
@@ -629,9 +574,14 @@ TEST_F(ServiceWorkerNavigationLoaderTest, Basic) {
const network::ResourceResponseHead& info = client_.response_head();
EXPECT_EQ(200, info.headers->response_code());
ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());
+
+ histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
}
TEST_F(ServiceWorkerNavigationLoaderTest, NoActiveWorker) {
+ base::HistogramTester histogram_tester;
+
// Clear |version_| to make GetServiceWorkerVersion() return null.
version_ = nullptr;
@@ -641,6 +591,9 @@ TEST_F(ServiceWorkerNavigationLoaderTest, NoActiveWorker) {
client_.RunUntilComplete();
EXPECT_EQ(net::ERR_FAILED, client_.completion_status().error_code);
+
+ // No fetch event was dispatched.
+ histogram_tester.ExpectTotalCount(kHistogramMainResourceFetchEvent, 0);
}
// Test that the request body is passed to the fetch event.
@@ -829,7 +782,8 @@ TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponseAndCancel) {
EXPECT_TRUE(data_pipe.producer_handle.is_valid());
EXPECT_FALSE(loader_->WasCanceled());
EXPECT_TRUE(version_->HasWorkInBrowser());
- loader_->Cancel();
+ loader_ptr_.reset();
+ base::RunLoop().RunUntilIdle();
EXPECT_TRUE(loader_->WasCanceled());
EXPECT_FALSE(version_->HasWorkInBrowser());
@@ -850,6 +804,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponseAndCancel) {
// Test when the service worker responds with network fallback.
// i.e., does not call respondWith().
TEST_F(ServiceWorkerNavigationLoaderTest, FallbackResponse) {
+ base::HistogramTester histogram_tester;
helper_->RespondWithFallback();
// Perform the request.
@@ -859,10 +814,13 @@ TEST_F(ServiceWorkerNavigationLoaderTest, FallbackResponse) {
// The request should not be handled by the loader, but it shouldn't be a
// failure.
EXPECT_FALSE(was_main_resource_load_failed_called_);
+ histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
}
// Test when the service worker rejects the FetchEvent.
TEST_F(ServiceWorkerNavigationLoaderTest, ErrorResponse) {
+ base::HistogramTester histogram_tester;
helper_->RespondWithError();
// Perform the request.
@@ -871,16 +829,24 @@ TEST_F(ServiceWorkerNavigationLoaderTest, ErrorResponse) {
client_.RunUntilComplete();
EXPECT_EQ(net::ERR_FAILED, client_.completion_status().error_code);
+
+ // Event dispatch still succeeded.
+ histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
}
// Test when dispatching the fetch event to the service worker failed.
TEST_F(ServiceWorkerNavigationLoaderTest, FailFetchDispatch) {
+ base::HistogramTester histogram_tester;
helper_->FailToDispatchFetchEvent();
// Perform the request.
LoaderResult result = StartRequest(CreateRequest());
EXPECT_EQ(LoaderResult::kDidNotHandleRequest, result);
EXPECT_TRUE(was_main_resource_load_failed_called_);
+ histogram_tester.ExpectUniqueSample(
+ kHistogramMainResourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kErrorFailed, 1);
}
// Test when the respondWith() promise resolves before the waitUntil() promise
@@ -908,6 +874,8 @@ TEST_F(ServiceWorkerNavigationLoaderTest, EarlyResponse) {
// happens when there is no active service worker for the URL, or it must be
// skipped, etc.
TEST_F(ServiceWorkerNavigationLoaderTest, FallbackToNetwork) {
+ base::HistogramTester histogram_tester;
+
network::ResourceRequest request;
request.url = GURL("https://www.example.com/");
request.method = "GET";
@@ -926,6 +894,9 @@ TEST_F(ServiceWorkerNavigationLoaderTest, FallbackToNetwork) {
loader->FallbackToNetwork();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(handler);
+
+ // No fetch event was dispatched.
+ histogram_tester.ExpectTotalCount(kHistogramMainResourceFetchEvent, 0);
}
// Test responding to the fetch event with the navigation preload response.
@@ -956,6 +927,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, NavigationPreload) {
// Test responding to the fetch event with a redirect response.
TEST_F(ServiceWorkerNavigationLoaderTest, Redirect) {
+ base::HistogramTester histogram_tester;
GURL new_url("https://example.com/redirected");
helper_->RespondWithRedirectResponse(new_url);
@@ -972,6 +944,60 @@ TEST_F(ServiceWorkerNavigationLoaderTest, Redirect) {
EXPECT_EQ(301, redirect_info.status_code);
EXPECT_EQ("GET", redirect_info.new_method);
EXPECT_EQ(new_url, redirect_info.new_url);
+
+ histogram_tester.ExpectUniqueSample(kHistogramMainResourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
+}
+
+TEST_F(ServiceWorkerNavigationLoaderTest, LifetimeAfterForwardToServiceWorker) {
+ LoaderResult result = StartRequest(CreateRequest());
+ EXPECT_EQ(LoaderResult::kHandledRequest, result);
+ base::WeakPtr<ServiceWorkerNavigationLoader> loader = loader_->AsWeakPtr();
+ ASSERT_TRUE(loader);
+
+ client_.RunUntilComplete();
+ EXPECT_TRUE(loader);
+
+ // Even after calling DetachedFromRequest(), |loader_| should be alive until
+ // the Mojo connection to the loader is disconnected.
+ loader_.release()->DetachedFromRequest();
+ EXPECT_TRUE(loader);
+
+ // When the interface pointer to |loader_| is disconnected, its weak pointers
+ // (|loader|) are invalidated.
+ loader_ptr_.reset();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(loader);
+
+ // |loader_| is deleted here. LSan test will alert if it leaks.
+}
+
+TEST_F(ServiceWorkerNavigationLoaderTest, LifetimeAfterFallbackToNetwork) {
+ network::ResourceRequest request;
+ request.url = GURL("https://www.example.com/");
+ request.method = "GET";
+ request.fetch_request_mode = network::mojom::FetchRequestMode::kNavigate;
+ request.fetch_credentials_mode =
+ network::mojom::FetchCredentialsMode::kInclude;
+ request.fetch_redirect_mode = network::mojom::FetchRedirectMode::kManual;
+
+ SingleRequestURLLoaderFactory::RequestHandler handler;
+ auto loader = std::make_unique<ServiceWorkerNavigationLoader>(
+ base::BindOnce(&ReceiveRequestHandler, &handler), this, request,
+ base::WrapRefCounted<URLLoaderFactoryGetter>(
+ helper_->context()->loader_factory_getter()));
+ base::WeakPtr<ServiceWorkerNavigationLoader> loader_weakptr =
+ loader->AsWeakPtr();
+ // Ask the loader to fallback to network. In production code,
+ // ServiceWorkerControlleeRequestHandler calls FallbackToNetwork() to do this.
+ loader->FallbackToNetwork();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(handler);
+ EXPECT_TRUE(loader_weakptr);
+
+ // DetachedFromRequest() deletes |loader_|.
+ loader.release()->DetachedFromRequest();
+ EXPECT_FALSE(loader_weakptr);
}
} // namespace service_worker_navigation_loader_unittest
diff --git a/chromium/content/browser/service_worker/service_worker_new_script_loader.cc b/chromium/content/browser/service_worker/service_worker_new_script_loader.cc
index 99d175d307f..369f7356f0d 100644
--- a/chromium/content/browser/service_worker/service_worker_new_script_loader.cc
+++ b/chromium/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -46,6 +46,7 @@ ServiceWorkerNewScriptLoader::ServiceWorkerNewScriptLoader(
base::SequencedTaskRunnerHandle::Get()),
loader_factory_(std::move(loader_factory)),
client_(std::move(client)),
+ original_options_(options),
weak_factory_(this) {
network::ResourceRequest resource_request(original_request);
@@ -85,11 +86,24 @@ ServiceWorkerNewScriptLoader::ServiceWorkerNewScriptLoader(
incumbent_cache_resource_id =
stored_version->script_cache_map()->LookupResourceId(request_url_);
}
+ // Request SSLInfo. It will be persisted in service worker storage and
+ // may be used by ServiceWorkerNavigationLoader for navigations handled
+ // by this service worker.
+ options |= network::mojom::kURLLoadOptionSendSSLInfoWithResponse;
}
+ // Bypass the browser cache if needed, e.g., updateViaCache demands it or 24
+ // hours passed since the last update check that hit network.
+ base::TimeDelta time_since_last_check =
+ base::Time::Now() - registration->last_update_check();
if (ServiceWorkerUtils::ShouldBypassCacheDueToUpdateViaCache(
- is_main_script, registration->update_via_cache()))
+ is_main_script, registration->update_via_cache()) ||
+ time_since_last_check > kServiceWorkerScriptMaxCacheAge ||
+ version_->force_bypass_cache_for_scripts()) {
resource_request.load_flags |= net::LOAD_BYPASS_CACHE;
+ }
+
+ resource_request.headers.SetHeader("Service-Worker", "script");
// Create response readers only when we have to do the byte-for-byte check.
std::unique_ptr<ServiceWorkerResponseReader> compare_reader;
@@ -105,7 +119,6 @@ ServiceWorkerNewScriptLoader::ServiceWorkerNewScriptLoader(
version_->script_cache_map()->NotifyStartedCaching(request_url_,
cache_resource_id);
- AdvanceState(State::kStarted);
// Disable MIME sniffing. The spec requires the header list to have a
// JavaScript MIME type. Therefore, no sniffing is needed.
@@ -116,11 +129,15 @@ ServiceWorkerNewScriptLoader::ServiceWorkerNewScriptLoader(
loader_factory_->CreateLoaderAndStart(
mojo::MakeRequest(&network_loader_), routing_id, request_id, options,
resource_request, std::move(network_client), traffic_annotation);
+ DCHECK_EQ(NetworkLoaderState::kNotStarted, network_loader_state_);
+ network_loader_state_ = NetworkLoaderState::kLoadingHeader;
}
ServiceWorkerNewScriptLoader::~ServiceWorkerNewScriptLoader() = default;
void ServiceWorkerNewScriptLoader::FollowRedirect(
+ const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
// Resource requests for service worker scripts should not follow redirects.
// See comments in OnReceiveRedirect().
@@ -147,8 +164,8 @@ void ServiceWorkerNewScriptLoader::ResumeReadingBodyFromNet() {
// URLLoaderClient for network loader ------------------------------------------
void ServiceWorkerNewScriptLoader::OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) {
+ const network::ResourceResponseHead& response_head) {
+ DCHECK_EQ(NetworkLoaderState::kLoadingHeader, network_loader_state_);
if (!version_->context() || version_->is_redundant()) {
CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_FAILED),
kServiceWorkerFetchScriptError);
@@ -170,6 +187,9 @@ void ServiceWorkerNewScriptLoader::OnReceiveResponse(
// The following sequence is equivalent to
// ServiceWorkerWriteToCacheJob::OnResponseStarted.
+ // TODO(falken): Make these steps be in the same order as the spec. Right now
+ // there are slight differences, like we only bump last update check time on
+ // OK status.
if (response_head.headers->response_code() / 100 != 2) {
// Non-2XX HTTP status code is handled as an error.
@@ -221,13 +241,28 @@ void ServiceWorkerNewScriptLoader::OnReceiveResponse(
return;
}
+ if (response_head.network_accessed)
+ version_->embedded_worker()->OnNetworkAccessedForScriptLoad();
+
version_->SetMainScriptHttpResponseInfo(*response_info);
}
WriteHeaders(
base::MakeRefCounted<HttpResponseInfoIOBuffer>(response_info.release()));
- client_->OnReceiveResponse(response_head, std::move(downloaded_file));
+ // Don't pass SSLInfo to the client when the original request doesn't ask
+ // to send it.
+ if (response_head.ssl_info.has_value() &&
+ !(original_options_ &
+ network::mojom::kURLLoadOptionSendSSLInfoWithResponse)) {
+ network::ResourceResponseHead new_response_head = response_head;
+ new_response_head.ssl_info.reset();
+ client_->OnReceiveResponse(new_response_head);
+ } else {
+ client_->OnReceiveResponse(response_head);
+ }
+
+ network_loader_state_ = NetworkLoaderState::kWaitingForBody;
}
void ServiceWorkerNewScriptLoader::OnReceiveRedirect(
@@ -241,11 +276,6 @@ void ServiceWorkerNewScriptLoader::OnReceiveRedirect(
kServiceWorkerRedirectError);
}
-void ServiceWorkerNewScriptLoader::OnDataDownloaded(int64_t data_len,
- int64_t encoded_data_len) {
- client_->OnDataDownloaded(data_len, encoded_data_len);
-}
-
void ServiceWorkerNewScriptLoader::OnUploadProgress(
int64_t current_position,
int64_t total_size,
@@ -266,6 +296,7 @@ void ServiceWorkerNewScriptLoader::OnTransferSizeUpdated(
void ServiceWorkerNewScriptLoader::OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle consumer) {
+ DCHECK_EQ(NetworkLoaderState::kWaitingForBody, network_loader_state_);
// Create a pair of the consumer and producer for responding to the client.
mojo::ScopedDataPipeConsumerHandle client_consumer;
if (mojo::CreateDataPipe(nullptr, &client_producer_, &client_consumer) !=
@@ -279,61 +310,75 @@ void ServiceWorkerNewScriptLoader::OnStartLoadingResponseBody(
client_->OnStartLoadingResponseBody(std::move(client_consumer));
network_consumer_ = std::move(consumer);
+ network_loader_state_ = NetworkLoaderState::kLoadingBody;
MaybeStartNetworkConsumerHandleWatcher();
}
void ServiceWorkerNewScriptLoader::OnComplete(
const network::URLLoaderCompletionStatus& status) {
+ DCHECK(network_loader_state_ == NetworkLoaderState::kWaitingForBody ||
+ network_loader_state_ == NetworkLoaderState::kLoadingBody);
+ NetworkLoaderState previous_state = network_loader_state_;
+ network_loader_state_ = NetworkLoaderState::kCompleted;
if (status.error_code != net::OK) {
CommitCompleted(status, kServiceWorkerFetchScriptError);
return;
}
- network_load_completed_ = true;
- switch (state_) {
- case State::kNotStarted:
- case State::kCompleted:
- break;
- case State::kStarted:
- case State::kWroteHeaders:
- // CommitCompleted() will be called after the data is written in the
- // storage.
- return;
- case State::kWroteData:
- CommitCompleted(network::URLLoaderCompletionStatus(net::OK),
- std::string() /* status_message */);
- return;
+ // Response body is empty.
+ if (previous_state == NetworkLoaderState::kWaitingForBody) {
+ DCHECK_EQ(WriterState::kNotStarted, body_writer_state_);
+ body_writer_state_ = WriterState::kCompleted;
+ switch (header_writer_state_) {
+ case WriterState::kNotStarted:
+ NOTREACHED()
+ << "Response header should be received before OnComplete()";
+ break;
+ case WriterState::kWriting:
+ // Wait until it's written. OnWriteHeadersComplete() will call
+ // CommitCompleted().
+ return;
+ case WriterState::kCompleted:
+ DCHECK(!network_consumer_.is_valid());
+ CommitCompleted(network::URLLoaderCompletionStatus(net::OK),
+ std::string() /* status_message */);
+ return;
+ }
+ NOTREACHED();
}
- NOTREACHED() << static_cast<int>(state_);
-}
-
-// End of URLLoaderClient ------------------------------------------------------
-void ServiceWorkerNewScriptLoader::AdvanceState(State new_state) {
- switch (state_) {
- case State::kNotStarted:
- DCHECK_EQ(State::kStarted, new_state);
- break;
- case State::kStarted:
- DCHECK(new_state == State::kWroteHeaders ||
- new_state == State::kCompleted);
- break;
- case State::kWroteHeaders:
- DCHECK(new_state == State::kWroteData || new_state == State::kCompleted);
- break;
- case State::kWroteData:
- DCHECK_EQ(State::kCompleted, new_state);
- break;
- case State::kCompleted:
- // This is the end state.
- NOTREACHED();
- break;
+ // Response body exists.
+ if (previous_state == NetworkLoaderState::kLoadingBody) {
+ switch (body_writer_state_) {
+ case WriterState::kNotStarted:
+ // Wait until it's written. OnNetworkDataAvailable() will call
+ // CommitCompleted() after all data from |network_consumer_| is
+ // consumed.
+ DCHECK_EQ(WriterState::kWriting, header_writer_state_);
+ return;
+ case WriterState::kWriting:
+ // Wait until it's written. OnNetworkDataAvailable() will call
+ // CommitCompleted() after all data from |network_consumer_| is
+ // consumed.
+ DCHECK_EQ(WriterState::kCompleted, header_writer_state_);
+ return;
+ case WriterState::kCompleted:
+ DCHECK_EQ(WriterState::kCompleted, header_writer_state_);
+ CommitCompleted(network::URLLoaderCompletionStatus(net::OK),
+ std::string() /* status_message */);
+ return;
+ }
+ NOTREACHED();
}
- state_ = new_state;
+
+ NOTREACHED();
}
+// End of URLLoaderClient ------------------------------------------------------
void ServiceWorkerNewScriptLoader::WriteHeaders(
scoped_refptr<HttpResponseInfoIOBuffer> info_buffer) {
+ DCHECK_EQ(WriterState::kNotStarted, header_writer_state_);
+ header_writer_state_ = WriterState::kWriting;
net::Error error = cache_writer_->MaybeWriteHeaders(
info_buffer.get(),
base::BindOnce(&ServiceWorkerNewScriptLoader::OnWriteHeadersComplete,
@@ -348,28 +393,43 @@ void ServiceWorkerNewScriptLoader::WriteHeaders(
}
void ServiceWorkerNewScriptLoader::OnWriteHeadersComplete(net::Error error) {
+ DCHECK_EQ(WriterState::kWriting, header_writer_state_);
DCHECK_NE(net::ERR_IO_PENDING, error);
if (error != net::OK) {
+ ServiceWorkerMetrics::CountWriteResponseResult(
+ ServiceWorkerMetrics::WRITE_HEADERS_ERROR);
CommitCompleted(network::URLLoaderCompletionStatus(error),
kServiceWorkerFetchScriptError);
return;
}
- AdvanceState(State::kWroteHeaders);
+ header_writer_state_ = WriterState::kCompleted;
+
+ // If all other states are kCompleted the response body is empty, we can
+ // finish now.
+ if (network_loader_state_ == NetworkLoaderState::kCompleted &&
+ body_writer_state_ == WriterState::kCompleted) {
+ CommitCompleted(network::URLLoaderCompletionStatus(net::OK),
+ std::string() /* status_message */);
+ return;
+ }
+
MaybeStartNetworkConsumerHandleWatcher();
}
void ServiceWorkerNewScriptLoader::MaybeStartNetworkConsumerHandleWatcher() {
- if (!network_consumer_.is_valid()) {
- // Wait until the network consumer handle is ready to read.
- // OnStartLoadingResponseBody() will continue the sequence.
+ if (network_loader_state_ == NetworkLoaderState::kWaitingForBody) {
+ // OnStartLoadingResponseBody() or OnComplete() will continue the sequence.
return;
}
- if (state_ != State::kWroteHeaders) {
- // Wait until the headers are written in the script storage because the
- // cache writer cannot write the headers and data in parallel.
+ if (header_writer_state_ != WriterState::kCompleted) {
+ DCHECK_EQ(WriterState::kWriting, header_writer_state_);
// OnWriteHeadersComplete() will continue the sequence.
return;
}
+
+ DCHECK_EQ(WriterState::kNotStarted, body_writer_state_);
+ body_writer_state_ = WriterState::kWriting;
+
network_watcher_.Watch(
network_consumer_.get(),
MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
@@ -379,6 +439,8 @@ void ServiceWorkerNewScriptLoader::MaybeStartNetworkConsumerHandleWatcher() {
}
void ServiceWorkerNewScriptLoader::OnNetworkDataAvailable(MojoResult) {
+ DCHECK_EQ(WriterState::kCompleted, header_writer_state_);
+ DCHECK_EQ(WriterState::kWriting, body_writer_state_);
DCHECK(network_consumer_.is_valid());
scoped_refptr<network::MojoToNetPendingBuffer> pending_buffer;
uint32_t bytes_available = 0;
@@ -392,10 +454,11 @@ void ServiceWorkerNewScriptLoader::OnNetworkDataAvailable(MojoResult) {
// Closed by peer. This indicates all the data from the network service
// are read or there is an error. In the error case, the reason is
// notified via OnComplete().
- AdvanceState(State::kWroteData);
- if (network_load_completed_)
+ body_writer_state_ = WriterState::kCompleted;
+ if (network_loader_state_ == NetworkLoaderState::kCompleted) {
CommitCompleted(network::URLLoaderCompletionStatus(net::OK),
std::string() /* status_message */);
+ }
return;
case MOJO_RESULT_SHOULD_WAIT:
network_watcher_.ArmOrNotify();
@@ -419,6 +482,8 @@ void ServiceWorkerNewScriptLoader::WriteData(
case MOJO_RESULT_OK:
break;
case MOJO_RESULT_FAILED_PRECONDITION:
+ ServiceWorkerMetrics::CountWriteResponseResult(
+ ServiceWorkerMetrics::WRITE_DATA_ERROR);
CommitCompleted(network::URLLoaderCompletionStatus(net::ERR_FAILED),
kServiceWorkerFetchScriptError);
return;
@@ -457,11 +522,15 @@ void ServiceWorkerNewScriptLoader::OnWriteDataComplete(
net::Error error) {
DCHECK_NE(net::ERR_IO_PENDING, error);
if (error != net::OK) {
+ ServiceWorkerMetrics::CountWriteResponseResult(
+ ServiceWorkerMetrics::WRITE_DATA_ERROR);
CommitCompleted(network::URLLoaderCompletionStatus(error),
kServiceWorkerFetchScriptError);
return;
}
DCHECK(pending_buffer);
+ ServiceWorkerMetrics::CountWriteResponseResult(
+ ServiceWorkerMetrics::WRITE_OK);
pending_buffer->CompleteRead(bytes_written);
// Get the consumer handle from a previous read operation if we have one.
network_consumer_ = pending_buffer->ReleaseHandle();
@@ -471,15 +540,18 @@ void ServiceWorkerNewScriptLoader::OnWriteDataComplete(
void ServiceWorkerNewScriptLoader::CommitCompleted(
const network::URLLoaderCompletionStatus& status,
const std::string& status_message) {
- AdvanceState(State::kCompleted);
net::Error error_code = static_cast<net::Error>(status.error_code);
int bytes_written = -1;
if (error_code == net::OK) {
+ DCHECK_EQ(NetworkLoaderState::kCompleted, network_loader_state_);
+ DCHECK_EQ(WriterState::kCompleted, header_writer_state_);
+ DCHECK_EQ(WriterState::kCompleted, body_writer_state_);
// If all the calls to WriteHeaders/WriteData succeeded, but the incumbent
// entry wasn't actually replaced because the new entry was equivalent, the
// new version didn't actually install because it already exists.
if (!cache_writer_->did_replace()) {
- version_->SetStartWorkerStatusCode(SERVICE_WORKER_ERROR_EXISTS);
+ version_->SetStartWorkerStatusCode(
+ blink::ServiceWorkerStatusCode::kErrorExists);
error_code = ServiceWorkerWriteToCacheJob::kIdenticalScriptError;
}
bytes_written = cache_writer_->bytes_written();
@@ -494,8 +566,6 @@ void ServiceWorkerNewScriptLoader::CommitCompleted(
version_->script_cache_map()->NotifyFinishedCaching(
request_url_, bytes_written, error_code, status_message);
- // TODO(nhiroki): Record ServiceWorkerMetrics::CountWriteResponseResult().
- // (https://crbug.com/762357)
client_->OnComplete(status);
client_producer_.reset();
@@ -504,6 +574,9 @@ void ServiceWorkerNewScriptLoader::CommitCompleted(
network_consumer_.reset();
network_watcher_.Cancel();
cache_writer_.reset();
+ network_loader_state_ = NetworkLoaderState::kCompleted;
+ header_writer_state_ = WriterState::kCompleted;
+ body_writer_state_ = WriterState::kCompleted;
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_new_script_loader.h b/chromium/content/browser/service_worker/service_worker_new_script_loader.h
index c26100f4ca9..d9d94245903 100644
--- a/chromium/content/browser/service_worker/service_worker_new_script_loader.h
+++ b/chromium/content/browser/service_worker/service_worker_new_script_loader.h
@@ -27,7 +27,7 @@ struct HttpResponseInfoIOBuffer;
// network, and returns the response to |client|, while also writing the
// response into the service worker script storage.
//
-// This works as follows:
+// In the common case, this works as follows:
// 1. Makes a network request.
// 2. OnReceiveResponse() is called, writes the response headers to the
// service worker script storage and responds with them to the |client|
@@ -38,6 +38,14 @@ struct HttpResponseInfoIOBuffer;
// 4. OnComplete() for the network load and OnWriteDataComplete() are called,
// calls CommitCompleted() and closes the connections with the network
// service and the renderer process.
+// In an uncommon case, the response body is empty so
+// OnStartLoadingResponseBody() is not called.
+//
+// A set of |network_loader_state_|, |header_writer_state_|, and
+// |body_writer_state_| is the state of this loader. Each of them is changed
+// independently, while some state changes have dependency to other state
+// changes. See the comment for each field below to see exactly when their
+// state changes happen.
//
// In case there is already an installed service worker for this registration,
// this class also performs the "byte-for-byte" comparison for updating the
@@ -67,7 +75,9 @@ class CONTENT_EXPORT ServiceWorkerNewScriptLoader
~ServiceWorkerNewScriptLoader() override;
// network::mojom::URLLoader:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
@@ -77,12 +87,10 @@ class CONTENT_EXPORT ServiceWorkerNewScriptLoader
// network::mojom::URLLoaderClient for the network load:
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override;
+ const network::ResourceResponseHead& response_head) override;
void OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const network::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;
@@ -96,14 +104,15 @@ class CONTENT_EXPORT ServiceWorkerNewScriptLoader
const static uint32_t kReadBufferSize;
private:
- enum class State {
+ enum class NetworkLoaderState {
kNotStarted,
- kStarted,
- kWroteHeaders,
- kWroteData,
+ kLoadingHeader,
+ kWaitingForBody,
+ kLoadingBody,
kCompleted,
};
- void AdvanceState(State new_state);
+
+ enum class WriterState { kNotStarted, kWriting, kCompleted };
// Writes the given headers into the service worker script storage.
void WriteHeaders(scoped_refptr<HttpResponseInfoIOBuffer> info_buffer);
@@ -146,14 +155,50 @@ class CONTENT_EXPORT ServiceWorkerNewScriptLoader
mojo::Binding<network::mojom::URLLoaderClient> network_client_binding_;
mojo::ScopedDataPipeConsumerHandle network_consumer_;
mojo::SimpleWatcher network_watcher_;
- bool network_load_completed_ = false;
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
// Used for responding with the fetched script to this loader's client.
network::mojom::URLLoaderClientPtr client_;
mojo::ScopedDataPipeProducerHandle client_producer_;
- State state_ = State::kNotStarted;
+ // Represents the state of |network_loader_|.
+ // Corresponds to the steps described in the class comments.
+ //
+ // When response body exists:
+ // CreateLoaderAndStart(): kNotStarted -> kLoadingHeader
+ // OnReceiveResponse(): kLoadingHeader -> kWaitingForBody
+ // OnStartLoadingResponseBody(): kWaitingForBody -> kLoadingBody
+ // OnComplete(): kLoadingBody -> kCompleted
+ //
+ // When response body is empty:
+ // CreateLoaderAndStart(): kNotStarted -> kLoadingHeader
+ // OnReceiveResponse(): kLoadingHeader -> kWaitingForBody
+ // OnComplete(): kWaitingForBody -> kCompleted
+ NetworkLoaderState network_loader_state_ = NetworkLoaderState::kNotStarted;
+
+ // Represents the state of |cache_writer_|.
+ // Set to kWriting when it starts to write the header, and set to kCompleted
+ // when the header has been written.
+ //
+ // OnReceiveResponse(): kNotStarted -> kWriting (in WriteHeaders())
+ // OnWriteHeadersComplete(): kWriting -> kCompleted
+ WriterState header_writer_state_ = WriterState::kNotStarted;
+
+ // Represents the state of |cache_writer_| and |network_consumer_|.
+ // Set to kWriting when |this| starts watching |network_consumer_|, and set to
+ // kCompleted when all data has been written to |cache_writer_|.
+ //
+ // When response body exists:
+ // OnStartLoadingResponseBody() && OnWriteHeadersComplete():
+ // kNotStarted -> kWriting
+ // OnNetworkDataAvailable() && MOJO_RESULT_FAILED_PRECONDITION:
+ // kWriting -> kCompleted
+ //
+ // When response body is empty:
+ // OnComplete(): kNotStarted -> kCompleted
+ WriterState body_writer_state_ = WriterState::kNotStarted;
+
+ const uint32_t original_options_;
base::WeakPtrFactory<ServiceWorkerNewScriptLoader> weak_factory_;
diff --git a/chromium/content/browser/service_worker/service_worker_new_script_loader_unittest.cc b/chromium/content/browser/service_worker/service_worker_new_script_loader_unittest.cc
index 100e0c71be4..7494702698a 100644
--- a/chromium/content/browser/service_worker/service_worker_new_script_loader_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_new_script_loader_unittest.cc
@@ -5,9 +5,12 @@
#include "content/browser/service_worker/service_worker_new_script_loader.h"
#include <map>
+#include <memory>
+#include <string>
#include <utility>
#include "base/run_loop.h"
#include "base/strings/string_util.h"
+#include "base/test/metrics/histogram_tester.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
@@ -15,6 +18,7 @@
#include "content/public/test/test_browser_thread_bundle.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/data_pipe_utils.h"
+#include "net/base/load_flags.h"
#include "net/base/test_completion_callback.h"
#include "net/http/http_util.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
@@ -26,10 +30,13 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
namespace content {
-
-namespace {
+namespace service_worker_new_script_loader_unittest {
const char kNormalScriptURL[] = "https://example.com/normal.js";
+const char kNormalImportedScriptURL[] =
+ "https://my-awesome-cdn.com/import_script.js";
+const char kHistogramWriteResponseResult[] =
+ "ServiceWorker.DiskCache.WriteResponseResult";
// MockHTTPServer is a utility to provide mocked responses for
// ServiceWorkerNewScriptLoader.
@@ -60,11 +67,6 @@ class MockHTTPServer {
};
// A URLLoaderFactory that returns a mocked response provided by MockHTTPServer.
-//
-// TODO(nhiroki): We copied this from
-// service_worker_navigation_loader_unittest.cc instead of making it a common
-// test helper because we might want to customize the mock factory to add more
-// tests later. Merge this and that if we're convinced it's better.
class MockNetworkURLLoaderFactory final
: public network::mojom::URLLoaderFactory {
public:
@@ -80,6 +82,7 @@ class MockNetworkURLLoaderFactory final
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag&
traffic_annotation) override {
+ last_request_ = url_request;
const MockHTTPServer::Response& response =
mock_server_->Get(url_request.url);
@@ -91,6 +94,7 @@ class MockNetworkURLLoaderFactory final
network::ResourceResponseHead response_head;
response_head.headers = info.headers;
response_head.headers->GetMimeType(&response_head.mime_type);
+ response_head.network_accessed = access_network_;
if (response.has_certificate_error) {
response_head.cert_status = net::CERT_STATUS_DATE_INVALID;
}
@@ -99,34 +103,46 @@ class MockNetworkURLLoaderFactory final
client->OnReceiveRedirect(net::RedirectInfo(), response_head);
return;
}
- client->OnReceiveResponse(response_head, nullptr /* downloaded_file */);
+ client->OnReceiveResponse(response_head);
// Pass the response body to the client.
- uint32_t bytes_written = response.body.size();
- mojo::DataPipe data_pipe;
- MojoResult result = data_pipe.producer_handle->WriteData(
- response.body.data(), &bytes_written, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
- ASSERT_EQ(MOJO_RESULT_OK, result);
- client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
-
+ if (!response.body.empty()) {
+ uint32_t bytes_written = response.body.size();
+ mojo::DataPipe data_pipe;
+ MojoResult result = data_pipe.producer_handle->WriteData(
+ response.body.data(), &bytes_written,
+ MOJO_WRITE_DATA_FLAG_ALL_OR_NONE);
+ ASSERT_EQ(MOJO_RESULT_OK, result);
+ client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle));
+ }
network::URLLoaderCompletionStatus status;
status.error_code = net::OK;
client->OnComplete(status);
}
+ void set_to_access_network(bool access_network) {
+ access_network_ = access_network;
+ }
+
+ network::ResourceRequest last_request() const { return last_request_; }
+
void Clone(network::mojom::URLLoaderFactoryRequest factory) override {
NOTREACHED();
}
private:
- // This is owned by ServiceWorkerNewScriptLoaderTest.
+ // |mock_server_| is owned by ServiceWorkerNewScriptLoaderTest.
MockHTTPServer* mock_server_;
+ // The most recent request received by this factory.
+ network::ResourceRequest last_request_;
+
+ // Controls whether a load simulates accessing network or cache.
+ bool access_network_ = false;
+
DISALLOW_COPY_AND_ASSIGN(MockNetworkURLLoaderFactory);
};
-} // namespace
-
// ServiceWorkerNewScriptLoaderTest is for testing the handling of requests for
// installing service worker scripts via ServiceWorkerNewScriptLoader.
class ServiceWorkerNewScriptLoaderTest : public testing::Test {
@@ -139,8 +155,7 @@ class ServiceWorkerNewScriptLoaderTest : public testing::Test {
ServiceWorkerContextCore* context() { return helper_->context(); }
void SetUp() override {
- helper_ = std::make_unique<EmbeddedWorkerTestHelper>(
- base::FilePath(), base::MakeRefCounted<URLLoaderFactoryGetter>());
+ helper_ = std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath());
InitializeStorage();
@@ -149,13 +164,19 @@ class ServiceWorkerNewScriptLoaderTest : public testing::Test {
std::string("HTTP/1.1 200 OK\n"
"Content-Type: text/javascript\n\n"),
std::string("this body came from the network")));
+ mock_server_->Set(
+ GURL(kNormalImportedScriptURL),
+ MockHTTPServer::Response(
+ std::string("HTTP/1.1 200 OK\n"
+ "Content-Type: text/javascript\n\n"),
+ std::string(
+ "this is an import script response body from the network")));
// Initialize URLLoaderFactory.
network::mojom::URLLoaderFactoryPtr test_loader_factory;
mock_url_loader_factory_ =
std::make_unique<MockNetworkURLLoaderFactory>(mock_server_.get());
- helper_->url_loader_factory_getter()->SetNetworkFactoryForTesting(
- mock_url_loader_factory_.get());
+ helper_->SetNetworkFactory(mock_url_loader_factory_.get());
}
void InitializeStorage() {
@@ -166,48 +187,47 @@ class ServiceWorkerNewScriptLoaderTest : public testing::Test {
// Sets up ServiceWorkerRegistration and ServiceWorkerVersion. This should be
// called before DoRequest().
- void SetUpRegistration(const GURL& script_url, const GURL& scope) {
+ void SetUpRegistration(const GURL& script_url) {
blink::mojom::ServiceWorkerRegistrationOptions options;
- options.scope = scope;
+ options.scope = script_url.GetWithoutFilename();
+ SetUpRegistrationWithOptions(script_url, options);
+ }
+ void SetUpRegistrationWithOptions(
+ const GURL& script_url,
+ blink::mojom::ServiceWorkerRegistrationOptions options) {
registration_ = base::MakeRefCounted<ServiceWorkerRegistration>(
options, context()->storage()->NewRegistrationId(),
context()->AsWeakPtr());
- version_ = base::MakeRefCounted<ServiceWorkerVersion>(
- registration_.get(), script_url, context()->storage()->NewVersionId(),
- helper_->context()->AsWeakPtr());
- version_->SetStatus(ServiceWorkerVersion::NEW);
- }
-
- // Sets up ServiceWorkerRegistration and ServiceWorkerVersion with the default
- // scope.
- void SetUpRegistration(const GURL& script_url) {
- SetUpRegistration(script_url, script_url.GetWithoutFilename());
+ SetUpVersion(script_url);
}
- // Creates an active worker in |registration_|. After this is called,
- // |version_| will be a new, uninstalled version. The next time DoRequest() is
- // called, |version_| will attempt to update, comparing against the active
- // worker.
- void SetUpActivatedWorker(const GURL& script_url) {
- DoRequest(script_url);
- client_->RunUntilComplete();
- EXPECT_EQ(net::OK, client_->completion_status().error_code);
- loader_.reset();
- client_.reset();
-
+ // Promotes |version_| to |registration_|'s active version, and then resets
+ // |version_| to null (as subsequent DoRequest() calls should not attempt to
+ // install or update |version_|).
+ void ActivateVersion() {
version_->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST);
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
registration_->SetActiveVersion(version_);
+ version_ = nullptr;
+ }
+ // After this is called, |version_| will be a new, uninstalled version. The
+ // next time DoRequest() is called, |version_| will attempt to install,
+ // possibly updating if registration has an installed worker.
+ void SetUpVersion(const GURL& script_url) {
version_ = base::MakeRefCounted<ServiceWorkerVersion>(
registration_.get(), script_url, context()->storage()->NewVersionId(),
context()->AsWeakPtr());
version_->SetStatus(ServiceWorkerVersion::NEW);
- version_->set_pause_after_download(true);
+
+ if (registration_->waiting_version() || registration_->active_version())
+ version_->SetToPauseAfterDownload(base::DoNothing());
}
- void DoRequest(const GURL& request_url) {
+ void DoRequest(const GURL& url,
+ std::unique_ptr<network::TestURLLoaderClient>* out_client,
+ std::unique_ptr<ServiceWorkerNewScriptLoader>* out_loader) {
DCHECK(registration_);
DCHECK(version_);
@@ -217,17 +237,17 @@ class ServiceWorkerNewScriptLoaderTest : public testing::Test {
uint32_t options = 0;
network::ResourceRequest request;
- request.url = version_->script_url();
+ request.url = url;
request.method = "GET";
- // TODO(nhiroki): Test importScripts() cases.
- request.resource_type = RESOURCE_TYPE_SERVICE_WORKER;
-
- DCHECK(!loader_);
- DCHECK(!client_);
- client_ = std::make_unique<network::TestURLLoaderClient>();
- loader_ = std::make_unique<ServiceWorkerNewScriptLoader>(
- routing_id, request_id, options, request, client_->CreateInterfacePtr(),
- version_, helper_->url_loader_factory_getter()->GetNetworkFactory(),
+ request.resource_type = (url == version_->script_url())
+ ? RESOURCE_TYPE_SERVICE_WORKER
+ : RESOURCE_TYPE_SCRIPT;
+
+ *out_client = std::make_unique<network::TestURLLoaderClient>();
+ *out_loader = std::make_unique<ServiceWorkerNewScriptLoader>(
+ routing_id, request_id, options, request,
+ (*out_client)->CreateInterfacePtr(), version_,
+ helper_->url_loader_factory_getter()->GetNetworkFactory(),
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
}
@@ -284,56 +304,67 @@ class ServiceWorkerNewScriptLoaderTest : public testing::Test {
scoped_refptr<ServiceWorkerRegistration> registration_;
scoped_refptr<ServiceWorkerVersion> version_;
- std::unique_ptr<ServiceWorkerNewScriptLoader> loader_;
std::unique_ptr<MockHTTPServer> mock_server_;
-
- std::unique_ptr<network::TestURLLoaderClient> client_;
};
TEST_F(ServiceWorkerNewScriptLoaderTest, Success) {
+ base::HistogramTester histogram_tester;
+
const GURL kScriptURL(kNormalScriptURL);
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
SetUpRegistration(kScriptURL);
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
- EXPECT_EQ(net::OK, client_->completion_status().error_code);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
// The client should have received the response.
- EXPECT_TRUE(client_->has_received_response());
- EXPECT_TRUE(client_->response_body().is_valid());
+ EXPECT_TRUE(client->has_received_response());
+ EXPECT_TRUE(client->response_body().is_valid());
std::string response;
EXPECT_TRUE(
- mojo::BlockingCopyToString(client_->response_body_release(), &response));
+ mojo::BlockingCopyToString(client->response_body_release(), &response));
EXPECT_EQ(mock_server_->Get(kScriptURL).body, response);
// The response should also be stored in the storage.
EXPECT_TRUE(VerifyStoredResponse(kScriptURL));
+ histogram_tester.ExpectUniqueSample(kHistogramWriteResponseResult,
+ ServiceWorkerMetrics::WRITE_OK, 1);
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Success_EmptyBody) {
+ base::HistogramTester histogram_tester;
+
const GURL kScriptURL("https://example.com/empty.js");
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
mock_server_->Set(
kScriptURL,
MockHTTPServer::Response(std::string("HTTP/1.1 200 OK\n"
"Content-Type: text/javascript\n\n"),
std::string()));
SetUpRegistration(kScriptURL);
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
- EXPECT_EQ(net::OK, client_->completion_status().error_code);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
// The client should have received the response.
- EXPECT_TRUE(client_->has_received_response());
- EXPECT_TRUE(client_->response_body().is_valid());
- std::string response;
- EXPECT_TRUE(
- mojo::BlockingCopyToString(client_->response_body_release(), &response));
- EXPECT_TRUE(response.empty());
+ EXPECT_TRUE(client->has_received_response());
+ EXPECT_FALSE(client->response_body().is_valid());
// The response should also be stored in the storage.
EXPECT_TRUE(VerifyStoredResponse(kScriptURL));
+ // We don't record write response result if body is empty.
+ histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0);
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Success_LargeBody) {
+ base::HistogramTester histogram_tester;
+
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
// Create a response that has a larger body than the script loader's buffer
// to test chunked data write. We chose this multiplier to avoid hitting the
// limit of mojo's data pipe buffer (it's about kReadBufferSize * 2 as of
@@ -347,58 +378,80 @@ TEST_F(ServiceWorkerNewScriptLoaderTest, Success_LargeBody) {
"Content-Type: text/javascript\n\n"),
std::string(kBodySize, 'a')));
SetUpRegistration(kScriptURL);
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
- EXPECT_EQ(net::OK, client_->completion_status().error_code);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
// The client should have received the response.
- EXPECT_TRUE(client_->has_received_response());
- EXPECT_TRUE(client_->response_body().is_valid());
+ EXPECT_TRUE(client->has_received_response());
+ EXPECT_TRUE(client->response_body().is_valid());
std::string response;
EXPECT_TRUE(
- mojo::BlockingCopyToString(client_->response_body_release(), &response));
+ mojo::BlockingCopyToString(client->response_body_release(), &response));
EXPECT_EQ(mock_server_->Get(kScriptURL).body, response);
// The response should also be stored in the storage.
EXPECT_TRUE(VerifyStoredResponse(kScriptURL));
+ // WRITE_OK should be recorded twice as we record every single write success.
+ histogram_tester.ExpectUniqueSample(kHistogramWriteResponseResult,
+ ServiceWorkerMetrics::WRITE_OK, 2);
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Error_404) {
+ base::HistogramTester histogram_tester;
+
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
const GURL kScriptURL("https://example.com/nonexistent.js");
mock_server_->Set(kScriptURL, MockHTTPServer::Response(
std::string("HTTP/1.1 404 Not Found\n\n"),
std::string()));
SetUpRegistration(kScriptURL);
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
// The request should be failed because of the 404 response.
- EXPECT_EQ(net::ERR_INVALID_RESPONSE, client_->completion_status().error_code);
- EXPECT_FALSE(client_->has_received_response());
+ EXPECT_EQ(net::ERR_INVALID_RESPONSE, client->completion_status().error_code);
+ EXPECT_FALSE(client->has_received_response());
// The response shouldn't be stored in the storage.
EXPECT_FALSE(VerifyStoredResponse(kScriptURL));
+ // No sample should be recorded since a write didn't occur.
+ histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0);
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Error_Redirect) {
+ base::HistogramTester histogram_tester;
+
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
const GURL kScriptURL("https://example.com/redirect.js");
mock_server_->Set(
kScriptURL,
MockHTTPServer::Response(
std::string("HTTP/1.1 307 Temporary Redirect\n\n"), std::string()));
SetUpRegistration(kScriptURL);
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
// The request should be failed because of the redirected response.
- EXPECT_EQ(net::ERR_UNSAFE_REDIRECT, client_->completion_status().error_code);
- EXPECT_FALSE(client_->has_received_response());
+ EXPECT_EQ(net::ERR_UNSAFE_REDIRECT, client->completion_status().error_code);
+ EXPECT_FALSE(client->has_received_response());
// The response shouldn't be stored in the storage.
EXPECT_FALSE(VerifyStoredResponse(kScriptURL));
+ // No sample should be recorded since a write didn't occur.
+ histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0);
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Error_CertificateError) {
+ base::HistogramTester histogram_tester;
+
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
// Serve a response with a certificate error.
const GURL kScriptURL("https://example.com/certificate-error.js");
MockHTTPServer::Response response(std::string("HTTP/1.1 200 OK\n\n"),
@@ -406,58 +459,76 @@ TEST_F(ServiceWorkerNewScriptLoaderTest, Error_CertificateError) {
response.has_certificate_error = true;
mock_server_->Set(kScriptURL, response);
SetUpRegistration(kScriptURL);
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
// The request should be failed because of the response with the certificate
// error.
- EXPECT_EQ(net::ERR_CERT_DATE_INVALID,
- client_->completion_status().error_code);
- EXPECT_FALSE(client_->has_received_response());
+ 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.
EXPECT_FALSE(VerifyStoredResponse(kScriptURL));
+ // No sample should be recorded since a write didn't occur.
+ histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0);
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Error_NoMimeType) {
+ base::HistogramTester histogram_tester;
+
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
const GURL kScriptURL("https://example.com/no-mime-type.js");
mock_server_->Set(kScriptURL, MockHTTPServer::Response(
std::string("HTTP/1.1 200 OK\n\n"),
std::string("body with no MIME type")));
SetUpRegistration(kScriptURL);
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
// The request should be failed because of the response with no MIME type.
- EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
- client_->completion_status().error_code);
- EXPECT_FALSE(client_->has_received_response());
+ EXPECT_EQ(net::ERR_INSECURE_RESPONSE, client->completion_status().error_code);
+ EXPECT_FALSE(client->has_received_response());
// The response shouldn't be stored in the storage.
EXPECT_FALSE(VerifyStoredResponse(kScriptURL));
+ // No sample should be recorded since a write didn't occur.
+ histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0);
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Error_BadMimeType) {
+ base::HistogramTester histogram_tester;
+
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
const GURL kScriptURL("https://example.com/bad-mime-type.js");
mock_server_->Set(kScriptURL, MockHTTPServer::Response(
std::string("HTTP/1.1 200 OK\n"
"Content-Type: text/css\n\n"),
std::string("body with bad MIME type")));
SetUpRegistration(kScriptURL);
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
// The request should be failed because of the response with the bad MIME
// type.
- EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
- client_->completion_status().error_code);
- EXPECT_FALSE(client_->has_received_response());
+ EXPECT_EQ(net::ERR_INSECURE_RESPONSE, client->completion_status().error_code);
+ EXPECT_FALSE(client->has_received_response());
// The response shouldn't be stored in the storage.
EXPECT_FALSE(VerifyStoredResponse(kScriptURL));
+ // No sample should be recorded since a write didn't occur.
+ histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0);
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Success_PathRestriction) {
+ base::HistogramTester histogram_tester;
+
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
// |kScope| is not under the default scope ("/out-of-scope/"), but the
// Service-Worker-Allowed header allows it.
const GURL kScriptURL("https://example.com/out-of-scope/normal.js");
@@ -467,25 +538,34 @@ TEST_F(ServiceWorkerNewScriptLoaderTest, Success_PathRestriction) {
std::string("HTTP/1.1 200 OK\n"
"Content-Type: text/javascript\n"
"Service-Worker-Allowed: /in-scope/\n\n"),
- std::string()));
- SetUpRegistration(kScriptURL, kScope);
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
- EXPECT_EQ(net::OK, client_->completion_status().error_code);
+ std::string("٩( ’ω’ )و I'm body!")));
+ blink::mojom::ServiceWorkerRegistrationOptions options;
+ options.scope = kScope;
+ SetUpRegistrationWithOptions(kScriptURL, options);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
// The client should have received the response.
- EXPECT_TRUE(client_->has_received_response());
- EXPECT_TRUE(client_->response_body().is_valid());
+ EXPECT_TRUE(client->has_received_response());
+ EXPECT_TRUE(client->response_body().is_valid());
std::string response;
EXPECT_TRUE(
- mojo::BlockingCopyToString(client_->response_body_release(), &response));
+ mojo::BlockingCopyToString(client->response_body_release(), &response));
EXPECT_EQ(mock_server_->Get(kScriptURL).body, response);
// The response should also be stored in the storage.
EXPECT_TRUE(VerifyStoredResponse(kScriptURL));
+ histogram_tester.ExpectUniqueSample(kHistogramWriteResponseResult,
+ ServiceWorkerMetrics::WRITE_OK, 1);
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Error_PathRestriction) {
+ base::HistogramTester histogram_tester;
+
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
// |kScope| is not under the default scope ("/out-of-scope/") and the
// Service-Worker-Allowed header is not specified.
const GURL kScriptURL("https://example.com/out-of-scope/normal.js");
@@ -495,43 +575,59 @@ TEST_F(ServiceWorkerNewScriptLoaderTest, Error_PathRestriction) {
MockHTTPServer::Response(std::string("HTTP/1.1 200 OK\n"
"Content-Type: text/javascript\n\n"),
std::string()));
- SetUpRegistration(kScriptURL, kScope);
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
+ blink::mojom::ServiceWorkerRegistrationOptions options;
+ options.scope = kScope;
+ SetUpRegistrationWithOptions(kScriptURL, options);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
// The request should be failed because the scope is not allowed.
- EXPECT_EQ(net::ERR_INSECURE_RESPONSE,
- client_->completion_status().error_code);
- EXPECT_FALSE(client_->has_received_response());
+ EXPECT_EQ(net::ERR_INSECURE_RESPONSE, client->completion_status().error_code);
+ EXPECT_FALSE(client->has_received_response());
// The response shouldn't be stored in the storage.
EXPECT_FALSE(VerifyStoredResponse(kScriptURL));
+ // No sample should be recorded since a write didn't occur.
+ histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0);
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Error_RedundantWorker) {
+ base::HistogramTester histogram_tester;
+
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
const GURL kScriptURL(kNormalScriptURL);
SetUpRegistration(kScriptURL);
- DoRequest(kScriptURL);
+ DoRequest(kScriptURL, &client, &loader);
// Make the service worker redundant.
version_->Doom();
ASSERT_TRUE(version_->is_redundant());
- client_->RunUntilComplete();
+ client->RunUntilComplete();
// The request should be aborted.
- EXPECT_EQ(net::ERR_FAILED, client_->completion_status().error_code);
- EXPECT_FALSE(client_->has_received_response());
+ EXPECT_EQ(net::ERR_FAILED, client->completion_status().error_code);
+ EXPECT_FALSE(client->has_received_response());
// The response shouldn't be stored in the storage.
EXPECT_FALSE(VerifyStoredResponse(kScriptURL));
+ // No sample should be recorded since a write didn't occur.
+ histogram_tester.ExpectTotalCount(kHistogramWriteResponseResult, 0);
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Update) {
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
// Set up a registration with an incumbent.
const GURL kScriptURL(kNormalScriptURL);
SetUpRegistration(kScriptURL);
- SetUpActivatedWorker(kScriptURL);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+ ActivateVersion();
// Change the script on the server.
mock_server_->Set(
@@ -541,26 +637,268 @@ TEST_F(ServiceWorkerNewScriptLoaderTest, Update) {
std::string("this is the updated body")));
// Attempt to update.
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
- EXPECT_EQ(net::OK, client_->completion_status().error_code);
+ SetUpVersion(kScriptURL);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
// |version_| should have installed.
EXPECT_EQ(1UL, version_->script_cache_map()->size());
}
TEST_F(ServiceWorkerNewScriptLoaderTest, Update_IdenticalScript) {
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
// Set up a registration with an incumbent.
const GURL kScriptURL(kNormalScriptURL);
SetUpRegistration(kScriptURL);
- SetUpActivatedWorker(kScriptURL);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+ ActivateVersion();
// Attempt to update.
- DoRequest(kScriptURL);
- client_->RunUntilComplete();
- EXPECT_EQ(net::OK, client_->completion_status().error_code);
+ SetUpVersion(kScriptURL);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
// The byte-to-byte check should detect the identical script, so the
// |version_| should not have installed.
EXPECT_EQ(0UL, version_->script_cache_map()->size());
}
+// Tests cache bypassing behavior when updateViaCache is 'all'.
+TEST_F(ServiceWorkerNewScriptLoaderTest, UpdateViaCache_All) {
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+ const GURL kScriptURL(kNormalScriptURL);
+ const GURL kImportedScriptURL(kNormalImportedScriptURL);
+
+ // Set up a registration.
+ blink::mojom::ServiceWorkerRegistrationOptions options;
+ options.scope = kScriptURL.GetWithoutFilename();
+ options.update_via_cache = blink::mojom::ServiceWorkerUpdateViaCache::kAll;
+ SetUpRegistrationWithOptions(kScriptURL, options);
+
+ // Install the main script and imported script. The cache should be bypassed
+ // since last update time is null.
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ network::ResourceRequest request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ DoRequest(kImportedScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ // Promote to active and prepare to update.
+ ActivateVersion();
+ registration_->set_last_update_check(base::Time::Now());
+
+ // Attempt to update. The requests should not bypass cache since the last
+ // update was recent.
+ SetUpVersion(kScriptURL);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_FALSE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ DoRequest(kImportedScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_FALSE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ // Set update check to far in the past and repeat. The requests should bypass
+ // cache.
+ registration_->set_last_update_check(base::Time::Now() -
+ base::TimeDelta::FromHours(24));
+
+ SetUpVersion(kScriptURL);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ DoRequest(kImportedScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+}
+
+// Tests cache bypassing behavior when updateViaCache is 'imports'.
+TEST_F(ServiceWorkerNewScriptLoaderTest, UpdateViaCache_Imports) {
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+ const GURL kScriptURL(kNormalScriptURL);
+ const GURL kImportedScriptURL(kNormalImportedScriptURL);
+
+ // Set up a registration.
+ blink::mojom::ServiceWorkerRegistrationOptions options;
+ options.scope = kScriptURL.GetWithoutFilename();
+ options.update_via_cache =
+ blink::mojom::ServiceWorkerUpdateViaCache::kImports;
+ SetUpRegistrationWithOptions(kScriptURL, options);
+
+ // Install the main script and imported script. The cache should be bypassed
+ // since last update time is null.
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ network::ResourceRequest request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ DoRequest(kImportedScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ // Promote to active and prepare to update.
+ ActivateVersion();
+ registration_->set_last_update_check(base::Time::Now());
+
+ // Attempt to update. Only the imported script should bypass cache because
+ // kImports.
+ SetUpVersion(kScriptURL);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ DoRequest(kImportedScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_FALSE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ // Set the time to far in the past and repeat. The requests should bypass
+ // cache.
+ registration_->set_last_update_check(base::Time::Now() -
+ base::TimeDelta::FromHours(24));
+
+ SetUpVersion(kScriptURL);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ DoRequest(kImportedScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+}
+
+// Tests cache bypassing behavior when updateViaCache is 'none'.
+TEST_F(ServiceWorkerNewScriptLoaderTest, UpdateViaCache_None) {
+ const GURL kScriptURL(kNormalScriptURL);
+ const GURL kImportedScriptURL(kNormalImportedScriptURL);
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
+ // Set up a registration.
+ blink::mojom::ServiceWorkerRegistrationOptions options;
+ options.scope = kScriptURL.GetWithoutFilename();
+ options.update_via_cache = blink::mojom::ServiceWorkerUpdateViaCache::kNone;
+ SetUpRegistrationWithOptions(kScriptURL, options);
+
+ // Install the main script and imported script. The cache should be bypassed
+ // since kNone (and the last update time is null anyway).
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ network::ResourceRequest request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ DoRequest(kImportedScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ // Promote to active and prepare to update.
+ ActivateVersion();
+ registration_->set_last_update_check(base::Time::Now());
+
+ // Attempt to update. The requests should bypass cache because KNone.
+ SetUpVersion(kScriptURL);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ DoRequest(kImportedScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+}
+
+// Tests respecting ServiceWorkerVersion's |force_bypass_cache_for_scripts|
+// flag.
+TEST_F(ServiceWorkerNewScriptLoaderTest, ForceBypassCache) {
+ const GURL kScriptURL(kNormalScriptURL);
+ const GURL kImportedScriptURL(kNormalImportedScriptURL);
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
+ // Set up a registration.
+ blink::mojom::ServiceWorkerRegistrationOptions options;
+ options.scope = kScriptURL.GetWithoutFilename();
+ // Use kAll to contradict |force_bypass_cache_for_scripts|. The force flag
+ // should win.
+ options.update_via_cache = blink::mojom::ServiceWorkerUpdateViaCache::kAll;
+ SetUpRegistrationWithOptions(kScriptURL, options);
+ // Also set last_update_time to a recent time, so the 24 hour bypass doesn't
+ // kick in.
+ registration_->set_last_update_check(base::Time::Now());
+
+ version_->set_force_bypass_cache_for_scripts(true);
+
+ // Install the main script and imported script. The cache should be bypassed.
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ network::ResourceRequest request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+
+ DoRequest(kImportedScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ request = mock_url_loader_factory_->last_request();
+ EXPECT_TRUE(request.load_flags & net::LOAD_BYPASS_CACHE);
+}
+
+// Tests that EmbeddedWorkerInstance's |network_accessed_for_script_| flag is
+// set when the script loader accesses network. This flag is used to enforce the
+// 24 hour cache bypass.
+TEST_F(ServiceWorkerNewScriptLoaderTest, AccessedNetwork) {
+ const GURL kScriptURL(kNormalScriptURL);
+ const GURL kImportedScriptURL(kNormalImportedScriptURL);
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ std::unique_ptr<ServiceWorkerNewScriptLoader> loader;
+
+ SetUpRegistration(kScriptURL);
+
+ // Install the main script. The network accessed flag should be flipped on.
+ version_->embedded_worker()->network_accessed_for_script_ = false;
+ mock_url_loader_factory_->set_to_access_network(true);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+ EXPECT_TRUE(version_->embedded_worker()->network_accessed_for_script());
+
+ // Install the imported script. The network accessed flag should be unchanged,
+ // as it's only meant for main scripts.
+ version_->embedded_worker()->network_accessed_for_script_ = false;
+ mock_url_loader_factory_->set_to_access_network(true);
+ DoRequest(kImportedScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+ EXPECT_FALSE(version_->embedded_worker()->network_accessed_for_script());
+
+ // Install a new main script, this time simulating coming from cache. The
+ // network accessed flag should be off.
+ SetUpRegistration(kScriptURL);
+ version_->embedded_worker()->network_accessed_for_script_ = false;
+ mock_url_loader_factory_->set_to_access_network(false);
+ DoRequest(kScriptURL, &client, &loader);
+ client->RunUntilComplete();
+ EXPECT_EQ(net::OK, client->completion_status().error_code);
+ EXPECT_FALSE(version_->embedded_worker()->network_accessed_for_script());
+}
+
+} // namespace service_worker_new_script_loader_unittest
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_handle.cc b/chromium/content/browser/service_worker/service_worker_object_host.cc
index 777cea9149d..49b037866c3 100644
--- a/chromium/content/browser/service_worker/service_worker_handle.cc
+++ b/chromium/content/browser/service_worker/service_worker_object_host.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/service_worker/service_worker_handle.h"
+#include "content/browser/service_worker/service_worker_object_host.h"
#include "content/browser/service_worker/service_worker_client_utils.h"
#include "content/browser/service_worker/service_worker_context_core.h"
@@ -18,7 +18,7 @@ namespace content {
namespace {
-using StatusCallback = base::OnceCallback<void(ServiceWorkerStatusCode)>;
+using StatusCallback = base::OnceCallback<void(blink::ServiceWorkerStatusCode)>;
using SetExtendableMessageEventSourceCallback =
base::OnceCallback<bool(mojom::ExtendableMessageEventPtr*)>;
@@ -29,8 +29,8 @@ void DispatchExtendableMessageEventAfterStartWorker(
const base::Optional<base::TimeDelta>& timeout,
StatusCallback callback,
SetExtendableMessageEventSourceCallback set_source_callback,
- ServiceWorkerStatusCode start_worker_status) {
- if (start_worker_status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode start_worker_status) {
+ if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(start_worker_status);
return;
}
@@ -39,7 +39,7 @@ void DispatchExtendableMessageEventAfterStartWorker(
event->message = std::move(message);
event->source_origin = source_origin;
if (!std::move(set_source_callback).Run(&event)) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_FAILED);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorFailed);
return;
}
@@ -52,7 +52,7 @@ void DispatchExtendableMessageEventAfterStartWorker(
request_id = worker->StartRequest(ServiceWorkerMetrics::EventType::MESSAGE,
std::move(callback));
}
- worker->event_dispatcher()->DispatchExtendableMessageEvent(
+ worker->endpoint()->DispatchExtendableMessageEvent(
std::move(event), worker->CreateSimpleEventCallback(request_id));
}
@@ -66,7 +66,7 @@ void StartWorkerToDispatchExtendableMessageEvent(
// If not enough time is left to actually process the event don't even
// bother starting the worker and sending the event.
if (timeout && *timeout < base::TimeDelta::FromMilliseconds(100)) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_TIMEOUT);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorTimeout);
return;
}
@@ -89,7 +89,7 @@ bool SetSourceClientInfo(
}
// The output |event| must be sent over Mojo immediately after this function
-// returns. See ServiceWorkerHandle::CreateCompleteObjectInfoToSend() for
+// returns. See ServiceWorkerObjectHost::CreateCompleteObjectInfoToSend() for
// details.
bool SetSourceServiceWorkerInfo(scoped_refptr<ServiceWorkerVersion> worker,
base::WeakPtr<ServiceWorkerProviderHost>
@@ -103,14 +103,14 @@ bool SetSourceServiceWorkerInfo(scoped_refptr<ServiceWorkerVersion> worker,
DCHECK_EQ(blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
source_service_worker_provider_host->provider_type());
blink::mojom::ServiceWorkerObjectInfoPtr source_worker_info;
- base::WeakPtr<ServiceWorkerHandle> service_worker_handle =
- worker->provider_host()->GetOrCreateServiceWorkerHandle(
+ base::WeakPtr<ServiceWorkerObjectHost> service_worker_object_host =
+ worker->provider_host()->GetOrCreateServiceWorkerObjectHost(
source_service_worker_provider_host->running_hosted_version());
- if (service_worker_handle) {
+ if (service_worker_object_host) {
// CreateCompleteObjectInfoToSend() is safe because |source_worker_info|
// will be sent immediately by the caller of this function.
source_worker_info =
- service_worker_handle->CreateCompleteObjectInfoToSend();
+ service_worker_object_host->CreateCompleteObjectInfoToSend();
}
(*event)->source_info_for_service_worker = std::move(source_worker_info);
@@ -129,7 +129,7 @@ void DispatchExtendableMessageEventFromClient(
// |source_client_info| may be null if a client sent the message but its
// info could not be retrieved.
if (!source_client_info) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_FAILED);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorFailed);
return;
}
@@ -148,7 +148,7 @@ void DispatchExtendableMessageEventFromServiceWorker(
base::WeakPtr<ServiceWorkerProviderHost>
source_service_worker_provider_host) {
if (!source_service_worker_provider_host) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_FAILED);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorFailed);
return;
}
@@ -162,34 +162,30 @@ void DispatchExtendableMessageEventFromServiceWorker(
} // namespace
-ServiceWorkerHandle::ServiceWorkerHandle(
+ServiceWorkerObjectHost::ServiceWorkerObjectHost(
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerProviderHost* provider_host,
scoped_refptr<ServiceWorkerVersion> version)
: context_(context),
provider_host_(provider_host),
provider_origin_(url::Origin::Create(provider_host->document_url())),
- provider_id_(provider_host->provider_id()),
version_(std::move(version)),
weak_ptr_factory_(this) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(context_ && provider_host_ && version_);
DCHECK(context_->GetLiveRegistration(version_->registration_id()));
- version_->AddListener(this);
+ version_->AddObserver(this);
bindings_.set_connection_error_handler(base::BindRepeating(
- &ServiceWorkerHandle::OnConnectionError, base::Unretained(this)));
+ &ServiceWorkerObjectHost::OnConnectionError, base::Unretained(this)));
}
-ServiceWorkerHandle::~ServiceWorkerHandle() {
- // TODO(crbug.com/838410): These CHECKs are temporary debugging for the linked
- // bug.
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- CHECK(!in_dtor_);
- in_dtor_ = true;
-
- version_->RemoveListener(this);
+ServiceWorkerObjectHost::~ServiceWorkerObjectHost() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ version_->RemoveObserver(this);
}
-void ServiceWorkerHandle::OnVersionStateChanged(ServiceWorkerVersion* version) {
+void ServiceWorkerObjectHost::OnVersionStateChanged(
+ ServiceWorkerVersion* version) {
DCHECK(version);
blink::mojom::ServiceWorkerState state =
mojo::ConvertTo<blink::mojom::ServiceWorkerState>(version->status());
@@ -200,7 +196,7 @@ void ServiceWorkerHandle::OnVersionStateChanged(ServiceWorkerVersion* version) {
}
blink::mojom::ServiceWorkerObjectInfoPtr
-ServiceWorkerHandle::CreateCompleteObjectInfoToSend() {
+ServiceWorkerObjectHost::CreateCompleteObjectInfoToSend() {
auto info = CreateIncompleteObjectInfo();
blink::mojom::ServiceWorkerObjectAssociatedPtr remote_object;
info->request = mojo::MakeRequest(&remote_object);
@@ -209,7 +205,7 @@ ServiceWorkerHandle::CreateCompleteObjectInfoToSend() {
}
blink::mojom::ServiceWorkerObjectInfoPtr
-ServiceWorkerHandle::CreateIncompleteObjectInfo() {
+ServiceWorkerObjectHost::CreateIncompleteObjectInfo() {
auto info = blink::mojom::ServiceWorkerObjectInfo::New();
info->url = version_->script_url();
info->state =
@@ -219,7 +215,7 @@ ServiceWorkerHandle::CreateIncompleteObjectInfo() {
return info;
}
-void ServiceWorkerHandle::AddRemoteObjectPtrAndUpdateState(
+void ServiceWorkerObjectHost::AddRemoteObjectPtrAndUpdateState(
blink::mojom::ServiceWorkerObjectAssociatedPtrInfo remote_object_ptr_info,
blink::mojom::ServiceWorkerState sent_state) {
DCHECK(remote_object_ptr_info.is_valid());
@@ -232,11 +228,11 @@ void ServiceWorkerHandle::AddRemoteObjectPtrAndUpdateState(
remote_objects_.AddPtr(std::move(remote_object));
}
-base::WeakPtr<ServiceWorkerHandle> ServiceWorkerHandle::AsWeakPtr() {
+base::WeakPtr<ServiceWorkerObjectHost> ServiceWorkerObjectHost::AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
-void ServiceWorkerHandle::PostMessageToServiceWorker(
+void ServiceWorkerObjectHost::PostMessageToServiceWorker(
::blink::TransferableMessage message) {
// When this method is called the encoded_message inside message could just
// point to the IPC message's buffer. But that buffer can become invalid
@@ -247,16 +243,16 @@ void ServiceWorkerHandle::PostMessageToServiceWorker(
DispatchExtendableMessageEvent(std::move(message), base::DoNothing());
}
-void ServiceWorkerHandle::TerminateForTesting(
+void ServiceWorkerObjectHost::TerminateForTesting(
TerminateForTestingCallback callback) {
version_->StopWorker(std::move(callback));
}
-void ServiceWorkerHandle::DispatchExtendableMessageEvent(
+void ServiceWorkerObjectHost::DispatchExtendableMessageEvent(
::blink::TransferableMessage message,
StatusCallback callback) {
if (!context_) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort);
return;
}
DCHECK_EQ(provider_origin_,
@@ -292,12 +288,12 @@ void ServiceWorkerHandle::DispatchExtendableMessageEvent(
NOTREACHED() << provider_host_->provider_type();
}
-void ServiceWorkerHandle::OnConnectionError() {
+void ServiceWorkerObjectHost::OnConnectionError() {
// If there are still bindings, |this| is still being used.
if (!bindings_.empty())
return;
// Will destroy |this|.
- provider_host_->RemoveServiceWorkerHandle(version_->version_id());
+ provider_host_->RemoveServiceWorkerObjectHost(version_->version_id());
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_handle.h b/chromium/content/browser/service_worker/service_worker_object_host.h
index 948f68283ac..0c43f3a238f 100644
--- a/chromium/content/browser/service_worker/service_worker_handle.h
+++ b/chromium/content/browser/service_worker/service_worker_object_host.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_SERVICE_WORKER_SERVICE_WORKER_HANDLE_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_H_
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_OBJECT_HOST_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_OBJECT_HOST_H_
#include <memory>
@@ -23,35 +23,37 @@ namespace content {
class ServiceWorkerContextCore;
class ServiceWorkerProviderHost;
-namespace service_worker_handle_unittest {
-class ServiceWorkerHandleTest;
-} // namespace service_worker_handle_unittest
+namespace service_worker_object_host_unittest {
+class ServiceWorkerObjectHostTest;
+} // namespace service_worker_object_host_unittest
// Roughly corresponds to one WebServiceWorker object in the renderer process.
//
// The WebServiceWorker object in the renderer process maintains a reference to
// |this| by owning an associated interface pointer to
-// blink::mojom::ServiceWorkerObjectHost.
+// blink::mojom::ServiceWorkerObjectHost. When all Mojo connections bound with
+// |bindings_| are disconnected, |this| will be deleted. See also comments on
+// |bindings_|.
//
// Has references to the corresponding ServiceWorkerVersion in order to ensure
// that the version is alive while this handle is around.
-class CONTENT_EXPORT ServiceWorkerHandle
+class CONTENT_EXPORT ServiceWorkerObjectHost
: public blink::mojom::ServiceWorkerObjectHost,
- public ServiceWorkerVersion::Listener {
+ public ServiceWorkerVersion::Observer {
public:
- ServiceWorkerHandle(base::WeakPtr<ServiceWorkerContextCore> context,
- ServiceWorkerProviderHost* provider_host,
- scoped_refptr<ServiceWorkerVersion> version);
- ~ServiceWorkerHandle() override;
+ ServiceWorkerObjectHost(base::WeakPtr<ServiceWorkerContextCore> context,
+ ServiceWorkerProviderHost* provider_host,
+ scoped_refptr<ServiceWorkerVersion> version);
+ ~ServiceWorkerObjectHost() override;
- // ServiceWorkerVersion::Listener overrides.
+ // ServiceWorkerVersion::Observer overrides.
void OnVersionStateChanged(ServiceWorkerVersion* version) override;
- // Returns an info for the ServiceWorker object of this handle. The info
- // contains a Mojo ptr to |this| which ensures |this| stays alive while the
- // info is alive. Furthermore, it contains a Mojo request for the
- // ServiceWorkerObject interface in the renderer. |this| will make calls to
- // the ServiceWorkerObject to update its state.
+ // Returns an info for the ServiceWorker object. The info contains a Mojo
+ // ptr to |this| which ensures |this| stays alive while the info is alive.
+ // Furthermore, it contains a Mojo request for the ServiceWorkerObject
+ // interface in the renderer. |this| will make calls to the
+ // ServiceWorkerObject to update its state.
//
// WARNING: The returned info must be sent immediately over Mojo, because
// |this| will start making calls on an associated interface ptr to
@@ -76,13 +78,12 @@ class CONTENT_EXPORT ServiceWorkerHandle
blink::mojom::ServiceWorkerObjectAssociatedPtrInfo remote_object_ptr_info,
blink::mojom::ServiceWorkerState sent_state);
- int provider_id() const { return provider_id_; }
ServiceWorkerVersion* version() { return version_.get(); }
- base::WeakPtr<ServiceWorkerHandle> AsWeakPtr();
+ base::WeakPtr<ServiceWorkerObjectHost> AsWeakPtr();
private:
- friend class service_worker_handle_unittest::ServiceWorkerHandleTest;
+ friend class service_worker_object_host_unittest::ServiceWorkerObjectHostTest;
// Implements blink::mojom::ServiceWorkerObjectHost.
void PostMessageToServiceWorker(
@@ -94,40 +95,36 @@ class CONTENT_EXPORT ServiceWorkerHandle
// observe the dispatch result in unit tests.
void DispatchExtendableMessageEvent(
::blink::TransferableMessage message,
- base::OnceCallback<void(ServiceWorkerStatusCode)> callback);
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)> callback);
void OnConnectionError();
base::WeakPtr<ServiceWorkerContextCore> context_;
// |provider_host_| is valid throughout lifetime of |this| because it owns
// |this|.
- ServiceWorkerProviderHost* provider_host_;
+ ServiceWorkerProviderHost* const provider_host_;
// The origin of the |provider_host_|. Note that this is const because once a
// JavaScript ServiceWorker object is created for an execution context, we
// don't expect that context to change origins and still hold on to the
// object.
const url::Origin provider_origin_;
- const int provider_id_;
scoped_refptr<ServiceWorkerVersion> version_;
+ // Typically both |bindings_| and |remote_objects_| contain only one Mojo
+ // connection, corresponding to the content::WebServiceWorkerImpl in the
+ // renderer which corresponds to the ServiceWorker JavaScript object. However,
+ // multiple Mojo connections may exist while propagating multiple service
+ // worker object infos to the renderer process, but only the first one that
+ // arrived there will be used to create the new content::WebServiceWorkerImpl
+ // instance and be bound to it.
mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerObjectHost> bindings_;
- // Typically |remote_objects_| contains only one Mojo connection,
- // corresponding to the content::WebServiceWorkerImpl in the renderer which
- // corresponds to the ServiceWorker JavaScript object. However, multiple Mojo
- // connections may exist while propagating multiple service worker object
- // infos to the renderer process, but only the first one that arrived there
- // will be used to create the new content::WebServiceWorkerImpl instance and
- // be bound to it.
mojo::AssociatedInterfacePtrSet<blink::mojom::ServiceWorkerObject>
remote_objects_;
- // TODO(crbug.com/838410): Temporary debugging for the linked bug.
- bool in_dtor_ = false;
+ base::WeakPtrFactory<ServiceWorkerObjectHost> weak_ptr_factory_;
- base::WeakPtrFactory<ServiceWorkerHandle> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandle);
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerObjectHost);
};
} // namespace content
-#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_H_
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_OBJECT_HOST_H_
diff --git a/chromium/content/browser/service_worker/service_worker_handle_unittest.cc b/chromium/content/browser/service_worker/service_worker_object_host_unittest.cc
index 6122d08b40c..fd1ca22f735 100644
--- a/chromium/content/browser/service_worker/service_worker_handle_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_object_host_unittest.cc
@@ -12,7 +12,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_dispatcher_host.h"
-#include "content/browser/service_worker/service_worker_handle.h"
+#include "content/browser/service_worker/service_worker_object_host.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"
@@ -28,11 +28,11 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_state.mojom.h"
namespace content {
-namespace service_worker_handle_unittest {
+namespace service_worker_object_host_unittest {
static void SaveStatusCallback(bool* called,
- ServiceWorkerStatusCode* out,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode* out,
+ blink::ServiceWorkerStatusCode status) {
*called = true;
*out = status;
}
@@ -52,8 +52,8 @@ class ExtendableMessageEventTestHelper : public EmbeddedWorkerTestHelper {
void OnExtendableMessageEvent(
mojom::ExtendableMessageEventPtr event,
- mojom::ServiceWorkerEventDispatcher::
- DispatchExtendableMessageEventCallback callback) override {
+ mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback)
+ override {
events_.push_back(std::move(event));
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time::Now());
@@ -77,7 +77,7 @@ class FailToStartWorkerTestHelper : public ExtendableMessageEventTestHelper {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
@@ -112,19 +112,13 @@ class MockServiceWorkerObject : public blink::mojom::ServiceWorkerObject {
mojo::AssociatedBinding<blink::mojom::ServiceWorkerObject> binding_;
};
-class ServiceWorkerHandleTest : public testing::Test {
+class ServiceWorkerObjectHostTest : public testing::Test {
public:
- ServiceWorkerHandleTest()
+ ServiceWorkerObjectHostTest()
: browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
void Initialize(std::unique_ptr<EmbeddedWorkerTestHelper> helper) {
helper_ = std::move(helper);
-
- dispatcher_host_ = base::MakeRefCounted<ServiceWorkerDispatcherHost>(
- helper_->mock_render_process_id());
- helper_->RegisterDispatcherHost(helper_->mock_render_process_id(),
- dispatcher_host_);
- dispatcher_host_->Init(helper_->context_wrapper());
}
void SetUpRegistration(const GURL& scope, const GURL& script_url) {
@@ -150,39 +144,37 @@ class ServiceWorkerHandleTest : public testing::Test {
version_->SetStatus(ServiceWorkerVersion::INSTALLING);
// Make the registration findable via storage functions.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
helper_->context()->storage()->StoreRegistration(
- registration_.get(),
- version_.get(),
+ registration_.get(), version_.get(),
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- ASSERT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
}
void TearDown() override {
- dispatcher_host_ = nullptr;
registration_ = nullptr;
version_ = nullptr;
helper_.reset();
}
void CallDispatchExtendableMessageEvent(
- ServiceWorkerHandle* handle,
+ ServiceWorkerObjectHost* object_host,
::blink::TransferableMessage message,
- base::OnceCallback<void(ServiceWorkerStatusCode)> callback) {
- handle->DispatchExtendableMessageEvent(std::move(message),
- std::move(callback));
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)> callback) {
+ object_host->DispatchExtendableMessageEvent(std::move(message),
+ std::move(callback));
}
- size_t GetBindingsCount(ServiceWorkerHandle* handle) {
- return handle->bindings_.size();
+ size_t GetBindingsCount(ServiceWorkerObjectHost* object_host) {
+ return object_host->bindings_.size();
}
- ServiceWorkerHandle* GetServiceWorkerHandle(
+ ServiceWorkerObjectHost* GetServiceWorkerObjectHost(
ServiceWorkerProviderHost* provider_host,
int64_t version_id) {
- auto iter = provider_host->handles_.find(version_id);
- if (iter != provider_host->handles_.end())
+ auto iter = provider_host->service_worker_object_hosts_.find(version_id);
+ if (iter != provider_host->service_worker_object_hosts_.end())
return iter->second.get();
return nullptr;
}
@@ -213,20 +205,16 @@ class ServiceWorkerHandleTest : public testing::Test {
}
TestBrowserThreadBundle browser_thread_bundle_;
-
- base::SimpleTestTickClock tick_clock_;
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
scoped_refptr<ServiceWorkerRegistration> registration_;
scoped_refptr<ServiceWorkerVersion> version_;
- scoped_refptr<ServiceWorkerDispatcherHost> dispatcher_host_;
private:
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandleTest);
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerObjectHostTest);
};
-TEST_F(ServiceWorkerHandleTest, OnVersionStateChanged) {
+TEST_F(ServiceWorkerObjectHostTest, OnVersionStateChanged) {
const int64_t kProviderId = 99;
- const int kRenderFrameId = 44;
const GURL pattern("https://www.example.com/");
const GURL script_url("https://www.example.com/service_worker.js");
Initialize(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath()));
@@ -235,10 +223,10 @@ TEST_F(ServiceWorkerHandleTest, OnVersionStateChanged) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint;
std::unique_ptr<ServiceWorkerProviderHost> provider_host =
- CreateProviderHostWithDispatcherHost(
+ CreateProviderHostForWindow(
helper_->mock_render_process_id(), kProviderId,
- helper_->context()->AsWeakPtr(), kRenderFrameId,
- dispatcher_host_.get(), &remote_endpoint);
+ true /* is_parent_frame_secure */, helper_->context()->AsWeakPtr(),
+ &remote_endpoint);
provider_host->SetDocumentUrl(pattern);
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info =
GetRegistrationFromRemote(remote_endpoint.host_ptr()->get(), pattern);
@@ -256,62 +244,65 @@ TEST_F(ServiceWorkerHandleTest, OnVersionStateChanged) {
EXPECT_EQ(blink::mojom::ServiceWorkerState::kInstalled, mock_object->state());
}
-TEST_F(ServiceWorkerHandleTest,
+TEST_F(ServiceWorkerObjectHostTest,
DispatchExtendableMessageEvent_FromServiceWorker) {
const GURL pattern("https://www.example.com/");
const GURL script_url("https://www.example.com/service_worker.js");
Initialize(std::make_unique<ExtendableMessageEventTestHelper>());
SetUpRegistration(pattern, script_url);
+ base::SimpleTestTickClock tick_clock;
// Set mock clock on version_ to check timeout behavior.
- tick_clock_.SetNowTicks(base::TimeTicks::Now());
- version_->SetTickClockForTesting(&tick_clock_);
+ tick_clock.SetNowTicks(base::TimeTicks::Now());
+ version_->SetTickClockForTesting(&tick_clock);
// Make sure worker has a non-zero timeout.
bool called = false;
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
base::BindOnce(&SaveStatusCallback, &called, &status));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
version_->StartRequestWithCustomTimeout(
ServiceWorkerMetrics::EventType::ACTIVATE, base::DoNothing(),
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);
- // Prepare a ServiceWorkerHandle corresponding to a JavaScript ServiceWorker
- // object in the service worker execution context for |version_|.
+ // Prepare a ServiceWorkerObjectHost corresponding to a JavaScript
+ // ServiceWorker object in the service worker execution context for
+ // |version_|.
ServiceWorkerProviderHost* provider_host = version_->provider_host();
blink::mojom::ServiceWorkerObjectInfoPtr info =
- provider_host->GetOrCreateServiceWorkerHandle(version_.get())
+ provider_host->GetOrCreateServiceWorkerObjectHost(version_)
->CreateCompleteObjectInfoToSend();
- ServiceWorkerHandle* sender_worker_handle =
- GetServiceWorkerHandle(provider_host, version_->version_id());
- EXPECT_EQ(1u, GetBindingsCount(sender_worker_handle));
+ ServiceWorkerObjectHost* sender_worker_object_host =
+ GetServiceWorkerObjectHost(provider_host, version_->version_id());
+ EXPECT_EQ(1u, GetBindingsCount(sender_worker_object_host));
// Dispatch an ExtendableMessageEvent simulating calling
// ServiceWorker#postMessage() on the ServiceWorker object corresponding to
- // |service_worker_handle|.
+ // |service_worker_object_host|.
blink::TransferableMessage message;
SetUpDummyMessagePort(&message.ports);
called = false;
- status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ status = blink::ServiceWorkerStatusCode::kErrorFailed;
CallDispatchExtendableMessageEvent(
- sender_worker_handle, std::move(message),
+ sender_worker_object_host, std::move(message),
base::BindOnce(&SaveStatusCallback, &called, &status));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
// The dispatched ExtendableMessageEvent should be kept in
// ExtendableMessageEventTestHelper, and the source service worker object info
// should correspond to the pair (|version_->provider_host()|, |version_|),
- // means it should correspond to |sender_worker_handle|.
- EXPECT_EQ(2u, GetBindingsCount(sender_worker_handle));
+ // means it should correspond to |sender_worker_object_host|.
+ EXPECT_EQ(2u, GetBindingsCount(sender_worker_object_host));
const std::vector<mojom::ExtendableMessageEventPtr>& events =
static_cast<ExtendableMessageEventTestHelper*>(helper_.get())->events();
EXPECT_EQ(1u, events.size());
@@ -322,9 +313,13 @@ TEST_F(ServiceWorkerHandleTest,
// Timeout of message event should not have extended life of service worker.
EXPECT_EQ(remaining_time, version_->remaining_timeout());
+ // Clean up.
+ base::RunLoop stop_loop;
+ version_->StopWorker(stop_loop.QuitClosure());
+ stop_loop.Run();
}
-TEST_F(ServiceWorkerHandleTest, DispatchExtendableMessageEvent_FromClient) {
+TEST_F(ServiceWorkerObjectHostTest, DispatchExtendableMessageEvent_FromClient) {
const int64_t kProviderId = 99;
const GURL pattern("https://www.example.com/");
const GURL script_url("https://www.example.com/service_worker.js");
@@ -339,33 +334,32 @@ TEST_F(ServiceWorkerHandleTest, DispatchExtendableMessageEvent_FromClient) {
WebContentsTester::CreateTestWebContents(helper_->browser_context(),
nullptr));
RenderFrameHost* frame_host = web_contents->GetMainFrame();
- ServiceWorkerProviderHostInfo provider_host_info(
- kProviderId, frame_host->GetRoutingID(),
- blink::mojom::ServiceWorkerProviderType::kForWindow,
- true /* is_parent_frame_secure */);
+ mojom::ServiceWorkerProviderHostInfoPtr provider_host_info =
+ CreateProviderHostInfoForWindow(kProviderId, frame_host->GetRoutingID());
std::unique_ptr<ServiceWorkerProviderHost> provider_host =
- ServiceWorkerProviderHost::Create(
- frame_host->GetProcess()->GetID(), std::move(provider_host_info),
- helper_->context()->AsWeakPtr(), dispatcher_host_->AsWeakPtr());
+ ServiceWorkerProviderHost::Create(frame_host->GetProcess()->GetID(),
+ std::move(provider_host_info),
+ helper_->context()->AsWeakPtr());
provider_host->SetDocumentUrl(pattern);
- // Prepare a ServiceWorkerHandle for the above |provider_host|.
+ // Prepare a ServiceWorkerObjectHost for the above |provider_host|.
blink::mojom::ServiceWorkerObjectInfoPtr info =
- provider_host->GetOrCreateServiceWorkerHandle(version_.get())
+ provider_host->GetOrCreateServiceWorkerObjectHost(version_)
->CreateCompleteObjectInfoToSend();
- ServiceWorkerHandle* handle =
- GetServiceWorkerHandle(provider_host.get(), version_->version_id());
+ ServiceWorkerObjectHost* object_host =
+ GetServiceWorkerObjectHost(provider_host.get(), version_->version_id());
// Simulate dispatching an ExtendableMessageEvent.
blink::TransferableMessage message;
SetUpDummyMessagePort(&message.ports);
bool called = false;
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
CallDispatchExtendableMessageEvent(
- handle, std::move(message),
+ object_host, std::move(message),
base::BindOnce(&SaveStatusCallback, &called, &status));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
// The dispatched ExtendableMessageEvent should be kept in
// ExtendableMessageEventTestHelper, and its source client info should
// correspond to |provider_host|.
@@ -380,7 +374,7 @@ TEST_F(ServiceWorkerHandleTest, DispatchExtendableMessageEvent_FromClient) {
events[0]->source_info_for_client->client_type);
}
-TEST_F(ServiceWorkerHandleTest, DispatchExtendableMessageEvent_Fail) {
+TEST_F(ServiceWorkerObjectHostTest, DispatchExtendableMessageEvent_Fail) {
const int64_t kProviderId = 99;
const GURL pattern("https://www.example.com/");
const GURL script_url("https://www.example.com/service_worker.js");
@@ -395,39 +389,37 @@ TEST_F(ServiceWorkerHandleTest, DispatchExtendableMessageEvent_Fail) {
WebContentsTester::CreateTestWebContents(helper_->browser_context(),
nullptr));
RenderFrameHost* frame_host = web_contents->GetMainFrame();
- ServiceWorkerProviderHostInfo provider_host_info(
- kProviderId, frame_host->GetRoutingID(),
- blink::mojom::ServiceWorkerProviderType::kForWindow,
- true /* is_parent_frame_secure */);
+ mojom::ServiceWorkerProviderHostInfoPtr provider_host_info =
+ CreateProviderHostInfoForWindow(kProviderId, frame_host->GetRoutingID());
std::unique_ptr<ServiceWorkerProviderHost> provider_host =
- ServiceWorkerProviderHost::Create(
- frame_host->GetProcess()->GetID(), std::move(provider_host_info),
- helper_->context()->AsWeakPtr(), dispatcher_host_->AsWeakPtr());
+ ServiceWorkerProviderHost::Create(frame_host->GetProcess()->GetID(),
+ std::move(provider_host_info),
+ helper_->context()->AsWeakPtr());
provider_host->SetDocumentUrl(pattern);
- // Prepare a ServiceWorkerHandle for the above |provider_host|.
+ // Prepare a ServiceWorkerObjectHost for the above |provider_host|.
blink::mojom::ServiceWorkerObjectInfoPtr info =
- provider_host->GetOrCreateServiceWorkerHandle(version_.get())
+ provider_host->GetOrCreateServiceWorkerObjectHost(version_)
->CreateCompleteObjectInfoToSend();
- ServiceWorkerHandle* handle =
- GetServiceWorkerHandle(provider_host.get(), version_->version_id());
+ ServiceWorkerObjectHost* object_host =
+ GetServiceWorkerObjectHost(provider_host.get(), version_->version_id());
// Try to dispatch ExtendableMessageEvent. This should fail to start the
// worker and to dispatch the event.
blink::TransferableMessage message;
SetUpDummyMessagePort(&message.ports);
bool called = false;
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ blink::ServiceWorkerStatusCode status = blink::ServiceWorkerStatusCode::kOk;
CallDispatchExtendableMessageEvent(
- handle, std::move(message),
+ object_host, std::move(message),
base::BindOnce(&SaveStatusCallback, &called, &status));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(called);
- EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed, status);
// No ExtendableMessageEvent has been dispatched.
const std::vector<mojom::ExtendableMessageEventPtr>& events =
static_cast<ExtendableMessageEventTestHelper*>(helper_.get())->events();
EXPECT_EQ(0u, events.size());
}
-} // namespace service_worker_handle_unittest
+} // namespace service_worker_object_host_unittest
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_ping_controller.cc b/chromium/content/browser/service_worker/service_worker_ping_controller.cc
new file mode 100644
index 00000000000..2f9425a57b9
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_ping_controller.cc
@@ -0,0 +1,68 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/service_worker/service_worker_ping_controller.h"
+
+#include "content/browser/service_worker/service_worker_version.h"
+
+namespace content {
+
+namespace {
+// Timeout for waiting for a response to a ping.
+constexpr base::TimeDelta kPingTimeout = base::TimeDelta::FromSeconds(30);
+} // namespace
+
+ServiceWorkerPingController::ServiceWorkerPingController(
+ ServiceWorkerVersion* version)
+ : version_(version) {}
+
+ServiceWorkerPingController::~ServiceWorkerPingController() = default;
+
+void ServiceWorkerPingController::Activate() {
+ ping_state_ = PingState::kPinging;
+}
+
+void ServiceWorkerPingController::Deactivate() {
+ ClearLastPingTime();
+ ping_state_ = PingState::kNotPinging;
+}
+
+void ServiceWorkerPingController::OnPongReceived() {
+ ClearLastPingTime();
+}
+
+bool ServiceWorkerPingController::IsActivated() const {
+ return ping_state_ == PingState::kPinging;
+}
+
+bool ServiceWorkerPingController::IsTimedOut() const {
+ return ping_state_ == PingState::kPingTimedOut;
+}
+
+void ServiceWorkerPingController::CheckPingStatus() {
+ if (version_->GetTickDuration(last_ping_time_) > kPingTimeout) {
+ ping_state_ = PingState::kPingTimedOut;
+ version_->OnPingTimeout();
+ return;
+ }
+
+ // Check if we want to send a next ping.
+ if (ping_state_ != PingState::kPinging || !last_ping_time_.is_null())
+ return;
+
+ version_->PingWorker();
+ version_->RestartTick(&last_ping_time_);
+}
+
+void ServiceWorkerPingController::SimulateTimeoutForTesting() {
+ version_->PingWorker();
+ ping_state_ = PingState::kPingTimedOut;
+ version_->OnPingTimeout();
+}
+
+void ServiceWorkerPingController::ClearLastPingTime() {
+ last_ping_time_ = base::TimeTicks();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_ping_controller.h b/chromium/content/browser/service_worker/service_worker_ping_controller.h
new file mode 100644
index 00000000000..5c7d261624f
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_ping_controller.h
@@ -0,0 +1,54 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PING_CONTROLLER_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PING_CONTROLLER_H_
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class ServiceWorkerVersion;
+
+// A controller for periodically sending a ping to the worker to see if the
+// worker is not stalling or is in a busy synchronous loop (possibly abusively).
+class CONTENT_EXPORT ServiceWorkerPingController final {
+ public:
+ explicit ServiceWorkerPingController(ServiceWorkerVersion* version);
+ ~ServiceWorkerPingController();
+
+ void Activate();
+ void Deactivate();
+ void OnPongReceived();
+
+ bool IsActivated() const;
+ bool IsTimedOut() const;
+
+ // Checks ping status. This is supposed to be called periodically.
+ // This may call:
+ // - version_->OnPingTimeout() if the worker hasn't reponded within a
+ // certain period.
+ // - version_->PingWorker() if we're running ping timer and can send next
+ // ping.
+ void CheckPingStatus();
+
+ void SimulateTimeoutForTesting();
+
+ private:
+ void ClearLastPingTime();
+
+ enum class PingState { kNotPinging, kPinging, kPingTimedOut };
+ ServiceWorkerVersion* version_; // Owns |this|.
+ // The time the most recent ping was sent.
+ base::TimeTicks last_ping_time_;
+ PingState ping_state_ = PingState::kNotPinging;
+
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerPingController);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PING_CONTROLLER_H_
diff --git a/chromium/content/browser/service_worker/service_worker_process_manager.cc b/chromium/content/browser/service_worker/service_worker_process_manager.cc
index 79850cf30c1..403f8b6525c 100644
--- a/chromium/content/browser/service_worker/service_worker_process_manager.cc
+++ b/chromium/content/browser/service_worker/service_worker_process_manager.cc
@@ -79,7 +79,8 @@ bool ServiceWorkerProcessManager::IsShutdown() {
return !browser_context_;
}
-ServiceWorkerStatusCode ServiceWorkerProcessManager::AllocateWorkerProcess(
+blink::ServiceWorkerStatusCode
+ServiceWorkerProcessManager::AllocateWorkerProcess(
int embedded_worker_id,
const GURL& pattern,
const GURL& script_url,
@@ -97,11 +98,11 @@ ServiceWorkerStatusCode ServiceWorkerProcessManager::AllocateWorkerProcess(
out_info->process_id = result;
out_info->start_situation =
ServiceWorkerMetrics::StartSituation::EXISTING_READY_PROCESS;
- return SERVICE_WORKER_OK;
+ return blink::ServiceWorkerStatusCode::kOk;
}
if (IsShutdown()) {
- return SERVICE_WORKER_ERROR_ABORT;
+ return blink::ServiceWorkerStatusCode::kErrorAbort;
}
DCHECK(!base::ContainsKey(worker_process_map_, embedded_worker_id))
@@ -138,9 +139,9 @@ ServiceWorkerStatusCode ServiceWorkerProcessManager::AllocateWorkerProcess(
rph->InSameStoragePartition(storage_partition_));
ServiceWorkerMetrics::StartSituation start_situation;
- if (!rph->HasConnection()) {
- // HasConnection() is false means that Init() has not been called or the
- // process has been killed.
+ if (!rph->IsInitializedAndNotDead()) {
+ // IsInitializedAndNotDead() is false means that Init() has not been called
+ // or the process has been killed.
start_situation = ServiceWorkerMetrics::StartSituation::NEW_PROCESS;
} else if (!rph->IsReady()) {
start_situation =
@@ -152,7 +153,7 @@ ServiceWorkerStatusCode ServiceWorkerProcessManager::AllocateWorkerProcess(
if (!rph->Init()) {
LOG(ERROR) << "Couldn't start a new process!";
- return SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND;
+ return blink::ServiceWorkerStatusCode::kErrorProcessNotFound;
}
worker_process_map_.emplace(embedded_worker_id, std::move(site_instance));
@@ -161,7 +162,7 @@ ServiceWorkerStatusCode ServiceWorkerProcessManager::AllocateWorkerProcess(
RenderProcessHost::KeepAliveClientType::kServiceWorker);
out_info->process_id = rph->GetID();
out_info->start_situation = start_situation;
- return SERVICE_WORKER_OK;
+ return blink::ServiceWorkerStatusCode::kOk;
}
void ServiceWorkerProcessManager::ReleaseWorkerProcess(int embedded_worker_id) {
diff --git a/chromium/content/browser/service_worker/service_worker_process_manager.h b/chromium/content/browser/service_worker/service_worker_process_manager.h
index 71f589a970c..f768781f2c9 100644
--- a/chromium/content/browser/service_worker/service_worker_process_manager.h
+++ b/chromium/content/browser/service_worker/service_worker_process_manager.h
@@ -14,7 +14,7 @@
#include "base/memory/weak_ptr.h"
#include "base/synchronization/lock.h"
#include "content/browser/service_worker/service_worker_metrics.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
class GURL;
@@ -66,15 +66,16 @@ class CONTENT_EXPORT ServiceWorkerProcessManager {
// false, or a suitable existing process is not found, a new process may be
// created.
//
- // If SERVICE_WORKER_OK is returned, |out_info| contains information about the
- // process.
+ // If blink::ServiceWorkerStatusCode::kOk is returned,
+ // |out_info| contains information about the process.
//
// Called on the UI thread.
- ServiceWorkerStatusCode AllocateWorkerProcess(int embedded_worker_id,
- const GURL& pattern,
- const GURL& script_url,
- bool can_use_existing_process,
- AllocatedProcessInfo* out_info);
+ blink::ServiceWorkerStatusCode AllocateWorkerProcess(
+ int embedded_worker_id,
+ const GURL& pattern,
+ const GURL& script_url,
+ bool can_use_existing_process,
+ AllocatedProcessInfo* out_info);
// Drops a reference to a process that was running a Service Worker, and its
// SiteInstance. This must match a call to AllocateWorkerProcess().
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 ab6899ad6ae..edc8d043b02 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
@@ -119,12 +119,13 @@ TEST_F(ServiceWorkerProcessManagerTest,
// Allocate a process to a worker, when process reuse is authorized.
ServiceWorkerProcessManager::AllocatedProcessInfo process_info;
- ServiceWorkerStatusCode status = process_manager_->AllocateWorkerProcess(
- kEmbeddedWorkerId, pattern_, script_url_,
- true /* can_use_existing_process */, &process_info);
+ blink::ServiceWorkerStatusCode status =
+ process_manager_->AllocateWorkerProcess(
+ kEmbeddedWorkerId, pattern_, script_url_,
+ true /* can_use_existing_process */, &process_info);
// An existing process should be allocated to the worker.
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
EXPECT_EQ(host->GetID(), process_info.process_id);
EXPECT_EQ(ServiceWorkerMetrics::StartSituation::EXISTING_UNREADY_PROCESS,
process_info.start_situation);
@@ -159,12 +160,13 @@ TEST_F(ServiceWorkerProcessManagerTest,
// Allocate a process to a worker, when process reuse is disallowed.
ServiceWorkerProcessManager::AllocatedProcessInfo process_info;
- ServiceWorkerStatusCode status = process_manager_->AllocateWorkerProcess(
- kEmbeddedWorkerId, pattern_, script_url_,
- false /* can_use_existing_process */, &process_info);
+ blink::ServiceWorkerStatusCode status =
+ process_manager_->AllocateWorkerProcess(
+ kEmbeddedWorkerId, pattern_, script_url_,
+ false /* can_use_existing_process */, &process_info);
// A new process should be allocated to the worker.
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
EXPECT_NE(host->GetID(), process_info.process_id);
EXPECT_EQ(ServiceWorkerMetrics::StartSituation::NEW_PROCESS,
process_info.start_situation);
@@ -187,12 +189,13 @@ TEST_F(ServiceWorkerProcessManagerTest, AllocateWorkerProcess_InShutdown) {
ASSERT_TRUE(process_manager_->IsShutdown());
ServiceWorkerProcessManager::AllocatedProcessInfo process_info;
- ServiceWorkerStatusCode status = process_manager_->AllocateWorkerProcess(
- 1, pattern_, script_url_, true /* can_use_existing_process */,
- &process_info);
+ blink::ServiceWorkerStatusCode status =
+ process_manager_->AllocateWorkerProcess(
+ 1, pattern_, script_url_, true /* can_use_existing_process */,
+ &process_info);
// Allocating a process in shutdown should abort.
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort, status);
EXPECT_EQ(ChildProcessHost::kInvalidUniqueID, process_info.process_id);
EXPECT_EQ(ServiceWorkerMetrics::StartSituation::UNKNOWN,
process_info.start_situation);
@@ -213,10 +216,11 @@ TEST_F(ServiceWorkerProcessManagerTest,
{
const int kEmbeddedWorkerId = 55; // dummy value
ServiceWorkerProcessManager::AllocatedProcessInfo process_info;
- ServiceWorkerStatusCode status = process_manager_->AllocateWorkerProcess(
- kEmbeddedWorkerId, pattern_, script_url_,
- true /* can_use_existing_process */, &process_info);
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ blink::ServiceWorkerStatusCode status =
+ process_manager_->AllocateWorkerProcess(
+ kEmbeddedWorkerId, pattern_, script_url_,
+ true /* can_use_existing_process */, &process_info);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
// Instead of testing the input to the CreateRenderProcessHost(), it'd be
// more interesting to check the StoragePartition of the returned process
// here and below. Alas, MockRenderProcessHosts always use the default
@@ -248,10 +252,11 @@ TEST_F(ServiceWorkerProcessManagerTest,
{
const int kEmbeddedWorkerId = 77; // dummy value
ServiceWorkerProcessManager::AllocatedProcessInfo process_info;
- ServiceWorkerStatusCode status = process_manager_->AllocateWorkerProcess(
- kEmbeddedWorkerId, pattern_, script_url_,
- true /* can_use_existing_process */, &process_info);
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ blink::ServiceWorkerStatusCode status =
+ process_manager_->AllocateWorkerProcess(
+ kEmbeddedWorkerId, pattern_, script_url_,
+ true /* can_use_existing_process */, &process_info);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
EXPECT_EQ(
kGuestSiteUrl,
render_process_host_factory_->last_site_instance_used()->GetSiteURL());
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 4208300ee9b..f3f335bde5e 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_provider_host.cc
@@ -21,7 +21,6 @@
#include "content/browser/service_worker/service_worker_context_request_handler.h"
#include "content/browser/service_worker/service_worker_context_wrapper.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_registration_object_host.h"
#include "content/browser/service_worker/service_worker_script_loader_factory.h"
#include "content/browser/service_worker/service_worker_type_converters.h"
@@ -43,6 +42,7 @@
#include "services/network/public/cpp/resource_request_body.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
@@ -147,6 +147,41 @@ ServiceWorkerMetrics::EventType PurposeToEventType(
} // anonymous namespace
+// RAII helper class for keeping track of versions waiting for an update hint
+// from the renderer.
+//
+// This class is move-only.
+class ServiceWorkerProviderHost::PendingUpdateVersion {
+ public:
+ explicit PendingUpdateVersion(scoped_refptr<ServiceWorkerVersion> version)
+ : version_(std::move(version)) {
+ version_->IncrementPendingUpdateHintCount();
+ }
+
+ PendingUpdateVersion(PendingUpdateVersion&& other) {
+ version_ = std::move(other.version_);
+ }
+
+ ~PendingUpdateVersion() {
+ if (version_)
+ version_->DecrementPendingUpdateHintCount();
+ }
+
+ PendingUpdateVersion& operator=(PendingUpdateVersion&& other) {
+ version_ = std::move(other.version_);
+ return *this;
+ }
+
+ // Needed for base::flat_set.
+ bool operator<(const PendingUpdateVersion& other) const {
+ return version_ < other.version_;
+ }
+
+ private:
+ scoped_refptr<ServiceWorkerVersion> version_;
+ DISALLOW_COPY_AND_ASSIGN(PendingUpdateVersion);
+};
+
// static
base::WeakPtr<ServiceWorkerProviderHost>
ServiceWorkerProviderHost::PreCreateNavigationHost(
@@ -156,11 +191,12 @@ ServiceWorkerProviderHost::PreCreateNavigationHost(
DCHECK(context);
auto host = base::WrapUnique(new ServiceWorkerProviderHost(
ChildProcessHost::kInvalidUniqueID,
- ServiceWorkerProviderHostInfo(
+ mojom::ServiceWorkerProviderHostInfo::New(
NextBrowserProvidedProviderId(), MSG_ROUTING_NONE,
blink::mojom::ServiceWorkerProviderType::kForWindow,
- are_ancestors_secure),
- context, nullptr /* dispatcher_host */));
+ are_ancestors_secure, nullptr /* host_request */,
+ nullptr /* client_ptr_info */),
+ context));
host->web_contents_getter_ = web_contents_getter;
auto weak_ptr = host->AsWeakPtr();
@@ -169,17 +205,32 @@ ServiceWorkerProviderHost::PreCreateNavigationHost(
}
// static
-std::unique_ptr<ServiceWorkerProviderHost>
+base::WeakPtr<ServiceWorkerProviderHost>
ServiceWorkerProviderHost::PreCreateForController(
- base::WeakPtr<ServiceWorkerContextCore> context) {
+ base::WeakPtr<ServiceWorkerContextCore> context,
+ scoped_refptr<ServiceWorkerVersion> version,
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr* out_provider_info) {
auto host = base::WrapUnique(new ServiceWorkerProviderHost(
ChildProcessHost::kInvalidUniqueID,
- ServiceWorkerProviderHostInfo(
+ mojom::ServiceWorkerProviderHostInfo::New(
NextBrowserProvidedProviderId(), MSG_ROUTING_NONE,
blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
- true /* is_parent_frame_secure */),
- std::move(context), nullptr));
- return host;
+ true /* is_parent_frame_secure */, nullptr /* host_request */,
+ nullptr /* client_ptr_info */),
+ context));
+ host->running_hosted_version_ = std::move(version);
+
+ (*out_provider_info)->provider_id = host->provider_id();
+ (*out_provider_info)->client_request = mojo::MakeRequest(&host->container_);
+ host->binding_.Bind(
+ mojo::MakeRequest(&((*out_provider_info)->host_ptr_info)));
+ host->binding_.set_connection_error_handler(
+ base::BindOnce(&RemoveProviderHost, context,
+ ChildProcessHost::kInvalidUniqueID, host->provider_id()));
+
+ auto weak_ptr = host->AsWeakPtr();
+ context->AddProviderHost(std::move(host));
+ return weak_ptr;
}
// static
@@ -190,12 +241,12 @@ ServiceWorkerProviderHost::PreCreateForSharedWorker(
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr* out_provider_info) {
auto host = base::WrapUnique(new ServiceWorkerProviderHost(
ChildProcessHost::kInvalidUniqueID,
- ServiceWorkerProviderHostInfo(
+ mojom::ServiceWorkerProviderHostInfo::New(
NextBrowserProvidedProviderId(), MSG_ROUTING_NONE,
blink::mojom::ServiceWorkerProviderType::kForSharedWorker,
- true /* is_parent_frame_secure */),
- context, nullptr));
- host->dispatcher_host_ = context->GetDispatcherHost(process_id)->AsWeakPtr();
+ true /* is_parent_frame_secure */, nullptr /* host_request */,
+ nullptr /* client_ptr_info */),
+ context));
host->render_process_id_ = process_id;
(*out_provider_info)->provider_id = host->provider_id();
@@ -213,33 +264,30 @@ ServiceWorkerProviderHost::PreCreateForSharedWorker(
// static
std::unique_ptr<ServiceWorkerProviderHost> ServiceWorkerProviderHost::Create(
int process_id,
- ServiceWorkerProviderHostInfo info,
- base::WeakPtr<ServiceWorkerContextCore> context,
- base::WeakPtr<ServiceWorkerDispatcherHost> dispatcher_host) {
- auto host = base::WrapUnique(new ServiceWorkerProviderHost(
- process_id, std::move(info), context, dispatcher_host));
+ mojom::ServiceWorkerProviderHostInfoPtr info,
+ base::WeakPtr<ServiceWorkerContextCore> context) {
+ auto host = base::WrapUnique(
+ new ServiceWorkerProviderHost(process_id, std::move(info), context));
host->is_execution_ready_ = true;
return host;
}
ServiceWorkerProviderHost::ServiceWorkerProviderHost(
int render_process_id,
- ServiceWorkerProviderHostInfo info,
- base::WeakPtr<ServiceWorkerContextCore> context,
- base::WeakPtr<ServiceWorkerDispatcherHost> dispatcher_host)
+ mojom::ServiceWorkerProviderHostInfoPtr info,
+ base::WeakPtr<ServiceWorkerContextCore> context)
: client_uuid_(base::GenerateGUID()),
create_time_(base::TimeTicks::Now()),
render_process_id_(render_process_id),
render_thread_id_(kDocumentMainThreadId),
info_(std::move(info)),
context_(context),
- dispatcher_host_(dispatcher_host),
allow_association_(true),
binding_(this),
interface_provider_binding_(this) {
- DCHECK_NE(blink::mojom::ServiceWorkerProviderType::kUnknown, info_.type);
+ DCHECK_NE(blink::mojom::ServiceWorkerProviderType::kUnknown, info_->type);
- if (info_.type ==
+ 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
@@ -251,23 +299,21 @@ ServiceWorkerProviderHost::ServiceWorkerProviderHost(
context_->RegisterProviderHostByClientID(client_uuid_, this);
// |client_| and |binding_| will be bound on CompleteNavigationInitialized
- // (providers created for navigation) or on
- // CompleteStartWorkerPreparation (providers for service workers).
- if (!info_.client_ptr_info.is_valid() && !info_.host_request.is_pending())
+ // (providers created for navigation) or in
+ // PreCreateForController (providers for service workers).
+ // TODO(falken): All provider types should just set the bindings here for
+ // consistency.
+ if (!info_->client_ptr_info.is_valid() && !info_->host_request.is_pending())
return;
- container_.Bind(std::move(info_.client_ptr_info));
- binding_.Bind(std::move(info_.host_request));
+ container_.Bind(std::move(info_->client_ptr_info));
+ binding_.Bind(std::move(info_->host_request));
binding_.set_connection_error_handler(base::BindOnce(
- &RemoveProviderHost, context_, render_process_id, info_.provider_id));
+ &RemoveProviderHost, context_, render_process_id, info_->provider_id));
}
ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
- // TODO(crbug.com/838410): The CHECKs are temporary debugging for the linked
- // bug.
- CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- CHECK(!in_dtor_);
- in_dtor_ = true;
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (context_)
context_->UnregisterProviderHostByClientID(client_uuid_);
@@ -282,16 +328,23 @@ ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
// ServiceWorkerRegistrationObjectHosts owned by |this|. Otherwise, this
// destructor can trigger their Mojo connection error handlers, which would
// call back into halfway destroyed |this|. This is because they are
- // associated with the ServiceWorkerEventDispatcher interface, which can
- // be destroyed while in this destructor (|running_hosted_version_|'s
- // |event_dispatcher_|). See https://crbug.com/854993.
- handles_.clear();
+ // associated with the ServiceWorker interface, which can be destroyed while
+ // in this destructor (|running_hosted_version_|'s |event_dispatcher_|). See
+ // https://crbug.com/854993.
+ service_worker_object_hosts_.clear();
registration_object_hosts_.clear();
+
+ // This host may be destroyed before it received the anticipated
+ // HintToUpdateServiceWorker IPC from the renderer. This can occur on
+ // navigation failure or if the frame closed soon after navigation. The
+ // PendingVersionUpdate objects decrement the hint count upon destruction.
+ DCHECK(versions_to_update_.empty() ||
+ blink::ServiceWorkerUtils::IsServicificationEnabled());
}
int ServiceWorkerProviderHost::frame_id() const {
- if (info_.type == blink::mojom::ServiceWorkerProviderType::kForWindow)
- return info_.route_id;
+ if (info_->type == blink::mojom::ServiceWorkerProviderType::kForWindow)
+ return info_->route_id;
return MSG_ROUTING_NONE;
}
@@ -314,6 +367,24 @@ bool ServiceWorkerProviderHost::IsContextSecureForServiceWorker() const {
return schemes.find(document_url().scheme()) != schemes.end();
}
+blink::mojom::ControllerServiceWorkerMode
+ServiceWorkerProviderHost::GetControllerMode() const {
+ if (!controller_)
+ return blink::mojom::ControllerServiceWorkerMode::kNoController;
+ switch (controller_->fetch_handler_existence()) {
+ case ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST:
+ return blink::mojom::ControllerServiceWorkerMode::kNoFetchEventHandler;
+ case ServiceWorkerVersion::FetchHandlerExistence::EXISTS:
+ return blink::mojom::ControllerServiceWorkerMode::kControlled;
+ case ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN:
+ // UNKNOWN means the controller is still installing. It's not possible to
+ // have a controller that hasn't finished installing.
+ NOTREACHED();
+ }
+ NOTREACHED();
+ return blink::mojom::ControllerServiceWorkerMode::kNoController;
+}
+
void ServiceWorkerProviderHost::OnVersionAttributesChanged(
ServiceWorkerRegistration* registration,
ChangedVersionAttributesMask changed_mask,
@@ -359,7 +430,7 @@ void ServiceWorkerProviderHost::OnSkippedWaiting(
mojom::ControllerServiceWorkerPtr
ServiceWorkerProviderHost::GetControllerServiceWorkerPtr() {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
DCHECK(controller_);
if (controller_->fetch_handler_existence() ==
ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST) {
@@ -405,16 +476,24 @@ void ServiceWorkerProviderHost::SetControllerVersionAttribute(
// SetController message should be sent only for clients.
DCHECK(IsProviderForClient());
+ // If there is no connection to the renderer yet, |this| is hosting a reserved
+ // client undergoing navigation. The controller will be sent on navigation
+ // commit. See CommitNavigation in frame.mojom.
+ if (!container_.is_bound()) {
+ DCHECK_EQ(blink::mojom::ServiceWorkerClientType::kWindow, client_type());
+ DCHECK(!is_execution_ready_);
+ return;
+ }
SendSetControllerServiceWorker(notify_controllerchange);
}
bool ServiceWorkerProviderHost::IsProviderForServiceWorker() const {
- return info_.type ==
+ return info_->type ==
blink::mojom::ServiceWorkerProviderType::kForServiceWorker;
}
bool ServiceWorkerProviderHost::IsProviderForClient() const {
- switch (info_.type) {
+ switch (info_->type) {
case blink::mojom::ServiceWorkerProviderType::kForWindow:
case blink::mojom::ServiceWorkerProviderType::kForSharedWorker:
return true;
@@ -423,13 +502,13 @@ bool ServiceWorkerProviderHost::IsProviderForClient() const {
case blink::mojom::ServiceWorkerProviderType::kUnknown:
break;
}
- NOTREACHED() << info_.type;
+ NOTREACHED() << info_->type;
return false;
}
blink::mojom::ServiceWorkerClientType ServiceWorkerProviderHost::client_type()
const {
- switch (info_.type) {
+ switch (info_->type) {
case blink::mojom::ServiceWorkerProviderType::kForWindow:
return blink::mojom::ServiceWorkerClientType::kWindow;
case blink::mojom::ServiceWorkerProviderType::kForSharedWorker:
@@ -438,7 +517,7 @@ blink::mojom::ServiceWorkerClientType ServiceWorkerProviderHost::client_type()
case blink::mojom::ServiceWorkerProviderType::kUnknown:
break;
}
- NOTREACHED() << info_.type;
+ NOTREACHED() << info_->type;
return blink::mojom::ServiceWorkerClientType::kWindow;
}
@@ -504,9 +583,11 @@ void ServiceWorkerProviderHost::RemoveServiceWorkerRegistrationObjectHost(
registration_object_hosts_.erase(registration_id);
}
-void ServiceWorkerProviderHost::RemoveServiceWorkerHandle(int64_t version_id) {
- DCHECK(base::ContainsKey(handles_, version_id));
- handles_.erase(version_id);
+void ServiceWorkerProviderHost::RemoveServiceWorkerObjectHost(
+ int64_t version_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ DCHECK(base::ContainsKey(service_worker_object_hosts_, version_id));
+ service_worker_object_hosts_.erase(version_id);
}
bool ServiceWorkerProviderHost::AllowServiceWorker(const GURL& scope) {
@@ -522,6 +603,17 @@ void ServiceWorkerProviderHost::NotifyControllerLost() {
SetControllerVersionAttribute(nullptr, true /* notify_controllerchange */);
}
+void ServiceWorkerProviderHost::AddServiceWorkerToUpdate(
+ scoped_refptr<ServiceWorkerVersion> version) {
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
+ // This is only called for windows now, but it should be called for all
+ // clients someday.
+ DCHECK_EQ(provider_type(),
+ blink::mojom::ServiceWorkerProviderType::kForWindow);
+
+ versions_to_update_.emplace(std::move(version));
+}
+
std::unique_ptr<ServiceWorkerRequestHandler>
ServiceWorkerProviderHost::CreateRequestHandler(
network::mojom::FetchRequestMode request_mode,
@@ -566,20 +658,21 @@ ServiceWorkerProviderHost::CreateRequestHandler(
return std::unique_ptr<ServiceWorkerRequestHandler>();
}
-base::WeakPtr<ServiceWorkerHandle>
-ServiceWorkerProviderHost::GetOrCreateServiceWorkerHandle(
- ServiceWorkerVersion* version) {
+base::WeakPtr<ServiceWorkerObjectHost>
+ServiceWorkerProviderHost::GetOrCreateServiceWorkerObjectHost(
+ scoped_refptr<ServiceWorkerVersion> version) {
if (!context_ || !version)
return nullptr;
const int64_t version_id = version->version_id();
- auto existing_handle = handles_.find(version_id);
- if (existing_handle != handles_.end())
- return existing_handle->second->AsWeakPtr();
+ auto existing_object_host = service_worker_object_hosts_.find(version_id);
+ if (existing_object_host != service_worker_object_hosts_.end())
+ return existing_object_host->second->AsWeakPtr();
- handles_[version_id] =
- std::make_unique<ServiceWorkerHandle>(context_, this, version);
- return handles_[version_id]->AsWeakPtr();
+ service_worker_object_hosts_[version_id] =
+ std::make_unique<ServiceWorkerObjectHost>(context_, this,
+ std::move(version));
+ return service_worker_object_hosts_[version_id]->AsWeakPtr();
}
bool ServiceWorkerProviderHost::CanAssociateRegistration(
@@ -597,22 +690,27 @@ void ServiceWorkerProviderHost::PostMessageToClient(
ServiceWorkerVersion* version,
blink::TransferableMessage message) {
DCHECK(IsProviderForClient());
- if (!dispatcher_host_)
- return;
blink::mojom::ServiceWorkerObjectInfoPtr info;
- base::WeakPtr<ServiceWorkerHandle> handle =
- GetOrCreateServiceWorkerHandle(version);
- if (handle)
- info = handle->CreateCompleteObjectInfoToSend();
+ base::WeakPtr<ServiceWorkerObjectHost> object_host =
+ GetOrCreateServiceWorkerObjectHost(version);
+ if (object_host)
+ info = object_host->CreateCompleteObjectInfoToSend();
container_->PostMessageToClient(std::move(info), std::move(message));
}
void ServiceWorkerProviderHost::CountFeature(blink::mojom::WebFeature feature) {
- if (!dispatcher_host_)
- return;
// CountFeature message should be sent only for clients.
DCHECK(IsProviderForClient());
+ // If there is no connection to the renderer yet, |this| is hosting a reserved
+ // client undergoing navigation. The use counter will be sent correctly in
+ // CompleteNavigationInitialized() later.
+ if (!container_.is_bound()) {
+ DCHECK_EQ(blink::mojom::ServiceWorkerClientType::kWindow, client_type());
+ DCHECK(!is_execution_ready_);
+ return;
+ }
+
container_->CountFeature(feature);
}
@@ -630,28 +728,26 @@ void ServiceWorkerProviderHost::ClaimedByRegistration(
void ServiceWorkerProviderHost::CompleteNavigationInitialized(
int process_id,
- ServiceWorkerProviderHostInfo info,
- base::WeakPtr<ServiceWorkerDispatcherHost> dispatcher_host) {
+ mojom::ServiceWorkerProviderHostInfoPtr info) {
DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_);
- DCHECK_EQ(blink::mojom::ServiceWorkerProviderType::kForWindow, info_.type);
+ DCHECK_EQ(blink::mojom::ServiceWorkerProviderType::kForWindow, info_->type);
DCHECK_EQ(kDocumentMainThreadId, render_thread_id_);
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id);
- DCHECK_EQ(info_.provider_id, info.provider_id);
- DCHECK_NE(MSG_ROUTING_NONE, info.route_id);
+ DCHECK_EQ(info_->provider_id, info->provider_id);
+ DCHECK_NE(MSG_ROUTING_NONE, info->route_id);
is_execution_ready_ = true;
// Connect with the mojom::ServiceWorkerContainer on the renderer.
DCHECK(!container_.is_bound());
DCHECK(!binding_.is_bound());
- container_.Bind(std::move(info.client_ptr_info));
- binding_.Bind(std::move(info.host_request));
+ container_.Bind(std::move(info->client_ptr_info));
+ binding_.Bind(std::move(info->host_request));
binding_.set_connection_error_handler(
base::BindOnce(&RemoveProviderHost, context_, process_id, provider_id()));
- info_.route_id = info.route_id;
+ info_->route_id = info->route_id;
render_process_id_ = process_id;
- dispatcher_host_ = dispatcher_host;
// Now that there is a connection with the renderer-side provider, initialize
// the handle for ServiceWorkerContainer#controller, and send the controller
@@ -668,34 +764,21 @@ void ServiceWorkerProviderHost::CompleteNavigationInitialized(
mojom::ServiceWorkerProviderInfoForStartWorkerPtr
ServiceWorkerProviderHost::CompleteStartWorkerPreparation(
int process_id,
- scoped_refptr<ServiceWorkerVersion> hosted_version,
- scoped_refptr<network::SharedURLLoaderFactory> loader_factory) {
+ scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info) {
DCHECK(context_);
DCHECK_EQ(kInvalidEmbeddedWorkerThreadId, render_thread_id_);
DCHECK_EQ(ChildProcessHost::kInvalidUniqueID, render_process_id_);
DCHECK_EQ(blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
provider_type());
- DCHECK(!running_hosted_version_);
+ DCHECK_EQ(provider_info->provider_id, provider_id());
DCHECK_NE(ChildProcessHost::kInvalidUniqueID, process_id);
-
- running_hosted_version_ = std::move(hosted_version);
-
- ServiceWorkerDispatcherHost* dispatcher_host =
- context_->GetDispatcherHost(process_id);
- DCHECK(dispatcher_host);
render_process_id_ = process_id;
- dispatcher_host_ = dispatcher_host->AsWeakPtr();
-
- // Initialize provider_info.
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info =
- mojom::ServiceWorkerProviderInfoForStartWorker::New();
- provider_info->provider_id = provider_id();
- provider_info->client_request = mojo::MakeRequest(&container_);
- network::mojom::URLLoaderFactoryAssociatedPtrInfo
- script_loader_factory_ptr_info;
- if (ServiceWorkerUtils::IsServicificationEnabled()) {
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ network::mojom::URLLoaderFactoryAssociatedPtrInfo
+ script_loader_factory_ptr_info;
mojo::MakeStrongAssociatedBinding(
std::make_unique<ServiceWorkerScriptLoaderFactory>(
context_, AsWeakPtr(), std::move(loader_factory)),
@@ -704,10 +787,6 @@ ServiceWorkerProviderHost::CompleteStartWorkerPreparation(
std::move(script_loader_factory_ptr_info);
}
- binding_.Bind(mojo::MakeRequest(&provider_info->host_ptr_info));
- 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)));
@@ -751,7 +830,7 @@ void ServiceWorkerProviderHost::ReturnRegistrationForReadyIfNeeded() {
TRACE_EVENT_ASYNC_END1("ServiceWorker",
"ServiceWorkerProviderHost::GetRegistrationForReady",
this, "Registration ID", registration->id());
- if (!dispatcher_host_ || !IsContextAlive()) {
+ if (!IsContextAlive()) {
// Here no need to run or destroy |get_ready_callback_|, which will destroy
// together with |binding_| when |this| destroys.
return;
@@ -768,8 +847,7 @@ bool ServiceWorkerProviderHost::IsContextAlive() {
void ServiceWorkerProviderHost::SendSetControllerServiceWorker(
bool notify_controllerchange) {
- if (!dispatcher_host_)
- return;
+ DCHECK(IsProviderForClient());
auto controller_info = mojom::ControllerServiceWorkerInfo::New();
controller_info->client_id = client_uuid();
@@ -783,21 +861,25 @@ void ServiceWorkerProviderHost::SendSetControllerServiceWorker(
DCHECK(associated_registration_);
DCHECK_EQ(associated_registration_->active_version(), controller_.get());
+ controller_info->mode = GetControllerMode();
+
+ // S13nServiceWorker: Pass an endpoint for the client to talk to this
+ // controller.
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
+ controller_info->endpoint = GetControllerServiceWorkerPtr().PassInterface();
+
// Set the info for the JavaScript ServiceWorkerContainer#controller object.
- base::WeakPtr<ServiceWorkerHandle> handle =
- GetOrCreateServiceWorkerHandle(controller_.get());
- if (handle)
- controller_info->object_info = handle->CreateCompleteObjectInfoToSend();
+ base::WeakPtr<ServiceWorkerObjectHost> object_host =
+ GetOrCreateServiceWorkerObjectHost(controller_);
+ if (object_host)
+ controller_info->object_info =
+ object_host->CreateCompleteObjectInfoToSend();
// Populate used features for UseCounter purposes.
std::vector<blink::mojom::WebFeature> used_features;
for (const blink::mojom::WebFeature feature : controller_->used_features())
used_features.push_back(feature);
- // S13nServiceWorker: Pass an endpoint for the client to talk to this
- // controller.
- if (ServiceWorkerUtils::IsServicificationEnabled())
- controller_info->endpoint = GetControllerServiceWorkerPtr().PassInterface();
container_->SetController(std::move(controller_info), used_features,
notify_controllerchange);
@@ -837,13 +919,14 @@ void ServiceWorkerProviderHost::Register(
void ServiceWorkerProviderHost::RegistrationComplete(
RegisterCallback callback,
int64_t trace_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id) {
TRACE_EVENT_ASYNC_END2("ServiceWorker", "ServiceWorkerProviderHost::Register",
- trace_id, "Status", status, "Registration ID",
- registration_id);
- if (!dispatcher_host_ || !IsContextAlive()) {
+ trace_id, "Status",
+ blink::ServiceWorkerStatusToString(status),
+ "Registration ID", registration_id);
+ if (!IsContextAlive()) {
std::move(callback).Run(
blink::mojom::ServiceWorkerErrorType::kAbort,
std::string(kServiceWorkerRegisterErrorPrefix) +
@@ -852,7 +935,7 @@ void ServiceWorkerProviderHost::RegistrationComplete(
return;
}
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::string error_message;
blink::mojom::ServiceWorkerErrorType error_type;
GetServiceWorkerErrorTypeForRegistration(status, status_message,
@@ -934,14 +1017,14 @@ void ServiceWorkerProviderHost::GetRegistrations(
void ServiceWorkerProviderHost::GetRegistrationComplete(
GetRegistrationCallback callback,
int64_t trace_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
TRACE_EVENT_ASYNC_END2(
"ServiceWorker", "ServiceWorkerProviderHost::GetRegistration", trace_id,
- "Status", status, "Registration ID",
+ "Status", blink::ServiceWorkerStatusToString(status), "Registration ID",
registration ? registration->id()
: blink::mojom::kInvalidServiceWorkerRegistrationId);
- if (!dispatcher_host_ || !IsContextAlive()) {
+ if (!IsContextAlive()) {
std::move(callback).Run(
blink::mojom::ServiceWorkerErrorType::kAbort,
std::string(kServiceWorkerGetRegistrationErrorPrefix) +
@@ -950,7 +1033,8 @@ void ServiceWorkerProviderHost::GetRegistrationComplete(
return;
}
- if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
+ if (status != blink::ServiceWorkerStatusCode::kOk &&
+ status != blink::ServiceWorkerStatusCode::kErrorNotFound) {
std::string error_message;
blink::mojom::ServiceWorkerErrorType error_type;
GetServiceWorkerErrorTypeForRegistration(status, std::string(), &error_type,
@@ -961,9 +1045,10 @@ void ServiceWorkerProviderHost::GetRegistrationComplete(
return;
}
- DCHECK(status != SERVICE_WORKER_OK || registration);
+ DCHECK(status != blink::ServiceWorkerStatusCode::kOk || registration);
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
- if (status == SERVICE_WORKER_OK && !registration->is_uninstalling())
+ if (status == blink::ServiceWorkerStatusCode::kOk &&
+ !registration->is_uninstalling())
info = CreateServiceWorkerRegistrationObjectInfo(std::move(registration));
std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone,
@@ -973,13 +1058,13 @@ void ServiceWorkerProviderHost::GetRegistrationComplete(
void ServiceWorkerProviderHost::GetRegistrationsComplete(
GetRegistrationsCallback callback,
int64_t trace_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<scoped_refptr<ServiceWorkerRegistration>>&
registrations) {
- TRACE_EVENT_ASYNC_END1("ServiceWorker",
- "ServiceWorkerProviderHost::GetRegistrations",
- trace_id, "Status", status);
- if (!dispatcher_host_ || !IsContextAlive()) {
+ TRACE_EVENT_ASYNC_END1(
+ "ServiceWorker", "ServiceWorkerProviderHost::GetRegistrations", trace_id,
+ "Status", blink::ServiceWorkerStatusToString(status));
+ if (!IsContextAlive()) {
std::move(callback).Run(
blink::mojom::ServiceWorkerErrorType::kAbort,
std::string(kServiceWorkerGetRegistrationsErrorPrefix) +
@@ -988,7 +1073,7 @@ void ServiceWorkerProviderHost::GetRegistrationsComplete(
return;
}
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::string error_message;
blink::mojom::ServiceWorkerErrorType error_type;
GetServiceWorkerErrorTypeForRegistration(status, std::string(), &error_type,
@@ -1036,9 +1121,9 @@ void ServiceWorkerProviderHost::GetRegistrationForReady(
void ServiceWorkerProviderHost::StartControllerComplete(
mojom::ControllerServiceWorkerRequest controller_request,
- ServiceWorkerStatusCode status) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
- if (status == SERVICE_WORKER_OK)
+ blink::ServiceWorkerStatusCode status) {
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
+ if (status == blink::ServiceWorkerStatusCode::kOk)
controller_->controller()->Clone(std::move(controller_request));
}
@@ -1046,10 +1131,10 @@ void ServiceWorkerProviderHost::EnsureControllerServiceWorker(
mojom::ControllerServiceWorkerRequest controller_request,
mojom::ControllerServiceWorkerPurpose purpose) {
// TODO(kinuko): Log the reasons we drop the request.
- if (!dispatcher_host_ || !IsContextAlive() || !controller_)
+ if (!IsContextAlive() || !controller_)
return;
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
controller_->RunAfterStartWorker(
PurposeToEventType(purpose),
base::BindOnce(&ServiceWorkerProviderHost::StartControllerComplete,
@@ -1058,7 +1143,7 @@ void ServiceWorkerProviderHost::EnsureControllerServiceWorker(
void ServiceWorkerProviderHost::CloneForWorker(
mojom::ServiceWorkerContainerHostRequest container_host_request) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
bindings_for_worker_threads_.AddBinding(this,
std::move(container_host_request));
}
@@ -1067,6 +1152,17 @@ void ServiceWorkerProviderHost::Ping(PingCallback callback) {
std::move(callback).Run();
}
+void ServiceWorkerProviderHost::HintToUpdateServiceWorker() {
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
+ if (!IsProviderForClient()) {
+ mojo::ReportBadMessage("SWPH_HTUSW_NOT_CLIENT");
+ return;
+ }
+
+ // The destructors notify the ServiceWorkerVersions to update.
+ versions_to_update_.clear();
+}
+
bool ServiceWorkerProviderHost::IsValidRegisterMessage(
const GURL& script_url,
const blink::mojom::ServiceWorkerRegistrationOptions& options,
@@ -1175,7 +1271,7 @@ bool ServiceWorkerProviderHost::CanServeContainerHostMethods(
const GURL& scope,
const char* error_prefix,
Args... args) {
- if (!dispatcher_host_ || !IsContextAlive()) {
+ if (!IsContextAlive()) {
std::move(*callback).Run(
blink::mojom::ServiceWorkerErrorType::kAbort,
std::string(error_prefix) +
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 9b69c149e3a..ded291f894a 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host.h
+++ b/chromium/content/browser/service_worker/service_worker_provider_host.h
@@ -19,11 +19,11 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
-#include "content/browser/service_worker/service_worker_handle.h"
+#include "content/browser/service_worker/service_worker_object_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_container.mojom.h"
-#include "content/common/service_worker/service_worker_provider_host_info.h"
+#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
@@ -40,8 +40,8 @@ namespace network {
class ResourceRequestBody;
}
-namespace service_worker_handle_unittest {
-class ServiceWorkerHandleTest;
+namespace service_worker_object_host_unittest {
+class ServiceWorkerObjectHostTest;
}
namespace storage {
@@ -51,7 +51,6 @@ class BlobStorageContext;
namespace content {
class ServiceWorkerContextCore;
-class ServiceWorkerDispatcherHost;
class ServiceWorkerRegistrationObjectHost;
class ServiceWorkerRequestHandler;
class ServiceWorkerVersion;
@@ -147,11 +146,16 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
bool are_ancestors_secure,
const WebContentsGetter& web_contents_getter);
- // Creates a ServiceWorkerProviderHost for a service worker execution context.
- // Information about this provider host is passed down to the service worker
- // via StartWorker message.
- static std::unique_ptr<ServiceWorkerProviderHost> PreCreateForController(
- base::WeakPtr<ServiceWorkerContextCore> context);
+ // Used for starting a service worker. Returns a provider host for the service
+ // worker and partially fills |out_provider_info|. The host stays alive as
+ // long as this info stays alive (namely, as long as
+ // |out_provider_info->host_ptr_info| stays alive).
+ // CompleteStartWorkerPreparation() must be called later to get a full info to
+ // send to the renderer.
+ static base::WeakPtr<ServiceWorkerProviderHost> PreCreateForController(
+ base::WeakPtr<ServiceWorkerContextCore> context,
+ scoped_refptr<ServiceWorkerVersion> version,
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr* out_provider_info);
// S13nServiceWorker:
// Used for starting a shared worker. Returns a provider host for the shared
@@ -168,23 +172,22 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// |process_id|.
static std::unique_ptr<ServiceWorkerProviderHost> Create(
int process_id,
- ServiceWorkerProviderHostInfo info,
- base::WeakPtr<ServiceWorkerContextCore> context,
- base::WeakPtr<ServiceWorkerDispatcherHost> dispatcher_host);
+ mojom::ServiceWorkerProviderHostInfoPtr info,
+ base::WeakPtr<ServiceWorkerContextCore> context);
~ServiceWorkerProviderHost() override;
const std::string& client_uuid() const { return client_uuid_; }
base::TimeTicks create_time() const { return create_time_; }
int process_id() const { return render_process_id_; }
- int provider_id() const { return info_.provider_id; }
+ int provider_id() const { return info_->provider_id; }
int frame_id() const;
- int route_id() const { return info_.route_id; }
+ int route_id() const { return info_->route_id; }
const WebContentsGetter& web_contents_getter() const {
return web_contents_getter_;
}
- bool is_parent_frame_secure() const { return info_.is_parent_frame_secure; }
+ bool is_parent_frame_secure() const { return info_->is_parent_frame_secure; }
// Returns whether this provider host is secure enough to have a service
// worker controller.
@@ -196,6 +199,10 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// security, so they must be set properly before calling this function.
bool IsContextSecureForServiceWorker() const;
+ // For service worker clients. Describes whether the client has a controller
+ // and if it has a fetch event handler.
+ blink::mojom::ControllerServiceWorkerMode GetControllerMode() const;
+
// Returns this provider's controller. The controller is typically the same as
// active_version() but can differ in the following cases:
// (1) The client was created before the registration existed or had an active
@@ -244,7 +251,7 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// CompleteStartWorkerPreparation() is called).
ServiceWorkerVersion* running_hosted_version() const {
DCHECK(!running_hosted_version_ ||
- info_.type ==
+ info_->type ==
blink::mojom::ServiceWorkerProviderType::kForServiceWorker);
return running_hosted_version_.get();
}
@@ -291,7 +298,8 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// is in scope of all |matching_registrations_|.
// |document_url_| is the service worker script URL if this is for a
// service worker execution context. It will be used when creating
- // ServiceWorkerHandle or handling ServiceWorkerRegistration#{*} calls etc.
+ // ServiceWorkerObjectHost or handling ServiceWorkerRegistration#{*} calls
+ // etc.
// TODO(leonhsl): We should rename |document_url_| to something more
// appropriate and/or split this class into one for clients vs one for service
// workers.
@@ -305,7 +313,7 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
const GURL& topmost_frame_url() const;
blink::mojom::ServiceWorkerProviderType provider_type() const {
- return info_.type;
+ return info_->type;
}
bool IsProviderForServiceWorker() const;
bool IsProviderForClient() const;
@@ -352,12 +360,11 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
CreateServiceWorkerRegistrationObjectInfo(
scoped_refptr<ServiceWorkerRegistration> registration);
- // Returns a ServiceWorkerHandle instance for |version| for this provider
+ // Returns a ServiceWorkerObjectHost instance for |version| for this provider
// host. A new instance is created if one does not already exist.
- // TODO(leonhsl): Make |version| be a scoped_refptr because we'll take its
- // ownership.
- base::WeakPtr<ServiceWorkerHandle> GetOrCreateServiceWorkerHandle(
- ServiceWorkerVersion* version);
+ // ServiceWorkerObjectHost will have an ownership of the |version|.
+ base::WeakPtr<ServiceWorkerObjectHost> GetOrCreateServiceWorkerObjectHost(
+ scoped_refptr<ServiceWorkerVersion> version);
// Returns true if |registration| can be associated with this provider.
bool CanAssociateRegistration(ServiceWorkerRegistration* registration);
@@ -386,15 +393,16 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// provider hosts used for navigation requests.
void CompleteNavigationInitialized(
int process_id,
- ServiceWorkerProviderHostInfo info,
- base::WeakPtr<ServiceWorkerDispatcherHost> dispatcher_host);
+ mojom::ServiceWorkerProviderHostInfoPtr info);
// For service worker execution contexts. Completes initialization of this
// provider host. It is called once a renderer process has been found to host
// the worker. Returns the info needed for creating a provider on the renderer
- // which will be connected to this provider host. This instance will take the
- // reference to |hosted_version|, so be careful not to create a reference
- // cycle.
+ // which will be connected to this provider host.
+ //
+ // |provider_info| should be the info returned by PreCreateForController(),
+ // which is partially filled out. This function returns it after
+ // filling it out completely.
//
// S13nServiceWorker:
// |loader_factory| is the factory to use for "network" requests for the
@@ -404,8 +412,8 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
mojom::ServiceWorkerProviderInfoForStartWorkerPtr
CompleteStartWorkerPreparation(
int process_id,
- scoped_refptr<ServiceWorkerVersion> hosted_version,
- scoped_refptr<network::SharedURLLoaderFactory> loader_factory);
+ scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
+ mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info);
// Called when the shared worker main script resource has finished loading.
// After this is called, is_execution_ready() returns true.
@@ -422,8 +430,8 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// |registration_id|.
void RemoveServiceWorkerRegistrationObjectHost(int64_t registration_id);
- // Removes the ServiceWorkerHandle corresponding to |version_id|.
- void RemoveServiceWorkerHandle(int64_t version_id);
+ // Removes the ServiceWorkerObjectHost corresponding to |version_id|.
+ void RemoveServiceWorkerObjectHost(int64_t version_id);
// Calls ContentBrowserClient::AllowServiceWorker(). Returns true if content
// settings allows service workers to run at |scope|. If this provider is for
@@ -436,6 +444,26 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// cache.
void NotifyControllerLost();
+ // S13nServiceWorker:
+ // For service worker clients. Called when |version| is the active worker upon
+ // the main resource request for this client. Remembers |version| as needing
+ // a Soft Update. To avoid affecting page load performance, the update occurs
+ // when we get a HintToUpdateServiceWorker message from the renderer, or when
+ // |this| is destroyed before receiving that message.
+ //
+ // Corresponds to the Handle Fetch algorithm:
+ // "If request is a non-subresource request...invoke Soft Update algorithm
+ // with registration."
+ // https://w3c.github.io/ServiceWorker/#on-fetch-request-algorithm
+ //
+ // This can be called multiple times due to redirects during a main resource
+ // load. All service workers are updated.
+ //
+ // For non-S13nServiceWorker: The update logic is controlled entirely by
+ // ServiceWorkerControlleeRequestHandler, which sees all resource request
+ // activity and schedules an update at a convenient time.
+ void AddServiceWorkerToUpdate(scoped_refptr<ServiceWorkerVersion> version);
+
bool is_execution_ready() const { return is_execution_ready_; }
private:
@@ -443,7 +471,7 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
friend class ServiceWorkerProviderHostTest;
friend class ServiceWorkerWriteToCacheJobTest;
friend class ServiceWorkerContextRequestHandlerTest;
- friend class service_worker_handle_unittest::ServiceWorkerHandleTest;
+ friend class service_worker_object_host_unittest::ServiceWorkerObjectHostTest;
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest, Update_SameScript);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerWriteToCacheJobTest,
Update_SameSizeScript);
@@ -467,11 +495,9 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
FRIEND_TEST_ALL_PREFIXES(BackgroundSyncManagerTest,
RegisterWithoutLiveSWRegistration);
- ServiceWorkerProviderHost(
- int process_id,
- ServiceWorkerProviderHostInfo info,
- base::WeakPtr<ServiceWorkerContextCore> context,
- base::WeakPtr<ServiceWorkerDispatcherHost> dispatcher_host);
+ ServiceWorkerProviderHost(int process_id,
+ mojom::ServiceWorkerProviderHostInfoPtr info,
+ base::WeakPtr<ServiceWorkerContextCore> context);
// ServiceWorkerRegistration::Listener overrides.
void OnVersionAttributesChanged(
@@ -519,31 +545,32 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
void CloneForWorker(
mojom::ServiceWorkerContainerHostRequest container_host_request) override;
void Ping(PingCallback callback) override;
+ void HintToUpdateServiceWorker() override;
// Callback for ServiceWorkerContextCore::RegisterServiceWorker().
void RegistrationComplete(RegisterCallback callback,
int64_t trace_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id);
// Callback for ServiceWorkerStorage::FindRegistrationForDocument().
void GetRegistrationComplete(
GetRegistrationCallback callback,
int64_t trace_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
// Callback for ServiceWorkerStorage::GetRegistrationsForOrigin().
void GetRegistrationsComplete(
GetRegistrationsCallback callback,
int64_t trace_id,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<scoped_refptr<ServiceWorkerRegistration>>&
registrations);
// Callback for ServiceWorkerVersion::RunAfterStartWorker()
void StartControllerComplete(
mojom::ControllerServiceWorkerRequest controller_request,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
bool IsValidRegisterMessage(
const GURL& script_url,
@@ -580,7 +607,7 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// Otherwise, |kDocumentMainThreadId|.
int render_thread_id_;
- ServiceWorkerProviderHostInfo info_;
+ mojom::ServiceWorkerProviderHostInfoPtr info_;
// Only set when this object is pre-created for a navigation. It indicates the
// tab where the navigation occurs.
@@ -607,12 +634,12 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
std::unique_ptr<ServiceWorkerRegistrationObjectHost>>
registration_object_hosts_;
- // Contains all ServiceWorkerHandle instances corresponding to
+ // Contains all ServiceWorkerObjectHost instances corresponding to
// the service worker JavaScript objects for the hosted execution
// context (service worker global scope or service worker client) in the
// renderer process.
- std::map<int64_t /* version_id */, std::unique_ptr<ServiceWorkerHandle>>
- handles_;
+ std::map<int64_t /* version_id */, std::unique_ptr<ServiceWorkerObjectHost>>
+ service_worker_object_hosts_;
// The ready() promise is only allowed to be created once.
// |get_ready_callback_| has three states:
@@ -627,22 +654,11 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// ServiceWorkerContainer#controller).
scoped_refptr<ServiceWorkerVersion> controller_;
// For service worker execution contexts. The ServiceWorkerVersion of the
- // service worker this is a provider for. This is nullptr if the service
- // worker is still being started up (until CompleteStartWorkerPreparation() is
- // called).
+ // service worker this is a provider for.
scoped_refptr<ServiceWorkerVersion> running_hosted_version_;
base::WeakPtr<ServiceWorkerContextCore> context_;
- // |dispatcher_host_| is expected to outlive |this| because it destroys
- // |this| upon destruction. However, it may be null in some cases:
- // 1) In some tests.
- // 2) Navigations 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.
- base::WeakPtr<ServiceWorkerDispatcherHost> dispatcher_host_;
-
bool allow_association_;
// |container_| is the Mojo endpoint to the renderer-side
@@ -677,8 +693,11 @@ class CONTENT_EXPORT ServiceWorkerProviderHost
// redirects.
bool is_execution_ready_ = false;
- // TODO(crbug.com/838410): Temporary debugging for the linked bug.
- bool in_dtor_ = false;
+ // For service worker clients. The service workers in the chain of redirects
+ // during the main resource request for this client. These workers should be
+ // updated "soon". See AddServiceWorkerToUpdate() documentation.
+ class PendingUpdateVersion;
+ base::flat_set<PendingUpdateVersion> versions_to_update_;
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 d5a07710e2f..7cc8b71f605 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
@@ -10,6 +10,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
+#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
@@ -27,8 +28,9 @@
#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 "mojo/core/embedder/embedder.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
@@ -73,7 +75,7 @@ class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient {
} // namespace
-class ServiceWorkerProviderHostTest : public testing::Test {
+class ServiceWorkerProviderHostTest : public testing::TestWithParam<bool> {
protected:
ServiceWorkerProviderHostTest()
: thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
@@ -83,10 +85,18 @@ class ServiceWorkerProviderHostTest : public testing::Test {
~ServiceWorkerProviderHostTest() override {}
void SetUp() override {
+ if (IsServiceWorkerServicificationEnabled()) {
+ scoped_feature_list_.InitAndEnableFeature(
+ blink::features::kServiceWorkerServicification);
+ } else {
+ scoped_feature_list_.InitAndDisableFeature(
+ blink::features::kServiceWorkerServicification);
+ }
+
old_content_browser_client_ =
SetBrowserClientForTesting(&test_content_browser_client_);
ResetSchemesAndOriginsWhitelist();
- mojo::edk::SetDefaultProcessErrorCallback(base::Bind(
+ mojo::core::SetDefaultProcessErrorCallback(base::Bind(
&ServiceWorkerProviderHostTest::OnMojoError, base::Unretained(this)));
helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
@@ -117,8 +127,8 @@ 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());
+ mojo::core::SetDefaultProcessErrorCallback(
+ mojo::core::ProcessErrorCallback());
}
ServiceWorkerRemoteProviderEndpoint PrepareServiceWorkerProviderHost(
@@ -162,21 +172,15 @@ class ServiceWorkerProviderHostTest : public testing::Test {
}
void FinishNavigation(ServiceWorkerProviderHost* host,
- ServiceWorkerProviderHostInfo info) {
+ mojom::ServiceWorkerProviderHostInfoPtr info) {
// In production code, the loader/request handler does this.
host->SetDocumentUrl(GURL("https://www.example.com/page"));
host->SetTopmostFrameUrl(GURL("https://www.example.com/page"));
// In production code, the OnProviderCreated IPC is received which
// does this.
- std::unique_ptr<ServiceWorkerProviderHost> owned_host =
- helper_->context()->ReleaseProviderHost(host->process_id(),
- host->provider_id());
- host->CompleteNavigationInitialized(
- helper_->mock_render_process_id(), std::move(info),
- helper_->GetDispatcherHostForProcess(helper_->mock_render_process_id())
- ->AsWeakPtr());
- helper_->context()->AddProviderHost(std::move(owned_host));
+ host->CompleteNavigationInitialized(helper_->mock_render_process_id(),
+ std::move(info));
}
blink::mojom::ServiceWorkerErrorType Register(
@@ -255,8 +259,29 @@ class ServiceWorkerProviderHostTest : public testing::Test {
return false;
}
- std::vector<std::string> bad_messages_;
+ bool IsServiceWorkerServicificationEnabled() { return GetParam(); }
+
+ void ExpectUpdateIsScheduled(ServiceWorkerVersion* version) {
+ EXPECT_TRUE(version->is_update_scheduled_);
+ EXPECT_TRUE(version->update_timer_.IsRunning());
+ }
+
+ void ExpectUpdateIsNotScheduled(ServiceWorkerVersion* version) {
+ EXPECT_FALSE(version->is_update_scheduled_);
+ EXPECT_FALSE(version->update_timer_.IsRunning());
+ }
+
+ bool HasVersionToUpdate(ServiceWorkerProviderHost* host) {
+ return !host->versions_to_update_.empty();
+ }
+
+ // |scoped_feature_list_| must be before |thread_bundle_|, since
+ // the thread bundle's destruction causes service worker-related
+ // objects to destruct, whose destructors need to know whether servicification
+ // is enabled.
+ base::test::ScopedFeatureList scoped_feature_list_;
TestBrowserThreadBundle thread_bundle_;
+
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
ServiceWorkerContextCore* context_;
scoped_refptr<ServiceWorkerRegistration> registration1_;
@@ -268,6 +293,7 @@ class ServiceWorkerProviderHostTest : public testing::Test {
ContentBrowserClient* old_content_browser_client_;
int next_renderer_provided_id_;
std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints_;
+ std::vector<std::string> bad_messages_;
private:
ServiceWorkerProviderHost* CreateProviderHostInternal(
@@ -278,30 +304,21 @@ class ServiceWorkerProviderHostTest : public testing::Test {
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 */);
+ mojom::ServiceWorkerProviderHostInfoPtr info =
+ CreateProviderHostInfoForWindow(host->provider_id(), 1 /* route_id */);
remote_endpoint->BindWithProviderHostInfo(&info);
- std::unique_ptr<ServiceWorkerProviderHost> owned_host =
- helper_->context()->ReleaseProviderHost(host->process_id(),
- host->provider_id());
- host->CompleteNavigationInitialized(
- helper_->mock_render_process_id(), std::move(info),
- helper_->GetDispatcherHostForProcess(helper_->mock_render_process_id())
- ->AsWeakPtr());
+ host->CompleteNavigationInitialized(helper_->mock_render_process_id(),
+ std::move(info));
host->SetDocumentUrl(document_url);
host->SetTopmostFrameUrl(topmost_frame_url);
- helper_->context()->AddProviderHost(std::move(owned_host));
-
return host.get();
}
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderHostTest);
};
-TEST_F(ServiceWorkerProviderHostTest, MatchRegistration) {
+TEST_P(ServiceWorkerProviderHostTest, MatchRegistration) {
ServiceWorkerProviderHost* provider_host1 =
CreateProviderHost(GURL("https://www.example.com/example1.html"));
@@ -327,7 +344,7 @@ TEST_F(ServiceWorkerProviderHostTest, MatchRegistration) {
ASSERT_EQ(nullptr, provider_host1->MatchRegistration());
}
-TEST_F(ServiceWorkerProviderHostTest, ContextSecurity) {
+TEST_P(ServiceWorkerProviderHostTest, ContextSecurity) {
ServiceWorkerProviderHost* provider_host_secure_parent =
CreateProviderHost(GURL("https://www.example.com/example1.html"));
ServiceWorkerProviderHost* provider_host_insecure_parent =
@@ -388,7 +405,7 @@ class MockServiceWorkerRegistration : public ServiceWorkerRegistration {
std::set<ServiceWorkerRegistration::Listener*> listeners_;
};
-TEST_F(ServiceWorkerProviderHostTest, RemoveProvider) {
+TEST_P(ServiceWorkerProviderHostTest, RemoveProvider) {
// Create a provider host connected with the renderer process.
ServiceWorkerProviderHost* provider_host =
CreateProviderHost(GURL("https://www.example.com/example1.html"));
@@ -427,16 +444,14 @@ class MockServiceWorkerContainer : public mojom::ServiceWorkerContainer {
mojo::AssociatedBinding<mojom::ServiceWorkerContainer> binding_;
};
-TEST_F(ServiceWorkerProviderHostTest, Controller) {
+TEST_P(ServiceWorkerProviderHostTest, Controller) {
// Create a host.
base::WeakPtr<ServiceWorkerProviderHost> host =
ServiceWorkerProviderHost::PreCreateNavigationHost(
helper_->context()->AsWeakPtr(), true /* are_ancestors_secure */,
base::Callback<WebContents*(void)>());
- ServiceWorkerProviderHostInfo info(
- host->provider_id(), 1 /* route_id */,
- blink::mojom::ServiceWorkerProviderType::kForWindow,
- true /* is_parent_frame_secure */);
+ mojom::ServiceWorkerProviderHostInfoPtr info =
+ CreateProviderHostInfoForWindow(host->provider_id(), 1 /* route_id */);
remote_endpoints_.emplace_back();
remote_endpoints_.back().BindWithProviderHostInfo(&info);
auto container = std::make_unique<MockServiceWorkerContainer>(
@@ -446,6 +461,9 @@ TEST_F(ServiceWorkerProviderHostTest, Controller) {
scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
registration1_.get(), GURL("https://www.example.com/sw.js"),
1 /* version_id */, helper_->context()->AsWeakPtr());
+ version->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version->SetStatus(ServiceWorkerVersion::ACTIVATED);
registration1_->SetActiveVersion(version);
// Finish the navigation.
@@ -461,16 +479,14 @@ TEST_F(ServiceWorkerProviderHostTest, Controller) {
EXPECT_TRUE(container->was_set_controller_called());
}
-TEST_F(ServiceWorkerProviderHostTest, ActiveIsNotController) {
+TEST_P(ServiceWorkerProviderHostTest, ActiveIsNotController) {
// Create a host.
base::WeakPtr<ServiceWorkerProviderHost> host =
ServiceWorkerProviderHost::PreCreateNavigationHost(
helper_->context()->AsWeakPtr(), true /* are_ancestors_secure */,
base::Callback<WebContents*(void)>());
- ServiceWorkerProviderHostInfo info(
- host->provider_id(), 1 /* route_id */,
- blink::mojom::ServiceWorkerProviderType::kForWindow,
- true /* is_parent_frame_secure */);
+ mojom::ServiceWorkerProviderHostInfoPtr info =
+ CreateProviderHostInfoForWindow(host->provider_id(), 1 /* route_id */);
remote_endpoints_.emplace_back();
remote_endpoints_.back().BindWithProviderHostInfo(&info);
auto container = std::make_unique<MockServiceWorkerContainer>(
@@ -499,7 +515,7 @@ TEST_F(ServiceWorkerProviderHostTest, ActiveIsNotController) {
EXPECT_FALSE(container->was_set_controller_called());
}
-TEST_F(ServiceWorkerProviderHostTest,
+TEST_P(ServiceWorkerProviderHostTest,
Register_ContentSettingsDisallowsServiceWorker) {
ServiceWorkerTestContentBrowserClient test_browser_client;
ContentBrowserClient* old_browser_client =
@@ -540,7 +556,7 @@ TEST_F(ServiceWorkerProviderHostTest,
SetBrowserClientForTesting(old_browser_client);
}
-TEST_F(ServiceWorkerProviderHostTest, AllowsServiceWorker) {
+TEST_P(ServiceWorkerProviderHostTest, AllowsServiceWorker) {
// Create an active version.
scoped_refptr<ServiceWorkerVersion> version =
base::MakeRefCounted<ServiceWorkerVersion>(
@@ -549,7 +565,7 @@ TEST_F(ServiceWorkerProviderHostTest, AllowsServiceWorker) {
registration1_->SetActiveVersion(version);
ServiceWorkerRemoteProviderEndpoint remote_endpoint;
- std::unique_ptr<ServiceWorkerProviderHost> host =
+ base::WeakPtr<ServiceWorkerProviderHost> host =
CreateProviderHostForServiceWorkerContext(
helper_->mock_render_process_id(), true /* is_parent_frame_secure */,
version.get(), helper_->context()->AsWeakPtr(), &remote_endpoint);
@@ -569,7 +585,7 @@ TEST_F(ServiceWorkerProviderHostTest, AllowsServiceWorker) {
SetBrowserClientForTesting(old_browser_client);
}
-TEST_F(ServiceWorkerProviderHostTest, Register_HTTPS) {
+TEST_P(ServiceWorkerProviderHostTest, Register_HTTPS) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
@@ -579,7 +595,7 @@ TEST_F(ServiceWorkerProviderHostTest, Register_HTTPS) {
GURL("https://www.example.com/bar")));
}
-TEST_F(ServiceWorkerProviderHostTest, Register_NonSecureTransportLocalhost) {
+TEST_P(ServiceWorkerProviderHostTest, Register_NonSecureTransportLocalhost) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("http://127.0.0.3:81/foo"));
@@ -589,7 +605,7 @@ TEST_F(ServiceWorkerProviderHostTest, Register_NonSecureTransportLocalhost) {
GURL("http://127.0.0.3:81/baz")));
}
-TEST_F(ServiceWorkerProviderHostTest, Register_InvalidScopeShouldFail) {
+TEST_P(ServiceWorkerProviderHostTest, Register_InvalidScopeShouldFail) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
@@ -599,7 +615,7 @@ TEST_F(ServiceWorkerProviderHostTest, Register_InvalidScopeShouldFail) {
EXPECT_EQ(1u, bad_messages_.size());
}
-TEST_F(ServiceWorkerProviderHostTest, Register_InvalidScriptShouldFail) {
+TEST_P(ServiceWorkerProviderHostTest, Register_InvalidScriptShouldFail) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
@@ -609,7 +625,7 @@ TEST_F(ServiceWorkerProviderHostTest, Register_InvalidScriptShouldFail) {
EXPECT_EQ(1u, bad_messages_.size());
}
-TEST_F(ServiceWorkerProviderHostTest, Register_NonSecureOriginShouldFail) {
+TEST_P(ServiceWorkerProviderHostTest, Register_NonSecureOriginShouldFail) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("http://www.example.com/foo"));
@@ -619,7 +635,7 @@ TEST_F(ServiceWorkerProviderHostTest, Register_NonSecureOriginShouldFail) {
EXPECT_EQ(1u, bad_messages_.size());
}
-TEST_F(ServiceWorkerProviderHostTest, Register_CrossOriginShouldFail) {
+TEST_P(ServiceWorkerProviderHostTest, Register_CrossOriginShouldFail) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
@@ -654,7 +670,7 @@ TEST_F(ServiceWorkerProviderHostTest, Register_CrossOriginShouldFail) {
EXPECT_EQ(6u, bad_messages_.size());
}
-TEST_F(ServiceWorkerProviderHostTest, Register_BadCharactersShouldFail) {
+TEST_P(ServiceWorkerProviderHostTest, Register_BadCharactersShouldFail) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("https://www.example.com"));
@@ -687,7 +703,7 @@ TEST_F(ServiceWorkerProviderHostTest, Register_BadCharactersShouldFail) {
EXPECT_EQ(6u, bad_messages_.size());
}
-TEST_F(ServiceWorkerProviderHostTest, Register_FileSystemDocumentShouldFail) {
+TEST_P(ServiceWorkerProviderHostTest, Register_FileSystemDocumentShouldFail) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(
GURL("filesystem:https://www.example.com/temporary/a"));
@@ -709,7 +725,7 @@ TEST_F(ServiceWorkerProviderHostTest, Register_FileSystemDocumentShouldFail) {
EXPECT_EQ(3u, bad_messages_.size());
}
-TEST_F(ServiceWorkerProviderHostTest,
+TEST_P(ServiceWorkerProviderHostTest,
Register_FileSystemScriptOrScopeShouldFail) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(
@@ -732,7 +748,7 @@ TEST_F(ServiceWorkerProviderHostTest,
EXPECT_EQ(3u, bad_messages_.size());
}
-TEST_F(ServiceWorkerProviderHostTest, EarlyContextDeletion) {
+TEST_P(ServiceWorkerProviderHostTest, EarlyContextDeletion) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
@@ -746,7 +762,7 @@ TEST_F(ServiceWorkerProviderHostTest, EarlyContextDeletion) {
EXPECT_TRUE(remote_endpoint.host_ptr()->encountered_error());
}
-TEST_F(ServiceWorkerProviderHostTest, GetRegistration_Success) {
+TEST_P(ServiceWorkerProviderHostTest, GetRegistration_Success) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
@@ -761,7 +777,7 @@ TEST_F(ServiceWorkerProviderHostTest, GetRegistration_Success) {
EXPECT_EQ(kScope, info->options->scope);
}
-TEST_F(ServiceWorkerProviderHostTest,
+TEST_P(ServiceWorkerProviderHostTest,
GetRegistration_NotFoundShouldReturnNull) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
@@ -773,7 +789,7 @@ TEST_F(ServiceWorkerProviderHostTest,
EXPECT_FALSE(info);
}
-TEST_F(ServiceWorkerProviderHostTest, GetRegistration_CrossOriginShouldFail) {
+TEST_P(ServiceWorkerProviderHostTest, GetRegistration_CrossOriginShouldFail) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
@@ -783,7 +799,7 @@ TEST_F(ServiceWorkerProviderHostTest, GetRegistration_CrossOriginShouldFail) {
EXPECT_EQ(1u, bad_messages_.size());
}
-TEST_F(ServiceWorkerProviderHostTest, GetRegistration_InvalidScopeShouldFail) {
+TEST_P(ServiceWorkerProviderHostTest, GetRegistration_InvalidScopeShouldFail) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
@@ -792,7 +808,7 @@ TEST_F(ServiceWorkerProviderHostTest, GetRegistration_InvalidScopeShouldFail) {
EXPECT_EQ(1u, bad_messages_.size());
}
-TEST_F(ServiceWorkerProviderHostTest,
+TEST_P(ServiceWorkerProviderHostTest,
GetRegistration_NonSecureOriginShouldFail) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("http://www.example.com/foo"));
@@ -803,7 +819,7 @@ TEST_F(ServiceWorkerProviderHostTest,
EXPECT_EQ(1u, bad_messages_.size());
}
-TEST_F(ServiceWorkerProviderHostTest, GetRegistrations_SecureOrigin) {
+TEST_P(ServiceWorkerProviderHostTest, GetRegistrations_SecureOrigin) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo"));
@@ -811,7 +827,7 @@ TEST_F(ServiceWorkerProviderHostTest, GetRegistrations_SecureOrigin) {
GetRegistrations(remote_endpoint.host_ptr()->get()));
}
-TEST_F(ServiceWorkerProviderHostTest,
+TEST_P(ServiceWorkerProviderHostTest,
GetRegistrations_NonSecureOriginShouldFail) {
ServiceWorkerRemoteProviderEndpoint remote_endpoint =
PrepareServiceWorkerProviderHost(GURL("http://www.example.com/foo"));
@@ -824,7 +840,7 @@ TEST_F(ServiceWorkerProviderHostTest,
// Test that a "reserved" (i.e., not execution ready) client is not included
// when iterating over client provider hosts. If it were, it'd be undesirably
// exposed via the Clients API.
-TEST_F(ServiceWorkerProviderHostTest,
+TEST_P(ServiceWorkerProviderHostTest,
ReservedClientsAreNotExposedToClientsAPI) {
{
auto provider_info = mojom::ServiceWorkerProviderInfoForSharedWorker::New();
@@ -844,10 +860,8 @@ TEST_F(ServiceWorkerProviderHostTest,
ServiceWorkerProviderHost::PreCreateNavigationHost(
helper_->context()->AsWeakPtr(), true,
base::RepeatingCallback<WebContents*(void)>());
- ServiceWorkerProviderHostInfo info(
- host->provider_id(), 1 /* route_id */,
- blink::mojom::ServiceWorkerProviderType::kForWindow,
- true /* is_parent_frame_secure */);
+ mojom::ServiceWorkerProviderHostInfoPtr info =
+ CreateProviderHostInfoForWindow(host->provider_id(), 1 /* route_id */);
ServiceWorkerRemoteProviderEndpoint remote_endpoint;
remote_endpoint.BindWithProviderHostInfo(&info);
host->SetDocumentUrl(GURL("https://www.example.com/page"));
@@ -858,4 +872,272 @@ TEST_F(ServiceWorkerProviderHostTest,
}
}
+// Regression test for https://crbug.com/860106. When a provider host
+// is destroyed, it removes itself as a controllee from its controller.
+// This can trigger the waiting version starting to activate. The
+// destructing host shouldn't try to change its controller to the new
+// active version.
+TEST_P(ServiceWorkerProviderHostTest, DontSetControllerInDestructor) {
+ // This test requires the idle timeout mechanism of S13nSW to exercise the
+ // desired code path.
+ if (!IsServiceWorkerServicificationEnabled())
+ return;
+
+ // Make a window.
+ ServiceWorkerProviderHost* provider_host1 =
+ CreateProviderHost(GURL("https://www.example.com/example1.html"));
+
+ // Make an active version.
+ auto version1 = base::MakeRefCounted<ServiceWorkerVersion>(
+ registration1_.get(), GURL("https://www.example.com/sw.js"),
+ 1 /* version_id */, helper_->context()->AsWeakPtr());
+ version1->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version1->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ registration1_->SetActiveVersion(version1);
+
+ // Make the registration findable via storage functions. This allows
+ // the service worker to start, which will be needed later.
+ base::RunLoop loop;
+ helper_->context()->storage()->LazyInitializeForTest(loop.QuitClosure());
+ loop.Run();
+ std::vector<ServiceWorkerDatabase::ResourceRecord> records;
+ records.push_back(WriteToDiskCacheSync(
+ helper_->context()->storage(), version1->script_url(),
+ helper_->context()->storage()->NewResourceId(), {} /* headers */,
+ "I'm the body", "I'm the meta data"));
+ version1->script_cache_map()->SetResources(records);
+ version1->SetMainScriptHttpResponseInfo(
+ EmbeddedWorkerTestHelper::CreateHttpResponseInfo());
+ base::Optional<blink::ServiceWorkerStatusCode> status;
+ helper_->context()->storage()->StoreRegistration(
+ registration1_.get(), version1.get(),
+ CreateReceiverOnCurrentThread(&status));
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
+
+ // Make the active worker the controller and give it an ongoing request. This
+ // way when a waiting worker calls SkipWaiting(), activation won't trigger
+ // until we're ready.
+ provider_host1->AssociateRegistration(registration1_.get(), false);
+ EXPECT_EQ(version1.get(), provider_host1->controller());
+ // The worker must be running to have a request.
+ version1->StartWorker(ServiceWorkerMetrics::EventType::PUSH,
+ base::DoNothing());
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version1->running_status());
+ int request = version1->StartRequest(ServiceWorkerMetrics::EventType::PUSH,
+ base::DoNothing());
+
+ // Make the waiting worker and have it call SkipWaiting().
+ auto version2 = base::MakeRefCounted<ServiceWorkerVersion>(
+ registration1_.get(), GURL("https://www.example.com/sw.js"),
+ 2 /* version_id */, helper_->context()->AsWeakPtr());
+ version2->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version2->SetStatus(ServiceWorkerVersion::INSTALLED);
+ registration1_->SetWaitingVersion(version2);
+ version2->SkipWaiting(base::DoNothing());
+
+ // Finish the request. Activation won't yet occur until as
+ // |idle_time_fired_in_renderer_| isn't true.
+ version1->FinishRequest(request, true, base::Time::Now());
+
+ // Destroy the provider host. This triggers activation, and since
+ // SkipWaiting() was called, the provider host is in danger
+ // of receiving an OnSkippedWaiting() call during destruction.
+ ASSERT_TRUE(remote_endpoints_.back().host_ptr()->is_bound());
+ remote_endpoints_.back().host_ptr()->reset();
+ base::RunLoop().RunUntilIdle();
+
+ // No crash should occur, and the new version should be the active
+ // one.
+ EXPECT_EQ(version2.get(), registration1_->active_version());
+ EXPECT_FALSE(version2->HasControllee());
+}
+
+// Tests that the service worker involved with a navigation (via
+// AddServiceWorkerToUpdate) is updated when the host for the navigation is
+// destroyed.
+TEST_P(ServiceWorkerProviderHostTest, UpdateServiceWorkerOnDestruction) {
+ // This code path only is used in S13nSW.
+ if (!IsServiceWorkerServicificationEnabled())
+ return;
+
+ // Make a window.
+ ServiceWorkerProviderHost* host =
+ CreateProviderHost(GURL("https://www.example.com/example.html"));
+
+ // Make an active version.
+ auto version1 = base::MakeRefCounted<ServiceWorkerVersion>(
+ registration1_.get(), GURL("https://www.example.com/sw.js"),
+ 1 /* version_id */, helper_->context()->AsWeakPtr());
+ version1->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version1->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ registration1_->SetActiveVersion(version1);
+
+ auto version2 = base::MakeRefCounted<ServiceWorkerVersion>(
+ registration2_.get(), GURL("https://www.example.com/sw.js"),
+ 2 /* version_id */, helper_->context()->AsWeakPtr());
+ version2->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version2->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ registration2_->SetActiveVersion(version1);
+
+ host->AddServiceWorkerToUpdate(version1);
+ host->AddServiceWorkerToUpdate(version2);
+ ExpectUpdateIsNotScheduled(version1.get());
+ ExpectUpdateIsNotScheduled(version2.get());
+
+ // Destroy the provider host.
+ ASSERT_TRUE(remote_endpoints_.back().host_ptr()->is_bound());
+ remote_endpoints_.back().host_ptr()->reset();
+ base::RunLoop().RunUntilIdle();
+
+ // The provider host's destructor should have scheduled the update.
+ ExpectUpdateIsScheduled(version1.get());
+ ExpectUpdateIsScheduled(version2.get());
+}
+
+// Tests that the service worker involved with a navigation is updated when the
+// host receives a HintToUpdateServiceWorker message.
+TEST_P(ServiceWorkerProviderHostTest, HintToUpdateServiceWorker) {
+ // This code path only is used in S13nSW.
+ if (!IsServiceWorkerServicificationEnabled())
+ return;
+
+ // Make an active version.
+ auto version1 = base::MakeRefCounted<ServiceWorkerVersion>(
+ registration1_.get(), GURL("https://www.example.com/sw.js"),
+ 1 /* version_id */, helper_->context()->AsWeakPtr());
+ version1->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version1->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ registration1_->SetActiveVersion(version1);
+
+ // Make a window.
+ ServiceWorkerProviderHost* host =
+ CreateProviderHost(GURL("https://www.example.com/example.html"));
+
+ // Mark the service worker as needing update. Update should not be scheduled
+ // yet.
+ host->AddServiceWorkerToUpdate(version1);
+ ExpectUpdateIsNotScheduled(version1.get());
+ EXPECT_TRUE(HasVersionToUpdate(host));
+
+ // Send the hint from the renderer. Update should be scheduled.
+ mojom::ServiceWorkerContainerHostAssociatedPtr* host_ptr =
+ remote_endpoints_.back().host_ptr();
+ (*host_ptr)->HintToUpdateServiceWorker();
+ base::RunLoop().RunUntilIdle();
+ ExpectUpdateIsScheduled(version1.get());
+ EXPECT_FALSE(HasVersionToUpdate(host));
+}
+
+// Tests that the host receives a HintToUpdateServiceWorker message but
+// there was no service worker at main resource request time. This
+// can happen due to claim().
+TEST_P(ServiceWorkerProviderHostTest,
+ HintToUpdateServiceWorkerButNoVersionToUpdate) {
+ // This code path only is used in S13nSW.
+ if (!IsServiceWorkerServicificationEnabled())
+ return;
+
+ // Make a window.
+ ServiceWorkerProviderHost* host =
+ CreateProviderHost(GURL("https://www.example.com/example.html"));
+
+ // Make an active version.
+ auto version1 = base::MakeRefCounted<ServiceWorkerVersion>(
+ registration1_.get(), GURL("https://www.example.com/sw.js"),
+ 1 /* version_id */, helper_->context()->AsWeakPtr());
+ version1->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version1->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ registration1_->SetActiveVersion(version1);
+
+ // Pretend the registration gets associated after the main
+ // resource request, so AddServiceWorkerToUpdate() is not called.
+
+ ExpectUpdateIsNotScheduled(version1.get());
+ EXPECT_FALSE(HasVersionToUpdate(host));
+
+ // Send the hint from the renderer. Update should not be scheduled, since
+ // AddServiceWorkerToUpdate() was not called.
+ mojom::ServiceWorkerContainerHostAssociatedPtr* host_ptr =
+ remote_endpoints_.back().host_ptr();
+ (*host_ptr)->HintToUpdateServiceWorker();
+ base::RunLoop().RunUntilIdle();
+ ExpectUpdateIsNotScheduled(version1.get());
+ EXPECT_FALSE(HasVersionToUpdate(host));
+}
+
+TEST_P(ServiceWorkerProviderHostTest, HintToUpdateServiceWorkerMultiple) {
+ // This code path only is used in S13nSW.
+ if (!IsServiceWorkerServicificationEnabled())
+ return;
+
+ // Make active versions.
+ auto version1 = base::MakeRefCounted<ServiceWorkerVersion>(
+ registration1_.get(), GURL("https://www.example.com/sw.js"),
+ 1 /* version_id */, helper_->context()->AsWeakPtr());
+ version1->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version1->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ registration1_->SetActiveVersion(version1);
+
+ auto version2 = base::MakeRefCounted<ServiceWorkerVersion>(
+ registration2_.get(), GURL("https://www.example.com/sw.js"),
+ 2 /* version_id */, helper_->context()->AsWeakPtr());
+ version2->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version2->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ registration2_->SetActiveVersion(version1);
+
+ auto version3 = base::MakeRefCounted<ServiceWorkerVersion>(
+ registration3_.get(), GURL("https://other.example.com/sw.js"),
+ 3 /* version_id */, helper_->context()->AsWeakPtr());
+ version3->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version3->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ registration3_->SetActiveVersion(version1);
+
+ // Make a window.
+ ServiceWorkerProviderHost* host =
+ CreateProviderHost(GURL("https://www.example.com/example.html"));
+
+ // Mark the service worker as needing update. Update should not be scheduled
+ // yet.
+ host->AddServiceWorkerToUpdate(version1);
+ host->AddServiceWorkerToUpdate(version2);
+ host->AddServiceWorkerToUpdate(version3);
+ ExpectUpdateIsNotScheduled(version1.get());
+ ExpectUpdateIsNotScheduled(version2.get());
+ ExpectUpdateIsNotScheduled(version3.get());
+ EXPECT_TRUE(HasVersionToUpdate(host));
+
+ // Pretend another page also used version3.
+ version3->IncrementPendingUpdateHintCount();
+
+ // Send the hint from the renderer. Update should be scheduled except for
+ // |version3| as it's being used by another page.
+ mojom::ServiceWorkerContainerHostAssociatedPtr* host_ptr =
+ remote_endpoints_.back().host_ptr();
+ (*host_ptr)->HintToUpdateServiceWorker();
+ base::RunLoop().RunUntilIdle();
+ ExpectUpdateIsScheduled(version1.get());
+ ExpectUpdateIsScheduled(version2.get());
+ ExpectUpdateIsNotScheduled(version3.get());
+ EXPECT_FALSE(HasVersionToUpdate(host));
+
+ // Pretend the other page also finished for version3.
+ version3->DecrementPendingUpdateHintCount();
+ ExpectUpdateIsScheduled(version3.get());
+}
+
+INSTANTIATE_TEST_CASE_P(IsServiceWorkerServicificationEnabled,
+ ServiceWorkerProviderHostTest,
+ ::testing::Bool(););
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_read_from_cache_job.cc b/chromium/content/browser/service_worker/service_worker_read_from_cache_job.cc
index e90ad63f3f0..04c4f20c2aa 100644
--- a/chromium/content/browser/service_worker/service_worker_read_from_cache_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_read_from_cache_job.cc
@@ -201,7 +201,8 @@ void ServiceWorkerReadFromCacheJob::SetupRangeResponse(int resource_size) {
void ServiceWorkerReadFromCacheJob::Done(const net::URLRequestStatus& status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!status.is_success()) {
- version_->SetStartWorkerStatusCode(SERVICE_WORKER_ERROR_DISK_CACHE);
+ version_->SetStartWorkerStatusCode(
+ blink::ServiceWorkerStatusCode::kErrorDiskCache);
// TODO(falken): Retry before evicting.
if (context_) {
ServiceWorkerRegistration* registration =
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 85f49357f2e..4fdb26ad89c 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
@@ -39,17 +39,17 @@ const int64_t kImportedScriptResourceId = 11;
const int64_t kNonExistentResourceId = 12;
const int64_t kResourceSize = 100;
-void DidStoreRegistration(ServiceWorkerStatusCode* status_out,
+void DidStoreRegistration(blink::ServiceWorkerStatusCode* status_out,
const base::Closure& quit_closure,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
*status_out = status;
quit_closure.Run();
}
void DidFindRegistration(
- ServiceWorkerStatusCode* status_out,
+ blink::ServiceWorkerStatusCode* status_out,
const base::Closure& quit_closure,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
*status_out = status;
quit_closure.Run();
@@ -103,7 +103,7 @@ class ServiceWorkerReadFromCacheJobTest : public testing::Test {
version_->script_cache_map()->SetResources(resources);
version_->set_fetch_handler_existence(
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
- ASSERT_EQ(SERVICE_WORKER_OK, StoreRegistration());
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, StoreRegistration());
ASSERT_TRUE(WriteResource(main_script_.resource_id));
ASSERT_TRUE(WriteResource(imported_script_.resource_id));
}
@@ -142,9 +142,10 @@ class ServiceWorkerReadFromCacheJobTest : public testing::Test {
return true;
}
- ServiceWorkerStatusCode StoreRegistration() {
+ blink::ServiceWorkerStatusCode StoreRegistration() {
base::RunLoop run_loop;
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
context()->storage()->StoreRegistration(
registration_.get(), version_.get(),
base::BindOnce(&DidStoreRegistration, &status, run_loop.QuitClosure()));
@@ -152,9 +153,10 @@ class ServiceWorkerReadFromCacheJobTest : public testing::Test {
return status;
}
- ServiceWorkerStatusCode FindRegistration() {
+ blink::ServiceWorkerStatusCode FindRegistration() {
base::RunLoop run_loop;
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
context()->storage()->FindRegistrationForId(
registration_->id(), registration_->pattern().GetOrigin(),
base::BindOnce(&DidFindRegistration, &status, run_loop.QuitClosure()));
@@ -168,8 +170,8 @@ class ServiceWorkerReadFromCacheJobTest : public testing::Test {
base::RunLoop().RunUntilIdle();
}
- ServiceWorkerStatusCode DeduceStartWorkerFailureReason(
- ServiceWorkerStatusCode default_code) {
+ blink::ServiceWorkerStatusCode DeduceStartWorkerFailureReason(
+ blink::ServiceWorkerStatusCode default_code) {
return version_->DeduceStartWorkerFailureReason(default_code);
}
@@ -207,8 +209,9 @@ TEST_F(ServiceWorkerReadFromCacheJobTest, ReadMainScript) {
EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
EXPECT_EQ(0, request->status().error());
- EXPECT_EQ(SERVICE_WORKER_OK,
- DeduceStartWorkerFailureReason(SERVICE_WORKER_OK));
+ EXPECT_EQ(
+ blink::ServiceWorkerStatusCode::kOk,
+ DeduceStartWorkerFailureReason(blink::ServiceWorkerStatusCode::kOk));
}
TEST_F(ServiceWorkerReadFromCacheJobTest, ReadImportedScript) {
@@ -225,12 +228,13 @@ TEST_F(ServiceWorkerReadFromCacheJobTest, ReadImportedScript) {
EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
EXPECT_EQ(0, request->status().error());
- EXPECT_EQ(SERVICE_WORKER_OK,
- DeduceStartWorkerFailureReason(SERVICE_WORKER_OK));
+ EXPECT_EQ(
+ blink::ServiceWorkerStatusCode::kOk,
+ DeduceStartWorkerFailureReason(blink::ServiceWorkerStatusCode::kOk));
}
TEST_F(ServiceWorkerReadFromCacheJobTest, ResourceNotFound) {
- ASSERT_EQ(SERVICE_WORKER_OK, FindRegistration());
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, FindRegistration());
// Populate the script cache map with a nonexistent resource.
ServiceWorkerScriptCacheMap* script_cache_map = version_->script_cache_map();
@@ -257,12 +261,13 @@ TEST_F(ServiceWorkerReadFromCacheJobTest, ResourceNotFound) {
EXPECT_EQ(net::URLRequestStatus::FAILED, request->status().status());
EXPECT_EQ(net::ERR_CACHE_MISS, request->status().error());
- EXPECT_EQ(SERVICE_WORKER_ERROR_DISK_CACHE,
- DeduceStartWorkerFailureReason(SERVICE_WORKER_OK));
+ EXPECT_EQ(
+ blink::ServiceWorkerStatusCode::kErrorDiskCache,
+ DeduceStartWorkerFailureReason(blink::ServiceWorkerStatusCode::kOk));
// The version should be doomed by the job.
EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version_->status());
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND, FindRegistration());
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound, FindRegistration());
}
} // namespace content
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 69d7b3154e2..81b62c81e86 100644
--- a/chromium/content/browser/service_worker/service_worker_register_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_register_job.cc
@@ -10,21 +10,23 @@
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
+#include "content/browser/service_worker/embedded_worker_instance.h"
#include "content/browser/service_worker/embedded_worker_status.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_job_coordinator.h"
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_storage.h"
-#include "content/browser/service_worker/service_worker_type_converters.h"
+#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/service_worker/service_worker_write_to_cache_job.h"
-#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker.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/browser_thread.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "net/base/net_errors.h"
+#include "third_party/blink/public/common/service_worker/service_worker_type_converters.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
namespace content {
@@ -46,8 +48,7 @@ ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
should_uninstall_on_failure_(false),
force_bypass_cache_(false),
skip_script_comparison_(false),
- promise_resolved_status_(SERVICE_WORKER_OK),
- observer_(this),
+ promise_resolved_status_(blink::ServiceWorkerStatusCode::kOk),
weak_factory_(this) {}
ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
@@ -65,8 +66,7 @@ ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
should_uninstall_on_failure_(false),
force_bypass_cache_(force_bypass_cache),
skip_script_comparison_(skip_script_comparison),
- promise_resolved_status_(SERVICE_WORKER_OK),
- observer_(this),
+ promise_resolved_status_(blink::ServiceWorkerStatusCode::kOk),
weak_factory_(this) {
internal_.registration = registration;
}
@@ -113,7 +113,8 @@ void ServiceWorkerRegisterJob::StartImpl() {
if (registration.get())
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
- base::BindOnce(std::move(next_step), SERVICE_WORKER_OK, registration));
+ base::BindOnce(std::move(next_step),
+ blink::ServiceWorkerStatusCode::kOk, registration));
else
context_->storage()->FindRegistrationForPattern(pattern_,
std::move(next_step));
@@ -121,7 +122,7 @@ void ServiceWorkerRegisterJob::StartImpl() {
void ServiceWorkerRegisterJob::Abort() {
SetPhase(ABORT);
- CompleteInternal(SERVICE_WORKER_ERROR_ABORT, std::string());
+ CompleteInternal(blink::ServiceWorkerStatusCode::kErrorAbort, std::string());
// Don't have to call FinishJob() because the caller takes care of removing
// the jobs from the queue.
}
@@ -145,7 +146,8 @@ RegistrationJobType ServiceWorkerRegisterJob::GetType() const {
void ServiceWorkerRegisterJob::DoomInstallingWorker() {
doom_installing_worker_ = true;
if (phase_ == INSTALL)
- Complete(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED, std::string());
+ Complete(blink::ServiceWorkerStatusCode::kErrorInstallWorkerFailed,
+ std::string());
}
ServiceWorkerRegisterJob::Internal::Internal() {}
@@ -209,10 +211,11 @@ void ServiceWorkerRegisterJob::SetPhase(Phase phase) {
// "Let registration be the result of running the [[GetRegistration]] algorithm.
// Throughout this file, comments in quotes are excerpts from the spec.
void ServiceWorkerRegisterJob::ContinueWithRegistration(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> existing_registration) {
DCHECK_EQ(REGISTRATION_JOB, job_type_);
- if (status != SERVICE_WORKER_ERROR_NOT_FOUND && status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kErrorNotFound &&
+ status != blink::ServiceWorkerStatusCode::kOk) {
Complete(status);
return;
}
@@ -251,23 +254,23 @@ void ServiceWorkerRegisterJob::ContinueWithRegistration(
}
void ServiceWorkerRegisterJob::ContinueWithUpdate(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> existing_registration) {
DCHECK_EQ(UPDATE_JOB, job_type_);
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
Complete(status);
return;
}
if (existing_registration.get() != registration()) {
- Complete(SERVICE_WORKER_ERROR_NOT_FOUND);
+ Complete(blink::ServiceWorkerStatusCode::kErrorNotFound);
return;
}
// A previous job may have unregistered this registration.
if (registration()->is_uninstalling() ||
!registration()->GetNewestVersion()) {
- Complete(SERVICE_WORKER_ERROR_NOT_FOUND);
+ Complete(blink::ServiceWorkerStatusCode::kErrorNotFound);
return;
}
@@ -287,7 +290,7 @@ void ServiceWorkerRegisterJob::RegisterAndContinue() {
int64_t registration_id = context_->storage()->NewRegistrationId();
if (registration_id == blink::mojom::kInvalidServiceWorkerRegistrationId) {
- Complete(SERVICE_WORKER_ERROR_ABORT);
+ Complete(blink::ServiceWorkerStatusCode::kErrorAbort);
return;
}
@@ -301,8 +304,8 @@ void ServiceWorkerRegisterJob::RegisterAndContinue() {
void ServiceWorkerRegisterJob::ContinueWithUninstallingRegistration(
scoped_refptr<ServiceWorkerRegistration> existing_registration,
- ServiceWorkerStatusCode status) {
- if (status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode status) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
Complete(status);
return;
}
@@ -313,8 +316,8 @@ void ServiceWorkerRegisterJob::ContinueWithUninstallingRegistration(
void ServiceWorkerRegisterJob::ContinueWithRegistrationForSameScriptUrl(
scoped_refptr<ServiceWorkerRegistration> existing_registration,
- ServiceWorkerStatusCode status) {
- if (status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode status) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
Complete(status);
return;
}
@@ -331,7 +334,7 @@ void ServiceWorkerRegisterJob::ContinueWithRegistrationForSameScriptUrl(
DCHECK(!existing_registration->installing_version());
if (existing_registration->active_version()) {
ResolvePromise(status, std::string(), existing_registration.get());
- Complete(SERVICE_WORKER_OK);
+ Complete(blink::ServiceWorkerStatusCode::kOk);
return;
}
@@ -347,7 +350,7 @@ void ServiceWorkerRegisterJob::UpdateAndContinue() {
int64_t version_id = context_->storage()->NewVersionId();
if (version_id == blink::mojom::kInvalidServiceWorkerVersionId) {
- Complete(SERVICE_WORKER_ERROR_ABORT);
+ Complete(blink::ServiceWorkerStatusCode::kErrorAbort);
return;
}
@@ -357,10 +360,9 @@ void ServiceWorkerRegisterJob::UpdateAndContinue() {
version_id, context_));
new_version()->set_force_bypass_cache_for_scripts(force_bypass_cache_);
if (registration()->has_installed_version() && !skip_script_comparison_) {
- new_version()->set_pause_after_download(true);
- observer_.Add(new_version()->embedded_worker());
- } else {
- new_version()->set_pause_after_download(false);
+ new_version()->SetToPauseAfterDownload(
+ base::BindOnce(&ServiceWorkerRegisterJob::OnPausedAfterDownload,
+ weak_factory_.GetWeakPtr()));
}
new_version()->StartWorker(
ServiceWorkerMetrics::EventType::INSTALL,
@@ -369,17 +371,17 @@ void ServiceWorkerRegisterJob::UpdateAndContinue() {
}
void ServiceWorkerRegisterJob::OnStartWorkerFinished(
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
BumpLastUpdateCheckTimeIfNeeded();
- if (status == SERVICE_WORKER_OK) {
+ if (status == blink::ServiceWorkerStatusCode::kOk) {
InstallAndContinue();
return;
}
// "If serviceWorker fails to start up..." then reject the promise with an
// error and abort.
- if (status == SERVICE_WORKER_ERROR_TIMEOUT) {
+ if (status == blink::ServiceWorkerStatusCode::kErrorTimeout) {
Complete(status, "Timed out while trying to start the Service Worker.");
return;
}
@@ -408,7 +410,8 @@ void ServiceWorkerRegisterJob::InstallAndContinue() {
new_version()->SetStatus(ServiceWorkerVersion::INSTALLING);
// "Resolve registrationPromise with registration."
- ResolvePromise(SERVICE_WORKER_OK, std::string(), registration());
+ ResolvePromise(blink::ServiceWorkerStatusCode::kOk, std::string(),
+ registration());
// "Fire a simple event named updatefound..."
registration()->NotifyUpdateFound();
@@ -423,12 +426,12 @@ void ServiceWorkerRegisterJob::InstallAndContinue() {
// only do so after we've started the worker and dispatched the install
// event, as those are atomic substeps in the [[Install]] algorithm.
if (doom_installing_worker_)
- Complete(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED);
+ Complete(blink::ServiceWorkerStatusCode::kErrorInstallWorkerFailed);
}
void ServiceWorkerRegisterJob::DispatchInstallEvent(
- ServiceWorkerStatusCode start_worker_status) {
- if (start_worker_status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode start_worker_status) {
+ if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) {
OnInstallFailed(start_worker_status);
return;
}
@@ -442,7 +445,7 @@ void ServiceWorkerRegisterJob::DispatchInstallEvent(
base::BindOnce(&ServiceWorkerRegisterJob::OnInstallFailed,
weak_factory_.GetWeakPtr()));
- new_version()->event_dispatcher()->DispatchInstallEvent(
+ new_version()->endpoint()->DispatchInstallEvent(
base::BindOnce(&ServiceWorkerRegisterJob::OnInstallFinished,
weak_factory_.GetWeakPtr(), request_id));
}
@@ -457,11 +460,13 @@ void ServiceWorkerRegisterJob::OnInstallFinished(
new_version()->FinishRequest(request_id, succeeded, dispatch_event_time);
if (!succeeded) {
- OnInstallFailed(mojo::ConvertTo<ServiceWorkerStatusCode>(event_status));
+ OnInstallFailed(
+ mojo::ConvertTo<blink::ServiceWorkerStatusCode>(event_status));
return;
}
- ServiceWorkerMetrics::RecordInstallEventStatus(SERVICE_WORKER_OK);
+ ServiceWorkerMetrics::RecordInstallEventStatus(
+ blink::ServiceWorkerStatusCode::kOk);
SetPhase(STORE);
DCHECK(!registration()->last_update_check().is_null());
@@ -475,17 +480,19 @@ void ServiceWorkerRegisterJob::OnInstallFinished(
weak_factory_.GetWeakPtr()));
}
-void ServiceWorkerRegisterJob::OnInstallFailed(ServiceWorkerStatusCode status) {
+void ServiceWorkerRegisterJob::OnInstallFailed(
+ blink::ServiceWorkerStatusCode status) {
ServiceWorkerMetrics::RecordInstallEventStatus(status);
- DCHECK_NE(status, SERVICE_WORKER_OK)
- << "OnInstallFailed should not handle SERVICE_WORKER_OK";
+ DCHECK_NE(status, blink::ServiceWorkerStatusCode::kOk)
+ << "OnInstallFailed should not handle "
+ "blink::ServiceWorkerStatusCode::kOk";
Complete(status, std::string("ServiceWorker failed to install: ") +
- ServiceWorkerStatusToString(status));
+ blink::ServiceWorkerStatusToString(status));
}
void ServiceWorkerRegisterJob::OnStoreRegistrationComplete(
- ServiceWorkerStatusCode status) {
- if (status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode status) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
Complete(status);
return;
}
@@ -515,36 +522,35 @@ void ServiceWorkerRegisterJob::OnStoreRegistrationComplete(
// client is using registration as their service worker registration."
registration()->ActivateWaitingVersionWhenReady();
- Complete(SERVICE_WORKER_OK);
+ Complete(blink::ServiceWorkerStatusCode::kOk);
}
-void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) {
+void ServiceWorkerRegisterJob::Complete(blink::ServiceWorkerStatusCode status) {
Complete(status, std::string());
}
-void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status,
+void ServiceWorkerRegisterJob::Complete(blink::ServiceWorkerStatusCode status,
const std::string& status_message) {
CompleteInternal(status, status_message);
context_->job_coordinator()->FinishJob(pattern_, this);
}
void ServiceWorkerRegisterJob::CompleteInternal(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message) {
SetPhase(COMPLETE);
- if (new_version()) {
- new_version()->set_pause_after_download(false);
- observer_.RemoveAll();
- }
+ if (new_version())
+ new_version()->SetToNotPauseAfterDownload();
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
if (registration()) {
if (should_uninstall_on_failure_)
registration()->ClearWhenReady();
if (new_version()) {
- if (status == SERVICE_WORKER_ERROR_EXISTS)
- new_version()->SetStartWorkerStatusCode(SERVICE_WORKER_ERROR_EXISTS);
+ if (status == blink::ServiceWorkerStatusCode::kErrorExists)
+ new_version()->SetStartWorkerStatusCode(
+ blink::ServiceWorkerStatusCode::kErrorExists);
else
new_version()->ReportError(status, status_message);
registration()->UnsetVersion(new_version());
@@ -571,7 +577,7 @@ void ServiceWorkerRegisterJob::CompleteInternal(
}
void ServiceWorkerRegisterJob::ResolvePromise(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
ServiceWorkerRegistration* registration) {
DCHECK(!is_promise_resolved_);
@@ -602,20 +608,27 @@ void ServiceWorkerRegisterJob::AddRegistrationToMatchingProviderHosts(
}
}
-void ServiceWorkerRegisterJob::OnScriptLoaded() {
- DCHECK(new_version()->pause_after_download());
- new_version()->set_pause_after_download(false);
+void ServiceWorkerRegisterJob::OnPausedAfterDownload() {
net::URLRequestStatus status =
new_version()->script_cache_map()->main_script_status();
if (!status.is_success()) {
- // OnScriptLoaded signifies a successful network load, which translates into
- // a script cache error only in the byte-for-byte identical case.
+ // OnPausedAfterDownload() signifies a successful network load, which
+ // translates into a script cache error only in the byte-for-byte identical
+ // case.
DCHECK_EQ(status.error(),
ServiceWorkerWriteToCacheJob::kIdenticalScriptError);
BumpLastUpdateCheckTimeIfNeeded();
- ResolvePromise(SERVICE_WORKER_OK, std::string(), registration());
- Complete(SERVICE_WORKER_ERROR_EXISTS,
+ ResolvePromise(blink::ServiceWorkerStatusCode::kOk, std::string(),
+ registration());
+ // Note: Complete() destroys this job and hence risks destroying
+ // |new_version()| inside this callback, which is impolite and dangerous.
+ // But most of this class operates this way, and introducing asynchronicity
+ // here can potentially create bad interactions with other callbacks into
+ // this class, so continue the pattern here. This code path should be
+ // removed anyway when the byte-to-byte update check is moved outside of
+ // worker startup.
+ Complete(blink::ServiceWorkerStatusCode::kErrorExists,
"The updated worker is identical to the incumbent.");
return;
}
@@ -623,16 +636,6 @@ void ServiceWorkerRegisterJob::OnScriptLoaded() {
new_version()->embedded_worker()->ResumeAfterDownload();
}
-void ServiceWorkerRegisterJob::OnDestroyed() {
- // The version's EmbeddedWorkerInstance is getting destructed, so
- // remove the observer to avoid a use-after-free. We expect to continue when
- // the StartWorker() callback is called with failure.
- // TODO(crbug.com/855852): Remove the EmbeddedWorkerInstance::Listener
- // interface and have this class listen to ServiceWorkerVersion directly.
- if (observer_.IsObserving(new_version()->embedded_worker()))
- observer_.Remove(new_version()->embedded_worker());
-}
-
void ServiceWorkerRegisterJob::BumpLastUpdateCheckTimeIfNeeded() {
// Bump the last update check time only when the register/update job fetched
// the version having bypassed the network cache. We assume that the
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 29cd3f2e423..53814919752 100644
--- a/chromium/content/browser/service_worker/service_worker_register_job.h
+++ b/chromium/content/browser/service_worker/service_worker_register_job.h
@@ -10,12 +10,10 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "base/scoped_observer.h"
#include "base/time/time.h"
-#include "content/browser/service_worker/embedded_worker_instance.h"
#include "content/browser/service_worker/service_worker_register_job_base.h"
#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
#include "url/gurl.h"
@@ -36,10 +34,9 @@ namespace content {
// - waiting for older ServiceWorkerVersions to deactivate
// - designating the new version to be the 'active' version
// - updating storage
-class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase,
- public EmbeddedWorkerInstance::Listener {
+class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase {
public:
- typedef base::OnceCallback<void(ServiceWorkerStatusCode status,
+ typedef base::OnceCallback<void(blink::ServiceWorkerStatusCode status,
const std::string& status_message,
ServiceWorkerRegistration* registration)>
RegistrationCallback;
@@ -103,44 +100,42 @@ class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase,
void StartImpl();
void ContinueWithRegistration(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void ContinueWithUpdate(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void RegisterAndContinue();
void ContinueWithUninstallingRegistration(
scoped_refptr<ServiceWorkerRegistration> existing_registration,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void ContinueWithRegistrationForSameScriptUrl(
scoped_refptr<ServiceWorkerRegistration> existing_registration,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
void UpdateAndContinue();
- void OnStartWorkerFinished(ServiceWorkerStatusCode status);
- void OnStoreRegistrationComplete(ServiceWorkerStatusCode status);
+ void OnStartWorkerFinished(blink::ServiceWorkerStatusCode status);
+ void OnStoreRegistrationComplete(blink::ServiceWorkerStatusCode status);
void InstallAndContinue();
- void DispatchInstallEvent(ServiceWorkerStatusCode start_worker_status);
+ void DispatchInstallEvent(blink::ServiceWorkerStatusCode start_worker_status);
void OnInstallFinished(
int request_id,
blink::mojom::ServiceWorkerEventStatus event_status,
bool has_fetch_handler,
base::Time dispatch_event_time);
- void OnInstallFailed(ServiceWorkerStatusCode status);
- void Complete(ServiceWorkerStatusCode status);
- void Complete(ServiceWorkerStatusCode status,
+ void OnInstallFailed(blink::ServiceWorkerStatusCode status);
+ void Complete(blink::ServiceWorkerStatusCode status);
+ void Complete(blink::ServiceWorkerStatusCode status,
const std::string& status_message);
- void CompleteInternal(ServiceWorkerStatusCode status,
+ void CompleteInternal(blink::ServiceWorkerStatusCode status,
const std::string& status_message);
- void ResolvePromise(ServiceWorkerStatusCode status,
+ void ResolvePromise(blink::ServiceWorkerStatusCode status,
const std::string& status_message,
ServiceWorkerRegistration* registration);
void AddRegistrationToMatchingProviderHosts(
ServiceWorkerRegistration* registration);
- // EmbeddedWorkerInstance::Listener implementation:
- void OnScriptLoaded() override;
- void OnDestroyed() override;
+ void OnPausedAfterDownload();
void BumpLastUpdateCheckTimeIfNeeded();
@@ -159,11 +154,10 @@ class ServiceWorkerRegisterJob : public ServiceWorkerRegisterJobBase,
bool should_uninstall_on_failure_;
bool force_bypass_cache_;
bool skip_script_comparison_;
- ServiceWorkerStatusCode promise_resolved_status_;
+ blink::ServiceWorkerStatusCode promise_resolved_status_;
std::string promise_resolved_status_message_;
scoped_refptr<ServiceWorkerRegistration> promise_resolved_registration_;
- ScopedObserver<EmbeddedWorkerInstance, EmbeddedWorkerInstance::Listener>
- observer_;
+
base::WeakPtrFactory<ServiceWorkerRegisterJob> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRegisterJob);
diff --git a/chromium/content/browser/service_worker/service_worker_registration.cc b/chromium/content/browser/service_worker/service_worker_registration.cc
index 98c613109de..dec34316469 100644
--- a/chromium/content/browser/service_worker/service_worker_registration.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration.cc
@@ -14,8 +14,8 @@
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_register_job.h"
#include "content/common/service_worker/service_worker_messages.h"
-#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_thread.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
namespace content {
@@ -64,7 +64,7 @@ ServiceWorkerRegistration::~ServiceWorkerRegistration() {
if (context_)
context_->RemoveLiveRegistration(registration_id_);
if (active_version())
- active_version()->RemoveListener(this);
+ active_version()->RemoveObserver(this);
}
ServiceWorkerVersion* ServiceWorkerRegistration::GetNewestVersion() const {
@@ -126,10 +126,10 @@ void ServiceWorkerRegistration::SetActiveVersion(
if (version)
UnsetVersionInternal(version.get(), &mask);
if (active_version_)
- active_version_->RemoveListener(this);
+ active_version_->RemoveObserver(this);
active_version_ = version;
if (active_version_) {
- active_version_->AddListener(this);
+ active_version_->AddObserver(this);
active_version_->SetNavigationPreloadState(navigation_preload_state_);
}
mask.add(ChangedVersionAttributesMask::ACTIVE_VERSION);
@@ -188,7 +188,7 @@ void ServiceWorkerRegistration::UnsetVersionInternal(
should_activate_when_ready_ = false;
mask->add(ChangedVersionAttributesMask::WAITING_VERSION);
} else if (active_version_.get() == version) {
- active_version_->RemoveListener(this);
+ active_version_->RemoveObserver(this);
active_version_ = nullptr;
mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION);
}
@@ -212,12 +212,12 @@ void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() {
}
if (IsLameDuckActiveVersion()) {
- if (ServiceWorkerUtils::IsServicificationEnabled() &&
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled() &&
active_version()->running_status() == EmbeddedWorkerStatus::RUNNING) {
// If the waiting worker is ready and the active worker needs to be
// swapped out, ask the active worker to trigger idle timer as soon as
// possible.
- active_version()->event_dispatcher()->SetIdleTimerDelayToZero();
+ active_version()->endpoint()->SetIdleTimerDelayToZero();
}
StartLameDuckTimer();
}
@@ -260,7 +260,7 @@ void ServiceWorkerRegistration::ClearWhenReady() {
void ServiceWorkerRegistration::AbortPendingClear(StatusCallback callback) {
DCHECK(context_);
if (!is_uninstalling()) {
- std::move(callback).Run(SERVICE_WORKER_OK);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kOk);
return;
}
is_uninstalling_ = false;
@@ -294,13 +294,13 @@ void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) {
}
if (IsLameDuckActiveVersion()) {
- if (ServiceWorkerUtils::IsServicificationEnabled() &&
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled() &&
should_activate_when_ready_ &&
active_version()->running_status() == EmbeddedWorkerStatus::RUNNING) {
// If the waiting worker is ready and the active worker needs to be
// swapped out, ask the active worker to trigger idle timer as soon as
// possible.
- active_version()->event_dispatcher()->SetIdleTimerDelayToZero();
+ active_version()->endpoint()->SetIdleTimerDelayToZero();
}
StartLameDuckTimer();
}
@@ -497,13 +497,14 @@ void ServiceWorkerRegistration::RegisterRegistrationFinishedCallback(
void ServiceWorkerRegistration::DispatchActivateEvent(
scoped_refptr<ServiceWorkerVersion> activating_version,
- ServiceWorkerStatusCode start_worker_status) {
- if (start_worker_status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode start_worker_status) {
+ if (start_worker_status != blink::ServiceWorkerStatusCode::kOk) {
OnActivateEventFinished(activating_version, start_worker_status);
return;
}
if (activating_version != active_version()) {
- OnActivateEventFinished(activating_version, SERVICE_WORKER_ERROR_FAILED);
+ OnActivateEventFinished(activating_version,
+ blink::ServiceWorkerStatusCode::kErrorFailed);
return;
}
@@ -514,13 +515,13 @@ void ServiceWorkerRegistration::DispatchActivateEvent(
ServiceWorkerMetrics::EventType::ACTIVATE,
base::BindOnce(&ServiceWorkerRegistration::OnActivateEventFinished, this,
activating_version));
- activating_version->event_dispatcher()->DispatchActivateEvent(
+ activating_version->endpoint()->DispatchActivateEvent(
activating_version->CreateSimpleEventCallback(request_id));
}
void ServiceWorkerRegistration::OnActivateEventFinished(
scoped_refptr<ServiceWorkerVersion> activating_version,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
// Activate is prone to failing due to shutdown, because it's triggered when
// tabs close.
bool is_shutdown =
@@ -537,7 +538,7 @@ void ServiceWorkerRegistration::OnActivateEventFinished(
// it should still be activated. However, if the failure occurred during
// shutdown, ignore it to give the worker another chance the next time the
// browser starts up.
- if (is_shutdown && status != SERVICE_WORKER_OK)
+ if (is_shutdown && status != blink::ServiceWorkerStatusCode::kOk)
return;
// "Run the Update State algorithm passing registration's active worker and
@@ -547,7 +548,7 @@ void ServiceWorkerRegistration::OnActivateEventFinished(
}
void ServiceWorkerRegistration::OnDeleteFinished(
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
for (auto& listener : listeners_)
listener.OnRegistrationDeleted(this);
}
@@ -581,7 +582,7 @@ void ServiceWorkerRegistration::Clear() {
}
if (active_version_.get()) {
versions_to_doom.push_back(active_version_);
- active_version_->RemoveListener(this);
+ active_version_->RemoveObserver(this);
active_version_ = nullptr;
mask.add(ChangedVersionAttributesMask::ACTIVE_VERSION);
}
@@ -603,9 +604,9 @@ void ServiceWorkerRegistration::Clear() {
void ServiceWorkerRegistration::OnRestoreFinished(
StatusCallback callback,
scoped_refptr<ServiceWorkerVersion> version,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
if (!context_) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort);
return;
}
context_->storage()->NotifyDoneInstallingRegistration(
diff --git a/chromium/content/browser/service_worker/service_worker_registration.h b/chromium/content/browser/service_worker/service_worker_registration.h
index 032fa94be09..e579f31c727 100644
--- a/chromium/content/browser/service_worker/service_worker_registration.h
+++ b/chromium/content/browser/service_worker/service_worker_registration.h
@@ -36,10 +36,10 @@ class ServiceWorkerActivationTest;
// facilitate multiple controllees being associated with the same registration.
class CONTENT_EXPORT ServiceWorkerRegistration
: public base::RefCounted<ServiceWorkerRegistration>,
- public ServiceWorkerVersion::Listener {
+ public ServiceWorkerVersion::Observer {
public:
using StatusCallback =
- base::OnceCallback<void(ServiceWorkerStatusCode status)>;
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode status)>;
class CONTENT_EXPORT Listener {
public:
@@ -91,7 +91,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
// state. If you require an ACTIVATED version, use
// ServiceWorkerContextWrapper::FindReadyRegistration* to get a registration
// with such a version. Alternatively, use
- // ServiceWorkerVersion::Listener::OnVersionStateChanged to wait for the
+ // ServiceWorkerVersion::Observer::OnVersionStateChanged to wait for the
// ACTIVATING version to become ACTIVATED.
ServiceWorkerVersion* active_version() const {
return active_version_.get();
@@ -187,7 +187,7 @@ class CONTENT_EXPORT ServiceWorkerRegistration
ServiceWorkerVersion* version,
ChangedVersionAttributesMask* mask);
- // ServiceWorkerVersion::Listener override.
+ // ServiceWorkerVersion::Observer override.
void OnNoControllees(ServiceWorkerVersion* version) override;
void OnNoWork(ServiceWorkerVersion* version) override;
@@ -204,19 +204,19 @@ class CONTENT_EXPORT ServiceWorkerRegistration
scoped_refptr<ServiceWorkerVersion> activating_version);
void DispatchActivateEvent(
scoped_refptr<ServiceWorkerVersion> activating_version,
- ServiceWorkerStatusCode start_worker_status);
+ blink::ServiceWorkerStatusCode start_worker_status);
void OnActivateEventFinished(
scoped_refptr<ServiceWorkerVersion> activating_version,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
- void OnDeleteFinished(ServiceWorkerStatusCode status);
+ void OnDeleteFinished(blink::ServiceWorkerStatusCode status);
// This method corresponds to the [[ClearRegistration]] algorithm.
void Clear();
void OnRestoreFinished(StatusCallback callback,
scoped_refptr<ServiceWorkerVersion> version,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
const GURL pattern_;
blink::mojom::ServiceWorkerUpdateViaCache update_via_cache_;
diff --git a/chromium/content/browser/service_worker/service_worker_registration_object_host.cc b/chromium/content/browser/service_worker/service_worker_registration_object_host.cc
index 38ea97ec4ac..4e758bf31af 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_object_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration_object_host.cc
@@ -6,7 +6,7 @@
#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_object_host.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "net/http/http_util.h"
@@ -17,15 +17,15 @@ namespace content {
namespace {
// Returns an object info to send over Mojo. The info must be sent immediately.
-// See ServiceWorkerHandle::CreateCompleteObjectInfoToSend() for details.
+// See ServiceWorkerObjectHost::CreateCompleteObjectInfoToSend() for details.
blink::mojom::ServiceWorkerObjectInfoPtr CreateCompleteObjectInfoToSend(
ServiceWorkerProviderHost* provider_host,
ServiceWorkerVersion* version) {
- base::WeakPtr<ServiceWorkerHandle> service_worker_handle =
- provider_host->GetOrCreateServiceWorkerHandle(version);
- if (!service_worker_handle)
+ base::WeakPtr<ServiceWorkerObjectHost> service_worker_object_host =
+ provider_host->GetOrCreateServiceWorkerObjectHost(version);
+ if (!service_worker_object_host)
return nullptr;
- return service_worker_handle->CreateCompleteObjectInfoToSend();
+ return service_worker_object_host->CreateCompleteObjectInfoToSend();
}
} // anonymous namespace
@@ -212,10 +212,10 @@ void ServiceWorkerRegistrationObjectHost::SetNavigationPreloadHeader(
void ServiceWorkerRegistrationObjectHost::UpdateComplete(
UpdateCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
int64_t registration_id) {
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::string error_message;
blink::mojom::ServiceWorkerErrorType error_type;
GetServiceWorkerErrorTypeForRegistration(status, status_message,
@@ -231,8 +231,8 @@ void ServiceWorkerRegistrationObjectHost::UpdateComplete(
void ServiceWorkerRegistrationObjectHost::UnregistrationComplete(
UnregisterCallback callback,
- ServiceWorkerStatusCode status) {
- if (status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode status) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::string error_message;
blink::mojom::ServiceWorkerErrorType error_type;
GetServiceWorkerErrorTypeForRegistration(status, std::string(), &error_type,
@@ -249,8 +249,8 @@ void ServiceWorkerRegistrationObjectHost::UnregistrationComplete(
void ServiceWorkerRegistrationObjectHost::DidUpdateNavigationPreloadEnabled(
bool enable,
EnableNavigationPreloadCallback callback,
- ServiceWorkerStatusCode status) {
- if (status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode status) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(
blink::mojom::ServiceWorkerErrorType::kUnknown,
std::string(ServiceWorkerConsts::kEnableNavigationPreloadErrorPrefix) +
@@ -267,8 +267,8 @@ void ServiceWorkerRegistrationObjectHost::DidUpdateNavigationPreloadEnabled(
void ServiceWorkerRegistrationObjectHost::DidUpdateNavigationPreloadHeader(
const std::string& value,
SetNavigationPreloadHeaderCallback callback,
- ServiceWorkerStatusCode status) {
- if (status != SERVICE_WORKER_OK) {
+ blink::ServiceWorkerStatusCode status) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
std::move(callback).Run(
blink::mojom::ServiceWorkerErrorType::kUnknown,
std::string(
diff --git a/chromium/content/browser/service_worker/service_worker_registration_object_host.h b/chromium/content/browser/service_worker/service_worker_registration_object_host.h
index 6af91e91ccd..b96daf0cda7 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_object_host.h
+++ b/chromium/content/browser/service_worker/service_worker_registration_object_host.h
@@ -70,25 +70,25 @@ class CONTENT_EXPORT ServiceWorkerRegistrationObjectHost
// Called back from ServiceWorkerContextCore when an update is complete.
void UpdateComplete(UpdateCallback callback,
- ServiceWorkerStatusCode status,
+ blink::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);
+ blink::ServiceWorkerStatusCode status);
// Called back from ServiceWorkerStorage when setting navigation preload is
// complete.
void DidUpdateNavigationPreloadEnabled(
bool enable,
EnableNavigationPreloadCallback callback,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// Called back from ServiceWorkerStorage when setting navigation preload
// header is complete.
void DidUpdateNavigationPreloadHeader(
const std::string& value,
SetNavigationPreloadHeaderCallback callback,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// Sets the corresponding version field to the given version or if the given
// version is nullptr, clears the field.
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 97954034a48..c331293b639 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_status.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration_status.cc
@@ -15,7 +15,7 @@ namespace content {
using blink::WebServiceWorkerError;
void GetServiceWorkerErrorTypeForRegistration(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
blink::mojom::ServiceWorkerErrorType* out_error,
std::string* out_message) {
@@ -23,58 +23,57 @@ void GetServiceWorkerErrorTypeForRegistration(
if (!status_message.empty())
*out_message = status_message;
else
- *out_message = ServiceWorkerStatusToString(status);
+ *out_message = blink::ServiceWorkerStatusToString(status);
switch (status) {
- case SERVICE_WORKER_OK:
+ case blink::ServiceWorkerStatusCode::kOk:
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:
+ case blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorInstallWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorProcessNotFound:
+ case blink::ServiceWorkerStatusCode::kErrorRedundant:
+ case blink::ServiceWorkerStatusCode::kErrorDisallowed:
*out_error = blink::mojom::ServiceWorkerErrorType::kInstall;
return;
- case SERVICE_WORKER_ERROR_NOT_FOUND:
+ case blink::ServiceWorkerStatusCode::kErrorNotFound:
*out_error = blink::mojom::ServiceWorkerErrorType::kNotFound;
return;
- case SERVICE_WORKER_ERROR_NETWORK:
+ case blink::ServiceWorkerStatusCode::kErrorNetwork:
*out_error = blink::mojom::ServiceWorkerErrorType::kNetwork;
return;
- case SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED:
+ case blink::ServiceWorkerStatusCode::kErrorScriptEvaluateFailed:
*out_error = blink::mojom::ServiceWorkerErrorType::kScriptEvaluateFailed;
return;
- case SERVICE_WORKER_ERROR_SECURITY:
+ case blink::ServiceWorkerStatusCode::kErrorSecurity:
*out_error = blink::mojom::ServiceWorkerErrorType::kSecurity;
return;
- case SERVICE_WORKER_ERROR_TIMEOUT:
+ case blink::ServiceWorkerStatusCode::kErrorTimeout:
*out_error = blink::mojom::ServiceWorkerErrorType::kTimeout;
return;
- case SERVICE_WORKER_ERROR_ABORT:
+ case blink::ServiceWorkerStatusCode::kErrorAbort:
*out_error = 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:
+ case blink::ServiceWorkerStatusCode::kErrorActivateWorkerFailed:
+ case blink::ServiceWorkerStatusCode::kErrorIpcFailed:
+ case blink::ServiceWorkerStatusCode::kErrorFailed:
+ case blink::ServiceWorkerStatusCode::kErrorExists:
+ case blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected:
+ case blink::ServiceWorkerStatusCode::kErrorState:
+ case blink::ServiceWorkerStatusCode::kErrorDiskCache:
// 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);
+ NOTREACHED() << "Got unexpected error code: " << static_cast<uint32_t>(status)
+ << " " << blink::ServiceWorkerStatusToString(status);
}
} // namespace content
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 b7368901770..b09c204d65d 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_status.h
+++ b/chromium/content/browser/service_worker/service_worker_registration_status.h
@@ -6,14 +6,14 @@
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_REGISTRATION_STATUS_H_
#include "base/strings/string16.h"
-#include "content/common/service_worker/service_worker_status_code.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_error.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
namespace content {
// This should only be called for errors, where status != OK.
void GetServiceWorkerErrorTypeForRegistration(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::string& status_message,
blink::mojom::ServiceWorkerErrorType* out_error,
std::string* out_message);
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 2a7e84d67f4..35671bbced4 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -25,7 +25,7 @@
#include "content/common/service_worker/service_worker_utils.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 "mojo/core/embedder/embedder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
@@ -46,8 +46,8 @@ int CreateInflightRequest(ServiceWorkerVersion* version) {
}
static void SaveStatusCallback(bool* called,
- ServiceWorkerStatusCode* out,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode* out,
+ blink::ServiceWorkerStatusCode status) {
*called = true;
*out = status;
}
@@ -270,15 +270,13 @@ TEST_F(ServiceWorkerRegistrationTest, FailedRegistrationNoCrash) {
options.scope = kScope;
auto registration = base::MakeRefCounted<ServiceWorkerRegistration>(
options, kRegistrationId, context()->AsWeakPtr());
- auto dispatcher_host = base::MakeRefCounted<ServiceWorkerDispatcherHost>(
- helper_->mock_render_process_id());
// 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);
+ CreateProviderHostForWindow(helper_->mock_render_process_id(),
+ 1 /* dummy provider_id */,
+ true /* is_parent_frame_secure */,
+ context()->AsWeakPtr(), &remote_endpoint);
auto registration_object_host =
std::make_unique<ServiceWorkerRegistrationObjectHost>(
context()->AsWeakPtr(), provider_host.get(), registration);
@@ -370,12 +368,12 @@ class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest {
version_1->script_cache_map()->SetResources(records_1);
version_1->SetMainScriptHttpResponseInfo(
EmbeddedWorkerTestHelper::CreateHttpResponseInfo());
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
context()->storage()->StoreRegistration(
registration_.get(), version_1.get(),
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- ASSERT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
// Give the active version a controllee.
host_ = CreateProviderHostForWindow(
@@ -417,7 +415,7 @@ class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest {
}
void TearDown() override {
- registration_->active_version()->RemoveListener(registration_.get());
+ registration_->active_version()->RemoveObserver(registration_.get());
ServiceWorkerRegistrationTest::TearDown();
}
@@ -661,14 +659,14 @@ class ServiceWorkerRegistrationObjectHostTest
protected:
void SetUp() override {
ServiceWorkerRegistrationTest::SetUp();
- mojo::edk::SetDefaultProcessErrorCallback(base::AdaptCallbackForRepeating(
+ mojo::core::SetDefaultProcessErrorCallback(base::AdaptCallbackForRepeating(
base::BindOnce(&ServiceWorkerRegistrationObjectHostTest::OnMojoError,
base::Unretained(this))));
}
void TearDown() override {
- mojo::edk::SetDefaultProcessErrorCallback(
- mojo::edk::ProcessErrorCallback());
+ mojo::core::SetDefaultProcessErrorCallback(
+ mojo::core::ProcessErrorCallback());
ServiceWorkerRegistrationTest::TearDown();
}
@@ -702,19 +700,21 @@ class ServiceWorkerRegistrationObjectHostTest
return error;
}
- ServiceWorkerStatusCode FindRegistrationInStorage(int64_t registration_id,
- const GURL& scope) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ blink::ServiceWorkerStatusCode FindRegistrationInStorage(
+ int64_t registration_id,
+ const GURL& scope) {
+ base::Optional<blink::ServiceWorkerStatusCode> status;
storage()->FindRegistrationForId(
registration_id, scope,
base::AdaptCallbackForRepeating(base::BindOnce(
- [](ServiceWorkerStatusCode* out_status,
- ServiceWorkerStatusCode status,
+ [](base::Optional<blink::ServiceWorkerStatusCode>* out_status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
*out_status = status;
},
&status)));
- return status;
+ base::RunLoop().RunUntilIdle();
+ return status.value();
}
int64_t SetUpRegistration(const GURL& scope, const GURL& script_url) {
@@ -744,12 +744,13 @@ class ServiceWorkerRegistrationObjectHostTest
version->SetStatus(ServiceWorkerVersion::INSTALLING);
// Make the registration findable via storage functions.
bool called = false;
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
storage()->StoreRegistration(registration.get(), version.get(),
base::AdaptCallbackForRepeating(base::BindOnce(
&SaveStatusCallback, &called, &status)));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
return registration->id();
}
@@ -759,10 +760,10 @@ class ServiceWorkerRegistrationObjectHostTest
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);
+ CreateProviderHostForWindow(helper_->mock_render_process_id(),
+ provider_id,
+ true /* is_parent_frame_secure */,
+ context()->AsWeakPtr(), &remote_endpoint);
host->SetDocumentUrl(document_url);
context()->AddProviderHost(std::move(host));
return remote_endpoint;
@@ -790,11 +791,6 @@ class ServiceWorkerRegistrationObjectHostTest
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_;
@@ -902,12 +898,12 @@ TEST_F(ServiceWorkerRegistrationObjectHostTest, Unregister_Success) {
info->request = nullptr;
info->waiting->request = nullptr;
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationInStorage(registration_id, kScope));
EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
CallUnregister(registration_host_ptr.get()));
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
FindRegistrationInStorage(registration_id, kScope));
EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNotFound,
CallUnregister(registration_host_ptr.get()));
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 379a90df55e..15033201505 100644
--- a/chromium/content/browser/service_worker/service_worker_request_handler.cc
+++ b/chromium/content/browser/service_worker/service_worker_request_handler.cc
@@ -17,7 +17,6 @@
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_url_request_job.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/resource_context.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/child_process_host.h"
@@ -31,6 +30,7 @@
#include "net/url_request/url_request_interceptor.h"
#include "services/network/public/cpp/resource_request_body.h"
#include "storage/browser/blob/blob_storage_context.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
@@ -83,22 +83,20 @@ void ServiceWorkerRequestHandler::InitializeForNavigation(
bool is_parent_frame_secure,
scoped_refptr<network::ResourceRequestBody> body,
const base::Callback<WebContents*(void)>& web_contents_getter) {
- CHECK(IsBrowserSideNavigationEnabled());
-
- // S13nServiceWorker enabled, NetworkService disabled:
- // To start the navigation, InitializeForNavigationNetworkService() is called
- // instead of this, but when that request handler falls back to network,
- // InitializeForNavigation() is called.
- // Since we already determined to fall back to network, don't create another
- // handler.
- if (ServiceWorkerUtils::IsServicificationEnabled())
- return;
-
// Only create a handler when there is a ServiceWorkerNavigationHandlerCore
// to take ownership of a pre-created SeviceWorkerProviderHost.
if (!navigation_handle_core)
return;
+ // This is the legacy path used by non-NetworkService and
+ // non-S13nServiceWorker. The NetworkService/S13nServiceWorker path is
+ // InitializeForNavigationNetworkService().
+ //
+ // This function can still be called with a null navigation_handle_core by
+ // ResourceDispatcherHostImpl::BeginNavigationRequest when S13nSW is on and
+ // NetworkService is off, so this DCHECK must be after the null check above.
+ DCHECK(!blink::ServiceWorkerUtils::IsServicificationEnabled());
+
// Create the handler even for insecure HTTP since it's used in the
// case of redirect to HTTPS.
if (!request->url().SchemeIsHTTPOrHTTPS() &&
@@ -149,7 +147,7 @@ ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
bool is_parent_frame_secure,
scoped_refptr<network::ResourceRequestBody> body,
const base::Callback<WebContents*(void)>& web_contents_getter) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
DCHECK(navigation_handle_core);
// Create the handler even for insecure HTTP since it's used in the
@@ -169,8 +167,7 @@ ServiceWorkerRequestHandler::InitializeForNavigationNetworkService(
// Initialize the SWProviderHost.
base::WeakPtr<ServiceWorkerProviderHost> provider_host =
ServiceWorkerProviderHost::PreCreateNavigationHost(
- navigation_handle_core->context_wrapper()->context()->AsWeakPtr(),
- is_parent_frame_secure, web_contents_getter);
+ context->AsWeakPtr(), is_parent_frame_secure, web_contents_getter);
std::unique_ptr<ServiceWorkerRequestHandler> handler(
provider_host->CreateRequestHandler(
@@ -192,7 +189,7 @@ std::unique_ptr<NavigationLoaderInterceptor>
ServiceWorkerRequestHandler::InitializeForSharedWorker(
const network::ResourceRequest& resource_request,
base::WeakPtr<ServiceWorkerProviderHost> host) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
// Create the handler even for insecure HTTP since it's used in the
// case of redirect to HTTPS.
@@ -237,7 +234,7 @@ void ServiceWorkerRequestHandler::InitializeHandler(
// request handler falls back to network, InitializeHandler() is called.
// Since we already determined to fall back to network, don't create another
// handler.
- if (ServiceWorkerUtils::IsServicificationEnabled())
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
return;
// Create the handler even for insecure HTTP since it's used in the
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 1dc6fb71f4e..5ab4546ffb3 100644
--- a/chromium/content/browser/service_worker/service_worker_request_handler.h
+++ b/chromium/content/browser/service_worker/service_worker_request_handler.h
@@ -14,13 +14,13 @@
#include "base/time/time.h"
#include "content/browser/loader/navigation_loader_interceptor.h"
#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
#include "net/url_request/url_request_job_factory.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace net {
class NetworkDelegate;
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 a49f0d0f0e2..1806fc576cd 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
@@ -25,6 +25,7 @@
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
namespace service_worker_request_handler_unittest {
@@ -119,6 +120,11 @@ class ServiceWorkerRequestHandlerTest : public testing::Test {
const std::string& method,
bool skip_service_worker,
ResourceType resource_type) {
+ // Skip handler initialization tests when S13nServiceWorker is enabled
+ // because we don't use this path. See also comments in
+ // ServiceWorkerRequestHandler::InitializeHandler().
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
+ return;
InitializeProviderHostForWindow();
std::unique_ptr<net::URLRequest> request = CreateRequest(url, method);
InitializeHandler(request.get(), skip_service_worker, resource_type);
diff --git a/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc b/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc
index 344db0e12f9..e90b006c0fd 100644
--- a/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc
+++ b/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc
@@ -10,10 +10,10 @@
#include "content/browser/service_worker/service_worker_new_script_loader.h"
#include "content/browser/service_worker/service_worker_provider_host.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"
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
@@ -38,24 +38,30 @@ void ServiceWorkerScriptLoaderFactory::CreateLoaderAndStart(
const network::ResourceRequest& resource_request,
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
- if (!ShouldHandleScriptRequest(resource_request)) {
- // If the request should not be handled, just do a passthrough load. This
- // needs a relaying as we use different associated message pipes.
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
+ if (!CheckIfScriptRequestIsValid(resource_request)) {
// TODO(kinuko): Record the reason like what we do with netlog in
// ServiceWorkerContextRequestHandler.
- loader_factory_->CreateLoaderAndStart(
- std::move(request), routing_id, request_id, options, resource_request,
- std::move(client), traffic_annotation);
+ client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_ABORTED));
return;
}
- // If we get here, the service worker is not installed, so the script is
- // usually not yet installed. However, there is a special case when an
- // installing worker that imports the same script twice (e.g.
- // importScripts('dupe.js'); importScripts('dupe.js');) or if it recursively
- // imports the main script. In this case, read the installed script from
- // storage.
+ // There are four cases of how to handle the request for the script.
+ // A) service worker is installed, script is installed: serve from storage
+ // (use ServceWorkerInstalledScriptLoader). Typically this case is handled
+ // by ServiceWorkerInstalledScriptsSender, but we can still get here when a
+ // new service worker starts up and becomes installed while it is running.
+ // B) service worker is installed, script is not installed: serve from direct
+ // network. This happens when the script is newly imported after
+ // installation.
+ // TODO(crbug.com/719052): deprecate this.
+ // C) service worker is not installed, script is installed: serve from
+ // storage (use ServceWorkerInstalledScriptLoader)
+ // D) service worker is not installed, script is not installed: serve from
+ // network with installing the script (use ServceWorkerNewScriptLoader)
+ // This is the common case: load the script and install it.
+
+ // Case A and C:
scoped_refptr<ServiceWorkerVersion> version =
provider_host_->running_hosted_version();
int64_t resource_id =
@@ -70,7 +76,17 @@ void ServiceWorkerScriptLoaderFactory::CreateLoaderAndStart(
return;
}
- // The common case: load the script and install it.
+ // Case B:
+ if (ServiceWorkerVersion::IsInstalled(version->status())) {
+ // TODO(kinuko): Record the reason like what we do with netlog in
+ // ServiceWorkerContextRequestHandler.
+ loader_factory_->CreateLoaderAndStart(
+ std::move(request), routing_id, request_id, options, resource_request,
+ std::move(client), traffic_annotation);
+ return;
+ }
+
+ // Case D:
mojo::MakeStrongBinding(
std::make_unique<ServiceWorkerNewScriptLoader>(
routing_id, request_id, options, resource_request, std::move(client),
@@ -81,12 +97,10 @@ void ServiceWorkerScriptLoaderFactory::CreateLoaderAndStart(
void ServiceWorkerScriptLoaderFactory::Clone(
network::mojom::URLLoaderFactoryRequest request) {
- // This method is required to support synchronous requests which are not
- // performed during installation.
- NOTREACHED();
+ bindings_.AddBinding(this, std::move(request));
}
-bool ServiceWorkerScriptLoaderFactory::ShouldHandleScriptRequest(
+bool ServiceWorkerScriptLoaderFactory::CheckIfScriptRequestIsValid(
const network::ResourceRequest& resource_request) {
if (!context_ || !provider_host_)
return false;
@@ -98,45 +112,23 @@ bool ServiceWorkerScriptLoaderFactory::ShouldHandleScriptRequest(
// Handle only the service worker main script (RESOURCE_TYPE_SERVICE_WORKER)
// or importScripts() (RESOURCE_TYPE_SCRIPT).
- switch (resource_request.resource_type) {
- case RESOURCE_TYPE_SERVICE_WORKER:
- // The main script should be fetched only when we start a new service
- // worker.
- if (version->status() != ServiceWorkerVersion::NEW)
- return false;
- break;
- case RESOURCE_TYPE_SCRIPT:
- // TODO(nhiroki): In the current implementation, importScripts() can be
- // called in any ServiceWorkerVersion::Status except for REDUNDANT, but
- // the spec defines importScripts() works only on the initial script
- // evaluation and the install event. Update this check once
- // importScripts() is fixed (https://crbug.com/719052).
- if (version->status() == ServiceWorkerVersion::REDUNDANT) {
- // This could happen if browser-side has set the status to redundant but
- // the worker has not yet stopped. The worker is already doomed so just
- // reject the request. Handle it specially here because otherwise it'd
- // be unclear whether "REDUNDANT" should count as installed or not
- // installed when making decisions about how to handle the request and
- // logging UMA.
- return false;
- }
- break;
- default:
- // TODO(nhiroki): Record bad message, we shouldn't come here for other
- // request types.
- NOTREACHED();
- return false;
+ if (resource_request.resource_type != RESOURCE_TYPE_SERVICE_WORKER &&
+ resource_request.resource_type != RESOURCE_TYPE_SCRIPT) {
+ mojo::ReportBadMessage("SWSLF_BAD_RESOURCE_TYPE");
+ return false;
}
- // TODO(falken): Make sure we don't handle a redirected request.
-
- // For installed service workers, typically all the scripts are served via
- // script streaming, so we don't come here. However, we still come here when
- // the service worker is importing a script that was never installed. For now,
- // return false here to fallback to network. Eventually, it should be
- // deprecated (https://crbug.com/719052).
- if (ServiceWorkerVersion::IsInstalled(version->status()))
+ if (version->status() == ServiceWorkerVersion::REDUNDANT) {
+ // This could happen if browser-side has set the status to redundant but
+ // the worker has not yet stopped. The worker is already doomed so just
+ // reject the request. Handle it specially here because otherwise it'd
+ // be unclear whether "REDUNDANT" should count as installed or not
+ // installed when making decisions about how to handle the request and
+ // logging UMA.
return false;
+ }
+
+ // TODO(falken): Make sure we don't handle a redirected request.
return true;
}
diff --git a/chromium/content/browser/service_worker/service_worker_script_loader_factory.h b/chromium/content/browser/service_worker/service_worker_script_loader_factory.h
index 995bb61f499..efc08ff62e5 100644
--- a/chromium/content/browser/service_worker/service_worker_script_loader_factory.h
+++ b/chromium/content/browser/service_worker/service_worker_script_loader_factory.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_LOADER_FACTORY_H_
#include "base/macros.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace network {
@@ -54,13 +55,15 @@ class ServiceWorkerScriptLoaderFactory
void Clone(network::mojom::URLLoaderFactoryRequest request) override;
private:
- bool ShouldHandleScriptRequest(
+ bool CheckIfScriptRequestIsValid(
const network::ResourceRequest& resource_request);
base::WeakPtr<ServiceWorkerContextCore> context_;
base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
+ mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerScriptLoaderFactory);
};
diff --git a/chromium/content/browser/service_worker/service_worker_storage.cc b/chromium/content/browser/service_worker/service_worker_storage.cc
index 81676aaacaf..93a71912a4c 100644
--- a/chromium/content/browser/service_worker/service_worker_storage.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage.cc
@@ -44,11 +44,12 @@ void RunSoon(const base::Location& from_here, base::OnceClosure closure) {
}
void CompleteFindNow(scoped_refptr<ServiceWorkerRegistration> registration,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
ServiceWorkerStorage::FindRegistrationCallback callback) {
if (registration && registration->is_deleted()) {
// It's past the point of no return and no longer findable.
- std::move(callback).Run(SERVICE_WORKER_ERROR_NOT_FOUND, nullptr);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorNotFound,
+ nullptr);
return;
}
std::move(callback).Run(status, std::move(registration));
@@ -56,7 +57,7 @@ void CompleteFindNow(scoped_refptr<ServiceWorkerRegistration> registration,
void CompleteFindSoon(const base::Location& from_here,
scoped_refptr<ServiceWorkerRegistration> registration,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
ServiceWorkerStorage::FindRegistrationCallback callback) {
RunSoon(from_here, base::BindOnce(&CompleteFindNow, std::move(registration),
status, std::move(callback)));
@@ -70,18 +71,18 @@ const base::FilePath::CharType kDiskCacheName[] =
const int kMaxServiceWorkerStorageMemDiskCacheSize = 10 * 1024 * 1024;
const int kMaxServiceWorkerStorageDiskCacheSize = 250 * 1024 * 1024;
-ServiceWorkerStatusCode DatabaseStatusToStatusCode(
+blink::ServiceWorkerStatusCode DatabaseStatusToStatusCode(
ServiceWorkerDatabase::Status status) {
switch (status) {
case ServiceWorkerDatabase::STATUS_OK:
- return SERVICE_WORKER_OK;
+ return blink::ServiceWorkerStatusCode::kOk;
case ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND:
- return SERVICE_WORKER_ERROR_NOT_FOUND;
+ return blink::ServiceWorkerStatusCode::kErrorNotFound;
case ServiceWorkerDatabase::STATUS_ERROR_MAX:
NOTREACHED();
FALLTHROUGH;
default:
- return SERVICE_WORKER_ERROR_FAILED;
+ return blink::ServiceWorkerStatusCode::kErrorFailed;
}
}
@@ -148,7 +149,8 @@ void ServiceWorkerStorage::FindRegistrationForDocument(
switch (state_) {
case DISABLED:
CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(),
- SERVICE_WORKER_ERROR_ABORT, std::move(callback));
+ blink::ServiceWorkerStatusCode::kErrorAbort,
+ std::move(callback));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -169,15 +171,15 @@ void ServiceWorkerStorage::FindRegistrationForDocument(
// Look for something currently being installed.
scoped_refptr<ServiceWorkerRegistration> installing_registration =
FindInstallingRegistrationForDocument(document_url);
- ServiceWorkerStatusCode status = installing_registration
- ? SERVICE_WORKER_OK
- : SERVICE_WORKER_ERROR_NOT_FOUND;
+ blink::ServiceWorkerStatusCode status =
+ installing_registration
+ ? blink::ServiceWorkerStatusCode::kOk
+ : blink::ServiceWorkerStatusCode::kErrorNotFound;
TRACE_EVENT_INSTANT2(
"ServiceWorker",
"ServiceWorkerStorage::FindRegistrationForDocument:CheckInstalling",
- TRACE_EVENT_SCOPE_THREAD,
- "URL", document_url.spec(),
- "Status", ServiceWorkerStatusToString(status));
+ TRACE_EVENT_SCOPE_THREAD, "URL", document_url.spec(), "Status",
+ blink::ServiceWorkerStatusToString(status));
CompleteFindNow(std::move(installing_registration), status,
std::move(callback));
return;
@@ -205,7 +207,8 @@ void ServiceWorkerStorage::FindRegistrationForPattern(
switch (state_) {
case DISABLED:
CompleteFindSoon(FROM_HERE, scoped_refptr<ServiceWorkerRegistration>(),
- SERVICE_WORKER_ERROR_ABORT, std::move(callback));
+ blink::ServiceWorkerStatusCode::kErrorAbort,
+ std::move(callback));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -222,9 +225,10 @@ void ServiceWorkerStorage::FindRegistrationForPattern(
// Look for something currently being installed.
scoped_refptr<ServiceWorkerRegistration> installing_registration =
FindInstallingRegistrationForPattern(scope);
- ServiceWorkerStatusCode installing_status =
- installing_registration ? SERVICE_WORKER_OK
- : SERVICE_WORKER_ERROR_NOT_FOUND;
+ blink::ServiceWorkerStatusCode installing_status =
+ installing_registration
+ ? blink::ServiceWorkerStatusCode::kOk
+ : blink::ServiceWorkerStatusCode::kErrorNotFound;
CompleteFindSoon(FROM_HERE, std::move(installing_registration),
installing_status, std::move(callback));
return;
@@ -260,7 +264,8 @@ void ServiceWorkerStorage::FindRegistrationForId(
switch (state_) {
case DISABLED:
CompleteFindNow(scoped_refptr<ServiceWorkerRegistration>(),
- SERVICE_WORKER_ERROR_ABORT, std::move(callback));
+ blink::ServiceWorkerStatusCode::kErrorAbort,
+ std::move(callback));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -279,8 +284,9 @@ void ServiceWorkerStorage::FindRegistrationForId(
scoped_refptr<ServiceWorkerRegistration> installing_registration =
FindInstallingRegistrationForId(registration_id);
CompleteFindNow(installing_registration,
- installing_registration ? SERVICE_WORKER_OK
- : SERVICE_WORKER_ERROR_NOT_FOUND,
+ installing_registration
+ ? blink::ServiceWorkerStatusCode::kOk
+ : blink::ServiceWorkerStatusCode::kErrorNotFound,
std::move(callback));
return;
}
@@ -288,8 +294,8 @@ void ServiceWorkerStorage::FindRegistrationForId(
scoped_refptr<ServiceWorkerRegistration> registration =
context_->GetLiveRegistration(registration_id);
if (registration) {
- CompleteFindNow(std::move(registration), SERVICE_WORKER_OK,
- std::move(callback));
+ CompleteFindNow(std::move(registration),
+ blink::ServiceWorkerStatusCode::kOk, std::move(callback));
return;
}
@@ -307,7 +313,8 @@ void ServiceWorkerStorage::FindRegistrationForIdOnly(
FindRegistrationCallback callback) {
switch (state_) {
case DISABLED:
- CompleteFindNow(nullptr, SERVICE_WORKER_ERROR_ABORT, std::move(callback));
+ CompleteFindNow(nullptr, blink::ServiceWorkerStatusCode::kErrorAbort,
+ std::move(callback));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -345,10 +352,11 @@ void ServiceWorkerStorage::GetRegistrationsForOrigin(
GetRegistrationsCallback callback) {
switch (state_) {
case DISABLED:
- RunSoon(FROM_HERE,
- base::BindOnce(
- std::move(callback), SERVICE_WORKER_ERROR_ABORT,
- std::vector<scoped_refptr<ServiceWorkerRegistration>>()));
+ RunSoon(
+ FROM_HERE,
+ base::BindOnce(
+ std::move(callback), blink::ServiceWorkerStatusCode::kErrorAbort,
+ std::vector<scoped_refptr<ServiceWorkerRegistration>>()));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -378,7 +386,8 @@ void ServiceWorkerStorage::GetAllRegistrationsInfos(
switch (state_) {
case DISABLED:
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT,
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort,
std::vector<ServiceWorkerRegistrationInfo>()));
return;
case INITIALIZING: // Fall-through.
@@ -411,7 +420,8 @@ void ServiceWorkerStorage::StoreRegistration(
DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
if (IsDisabled()) {
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
@@ -439,7 +449,8 @@ void ServiceWorkerStorage::StoreRegistration(
if (resources.empty()) {
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_FAILED));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
@@ -471,7 +482,8 @@ void ServiceWorkerStorage::UpdateToActiveState(
DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
if (IsDisabled()) {
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
@@ -507,7 +519,7 @@ void ServiceWorkerStorage::UpdateNavigationPreloadEnabled(
StatusCallback callback) {
DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
if (IsDisabled()) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort);
return;
}
@@ -526,7 +538,7 @@ void ServiceWorkerStorage::UpdateNavigationPreloadHeader(
StatusCallback callback) {
DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
if (IsDisabled()) {
- std::move(callback).Run(SERVICE_WORKER_ERROR_ABORT);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort);
return;
}
@@ -544,7 +556,8 @@ void ServiceWorkerStorage::DeleteRegistration(int64_t registration_id,
DCHECK(state_ == INITIALIZED || state_ == DISABLED) << state_;
if (IsDisabled()) {
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
@@ -636,7 +649,8 @@ void ServiceWorkerStorage::StoreUserData(
switch (state_) {
case DISABLED:
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -651,13 +665,15 @@ void ServiceWorkerStorage::StoreUserData(
if (registration_id == blink::mojom::kInvalidServiceWorkerRegistrationId ||
key_value_pairs.empty()) {
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_FAILED));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
for (const auto& kv : key_value_pairs) {
if (kv.first.empty()) {
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_FAILED));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
}
@@ -678,7 +694,7 @@ void ServiceWorkerStorage::GetUserData(int64_t registration_id,
case DISABLED:
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback), std::vector<std::string>(),
- SERVICE_WORKER_ERROR_ABORT));
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -694,14 +710,14 @@ void ServiceWorkerStorage::GetUserData(int64_t registration_id,
keys.empty()) {
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback), std::vector<std::string>(),
- SERVICE_WORKER_ERROR_FAILED));
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
for (const std::string& key : keys) {
if (key.empty()) {
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback), std::vector<std::string>(),
- SERVICE_WORKER_ERROR_FAILED));
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
}
@@ -723,7 +739,7 @@ void ServiceWorkerStorage::GetUserDataByKeyPrefix(
case DISABLED:
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback), std::vector<std::string>(),
- SERVICE_WORKER_ERROR_ABORT));
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -739,13 +755,13 @@ void ServiceWorkerStorage::GetUserDataByKeyPrefix(
if (registration_id == blink::mojom::kInvalidServiceWorkerRegistrationId) {
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback), std::vector<std::string>(),
- SERVICE_WORKER_ERROR_FAILED));
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
if (key_prefix.empty()) {
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback), std::vector<std::string>(),
- SERVICE_WORKER_ERROR_FAILED));
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
@@ -767,7 +783,7 @@ void ServiceWorkerStorage::GetUserKeysAndDataByKeyPrefix(
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback),
base::flat_map<std::string, std::string>(),
- SERVICE_WORKER_ERROR_ABORT));
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -785,7 +801,7 @@ void ServiceWorkerStorage::GetUserKeysAndDataByKeyPrefix(
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback),
base::flat_map<std::string, std::string>(),
- SERVICE_WORKER_ERROR_FAILED));
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
@@ -805,7 +821,8 @@ void ServiceWorkerStorage::ClearUserData(int64_t registration_id,
switch (state_) {
case DISABLED:
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -820,13 +837,15 @@ void ServiceWorkerStorage::ClearUserData(int64_t registration_id,
if (registration_id == blink::mojom::kInvalidServiceWorkerRegistrationId ||
keys.empty()) {
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_FAILED));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
for (const std::string& key : keys) {
if (key.empty()) {
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_FAILED));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
}
@@ -846,7 +865,8 @@ void ServiceWorkerStorage::ClearUserDataByKeyPrefixes(
switch (state_) {
case DISABLED:
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -862,13 +882,15 @@ void ServiceWorkerStorage::ClearUserDataByKeyPrefixes(
if (registration_id == blink::mojom::kInvalidServiceWorkerRegistrationId ||
key_prefixes.empty()) {
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_FAILED));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
for (const std::string& key_prefix : key_prefixes) {
if (key_prefix.empty()) {
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_FAILED));
+ base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
}
@@ -890,7 +912,7 @@ void ServiceWorkerStorage::GetUserDataForAllRegistrations(
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback),
std::vector<std::pair<int64_t, std::string>>(),
- SERVICE_WORKER_ERROR_ABORT));
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -906,7 +928,7 @@ void ServiceWorkerStorage::GetUserDataForAllRegistrations(
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback),
std::vector<std::pair<int64_t, std::string>>(),
- SERVICE_WORKER_ERROR_FAILED));
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
@@ -928,7 +950,7 @@ void ServiceWorkerStorage::GetUserDataForAllRegistrationsByKeyPrefix(
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback),
std::vector<std::pair<int64_t, std::string>>(),
- SERVICE_WORKER_ERROR_ABORT));
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
case INITIALIZING: // Fall-through.
case UNINITIALIZED:
@@ -944,7 +966,7 @@ void ServiceWorkerStorage::GetUserDataForAllRegistrationsByKeyPrefix(
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback),
std::vector<std::pair<int64_t, std::string>>(),
- SERVICE_WORKER_ERROR_FAILED));
+ blink::ServiceWorkerStatusCode::kErrorFailed));
return;
}
@@ -1012,11 +1034,11 @@ void ServiceWorkerStorage::NotifyInstallingRegistration(
}
void ServiceWorkerStorage::NotifyDoneInstallingRegistration(
- ServiceWorkerRegistration* registration,
- ServiceWorkerVersion* version,
- ServiceWorkerStatusCode status) {
+ ServiceWorkerRegistration* registration,
+ ServiceWorkerVersion* version,
+ blink::ServiceWorkerStatusCode status) {
installing_registrations_.erase(registration->id());
- if (status != SERVICE_WORKER_OK && version) {
+ if (status != blink::ServiceWorkerStatusCode::kOk && version) {
ResourceList resources;
version->script_cache_map()->GetResources(&resources);
@@ -1160,20 +1182,19 @@ void ServiceWorkerStorage::DidFindRegistrationForDocument(
// Look for something currently being installed.
scoped_refptr<ServiceWorkerRegistration> installing_registration =
FindInstallingRegistrationForDocument(document_url);
- ServiceWorkerStatusCode installing_status =
- installing_registration ? SERVICE_WORKER_OK
- : SERVICE_WORKER_ERROR_NOT_FOUND;
+ blink::ServiceWorkerStatusCode installing_status =
+ installing_registration
+ ? blink::ServiceWorkerStatusCode::kOk
+ : blink::ServiceWorkerStatusCode::kErrorNotFound;
std::move(callback).Run(installing_status,
std::move(installing_registration));
TRACE_EVENT_ASYNC_END2(
- "ServiceWorker",
- "ServiceWorkerStorage::FindRegistrationForDocument",
- callback_id,
- "Status", ServiceWorkerDatabase::StatusToString(status),
+ "ServiceWorker", "ServiceWorkerStorage::FindRegistrationForDocument",
+ callback_id, "Status", ServiceWorkerDatabase::StatusToString(status),
"Info",
- (installing_status == SERVICE_WORKER_OK) ?
- "Installing registration is found" :
- "Any registrations are not found");
+ (installing_status == blink::ServiceWorkerStatusCode::kOk)
+ ? "Installing registration is found"
+ : "Any registrations are not found");
return;
}
@@ -1201,9 +1222,10 @@ void ServiceWorkerStorage::DidFindRegistrationForPattern(
if (status == ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND) {
scoped_refptr<ServiceWorkerRegistration> installing_registration =
FindInstallingRegistrationForPattern(scope);
- ServiceWorkerStatusCode installing_status =
- installing_registration ? SERVICE_WORKER_OK
- : SERVICE_WORKER_ERROR_NOT_FOUND;
+ blink::ServiceWorkerStatusCode installing_status =
+ installing_registration
+ ? blink::ServiceWorkerStatusCode::kOk
+ : blink::ServiceWorkerStatusCode::kErrorNotFound;
std::move(callback).Run(installing_status,
std::move(installing_registration));
return;
@@ -1243,7 +1265,7 @@ void ServiceWorkerStorage::ReturnFoundRegistration(
DCHECK(!resources.empty());
scoped_refptr<ServiceWorkerRegistration> registration =
GetOrCreateRegistration(data, resources);
- CompleteFindNow(std::move(registration), SERVICE_WORKER_OK,
+ CompleteFindNow(std::move(registration), blink::ServiceWorkerStatusCode::kOk,
std::move(callback));
}
@@ -1284,7 +1306,8 @@ void ServiceWorkerStorage::DidGetRegistrationsForOrigin(
registrations.push_back(registration.second);
}
- std::move(callback).Run(SERVICE_WORKER_OK, std::move(registrations));
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kOk,
+ std::move(registrations));
}
void ServiceWorkerStorage::DidGetAllRegistrationsInfos(
@@ -1359,7 +1382,7 @@ void ServiceWorkerStorage::DidGetAllRegistrationsInfos(
infos.push_back(registration.second->GetInfo());
}
- std::move(callback).Run(SERVICE_WORKER_OK, infos);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kOk, infos);
}
void ServiceWorkerStorage::DidStoreRegistration(
@@ -1393,7 +1416,7 @@ void ServiceWorkerStorage::DidStoreRegistration(
context_->NotifyRegistrationStored(new_version.registration_id,
new_version.scope);
- std::move(callback).Run(SERVICE_WORKER_OK);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kOk);
if (!context_->GetLiveVersion(deleted_version.version_id))
StartPurgingResources(newly_purgeable_resources);
@@ -1431,7 +1454,7 @@ void ServiceWorkerStorage::DidDeleteRegistration(
}
if (origin_state == OriginState::kDelete)
registered_origins_.erase(params->origin);
- std::move(params->callback).Run(SERVICE_WORKER_OK);
+ std::move(params->callback).Run(blink::ServiceWorkerStatusCode::kOk);
if (!context_->GetLiveVersion(deleted_version.version_id))
StartPurgingResources(newly_purgeable_resources);
@@ -2112,13 +2135,13 @@ void ServiceWorkerStorage::DidDeleteDiskCache(StatusCallback callback,
LOG(ERROR) << "Failed to delete the diskcache.";
ServiceWorkerMetrics::RecordDeleteAndStartOverResult(
ServiceWorkerMetrics::DELETE_DISK_CACHE_ERROR);
- std::move(callback).Run(SERVICE_WORKER_ERROR_FAILED);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorFailed);
return;
}
DVLOG(1) << "Deleted ServiceWorkerDiskCache successfully.";
ServiceWorkerMetrics::RecordDeleteAndStartOverResult(
ServiceWorkerMetrics::DELETE_OK);
- std::move(callback).Run(SERVICE_WORKER_OK);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kOk);
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_storage.h b/chromium/content/browser/service_worker/service_worker_storage.h
index 88a1c291efb..722ba4e9f42 100644
--- a/chromium/content/browser/service_worker/service_worker_storage.h
+++ b/chromium/content/browser/service_worker/service_worker_storage.h
@@ -25,7 +25,7 @@
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"
namespace base {
@@ -69,30 +69,30 @@ FORWARD_DECLARE_TEST(ServiceWorkerResourceStorageDiskTest,
// disabled and all subsequent requests are aborted until the context core is
// restarted.
class CONTENT_EXPORT ServiceWorkerStorage
- : public ServiceWorkerVersion::Listener {
+ : public ServiceWorkerVersion::Observer {
public:
using ResourceList = std::vector<ServiceWorkerDatabase::ResourceRecord>;
using StatusCallback =
- base::OnceCallback<void(ServiceWorkerStatusCode status)>;
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode status)>;
using FindRegistrationCallback = base::OnceCallback<void(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration)>;
using GetRegistrationsCallback = base::OnceCallback<void(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<scoped_refptr<ServiceWorkerRegistration>>&
registrations)>;
using GetRegistrationsInfosCallback = base::OnceCallback<void(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<ServiceWorkerRegistrationInfo>& registrations)>;
using GetUserDataCallback =
base::OnceCallback<void(const std::vector<std::string>& data,
- ServiceWorkerStatusCode status)>;
+ blink::ServiceWorkerStatusCode status)>;
using GetUserKeysAndDataCallback = base::OnceCallback<void(
const base::flat_map<std::string, std::string>& data_map,
- ServiceWorkerStatusCode status)>;
+ blink::ServiceWorkerStatusCode status)>;
using GetUserDataForAllRegistrationsCallback = base::OnceCallback<void(
const std::vector<std::pair<int64_t, std::string>>& user_data,
- ServiceWorkerStatusCode status)>;
+ blink::ServiceWorkerStatusCode status)>;
~ServiceWorkerStorage() override;
@@ -110,9 +110,10 @@ class CONTENT_EXPORT ServiceWorkerStorage
// Finds registration for |document_url| or |pattern| or |registration_id|.
// The Find methods will find stored and initially installing registrations.
- // Returns SERVICE_WORKER_OK with non-null registration if registration
- // is found, or returns SERVICE_WORKER_ERROR_NOT_FOUND if no matching
- // registration is found. The FindRegistrationForPattern method is
+ // Returns blink::ServiceWorkerStatusCode::kOk with non-null
+ // registration if registration is found, or returns
+ // blink::ServiceWorkerStatusCode::kErrorNotFound if no
+ // matching registration is found. The FindRegistrationForPattern method is
// guaranteed to return asynchronously. However, the methods to find
// for |document_url| or |registration_id| may complete immediately
// (the callback may be called prior to the method returning) or
@@ -259,10 +260,9 @@ class CONTENT_EXPORT ServiceWorkerStorage
// ServiceWorkerRegistration.
void NotifyInstallingRegistration(
ServiceWorkerRegistration* registration);
- void NotifyDoneInstallingRegistration(
- ServiceWorkerRegistration* registration,
- ServiceWorkerVersion* version,
- ServiceWorkerStatusCode status);
+ void NotifyDoneInstallingRegistration(ServiceWorkerRegistration* registration,
+ ServiceWorkerVersion* version,
+ blink::ServiceWorkerStatusCode status);
void NotifyUninstallingRegistration(ServiceWorkerRegistration* registration);
void NotifyDoneUninstallingRegistration(
ServiceWorkerRegistration* registration);
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 1c69543d47c..babac6c2096 100644
--- a/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -14,7 +14,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
@@ -23,7 +23,6 @@
#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_status_code.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/common/content_client.h"
#include "content/public/common/origin_util.h"
@@ -40,6 +39,7 @@
#include "net/test/test_data_directory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/origin_trials/origin_trial_policy.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
@@ -68,30 +68,30 @@ const uint8_t kTestPublicKey[] = {
0x64, 0x90, 0x08, 0x8e, 0xa8, 0xe0, 0x56, 0x3a, 0x04, 0xd0,
};
-void StatusAndQuitCallback(ServiceWorkerStatusCode* result,
+void StatusAndQuitCallback(blink::ServiceWorkerStatusCode* result,
const base::Closure& quit_closure,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
*result = status;
quit_closure.Run();
}
void StatusCallback(bool* was_called,
- ServiceWorkerStatusCode* result,
- ServiceWorkerStatusCode status) {
+ base::Optional<blink::ServiceWorkerStatusCode>* result,
+ blink::ServiceWorkerStatusCode status) {
*was_called = true;
*result = status;
}
ServiceWorkerStorage::StatusCallback MakeStatusCallback(
bool* was_called,
- ServiceWorkerStatusCode* result) {
+ base::Optional<blink::ServiceWorkerStatusCode>* result) {
return base::BindOnce(&StatusCallback, was_called, result);
}
void FindCallback(bool* was_called,
- ServiceWorkerStatusCode* result,
+ base::Optional<blink::ServiceWorkerStatusCode>* result,
scoped_refptr<ServiceWorkerRegistration>* found,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
*was_called = true;
*result = status;
@@ -100,16 +100,16 @@ void FindCallback(bool* was_called,
ServiceWorkerStorage::FindRegistrationCallback MakeFindCallback(
bool* was_called,
- ServiceWorkerStatusCode* result,
+ base::Optional<blink::ServiceWorkerStatusCode>* result,
scoped_refptr<ServiceWorkerRegistration>* found) {
return base::BindOnce(&FindCallback, was_called, result, found);
}
void GetAllCallback(
bool* was_called,
- ServiceWorkerStatusCode* result,
+ base::Optional<blink::ServiceWorkerStatusCode>* result,
std::vector<scoped_refptr<ServiceWorkerRegistration>>* all_out,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<scoped_refptr<ServiceWorkerRegistration>>& all) {
*was_called = true;
*result = status;
@@ -118,9 +118,9 @@ void GetAllCallback(
void GetAllInfosCallback(
bool* was_called,
- ServiceWorkerStatusCode* result,
+ base::Optional<blink::ServiceWorkerStatusCode>* result,
std::vector<ServiceWorkerRegistrationInfo>* all_out,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
const std::vector<ServiceWorkerRegistrationInfo>& all) {
*was_called = true;
*result = status;
@@ -129,7 +129,7 @@ void GetAllInfosCallback(
ServiceWorkerStorage::GetRegistrationsCallback MakeGetRegistrationsCallback(
bool* was_called,
- ServiceWorkerStatusCode* status,
+ base::Optional<blink::ServiceWorkerStatusCode>* status,
std::vector<scoped_refptr<ServiceWorkerRegistration>>* all) {
return base::BindOnce(&GetAllCallback, was_called, status, all);
}
@@ -137,16 +137,17 @@ ServiceWorkerStorage::GetRegistrationsCallback MakeGetRegistrationsCallback(
ServiceWorkerStorage::GetRegistrationsInfosCallback
MakeGetRegistrationsInfosCallback(
bool* was_called,
- ServiceWorkerStatusCode* status,
+ base::Optional<blink::ServiceWorkerStatusCode>* status,
std::vector<ServiceWorkerRegistrationInfo>* all) {
return base::BindOnce(&GetAllInfosCallback, was_called, status, all);
}
-void GetUserDataCallback(bool* was_called,
- std::vector<std::string>* data_out,
- ServiceWorkerStatusCode* status_out,
- const std::vector<std::string>& data,
- ServiceWorkerStatusCode status) {
+void GetUserDataCallback(
+ bool* was_called,
+ std::vector<std::string>* data_out,
+ base::Optional<blink::ServiceWorkerStatusCode>* status_out,
+ const std::vector<std::string>& data,
+ blink::ServiceWorkerStatusCode status) {
*was_called = true;
*data_out = data;
*status_out = status;
@@ -155,9 +156,9 @@ void GetUserDataCallback(bool* was_called,
void GetUserDataForAllRegistrationsCallback(
bool* was_called,
std::vector<std::pair<int64_t, std::string>>* data_out,
- ServiceWorkerStatusCode* status_out,
+ base::Optional<blink::ServiceWorkerStatusCode>* status_out,
const std::vector<std::pair<int64_t, std::string>>& data,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
*was_called = true;
*data_out = data;
*status_out = status;
@@ -339,8 +340,8 @@ class ServiceWorkerStorageTest : public testing::Test {
ServiceWorkerDatabase* database,
std::set<int64_t>* purgeable_ids,
bool* was_called,
- ServiceWorkerStatusCode* result,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode* result,
+ blink::ServiceWorkerStatusCode status) {
*was_called = true;
*result = status;
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -378,151 +379,153 @@ class ServiceWorkerStorageTest : public testing::Test {
return registration;
}
- ServiceWorkerStatusCode StoreRegistration(
+ blink::ServiceWorkerStatusCode StoreRegistration(
scoped_refptr<ServiceWorkerRegistration> registration,
scoped_refptr<ServiceWorkerVersion> version) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->StoreRegistration(registration.get(),
version.get(),
MakeStatusCallback(&was_called, &result));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode DeleteRegistration(int64_t registration_id,
- const GURL& origin) {
+ blink::ServiceWorkerStatusCode DeleteRegistration(int64_t registration_id,
+ const GURL& origin) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->DeleteRegistration(
registration_id, origin, MakeStatusCallback(&was_called, &result));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode GetAllRegistrationsInfos(
+ blink::ServiceWorkerStatusCode GetAllRegistrationsInfos(
std::vector<ServiceWorkerRegistrationInfo>* registrations) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->GetAllRegistrationsInfos(
MakeGetRegistrationsInfosCallback(&was_called, &result, registrations));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode GetRegistrationsForOrigin(
+ blink::ServiceWorkerStatusCode GetRegistrationsForOrigin(
const GURL& origin,
std::vector<scoped_refptr<ServiceWorkerRegistration>>* registrations) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->GetRegistrationsForOrigin(
origin,
MakeGetRegistrationsCallback(&was_called, &result, registrations));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode GetUserData(int64_t registration_id,
- const std::vector<std::string>& keys,
- std::vector<std::string>* data) {
+ blink::ServiceWorkerStatusCode GetUserData(
+ int64_t registration_id,
+ const std::vector<std::string>& keys,
+ std::vector<std::string>* data) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->GetUserData(
registration_id, keys,
base::BindOnce(&GetUserDataCallback, &was_called, data, &result));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode GetUserDataByKeyPrefix(
+ blink::ServiceWorkerStatusCode GetUserDataByKeyPrefix(
int64_t registration_id,
const std::string& key_prefix,
std::vector<std::string>* data) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->GetUserDataByKeyPrefix(
registration_id, key_prefix,
base::BindOnce(&GetUserDataCallback, &was_called, data, &result));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode StoreUserData(
+ blink::ServiceWorkerStatusCode StoreUserData(
int64_t registration_id,
const GURL& origin,
const std::vector<std::pair<std::string, std::string>>& key_value_pairs) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->StoreUserData(registration_id, origin, key_value_pairs,
MakeStatusCallback(&was_called, &result));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode ClearUserData(int64_t registration_id,
- const std::vector<std::string>& keys) {
+ blink::ServiceWorkerStatusCode ClearUserData(
+ int64_t registration_id,
+ const std::vector<std::string>& keys) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->ClearUserData(registration_id, keys,
MakeStatusCallback(&was_called, &result));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode ClearUserDataByKeyPrefixes(
+ blink::ServiceWorkerStatusCode ClearUserDataByKeyPrefixes(
int64_t registration_id,
const std::vector<std::string>& key_prefixes) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->ClearUserDataByKeyPrefixes(
registration_id, key_prefixes,
MakeStatusCallback(&was_called, &result));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode GetUserDataForAllRegistrations(
+ blink::ServiceWorkerStatusCode GetUserDataForAllRegistrations(
const std::string& key,
std::vector<std::pair<int64_t, std::string>>* data) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->GetUserDataForAllRegistrations(
key, base::BindOnce(&GetUserDataForAllRegistrationsCallback,
&was_called, data, &result));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode UpdateToActiveState(
+ blink::ServiceWorkerStatusCode UpdateToActiveState(
scoped_refptr<ServiceWorkerRegistration> registration) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->UpdateToActiveState(registration.get(),
MakeStatusCallback(&was_called, &result));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
void UpdateLastUpdateCheckTime(
@@ -531,55 +534,55 @@ class ServiceWorkerStorageTest : public testing::Test {
base::RunLoop().RunUntilIdle();
}
- ServiceWorkerStatusCode FindRegistrationForDocument(
+ blink::ServiceWorkerStatusCode FindRegistrationForDocument(
const GURL& document_url,
scoped_refptr<ServiceWorkerRegistration>* registration) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->FindRegistrationForDocument(
document_url, MakeFindCallback(&was_called, &result, registration));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode FindRegistrationForPattern(
+ blink::ServiceWorkerStatusCode FindRegistrationForPattern(
const GURL& scope,
scoped_refptr<ServiceWorkerRegistration>* registration) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->FindRegistrationForPattern(
scope, MakeFindCallback(&was_called, &result, registration));
EXPECT_FALSE(was_called); // always async
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode FindRegistrationForId(
+ blink::ServiceWorkerStatusCode FindRegistrationForId(
int64_t registration_id,
const GURL& origin,
scoped_refptr<ServiceWorkerRegistration>* registration) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->FindRegistrationForId(
registration_id, origin,
MakeFindCallback(&was_called, &result, registration));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
- ServiceWorkerStatusCode FindRegistrationForIdOnly(
+ blink::ServiceWorkerStatusCode FindRegistrationForIdOnly(
int64_t registration_id,
scoped_refptr<ServiceWorkerRegistration>* registration) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> result;
storage()->FindRegistrationForIdOnly(
registration_id, MakeFindCallback(&was_called, &result, registration));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
- return result;
+ return result.value();
}
// Directly writes a registration using
@@ -616,24 +619,24 @@ TEST_F(ServiceWorkerStorageTest, DisabledStorage) {
storage()->Disable();
scoped_refptr<ServiceWorkerRegistration> found_registration;
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
FindRegistrationForPattern(kScope, &found_registration));
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
FindRegistrationForId(kRegistrationId, kScope.GetOrigin(),
&found_registration));
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
FindRegistrationForIdOnly(kRegistrationId, &found_registration));
EXPECT_FALSE(storage()->GetUninstallingRegistration(kScope.GetOrigin()));
std::vector<scoped_refptr<ServiceWorkerRegistration>> found_registrations;
EXPECT_EQ(
- SERVICE_WORKER_ERROR_ABORT,
+ blink::ServiceWorkerStatusCode::kErrorAbort,
GetRegistrationsForOrigin(kScope.GetOrigin(), &found_registrations));
std::vector<ServiceWorkerRegistrationInfo> all_registrations;
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
GetAllRegistrationsInfos(&all_registrations));
blink::mojom::ServiceWorkerRegistrationOptions options;
@@ -643,12 +646,13 @@ TEST_F(ServiceWorkerStorageTest, DisabledStorage) {
context()->AsWeakPtr());
scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
live_registration.get(), kScript, kVersionId, context()->AsWeakPtr());
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
StoreRegistration(live_registration, live_version));
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, UpdateToActiveState(live_registration));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
+ UpdateToActiveState(live_registration));
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
DeleteRegistration(kRegistrationId, kScope.GetOrigin()));
// Response reader and writer created by the disabled storage should fail to
@@ -663,19 +667,19 @@ TEST_F(ServiceWorkerStorageTest, DisabledStorage) {
const std::string kUserDataKey = "key";
std::vector<std::string> user_data_out;
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
GetUserData(kRegistrationId, {kUserDataKey}, &user_data_out));
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
GetUserDataByKeyPrefix(kRegistrationId, "prefix", &user_data_out));
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
StoreUserData(kRegistrationId, kScope.GetOrigin(),
{{kUserDataKey, "foo"}}));
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
ClearUserData(kRegistrationId, {kUserDataKey}));
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
ClearUserDataByKeyPrefixes(kRegistrationId, {"prefix"}));
std::vector<std::pair<int64_t, std::string>> data_list_out;
- EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorAbort,
GetUserDataForAllRegistrations(kUserDataKey, &data_list_out));
// Next available ids should be invalid.
@@ -705,17 +709,17 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
scoped_refptr<ServiceWorkerRegistration> found_registration;
// We shouldn't find anything without having stored anything.
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
EXPECT_FALSE(found_registration.get());
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
FindRegistrationForPattern(kScope, &found_registration));
EXPECT_FALSE(found_registration.get());
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
- FindRegistrationForId(
- kRegistrationId, kScope.GetOrigin(), &found_registration));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
+ FindRegistrationForId(kRegistrationId, kScope.GetOrigin(),
+ &found_registration));
EXPECT_FALSE(found_registration.get());
std::vector<ResourceRecord> resources;
@@ -738,11 +742,11 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
std::set<blink::mojom::WebFeature>(used_features));
live_registration->SetWaitingVersion(live_version);
live_registration->set_last_update_check(kYesterday);
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
StoreRegistration(live_registration, live_version));
// Now we should find it and get the live ptr back immediately.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
EXPECT_EQ(live_registration, found_registration);
EXPECT_EQ(kResource1Size + kResource2Size,
@@ -754,22 +758,22 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
found_registration = nullptr;
// But FindRegistrationForPattern is always async.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForPattern(kScope, &found_registration));
EXPECT_EQ(live_registration, found_registration);
found_registration = nullptr;
// Can be found by id too.
- EXPECT_EQ(SERVICE_WORKER_OK,
- FindRegistrationForId(
- kRegistrationId, kScope.GetOrigin(), &found_registration));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ FindRegistrationForId(kRegistrationId, kScope.GetOrigin(),
+ &found_registration));
ASSERT_TRUE(found_registration.get());
EXPECT_EQ(kRegistrationId, found_registration->id());
EXPECT_EQ(live_registration, found_registration);
found_registration = nullptr;
// Can be found by just the id too.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForIdOnly(kRegistrationId, &found_registration));
ASSERT_TRUE(found_registration.get());
EXPECT_EQ(kRegistrationId, found_registration->id());
@@ -780,7 +784,7 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
live_registration = nullptr;
// Now FindRegistrationForDocument should be async.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
ASSERT_TRUE(found_registration.get());
EXPECT_EQ(kRegistrationId, found_registration->id());
@@ -791,7 +795,8 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
EXPECT_EQ(kResource1Size + kResource2Size,
found_registration->resources_total_size_bytes());
std::vector<ServiceWorkerRegistrationInfo> all_registrations;
- EXPECT_EQ(SERVICE_WORKER_OK, GetAllRegistrationsInfos(&all_registrations));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ GetAllRegistrationsInfos(&all_registrations));
EXPECT_EQ(1u, all_registrations.size());
ServiceWorkerRegistrationInfo info = all_registrations[0];
EXPECT_EQ(kResource1Size + kResource2Size, info.stored_version_size_bytes);
@@ -801,12 +806,12 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
std::vector<scoped_refptr<ServiceWorkerRegistration>>
registrations_for_origin;
EXPECT_EQ(
- SERVICE_WORKER_OK,
+ blink::ServiceWorkerStatusCode::kOk,
GetRegistrationsForOrigin(kScope.GetOrigin(), &registrations_for_origin));
EXPECT_EQ(1u, registrations_for_origin.size());
registrations_for_origin.clear();
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
&registrations_for_origin));
EXPECT_TRUE(registrations_for_origin.empty());
@@ -817,7 +822,7 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
live_version = nullptr;
// And FindRegistrationForPattern is always async.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForPattern(kScope, &found_registration));
ASSERT_TRUE(found_registration.get());
EXPECT_EQ(kRegistrationId, found_registration->id());
@@ -834,7 +839,8 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
temp_version->SetStatus(ServiceWorkerVersion::ACTIVATED);
found_registration->SetActiveVersion(temp_version);
temp_version = nullptr;
- EXPECT_EQ(SERVICE_WORKER_OK, UpdateToActiveState(found_registration));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ UpdateToActiveState(found_registration));
found_registration->set_last_update_check(kToday);
UpdateLastUpdateCheckTime(found_registration.get());
@@ -844,13 +850,13 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
scoped_refptr<ServiceWorkerRegistration> unstored_registration =
new ServiceWorkerRegistration(options, kRegistrationId + 1,
context()->AsWeakPtr());
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
UpdateToActiveState(unstored_registration));
unstored_registration = nullptr;
// The Find methods should return a registration with an active version
// and the expected update time.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
ASSERT_TRUE(found_registration.get());
EXPECT_EQ(kRegistrationId, found_registration->id());
@@ -863,21 +869,21 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
// Delete from storage but with a instance still live.
EXPECT_TRUE(context()->GetLiveVersion(kRegistrationId));
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
DeleteRegistration(kRegistrationId, kScope.GetOrigin()));
EXPECT_TRUE(context()->GetLiveVersion(kRegistrationId));
// Should no longer be found.
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
- FindRegistrationForId(
- kRegistrationId, kScope.GetOrigin(), &found_registration));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
+ FindRegistrationForId(kRegistrationId, kScope.GetOrigin(),
+ &found_registration));
EXPECT_FALSE(found_registration.get());
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
FindRegistrationForIdOnly(kRegistrationId, &found_registration));
EXPECT_FALSE(found_registration.get());
// Deleting an unstored registration should succeed.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
DeleteRegistration(kRegistrationId + 1, kScope.GetOrigin()));
}
@@ -902,35 +908,36 @@ TEST_F(ServiceWorkerStorageTest, InstallingRegistrationsAreFindable) {
live_registration->SetWaitingVersion(live_version);
// Should not be findable, including by GetAllRegistrationsInfos.
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
- FindRegistrationForId(
- kRegistrationId, kScope.GetOrigin(), &found_registration));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
+ FindRegistrationForId(kRegistrationId, kScope.GetOrigin(),
+ &found_registration));
EXPECT_FALSE(found_registration.get());
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
FindRegistrationForIdOnly(kRegistrationId, &found_registration));
EXPECT_FALSE(found_registration.get());
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
EXPECT_FALSE(found_registration.get());
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
FindRegistrationForPattern(kScope, &found_registration));
EXPECT_FALSE(found_registration.get());
std::vector<ServiceWorkerRegistrationInfo> all_registrations;
- EXPECT_EQ(SERVICE_WORKER_OK, GetAllRegistrationsInfos(&all_registrations));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ GetAllRegistrationsInfos(&all_registrations));
EXPECT_TRUE(all_registrations.empty());
std::vector<scoped_refptr<ServiceWorkerRegistration>>
registrations_for_origin;
EXPECT_EQ(
- SERVICE_WORKER_OK,
+ blink::ServiceWorkerStatusCode::kOk,
GetRegistrationsForOrigin(kScope.GetOrigin(), &registrations_for_origin));
EXPECT_TRUE(registrations_for_origin.empty());
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
&registrations_for_origin));
EXPECT_TRUE(registrations_for_origin.empty());
@@ -939,74 +946,76 @@ TEST_F(ServiceWorkerStorageTest, InstallingRegistrationsAreFindable) {
storage()->NotifyInstallingRegistration(live_registration.get());
// Now should be findable.
- EXPECT_EQ(SERVICE_WORKER_OK,
- FindRegistrationForId(
- kRegistrationId, kScope.GetOrigin(), &found_registration));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ FindRegistrationForId(kRegistrationId, kScope.GetOrigin(),
+ &found_registration));
EXPECT_EQ(live_registration, found_registration);
found_registration = nullptr;
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForIdOnly(kRegistrationId, &found_registration));
EXPECT_EQ(live_registration, found_registration);
found_registration = nullptr;
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
EXPECT_EQ(live_registration, found_registration);
found_registration = nullptr;
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForPattern(kScope, &found_registration));
EXPECT_EQ(live_registration, found_registration);
found_registration = nullptr;
- EXPECT_EQ(SERVICE_WORKER_OK, GetAllRegistrationsInfos(&all_registrations));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ GetAllRegistrationsInfos(&all_registrations));
EXPECT_EQ(1u, all_registrations.size());
all_registrations.clear();
// Finding by origin should provide the same result if origin is kScope.
EXPECT_EQ(
- SERVICE_WORKER_OK,
+ blink::ServiceWorkerStatusCode::kOk,
GetRegistrationsForOrigin(kScope.GetOrigin(), &registrations_for_origin));
EXPECT_EQ(1u, registrations_for_origin.size());
registrations_for_origin.clear();
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
&registrations_for_origin));
EXPECT_TRUE(registrations_for_origin.empty());
// Notify storage of installation no longer happening.
- storage()->NotifyDoneInstallingRegistration(live_registration.get(), nullptr,
- SERVICE_WORKER_OK);
+ storage()->NotifyDoneInstallingRegistration(
+ live_registration.get(), nullptr, blink::ServiceWorkerStatusCode::kOk);
// Once again, should not be findable.
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
- FindRegistrationForId(
- kRegistrationId, kScope.GetOrigin(), &found_registration));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
+ FindRegistrationForId(kRegistrationId, kScope.GetOrigin(),
+ &found_registration));
EXPECT_FALSE(found_registration.get());
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
FindRegistrationForIdOnly(kRegistrationId, &found_registration));
EXPECT_FALSE(found_registration.get());
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
EXPECT_FALSE(found_registration.get());
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
FindRegistrationForPattern(kScope, &found_registration));
EXPECT_FALSE(found_registration.get());
- EXPECT_EQ(SERVICE_WORKER_OK, GetAllRegistrationsInfos(&all_registrations));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ GetAllRegistrationsInfos(&all_registrations));
EXPECT_TRUE(all_registrations.empty());
EXPECT_EQ(
- SERVICE_WORKER_OK,
+ blink::ServiceWorkerStatusCode::kOk,
GetRegistrationsForOrigin(kScope.GetOrigin(), &registrations_for_origin));
EXPECT_TRUE(registrations_for_origin.empty());
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
&registrations_for_origin));
EXPECT_TRUE(registrations_for_origin.empty());
@@ -1020,7 +1029,7 @@ TEST_F(ServiceWorkerStorageTest, StoreUserData) {
// Store a registration.
scoped_refptr<ServiceWorkerRegistration> live_registration =
CreateLiveRegistrationAndVersion(kScope, kScript);
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
StoreRegistration(live_registration,
live_registration->waiting_version()));
const int64_t kRegistrationId = live_registration->id();
@@ -1028,149 +1037,151 @@ TEST_F(ServiceWorkerStorageTest, StoreUserData) {
// Store user data associated with the registration.
std::vector<std::string> data_out;
EXPECT_EQ(
- SERVICE_WORKER_OK,
+ blink::ServiceWorkerStatusCode::kOk,
StoreUserData(kRegistrationId, kScope.GetOrigin(), {{"key", "data"}}));
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetUserData(kRegistrationId, {"key"}, &data_out));
ASSERT_EQ(1u, data_out.size());
EXPECT_EQ("data", data_out[0]);
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
GetUserData(kRegistrationId, {"unknown_key"}, &data_out));
std::vector<std::pair<int64_t, std::string>> data_list_out;
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetUserDataForAllRegistrations("key", &data_list_out));
ASSERT_EQ(1u, data_list_out.size());
EXPECT_EQ(kRegistrationId, data_list_out[0].first);
EXPECT_EQ("data", data_list_out[0].second);
data_list_out.clear();
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetUserDataForAllRegistrations("unknown_key", &data_list_out));
EXPECT_EQ(0u, data_list_out.size());
- EXPECT_EQ(SERVICE_WORKER_OK, ClearUserData(kRegistrationId, {"key"}));
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ ClearUserData(kRegistrationId, {"key"}));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
GetUserData(kRegistrationId, {"key"}, &data_out));
// Write/overwrite multiple user data keys.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
StoreUserData(
kRegistrationId, kScope.GetOrigin(),
{{"key", "overwrite"}, {"key3", "data3"}, {"key4", "data4"}}));
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
GetUserData(kRegistrationId, {"key2"}, &data_out));
EXPECT_TRUE(data_out.empty());
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetUserData(kRegistrationId, {"key", "key3", "key4"}, &data_out));
ASSERT_EQ(3u, data_out.size());
EXPECT_EQ("overwrite", data_out[0]);
EXPECT_EQ("data3", data_out[1]);
EXPECT_EQ("data4", data_out[2]);
// Multiple gets fail if one is not found.
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
GetUserData(kRegistrationId, {"key", "key2"}, &data_out));
EXPECT_TRUE(data_out.empty());
// Delete multiple user data keys, even if some are not found.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
ClearUserData(kRegistrationId, {"key", "key2", "key3"}));
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
GetUserData(kRegistrationId, {"key"}, &data_out));
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
GetUserData(kRegistrationId, {"key2"}, &data_out));
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
GetUserData(kRegistrationId, {"key3"}, &data_out));
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetUserData(kRegistrationId, {"key4"}, &data_out));
ASSERT_EQ(1u, data_out.size());
EXPECT_EQ("data4", data_out[0]);
// Get/delete multiple user data keys by prefixes.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
StoreUserData(kRegistrationId, kScope.GetOrigin(),
{{"prefixA", "data1"},
{"prefixA2", "data2"},
{"prefixB", "data3"},
{"prefixC", "data4"}}));
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetUserDataByKeyPrefix(kRegistrationId, "prefix", &data_out));
ASSERT_EQ(4u, data_out.size());
EXPECT_EQ("data1", data_out[0]);
EXPECT_EQ("data2", data_out[1]);
EXPECT_EQ("data3", data_out[2]);
EXPECT_EQ("data4", data_out[3]);
- EXPECT_EQ(SERVICE_WORKER_OK, ClearUserDataByKeyPrefixes(
- kRegistrationId, {"prefixA", "prefixC"}));
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(
+ blink::ServiceWorkerStatusCode::kOk,
+ ClearUserDataByKeyPrefixes(kRegistrationId, {"prefixA", "prefixC"}));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetUserDataByKeyPrefix(kRegistrationId, "prefix", &data_out));
ASSERT_EQ(1u, data_out.size());
EXPECT_EQ("data3", data_out[0]);
// User data should be deleted when the associated registration is deleted.
ASSERT_EQ(
- SERVICE_WORKER_OK,
+ blink::ServiceWorkerStatusCode::kOk,
StoreUserData(kRegistrationId, kScope.GetOrigin(), {{"key", "data"}}));
- ASSERT_EQ(SERVICE_WORKER_OK,
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetUserData(kRegistrationId, {"key"}, &data_out));
ASSERT_EQ(1u, data_out.size());
ASSERT_EQ("data", data_out[0]);
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
DeleteRegistration(kRegistrationId, kScope.GetOrigin()));
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
GetUserData(kRegistrationId, {"key"}, &data_out));
data_list_out.clear();
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetUserDataForAllRegistrations("key", &data_list_out));
EXPECT_EQ(0u, data_list_out.size());
// Data access with an invalid registration id should be failed.
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
StoreUserData(blink::mojom::kInvalidServiceWorkerRegistrationId,
kScope.GetOrigin(), {{"key", "data"}}));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
GetUserData(blink::mojom::kInvalidServiceWorkerRegistrationId,
{"key"}, &data_out));
EXPECT_EQ(
- SERVICE_WORKER_ERROR_FAILED,
+ blink::ServiceWorkerStatusCode::kErrorFailed,
GetUserDataByKeyPrefix(blink::mojom::kInvalidServiceWorkerRegistrationId,
"prefix", &data_out));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
ClearUserData(blink::mojom::kInvalidServiceWorkerRegistrationId,
{"key"}));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
ClearUserDataByKeyPrefixes(
blink::mojom::kInvalidServiceWorkerRegistrationId, {"prefix"}));
// Data access with an empty key should be failed.
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
StoreUserData(kRegistrationId, kScope.GetOrigin(),
std::vector<std::pair<std::string, std::string>>()));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
StoreUserData(kRegistrationId, kScope.GetOrigin(),
{{std::string(), "data"}}));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
StoreUserData(kRegistrationId, kScope.GetOrigin(),
{{std::string(), "data"}, {"key", "data"}}));
EXPECT_EQ(
- SERVICE_WORKER_ERROR_FAILED,
+ blink::ServiceWorkerStatusCode::kErrorFailed,
GetUserData(kRegistrationId, std::vector<std::string>(), &data_out));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
GetUserDataByKeyPrefix(kRegistrationId, std::string(), &data_out));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
GetUserData(kRegistrationId, {std::string()}, &data_out));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
GetUserData(kRegistrationId, {std::string(), "key"}, &data_out));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
ClearUserData(kRegistrationId, std::vector<std::string>()));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
ClearUserData(kRegistrationId, {std::string()}));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
ClearUserData(kRegistrationId, {std::string(), "key"}));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
ClearUserDataByKeyPrefixes(kRegistrationId, {}));
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
ClearUserDataByKeyPrefixes(kRegistrationId, {std::string()}));
data_list_out.clear();
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed,
GetUserDataForAllRegistrations(std::string(), &data_list_out));
}
@@ -1178,7 +1189,7 @@ TEST_F(ServiceWorkerStorageTest, StoreUserData) {
// called.
TEST_F(ServiceWorkerStorageTest, StoreUserData_BeforeInitialize) {
const int kRegistrationId = 0;
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
StoreUserData(kRegistrationId, GURL("https://example.com"),
{{"key", "data"}}));
}
@@ -1186,23 +1197,24 @@ TEST_F(ServiceWorkerStorageTest, StoreUserData_BeforeInitialize) {
TEST_F(ServiceWorkerStorageTest, GetUserData_BeforeInitialize) {
const int kRegistrationId = 0;
std::vector<std::string> data_out;
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
GetUserData(kRegistrationId, {"key"}, &data_out));
- EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
GetUserDataByKeyPrefix(kRegistrationId, "prefix", &data_out));
}
TEST_F(ServiceWorkerStorageTest, ClearUserData_BeforeInitialize) {
const int kRegistrationId = 0;
- EXPECT_EQ(SERVICE_WORKER_OK, ClearUserData(kRegistrationId, {"key"}));
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ ClearUserData(kRegistrationId, {"key"}));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
ClearUserDataByKeyPrefixes(kRegistrationId, {"prefix"}));
}
TEST_F(ServiceWorkerStorageTest,
GetUserDataForAllRegistrations_BeforeInitialize) {
std::vector<std::pair<int64_t, std::string>> data_list_out;
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
GetUserDataForAllRegistrations("key", &data_list_out));
EXPECT_TRUE(data_list_out.empty());
}
@@ -1257,7 +1269,7 @@ class ServiceWorkerResourceStorageTest : public ServiceWorkerStorageTest {
// Storing the registration/version should take the resources ids out
// of the uncommitted list.
EXPECT_EQ(
- SERVICE_WORKER_OK,
+ blink::ServiceWorkerStatusCode::kOk,
StoreRegistration(registration_, registration_->waiting_version()));
verify_ids.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -1349,7 +1361,8 @@ TEST_F(ServiceWorkerResourceStorageTest,
TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
+ blink::ServiceWorkerStatusCode result =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
std::set<int64_t> verify_ids;
registration_->SetWaitingVersion(nullptr);
@@ -1365,7 +1378,7 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) {
&result));
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(was_called);
- EXPECT_EQ(SERVICE_WORKER_OK, result);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, result);
EXPECT_EQ(2u, verify_ids.size());
verify_ids.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -1378,7 +1391,8 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) {
TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_WaitingVersion) {
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
+ blink::ServiceWorkerStatusCode result =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
std::set<int64_t> verify_ids;
// Deleting the registration should result in the resources being added to the
@@ -1391,7 +1405,7 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_WaitingVersion) {
&result));
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(was_called);
- EXPECT_EQ(SERVICE_WORKER_OK, result);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, result);
EXPECT_EQ(2u, verify_ids.size());
verify_ids.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -1404,7 +1418,7 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_WaitingVersion) {
// Doom the version, now it happens.
registration_->waiting_version()->Doom();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, result);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, result);
EXPECT_EQ(2u, verify_ids.size());
verify_ids.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -1427,7 +1441,8 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_ActiveVersion) {
registration_->active_version()->AddControllee(host.get());
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
+ blink::ServiceWorkerStatusCode result =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
std::set<int64_t> verify_ids;
// Deleting the registration should move the resources to the purgeable list
@@ -1439,7 +1454,7 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_ActiveVersion) {
&result));
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(was_called);
- EXPECT_EQ(SERVICE_WORKER_OK, result);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, result);
EXPECT_EQ(2u, verify_ids.size());
verify_ids.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -1475,7 +1490,8 @@ TEST_F(ServiceWorkerResourceStorageDiskTest, CleanupOnRestart) {
registration_->active_version()->AddControllee(host.get());
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
+ blink::ServiceWorkerStatusCode result =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
std::set<int64_t> verify_ids;
// Deleting the registration should move the resources to the purgeable list
@@ -1487,7 +1503,7 @@ TEST_F(ServiceWorkerResourceStorageDiskTest, CleanupOnRestart) {
&result));
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(was_called);
- EXPECT_EQ(SERVICE_WORKER_OK, result);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, result);
EXPECT_EQ(2u, verify_ids.size());
verify_ids.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -1549,12 +1565,13 @@ TEST_F(ServiceWorkerResourceStorageDiskTest, DeleteAndStartOver) {
ASSERT_TRUE(base::DirectoryExists(storage()->GetDatabasePath()));
base::RunLoop run_loop;
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
storage()->DeleteAndStartOver(
base::BindOnce(&StatusAndQuitCallback, &status, run_loop.QuitClosure()));
run_loop.Run();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
EXPECT_TRUE(storage()->IsDisabled());
EXPECT_FALSE(base::DirectoryExists(storage()->GetDiskCachePath()));
EXPECT_FALSE(base::DirectoryExists(storage()->GetDatabasePath()));
@@ -1574,12 +1591,13 @@ TEST_F(ServiceWorkerResourceStorageDiskTest,
ASSERT_TRUE(base::PathExists(file_path));
base::RunLoop run_loop;
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
storage()->DeleteAndStartOver(
base::BindOnce(&StatusAndQuitCallback, &status, run_loop.QuitClosure()));
run_loop.Run();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
EXPECT_TRUE(storage()->IsDisabled());
EXPECT_FALSE(base::DirectoryExists(storage()->GetDiskCachePath()));
EXPECT_FALSE(base::DirectoryExists(storage()->GetDatabasePath()));
@@ -1600,19 +1618,20 @@ TEST_F(ServiceWorkerResourceStorageDiskTest,
ASSERT_TRUE(base::PathExists(file_path));
base::RunLoop run_loop;
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorNotFound;
storage()->DeleteAndStartOver(
base::BindOnce(&StatusAndQuitCallback, &status, run_loop.QuitClosure()));
run_loop.Run();
#if defined(OS_WIN)
// On Windows, deleting the directory containing an opened file should fail.
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed, status);
EXPECT_TRUE(storage()->IsDisabled());
EXPECT_TRUE(base::DirectoryExists(storage()->GetDiskCachePath()));
EXPECT_TRUE(base::DirectoryExists(storage()->GetDatabasePath()));
#else
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
EXPECT_TRUE(storage()->IsDisabled());
EXPECT_FALSE(base::DirectoryExists(storage()->GetDiskCachePath()));
EXPECT_FALSE(base::DirectoryExists(storage()->GetDatabasePath()));
@@ -1631,7 +1650,8 @@ TEST_F(ServiceWorkerResourceStorageTest, UpdateRegistration) {
registration_->active_version()->AddControllee(host.get());
bool was_called = false;
- ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
+ blink::ServiceWorkerStatusCode result =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
std::set<int64_t> verify_ids;
// Make an updated registration.
@@ -1655,7 +1675,7 @@ TEST_F(ServiceWorkerResourceStorageTest, UpdateRegistration) {
&result));
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(was_called);
- EXPECT_EQ(SERVICE_WORKER_OK, result);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, result);
EXPECT_EQ(2u, verify_ids.size());
verify_ids.clear();
EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
@@ -1708,32 +1728,32 @@ TEST_F(ServiceWorkerStorageTest, FindRegistration_LongestScopeMatch) {
storage()->NotifyInstallingRegistration(live_registration3.get());
// Find a registration among installing ones.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
EXPECT_EQ(live_registration2, found_registration);
found_registration = nullptr;
// Store registrations.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
StoreRegistration(live_registration1,
live_registration1->waiting_version()));
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
StoreRegistration(live_registration2,
live_registration2->waiting_version()));
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
StoreRegistration(live_registration3,
live_registration3->waiting_version()));
// Notify storage of installations no longer happening.
- 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);
+ storage()->NotifyDoneInstallingRegistration(
+ live_registration1.get(), nullptr, blink::ServiceWorkerStatusCode::kOk);
+ storage()->NotifyDoneInstallingRegistration(
+ live_registration2.get(), nullptr, blink::ServiceWorkerStatusCode::kOk);
+ storage()->NotifyDoneInstallingRegistration(
+ live_registration3.get(), nullptr, blink::ServiceWorkerStatusCode::kOk);
// Find a registration among installed ones.
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(kDocumentUrl, &found_registration));
EXPECT_EQ(live_registration2, found_registration);
}
@@ -1780,13 +1800,13 @@ TEST_F(ServiceWorkerStorageTest, OriginTrialsAbsentEntryAndEmptyEntry) {
scoped_refptr<ServiceWorkerRegistration> found_registration;
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(scope1, &found_registration));
ASSERT_TRUE(found_registration->active_version());
// origin_trial_tokens must be unset.
EXPECT_FALSE(found_registration->active_version()->origin_trial_tokens());
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(scope2, &found_registration));
ASSERT_TRUE(found_registration->active_version());
// Empty origin_trial_tokens must exist.
@@ -1901,7 +1921,8 @@ TEST_F(ServiceWorkerStorageOriginTrialsDiskTest, FromMainScript) {
version->SetStatus(ServiceWorkerVersion::INSTALLED);
registration->SetActiveVersion(version);
- EXPECT_EQ(SERVICE_WORKER_OK, StoreRegistration(registration, version));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ StoreRegistration(registration, version));
// Simulate browser shutdown and restart.
registration = nullptr;
@@ -1910,7 +1931,7 @@ TEST_F(ServiceWorkerStorageOriginTrialsDiskTest, FromMainScript) {
LazyInitialize();
scoped_refptr<ServiceWorkerRegistration> found_registration;
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(kScope, &found_registration));
ASSERT_TRUE(found_registration->active_version());
const blink::TrialTokenValidator::FeatureToTokensMap& found_tokens =
@@ -1940,7 +1961,7 @@ TEST_F(ServiceWorkerStorageTest, AbsentNavigationPreloadState) {
WriteRegistration(data1, resources1);
scoped_refptr<ServiceWorkerRegistration> found_registration;
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(scope1, &found_registration));
const blink::mojom::NavigationPreloadState& registration_state =
found_registration->navigation_preload_state();
@@ -1980,7 +2001,7 @@ TEST_F(ServiceWorkerStorageDiskTest, RegisteredOriginCount) {
// Store all registrations.
for (const auto& registration : registrations) {
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
StoreRegistration(registration, registration->waiting_version()));
}
@@ -2017,7 +2038,8 @@ TEST_F(ServiceWorkerStorageDiskTest, DisabledNavigationPreloadState) {
registration->SetActiveVersion(version);
registration->EnableNavigationPreload(false);
- EXPECT_EQ(SERVICE_WORKER_OK, StoreRegistration(registration, version));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ StoreRegistration(registration, version));
// Simulate browser shutdown and restart.
registration = nullptr;
@@ -2026,7 +2048,7 @@ TEST_F(ServiceWorkerStorageDiskTest, DisabledNavigationPreloadState) {
LazyInitialize();
scoped_refptr<ServiceWorkerRegistration> found_registration;
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(kScope, &found_registration));
const blink::mojom::NavigationPreloadState& registration_state =
found_registration->navigation_preload_state();
@@ -2054,7 +2076,8 @@ TEST_F(ServiceWorkerStorageDiskTest, EnabledNavigationPreloadState) {
registration->EnableNavigationPreload(true);
registration->SetNavigationPreloadHeader(kHeaderValue);
- EXPECT_EQ(SERVICE_WORKER_OK, StoreRegistration(registration, version));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ StoreRegistration(registration, version));
// Simulate browser shutdown and restart.
registration = nullptr;
@@ -2063,7 +2086,7 @@ TEST_F(ServiceWorkerStorageDiskTest, EnabledNavigationPreloadState) {
LazyInitialize();
scoped_refptr<ServiceWorkerRegistration> found_registration;
- EXPECT_EQ(SERVICE_WORKER_OK,
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
FindRegistrationForDocument(kScope, &found_registration));
const blink::mojom::NavigationPreloadState& registration_state =
found_registration->navigation_preload_state();
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 d01073ccaeb..384440dc50c 100644
--- a/chromium/content/browser/service_worker/service_worker_test_utils.cc
+++ b/chromium/content/browser/service_worker/service_worker_test_utils.cc
@@ -13,20 +13,73 @@
#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"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
namespace {
+// A mock SharedURLLoaderFactory that always fails to start.
+// TODO(bashi): Make this factory not to fail when unit tests actually need
+// this to be working.
+class MockSharedURLLoaderFactory final
+ : public network::SharedURLLoaderFactory {
+ public:
+ MockSharedURLLoaderFactory() = default;
+
+ // network::mojom::URLLoaderFactory:
+ void CreateLoaderAndStart(network::mojom::URLLoaderRequest request,
+ int32_t routing_id,
+ int32_t request_id,
+ uint32_t options,
+ const network::ResourceRequest& url_request,
+ network::mojom::URLLoaderClientPtr client,
+ const net::MutableNetworkTrafficAnnotationTag&
+ traffic_annotation) override {
+ client->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_NOT_IMPLEMENTED));
+ }
+ void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+ NOTREACHED();
+ }
+
+ // network::SharedURLLoaderFactory:
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override {
+ NOTREACHED();
+ return nullptr;
+ }
+
+ private:
+ friend class base::RefCounted<MockSharedURLLoaderFactory>;
+
+ ~MockSharedURLLoaderFactory() override = default;
+
+ DISALLOW_COPY_AND_ASSIGN(MockSharedURLLoaderFactory);
+};
+
+// Returns MockSharedURLLoaderFactory.
+class MockSharedURLLoaderFactoryInfo final
+ : public network::SharedURLLoaderFactoryInfo {
+ public:
+ MockSharedURLLoaderFactoryInfo() = default;
+ ~MockSharedURLLoaderFactoryInfo() override = default;
+
+ protected:
+ scoped_refptr<network::SharedURLLoaderFactory> CreateFactory() override {
+ return base::MakeRefCounted<MockSharedURLLoaderFactory>();
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockSharedURLLoaderFactoryInfo);
+};
+
void OnWriteBodyInfoToDiskCache(
std::unique_ptr<ServiceWorkerResponseWriter> writer,
const std::string& body,
@@ -90,11 +143,12 @@ ServiceWorkerRemoteProviderEndpoint::ServiceWorkerRemoteProviderEndpoint(
ServiceWorkerRemoteProviderEndpoint::~ServiceWorkerRemoteProviderEndpoint() {}
void ServiceWorkerRemoteProviderEndpoint::BindWithProviderHostInfo(
- content::ServiceWorkerProviderHostInfo* info) {
+ mojom::ServiceWorkerProviderHostInfoPtr* info) {
mojom::ServiceWorkerContainerAssociatedPtr client_ptr;
client_request_ = mojo::MakeRequestAssociatedWithDedicatedPipe(&client_ptr);
- info->client_ptr_info = client_ptr.PassInterface();
- info->host_request = mojo::MakeRequestAssociatedWithDedicatedPipe(&host_ptr_);
+ (*info)->client_ptr_info = client_ptr.PassInterface();
+ (*info)->host_request =
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&host_ptr_);
}
void ServiceWorkerRemoteProviderEndpoint::BindWithProviderInfo(
@@ -103,58 +157,57 @@ void ServiceWorkerRemoteProviderEndpoint::BindWithProviderInfo(
host_ptr_.Bind(std::move(info->host_ptr_info));
}
+mojom::ServiceWorkerProviderHostInfoPtr CreateProviderHostInfoForWindow(
+ int provider_id,
+ int route_id) {
+ return mojom::ServiceWorkerProviderHostInfo::New(
+ provider_id, route_id,
+ blink::mojom::ServiceWorkerProviderType::kForWindow,
+ true /* is_parent_frame_secure */, nullptr /* host_request */,
+ nullptr /* client_ptr_info */);
+}
+
std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostForWindow(
int process_id,
int provider_id,
bool is_parent_frame_secure,
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerRemoteProviderEndpoint* output_endpoint) {
- ServiceWorkerProviderHostInfo info(
- provider_id, 1 /* route_id */,
- blink::mojom::ServiceWorkerProviderType::kForWindow,
- is_parent_frame_secure);
+ mojom::ServiceWorkerProviderHostInfoPtr info =
+ CreateProviderHostInfoForWindow(provider_id, 1 /* route_id */);
+ info->is_parent_frame_secure = is_parent_frame_secure;
output_endpoint->BindWithProviderHostInfo(&info);
return ServiceWorkerProviderHost::Create(process_id, std::move(info),
- std::move(context), nullptr);
+ std::move(context));
}
-std::unique_ptr<ServiceWorkerProviderHost>
+base::WeakPtr<ServiceWorkerProviderHost>
CreateProviderHostForServiceWorkerContext(
int process_id,
bool is_parent_frame_secure,
ServiceWorkerVersion* hosted_version,
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerRemoteProviderEndpoint* output_endpoint) {
- ServiceWorkerProviderHostInfo info(
- kInvalidServiceWorkerProviderId, MSG_ROUTING_NONE,
- blink::mojom::ServiceWorkerProviderType::kForServiceWorker,
- is_parent_frame_secure);
- std::unique_ptr<ServiceWorkerProviderHost> host =
- ServiceWorkerProviderHost::PreCreateForController(std::move(context));
+ auto provider_info = mojom::ServiceWorkerProviderInfoForStartWorker::New();
+ base::WeakPtr<ServiceWorkerProviderHost> host =
+ ServiceWorkerProviderHost::PreCreateForController(
+ std::move(context), base::WrapRefCounted(hosted_version),
+ &provider_info);
+
host->SetDocumentUrl(hosted_version->script_url());
- mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info =
- host->CompleteStartWorkerPreparation(
- process_id, hosted_version, nullptr /* non_network_loader_factory */);
+
+ scoped_refptr<network::SharedURLLoaderFactory> loader_factory;
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ loader_factory = network::SharedURLLoaderFactory::Create(
+ std::make_unique<MockSharedURLLoaderFactoryInfo>());
+ }
+
+ provider_info = host->CompleteStartWorkerPreparation(
+ process_id, loader_factory, std::move(provider_info));
output_endpoint->BindWithProviderInfo(std::move(provider_info));
return host;
}
-std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostWithDispatcherHost(
- int process_id,
- int provider_id,
- base::WeakPtr<ServiceWorkerContextCore> context,
- int route_id,
- ServiceWorkerDispatcherHost* dispatcher_host,
- ServiceWorkerRemoteProviderEndpoint* output_endpoint) {
- 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,
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 859b06d488f..7b550c6efd0 100644
--- a/chromium/content/browser/service_worker/service_worker_test_utils.h
+++ b/chromium/content/browser/service_worker/service_worker_test_utils.h
@@ -27,35 +27,35 @@ class HttpResponseInfo;
namespace content {
class ServiceWorkerContextCore;
-class ServiceWorkerDispatcherHost;
class ServiceWorkerProviderHost;
class ServiceWorkerStorage;
class ServiceWorkerVersion;
-struct ServiceWorkerProviderHostInfo;
template <typename Arg>
void ReceiveResult(BrowserThread::ID run_quit_thread,
const base::Closure& quit,
- Arg* out, Arg actual) {
+ base::Optional<Arg>* out,
+ Arg actual) {
*out = actual;
if (!quit.is_null())
BrowserThread::PostTask(run_quit_thread, FROM_HERE, quit);
}
-template <typename Arg> base::Callback<void(Arg)>
-CreateReceiver(BrowserThread::ID run_quit_thread,
- const base::Closure& quit, Arg* out) {
- return base::Bind(&ReceiveResult<Arg>, run_quit_thread, quit, out);
+template <typename Arg>
+base::OnceCallback<void(Arg)> CreateReceiver(BrowserThread::ID run_quit_thread,
+ const base::RepeatingClosure& quit,
+ base::Optional<Arg>* out) {
+ return base::BindOnce(&ReceiveResult<Arg>, run_quit_thread, quit, out);
}
template <typename Arg>
-base::Callback<void(Arg)> CreateReceiverOnCurrentThread(
- Arg* out,
+base::OnceCallback<void(Arg)> CreateReceiverOnCurrentThread(
+ base::Optional<Arg>* out,
const base::Closure& quit = base::Closure()) {
BrowserThread::ID id;
bool ret = BrowserThread::GetCurrentThreadIdentifier(&id);
DCHECK(ret);
- return base::Bind(&ReceiveResult<Arg>, id, quit, out);
+ return CreateReceiver(id, quit, out);
}
// Container for keeping the Mojo connection to the service worker provider on
@@ -67,7 +67,7 @@ class ServiceWorkerRemoteProviderEndpoint {
ServiceWorkerRemoteProviderEndpoint&& other);
~ServiceWorkerRemoteProviderEndpoint();
- void BindWithProviderHostInfo(ServiceWorkerProviderHostInfo* info);
+ void BindWithProviderHostInfo(mojom::ServiceWorkerProviderHostInfoPtr* info);
void BindWithProviderInfo(
mojom::ServiceWorkerProviderInfoForStartWorkerPtr info);
@@ -90,6 +90,10 @@ class ServiceWorkerRemoteProviderEndpoint {
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRemoteProviderEndpoint);
};
+mojom::ServiceWorkerProviderHostInfoPtr CreateProviderHostInfoForWindow(
+ int provider_id,
+ int route_id);
+
std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostForWindow(
int process_id,
int provider_id,
@@ -97,7 +101,7 @@ std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostForWindow(
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerRemoteProviderEndpoint* output_endpoint);
-std::unique_ptr<ServiceWorkerProviderHost>
+base::WeakPtr<ServiceWorkerProviderHost>
CreateProviderHostForServiceWorkerContext(
int process_id,
bool is_parent_frame_secure,
@@ -105,14 +109,6 @@ CreateProviderHostForServiceWorkerContext(
base::WeakPtr<ServiceWorkerContextCore> context,
ServiceWorkerRemoteProviderEndpoint* output_endpoint);
-std::unique_ptr<ServiceWorkerProviderHost> CreateProviderHostWithDispatcherHost(
- int process_id,
- int provider_id,
- base::WeakPtr<ServiceWorkerContextCore> context,
- int route_id,
- 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
diff --git a/chromium/content/browser/service_worker/service_worker_type_converters.cc b/chromium/content/browser/service_worker/service_worker_type_converters.cc
index 4bdb3cc82af..163959c53b5 100644
--- a/chromium/content/browser/service_worker/service_worker_type_converters.cc
+++ b/chromium/content/browser/service_worker/service_worker_type_converters.cc
@@ -34,20 +34,4 @@ TypeConverter<blink::mojom::ServiceWorkerState,
return blink::mojom::ServiceWorkerState::kUnknown;
}
-content::ServiceWorkerStatusCode
-TypeConverter<content::ServiceWorkerStatusCode,
- blink::mojom::ServiceWorkerEventStatus>::
- Convert(blink::mojom::ServiceWorkerEventStatus status) {
- switch (status) {
- case blink::mojom::ServiceWorkerEventStatus::COMPLETED:
- return content::SERVICE_WORKER_OK;
- case blink::mojom::ServiceWorkerEventStatus::REJECTED:
- return content::SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED;
- case blink::mojom::ServiceWorkerEventStatus::ABORTED:
- return content::SERVICE_WORKER_ERROR_ABORT;
- }
- NOTREACHED() << status;
- return content::SERVICE_WORKER_ERROR_FAILED;
-}
-
} // namespace mojo
diff --git a/chromium/content/browser/service_worker/service_worker_type_converters.h b/chromium/content/browser/service_worker/service_worker_type_converters.h
index 207ef89cc3c..cd53395549a 100644
--- a/chromium/content/browser/service_worker/service_worker_type_converters.h
+++ b/chromium/content/browser/service_worker/service_worker_type_converters.h
@@ -2,12 +2,10 @@
// 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_STATE_CONVERTERS_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_STATE_CONVERTERS_H_
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_TYPE_CONVERTERS_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_TYPE_CONVERTERS_H_
#include "content/browser/service_worker/service_worker_version.h"
-#include "content/common/service_worker/service_worker_status_code.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_state.mojom.h"
namespace mojo {
@@ -19,13 +17,6 @@ struct CONTENT_EXPORT TypeConverter<blink::mojom::ServiceWorkerState,
content::ServiceWorkerVersion::Status status);
};
-template <>
-struct CONTENT_EXPORT TypeConverter<content::ServiceWorkerStatusCode,
- blink::mojom::ServiceWorkerEventStatus> {
- static content::ServiceWorkerStatusCode Convert(
- blink::mojom::ServiceWorkerEventStatus status);
-};
-
} // namespace mojo
-#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_STATE_CONVERTERS_H_
+#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_TYPE_CONVERTERS_H_
diff --git a/chromium/content/browser/service_worker/service_worker_unregister_job.cc b/chromium/content/browser/service_worker/service_worker_unregister_job.cc
index 64eb79e375d..9b063838484 100644
--- a/chromium/content/browser/service_worker/service_worker_unregister_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_unregister_job.cc
@@ -40,7 +40,7 @@ void ServiceWorkerUnregisterJob::Start() {
void ServiceWorkerUnregisterJob::Abort() {
CompleteInternal(blink::mojom::kInvalidServiceWorkerRegistrationId,
- SERVICE_WORKER_ERROR_ABORT);
+ blink::ServiceWorkerStatusCode::kErrorAbort);
}
bool ServiceWorkerUnregisterJob::Equals(
@@ -55,16 +55,17 @@ RegistrationJobType ServiceWorkerUnregisterJob::GetType() const {
}
void ServiceWorkerUnregisterJob::OnRegistrationFound(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
- if (status == SERVICE_WORKER_ERROR_NOT_FOUND) {
+ if (status == blink::ServiceWorkerStatusCode::kErrorNotFound) {
DCHECK(!registration.get());
Complete(blink::mojom::kInvalidServiceWorkerRegistrationId,
- SERVICE_WORKER_ERROR_NOT_FOUND);
+ blink::ServiceWorkerStatusCode::kErrorNotFound);
return;
}
- if (status != SERVICE_WORKER_OK || registration->is_uninstalling()) {
+ if (status != blink::ServiceWorkerStatusCode::kOk ||
+ registration->is_uninstalling()) {
Complete(blink::mojom::kInvalidServiceWorkerRegistrationId, status);
return;
}
@@ -72,29 +73,30 @@ void ServiceWorkerUnregisterJob::OnRegistrationFound(
// TODO: "7. If registration.updatePromise is not null..."
// "8. Resolve promise."
- ResolvePromise(registration->id(), SERVICE_WORKER_OK);
+ ResolvePromise(registration->id(), blink::ServiceWorkerStatusCode::kOk);
registration->ClearWhenReady();
- Complete(registration->id(), SERVICE_WORKER_OK);
+ Complete(registration->id(), blink::ServiceWorkerStatusCode::kOk);
}
-void ServiceWorkerUnregisterJob::Complete(int64_t registration_id,
- ServiceWorkerStatusCode status) {
+void ServiceWorkerUnregisterJob::Complete(
+ int64_t registration_id,
+ blink::ServiceWorkerStatusCode status) {
CompleteInternal(registration_id, status);
context_->job_coordinator()->FinishJob(pattern_, this);
}
void ServiceWorkerUnregisterJob::CompleteInternal(
int64_t registration_id,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
if (!is_promise_resolved_)
ResolvePromise(registration_id, status);
}
void ServiceWorkerUnregisterJob::ResolvePromise(
int64_t registration_id,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK(!is_promise_resolved_);
is_promise_resolved_ = true;
for (UnregistrationCallback& callback : callbacks_)
diff --git a/chromium/content/browser/service_worker/service_worker_unregister_job.h b/chromium/content/browser/service_worker/service_worker_unregister_job.h
index 0ded1bb3cd1..1c86888aa76 100644
--- a/chromium/content/browser/service_worker/service_worker_unregister_job.h
+++ b/chromium/content/browser/service_worker/service_worker_unregister_job.h
@@ -13,7 +13,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/service_worker/service_worker_register_job_base.h"
-#include "content/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"
namespace content {
@@ -29,7 +29,7 @@ class ServiceWorkerRegistration;
class ServiceWorkerUnregisterJob : public ServiceWorkerRegisterJobBase {
public:
typedef base::OnceCallback<void(int64_t registration_id,
- ServiceWorkerStatusCode status)>
+ blink::ServiceWorkerStatusCode status)>
UnregistrationCallback;
ServiceWorkerUnregisterJob(base::WeakPtr<ServiceWorkerContextCore> context,
@@ -48,12 +48,13 @@ class ServiceWorkerUnregisterJob : public ServiceWorkerRegisterJobBase {
private:
void OnRegistrationFound(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
- void Complete(int64_t registration_id, ServiceWorkerStatusCode status);
+ void Complete(int64_t registration_id, blink::ServiceWorkerStatusCode status);
void CompleteInternal(int64_t registration_id,
- ServiceWorkerStatusCode status);
- void ResolvePromise(int64_t registration_id, ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
+ void ResolvePromise(int64_t registration_id,
+ blink::ServiceWorkerStatusCode status);
base::WeakPtr<ServiceWorkerContextCore> context_;
const GURL pattern_;
diff --git a/chromium/content/browser/service_worker/service_worker_url_job_wrapper.cc b/chromium/content/browser/service_worker/service_worker_url_job_wrapper.cc
index 67c69af0b3c..52fc1fc8fe3 100644
--- a/chromium/content/browser/service_worker/service_worker_url_job_wrapper.cc
+++ b/chromium/content/browser/service_worker/service_worker_url_job_wrapper.cc
@@ -39,7 +39,10 @@ void ServiceWorkerURLJobWrapper::FallbackToNetwork() {
void ServiceWorkerURLJobWrapper::FallbackToNetworkOrRenderer() {
if (url_loader_job_) {
- url_loader_job_->FallbackToNetworkOrRenderer();
+ // Fallback to renderer is used when CORS checks need to be performed on the
+ // request. CORS doesn't apply to navigations, and |url_loader_job_| is for
+ // navigations, so just use FallbackToNetwork().
+ url_loader_job_->FallbackToNetwork();
} else {
url_request_job_->FallbackToNetworkOrRenderer();
}
@@ -62,11 +65,10 @@ bool ServiceWorkerURLJobWrapper::ShouldFallbackToNetwork() {
}
void ServiceWorkerURLJobWrapper::FailDueToLostController() {
- if (url_loader_job_) {
- url_loader_job_->FailDueToLostController();
- } else {
- url_request_job_->FailDueToLostController();
- }
+ // This function is only called for subresource requests, so it can't
+ // be called for |url_loader_job_|, which is for navigations.
+ DCHECK(!url_loader_job_);
+ url_request_job_->FailDueToLostController();
}
bool ServiceWorkerURLJobWrapper::WasCanceled() const {
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 0405cdb5dfa..c40adc1c9bb 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
@@ -106,12 +106,6 @@ net::NetLogEventType RequestJobResultToNetEventType(
return n::SERVICE_WORKER_ERROR_BAD_DELEGATE;
case m::REQUEST_JOB_ERROR_REQUEST_BODY_BLOB_FAILED:
return n::SERVICE_WORKER_ERROR_REQUEST_BODY_BLOB_FAILED;
- // We can't log if there's no request; fallthrough.
- case m::REQUEST_JOB_ERROR_NO_REQUEST:
- // Obsolete types; fallthrough.
- case m::REQUEST_JOB_ERROR_DESTROYED:
- case m::REQUEST_JOB_ERROR_DESTROYED_WITH_BLOB:
- case m::REQUEST_JOB_ERROR_DESTROYED_WITH_STREAM:
// Invalid type.
case m::NUM_REQUEST_JOB_RESULT_TYPES:
NOTREACHED() << result;
@@ -662,7 +656,7 @@ void ServiceWorkerURLRequestJob::DidPrepareFetchEvent(
}
void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
@@ -685,7 +679,7 @@ void ServiceWorkerURLRequestJob::DidDispatchFetchEvent(
return;
}
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
RecordResult(ServiceWorkerMetrics::REQUEST_JOB_ERROR_FETCH_EVENT_DISPATCH);
if (IsMainResourceLoad()) {
// Using the service worker failed, so fallback to network.
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 9d25a9c5a9b..5c8f00e1ee7 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
@@ -23,8 +23,7 @@
#include "content/browser/service_worker/service_worker_response_type.h"
#include "content/browser/service_worker/service_worker_url_job_wrapper.h"
#include "content/common/content_export.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.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/request_context_type.h"
#include "content/public/common/resource_type.h"
@@ -37,6 +36,7 @@
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "storage/common/blob_storage/blob_storage_constants.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"
namespace net {
@@ -188,7 +188,7 @@ class CONTENT_EXPORT ServiceWorkerURLRequestJob : public net::URLRequestJob {
// For FORWARD_TO_SERVICE_WORKER case.
void DidPrepareFetchEvent(scoped_refptr<ServiceWorkerVersion> version);
void DidDispatchFetchEvent(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
const ServiceWorkerResponse& response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
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 094bfb5e5f4..ce237a44d28 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
@@ -14,7 +14,7 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
@@ -31,7 +31,6 @@
#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_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"
@@ -61,6 +60,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/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom.h"
@@ -156,8 +156,8 @@ std::unique_ptr<ServiceWorkerHeaderMap> MakeHeaders() {
return headers;
}
-void SaveStatusCallback(ServiceWorkerStatusCode* out_status,
- ServiceWorkerStatusCode status) {
+void SaveStatusCallback(blink::ServiceWorkerStatusCode* out_status,
+ blink::ServiceWorkerStatusCode status) {
*out_status = status;
}
@@ -231,13 +231,13 @@ class ServiceWorkerURLRequestJobTest
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
// Make the registration findable via storage functions.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
helper_->context()->storage()->StoreRegistration(
registration_.get(),
version_.get(),
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- ASSERT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
// Create a controlled client.
std::unique_ptr<ServiceWorkerProviderHost> provider_host =
@@ -497,7 +497,7 @@ class DelayHelper : public EmbeddedWorkerTestHelper {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
@@ -508,7 +508,7 @@ class DelayHelper : public EmbeddedWorkerTestHelper {
scope_ = scope;
script_url_ = script_url;
pause_after_download_ = pause_after_download;
- start_worker_request_ = std::move(dispatcher_request);
+ start_worker_request_ = std::move(service_worker_request);
controller_request_ = std::move(controller_request);
start_worker_instance_host_ = std::move(instance_host);
provider_info_ = std::move(provider_info);
@@ -518,10 +518,10 @@ class DelayHelper : public EmbeddedWorkerTestHelper {
void OnFetchEvent(
int embedded_worker_id,
const network::ResourceRequest& /* request */,
- mojom::FetchEventPreloadHandlePtr preload_handle,
+ blink::mojom::FetchEventPreloadHandlePtr preload_handle,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback) override {
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
+ override {
embedded_worker_id_ = embedded_worker_id;
response_callback_ = std::move(response_callback);
finish_callback_ = std::move(finish_callback);
@@ -533,7 +533,7 @@ class DelayHelper : public EmbeddedWorkerTestHelper {
GURL scope_;
GURL script_url_;
bool pause_after_download_;
- mojom::ServiceWorkerEventDispatcherRequest start_worker_request_;
+ mojom::ServiceWorkerRequest start_worker_request_;
mojom::ControllerServiceWorkerRequest controller_request_;
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo
start_worker_instance_host_;
@@ -541,9 +541,8 @@ class DelayHelper : public EmbeddedWorkerTestHelper {
blink::mojom::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info_;
int embedded_worker_id_ = 0;
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_;
- mojom::FetchEventPreloadHandlePtr preload_handle_;
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback_;
+ blink::mojom::FetchEventPreloadHandlePtr preload_handle_;
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_;
ServiceWorkerURLRequestJobTest* test_;
DISALLOW_COPY_AND_ASSIGN(DelayHelper);
};
@@ -554,14 +553,15 @@ TEST_F(ServiceWorkerURLRequestJobTest,
DelayHelper* helper = static_cast<DelayHelper*>(helper_.get());
// Start the worker before the navigation.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ blink::ServiceWorkerStatusCode status =
+ blink::ServiceWorkerStatusCode::kErrorFailed;
base::HistogramTester histogram_tester;
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
base::BindOnce(&SaveStatusCallback, &status));
base::RunLoop().RunUntilIdle();
helper->CompleteStartWorker();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status);
// Do the navigation.
SetUpNavigationPreloadTest(RESOURCE_TYPE_MAIN_FRAME);
@@ -696,10 +696,10 @@ class ProviderDeleteHelper : public EmbeddedWorkerTestHelper {
void OnFetchEvent(
int /* embedded_worker_id */,
const network::ResourceRequest& /* request */,
- mojom::FetchEventPreloadHandlePtr /* preload_handle */,
+ blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback) override {
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
+ override {
context()->RemoveProviderHost(mock_render_process_id(), kProviderID);
response_callback->OnResponse(
ServiceWorkerResponse(
@@ -786,10 +786,10 @@ class BlobResponder : public EmbeddedWorkerTestHelper {
void OnFetchEvent(
int /* embedded_worker_id */,
const network::ResourceRequest& /* request */,
- mojom::FetchEventPreloadHandlePtr /* preload_handle */,
+ blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback) override {
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
+ override {
response_callback->OnResponse(
ServiceWorkerResponse(
std::make_unique<std::vector<GURL>>(), 200, "OK",
@@ -887,10 +887,10 @@ class StreamResponder : public EmbeddedWorkerTestHelper {
void OnFetchEvent(
int /* embedded_worker_id */,
const network::ResourceRequest& /* request */,
- mojom::FetchEventPreloadHandlePtr /* preload_handle */,
+ blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback) override {
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
+ override {
ASSERT_FALSE(stream_handle_.is_null());
response_callback->OnResponseStream(
ServiceWorkerResponse(
@@ -1277,10 +1277,10 @@ class FailFetchHelper : public EmbeddedWorkerTestHelper {
void OnFetchEvent(
int embedded_worker_id,
const network::ResourceRequest& /* request */,
- mojom::FetchEventPreloadHandlePtr /* preload_handle */,
+ blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr /* response_callback */,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback) override {
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
+ override {
SimulateWorkerStopped(embedded_worker_id);
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::ABORTED,
@@ -1370,10 +1370,10 @@ class EarlyResponseHelper : public EmbeddedWorkerTestHelper {
void OnFetchEvent(
int /* embedded_worker_id */,
const network::ResourceRequest& /* request */,
- mojom::FetchEventPreloadHandlePtr /* preload_handle */,
+ blink::mojom::FetchEventPreloadHandlePtr /* preload_handle */,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback) override {
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback)
+ override {
finish_callback_ = std::move(finish_callback);
response_callback->OnResponse(
ServiceWorkerResponse(
@@ -1390,8 +1390,7 @@ class EarlyResponseHelper : public EmbeddedWorkerTestHelper {
}
private:
- mojom::ServiceWorkerEventDispatcher::DispatchFetchEventCallback
- finish_callback_;
+ mojom::ServiceWorker::DispatchFetchEventCallback finish_callback_;
DISALLOW_COPY_AND_ASSIGN(EarlyResponseHelper);
};
diff --git a/chromium/content/browser/service_worker/service_worker_version.cc b/chromium/content/browser/service_worker/service_worker_version.cc
index bfe78b055f3..8d58920080e 100644
--- a/chromium/content/browser/service_worker/service_worker_version.cc
+++ b/chromium/content/browser/service_worker/service_worker_version.cc
@@ -30,7 +30,6 @@
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_installed_scripts_sender.h"
#include "content/browser/service_worker/service_worker_registration.h"
-#include "content/browser/service_worker/service_worker_type_converters.h"
#include "content/common/service_worker/embedded_worker.mojom.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "content/common/service_worker/service_worker_utils.h"
@@ -44,6 +43,8 @@
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
+#include "third_party/blink/public/common/service_worker/service_worker_type_converters.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
@@ -62,9 +63,6 @@ constexpr base::TimeDelta kRequestTimeout = base::TimeDelta::FromMinutes(5);
// Time to wait until stopping an idle worker.
constexpr base::TimeDelta kIdleWorkerTimeout = base::TimeDelta::FromSeconds(30);
-// Timeout for waiting for a response to a ping.
-constexpr base::TimeDelta kPingTimeout = base::TimeDelta::FromSeconds(30);
-
// Default delay for scheduled update.
constexpr base::TimeDelta kUpdateDelay = base::TimeDelta::FromSeconds(1);
@@ -98,13 +96,14 @@ void RunCallbacks(ServiceWorkerVersion* version,
// An adapter to run a |callback| after StartWorker.
void RunCallbackAfterStartWorker(base::WeakPtr<ServiceWorkerVersion> version,
ServiceWorkerVersion::StatusCallback callback,
- ServiceWorkerStatusCode status) {
- if (status == SERVICE_WORKER_OK &&
+ blink::ServiceWorkerStatusCode status) {
+ if (status == blink::ServiceWorkerStatusCode::kOk &&
version->running_status() != EmbeddedWorkerStatus::RUNNING) {
// We've tried to start the worker (and it has succeeded), but
// it looks it's not running yet.
NOTREACHED() << "The worker's not running after successful StartWorker";
- std::move(callback).Run(SERVICE_WORKER_ERROR_START_WORKER_FAILED);
+ std::move(callback).Run(
+ blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed);
return;
}
std::move(callback).Run(status);
@@ -146,8 +145,7 @@ int NextTraceId() {
return trace_id;
}
-void OnEventDispatcherConnectionError(
- base::WeakPtr<EmbeddedWorkerInstance> embedded_worker) {
+void OnConnectionError(base::WeakPtr<EmbeddedWorkerInstance> embedded_worker) {
if (!embedded_worker)
return;
@@ -165,30 +163,12 @@ void OnEventDispatcherConnectionError(
}
}
-// In S13nServiceWorker, |loader_factory| is the factory to use loading new
-// scripts from network (or other sources, e.g., for chrome-extension:// URLs).
-mojom::ServiceWorkerProviderInfoForStartWorkerPtr
-CompleteProviderHostPreparation(
- ServiceWorkerVersion* version,
- std::unique_ptr<ServiceWorkerProviderHost> provider_host,
- base::WeakPtr<ServiceWorkerContextCore> context,
- int process_id,
- scoped_refptr<network::SharedURLLoaderFactory> loader_factory) {
- // Caller should ensure |context| is alive when completing StartWorker
- // preparation.
- DCHECK(context);
- auto info = provider_host->CompleteStartWorkerPreparation(
- process_id, version, std::move(loader_factory));
- context->AddProviderHost(std::move(provider_host));
- return info;
-}
-
void OnOpenWindowFinished(
blink::mojom::ServiceWorkerHost::OpenNewTabCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
blink::mojom::ServiceWorkerClientInfoPtr client_info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- const bool success = (status == SERVICE_WORKER_OK);
+ const bool success = (status == blink::ServiceWorkerStatusCode::kOk);
base::Optional<std::string> error_msg;
if (!success) {
DCHECK(!client_info);
@@ -210,7 +190,8 @@ void DidShowPaymentHandlerWindow(
base::BindOnce(&OnOpenWindowFinished, std::move(callback)),
render_process_id, render_frame_id);
} else {
- OnOpenWindowFinished(std::move(callback), SERVICE_WORKER_ERROR_FAILED,
+ OnOpenWindowFinished(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorFailed,
nullptr /* client_info */);
}
}
@@ -226,10 +207,10 @@ void DidGetClients(
void DidNavigateClient(
blink::mojom::ServiceWorkerHost::NavigateClientCallback callback,
const GURL& url,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
blink::mojom::ServiceWorkerClientInfoPtr client) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- const bool success = (status == SERVICE_WORKER_OK);
+ const bool success = (status == blink::ServiceWorkerStatusCode::kOk);
base::Optional<std::string> error_msg;
if (!success) {
DCHECK(!client);
@@ -262,57 +243,6 @@ base::TimeDelta ServiceWorkerVersion::GetTickDuration(
return tick_clock_->NowTicks() - time;
}
-// A controller for periodically sending a ping to the worker to see
-// if the worker is not stalling.
-class ServiceWorkerVersion::PingController {
- public:
- explicit PingController(ServiceWorkerVersion* version) : version_(version) {}
- ~PingController() {}
-
- void Activate() { ping_state_ = PINGING; }
-
- void Deactivate() {
- ClearTick(&ping_time_);
- ping_state_ = NOT_PINGING;
- }
-
- void OnPongReceived() { ClearTick(&ping_time_); }
-
- bool IsTimedOut() { return ping_state_ == PING_TIMED_OUT; }
-
- // Checks ping status. This is supposed to be called periodically.
- // This may call:
- // - OnPingTimeout() if the worker hasn't reponded within a certain period.
- // - PingWorker() if we're running ping timer and can send next ping.
- void CheckPingStatus() {
- if (version_->GetTickDuration(ping_time_) > kPingTimeout) {
- ping_state_ = PING_TIMED_OUT;
- version_->OnPingTimeout();
- return;
- }
-
- // Check if we want to send a next ping.
- if (ping_state_ != PINGING || !ping_time_.is_null())
- return;
-
- version_->PingWorker();
- version_->RestartTick(&ping_time_);
- }
-
- void SimulateTimeoutForTesting() {
- version_->PingWorker();
- ping_state_ = PING_TIMED_OUT;
- version_->OnPingTimeout();
- }
-
- private:
- enum PingState { NOT_PINGING, PINGING, PING_TIMED_OUT };
- ServiceWorkerVersion* version_; // Not owned.
- base::TimeTicks ping_time_;
- PingState ping_state_ = NOT_PINGING;
- DISALLOW_COPY_AND_ASSIGN(PingController);
-};
-
ServiceWorkerVersion::ServiceWorkerVersion(
ServiceWorkerRegistration* registration,
const GURL& script_url,
@@ -330,7 +260,7 @@ ServiceWorkerVersion::ServiceWorkerVersion(
script_cache_map_(this, context),
tick_clock_(base::DefaultTickClock::GetInstance()),
clock_(base::DefaultClock::GetInstance()),
- ping_controller_(new PingController(this)),
+ ping_controller_(this),
validator_(std::make_unique<blink::TrialTokenValidator>()),
weak_factory_(this) {
DCHECK_NE(blink::mojom::kInvalidServiceWorkerVersionId, version_id);
@@ -351,7 +281,8 @@ ServiceWorkerVersion::~ServiceWorkerVersion() {
// RecordStartWorkerResult must be the first element of start_callbacks_.
StatusCallback record_start_worker_result = std::move(start_callbacks_[0]);
start_callbacks_.clear();
- std::move(record_start_worker_result).Run(SERVICE_WORKER_ERROR_ABORT);
+ std::move(record_start_worker_result)
+ .Run(blink::ServiceWorkerStatusCode::kErrorAbort);
}
if (context_)
@@ -418,14 +349,14 @@ void ServiceWorkerVersion::SetStatus(Status status) {
}
// OnVersionStateChanged() invokes updates of the status using state
- // change IPC at ServiceWorkerHandle (for JS-land on renderer process) and
+ // change IPC at ServiceWorkerObjectHost (for JS-land on renderer process) and
// ServiceWorkerContextCore (for devtools and serviceworker-internals).
// This should be done before using the new status by
// |status_change_callbacks_| which sends the IPC for resolving the .ready
// property.
// TODO(shimazu): Clarify the dependency of OnVersionStateChanged and
// |status_change_callbacks_|
- for (auto& observer : listeners_)
+ for (auto& observer : observers_)
observer.OnVersionStateChanged(this);
std::vector<base::OnceClosure> callbacks;
@@ -494,24 +425,25 @@ void ServiceWorkerVersion::StartWorker(ServiceWorkerMetrics::EventType purpose,
if (!context_) {
RecordStartWorkerResult(purpose, status_, kInvalidTraceId,
is_browser_startup_complete,
- SERVICE_WORKER_ERROR_ABORT);
- RunSoon(base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_ABORT));
+ blink::ServiceWorkerStatusCode::kErrorAbort);
+ RunSoon(base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
if (is_redundant()) {
RecordStartWorkerResult(purpose, status_, kInvalidTraceId,
is_browser_startup_complete,
- SERVICE_WORKER_ERROR_REDUNDANT);
- RunSoon(
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_REDUNDANT));
+ blink::ServiceWorkerStatusCode::kErrorRedundant);
+ RunSoon(base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorRedundant));
return;
}
if (!IsStartWorkerAllowed()) {
RecordStartWorkerResult(purpose, status_, kInvalidTraceId,
is_browser_startup_complete,
- SERVICE_WORKER_ERROR_DISALLOWED);
- RunSoon(
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_DISALLOWED));
+ blink::ServiceWorkerStatusCode::kErrorDisallowed);
+ RunSoon(base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorDisallowed));
return;
}
@@ -602,6 +534,7 @@ int ServiceWorkerVersion::StartRequestWithCustomTimeout(
DCHECK(event_type == ServiceWorkerMetrics::EventType::INSTALL ||
event_type == ServiceWorkerMetrics::EventType::ACTIVATE ||
event_type == ServiceWorkerMetrics::EventType::MESSAGE ||
+ event_type == ServiceWorkerMetrics::EventType::EXTERNAL_REQUEST ||
status() == ACTIVATED)
<< "Event of type " << static_cast<int>(event_type)
<< " can only be dispatched to an active worker: " << status();
@@ -637,6 +570,9 @@ int ServiceWorkerVersion::StartRequestWithCustomTimeout(
bool ServiceWorkerVersion::StartExternalRequest(
const std::string& request_uuid) {
+ if (running_status() == EmbeddedWorkerStatus::STARTING)
+ return pending_external_requests_.insert(request_uuid).second;
+
// It's possible that the renderer is lying or the version started stopping
// right around the time of the IPC.
if (running_status() != EmbeddedWorkerStatus::RUNNING)
@@ -660,13 +596,12 @@ bool ServiceWorkerVersion::FinishRequest(int request_id,
if (!request)
return false;
if (event_recorder_)
- event_recorder_->RecordEventHandledStatus(request->event_type, was_handled);
+ event_recorder_->RecordEventHandledStatus(request->event_type);
ServiceWorkerMetrics::RecordEventDuration(
request->event_type, tick_clock_->NowTicks() - request->start_time_ticks,
was_handled);
ServiceWorkerMetrics::RecordEventDispatchingDelay(
- request->event_type, dispatch_event_time - request->start_time,
- site_for_uma());
+ request->event_type, dispatch_event_time - request->start_time);
RestartTick(&idle_time_);
TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request",
@@ -681,6 +616,9 @@ bool ServiceWorkerVersion::FinishRequest(int request_id,
bool ServiceWorkerVersion::FinishExternalRequest(
const std::string& request_uuid) {
+ if (running_status() == EmbeddedWorkerStatus::STARTING)
+ return pending_external_requests_.erase(request_uuid) > 0u;
+
// It's possible that the renderer is lying or the version started stopping
// right around the time of the IPC.
if (running_status() != EmbeddedWorkerStatus::RUNNING)
@@ -703,7 +641,7 @@ bool ServiceWorkerVersion::FinishExternalRequest(
ServiceWorkerVersion::SimpleEventCallback
ServiceWorkerVersion::CreateSimpleEventCallback(int request_id) {
// The weak reference to |this| is safe because storage of the callbacks, the
- // inflight responses of the ServiceWorkerEventDispatcher, is owned by |this|.
+ // inflight responses of mojom::ServiceWorker messages, is owned by |this|.
return base::BindOnce(&ServiceWorkerVersion::OnSimpleEventFinished,
base::Unretained(this), request_id);
}
@@ -713,7 +651,7 @@ void ServiceWorkerVersion::RunAfterStartWorker(
StatusCallback callback) {
if (running_status() == EmbeddedWorkerStatus::RUNNING) {
DCHECK(start_callbacks_.empty());
- std::move(callback).Run(SERVICE_WORKER_OK);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kOk);
return;
}
StartWorker(purpose,
@@ -767,19 +705,20 @@ void ServiceWorkerVersion::OnStreamResponseFinished() {
OnNoWorkInBrowser();
}
-void ServiceWorkerVersion::AddListener(Listener* listener) {
- listeners_.AddObserver(listener);
+void ServiceWorkerVersion::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
}
-void ServiceWorkerVersion::RemoveListener(Listener* listener) {
- listeners_.RemoveObserver(listener);
+void ServiceWorkerVersion::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
}
-void ServiceWorkerVersion::ReportError(ServiceWorkerStatusCode status,
+void ServiceWorkerVersion::ReportError(blink::ServiceWorkerStatusCode status,
const std::string& status_message) {
if (status_message.empty()) {
- OnReportException(base::UTF8ToUTF16(ServiceWorkerStatusToString(status)),
- -1, -1, GURL());
+ OnReportException(
+ base::UTF8ToUTF16(blink::ServiceWorkerStatusToString(status)), -1, -1,
+ GURL());
} else {
OnReportException(base::UTF8ToUTF16(status_message), -1, -1, GURL());
}
@@ -791,7 +730,7 @@ void ServiceWorkerVersion::ReportForceUpdateToDevTools() {
}
void ServiceWorkerVersion::SetStartWorkerStatusCode(
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
start_worker_status_ = status;
}
@@ -822,6 +761,22 @@ void ServiceWorkerVersion::Doom() {
context_->storage()->PurgeResources(resources);
}
+void ServiceWorkerVersion::SetToPauseAfterDownload(base::OnceClosure callback) {
+ pause_after_download_callback_ = std::move(callback);
+}
+
+void ServiceWorkerVersion::SetToNotPauseAfterDownload() {
+ pause_after_download_callback_.Reset();
+}
+
+void ServiceWorkerVersion::OnMainScriptLoaded() {
+ if (!pause_after_download_callback_)
+ return;
+ // The callback can destroy |this|, so protect it first.
+ auto protect = base::WrapRefCounted(this);
+ std::move(pause_after_download_callback_).Run();
+}
+
void ServiceWorkerVersion::SetValidOriginTrialTokens(
const blink::TrialTokenValidator::FeatureToTokensMap& tokens) {
origin_trial_tokens_ = validator_->GetValidTokens(
@@ -880,12 +835,12 @@ void ServiceWorkerVersion::SetMainScriptHttpResponseInfo(
url::Origin::Create(scope()), http_info.headers.get(), clock_->Now());
}
- for (auto& observer : listeners_)
+ for (auto& observer : observers_)
observer.OnMainScriptHttpResponseInfoSet(this);
}
void ServiceWorkerVersion::SimulatePingTimeoutForTesting() {
- ping_controller_->SimulateTimeoutForTesting();
+ ping_controller_.SimulateTimeoutForTesting();
}
void ServiceWorkerVersion::SetTickClockForTesting(
@@ -934,26 +889,42 @@ ServiceWorkerVersion::InflightRequest::InflightRequest(
ServiceWorkerVersion::InflightRequest::~InflightRequest() {}
-void ServiceWorkerVersion::OnThreadStarted() {
+void ServiceWorkerVersion::OnScriptEvaluationStart() {
DCHECK_EQ(EmbeddedWorkerStatus::STARTING, running_status());
// Activate ping/pong now that JavaScript execution will start.
- ping_controller_->Activate();
+ ping_controller_.Activate();
}
void ServiceWorkerVersion::OnStarting() {
- for (auto& observer : listeners_)
+ for (auto& observer : observers_)
observer.OnRunningStateChanged(this);
}
-void ServiceWorkerVersion::OnStarted() {
+void ServiceWorkerVersion::OnStarted(
+ blink::mojom::ServiceWorkerStartStatus start_status) {
DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, running_status());
RestartTick(&idle_time_);
+ // TODO(falken): This maps kAbruptCompletion to kErrorScriptEvaluated, which
+ // most start callbacks will consider to be a failure. But the worker thread
+ // is running, and the spec considers it a success, so the callbacks should
+ // change to treat kErrorScriptEvaluated as success, or use
+ // ServiceWorkerStartStatus directly.
+ blink::ServiceWorkerStatusCode status =
+ mojo::ConvertTo<blink::ServiceWorkerStatusCode>(start_status);
+
// Fire all start callbacks.
scoped_refptr<ServiceWorkerVersion> protect(this);
- FinishStartWorker(SERVICE_WORKER_OK);
- for (auto& observer : listeners_)
+ FinishStartWorker(status);
+ for (auto& observer : observers_)
observer.OnRunningStateChanged(this);
+
+ if (!pending_external_requests_.empty()) {
+ std::set<std::string> pending_external_requests;
+ std::swap(pending_external_requests_, pending_external_requests);
+ for (const std::string& request_uuid : pending_external_requests)
+ StartExternalRequest(request_uuid);
+ }
}
void ServiceWorkerVersion::OnStopping() {
@@ -968,7 +939,7 @@ void ServiceWorkerVersion::OnStopping() {
// worker stops, the timer is disabled. The interval will be reset to normal
// when the worker starts up again.
SetTimeoutTimerInterval(kStopWorkerTimeout);
- for (auto& observer : listeners_)
+ for (auto& observer : observers_)
observer.OnRunningStateChanged(this);
}
@@ -991,19 +962,8 @@ void ServiceWorkerVersion::OnDetached(EmbeddedWorkerStatus old_status) {
OnStoppedInternal(old_status);
}
-void ServiceWorkerVersion::OnScriptLoaded() {
- DCHECK(GetMainScriptHttpResponseInfo());
- if (IsInstalled(status()))
- UMA_HISTOGRAM_BOOLEAN("ServiceWorker.ScriptLoadSuccess", true);
-}
-
-void ServiceWorkerVersion::OnScriptLoadFailed() {
- if (IsInstalled(status()))
- UMA_HISTOGRAM_BOOLEAN("ServiceWorker.ScriptLoadSuccess", false);
-}
-
void ServiceWorkerVersion::OnRegisteredToDevToolsManager() {
- for (auto& observer : listeners_)
+ for (auto& observer : observers_)
observer.OnDevToolsRoutingIdChanged(this);
}
@@ -1012,7 +972,7 @@ void ServiceWorkerVersion::OnReportException(
int line_number,
int column_number,
const GURL& source_url) {
- for (auto& observer : listeners_) {
+ for (auto& observer : observers_) {
observer.OnErrorReported(this, error_message, line_number, column_number,
source_url);
}
@@ -1023,15 +983,14 @@ void ServiceWorkerVersion::OnReportConsoleMessage(int source_identifier,
const base::string16& message,
int line_number,
const GURL& source_url) {
- for (auto& observer : listeners_) {
+ for (auto& observer : observers_) {
observer.OnReportConsoleMessage(this, source_identifier, message_level,
message, line_number, source_url);
}
}
-void ServiceWorkerVersion::OnStartSentAndScriptEvaluated(
- ServiceWorkerStatusCode status) {
- if (status != SERVICE_WORKER_OK) {
+void ServiceWorkerVersion::OnStartSent(blink::ServiceWorkerStatusCode status) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
scoped_refptr<ServiceWorkerVersion> protect(this);
FinishStartWorker(DeduceStartWorkerFailureReason(status));
}
@@ -1161,6 +1120,12 @@ void ServiceWorkerVersion::PostMessageToClient(
binding_.Close();
return;
}
+ if (!provider_host->is_execution_ready()) {
+ mojo::ReportBadMessage(
+ "Received Client#postMessage() request for a reserved client.");
+ binding_.Close();
+ return;
+ }
provider_host->PostMessageToClient(this, std::move(message));
}
@@ -1301,8 +1266,8 @@ void ServiceWorkerVersion::OnSetCachedMetadataFinished(int64_t callback_id,
TRACE_EVENT_ASYNC_END1("ServiceWorker",
"ServiceWorkerVersion::SetCachedMetadata", callback_id,
"result", result);
- for (auto& listener : listeners_)
- listener.OnCachedMetadataUpdated(this, size);
+ for (auto& observer : observers_)
+ observer.OnCachedMetadataUpdated(this, size);
}
void ServiceWorkerVersion::OnClearCachedMetadataFinished(int64_t callback_id,
@@ -1310,8 +1275,8 @@ void ServiceWorkerVersion::OnClearCachedMetadataFinished(int64_t callback_id,
TRACE_EVENT_ASYNC_END1("ServiceWorker",
"ServiceWorkerVersion::ClearCachedMetadata",
callback_id, "result", result);
- for (auto& listener : listeners_)
- listener.OnCachedMetadataUpdated(this, 0);
+ for (auto& observer : observers_)
+ observer.OnCachedMetadataUpdated(this, 0);
}
void ServiceWorkerVersion::OpenWindow(
@@ -1369,7 +1334,8 @@ void ServiceWorkerVersion::OnSimpleEventFinished(
status == blink::mojom::ServiceWorkerEventStatus::COMPLETED,
dispatch_event_time);
- std::move(callback).Run(mojo::ConvertTo<ServiceWorkerStatusCode>(status));
+ std::move(callback).Run(
+ mojo::ConvertTo<blink::ServiceWorkerStatusCode>(status));
}
void ServiceWorkerVersion::CountFeature(blink::mojom::WebFeature feature) {
@@ -1394,8 +1360,21 @@ bool ServiceWorkerVersion::IsInstalled(ServiceWorkerVersion::Status status) {
return false;
}
+void ServiceWorkerVersion::IncrementPendingUpdateHintCount() {
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
+ pending_update_hint_count_++;
+}
+
+void ServiceWorkerVersion::DecrementPendingUpdateHintCount() {
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK_GT(pending_update_hint_count_, 0);
+ pending_update_hint_count_--;
+ if (pending_update_hint_count_ == 0)
+ ScheduleUpdate();
+}
+
void ServiceWorkerVersion::OnPongFromWorker() {
- ping_controller_->OnPongReceived();
+ ping_controller_.OnPongReceived();
}
void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
@@ -1403,10 +1382,10 @@ void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
Status prestart_status,
bool is_browser_startup_complete,
StatusCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
scoped_refptr<ServiceWorkerRegistration> protect = registration;
- if (status == SERVICE_WORKER_ERROR_NOT_FOUND) {
+ if (status == blink::ServiceWorkerStatusCode::kErrorNotFound) {
// When the registration has already been deleted from the storage but its
// active worker is still controlling clients, the event should be
// dispatched on the worker. However, the storage cannot find the
@@ -1414,22 +1393,23 @@ void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
protect = context_->GetLiveRegistration(registration_id_);
if (protect) {
DCHECK(protect->is_deleted());
- status = SERVICE_WORKER_OK;
+ status = blink::ServiceWorkerStatusCode::kOk;
}
}
- if (status != SERVICE_WORKER_OK) {
+ if (status != blink::ServiceWorkerStatusCode::kOk) {
RecordStartWorkerResult(purpose, prestart_status, kInvalidTraceId,
is_browser_startup_complete, status);
- RunSoon(base::BindOnce(std::move(callback),
- SERVICE_WORKER_ERROR_START_WORKER_FAILED));
+ RunSoon(base::BindOnce(
+ std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed));
return;
}
if (is_redundant()) {
RecordStartWorkerResult(purpose, prestart_status, kInvalidTraceId,
is_browser_startup_complete,
- SERVICE_WORKER_ERROR_REDUNDANT);
- RunSoon(
- base::BindOnce(std::move(callback), SERVICE_WORKER_ERROR_REDUNDANT));
+ blink::ServiceWorkerStatusCode::kErrorRedundant);
+ RunSoon(base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kErrorRedundant));
return;
}
@@ -1437,7 +1417,8 @@ void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
switch (running_status()) {
case EmbeddedWorkerStatus::RUNNING:
- RunSoon(base::BindOnce(std::move(callback), SERVICE_WORKER_OK));
+ RunSoon(base::BindOnce(std::move(callback),
+ blink::ServiceWorkerStatusCode::kOk));
return;
case EmbeddedWorkerStatus::STARTING:
DCHECK(!start_callbacks_.empty());
@@ -1464,7 +1445,9 @@ void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
start_callbacks_.push_back(base::BindOnce(
[](StatusCallback callback,
scoped_refptr<ServiceWorkerRegistration> protect,
- ServiceWorkerStatusCode status) { std::move(callback).Run(status); },
+ blink::ServiceWorkerStatusCode status) {
+ std::move(callback).Run(status);
+ },
std::move(callback), protect));
if (running_status() == EmbeddedWorkerStatus::STOPPED)
@@ -1473,16 +1456,18 @@ void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
}
void ServiceWorkerVersion::StartWorkerInternal() {
+ DCHECK(context_);
DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, running_status());
DCHECK(inflight_requests_.IsEmpty());
DCHECK(request_timeouts_.empty());
DCHECK(start_worker_first_purpose_);
- if (!ServiceWorkerMetrics::ShouldExcludeSiteFromHistogram(site_for_uma_)) {
+ if (!ServiceWorkerMetrics::ShouldExcludeSiteFromHistogram(site_for_uma_) &&
+ start_worker_first_purpose_.value() ==
+ ServiceWorkerMetrics::EventType::NAVIGATION_HINT) {
DCHECK(!event_recorder_);
event_recorder_ =
- std::make_unique<ServiceWorkerMetrics::ScopedEventRecorder>(
- start_worker_first_purpose_.value());
+ std::make_unique<ServiceWorkerMetrics::ScopedEventRecorder>();
}
// We don't clear |start_worker_first_purpose_| here but clear in
// FinishStartWorker. This is because StartWorkerInternal may be called
@@ -1491,18 +1476,19 @@ void ServiceWorkerVersion::StartWorkerInternal() {
StartTimeoutTimer();
idle_timer_fired_in_renderer_ = false;
- std::unique_ptr<ServiceWorkerProviderHost> provider_host =
- ServiceWorkerProviderHost::PreCreateForController(context());
- provider_host_ = provider_host->AsWeakPtr();
+ auto provider_info = mojom::ServiceWorkerProviderInfoForStartWorker::New();
+ provider_host_ = ServiceWorkerProviderHost::PreCreateForController(
+ context(), base::WrapRefCounted(this), &provider_info);
auto params = mojom::EmbeddedWorkerStartParams::New();
params->service_worker_version_id = version_id_;
params->scope = scope_;
params->script_url = script_url_;
params->is_installed = IsInstalled(status_);
- params->pause_after_download = pause_after_download_;
+ params->pause_after_download = pause_after_download();
- if (IsInstalled(status()) && !pause_after_download_) {
+ if (IsInstalled(status())) {
+ DCHECK(!params->pause_after_download);
DCHECK(!installed_scripts_sender_);
installed_scripts_sender_ =
std::make_unique<ServiceWorkerInstalledScriptsSender>(this);
@@ -1511,23 +1497,23 @@ void ServiceWorkerVersion::StartWorkerInternal() {
installed_scripts_sender_->Start();
}
- params->dispatcher_request = mojo::MakeRequest(&event_dispatcher_);
+ params->service_worker_request = mojo::MakeRequest(&service_worker_ptr_);
// TODO(horo): These CHECKs are for debugging crbug.com/759938.
- CHECK(event_dispatcher_.is_bound());
- CHECK(params->dispatcher_request.is_pending());
- event_dispatcher_.set_connection_error_handler(base::BindOnce(
- &OnEventDispatcherConnectionError, embedded_worker_->AsWeakPtr()));
+ CHECK(service_worker_ptr_.is_bound());
+ CHECK(params->service_worker_request.is_pending());
+ service_worker_ptr_.set_connection_error_handler(
+ base::BindOnce(&OnConnectionError, embedded_worker_->AsWeakPtr()));
blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host;
binding_.Close();
binding_.Bind(mojo::MakeRequest(&service_worker_host));
ServiceWorkerRegistration* registration =
context_->GetLiveRegistration(registration_id_);
DCHECK(registration);
- provider_host->SetDocumentUrl(script_url());
- event_dispatcher_->InitializeGlobalScope(
+ provider_host_->SetDocumentUrl(script_url());
+ service_worker_ptr_->InitializeGlobalScope(
std::move(service_worker_host),
- provider_host->CreateServiceWorkerRegistrationObjectInfo(
- scoped_refptr<ServiceWorkerRegistration>(registration)));
+ provider_host_->CreateServiceWorkerRegistrationObjectInfo(
+ base::WrapRefCounted(registration)));
// S13nServiceWorker:
if (!controller_request_.is_pending()) {
@@ -1536,13 +1522,11 @@ void ServiceWorkerVersion::StartWorkerInternal() {
}
params->controller_request = std::move(controller_request_);
+ params->provider_info = std::move(provider_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(provider_host), context()),
- base::BindOnce(&ServiceWorkerVersion::OnStartSentAndScriptEvaluated,
+ base::BindOnce(&ServiceWorkerVersion::OnStartSent,
weak_factory_.GetWeakPtr()));
}
@@ -1561,8 +1545,8 @@ void ServiceWorkerVersion::StartTimeoutTimer() {
// The worker is starting up and not yet idle.
ClearTick(&idle_time_);
- // Ping will be activated in OnScriptLoaded.
- ping_controller_->Deactivate();
+ // Ping will be activated in OnScriptEvaluationStart.
+ ping_controller_.Deactivate();
timeout_timer_.Start(FROM_HERE, kTimeoutTimerDelay, this,
&ServiceWorkerVersion::OnTimeoutTimer);
@@ -1608,7 +1592,8 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
ServiceWorkerMetrics::RecordWorkerStopped(
ServiceWorkerMetrics::StopStatus::TIMEOUT);
}
- ReportError(SERVICE_WORKER_ERROR_TIMEOUT, "DETACH_STALLED_IN_STOPPING");
+ ReportError(blink::ServiceWorkerStatusCode::kErrorTimeout,
+ "DETACH_STALLED_IN_STOPPING");
// Detach the worker. Remove |this| as a listener first; otherwise
// OnStoppedInternal might try to restart before the new worker
@@ -1643,7 +1628,7 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
running_status() == EmbeddedWorkerStatus::STOPPING)
<< static_cast<int>(running_status());
scoped_refptr<ServiceWorkerVersion> protect(this);
- FinishStartWorker(SERVICE_WORKER_ERROR_TIMEOUT);
+ FinishStartWorker(blink::ServiceWorkerStatusCode::kErrorTimeout);
if (running_status() == EmbeddedWorkerStatus::STARTING)
embedded_worker_->Stop();
return;
@@ -1674,29 +1659,31 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
// The worker has been idle for longer than a certain period.
// S13nServiceWorker: The idle timer is implemented on the renderer, so we can
// skip this check.
- if (!ServiceWorkerUtils::IsServicificationEnabled() &&
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled() &&
GetTickDuration(idle_time_) > kIdleWorkerTimeout) {
StopWorkerIfIdle(false /* requested_from_renderer */);
return;
}
// Check ping status.
- ping_controller_->CheckPingStatus();
+ ping_controller_.CheckPingStatus();
}
void ServiceWorkerVersion::PingWorker() {
// 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)));
+ // base::Unretained here is safe because endpoint() is owned by
+ // |this|.
+ endpoint()->Ping(base::BindOnce(&ServiceWorkerVersion::OnPongFromWorker,
+ base::Unretained(this)));
}
void ServiceWorkerVersion::OnPingTimeout() {
DCHECK(running_status() == EmbeddedWorkerStatus::STARTING ||
running_status() == EmbeddedWorkerStatus::RUNNING);
- // TODO(falken): Change the error code to SERVICE_WORKER_ERROR_TIMEOUT.
+ // TODO(falken): Change the error code to
+ // blink::ServiceWorkerStatusCode::kErrorTimeout.
embedded_worker_->AddMessageToConsole(blink::WebConsoleMessage::kLevelVerbose,
kNotRespondingErrorMesage);
StopWorkerIfIdle(false /* requested_from_renderer */);
@@ -1709,19 +1696,19 @@ void ServiceWorkerVersion::StopWorkerIfIdle(bool requested_from_renderer) {
return;
}
- if (!ServiceWorkerUtils::IsServicificationEnabled()) {
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled()) {
// StopWorkerIfIdle() may be called for two reasons: "idle-timeout" or
// "ping-timeout". For idle-timeout (i.e. ping hasn't timed out), check if
// the worker really is idle.
- if (!ping_controller_->IsTimedOut() && HasWorkInBrowser())
+ if (!ping_controller_.IsTimedOut() && HasWorkInBrowser())
return;
embedded_worker_->StopIfNotAttachedToDevTools();
return;
}
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
// Ping timeout
- if (ping_controller_->IsTimedOut()) {
+ if (ping_controller_.IsTimedOut()) {
DCHECK(!requested_from_renderer);
embedded_worker_->StopIfNotAttachedToDevTools();
return;
@@ -1753,11 +1740,11 @@ void ServiceWorkerVersion::RecordStartWorkerResult(
Status prestart_status,
int trace_id,
bool is_browser_startup_complete,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
if (trace_id != kInvalidTraceId) {
TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::StartWorker",
trace_id, "Status",
- ServiceWorkerStatusToString(status));
+ blink::ServiceWorkerStatusToString(status));
}
base::TimeTicks start_time = start_time_;
ClearTick(&start_time_);
@@ -1772,14 +1759,14 @@ void ServiceWorkerVersion::RecordStartWorkerResult(
ServiceWorkerMetrics::RecordStartWorkerStatus(status, purpose,
IsInstalled(prestart_status));
- if (status == SERVICE_WORKER_OK && !start_time.is_null() &&
+ if (status == blink::ServiceWorkerStatusCode::kOk && !start_time.is_null() &&
!skip_recording_startup_time_) {
ServiceWorkerMetrics::RecordStartWorkerTime(
GetTickDuration(start_time), IsInstalled(prestart_status),
embedded_worker_->start_situation(), purpose);
}
- if (status != SERVICE_WORKER_ERROR_TIMEOUT)
+ if (status != blink::ServiceWorkerStatusCode::kErrorTimeout)
return;
EmbeddedWorkerInstance::StartingPhase phase =
EmbeddedWorkerInstance::NOT_STARTING;
@@ -1811,7 +1798,8 @@ bool ServiceWorkerVersion::MaybeTimeoutRequest(
TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request",
request, "Error", "Timeout");
- std::move(request->error_callback).Run(SERVICE_WORKER_ERROR_TIMEOUT);
+ std::move(request->error_callback)
+ .Run(blink::ServiceWorkerStatusCode::kErrorTimeout);
inflight_requests_.Remove(info.id);
return true;
}
@@ -1832,27 +1820,28 @@ void ServiceWorkerVersion::SetAllRequestExpirations(
request_timeouts_.swap(new_timeouts);
}
-ServiceWorkerStatusCode ServiceWorkerVersion::DeduceStartWorkerFailureReason(
- ServiceWorkerStatusCode default_code) {
- if (ping_controller_->IsTimedOut())
- return SERVICE_WORKER_ERROR_TIMEOUT;
+blink::ServiceWorkerStatusCode
+ServiceWorkerVersion::DeduceStartWorkerFailureReason(
+ blink::ServiceWorkerStatusCode default_code) {
+ if (ping_controller_.IsTimedOut())
+ return blink::ServiceWorkerStatusCode::kErrorTimeout;
- if (start_worker_status_ != SERVICE_WORKER_OK)
+ if (start_worker_status_ != blink::ServiceWorkerStatusCode::kOk)
return start_worker_status_;
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;
+ return blink::ServiceWorkerStatusCode::kErrorSecurity;
switch (main_script_status.error()) {
case net::ERR_INSECURE_RESPONSE:
case net::ERR_UNSAFE_REDIRECT:
- return SERVICE_WORKER_ERROR_SECURITY;
+ return blink::ServiceWorkerStatusCode::kErrorSecurity;
case net::ERR_ABORTED:
- return SERVICE_WORKER_ERROR_ABORT;
+ return blink::ServiceWorkerStatusCode::kErrorAbort;
default:
- return SERVICE_WORKER_ERROR_NETWORK;
+ return blink::ServiceWorkerStatusCode::kErrorNetwork;
}
}
@@ -1875,7 +1864,7 @@ void ServiceWorkerVersion::MarkIfStale() {
}
void ServiceWorkerVersion::FoundRegistrationForUpdate(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration) {
if (!context_)
return;
@@ -1886,7 +1875,8 @@ void ServiceWorkerVersion::FoundRegistrationForUpdate(
is_update_scheduled_ = false;
}
- if (status != SERVICE_WORKER_OK || registration->active_version() != this)
+ if (status != blink::ServiceWorkerStatusCode::kOk ||
+ registration->active_version() != this)
return;
context_->UpdateServiceWorker(registration.get(),
false /* force_bypass_cache */);
@@ -1907,8 +1897,8 @@ void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) {
if (is_redundant() || in_dtor_) {
// This worker will be destroyed soon.
should_restart = false;
- } else if (ping_controller_->IsTimedOut()) {
- // This worker is unresponsive and restart may fail.
+ } else if (ping_controller_.IsTimedOut()) {
+ // This worker exhausted its time to run, don't let it restart.
should_restart = false;
} else if (old_status == EmbeddedWorkerStatus::STARTING) {
// This worker unexpectedly stopped because start failed. Attempting to
@@ -1935,7 +1925,7 @@ void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) {
if (!should_restart) {
// Let all start callbacks fail.
FinishStartWorker(DeduceStartWorkerFailureReason(
- SERVICE_WORKER_ERROR_START_WORKER_FAILED));
+ blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed));
}
// Let all message callbacks fail (this will also fire and clear all
@@ -1947,19 +1937,20 @@ void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) {
TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request",
iter.GetCurrentValue(), "Error", "Worker Stopped");
std::move(iter.GetCurrentValue()->error_callback)
- .Run(SERVICE_WORKER_ERROR_FAILED);
+ .Run(blink::ServiceWorkerStatusCode::kErrorFailed);
iter.Advance();
}
inflight_requests_.Clear();
request_timeouts_.clear();
external_request_uuid_to_request_id_.clear();
- event_dispatcher_.reset();
+ service_worker_ptr_.reset();
controller_ptr_.reset();
DCHECK(!controller_request_.is_pending());
installed_scripts_sender_.reset();
binding_.Close();
+ pending_external_requests_.clear();
- for (auto& observer : listeners_)
+ for (auto& observer : observers_)
observer.OnRunningStateChanged(this);
if (should_restart) {
StartWorkerInternal();
@@ -1968,34 +1959,35 @@ void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) {
}
}
-void ServiceWorkerVersion::FinishStartWorker(ServiceWorkerStatusCode status) {
+void ServiceWorkerVersion::FinishStartWorker(
+ blink::ServiceWorkerStatusCode status) {
start_worker_first_purpose_ = base::nullopt;
RunCallbacks(this, &start_callbacks_, status);
}
void ServiceWorkerVersion::CleanUpExternalRequest(
const std::string& request_uuid,
- ServiceWorkerStatusCode status) {
- if (status == SERVICE_WORKER_OK)
+ blink::ServiceWorkerStatusCode status) {
+ if (status == blink::ServiceWorkerStatusCode::kOk)
return;
external_request_uuid_to_request_id_.erase(request_uuid);
}
void ServiceWorkerVersion::OnNoWorkInBrowser() {
DCHECK(!HasWorkInBrowser());
- if (!ServiceWorkerUtils::IsServicificationEnabled()) {
- for (auto& observer : listeners_)
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ for (auto& observer : observers_)
observer.OnNoWork(this);
return;
}
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
if (!idle_timer_fired_in_renderer_ &&
running_status() != EmbeddedWorkerStatus::STOPPED) {
return;
}
- for (auto& observer : listeners_)
+ for (auto& observer : observers_)
observer.OnNoWork(this);
idle_timer_fired_in_renderer_ = false;
}
@@ -2027,7 +2019,7 @@ bool ServiceWorkerVersion::IsStartWorkerAllowed() const {
void ServiceWorkerVersion::NotifyControlleeAdded(
const std::string& uuid,
const ServiceWorkerClientInfo& info) {
- for (auto& observer : listeners_)
+ for (auto& observer : observers_)
observer.OnControlleeAdded(this, uuid, info);
}
@@ -2037,11 +2029,11 @@ void ServiceWorkerVersion::NotifyControlleeRemoved(const std::string& uuid) {
// instead of an observer callback, if it has dangerous side-effects like
// destroying the caller.
auto protect = base::WrapRefCounted(this);
- for (auto& observer : listeners_)
+ for (auto& observer : observers_)
observer.OnControlleeRemoved(this, uuid);
if (!HasControllee()) {
RestartTick(&no_controllees_time_);
- for (auto& observer : listeners_)
+ for (auto& observer : observers_)
observer.OnNoControllees(this);
}
}
diff --git a/chromium/content/browser/service_worker/service_worker_version.h b/chromium/content/browser/service_worker/service_worker_version.h
index ce8fec41aaa..8549a667e3c 100644
--- a/chromium/content/browser/service_worker/service_worker_version.h
+++ b/chromium/content/browser/service_worker/service_worker_version.h
@@ -33,16 +33,17 @@
#include "content/browser/service_worker/service_worker_client_utils.h"
#include "content/browser/service_worker/service_worker_context_request_handler.h"
#include "content/browser/service_worker/service_worker_metrics.h"
+#include "content/browser/service_worker/service_worker_ping_controller.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.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
#include "ipc/ipc_message.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
@@ -111,7 +112,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
public base::RefCounted<ServiceWorkerVersion>,
public EmbeddedWorkerInstance::Listener {
public:
- using StatusCallback = base::OnceCallback<void(ServiceWorkerStatusCode)>;
+ using StatusCallback =
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode)>;
using SimpleEventCallback =
base::OnceCallback<void(blink::mojom::ServiceWorkerEventStatus,
base::Time)>;
@@ -142,7 +144,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
DOES_NOT_EXIST,
};
- class Listener {
+ class Observer {
public:
virtual void OnRunningStateChanged(ServiceWorkerVersion* version) {}
virtual void OnVersionStateChanged(ServiceWorkerVersion* version) {}
@@ -175,7 +177,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
size_t size) {}
protected:
- virtual ~Listener() {}
+ virtual ~Observer() {}
};
ServiceWorkerVersion(ServiceWorkerRegistration* registration,
@@ -196,7 +198,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
// This status is set to EXISTS or DOES_NOT_EXIST when the install event has
// been executed in a new version or when an installed version is loaded from
- // the storage. When a new version is not installed yet, it is UNKNOW.
+ // the storage. When a new version is not installed yet, it is UNKNOWN.
FetchHandlerExistence fetch_handler_existence() const {
return fetch_handler_existence_;
}
@@ -265,10 +267,11 @@ class CONTENT_EXPORT ServiceWorkerVersion
void StartUpdate();
// Starts the worker if it isn't already running. Calls |callback| with
- // SERVICE_WORKER_OK when the worker started up successfully or if it is
- // already running. Otherwise, calls |callback| with an error code.
- // If the worker is already running, |callback| is executed synchronously
- // (before this method returns). |purpose| is used for UMA.
+ // blink::ServiceWorkerStatusCode::kOk when the worker started
+ // up successfully or if it is already running. Otherwise, calls |callback|
+ // with an error code. If the worker is already running, |callback| is
+ // executed synchronously (before this method returns). |purpose| is used for
+ // UMA.
void RunAfterStartWorker(ServiceWorkerMetrics::EventType purpose,
StatusCallback callback);
@@ -290,10 +293,10 @@ class CONTENT_EXPORT ServiceWorkerVersion
// Same as StartRequest, but allows the caller to specify a custom timeout for
// the event, as well as the behavior for when the request times out.
- // S13nServiceWorker: |timeout| and |timeout_behavior| don't have any
- // effect. They are just ignored. Timeouts can be added to the
- // mojom::ServiceWorkerEventDispatcher interface instead (see
- // DispatchSyncEvent for an example).
+ //
+ // S13nServiceWorker: |timeout| and |timeout_behavior| don't have any effect.
+ // They are just ignored. Timeouts can be added to the mojom::ServiceWorker
+ // interface instead (see DispatchSyncEvent for an example).
int StartRequestWithCustomTimeout(ServiceWorkerMetrics::EventType event_type,
StatusCallback error_callback,
const base::TimeDelta& timeout,
@@ -321,19 +324,19 @@ class CONTENT_EXPORT ServiceWorkerVersion
bool FinishExternalRequest(const std::string& request_uuid);
// Creates a callback that is to be used for marking simple events dispatched
- // through the ServiceWorkerEventDispatcher as finished for the |request_id|.
+ // through mojom::ServiceWorker as finished for the |request_id|.
// Simple event means those events expecting a response with only a status
- // code and the dispatch time. See service_worker_event_dispatcher.mojom.
+ // code and the dispatch time. See service_worker.mojom.
SimpleEventCallback CreateSimpleEventCallback(int request_id);
// This must be called when the worker is running.
- mojom::ServiceWorkerEventDispatcher* event_dispatcher() {
+ mojom::ServiceWorker* endpoint() {
DCHECK(running_status() == EmbeddedWorkerStatus::STARTING ||
running_status() == EmbeddedWorkerStatus::RUNNING);
// Temporarily CHECK for debugging https://crbug.com/817981.
- CHECK(event_dispatcher_.is_bound());
- CHECK(event_dispatcher_.get());
- return event_dispatcher_.get();
+ CHECK(service_worker_ptr_.is_bound());
+ CHECK(service_worker_ptr_.get());
+ return service_worker_ptr_.get();
}
// S13nServiceWorker:
@@ -376,21 +379,21 @@ class CONTENT_EXPORT ServiceWorkerVersion
void OnStreamResponseStarted();
void OnStreamResponseFinished();
- // Adds and removes Listeners.
- void AddListener(Listener* listener);
- void RemoveListener(Listener* listener);
+ // Adds and removes Observers.
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
ServiceWorkerScriptCacheMap* script_cache_map() { return &script_cache_map_; }
EmbeddedWorkerInstance* embedded_worker() { return embedded_worker_.get(); }
- // Reports the error message to |listeners_|.
- void ReportError(ServiceWorkerStatusCode status,
+ // Reports the error message to |observers_|.
+ void ReportError(blink::ServiceWorkerStatusCode status,
const std::string& status_message);
void ReportForceUpdateToDevTools();
// Sets the status code to pass to StartWorker callbacks if start fails.
- void SetStartWorkerStatusCode(ServiceWorkerStatusCode status);
+ void SetStartWorkerStatusCode(blink::ServiceWorkerStatusCode status);
// Sets this version's status to REDUNDANT and deletes its resources.
void Doom();
@@ -412,10 +415,16 @@ class CONTENT_EXPORT ServiceWorkerVersion
// Used for pausing service worker startup in the renderer in order to do the
// byte-for-byte check.
- bool pause_after_download() const { return pause_after_download_; }
- void set_pause_after_download(bool pause_after_download) {
- pause_after_download_ = pause_after_download;
+ bool pause_after_download() const {
+ return !pause_after_download_callback_.is_null();
}
+ void SetToPauseAfterDownload(base::OnceClosure callback);
+ void SetToNotPauseAfterDownload();
+
+ // For use by EmbeddedWorkerInstance. Called when the main script loaded.
+ // This is only called for new (non-installed) workers. It's used for resuming
+ // a paused worker via ResumeAfterDownload().
+ void OnMainScriptLoaded();
// Returns nullptr if the main script is not loaded yet and:
// 1) The worker is a new one.
@@ -482,12 +491,34 @@ class CONTENT_EXPORT ServiceWorkerVersion
static bool IsInstalled(ServiceWorkerVersion::Status status);
+ // For scheduling Soft Update after main resource requests. We schedule
+ // a Soft Update to happen "soon" after each main resource request, attempting
+ // to do the update after the page load finished. The renderer sends a hint
+ // when it's a good time to update. This is a count of outstanding expected
+ // hints, to handle multiple main resource requests occurring near the same
+ // time.
+ //
+ // On each request that dispatches a fetch event to this worker (or would
+ // have, in the case of a no-fetch event worker), this count is incremented.
+ // When the browser-side provider host receives a hint from the renderer that
+ // it is a good time to update the service worker, the count is decremented.
+ // It is also decremented when if the provider host is destroyed before
+ // receiving the hint.
+ //
+ // When the count transitions from 1 to 0, update is scheduled.
+ void IncrementPendingUpdateHintCount();
+ void DecrementPendingUpdateHintCount();
+
private:
friend class base::RefCounted<ServiceWorkerVersion>;
+ friend class EmbeddedWorkerInstanceTest;
+ friend class ServiceWorkerPingController;
+ friend class ServiceWorkerProviderHostTest;
friend class ServiceWorkerReadFromCacheJobTest;
friend class ServiceWorkerVersionBrowserTest;
friend class service_worker_registration_unittest::
ServiceWorkerActivationTest;
+ friend class service_worker_version_unittest::ServiceWorkerVersionTest;
FRIEND_TEST_ALL_PREFIXES(service_worker_controllee_request_handler_unittest::
ServiceWorkerControlleeRequestHandlerTest,
@@ -495,6 +526,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
FRIEND_TEST_ALL_PREFIXES(service_worker_controllee_request_handler_unittest::
ServiceWorkerControlleeRequestHandlerTest,
FallbackWithNoFetchHandler);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProviderHostTest,
+ DontSetControllerInDestructor);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerJobTest, Register);
FRIEND_TEST_ALL_PREFIXES(
service_worker_version_unittest::ServiceWorkerVersionTest,
@@ -554,8 +587,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, EarlyResponse);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, CancelRequest);
- class PingController;
-
// Contains timeout info for InflightRequest.
struct InflightRequestTimeoutInfo {
InflightRequestTimeoutInfo(int id,
@@ -608,14 +639,12 @@ class CONTENT_EXPORT ServiceWorkerVersion
base::TimeDelta GetTickDuration(const base::TimeTicks& time) const;
// EmbeddedWorkerInstance::Listener overrides:
- void OnThreadStarted() override;
+ void OnScriptEvaluationStart() override;
void OnStarting() override;
- void OnStarted() override;
+ void OnStarted(blink::mojom::ServiceWorkerStartStatus status) override;
void OnStopping() override;
void OnStopped(EmbeddedWorkerStatus old_status) override;
void OnDetached(EmbeddedWorkerStatus old_status) override;
- void OnScriptLoaded() override;
- void OnScriptLoadFailed() override;
void OnRegisteredToDevToolsManager() override;
void OnReportException(const base::string16& error_message,
int line_number,
@@ -627,7 +656,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
int line_number,
const GURL& source_url) override;
- void OnStartSentAndScriptEvaluated(ServiceWorkerStatusCode status);
+ void OnStartSent(blink::ServiceWorkerStatusCode status);
// Implements blink::mojom::ServiceWorkerHost.
void SetCachedMetadata(const GURL& url,
@@ -666,12 +695,12 @@ class CONTENT_EXPORT ServiceWorkerVersion
Status prestart_status,
bool is_browser_startup_complete,
StatusCallback callback,
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void StartWorkerInternal();
// Callback function for simple events dispatched through mojo interface
- // mojom::ServiceWorkerEventDispatcher. Use CreateSimpleEventCallback() to
+ // mojom::ServiceWorker. Use CreateSimpleEventCallback() to
// create a callback for a given |request_id|.
void OnSimpleEventFinished(int request_id,
blink::mojom::ServiceWorkerEventStatus status,
@@ -684,7 +713,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
void OnTimeoutTimer();
void SetTimeoutTimerInterval(base::TimeDelta interval);
- // Called by PingController for ping protocol.
+ // Called by ServiceWorkerPingController for ping protocol.
void PingWorker();
void OnPingTimeout();
@@ -694,7 +723,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
Status prestart_status,
int trace_id,
bool is_browser_startup_complete,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
bool MaybeTimeoutRequest(const InflightRequestTimeoutInfo& info);
void SetAllRequestExpirations(const base::TimeTicks& expiration);
@@ -702,26 +731,26 @@ class CONTENT_EXPORT ServiceWorkerVersion
// Returns the reason the embedded worker failed to start, using information
// inaccessible to EmbeddedWorkerInstance. Returns |default_code| if it can't
// deduce a reason.
- ServiceWorkerStatusCode DeduceStartWorkerFailureReason(
- ServiceWorkerStatusCode default_code);
+ blink::ServiceWorkerStatusCode DeduceStartWorkerFailureReason(
+ blink::ServiceWorkerStatusCode default_code);
// Sets |stale_time_| if this worker is stale, causing an update to eventually
// occur once the worker stops or is running too long.
void MarkIfStale();
void FoundRegistrationForUpdate(
- ServiceWorkerStatusCode status,
+ blink::ServiceWorkerStatusCode status,
scoped_refptr<ServiceWorkerRegistration> registration);
void OnStoppedInternal(EmbeddedWorkerStatus old_status);
// Resets |start_worker_first_purpose_| and fires and clears all start
// callbacks.
- void FinishStartWorker(ServiceWorkerStatusCode status);
+ void FinishStartWorker(blink::ServiceWorkerStatusCode status);
// Removes any pending external request that has GUID of |request_uuid|.
void CleanUpExternalRequest(const std::string& request_uuid,
- ServiceWorkerStatusCode status);
+ blink::ServiceWorkerStatusCode status);
// Called if no inflight events exist on the browser process.
// Non-S13nServiceWorker: Triggers OnNoWork().
@@ -769,8 +798,12 @@ class CONTENT_EXPORT ServiceWorkerVersion
using RequestUUIDToRequestIDMap = std::map<std::string, int>;
RequestUUIDToRequestIDMap external_request_uuid_to_request_id_;
+ // List of UUIDs of external requests that were issued before this worker
+ // reached RUNNING.
+ std::set<std::string> pending_external_requests_;
+
// Connected to ServiceWorkerContextClient while the worker is running.
- mojom::ServiceWorkerEventDispatcherPtr event_dispatcher_;
+ mojom::ServiceWorkerPtr service_worker_ptr_;
// S13nServiceWorker: connected to the controller service worker.
// |controller_request_| is non-null only when the |controller_ptr_| is
@@ -807,10 +840,14 @@ class CONTENT_EXPORT ServiceWorkerVersion
std::map<std::string, ServiceWorkerProviderHost*> controllee_map_;
// Will be null while shutting down.
base::WeakPtr<ServiceWorkerContextCore> context_;
- base::ObserverList<Listener> listeners_;
+ base::ObserverList<Observer> observers_;
ServiceWorkerScriptCacheMap script_cache_map_;
base::OneShotTimer update_timer_;
+ // For scheduling Soft Update after main resource requests. See
+ // IncrementPendingUpdateHintCount() documentation.
+ int pending_update_hint_count_ = 0;
+
// Starts running in StartWorker and continues until the worker is stopped.
base::RepeatingTimer timeout_timer_;
// Holds the time the worker last started being considered idle.
@@ -833,10 +870,14 @@ class CONTENT_EXPORT ServiceWorkerVersion
bool skip_waiting_ = false;
bool skip_recording_startup_time_ = false;
bool force_bypass_cache_for_scripts_ = false;
- bool pause_after_download_ = false;
bool is_update_scheduled_ = false;
bool in_dtor_ = false;
+ // For service worker update checks. Non-null if pause after download during
+ // startup was requested. Once paused, the callback is run and reset to
+ // null.
+ base::OnceClosure pause_after_download_callback_;
+
std::unique_ptr<net::HttpResponseInfo> main_script_http_info_;
std::unique_ptr<blink::TrialTokenValidator::FeatureToTokensMap>
@@ -844,7 +885,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
// If not OK, the reason that StartWorker failed. Used for
// running |start_callbacks_|.
- ServiceWorkerStatusCode start_worker_status_ = SERVICE_WORKER_OK;
+ blink::ServiceWorkerStatusCode start_worker_status_ =
+ blink::ServiceWorkerStatusCode::kOk;
// The clock used to vend tick time.
const base::TickClock* tick_clock_;
@@ -852,11 +894,11 @@ class CONTENT_EXPORT ServiceWorkerVersion
// The clock used for actual (wall clock) time
base::Clock* clock_;
- std::unique_ptr<PingController> ping_controller_;
+ ServiceWorkerPingController ping_controller_;
- // Used for recording worker activities (e.g., a ratio of handled events)
- // while this service worker is running (i.e., after it starts up until it
- // stops).
+ // Used for recording worker activities while this service worker is running
+ // (i.e., after it starts up until it stops). Created only when the service
+ // worker is speculatively launched for navigation hints.
std::unique_ptr<ServiceWorkerMetrics::ScopedEventRecorder> event_recorder_;
bool stop_when_devtools_detached_ = false;
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 dd8493e736a..2b3f97091de 100644
--- a/chromium/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_version_unittest.cc
@@ -12,7 +12,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/time/time.h"
#include "content/browser/service_worker/embedded_worker_registry.h"
@@ -20,6 +20,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_dispatcher_host.h"
+#include "content/browser/service_worker/service_worker_ping_controller.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/common/service_worker/service_worker_utils.h"
@@ -86,6 +87,10 @@ class TestServiceImpl : public mojom::TestService {
NOTREACHED();
}
+ void DoCrashImmediately(DoCrashImmediatelyCallback callback) override {
+ NOTREACHED();
+ }
+
void CreateFolder(CreateFolderCallback callback) override { NOTREACHED(); }
void GetRequestorName(GetRequestorNameCallback callback) override {
@@ -103,17 +108,17 @@ class TestServiceImpl : public mojom::TestService {
void StartWorker(ServiceWorkerVersion* version,
ServiceWorkerMetrics::EventType purpose) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
version->StartWorker(purpose, CreateReceiverOnCurrentThread(&status));
EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version->running_status());
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version->running_status());
}
class ServiceWorkerVersionTest : public testing::Test {
protected:
- struct RunningStateListener : public ServiceWorkerVersion::Listener {
+ struct RunningStateListener : public ServiceWorkerVersion::Observer {
RunningStateListener() : last_status(EmbeddedWorkerStatus::STOPPED) {}
~RunningStateListener() override {}
void OnRunningStateChanged(ServiceWorkerVersion* version) override {
@@ -122,7 +127,7 @@ class ServiceWorkerVersionTest : public testing::Test {
EmbeddedWorkerStatus last_status;
};
- struct CachedMetadataUpdateListener : public ServiceWorkerVersion::Listener {
+ struct CachedMetadataUpdateListener : public ServiceWorkerVersion::Observer {
CachedMetadataUpdateListener() = default;
~CachedMetadataUpdateListener() override = default;
void OnCachedMetadataUpdated(ServiceWorkerVersion* version,
@@ -164,13 +169,13 @@ class ServiceWorkerVersionTest : public testing::Test {
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
// Make the registration findable via storage functions.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
helper_->context()->storage()->StoreRegistration(
registration_.get(),
version_.get(),
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- ASSERT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
}
virtual std::unique_ptr<MessageReceiver> GetMessageReceiver() {
@@ -183,15 +188,22 @@ class ServiceWorkerVersionTest : public testing::Test {
helper_.reset();
}
+ bool IsPingActivated(ServiceWorkerVersion* version) const {
+ return version->ping_controller_.IsActivated();
+ }
+
+ void NotifyScriptEvaluationStart(ServiceWorkerVersion* version) {
+ version->OnScriptEvaluationStart();
+ }
+
void SimulateDispatchEvent(ServiceWorkerMetrics::EventType event_type) {
- ServiceWorkerStatusCode status =
- SERVICE_WORKER_ERROR_MAX_VALUE; // dummy value
+ base::Optional<blink::ServiceWorkerStatusCode> status;
// Make sure worker is running.
version_->RunAfterStartWorker(event_type,
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
// Start request, as if an event is being dispatched.
@@ -203,7 +215,7 @@ class ServiceWorkerVersionTest : public testing::Test {
EXPECT_TRUE(version_->FinishRequest(request_id, true /* was_handled */,
base::Time::Now()));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
}
void SetTickClockForTesting(base::SimpleTestTickClock* tick_clock) {
@@ -233,7 +245,7 @@ class MessageReceiverDisallowStart : public MessageReceiver {
const GURL& scope,
const GURL& script_url,
bool pause_after_download,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
@@ -245,8 +257,8 @@ 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(dispatcher_request);
+ service_worker_request_map_[embedded_worker_id] =
+ std::move(service_worker_request);
controller_request_map_[embedded_worker_id] =
std::move(controller_request);
break;
@@ -259,7 +271,7 @@ class MessageReceiverDisallowStart : public MessageReceiver {
case StartMode::SUCCEED:
MessageReceiver::OnStartWorker(
embedded_worker_id, service_worker_version_id, scope, script_url,
- pause_after_download, std::move(dispatcher_request),
+ pause_after_download, std::move(service_worker_request),
std::move(controller_request), std::move(instance_host),
std::move(provider_info), std::move(installed_scripts_info));
break;
@@ -286,9 +298,8 @@ class MessageReceiverDisallowStart : public MessageReceiver {
int /* embedded_worker_id */,
mojom::EmbeddedWorkerInstanceHostAssociatedPtr /* instance_host_ptr */>
instance_host_ptr_map_;
- std::map<int /* embedded_worker_id */,
- mojom::ServiceWorkerEventDispatcherRequest>
- event_dispatcher_request_map_;
+ std::map<int /* embedded_worker_id */, mojom::ServiceWorkerRequest>
+ service_worker_request_map_;
std::map<int /* embedded_worker_id */, mojom::ControllerServiceWorkerRequest>
controller_request_map_;
DISALLOW_COPY_AND_ASSIGN(MessageReceiverDisallowStart);
@@ -360,9 +371,9 @@ class ServiceWorkerStallInStoppingTest : public ServiceWorkerVersionTest {
TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) {
// Call StartWorker() multiple times.
- ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_FAILED;
- ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_FAILED;
- ServiceWorkerStatusCode status3 = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status1;
+ base::Optional<blink::ServiceWorkerStatusCode> status2;
+ base::Optional<blink::ServiceWorkerStatusCode> status3;
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status1));
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
@@ -378,9 +389,9 @@ TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) {
base::RunLoop().RunUntilIdle();
// All should just succeed.
- EXPECT_EQ(SERVICE_WORKER_OK, status1);
- EXPECT_EQ(SERVICE_WORKER_OK, status2);
- EXPECT_EQ(SERVICE_WORKER_OK, status3);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status1.value());
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status2.value());
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status3.value());
{
// Call StopWorker() multiple times.
@@ -399,8 +410,8 @@ TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) {
}
// Start worker again.
- status1 = SERVICE_WORKER_ERROR_FAILED;
- status2 = SERVICE_WORKER_ERROR_FAILED;
+ status1.reset();
+ status2.reset();
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status1));
@@ -423,8 +434,8 @@ TEST_F(ServiceWorkerVersionTest, ConcurrentStartAndStop) {
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
// All should just succeed.
- EXPECT_EQ(SERVICE_WORKER_OK, status1);
- EXPECT_EQ(SERVICE_WORKER_OK, status2);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status1.value());
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status2.value());
EXPECT_TRUE(has_stopped);
}
}
@@ -455,12 +466,12 @@ TEST_F(ServiceWorkerVersionTest, StartUnregisteredButStillLiveWorker) {
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
// Delete the registration.
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
helper_->context()->storage()->DeleteRegistration(
registration_->id(), registration_->pattern().GetOrigin(),
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- ASSERT_EQ(SERVICE_WORKER_OK, status);
+ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
// The live registration is marked as deleted, but still exists.
ASSERT_TRUE(registration_->is_deleted());
@@ -472,7 +483,6 @@ TEST_F(ServiceWorkerVersionTest, StartUnregisteredButStillLiveWorker) {
EXPECT_TRUE(has_stopped);
// Dispatch an event on the unregistered and stopped but still live worker.
- status = SERVICE_WORKER_ERROR_FAILED;
SimulateDispatchEvent(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
// The worker should be now started again.
@@ -609,19 +619,17 @@ 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;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
int request_id =
version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC,
CreateReceiverOnCurrentThread(&status));
EXPECT_TRUE(version_->FinishRequest(request_id, true /* was_handled */,
base::Time::Now()));
-
- EXPECT_EQ(SERVICE_WORKER_OK, status);
EXPECT_LT(idle_time, version_->idle_time_);
}
TEST_F(ServiceWorkerVersionTest, SetDevToolsAttached) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status));
@@ -646,13 +654,13 @@ TEST_F(ServiceWorkerVersionTest, SetDevToolsAttached) {
EXPECT_TRUE(version_->skip_recording_startup_time_);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
}
TEST_F(ServiceWorkerVersionTest, StoppingBeforeDestruct) {
RunningStateListener listener;
- version_->AddListener(&listener);
+ version_->AddObserver(&listener);
StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, listener.last_status);
@@ -767,7 +775,7 @@ TEST_F(ServiceWorkerVersionTest, StaleUpdate_DoNotDeferTimer) {
TEST_F(ServiceWorkerVersionTest, UpdateCachedMetadata) {
CachedMetadataUpdateListener listener;
- version_->AddListener(&listener);
+ version_->AddObserver(&listener);
ASSERT_EQ(0, listener.updated_count);
StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
@@ -786,7 +794,7 @@ TEST_F(ServiceWorkerVersionTest, UpdateCachedMetadata) {
version_->script_url());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(2, listener.updated_count);
- version_->RemoveListener(&listener);
+ version_->RemoveObserver(&listener);
}
TEST_F(ServiceWorkerVersionTest, RestartWorker) {
@@ -794,7 +802,7 @@ TEST_F(ServiceWorkerVersionTest, RestartWorker) {
ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
- ServiceWorkerStatusCode event_status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> event_status;
version_->StartRequest(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
CreateReceiverOnCurrentThread(&event_status));
@@ -802,17 +810,17 @@ TEST_F(ServiceWorkerVersionTest, RestartWorker) {
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;
+ base::Optional<blink::ServiceWorkerStatusCode> start_status;
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);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed, event_status.value());
// 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(blink::ServiceWorkerStatusCode::kOk, start_status.value());
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
// SetAllRequestExpirations() after restarting should not crash since all
@@ -827,8 +835,8 @@ class MessageReceiverControlEvents : public MessageReceiver {
void OnExtendableMessageEvent(
mojom::ExtendableMessageEventPtr event,
- mojom::ServiceWorkerEventDispatcher::
- DispatchExtendableMessageEventCallback callback) override {
+ mojom::ServiceWorker::DispatchExtendableMessageEventCallback callback)
+ override {
EXPECT_FALSE(extendable_message_event_callback_);
extendable_message_event_callback_ = std::move(callback);
}
@@ -844,7 +852,7 @@ class MessageReceiverControlEvents : public MessageReceiver {
return !extendable_message_event_callback_.is_null();
}
- mojom::ServiceWorkerEventDispatcher::DispatchExtendableMessageEventCallback
+ mojom::ServiceWorker::DispatchExtendableMessageEventCallback
TakeExtendableMessageEventCallback() {
return std::move(extendable_message_event_callback_);
}
@@ -854,7 +862,7 @@ class MessageReceiverControlEvents : public MessageReceiver {
}
private:
- mojom::ServiceWorkerEventDispatcher::DispatchExtendableMessageEventCallback
+ mojom::ServiceWorker::DispatchExtendableMessageEventCallback
extendable_message_event_callback_;
base::OnceClosure stop_worker_callback_;
};
@@ -872,7 +880,7 @@ class ServiceWorkerRequestTimeoutTest : public ServiceWorkerVersionTest {
->has_extendable_message_event_callback();
}
- mojom::ServiceWorkerEventDispatcher::DispatchExtendableMessageEventCallback
+ mojom::ServiceWorker::DispatchExtendableMessageEventCallback
TakeExtendableMessageEventCallback() {
return static_cast<MessageReceiverControlEvents*>(helper_.get())
->TakeExtendableMessageEventCallback();
@@ -888,8 +896,7 @@ class ServiceWorkerRequestTimeoutTest : public ServiceWorkerVersionTest {
};
TEST_F(ServiceWorkerRequestTimeoutTest, RequestTimeout) {
- ServiceWorkerStatusCode error_status =
- SERVICE_WORKER_ERROR_NETWORK; // dummy value
+ base::Optional<blink::ServiceWorkerStatusCode> error_status;
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
StartWorker(version_.get(),
ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
@@ -901,7 +908,7 @@ TEST_F(ServiceWorkerRequestTimeoutTest, RequestTimeout) {
// Dispatch a dummy event whose response will be received by SWVersion.
EXPECT_FALSE(has_extendable_message_event_callback());
- version_->event_dispatcher()->DispatchExtendableMessageEvent(
+ version_->endpoint()->DispatchExtendableMessageEvent(
mojom::ExtendableMessageEvent::New(),
version_->CreateSimpleEventCallback(request_id));
@@ -910,7 +917,7 @@ TEST_F(ServiceWorkerRequestTimeoutTest, RequestTimeout) {
EXPECT_TRUE(has_extendable_message_event_callback());
// Callback has not completed yet.
- EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, error_status);
+ EXPECT_FALSE(error_status);
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
// Simulate timeout.
@@ -925,7 +932,8 @@ TEST_F(ServiceWorkerRequestTimeoutTest, RequestTimeout) {
// The renderer should have received a StopWorker request.
EXPECT_TRUE(callback);
// The request should have timed out.
- EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, error_status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout,
+ error_status.value());
// Calling FinishRequest should be no-op, since the request timed out.
EXPECT_FALSE(version_->FinishRequest(request_id, true /* was_handled */,
base::Time::Now()));
@@ -943,7 +951,7 @@ TEST_F(ServiceWorkerRequestTimeoutTest, RequestTimeout) {
}
TEST_F(ServiceWorkerVersionTest, RequestNowTimeout) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+ base::Optional<blink::ServiceWorkerStatusCode> status;
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
StartWorker(version_.get(), ServiceWorkerMetrics::EventType::SYNC);
@@ -957,7 +965,7 @@ TEST_F(ServiceWorkerVersionTest, RequestNowTimeout) {
EXPECT_TRUE(version_->timeout_timer_.IsRunning());
version_->timeout_timer_.user_task().Run();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout, status.value());
EXPECT_FALSE(version_->FinishRequest(request_id, true /* was_handled */,
base::Time::Now()));
@@ -967,7 +975,7 @@ TEST_F(ServiceWorkerVersionTest, RequestNowTimeout) {
}
TEST_F(ServiceWorkerVersionTest, RequestNowTimeoutKill) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+ base::Optional<blink::ServiceWorkerStatusCode> status;
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
StartWorker(version_.get(), ServiceWorkerMetrics::EventType::SYNC);
@@ -981,7 +989,7 @@ TEST_F(ServiceWorkerVersionTest, RequestNowTimeoutKill) {
EXPECT_TRUE(version_->timeout_timer_.IsRunning());
version_->timeout_timer_.user_task().Run();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout, status.value());
EXPECT_FALSE(version_->FinishRequest(request_id, true /* was_handled */,
base::Time::Now()));
@@ -991,10 +999,8 @@ TEST_F(ServiceWorkerVersionTest, RequestNowTimeoutKill) {
}
TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeout) {
- ServiceWorkerStatusCode first_status =
- SERVICE_WORKER_ERROR_MAX_VALUE; // dummy value
- ServiceWorkerStatusCode second_status =
- SERVICE_WORKER_ERROR_MAX_VALUE; // dummy value
+ base::Optional<blink::ServiceWorkerStatusCode> first_status;
+ base::Optional<blink::ServiceWorkerStatusCode> second_status;
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
StartWorker(version_.get(), ServiceWorkerMetrics::EventType::SYNC);
@@ -1020,15 +1026,16 @@ TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeout) {
EXPECT_TRUE(version_->timeout_timer_.IsRunning());
version_->timeout_timer_.user_task().Run();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, first_status);
- EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, second_status);
+ EXPECT_FALSE(first_status);
+ EXPECT_FALSE(second_status);
// Now advance time until the second task timeout should expire.
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);
- EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, second_status);
+ EXPECT_FALSE(first_status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout,
+ second_status.value());
// CONTINUE_ON_TIMEOUT timeouts don't stop the service worker.
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
@@ -1037,8 +1044,10 @@ TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeout) {
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);
- EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, second_status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout,
+ first_status.value());
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout,
+ second_status.value());
EXPECT_FALSE(version_->FinishRequest(first_request_id, true /* was_handled */,
base::Time::Now()));
@@ -1051,10 +1060,8 @@ TEST_F(ServiceWorkerVersionTest, RequestCustomizedTimeout) {
}
TEST_F(ServiceWorkerVersionTest, MixedRequestTimeouts) {
- ServiceWorkerStatusCode sync_status =
- SERVICE_WORKER_ERROR_NETWORK; // dummy value
- ServiceWorkerStatusCode fetch_status =
- SERVICE_WORKER_ERROR_NETWORK; // dummy value
+ base::Optional<blink::ServiceWorkerStatusCode> sync_status;
+ base::Optional<blink::ServiceWorkerStatusCode> fetch_status;
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
StartWorker(version_.get(),
ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
@@ -1069,14 +1076,14 @@ TEST_F(ServiceWorkerVersionTest, MixedRequestTimeouts) {
CreateReceiverOnCurrentThread(&sync_status), base::TimeDelta(),
ServiceWorkerVersion::CONTINUE_ON_TIMEOUT);
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, sync_status);
+ EXPECT_FALSE(sync_status);
// Verify the sync has timed out but not the fetch.
EXPECT_TRUE(version_->timeout_timer_.IsRunning());
version_->timeout_timer_.user_task().Run();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, sync_status);
- EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, fetch_status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout, sync_status.value());
+ EXPECT_FALSE(fetch_status);
// Background sync timeouts don't stop the service worker.
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
@@ -1089,7 +1096,8 @@ TEST_F(ServiceWorkerVersionTest, MixedRequestTimeouts) {
version_->SetAllRequestExpirations(base::TimeTicks::Now());
version_->timeout_timer_.user_task().Run();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, fetch_status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout,
+ fetch_status.value());
// Fetch request should no longer exist.
EXPECT_FALSE(version_->FinishRequest(fetch_request_id, true /* was_handled */,
@@ -1100,13 +1108,13 @@ TEST_F(ServiceWorkerVersionTest, MixedRequestTimeouts) {
}
TEST_F(ServiceWorkerFailToStartTest, RendererCrash) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+ base::Optional<blink::ServiceWorkerStatusCode> status;
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
// Callback has not completed yet.
- EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, status);
+ EXPECT_FALSE(status);
EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version_->running_status());
// Simulate renderer crash: break EmbeddedWorkerInstance's Mojo connection to
@@ -1115,12 +1123,13 @@ TEST_F(ServiceWorkerFailToStartTest, RendererCrash) {
base::RunLoop().RunUntilIdle();
// Callback completed.
- EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed,
+ status.value());
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
}
TEST_F(ServiceWorkerFailToStartTest, Timeout) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value
+ base::Optional<blink::ServiceWorkerStatusCode> status;
// Start starting the worker.
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
@@ -1128,7 +1137,7 @@ TEST_F(ServiceWorkerFailToStartTest, Timeout) {
base::RunLoop().RunUntilIdle();
// Callback has not completed yet.
- EXPECT_EQ(SERVICE_WORKER_ERROR_NETWORK, status);
+ EXPECT_FALSE(status);
EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version_->running_status());
// Simulate timeout.
@@ -1138,7 +1147,7 @@ TEST_F(ServiceWorkerFailToStartTest, Timeout) {
base::TimeDelta::FromMinutes(1);
version_->timeout_timer_.user_task().Run();
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_ERROR_TIMEOUT, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorTimeout, status.value());
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
}
@@ -1189,7 +1198,7 @@ TEST_F(ServiceWorkerStallInStoppingTest, DetachThenRestart) {
EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status());
// Worker is now stalled in stopping. Add a start worker request.
- ServiceWorkerStatusCode start_status = SERVICE_WORKER_ERROR_FAILED;
+ base::Optional<blink::ServiceWorkerStatusCode> start_status;
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&start_status));
@@ -1201,21 +1210,21 @@ TEST_F(ServiceWorkerStallInStoppingTest, DetachThenRestart) {
version_->timeout_timer_.user_task().Run();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(has_stopped);
- EXPECT_EQ(SERVICE_WORKER_OK, start_status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, start_status.value());
}
TEST_F(ServiceWorkerVersionTest, RendererCrashDuringEvent) {
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
StartWorker(version_.get(), ServiceWorkerMetrics::EventType::SYNC);
- ServiceWorkerStatusCode status = SERVICE_WORKER_OK;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
int request_id =
version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC,
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
// Callback has not completed yet.
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_FALSE(status);
// Simulate renderer crash: break EmbeddedWorkerInstance's Mojo connection to
// the renderer-side client.
@@ -1223,7 +1232,7 @@ TEST_F(ServiceWorkerVersionTest, RendererCrashDuringEvent) {
base::RunLoop().RunUntilIdle();
// Callback completed.
- EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorFailed, status.value());
EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
// Request already failed, calling finsh should return false.
@@ -1231,6 +1240,22 @@ TEST_F(ServiceWorkerVersionTest, RendererCrashDuringEvent) {
base::Time::Now()));
}
+TEST_F(ServiceWorkerVersionTest, PingController) {
+ // Start starting an worker. Ping should not be active.
+ version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
+ base::DoNothing());
+ EXPECT_FALSE(IsPingActivated(version_.get()));
+
+ // Start script evaluation. Ping should be active.
+ NotifyScriptEvaluationStart(version_.get());
+ EXPECT_TRUE(IsPingActivated(version_.get()));
+
+ // Finish starting the worker. Ping should still be active.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
+ EXPECT_TRUE(IsPingActivated(version_.get()));
+}
+
// Test starting a service worker from a disallowed origin.
TEST_F(ServiceWorkerVersionTest, BadOrigin) {
const GURL scope("bad-origin://www.example.com/test/");
@@ -1244,15 +1269,15 @@ TEST_F(ServiceWorkerVersionTest, BadOrigin) {
GURL("bad-origin://www.example.com/test/service_worker.js"),
helper_->context()->storage()->NewVersionId(),
helper_->context()->AsWeakPtr());
- ServiceWorkerStatusCode status = SERVICE_WORKER_OK;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
version->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_ERROR_DISALLOWED, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorDisallowed, status.value());
}
TEST_F(ServiceWorkerFailToStartTest, FailingWorkerUsesNewRendererProcess) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
ServiceWorkerContextCore* context = helper_->context();
int64_t id = version_->version_id();
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
@@ -1262,33 +1287,38 @@ TEST_F(ServiceWorkerFailToStartTest, FailingWorkerUsesNewRendererProcess) {
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
EXPECT_EQ(helper_->mock_render_process_id(),
version_->embedded_worker()->process_id());
version_->StopWorker(base::DoNothing());
base::RunLoop().RunUntilIdle();
// Fail once.
+ status.reset();
set_start_mode(MessageReceiverDisallowStart::StartMode::FAIL);
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed,
+ status.value());
EXPECT_EQ(1, context->GetVersionFailureCount(id));
// Fail again.
+ status.reset();
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_ERROR_START_WORKER_FAILED, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed,
+ status.value());
EXPECT_EQ(2, context->GetVersionFailureCount(id));
// Succeed. It should choose the "new process".
+ status.reset();
set_start_mode(MessageReceiverDisallowStart::StartMode::SUCCEED);
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
EXPECT_EQ(helper_->new_render_process_id(),
version_->embedded_worker()->process_id());
EXPECT_EQ(0, context->GetVersionFailureCount(id));
@@ -1297,10 +1327,11 @@ TEST_F(ServiceWorkerFailToStartTest, FailingWorkerUsesNewRendererProcess) {
// Start again. It should choose the "existing process" again as we no longer
// force creation of a new process.
+ status.reset();
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
EXPECT_EQ(helper_->mock_render_process_id(),
version_->embedded_worker()->process_id());
version_->StopWorker(base::DoNothing());
@@ -1308,13 +1339,13 @@ TEST_F(ServiceWorkerFailToStartTest, FailingWorkerUsesNewRendererProcess) {
}
TEST_F(ServiceWorkerFailToStartTest, RestartStalledWorker) {
- ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
version_->StartWorker(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
- CreateReceiverOnCurrentThread(&status1));
+ CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
// The default start mode is StartMode::STALL. So the callback of StartWorker
// is not called yet.
- EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status1);
+ EXPECT_FALSE(status);
// Set StartMode::SUCCEED. So the next start worker will be successful.
set_start_mode(MessageReceiverDisallowStart::StartMode::SUCCEED);
@@ -1325,7 +1356,7 @@ TEST_F(ServiceWorkerFailToStartTest, RestartStalledWorker) {
version_->StopWorker(base::BindOnce(&VerifyCalled, &has_stopped));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status1);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
EXPECT_TRUE(has_stopped);
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
}
@@ -1335,10 +1366,10 @@ class ServiceWorkerNavigationHintUMATest : public ServiceWorkerVersionTest {
ServiceWorkerNavigationHintUMATest() : ServiceWorkerVersionTest() {}
void StartWorker(ServiceWorkerMetrics::EventType purpose) {
- ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> status;
version_->StartWorker(purpose, CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value());
}
void StopWorker() {
@@ -1387,28 +1418,28 @@ TEST_F(ServiceWorkerNavigationHintUMATest, Precision) {
TEST_F(ServiceWorkerNavigationHintUMATest, ConcurrentStart) {
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
- ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_MAX_VALUE;
- ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_MAX_VALUE;
+ base::Optional<blink::ServiceWorkerStatusCode> status1;
+ base::Optional<blink::ServiceWorkerStatusCode> status2;
version_->StartWorker(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
CreateReceiverOnCurrentThread(&status1));
version_->StartWorker(ServiceWorkerMetrics::EventType::NAVIGATION_HINT,
CreateReceiverOnCurrentThread(&status2));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status1);
- EXPECT_EQ(SERVICE_WORKER_OK, status2);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status1.value());
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status2.value());
StopWorker();
// The first purpose of starting worker was not a navigation hint.
histogram_tester_.ExpectTotalCount(kStartHintPrecision, 0);
- status1 = SERVICE_WORKER_ERROR_MAX_VALUE;
- status2 = SERVICE_WORKER_ERROR_MAX_VALUE;
+ status1.reset();
+ status2.reset();
version_->StartWorker(ServiceWorkerMetrics::EventType::NAVIGATION_HINT,
CreateReceiverOnCurrentThread(&status2));
version_->StartWorker(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
CreateReceiverOnCurrentThread(&status1));
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SERVICE_WORKER_OK, status1);
- EXPECT_EQ(SERVICE_WORKER_OK, status2);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status1.value());
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status2.value());
SimulateDispatchEvent(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
StopWorker();
// The first purpose of starting worker was a navigation hint.
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 7b25cc96dcd..25c0d8f11e2 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
@@ -476,7 +476,8 @@ net::Error ServiceWorkerWriteToCacheJob::NotifyFinishedCaching(
// equivalent, the new version didn't actually install because it already
// exists.
if (net_error == net::OK && !cache_writer_->did_replace()) {
- version_->SetStartWorkerStatusCode(SERVICE_WORKER_ERROR_EXISTS);
+ version_->SetStartWorkerStatusCode(
+ blink::ServiceWorkerStatusCode::kErrorExists);
version_->script_cache_map()->NotifyFinishedCaching(
url_, size, kIdenticalScriptError, std::string());
} else {
diff --git a/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h b/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h
index 1a3a3f2ad9a..46572db78e5 100644
--- a/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h
+++ b/chromium/content/browser/service_worker/service_worker_write_to_cache_job.h
@@ -15,12 +15,12 @@
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/resource_type.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
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 0b248f1fd2e..516c5b96b1a 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
@@ -210,8 +210,10 @@ class ResponseVerifier : public base::RefCounted<ResponseVerifier> {
public:
ResponseVerifier(std::unique_ptr<ServiceWorkerResponseReader> reader,
const std::string& expected,
- const base::Callback<void(bool)> callback)
- : reader_(reader.release()), expected_(expected), callback_(callback) {}
+ base::OnceCallback<void(bool)> callback)
+ : reader_(reader.release()),
+ expected_(expected),
+ callback_(std::move(callback)) {}
void Start() {
info_buffer_ = new HttpResponseInfoIOBuffer();
@@ -224,12 +226,12 @@ class ResponseVerifier : public base::RefCounted<ResponseVerifier> {
void OnReadInfoComplete(int result) {
if (result < 0) {
- callback_.Run(false);
+ std::move(callback_).Run(false);
return;
}
if (info_buffer_->response_data_size !=
static_cast<int>(expected_.size())) {
- callback_.Run(false);
+ std::move(callback_).Run(false);
return;
}
ReadSomeData();
@@ -243,17 +245,17 @@ class ResponseVerifier : public base::RefCounted<ResponseVerifier> {
void OnReadDataComplete(int result) {
if (result < 0) {
- callback_.Run(false);
+ std::move(callback_).Run(false);
return;
}
if (result == 0) {
- callback_.Run(true);
+ std::move(callback_).Run(true);
return;
}
std::string str(io_buffer_->data(), result);
std::string expect = expected_.substr(bytes_read_, result);
if (str != expect) {
- callback_.Run(false);
+ std::move(callback_).Run(false);
return;
}
bytes_read_ += result;
@@ -266,7 +268,7 @@ class ResponseVerifier : public base::RefCounted<ResponseVerifier> {
std::unique_ptr<ServiceWorkerResponseReader> reader_;
const std::string expected_;
- base::Callback<void(bool)> callback_;
+ base::OnceCallback<void(bool)> callback_;
scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_;
scoped_refptr<net::IOBuffer> io_buffer_;
size_t bytes_read_;
@@ -288,13 +290,9 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
base::WeakPtr<ServiceWorkerProviderHost> CreateHostForVersion(
int process_id,
const scoped_refptr<ServiceWorkerVersion>& version) {
- std::unique_ptr<ServiceWorkerProviderHost> host =
- CreateProviderHostForServiceWorkerContext(
- process_id, true /* is_parent_frame_secure */, version.get(),
- context()->AsWeakPtr(), &remote_endpoint_);
- base::WeakPtr<ServiceWorkerProviderHost> host_weakptr = host->AsWeakPtr();
- context()->AddProviderHost(std::move(host));
- return host_weakptr;
+ return CreateProviderHostForServiceWorkerContext(
+ process_id, true /* is_parent_frame_secure */, version.get(),
+ context()->AsWeakPtr(), &remote_endpoint_);
}
void SetUpScriptRequest(int process_id, int provider_id) {
@@ -393,7 +391,7 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
scoped_refptr<ServiceWorkerVersion> new_version =
new ServiceWorkerVersion(registration_.get(), script_url_,
NextVersionId(), context()->AsWeakPtr());
- new_version->set_pause_after_download(true);
+ new_version->SetToPauseAfterDownload(base::DoNothing());
base::WeakPtr<ServiceWorkerProviderHost> host =
CreateHostForVersion(helper_->mock_render_process_id(), new_version);
EXPECT_TRUE(host);
@@ -407,14 +405,14 @@ class ServiceWorkerWriteToCacheJobTest : public testing::Test {
void VerifyResource(int64_t id, const std::string& expected) {
ASSERT_NE(kInvalidServiceWorkerResourceId, id);
- bool is_equal = false;
+ base::Optional<bool> is_equal;
std::unique_ptr<ServiceWorkerResponseReader> reader =
context()->storage()->CreateResponseReader(id);
scoped_refptr<ResponseVerifier> verifier = new ResponseVerifier(
std::move(reader), expected, CreateReceiverOnCurrentThread(&is_equal));
verifier->Start();
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(is_equal);
+ EXPECT_TRUE(is_equal.value());
}
ServiceWorkerContextCore* context() const { return helper_->context(); }
diff --git a/chromium/content/browser/shared_worker/OWNERS b/chromium/content/browser/shared_worker/OWNERS
index 595a38572a7..6bda8b5e83f 100644
--- a/chromium/content/browser/shared_worker/OWNERS
+++ b/chromium/content/browser/shared_worker/OWNERS
@@ -1,3 +1,4 @@
+falken@chromium.org
horo@chromium.org
nhiroki@chromium.org
diff --git a/chromium/content/browser/shared_worker/mock_shared_worker.cc b/chromium/content/browser/shared_worker/mock_shared_worker.cc
index 32ce0577fdc..829d18dce64 100644
--- a/chromium/content/browser/shared_worker/mock_shared_worker.cc
+++ b/chromium/content/browser/shared_worker/mock_shared_worker.cc
@@ -4,6 +4,7 @@
#include "content/browser/shared_worker/mock_shared_worker.h"
+#include "content/common/url_loader_factory_bundle.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
@@ -97,11 +98,13 @@ void MockSharedWorkerFactory::CreateSharedWorker(
mojom::SharedWorkerInfoPtr info,
bool pause_on_start,
const base::UnguessableToken& devtools_worker_token,
+ const RendererPreferences& renderer_preferences,
blink::mojom::WorkerContentSettingsProxyPtr content_settings,
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_ptr_info,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider) {
diff --git a/chromium/content/browser/shared_worker/mock_shared_worker.h b/chromium/content/browser/shared_worker/mock_shared_worker.h
index 791fdb17060..7d99113c488 100644
--- a/chromium/content/browser/shared_worker/mock_shared_worker.h
+++ b/chromium/content/browser/shared_worker/mock_shared_worker.h
@@ -22,6 +22,7 @@
class GURL;
namespace content {
+class URLLoaderFactoryBundleInfo;
class MockSharedWorker : public mojom::SharedWorker {
public:
@@ -66,11 +67,13 @@ class MockSharedWorkerFactory : public mojom::SharedWorkerFactory {
mojom::SharedWorkerInfoPtr info,
bool pause_on_start,
const base::UnguessableToken& devtools_worker_token,
+ const RendererPreferences& renderer_preferences,
blink::mojom::WorkerContentSettingsProxyPtr content_settings,
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_ptr_info,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider) override;
diff --git a/chromium/content/browser/shared_worker/shared_worker_connector_impl.cc b/chromium/content/browser/shared_worker/shared_worker_connector_impl.cc
index 4b08ffd8b66..2fe70f50171 100644
--- a/chromium/content/browser/shared_worker/shared_worker_connector_impl.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_connector_impl.cc
@@ -33,19 +33,31 @@ void SharedWorkerConnectorImpl::Connect(
mojom::SharedWorkerInfoPtr info,
mojom::SharedWorkerClientPtr client,
blink::mojom::SharedWorkerCreationContextType creation_context_type,
- mojo::ScopedMessagePipeHandle message_port) {
+ mojo::ScopedMessagePipeHandle message_port,
+ blink::mojom::BlobURLTokenPtr blob_url_token) {
RenderProcessHost* host = RenderProcessHost::FromID(process_id_);
// The render process was already terminated.
if (!host) {
client->OnScriptLoadFailed();
return;
}
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory;
+ if (blob_url_token) {
+ if (!info->url.SchemeIsBlob()) {
+ mojo::ReportBadMessage("SWCI_BLOB_URL_TOKEN_FOR_NON_BLOB_URL");
+ return;
+ }
+ blob_url_loader_factory =
+ ChromeBlobStorageContext::URLLoaderFactoryForToken(
+ host->GetBrowserContext(), std::move(blob_url_token));
+ }
SharedWorkerServiceImpl* service =
static_cast<StoragePartitionImpl*>(host->GetStoragePartition())
->GetSharedWorkerService();
service->ConnectToWorker(process_id_, frame_id_, std::move(info),
std::move(client), creation_context_type,
- blink::MessagePortChannel(std::move(message_port)));
+ blink::MessagePortChannel(std::move(message_port)),
+ std::move(blob_url_loader_factory));
}
} // namespace content
diff --git a/chromium/content/browser/shared_worker/shared_worker_connector_impl.h b/chromium/content/browser/shared_worker/shared_worker_connector_impl.h
index 2c609c680d6..bd85820db69 100644
--- a/chromium/content/browser/shared_worker/shared_worker_connector_impl.h
+++ b/chromium/content/browser/shared_worker/shared_worker_connector_impl.h
@@ -27,7 +27,8 @@ class CONTENT_EXPORT SharedWorkerConnectorImpl
mojom::SharedWorkerInfoPtr info,
mojom::SharedWorkerClientPtr client,
blink::mojom::SharedWorkerCreationContextType creation_context_type,
- mojo::ScopedMessagePipeHandle message_port) override;
+ mojo::ScopedMessagePipeHandle message_port,
+ blink::mojom::BlobURLTokenPtr blob_url_token) override;
const int process_id_;
const int frame_id_;
diff --git a/chromium/content/browser/shared_worker/shared_worker_host.cc b/chromium/content/browser/shared_worker/shared_worker_host.cc
index 107d46564b9..407310cc763 100644
--- a/chromium/content/browser/shared_worker/shared_worker_host.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_host.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "base/unguessable_token.h"
#include "content/browser/devtools/shared_worker_devtools_manager.h"
@@ -14,11 +15,14 @@
#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"
+#include "content/browser/storage_partition_impl.h"
+#include "content/common/url_loader_factory_bundle.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_process_host.h"
#include "content/public/common/content_client.h"
+#include "services/network/public/cpp/features.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
#include "third_party/blink/public/platform/web_feature.mojom.h"
#include "third_party/blink/public/web/worker_content_settings_proxy.mojom.h"
@@ -121,7 +125,8 @@ void SharedWorkerHost::Start(
mojom::SharedWorkerFactoryPtr factory,
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
- network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory) {
+ network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
AdvanceTo(Phase::kStarted);
@@ -136,6 +141,11 @@ void SharedWorkerHost::Start(
devtools_handle_ = std::make_unique<ScopedDevToolsHandle>(
this, &pause_on_start, &devtools_worker_token);
+ RendererPreferences renderer_preferences;
+ GetContentClient()->browser()->UpdateRendererPreferencesForWorker(
+ RenderProcessHost::FromID(process_id_)->GetBrowserContext(),
+ &renderer_preferences);
+
// Set up content settings interface.
blink::mojom::WorkerContentSettingsProxyPtr content_settings;
content_settings_ = std::make_unique<SharedWorkerContentSettingsProxyImpl>(
@@ -151,19 +161,60 @@ void SharedWorkerHost::Start(
mojom::kNavigation_SharedWorkerSpec, process_id_,
mojo::MakeRequest(&interface_provider)));
+ // Add the network factory to the bundle to pass to the renderer. The bundle
+ // is only provided (along with |script_loader_factory|) if
+ // NetworkService/S13nSW is enabled.
+ DCHECK(!script_loader_factory || factory_bundle);
+ if (factory_bundle) {
+ network::mojom::URLLoaderFactoryPtrInfo network_factory_info;
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // NetworkService is on: Use the network service.
+ CreateNetworkFactory(mojo::MakeRequest(&network_factory_info));
+ } else {
+ // NetworkService is off: RenderProcessHost gives us a non-NetworkService
+ // network factory.
+ RenderProcessHost::FromID(process_id_)
+ ->CreateURLLoaderFactory(mojo::MakeRequest(&network_factory_info));
+ }
+ DCHECK(!factory_bundle->default_factory_info());
+ factory_bundle->default_factory_info() = std::move(network_factory_info);
+
+ // TODO(falken): We might need to set the default factory to AppCache
+ // instead, as we do for frames, if requests from this shared worker are
+ // supposed to go through AppCache.
+ }
+
// Send the CreateSharedWorker message.
factory_ = std::move(factory);
factory_->CreateSharedWorker(
std::move(info), pause_on_start, devtools_worker_token,
- std::move(content_settings), std::move(service_worker_provider_info),
- std::move(script_loader_factory), std::move(host),
- std::move(worker_request_), std::move(interface_provider));
+ renderer_preferences, std::move(content_settings),
+ std::move(service_worker_provider_info), std::move(script_loader_factory),
+ std::move(factory_bundle), std::move(host), std::move(worker_request_),
+ std::move(interface_provider));
// Monitor the lifetime of the worker.
worker_.set_connection_error_handler(base::BindOnce(
&SharedWorkerHost::OnWorkerConnectionLost, weak_factory_.GetWeakPtr()));
}
+// This is similar to
+// RenderFrameHostImpl::CreateNetworkServiceDefaultFactoryAndObserve.
+void SharedWorkerHost::CreateNetworkFactory(
+ network::mojom::URLLoaderFactoryRequest request) {
+ network::mojom::URLLoaderFactoryParamsPtr params =
+ network::mojom::URLLoaderFactoryParams::New();
+ params->process_id = process_id_;
+ // TODO(lukasza): https://crbug.com/792546: Start using CORB.
+ params->is_corb_enabled = false;
+
+ service_->storage_partition()->GetNetworkContext()->CreateURLLoaderFactory(
+ std::move(request), std::move(params));
+
+ // TODO(crbug.com/848256): Detect connection error and send a IPC with a new
+ // network factory like UpdateSubresourceLoaderFactories does for frames.
+}
+
void SharedWorkerHost::AllowFileSystem(
const GURL& url,
base::OnceCallback<void(bool)> callback) {
diff --git a/chromium/content/browser/shared_worker/shared_worker_host.h b/chromium/content/browser/shared_worker/shared_worker_host.h
index e6f1f73f997..95f9f2c26fd 100644
--- a/chromium/content/browser/shared_worker/shared_worker_host.h
+++ b/chromium/content/browser/shared_worker/shared_worker_host.h
@@ -36,6 +36,7 @@ namespace content {
class SharedWorkerContentSettingsProxyImpl;
class SharedWorkerInstance;
class SharedWorkerServiceImpl;
+class URLLoaderFactoryBundleInfo;
// The SharedWorkerHost is the interface that represents the browser side of
// the browser <-> worker communication channel. This is owned by
@@ -66,7 +67,8 @@ class CONTENT_EXPORT SharedWorkerHost
mojom::SharedWorkerFactoryPtr factory,
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
- network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory);
+ network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle);
void AllowFileSystem(const GURL& url,
base::OnceCallback<void(bool)> callback);
@@ -137,6 +139,8 @@ class CONTENT_EXPORT SharedWorkerHost
void GetInterface(const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) override;
+ void CreateNetworkFactory(network::mojom::URLLoaderFactoryRequest request);
+
void AdvanceTo(Phase phase);
mojo::Binding<mojom::SharedWorkerHost> binding_;
diff --git a/chromium/content/browser/shared_worker/shared_worker_host_unittest.cc b/chromium/content/browser/shared_worker/shared_worker_host_unittest.cc
index a00d44ffb4b..f90a0342ef7 100644
--- a/chromium/content/browser/shared_worker/shared_worker_host_unittest.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_host_unittest.cc
@@ -14,10 +14,14 @@
#include "content/browser/shared_worker/shared_worker_connector_impl.h"
#include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/browser/shared_worker/shared_worker_service_impl.h"
+#include "content/public/test/mock_render_process_host.h"
+#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_storage_partition.h"
#include "content/public/test/test_utils.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/test_support/test_utils.h"
+#include "services/network/test/test_network_context.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
#include "url/origin.h"
@@ -28,7 +32,11 @@ namespace content {
class SharedWorkerHostTest : public testing::Test {
public:
- SharedWorkerHostTest() : service_(nullptr) {}
+ SharedWorkerHostTest()
+ : mock_render_process_host_(&browser_context_),
+ service_(&storage_partition_, nullptr /* service_worker_context */) {
+ storage_partition_.set_network_context(&network_context_);
+ }
base::WeakPtr<SharedWorkerHost> CreateHost() {
GURL url("http://www.example.com/w.js");
@@ -47,7 +55,7 @@ class SharedWorkerHostTest : public testing::Test {
content_security_policy_type, creation_address_space,
creation_context_type);
auto host = std::make_unique<SharedWorkerHost>(
- &service_, std::move(instance), 11 /* dummy process_id */);
+ &service_, std::move(instance), mock_render_process_host_.GetID());
auto weak_host = host->AsWeakPtr();
service_.worker_hosts_.insert(std::move(host));
return weak_host;
@@ -56,7 +64,8 @@ class SharedWorkerHostTest : public testing::Test {
void StartWorker(SharedWorkerHost* host,
mojom::SharedWorkerFactoryPtr factory) {
host->Start(std::move(factory), nullptr /* service_worker_provider_info */,
- {} /* script_loader_factory_info */);
+ {} /* script_loader_factory_info */,
+ nullptr /* factory_bundle */);
}
MessagePortChannel AddClient(SharedWorkerHost* host,
@@ -71,6 +80,11 @@ class SharedWorkerHostTest : public testing::Test {
protected:
TestBrowserThreadBundle test_browser_thread_bundle_;
+ TestStoragePartition storage_partition_;
+ network::TestNetworkContext network_context_;
+ TestBrowserContext browser_context_;
+ MockRenderProcessHost mock_render_process_host_;
+
SharedWorkerServiceImpl service_;
DISALLOW_COPY_AND_ASSIGN(SharedWorkerHostTest);
@@ -181,7 +195,8 @@ TEST_F(SharedWorkerHostTest, TerminateAfterStarting) {
// Start the worker.
host->Start(std::move(factory), nullptr /* service_worker_provider_info */,
- {} /* script_loader_factory_info */);
+ {} /* script_loader_factory_info */,
+ nullptr /* factory_bundle */);
// Add a client.
MockSharedWorkerClient client;
diff --git a/chromium/content/browser/shared_worker/shared_worker_script_loader.cc b/chromium/content/browser/shared_worker/shared_worker_script_loader.cc
index 2a540fac395..81fb3763c49 100644
--- a/chromium/content/browser/shared_worker/shared_worker_script_loader.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_script_loader.cc
@@ -6,10 +6,10 @@
#include "content/browser/loader/navigation_loader_interceptor.h"
#include "content/browser/service_worker/service_worker_provider_host.h"
-#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/resource_context.h"
#include "net/url_request/redirect_util.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
@@ -34,7 +34,7 @@ SharedWorkerScriptLoader::SharedWorkerScriptLoader(
traffic_annotation_(traffic_annotation),
url_loader_client_binding_(this),
weak_factory_(this) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
if (service_worker_provider_host_) {
service_worker_interceptor_ =
@@ -76,8 +76,6 @@ void SharedWorkerScriptLoader::MaybeStartLoader(
return;
}
- // TODO(falken): Support blob urls.
-
LoadFromNetwork();
}
@@ -96,6 +94,8 @@ void SharedWorkerScriptLoader::LoadFromNetwork() {
// the new URL.
void SharedWorkerScriptLoader::FollowRedirect(
+ const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
DCHECK(!modified_request_headers.has_value()) << "Redirect with modified "
"headers was not supported "
@@ -107,7 +107,8 @@ void SharedWorkerScriptLoader::FollowRedirect(
bool should_clear_upload = false;
net::RedirectUtil::UpdateHttpRequest(
resource_request_.url, resource_request_.method, *redirect_info_,
- &resource_request_.headers, &should_clear_upload);
+ modified_request_headers, &resource_request_.headers,
+ &should_clear_upload);
resource_request_.url = redirect_info_->new_url;
resource_request_.method = redirect_info_->new_method;
@@ -151,9 +152,8 @@ void SharedWorkerScriptLoader::ResumeReadingBodyFromNet() {
// calls FollowRedirect(), it can do so.
void SharedWorkerScriptLoader::OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) {
- client_->OnReceiveResponse(response_head, std::move(downloaded_file));
+ const network::ResourceResponseHead& response_head) {
+ client_->OnReceiveResponse(response_head);
}
void SharedWorkerScriptLoader::OnReceiveRedirect(
@@ -169,11 +169,6 @@ void SharedWorkerScriptLoader::OnReceiveRedirect(
client_->OnReceiveRedirect(redirect_info, response_head);
}
-void SharedWorkerScriptLoader::OnDataDownloaded(int64_t data_len,
- int64_t encoded_data_len) {
- client_->OnDataDownloaded(data_len, encoded_data_len);
-}
-
void SharedWorkerScriptLoader::OnUploadProgress(
int64_t current_position,
int64_t total_size,
diff --git a/chromium/content/browser/shared_worker/shared_worker_script_loader.h b/chromium/content/browser/shared_worker/shared_worker_script_loader.h
index 3868aedd721..e7eb646e6a3 100644
--- a/chromium/content/browser/shared_worker/shared_worker_script_loader.h
+++ b/chromium/content/browser/shared_worker/shared_worker_script_loader.h
@@ -53,7 +53,9 @@ class SharedWorkerScriptLoader : public network::mojom::URLLoader,
~SharedWorkerScriptLoader() override;
// network::mojom::URLLoader:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
@@ -63,12 +65,10 @@ class SharedWorkerScriptLoader : public network::mojom::URLLoader,
// network::mojom::URLLoaderClient:
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override;
+ const network::ResourceResponseHead& response_head) override;
void OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const network::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;
diff --git a/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.cc b/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.cc
index 08260e2484f..6a21c378c48 100644
--- a/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_script_loader_factory.cc
@@ -10,10 +10,10 @@
#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/shared_worker/shared_worker_script_loader.h"
-#include "content/common/service_worker/service_worker_utils.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/network/public/cpp/resource_response.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
namespace content {
@@ -26,7 +26,7 @@ SharedWorkerScriptLoaderFactory::SharedWorkerScriptLoaderFactory(
: service_worker_provider_host_(service_worker_provider_host),
resource_context_(resource_context),
loader_factory_(std::move(loader_factory)) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
DCHECK_EQ(service_worker_provider_host_->provider_type(),
blink::mojom::ServiceWorkerProviderType::kForSharedWorker);
}
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 8140ae678d3..0727104684b 100644
--- a/chromium/content/browser/shared_worker/shared_worker_service_impl.cc
+++ b/chromium/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -12,13 +12,15 @@
#include "base/callback.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/task_scheduler/post_task.h"
+#include "content/browser/file_url_loader_factory.h"
#include "content/browser/shared_worker/shared_worker_host.h"
#include "content/browser/shared_worker/shared_worker_instance.h"
#include "content/browser/shared_worker/shared_worker_script_loader_factory.h"
#include "content/browser/storage_partition_impl.h"
+#include "content/browser/url_loader_factory_getter.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
-#include "content/common/service_worker/service_worker_utils.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"
@@ -29,6 +31,7 @@
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "url/origin.h"
namespace content {
@@ -39,13 +42,58 @@ bool IsShuttingDown(RenderProcessHost* host) {
host->IsKeepAliveRefCountDisabled();
}
+std::unique_ptr<URLLoaderFactoryBundleInfo> CreateFactoryBundle(
+ int process_id,
+ StoragePartitionImpl* storage_partition,
+ bool file_support) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ ContentBrowserClient::NonNetworkURLLoaderFactoryMap factories;
+ GetContentClient()
+ ->browser()
+ ->RegisterNonNetworkSubresourceURLLoaderFactories(
+ process_id, MSG_ROUTING_NONE, &factories);
+
+ auto factory_bundle = std::make_unique<URLLoaderFactoryBundleInfo>();
+ for (auto& pair : factories) {
+ const std::string& scheme = pair.first;
+ std::unique_ptr<network::mojom::URLLoaderFactory> factory =
+ std::move(pair.second);
+
+ network::mojom::URLLoaderFactoryPtr factory_ptr;
+ mojo::MakeStrongBinding(std::move(factory),
+ mojo::MakeRequest(&factory_ptr));
+ factory_bundle->factories_info().emplace(scheme,
+ factory_ptr.PassInterface());
+ }
+
+ if (file_support) {
+ auto file_factory = std::make_unique<FileURLLoaderFactory>(
+ storage_partition->browser_context()->GetPath(),
+ base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BACKGROUND,
+ base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}));
+ network::mojom::URLLoaderFactoryPtr file_factory_ptr;
+ mojo::MakeStrongBinding(std::move(file_factory),
+ mojo::MakeRequest(&file_factory_ptr));
+ factory_bundle->factories_info().emplace(url::kFileScheme,
+ file_factory_ptr.PassInterface());
+ }
+ return factory_bundle;
+}
+
void CreateScriptLoaderOnIO(
scoped_refptr<URLLoaderFactoryGetter> loader_factory_getter,
- std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_info,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_for_browser_info,
+ std::unique_ptr<URLLoaderFactoryBundleInfo>
+ factory_bundle_for_renderer_info,
scoped_refptr<ServiceWorkerContextWrapper> context,
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ blob_url_loader_factory_info,
int process_id,
base::OnceCallback<void(mojom::ServiceWorkerProviderInfoForSharedWorkerPtr,
- network::mojom::URLLoaderFactoryAssociatedPtrInfo)>
+ network::mojom::URLLoaderFactoryAssociatedPtrInfo,
+ std::unique_ptr<URLLoaderFactoryBundleInfo>)>
callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -54,46 +102,54 @@ void CreateScriptLoaderOnIO(
base::WeakPtr<ServiceWorkerProviderHost> host =
context->PreCreateHostForSharedWorker(process_id, &provider_info);
- // Create the factory bundle for loading the script.
- scoped_refptr<URLLoaderFactoryBundle> factory_bundle =
- base::MakeRefCounted<URLLoaderFactoryBundle>(
- std::move(factory_bundle_info));
-
- // Add the network factory to the bundle. The factory from
- // CloneNetworkFactory() doesn't support reconnection to the network service
- // after a crash, but it's OK since it's used for a single shared worker
- // startup.
- network::mojom::URLLoaderFactoryPtr network_factory_ptr;
- loader_factory_getter->CloneNetworkFactory(
- mojo::MakeRequest(&network_factory_ptr));
- factory_bundle->SetDefaultFactory(std::move(network_factory_ptr));
+ // Create the URL loader factory for SharedWorkerScriptLoaderFactory to use to
+ // load the main script.
+ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory;
+ if (blob_url_loader_factory_info) {
+ // If we have a blob_url_loader_factory just use that directly rather than
+ // creating a new URLLoaderFactoryBundle.
+ url_loader_factory = network::SharedURLLoaderFactory::Create(
+ std::move(blob_url_loader_factory_info));
+ } else {
+ // Create a factory bundle to use.
+ scoped_refptr<URLLoaderFactoryBundle> factory_bundle =
+ base::MakeRefCounted<URLLoaderFactoryBundle>(
+ std::move(factory_bundle_for_browser_info));
+ url_loader_factory = factory_bundle;
+
+ // Add the network factory to the bundle. The factory from
+ // CloneNetworkFactory() doesn't support reconnection to the network service
+ // after a crash, but it's OK since it's used for a single shared worker
+ // startup.
+ network::mojom::URLLoaderFactoryPtr network_factory_ptr;
+ loader_factory_getter->CloneNetworkFactory(
+ mojo::MakeRequest(&network_factory_ptr));
+ factory_bundle->SetDefaultFactory(std::move(network_factory_ptr));
+ }
// Create the SharedWorkerScriptLoaderFactory.
network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory;
mojo::MakeStrongAssociatedBinding(
std::make_unique<SharedWorkerScriptLoaderFactory>(
context.get(), host->AsWeakPtr(), context->resource_context(),
- std::move(factory_bundle)),
+ std::move(url_loader_factory)),
mojo::MakeRequest(&script_loader_factory));
- // TODO(falken): Also send the factory bundle to the renderer like
- // CommitNavigation does, to be used for subresource requests from the shared
- // worker (SharedWorkerScriptLoaderFactory is only used for the main resource
- // request). However, the restartable network factory should be used in this
- // case.
-
// We continue in StartWorker.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(std::move(callback), std::move(provider_info),
- std::move(script_loader_factory)));
+ std::move(script_loader_factory),
+ std::move(factory_bundle_for_renderer_info)));
}
} // namespace
SharedWorkerServiceImpl::SharedWorkerServiceImpl(
+ StoragePartition* storage_partition,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context)
- : service_worker_context_(std::move(service_worker_context)),
+ : storage_partition_(storage_partition),
+ service_worker_context_(std::move(service_worker_context)),
weak_factory_(this) {}
SharedWorkerServiceImpl::~SharedWorkerServiceImpl() {}
@@ -135,7 +191,8 @@ void SharedWorkerServiceImpl::ConnectToWorker(
mojom::SharedWorkerInfoPtr info,
mojom::SharedWorkerClientPtr client,
blink::mojom::SharedWorkerCreationContextType creation_context_type,
- const blink::MessagePortChannel& message_port) {
+ const blink::MessagePortChannel& message_port,
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
RenderFrameHostImpl* render_frame_host =
@@ -187,7 +244,7 @@ void SharedWorkerServiceImpl::ConnectToWorker(
}
CreateWorker(std::move(instance), std::move(client), process_id, frame_id,
- message_port);
+ message_port, std::move(blob_url_loader_factory));
}
void SharedWorkerServiceImpl::DestroyHost(SharedWorkerHost* host) {
@@ -210,9 +267,15 @@ void SharedWorkerServiceImpl::CreateWorker(
mojom::SharedWorkerClientPtr client,
int process_id,
int frame_id,
- const blink::MessagePortChannel& message_port) {
+ const blink::MessagePortChannel& message_port,
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(!blob_url_loader_factory || instance->url().SchemeIsBlob());
+
+ bool constructor_uses_file_url =
+ instance->constructor_origin().scheme() == url::kFileScheme;
+
// Create the host. We need to do this even before starting the worker,
// because we are about to bounce to the IO thread. If another ConnectToWorker
// request arrives in the meantime, it finds and reuses the host instead of
@@ -222,40 +285,37 @@ void SharedWorkerServiceImpl::CreateWorker(
auto weak_host = host->AsWeakPtr();
worker_hosts_.insert(std::move(host));
+ StoragePartitionImpl* storage_partition =
+ service_worker_context_->storage_partition();
// Bounce to the IO thread to setup service worker support in case the request
// for the worker script will need to be intercepted by service workers.
- if (ServiceWorkerUtils::IsServicificationEnabled()) {
- // Set up the factory bundle for non-NetworkService URLs, e.g.,
- // chrome-extension:// URLs.
- ContentBrowserClient::NonNetworkURLLoaderFactoryMap factories;
- GetContentClient()
- ->browser()
- ->RegisterNonNetworkSubresourceURLLoaderFactories(
- process_id, MSG_ROUTING_NONE, &factories);
-
- // TODO(falken): Add FileURLLoaderFactory if the requesting frame is a file
- // resource.
-
- auto factory_bundle = std::make_unique<URLLoaderFactoryBundleInfo>();
- for (auto& pair : factories) {
- const std::string& scheme = pair.first;
- std::unique_ptr<network::mojom::URLLoaderFactory> factory =
- std::move(pair.second);
-
- network::mojom::URLLoaderFactoryPtr factory_ptr;
- mojo::MakeStrongBinding(std::move(factory),
- mojo::MakeRequest(&factory_ptr));
- factory_bundle->factories_info().emplace(scheme,
- factory_ptr.PassInterface());
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ if (!storage_partition) {
+ // The context is shutting down. Just drop the request.
+ return;
}
+ // Set up the factory bundle for non-NetworkService URLs, e.g.,
+ // chrome-extension:// URLs. One factory bundle is consumed by the browser
+ // for SharedWorkerScriptLoaderFactory, and one is sent to the renderer.
+ std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_for_browser =
+ CreateFactoryBundle(process_id, storage_partition,
+ constructor_uses_file_url);
+ std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle_for_renderer =
+ CreateFactoryBundle(process_id, storage_partition,
+ constructor_uses_file_url);
+
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
&CreateScriptLoaderOnIO,
service_worker_context_->storage_partition()
->url_loader_factory_getter(),
- std::move(factory_bundle), service_worker_context_, process_id,
+ std::move(factory_bundle_for_browser),
+ std::move(factory_bundle_for_renderer), service_worker_context_,
+ blob_url_loader_factory ? blob_url_loader_factory->Clone()
+ : nullptr,
+ process_id,
base::BindOnce(&SharedWorkerServiceImpl::StartWorker,
weak_factory_.GetWeakPtr(), std::move(instance),
weak_host, std::move(client), process_id, frame_id,
@@ -264,7 +324,7 @@ void SharedWorkerServiceImpl::CreateWorker(
}
StartWorker(std::move(instance), weak_host, std::move(client), process_id,
- frame_id, message_port, nullptr, {});
+ frame_id, message_port, nullptr, {}, nullptr);
}
void SharedWorkerServiceImpl::StartWorker(
@@ -277,7 +337,8 @@ void SharedWorkerServiceImpl::StartWorker(
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
- script_loader_factory_info) {
+ script_loader_factory_info,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// The host may already be gone if something forcibly terminated the worker
@@ -304,7 +365,7 @@ void SharedWorkerServiceImpl::StartWorker(
BindInterface(process_host, &factory);
host->Start(std::move(factory), std::move(service_worker_provider_info),
- std::move(script_loader_factory_info));
+ std::move(script_loader_factory_info), std::move(factory_bundle));
host->AddClient(std::move(client), process_id, frame_id, message_port);
}
diff --git a/chromium/content/browser/shared_worker/shared_worker_service_impl.h b/chromium/content/browser/shared_worker/shared_worker_service_impl.h
index b41bcc2d352..46810fa5d75 100644
--- a/chromium/content/browser/shared_worker/shared_worker_service_impl.h
+++ b/chromium/content/browser/shared_worker/shared_worker_service_impl.h
@@ -29,10 +29,13 @@ class MessagePortChannel;
namespace content {
class SharedWorkerInstance;
class SharedWorkerHost;
+class StoragePartition;
+// Created per StoragePartition.
class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
public:
- explicit SharedWorkerServiceImpl(
+ SharedWorkerServiceImpl(
+ StoragePartition* storage_partition,
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context);
~SharedWorkerServiceImpl() override;
@@ -50,19 +53,24 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
mojom::SharedWorkerInfoPtr info,
mojom::SharedWorkerClientPtr client,
blink::mojom::SharedWorkerCreationContextType creation_context_type,
- const blink::MessagePortChannel& port);
+ const blink::MessagePortChannel& port,
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory);
void DestroyHost(SharedWorkerHost* host);
+ StoragePartition* storage_partition() { return storage_partition_; }
+
private:
friend class SharedWorkerServiceImplTest;
friend class SharedWorkerHostTest;
- void CreateWorker(std::unique_ptr<SharedWorkerInstance> instance,
- mojom::SharedWorkerClientPtr client,
- int process_id,
- int frame_id,
- const blink::MessagePortChannel& message_port);
+ void CreateWorker(
+ std::unique_ptr<SharedWorkerInstance> instance,
+ mojom::SharedWorkerClientPtr client,
+ int process_id,
+ int frame_id,
+ const blink::MessagePortChannel& message_port,
+ scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory);
void StartWorker(std::unique_ptr<SharedWorkerInstance> instance,
base::WeakPtr<SharedWorkerHost> host,
mojom::SharedWorkerClientPtr client,
@@ -72,7 +80,8 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
- script_loader_factory_info);
+ script_loader_factory_info,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> factory_bundle);
// Returns nullptr if there is no such host.
SharedWorkerHost* FindSharedWorkerHost(int process_id, int route_id);
@@ -83,6 +92,8 @@ class CONTENT_EXPORT SharedWorkerServiceImpl : public SharedWorkerService {
worker_hosts_;
base::OnceClosure terminate_all_workers_callback_;
+ // |storage_partition_| owns |this|.
+ StoragePartition* const storage_partition_;
scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
base::WeakPtrFactory<SharedWorkerServiceImpl> weak_factory_;
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 2afa11622eb..cf56ef37546 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
@@ -114,7 +114,7 @@ void ConnectToSharedWorker(mojom::SharedWorkerConnectorPtr connector,
connector->Connect(std::move(info), std::move(client_proxy),
blink::mojom::SharedWorkerCreationContextType::kSecure,
- std::move(message_pipe.handle1));
+ std::move(message_pipe.handle1), nullptr);
}
} // namespace
diff --git a/chromium/content/browser/shared_worker/worker_browsertest.cc b/chromium/content/browser/shared_worker/worker_browsertest.cc
index 179376232af..9c7ffc1364b 100644
--- a/chromium/content/browser/shared_worker/worker_browsertest.cc
+++ b/chromium/content/browser/shared_worker/worker_browsertest.cc
@@ -4,12 +4,14 @@
#include "base/bind.h"
#include "base/logging.h"
+#include "base/path_service.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 "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/client_certificate_delegate.h"
@@ -22,6 +24,7 @@
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_content_browser_client.h"
#include "net/base/escape.h"
+#include "net/base/filename_util.h"
#include "net/ssl/ssl_server_config.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/spawned_test_server/spawned_test_server.h"
@@ -64,20 +67,32 @@ class WorkerTest : public ContentBrowserTest {
int select_certificate_count() const { return select_certificate_count_; }
+ GURL GetTestFileURL(const std::string& test_case) {
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ base::FilePath path;
+ EXPECT_TRUE(base::PathService::Get(content::DIR_TEST_DATA, &path));
+ path = path.AppendASCII("workers").AppendASCII(test_case);
+ return net::FilePathToFileURL(path);
+ }
+
GURL GetTestURL(const std::string& test_case, const std::string& query) {
std::string url_string = "/workers/" + test_case + "?" + query;
return embedded_test_server()->GetURL(url_string);
}
- void RunTest(Shell* window, const GURL& url) {
- const base::string16 expected_title = base::ASCIIToUTF16("OK");
- TitleWatcher title_watcher(window->web_contents(), expected_title);
+ void RunTest(Shell* window, const GURL& url, bool expect_failure = false) {
+ const base::string16 ok_title = base::ASCIIToUTF16("OK");
+ const base::string16 fail_title = base::ASCIIToUTF16("FAIL");
+ TitleWatcher title_watcher(window->web_contents(), ok_title);
+ title_watcher.AlsoWaitForTitle(fail_title);
NavigateToURL(window, url);
base::string16 final_title = title_watcher.WaitAndGetTitle();
- EXPECT_EQ(expected_title, final_title);
+ EXPECT_EQ(expect_failure ? fail_title : ok_title, final_title);
}
- void RunTest(const GURL& url) { RunTest(shell(), url); }
+ void RunTest(const GURL& url, bool expect_failure = false) {
+ RunTest(shell(), url, expect_failure);
+ }
static void QuitUIMessageLoop(base::Callback<void()> callback) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(callback));
@@ -103,6 +118,18 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, SingleWorker) {
RunTest(GetTestURL("single_worker.html", std::string()));
}
+IN_PROC_BROWSER_TEST_F(WorkerTest, SingleWorkerFromFile) {
+ RunTest(GetTestFileURL("single_worker.html"));
+}
+
+IN_PROC_BROWSER_TEST_F(WorkerTest, HttpPageCantCreateFileWorker) {
+ GURL url = GetTestURL(
+ "single_worker.html",
+ "workerUrl=" + net::EscapeQueryParamValue(
+ GetTestFileURL("worker_common.js").spec(), true));
+ RunTest(url, /*expect_failure=*/true);
+}
+
IN_PROC_BROWSER_TEST_F(WorkerTest, MultipleWorkers) {
RunTest(GetTestURL("multi_worker.html", std::string()));
}
diff --git a/chromium/content/browser/site_instance_impl.cc b/chromium/content/browser/site_instance_impl.cc
index b34db8034e1..bf59f2d42ca 100644
--- a/chromium/content/browser/site_instance_impl.cc
+++ b/chromium/content/browser/site_instance_impl.cc
@@ -85,6 +85,11 @@ bool SiteInstanceImpl::ShouldAssignSiteForURL(const GURL& url) {
return GetContentClient()->browser()->ShouldAssignSiteForURL(url);
}
+// static
+bool SiteInstanceImpl::IsOriginLockASite(const GURL& lock_url) {
+ return lock_url.has_scheme() && lock_url.has_host();
+}
+
int32_t SiteInstanceImpl::GetId() {
return id_;
}
@@ -444,10 +449,41 @@ GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context,
// This is useful for cases like file URLs.
if (!origin.unique()) {
// Prefer to use the scheme of |origin| rather than |url|, to correctly
- // cover blob: and filesystem: URIs (see also https://crbug.com/697111).
+ // cover blob:file: and filesystem:file: URIs (see also
+ // https://crbug.com/697111).
DCHECK(!origin.scheme().empty());
return GURL(origin.scheme() + ":");
} else if (url.has_scheme()) {
+ // In some cases, it is not safe to use just the scheme as a site URL, as
+ // that might allow two URLs created by different sites to share a process.
+ // See https://crbug.com/863623 and https://crbug.com/863069.
+ //
+ // TODO(alexmos,creis): This should eventually be expanded to certain other
+ // schemes, such as file:.
+ // TODO(creis): This currently causes problems with tests on Android and
+ // Android WebView. For now, skip it when Site Isolation is not enabled,
+ // since there's no need to isolate data and blob URLs from each other in
+ // that case.
+ bool is_site_isolation_enabled =
+ SiteIsolationPolicy::UseDedicatedProcessesForAllSites() ||
+ SiteIsolationPolicy::AreIsolatedOriginsEnabled();
+ if (is_site_isolation_enabled &&
+ (url.SchemeIsBlob() || url.scheme() == url::kDataScheme)) {
+ // We get here for blob URLs of form blob:null/guid. Use the full URL
+ // with the guid in that case, which isolates all blob URLs with unique
+ // origins from each other. We also get here for browser-initiated
+ // navigations to data URLs, which have a unique origin and should only
+ // share a process when they are identical. Remove hash from the URL in
+ // either case, since same-document navigations shouldn't use a different
+ // site URL.
+ if (url.has_ref()) {
+ GURL::Replacements replacements;
+ replacements.ClearRef();
+ url = url.ReplaceComponents(replacements);
+ }
+ return url;
+ }
+
DCHECK(!url.scheme().empty());
return GURL(url.scheme() + ":");
}
@@ -544,13 +580,6 @@ void SiteInstanceImpl::RenderProcessHostDestroyed(RenderProcessHost* host) {
process_ = nullptr;
}
-void SiteInstanceImpl::RenderProcessWillExit(RenderProcessHost* host) {
- // TODO(nick): http://crbug.com/575400 - RenderProcessWillExit might not serve
- // any purpose here.
- for (auto& observer : observers_)
- observer.RenderProcessGone(this);
-}
-
void SiteInstanceImpl::RenderProcessExited(
RenderProcessHost* host,
const ChildProcessTerminationInfo& info) {
@@ -587,7 +616,7 @@ void SiteInstanceImpl::LockToOriginIfNeeded() {
// strong protection. If only some sites are isolated, we need
// additional logic to prevent the non-isolated sites from requesting
// resources for isolated sites. https://crbug.com/509125
- policy->LockToOrigin(process_->GetID(), site_);
+ process_->LockToOrigin(site_);
break;
}
case CheckOriginLockResult::HAS_WRONG_LOCK:
diff --git a/chromium/content/browser/site_instance_impl.h b/chromium/content/browser/site_instance_impl.h
index 4e96a2383e2..f2fa8e198bd 100644
--- a/chromium/content/browser/site_instance_impl.h
+++ b/chromium/content/browser/site_instance_impl.h
@@ -39,6 +39,12 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
const GURL& url);
static bool ShouldAssignSiteForURL(const GURL& url);
+ // Returns whether |lock_url| is at least at the granularity of a site (i.e.,
+ // a scheme plus eTLD+1, like https://google.com). Also returns true if the
+ // lock is to a more specific origin (e.g., https://accounts.google.com), but
+ // not if the lock is empty or applies to an entire scheme (e.g., file://).
+ static bool IsOriginLockASite(const GURL& lock_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
@@ -223,7 +229,6 @@ class CONTENT_EXPORT SiteInstanceImpl final : public SiteInstance,
// RenderProcessHostObserver implementation.
void RenderProcessHostDestroyed(RenderProcessHost* host) override;
- void RenderProcessWillExit(RenderProcessHost* host) override;
void RenderProcessExited(RenderProcessHost* host,
const ChildProcessTerminationInfo& info) override;
diff --git a/chromium/content/browser/site_instance_impl_unittest.cc b/chromium/content/browser/site_instance_impl_unittest.cc
index effcb936cb2..66159134d65 100644
--- a/chromium/content/browser/site_instance_impl_unittest.cc
+++ b/chromium/content/browser/site_instance_impl_unittest.cc
@@ -25,6 +25,7 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/webui/content_web_ui_controller_factory.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
+#include "content/public/common/bindings_policy.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_features.h"
@@ -42,6 +43,13 @@
#include "url/url_util.h"
namespace content {
+namespace {
+
+GURL GetWebUIURL(std::string host) {
+ return GURL(std::string(kChromeUIScheme) + "://" + host);
+}
+
+} // namespace
const char kPrivilegedScheme[] = "privileged";
@@ -212,41 +220,6 @@ TEST_F(SiteInstanceTest, SiteInstanceDestructor) {
// contents is now deleted, along with instance and browsing_instance
}
-// Test that NavigationEntries with SiteInstances can be cloned, but that their
-// SiteInstances can be changed afterwards. Also tests that the ref counts are
-// updated properly after the change.
-TEST_F(SiteInstanceTest, CloneNavigationEntry) {
- const GURL url("test:foo");
-
- std::unique_ptr<NavigationEntryImpl> e1 =
- base::WrapUnique(new NavigationEntryImpl(
- SiteInstanceImpl::Create(nullptr), url, Referrer(), base::string16(),
- ui::PAGE_TRANSITION_LINK, false,
- nullptr /* blob_url_loader_factory */));
-
- // Clone the entry.
- std::unique_ptr<NavigationEntryImpl> e2 = e1->Clone();
-
- // Should be able to change the SiteInstance of the cloned entry.
- e2->set_site_instance(SiteInstanceImpl::Create(nullptr));
-
- EXPECT_EQ(0, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(0, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
-
- // The first SiteInstance and BrowsingInstance should go away after resetting
- // e1, since e2 should no longer be referencing it.
- e1.reset();
- EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(1, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
-
- // The second SiteInstance should go away after resetting e2.
- e2.reset();
- EXPECT_EQ(1, browser_client()->GetAndClearSiteInstanceDeleteCount());
- EXPECT_EQ(1, browser_client()->GetAndClearBrowsingInstanceDeleteCount());
-
- DrainMessageLoop();
-}
-
// Test to ensure GetProcess returns and creates processes correctly.
TEST_F(SiteInstanceTest, GetProcess) {
// Ensure that GetProcess returns a process.
@@ -343,12 +316,25 @@ TEST_F(SiteInstanceTest, GetSiteForURL) {
EXPECT_EQ("file", site_url.scheme());
EXPECT_FALSE(site_url.has_host());
- // Data URLs should include the scheme.
+ // Data URLs should include the whole URL, except for the hash, when Site
+ // Isolation is enabled. Otherwise they just include the scheme.
test_url = GURL("data:text/html,foo");
site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
- EXPECT_EQ(GURL("data:"), site_url);
+ if (AreAllSitesIsolatedForTesting())
+ EXPECT_EQ(test_url, site_url);
+ else
+ EXPECT_EQ(GURL("data:"), site_url);
EXPECT_EQ("data", site_url.scheme());
EXPECT_FALSE(site_url.has_host());
+ test_url = GURL("data:text/html,foo#bar");
+ site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
+ EXPECT_FALSE(site_url.has_ref());
+ if (AreAllSitesIsolatedForTesting()) {
+ EXPECT_NE(test_url, site_url);
+ EXPECT_TRUE(site_url.EqualsIgnoringRef(test_url));
+ } else {
+ EXPECT_EQ(GURL("data:"), site_url);
+ }
// Javascript URLs should include the scheme.
test_url = GURL("javascript:foo();");
@@ -371,6 +357,25 @@ TEST_F(SiteInstanceTest, GetSiteForURL) {
EXPECT_EQ("file", site_url.scheme());
EXPECT_FALSE(site_url.has_host());
+ // Blob URLs created from a unique origin use the full URL as the site URL
+ // when Site Isolation is enabled, except for the hash. Otherwise they just
+ // include the scheme.
+ test_url = GURL("blob:null/1029e5a4-2983-4b90-a585-ed217563acfeb");
+ site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
+ if (AreAllSitesIsolatedForTesting())
+ EXPECT_EQ(test_url, site_url);
+ else
+ EXPECT_EQ(GURL("blob:"), site_url);
+ test_url = GURL("blob:null/1029e5a4-2983-4b90-a585-ed217563acfeb#foo");
+ site_url = SiteInstanceImpl::GetSiteForURL(nullptr, test_url);
+ EXPECT_FALSE(site_url.has_ref());
+ if (AreAllSitesIsolatedForTesting()) {
+ EXPECT_NE(test_url, site_url);
+ EXPECT_TRUE(site_url.EqualsIgnoringRef(test_url));
+ } else {
+ EXPECT_EQ(GURL("blob:"), site_url);
+ }
+
// Private domains are preserved, appspot being such a site.
test_url = GURL(
"blob:http://www.example.appspot.com:44/"
@@ -621,6 +626,7 @@ static scoped_refptr<SiteInstanceImpl> CreateSiteInstance(
// Test to ensure that pages that require certain privileges are grouped
// in processes with similar pages.
+// TODO(nasko): Remove. See https://crbug.com/847127.
TEST_F(SiteInstanceTest, ProcessSharingByType) {
// This test shouldn't run with --site-per-process mode, which prohibits
// the renderer process reuse this test explicitly exercises.
@@ -660,13 +666,13 @@ TEST_F(SiteInstanceTest, ProcessSharingByType) {
extension2_instance->GetProcess());
// Create some WebUI instances and make sure they share a process.
- scoped_refptr<SiteInstanceImpl> webui1_instance(CreateSiteInstance(
- browser_context.get(), GURL(kChromeUIScheme + std::string("://gpu"))));
- policy->GrantWebUIBindings(webui1_instance->GetProcess()->GetID());
+ scoped_refptr<SiteInstanceImpl> webui1_instance(
+ CreateSiteInstance(browser_context.get(), GetWebUIURL(kChromeUIGpuHost)));
+ policy->GrantWebUIBindings(webui1_instance->GetProcess()->GetID(),
+ BINDINGS_POLICY_WEB_UI);
scoped_refptr<SiteInstanceImpl> webui2_instance(CreateSiteInstance(
- browser_context.get(),
- GURL(kChromeUIScheme + std::string("://media-internals"))));
+ browser_context.get(), GetWebUIURL(kChromeUIMediaInternalsHost)));
std::unique_ptr<RenderProcessHost> dom_host(webui1_instance->GetProcess());
EXPECT_EQ(webui1_instance->GetProcess(), webui2_instance->GetProcess());
@@ -724,7 +730,7 @@ TEST_F(SiteInstanceTest, HasWrongProcessForURL) {
// Simulate granting WebUI bindings for the process.
ChildProcessSecurityPolicyImpl::GetInstance()->GrantWebUIBindings(
- webui_host->GetID());
+ webui_host->GetID(), BINDINGS_POLICY_WEB_UI);
EXPECT_TRUE(webui_instance->HasProcess());
EXPECT_FALSE(webui_instance->HasWrongProcessForURL(webui_url));
@@ -1024,7 +1030,7 @@ TEST_F(SiteInstanceTest, IsValidIsolatedOrigin) {
// Scheme must be HTTP or HTTPS.
EXPECT_FALSE(IsolatedOriginUtil::IsValidIsolatedOrigin(
- url::Origin::Create(GURL(kChromeUIScheme + std::string("://gpu")))));
+ url::Origin::Create(GetWebUIURL(kChromeUIGpuHost))));
EXPECT_TRUE(IsolatedOriginUtil::IsValidIsolatedOrigin(
url::Origin::Create(GURL("http://a.com"))));
EXPECT_TRUE(IsolatedOriginUtil::IsValidIsolatedOrigin(
@@ -1233,4 +1239,17 @@ TEST_F(SiteInstanceTest, OriginalURL) {
SetBrowserClientForTesting(regular_client);
}
+TEST_F(SiteInstanceTest, IsOriginLockASite) {
+ EXPECT_FALSE(SiteInstanceImpl::IsOriginLockASite(GURL("http://")));
+ EXPECT_FALSE(SiteInstanceImpl::IsOriginLockASite(GURL("")));
+ EXPECT_FALSE(SiteInstanceImpl::IsOriginLockASite(GURL("google.com")));
+ EXPECT_FALSE(SiteInstanceImpl::IsOriginLockASite(GURL("http:")));
+ EXPECT_FALSE(SiteInstanceImpl::IsOriginLockASite(GURL("chrome:")));
+
+ EXPECT_TRUE(SiteInstanceImpl::IsOriginLockASite(GURL("http://foo.com")));
+ EXPECT_TRUE(SiteInstanceImpl::IsOriginLockASite(GURL("http://bar.foo.com")));
+ EXPECT_TRUE(SiteInstanceImpl::IsOriginLockASite(
+ GURL("http://user:pass@google.com:99/foo;bar?q=a#ref")));
+}
+
} // namespace content
diff --git a/chromium/content/browser/site_per_process_browsertest.cc b/chromium/content/browser/site_per_process_browsertest.cc
index 569aa71cfe3..69281841aca 100644
--- a/chromium/content/browser/site_per_process_browsertest.cc
+++ b/chromium/content/browser/site_per_process_browsertest.cc
@@ -33,7 +33,7 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/test_timeouts.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -79,6 +79,7 @@
#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/hit_test_region_observer.h"
#include "content/public/test/navigation_handle_observer.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
@@ -231,16 +232,6 @@ double GetFrameDeviceScaleFactor(const ToRenderFrameHost& adapter) {
return device_scale_factor;
}
-// This helper accounts for Android devices which use page scale factor
-// different from 1.0. Coordinate targeting needs to be adjusted before
-// hit testing.
-double GetPageScaleFactor(Shell* shell) {
- return RenderWidgetHostImpl::From(
- shell->web_contents()->GetRenderViewHost()->GetWidget())
- ->last_frame_metadata()
- .page_scale_factor;
-}
-
class RedirectNotificationObserver : public NotificationObserver {
public:
// Register to listen for notifications of the given type from either a
@@ -539,6 +530,16 @@ void CheckFrameDepth(unsigned int expected_depth, FrameTreeNode* node) {
node->current_frame_host()->GetProcess()->GetFrameDepth());
}
+void GenerateTapDownGesture(RenderWidgetHost* rwh) {
+ blink::WebGestureEvent gesture_tap_down(
+ blink::WebGestureEvent::kGestureTapDown,
+ blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::GetStaticTimeStampForTests(),
+ blink::kWebGestureDeviceTouchscreen);
+ gesture_tap_down.is_source_touch_event_set_non_blocking = true;
+ rwh->ForwardGestureEvent(gesture_tap_down);
+}
+
} // namespace
//
@@ -1062,7 +1063,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
->GetRenderWidgetHost()
->GetView());
- WaitForChildFrameSurfaceReady(nested_iframe_node->current_frame_host());
+ RenderFrameSubmissionObserver frame_observer(nested_iframe_node);
+ frame_observer.WaitForMetadataChange();
// Verify that applying a CSS scale transform does not impact the size of the
// content of the nested iframe.
@@ -1117,6 +1119,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ViewBoundsInNestedFrameTest) {
GURL site_url(embedded_test_server()->GetURL(
"a.com", "/frame_tree/page_with_positioned_frame.html"));
NavigateFrameToURL(parent_iframe_node, site_url);
+ RenderFrameSubmissionObserver frame_observer(shell()->web_contents());
EXPECT_EQ(
" Site A ------------ proxies for B\n"
@@ -1132,9 +1135,11 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ViewBoundsInNestedFrameTest) {
nested_iframe_node->current_frame_host()
->GetRenderWidgetHost()
->GetView());
- WaitForChildFrameSurfaceReady(nested_iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(
+ nested_iframe_node->current_frame_host());
- float scale_factor = GetPageScaleFactor(shell());
+ float scale_factor =
+ frame_observer.LastRenderFrameMetadata().page_scale_factor;
// Get the view bounds of the nested iframe, which should account for the
// relative offset of its direct parent within the root frame.
@@ -1159,7 +1164,6 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ViewBoundsInNestedFrameTest) {
scroll_event.delta_y = -30.0f;
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
rwhv_root->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
-
filter->WaitForRect();
// The precise amount of scroll for the first view position update is not
@@ -1182,26 +1186,23 @@ 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);
RenderWidgetHost* child_rwh =
child_iframe_node->current_frame_host()->GetRenderWidgetHost();
- RenderWidgetHostViewBase* child_rwhv =
- static_cast<RenderWidgetHostViewBase*>(child_rwh->GetView());
-
- // If wheel scroll latching is enabled, the fling start won't bubble since
- // its corresponding GSB hasn't bubbled.
+ // 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);
+ child_rwh, blink::WebInputEvent::kGestureFlingStart);
- WaitForChildFrameSurfaceReady(child_iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(
+ child_iframe_node->current_frame_host());
gesture_fling_start_ack_observer.Reset();
+
+ GenerateTapDownGesture(child_rwh);
+
// Send a GSB, GSU, GFS sequence and verify that the GFS bubbles.
blink::WebGestureEvent gesture_scroll_begin(
blink::WebGestureEvent::kGestureScrollBegin,
@@ -1305,7 +1306,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
->GetRenderWidgetHost()
->GetView());
- WaitForChildFrameSurfaceReady(nested_iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(
+ nested_iframe_node->current_frame_host());
// Save the original offset as a point of reference.
filter->WaitForRect();
@@ -1327,17 +1329,14 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
scroll_event.has_precise_scrolling_deltas = true;
rwhv_parent->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- if (rwhv_parent->wheel_scroll_latching_enabled()) {
- // When scroll latching is enabled the event router sends wheel events of a
- // single scroll sequence to the target under the first wheel event. Send a
- // wheel end event to the current target view before sending a wheel event
- // to a different one.
- scroll_event.delta_y = 0.0f;
- scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
- scroll_event.dispatch_type =
- blink::WebInputEvent::DispatchType::kEventNonBlocking;
- rwhv_parent->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- }
+ // The event router sends wheel events of a single scroll sequence to the
+ // target under the first wheel event. Send a wheel end event to the current
+ // target view before sending a wheel event to a different one.
+ scroll_event.delta_y = 0.0f;
+ scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
+ scroll_event.dispatch_type =
+ blink::WebInputEvent::DispatchType::kEventNonBlocking;
+ rwhv_parent->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
// Ensure that the view position is propagated to the child properly.
filter->WaitForRect();
@@ -1370,17 +1369,14 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
update_rect = filter->last_rect();
}
- if (rwhv_parent->wheel_scroll_latching_enabled()) {
- // When scroll latching is enabled the event router sends wheel events of a
- // single scroll sequence to the target under the first wheel event. Send a
- // wheel end event to the current target view before sending a wheel event
- // to a different one.
- scroll_event.delta_y = 0.0f;
- scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
- scroll_event.dispatch_type =
- blink::WebInputEvent::DispatchType::kEventNonBlocking;
- rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- }
+ // The event router sends wheel events of a single scroll sequence to the
+ // target under the first wheel event. Send a wheel end event to the current
+ // target view before sending a wheel event to a different one.
+ scroll_event.delta_y = 0.0f;
+ scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
+ scroll_event.dispatch_type =
+ blink::WebInputEvent::DispatchType::kEventNonBlocking;
+ rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
filter->ResetRectRunLoop();
// Once we've sent a wheel to the nested iframe that we expect to turn into
@@ -1399,17 +1395,14 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollBubblingFromOOPIFTest) {
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseBegan;
rwhv_parent->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- if (rwhv_parent->wheel_scroll_latching_enabled()) {
- // When scroll latching is enabled the event router sends wheel events of a
- // single scroll sequence to the target under the first wheel event. Send a
- // wheel end event to the current target view before sending a wheel event
- // to a different one.
- scroll_event.delta_y = 0.0f;
- scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
- scroll_event.dispatch_type =
- blink::WebInputEvent::DispatchType::kEventNonBlocking;
- rwhv_parent->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- }
+ // The event router sends wheel events of a single scroll sequence to the
+ // target under the first wheel event. Send a wheel end event to the current
+ // target view before sending a wheel event to a different one.
+ scroll_event.delta_y = 0.0f;
+ scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
+ scroll_event.dispatch_type =
+ blink::WebInputEvent::DispatchType::kEventNonBlocking;
+ rwhv_parent->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
// Ensure ensuing offset change is received, and then reset the filter.
filter->WaitForRect();
@@ -1561,9 +1554,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
RenderWidgetHost* child_rwh =
child_iframe_node->current_frame_host()->GetRenderWidgetHost();
+ WaitForHitTestDataOrChildSurfaceReady(
+ child_iframe_node->current_frame_host());
- WaitForChildFrameSurfaceReady(child_iframe_node->current_frame_host());
-
+ GenerateTapDownGesture(child_rwh);
// Send a GSB to start scrolling sequence.
blink::WebGestureEvent gesture_scroll_begin(
blink::WebGestureEvent::kGestureScrollBegin,
@@ -1688,6 +1682,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_positioned_nested_frames.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ RenderFrameSubmissionObserver frame_observer(shell()->web_contents());
// It is safe to obtain the root frame tree node here, as it doesn't change.
FrameTreeNode* root = web_contents()->GetFrameTree()->root();
@@ -1712,22 +1707,19 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
->GetRenderWidgetHost()
->GetView());
- WaitForChildFrameSurfaceReady(nested_iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(
+ nested_iframe_node->current_frame_host());
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 = 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 = std::make_unique<ScrollObserver>(0, 5);
- }
+
+ // 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 = std::make_unique<ScrollObserver>(0, 15);
+
root->current_frame_host()->GetRenderWidgetHost()->AddInputEventObserver(
scroll_observer.get());
@@ -1737,7 +1729,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
blink::WebInputEvent::GetStaticTimeStampForTests());
gfx::Rect bounds = rwhv_nested->GetViewBounds();
- float scale_factor = GetPageScaleFactor(shell());
+ float scale_factor =
+ frame_observer.LastRenderFrameMetadata().page_scale_factor;
scroll_event.SetPositionInWidget(
gfx::ToCeiledInt((bounds.x() - root_view->GetViewBounds().x() + 10) *
scale_factor),
@@ -1750,35 +1743,22 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
ack_observer.Wait();
- // When wheel scroll latching is disabled, each wheel event will have its own
- // complete scroll seqeunce.
- if (!root_view->wheel_scroll_latching_enabled())
- scroll_observer->Wait();
-
- // Send 10 wheel events with delta_y = 1 to the nested oopif. When scroll
- // latching is disabled, each wheel event will have its own scroll sequence.
+ // Send 10 wheel events with delta_y = 1 to the nested oopif.
scroll_event.delta_y = 1.0f;
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseChanged;
- for (int i = 0; i < 10; i++) {
- if (!root_view->wheel_scroll_latching_enabled())
- scroll_observer->Reset(0, 1);
+ for (int i = 0; i < 10; i++)
rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- if (!root_view->wheel_scroll_latching_enabled())
- scroll_observer->Wait();
- }
- // Send a wheel end event to complete the scrolling sequence when wheel scroll
- // latching is enabled.
- if (root_view->wheel_scroll_latching_enabled()) {
- scroll_event.delta_y = 0.0f;
- scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
- rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- scroll_observer->Wait();
- }
+ // Send a wheel end event to complete the scrolling sequence.
+ scroll_event.delta_y = 0.0f;
+ scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
+ rwhv_nested->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
+ scroll_observer->Wait();
}
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_MACOSX)
// Flaky: https://crbug.com/836200.
+// Flaky timeouts on Mac: https://crbug.com/863971.
#define MAYBE_ScrollBubblingFromOOPIFWithBodyOverflowHidden \
DISABLED_ScrollBubblingFromOOPIFWithBodyOverflowHidden
#else
@@ -1792,13 +1772,14 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
GURL url_domain_a(embedded_test_server()->GetURL(
"a.com", "/scrollable_page_with_iframe.html"));
EXPECT_TRUE(NavigateToURL(shell(), url_domain_a));
+ RenderFrameSubmissionObserver frame_observer(shell()->web_contents());
FrameTreeNode* root = web_contents()->GetFrameTree()->root();
FrameTreeNode* iframe_node = root->child_at(0);
GURL url_domain_b(
embedded_test_server()->GetURL("b.com", "/body_overflow_hidden.html"));
NavigateFrameToURL(iframe_node, url_domain_b);
- WaitForChildFrameSurfaceReady(iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(iframe_node->current_frame_host());
RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
root->current_frame_host()->GetRenderWidgetHost()->GetView());
@@ -1816,7 +1797,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
blink::WebInputEvent::GetStaticTimeStampForTests());
gfx::Rect bounds = child_view->GetViewBounds();
- float scale_factor = GetPageScaleFactor(shell());
+ float scale_factor =
+ frame_observer.LastRenderFrameMetadata().page_scale_factor;
scroll_event.SetPositionInWidget(
gfx::ToCeiledInt((bounds.x() - root_view->GetViewBounds().x() + 10) *
scale_factor),
@@ -1828,13 +1810,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
scroll_event.has_precise_scrolling_deltas = true;
child_view->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- // Send a wheel end event to complete the scrolling sequence when wheel scroll
- // latching is enabled.
- if (root_view->wheel_scroll_latching_enabled()) {
- scroll_event.delta_y = 0.0f;
- scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
- child_view->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- }
+ // Send a wheel end event to complete the scrolling sequence.
+ scroll_event.delta_y = 0.0f;
+ scroll_event.phase = blink::WebMouseWheelEvent::kPhaseEnded;
+ child_view->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
scroll_observer.Wait();
}
@@ -1878,7 +1857,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, ScrollLocalSubframeInOOPIF) {
->GetRenderWidgetHost()
->GetView());
- WaitForChildFrameSurfaceReady(parent_iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(
+ parent_iframe_node->current_frame_host());
// When we scroll the inner frame, we should have the GSB be consumed.
// The outer iframe not being scrollable should not cause the GSB to go
@@ -2207,19 +2187,12 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CompositorFrameSwapped) {
EXPECT_EQ(site_url, child_node->current_url());
EXPECT_NE(shell()->web_contents()->GetSiteInstance(),
child_node->current_frame_host()->GetSiteInstance());
- RenderWidgetHostViewBase* rwhv_base = static_cast<RenderWidgetHostViewBase*>(
- child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
-
- // Wait for OnSwapCompositorFrame message.
- while (rwhv_base->RendererFrameNumber() <= 0) {
- // TODO(lazyboy): Find a better way to avoid sleeping like this. See
- // http://crbug.com/405282 for details.
- base::RunLoop run_loop;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, run_loop.QuitClosure(),
- base::TimeDelta::FromMilliseconds(10));
- run_loop.Run();
- }
+ // Wait for CompositorFrame submission.
+ RenderFrameSubmissionObserver observer(
+ child_node->current_frame_host()
+ ->GetRenderWidgetHost()
+ ->render_frame_metadata_provider());
+ observer.WaitForAnyFrameSubmission();
}
// Ensure that OOPIFs are deleted after navigating to a new main frame.
@@ -5530,8 +5503,15 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// navigation is initiated before the first page receives the SwapOut ACK.
// Ensure that this doesn't crash and that the RVH(A) is not reused in that
// case.
+#if defined(OS_MACOSX)
+#define MAYBE_RenderViewHostIsNotReusedAfterDelayedSwapOutACK \
+ DISABLED_RenderViewHostIsNotReusedAfterDelayedSwapOutACK
+#else
+#define MAYBE_RenderViewHostIsNotReusedAfterDelayedSwapOutACK \
+ RenderViewHostIsNotReusedAfterDelayedSwapOutACK
+#endif
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
- RenderViewHostIsNotReusedAfterDelayedSwapOutACK) {
+ MAYBE_RenderViewHostIsNotReusedAfterDelayedSwapOutACK) {
GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
EXPECT_TRUE(NavigateToURL(shell(), a_url));
@@ -6343,54 +6323,6 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, CSSVisibilityChanged) {
}
}
-// A class which counts the number of times a RenderWidgetHostViewChildFrame
-// swaps compositor frames.
-class ChildFrameCompositorFrameSwapCounter {
- public:
- explicit ChildFrameCompositorFrameSwapCounter(
- RenderWidgetHostViewChildFrame* view)
- : view_(view), weak_factory_(this) {
- RegisterCallback();
- }
-
- ~ChildFrameCompositorFrameSwapCounter() {}
-
- // Wait until at least |count| new frames are swapped.
- void WaitForNewFrames(size_t count) {
- while (counter_ < count) {
- base::RunLoop loop;
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, loop.QuitClosure(), TestTimeouts::tiny_timeout());
- loop.Run();
- }
- }
-
- void ResetCounter() { counter_ = 0; }
- size_t GetCount() const { return counter_; }
-
- private:
- void RegisterCallback() {
- view_->RegisterFrameSwappedCallback(
- base::BindOnce(&ChildFrameCompositorFrameSwapCounter::OnFrameSwapped,
- weak_factory_.GetWeakPtr()));
- }
-
- void OnFrameSwapped() {
- counter_++;
-
- // Register a new callback as the old one is released now.
- RegisterCallback();
- }
-
- size_t counter_ = 0;
-
- private:
- RenderWidgetHostViewChildFrame* view_;
- base::WeakPtrFactory<ChildFrameCompositorFrameSwapCounter> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(ChildFrameCompositorFrameSwapCounter);
-};
-
// This test verifies that hiding an OOPIF in CSS will stop generating
// compositor frames for the OOPIF and any nested OOPIFs inside it. This holds
// even when the whole page is shown.
@@ -6439,24 +6371,28 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
static_cast<RenderWidgetHostViewChildFrame*>(
root->child_at(0)->child_at(0)->current_frame_host()->GetView());
- ChildFrameCompositorFrameSwapCounter first_counter(first_child_view);
- ChildFrameCompositorFrameSwapCounter second_counter(second_child_view);
- ChildFrameCompositorFrameSwapCounter third_counter(nested_child_view);
+ RenderFrameSubmissionObserver first_frame_counter(
+ first_child_view->host_->render_frame_metadata_provider());
+ RenderFrameSubmissionObserver second_frame_counter(
+ second_child_view->host_->render_frame_metadata_provider());
+ RenderFrameSubmissionObserver third_frame_counter(
+ nested_child_view->host_->render_frame_metadata_provider());
- const size_t kFrameCountLimit = 20u;
+ const int kFrameCountLimit = 20;
// Wait for a minimum number of compositor frames for the second frame.
- second_counter.WaitForNewFrames(kFrameCountLimit);
- ASSERT_LE(kFrameCountLimit, second_counter.GetCount());
+ while (second_frame_counter.render_frame_count() < kFrameCountLimit)
+ second_frame_counter.WaitForAnyFrameSubmission();
+ ASSERT_LE(kFrameCountLimit, second_frame_counter.render_frame_count());
// Now make sure all frames have roughly the counter value in the sense that
// no counter value is more than twice any other.
- float ratio = static_cast<float>(first_counter.GetCount()) /
- static_cast<float>(second_counter.GetCount());
+ float ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
+ static_cast<float>(second_frame_counter.render_frame_count());
EXPECT_GT(2.5f, ratio + 1 / ratio) << "Ratio is: " << ratio;
- ratio = static_cast<float>(first_counter.GetCount()) /
- static_cast<float>(third_counter.GetCount());
+ ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
+ static_cast<float>(third_frame_counter.render_frame_count());
EXPECT_GT(2.5f, ratio + 1 / ratio) << "Ratio is: " << ratio;
// Make sure all views can become visible.
@@ -6485,21 +6421,22 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
shell()->web_contents()->WasHidden();
shell()->web_contents()->WasShown();
- first_counter.ResetCounter();
- second_counter.ResetCounter();
- third_counter.ResetCounter();
+ first_frame_counter.ResetCounter();
+ second_frame_counter.ResetCounter();
+ third_frame_counter.ResetCounter();
// We expect the second counter to keep running.
- second_counter.WaitForNewFrames(kFrameCountLimit);
- ASSERT_LT(kFrameCountLimit, second_counter.GetCount() + 1u);
+ while (second_frame_counter.render_frame_count() < kFrameCountLimit)
+ second_frame_counter.WaitForAnyFrameSubmission();
+ ASSERT_LT(kFrameCountLimit, second_frame_counter.render_frame_count() + 1);
// Verify that the counter for other two frames did not count much.
- ratio = static_cast<float>(first_counter.GetCount()) /
- static_cast<float>(second_counter.GetCount());
+ ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
+ static_cast<float>(second_frame_counter.render_frame_count());
EXPECT_GT(0.5f, ratio) << "Ratio is: " << ratio;
- ratio = static_cast<float>(third_counter.GetCount()) /
- static_cast<float>(second_counter.GetCount());
+ ratio = static_cast<float>(third_frame_counter.render_frame_count()) /
+ static_cast<float>(second_frame_counter.render_frame_count());
EXPECT_GT(0.5f, ratio) << "Ratio is: " << ratio;
}
@@ -6555,19 +6492,22 @@ IN_PROC_BROWSER_TEST_F(
EXPECT_FALSE(first_child_view->CanBecomeVisible());
- ChildFrameCompositorFrameSwapCounter first_counter(first_child_view);
- ChildFrameCompositorFrameSwapCounter second_counter(second_child_view);
+ RenderFrameSubmissionObserver first_frame_counter(
+ first_child_view->host_->render_frame_metadata_provider());
+ RenderFrameSubmissionObserver second_frame_counter(
+ second_child_view->host_->render_frame_metadata_provider());
- const size_t kFrameCountLimit = 20u;
+ const int kFrameCountLimit = 20;
// Wait for a certain number of swapped compositor frames generated for the
// second child view. During the same interval the first frame should not have
// swapped any compositor frames.
- second_counter.WaitForNewFrames(kFrameCountLimit);
- ASSERT_LT(kFrameCountLimit, second_counter.GetCount() + 1u);
+ while (second_frame_counter.render_frame_count() < kFrameCountLimit)
+ second_frame_counter.WaitForAnyFrameSubmission();
+ ASSERT_LT(kFrameCountLimit, second_frame_counter.render_frame_count() + 1);
- float ratio = static_cast<float>(first_counter.GetCount()) /
- static_cast<float>(second_counter.GetCount());
+ float ratio = static_cast<float>(first_frame_counter.render_frame_count()) /
+ static_cast<float>(second_frame_counter.render_frame_count());
EXPECT_GT(0.5f, ratio) << "Ratio is: " << ratio;
}
@@ -7397,20 +7337,25 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
EXPECT_FALSE(rvh->is_swapped_out_);
}
-// Helper class to wait for a ShutdownRequest message to arrive, in response to
-// which RenderProcessWillExit is called on observers by RenderProcessHost.
+// Helper class to wait for a ShutdownRequest message to arrive.
class ShutdownObserver : public RenderProcessHostObserver {
public:
ShutdownObserver() : message_loop_runner_(new MessageLoopRunner) {}
void RenderProcessShutdownRequested(RenderProcessHost* host) override {
+ has_received_shutdown_request_ = true;
message_loop_runner_->Quit();
}
void Wait() { message_loop_runner_->Run(); }
+ bool has_received_shutdown_request() {
+ return has_received_shutdown_request_;
+ }
+
private:
scoped_refptr<MessageLoopRunner> message_loop_runner_;
+ bool has_received_shutdown_request_ = false;
DISALLOW_COPY_AND_ASSIGN(ShutdownObserver);
};
@@ -7500,8 +7445,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
}
// Ensures that navigating to data: URLs present in session history will
-// correctly commit the navigation in the same process as the parent frame.
-// See https://crbug.com/606996.
+// correctly commit the navigation in the same process as the one used for the
+// original navigation. See https://crbug.com/606996.
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
NavigateSubframeToDataUrlInSessionHistory) {
GURL main_url(embedded_test_server()->GetURL(
@@ -7527,7 +7472,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
EXPECT_TRUE(observer.last_navigation_succeeded());
EXPECT_EQ(data_url, observer.last_navigation_url());
scoped_refptr<SiteInstanceImpl> orig_site_instance =
- child->current_frame_host()->GetSiteInstance();
+ child->current_frame_host()->GetSiteInstance();
EXPECT_NE(root->current_frame_host()->GetSiteInstance(), orig_site_instance);
// Navigate it to another cross-site url.
@@ -7547,6 +7492,286 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
EXPECT_EQ(orig_site_instance, child->current_frame_host()->GetSiteInstance());
}
+// Ensures that subframes navigated to data: URLs start in a process based on
+// their creator, but end up in unique processes after a restore (since
+// SiteInstance relationships are not preserved on restore, until
+// https://crbug.com/14987 is fixed). This is better than restoring into the
+// parent process, per https://crbug.com/863069.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ SubframeDataUrlsAfterRestore) {
+ // We must use a page that has iframes in the HTML here, unlike
+ // cross_site_iframe_factory.html which loads them dynamically. In the latter
+ // case, Chrome will not restore subframe URLs from history, which is needed
+ // for this test.
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/frame_tree/page_with_two_iframes.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+ EXPECT_EQ(2U, root->child_count());
+ EXPECT_EQ(
+ " Site A ------------ proxies for B C\n"
+ " |--Site B ------- proxies for A C\n"
+ " +--Site C ------- proxies for A B\n"
+ "Where A = http://a.com/\n"
+ " B = http://bar.com/\n"
+ " C = http://baz.com/",
+ DepictFrameTree(root));
+
+ FrameTreeNode* child_0 = root->child_at(0);
+ FrameTreeNode* child_1 = root->child_at(1);
+ scoped_refptr<SiteInstanceImpl> child_site_instance_0 =
+ child_0->current_frame_host()->GetSiteInstance();
+ scoped_refptr<SiteInstanceImpl> child_site_instance_1 =
+ child_1->current_frame_host()->GetSiteInstance();
+
+ // Navigate the iframes to data URLs via renderer initiated navigations, which
+ // will commit in the existing SiteInstances.
+ TestNavigationObserver observer(shell()->web_contents());
+ GURL data_url_0("data:text/html,dataurl_0");
+ {
+ TestFrameNavigationObserver commit_observer(child_0);
+ EXPECT_TRUE(
+ ExecuteScript(child_0, "location.href = '" + data_url_0.spec() + "';"));
+ commit_observer.WaitForCommit();
+ }
+ EXPECT_TRUE(observer.last_navigation_succeeded());
+ EXPECT_EQ(data_url_0, observer.last_navigation_url());
+ EXPECT_EQ(child_site_instance_0,
+ child_0->current_frame_host()->GetSiteInstance());
+
+ GURL data_url_1("data:text/html,dataurl_1");
+ {
+ TestFrameNavigationObserver commit_observer(child_1);
+ EXPECT_TRUE(
+ ExecuteScript(child_1, "location.href = '" + data_url_1.spec() + "';"));
+ commit_observer.WaitForCommit();
+ }
+ EXPECT_TRUE(observer.last_navigation_succeeded());
+ EXPECT_EQ(data_url_1, observer.last_navigation_url());
+ EXPECT_EQ(child_site_instance_1,
+ child_1->current_frame_host()->GetSiteInstance());
+
+ // Grab the NavigationEntry and clone its PageState into a new entry for
+ // restoring into a new tab.
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+ NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
+ std::unique_ptr<NavigationEntryImpl> restored_entry =
+ NavigationEntryImpl::FromNavigationEntry(
+ NavigationController::CreateNavigationEntry(
+ main_url, Referrer(), ui::PAGE_TRANSITION_RELOAD, false,
+ std::string(), controller.GetBrowserContext(),
+ nullptr /* blob_url_loader_factory */));
+ EXPECT_EQ(0U, restored_entry->root_node()->children.size());
+ restored_entry->SetPageState(entry->GetPageState());
+ ASSERT_EQ(2U, restored_entry->root_node()->children.size());
+
+ // Restore the NavigationEntry into a new tab and check that the data URLs are
+ // not loaded into the parent's SiteInstance.
+ std::vector<std::unique_ptr<NavigationEntry>> entries;
+ entries.push_back(std::move(restored_entry));
+ Shell* new_shell = Shell::CreateNewWindow(
+ controller.GetBrowserContext(), GURL::EmptyGURL(), nullptr, gfx::Size());
+ FrameTreeNode* new_root =
+ static_cast<WebContentsImpl*>(new_shell->web_contents())
+ ->GetFrameTree()
+ ->root();
+ NavigationControllerImpl& new_controller =
+ static_cast<NavigationControllerImpl&>(
+ new_shell->web_contents()->GetController());
+ new_controller.Restore(entries.size() - 1,
+ RestoreType::LAST_SESSION_EXITED_CLEANLY, &entries);
+ ASSERT_EQ(0u, entries.size());
+ {
+ TestNavigationObserver restore_observer(new_shell->web_contents());
+ new_controller.LoadIfNecessary();
+ restore_observer.Wait();
+ }
+ ASSERT_EQ(2U, new_root->child_count());
+ EXPECT_EQ(main_url, new_root->current_url());
+ EXPECT_EQ("data", new_root->child_at(0)->current_url().scheme());
+ EXPECT_EQ("data", new_root->child_at(1)->current_url().scheme());
+
+ EXPECT_NE(new_root->current_frame_host()->GetSiteInstance(),
+ new_root->child_at(0)->current_frame_host()->GetSiteInstance());
+ EXPECT_NE(new_root->current_frame_host()->GetSiteInstance(),
+ new_root->child_at(1)->current_frame_host()->GetSiteInstance());
+ EXPECT_NE(new_root->child_at(0)->current_frame_host()->GetSiteInstance(),
+ new_root->child_at(1)->current_frame_host()->GetSiteInstance());
+}
+
+// Similar to SubframeDataUrlsAfterRestore, but ensures that about:blank frames
+// do get put into their parent process after restore, even if they weren't
+// originally. This is safe because they do not contain active content (even
+// when there's a fragment in the URL), and it avoids unnecessary OOPIFs.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ SubframeBlankUrlsAfterRestore) {
+ // We must use a page that has iframes in the HTML here, unlike
+ // cross_site_iframe_factory.html which loads them dynamically. In the latter
+ // case, Chrome will not restore subframe URLs from history, which is needed
+ // for this test.
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/frame_tree/page_with_two_iframes.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+ EXPECT_EQ(2U, root->child_count());
+ EXPECT_EQ(
+ " Site A ------------ proxies for B C\n"
+ " |--Site B ------- proxies for A C\n"
+ " +--Site C ------- proxies for A B\n"
+ "Where A = http://a.com/\n"
+ " B = http://bar.com/\n"
+ " C = http://baz.com/",
+ DepictFrameTree(root));
+
+ FrameTreeNode* child_0 = root->child_at(0);
+ FrameTreeNode* child_1 = root->child_at(1);
+ scoped_refptr<SiteInstanceImpl> child_site_instance_0 =
+ child_0->current_frame_host()->GetSiteInstance();
+ scoped_refptr<SiteInstanceImpl> child_site_instance_1 =
+ child_1->current_frame_host()->GetSiteInstance();
+
+ // Navigate the iframes to about:blank URLs via renderer initiated
+ // navigations, which will commit in the existing SiteInstances.
+ TestNavigationObserver observer(shell()->web_contents());
+ GURL blank_url("about:blank");
+ {
+ TestFrameNavigationObserver commit_observer(child_0);
+ EXPECT_TRUE(
+ ExecuteScript(child_0, "location.href = '" + blank_url.spec() + "';"));
+ commit_observer.WaitForCommit();
+ }
+ EXPECT_TRUE(observer.last_navigation_succeeded());
+ EXPECT_EQ(blank_url, observer.last_navigation_url());
+ EXPECT_EQ(child_site_instance_0,
+ child_0->current_frame_host()->GetSiteInstance());
+
+ GURL blank_url_ref("about:blank#1");
+ {
+ TestFrameNavigationObserver commit_observer(child_1);
+ EXPECT_TRUE(ExecuteScript(
+ child_1, "location.href = '" + blank_url_ref.spec() + "';"));
+ commit_observer.WaitForCommit();
+ }
+ EXPECT_TRUE(observer.last_navigation_succeeded());
+ EXPECT_EQ(blank_url_ref, observer.last_navigation_url());
+ EXPECT_EQ(child_site_instance_1,
+ child_1->current_frame_host()->GetSiteInstance());
+
+ // Grab the NavigationEntry and clone its PageState into a new entry for
+ // restoring into a new tab.
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+ NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
+ std::unique_ptr<NavigationEntryImpl> restored_entry =
+ NavigationEntryImpl::FromNavigationEntry(
+ NavigationController::CreateNavigationEntry(
+ main_url, Referrer(), ui::PAGE_TRANSITION_RELOAD, false,
+ std::string(), controller.GetBrowserContext(),
+ nullptr /* blob_url_loader_factory */));
+ EXPECT_EQ(0U, restored_entry->root_node()->children.size());
+ restored_entry->SetPageState(entry->GetPageState());
+ ASSERT_EQ(2U, restored_entry->root_node()->children.size());
+
+ // Restore the NavigationEntry into a new tab and check that the data URLs are
+ // not loaded into the parent's SiteInstance.
+ std::vector<std::unique_ptr<NavigationEntry>> entries;
+ entries.push_back(std::move(restored_entry));
+ Shell* new_shell = Shell::CreateNewWindow(
+ controller.GetBrowserContext(), GURL::EmptyGURL(), nullptr, gfx::Size());
+ FrameTreeNode* new_root =
+ static_cast<WebContentsImpl*>(new_shell->web_contents())
+ ->GetFrameTree()
+ ->root();
+ NavigationControllerImpl& new_controller =
+ static_cast<NavigationControllerImpl&>(
+ new_shell->web_contents()->GetController());
+ new_controller.Restore(entries.size() - 1,
+ RestoreType::LAST_SESSION_EXITED_CLEANLY, &entries);
+ ASSERT_EQ(0u, entries.size());
+ {
+ TestNavigationObserver restore_observer(new_shell->web_contents());
+ new_controller.LoadIfNecessary();
+ restore_observer.Wait();
+ }
+ ASSERT_EQ(2U, new_root->child_count());
+ EXPECT_EQ(main_url, new_root->current_url());
+ EXPECT_TRUE(new_root->child_at(0)->current_url().IsAboutBlank());
+ EXPECT_TRUE(new_root->child_at(1)->current_url().IsAboutBlank());
+
+ EXPECT_EQ(new_root->current_frame_host()->GetSiteInstance(),
+ new_root->child_at(0)->current_frame_host()->GetSiteInstance());
+ EXPECT_EQ(new_root->current_frame_host()->GetSiteInstance(),
+ new_root->child_at(1)->current_frame_host()->GetSiteInstance());
+}
+
+// Similar to SubframeBlankUrlsAfterRestore, but ensures that about:srcdoc ends
+// up in its parent's process after restore, since that's where its content
+// comes from.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ SubframeSrcdocUrlAfterRestore) {
+ // Load a page that uses iframe srcdoc.
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/frame_tree/page_with_srcdoc_frame.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+ EXPECT_EQ(1U, root->child_count());
+ FrameTreeNode* child = root->child_at(0);
+ scoped_refptr<SiteInstanceImpl> child_site_instance =
+ child->current_frame_host()->GetSiteInstance();
+ EXPECT_EQ(child_site_instance, root->current_frame_host()->GetSiteInstance());
+
+ // Grab the NavigationEntry and clone its PageState into a new entry for
+ // restoring into a new tab.
+ const NavigationControllerImpl& controller =
+ static_cast<const NavigationControllerImpl&>(
+ shell()->web_contents()->GetController());
+ NavigationEntryImpl* entry = controller.GetLastCommittedEntry();
+ std::unique_ptr<NavigationEntryImpl> restored_entry =
+ NavigationEntryImpl::FromNavigationEntry(
+ NavigationController::CreateNavigationEntry(
+ main_url, Referrer(), ui::PAGE_TRANSITION_RELOAD, false,
+ std::string(), controller.GetBrowserContext(),
+ nullptr /* blob_url_loader_factory */));
+ EXPECT_EQ(0U, restored_entry->root_node()->children.size());
+ restored_entry->SetPageState(entry->GetPageState());
+ ASSERT_EQ(1U, restored_entry->root_node()->children.size());
+
+ // Restore the NavigationEntry into a new tab and check that the srcdoc URLs
+ // are still loaded into the parent's SiteInstance.
+ std::vector<std::unique_ptr<NavigationEntry>> entries;
+ entries.push_back(std::move(restored_entry));
+ Shell* new_shell = Shell::CreateNewWindow(
+ controller.GetBrowserContext(), GURL::EmptyGURL(), nullptr, gfx::Size());
+ FrameTreeNode* new_root =
+ static_cast<WebContentsImpl*>(new_shell->web_contents())
+ ->GetFrameTree()
+ ->root();
+ NavigationControllerImpl& new_controller =
+ static_cast<NavigationControllerImpl&>(
+ new_shell->web_contents()->GetController());
+ new_controller.Restore(entries.size() - 1,
+ RestoreType::LAST_SESSION_EXITED_CLEANLY, &entries);
+ ASSERT_EQ(0u, entries.size());
+ {
+ TestNavigationObserver restore_observer(new_shell->web_contents());
+ new_controller.LoadIfNecessary();
+ restore_observer.Wait();
+ }
+ ASSERT_EQ(1U, new_root->child_count());
+ EXPECT_EQ(main_url, new_root->current_url());
+ EXPECT_EQ(GURL(content::kAboutSrcDocURL),
+ new_root->child_at(0)->current_url());
+
+ EXPECT_EQ(new_root->current_frame_host()->GetSiteInstance(),
+ new_root->child_at(0)->current_frame_host()->GetSiteInstance());
+}
+
// Ensures that navigating to about:blank URLs present in session history will
// correctly commit the navigation in the same process as the one used for
// the original navigation.
@@ -8082,8 +8307,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
child->current_frame_host()->GetView(),
proxy_to_parent->cross_process_frame_connector()->get_view_for_testing());
- // Make sure that the child frame has submitted a compositor frame.
- WaitForChildFrameSurfaceReady(child->current_frame_host());
+ // Make sure that the child frame has submitted a compositor frame
+ RenderFrameSubmissionObserver frame_observer(child);
+ frame_observer.WaitForMetadataChange();
// Send a postMessage from the child to its parent. This verifies that the
// parent's proxy in the child's SiteInstance was also restored.
@@ -9587,8 +9813,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// 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,
- CrossProcessMainFrameNavigationDoesNotOverwriteHistory) {
+IN_PROC_BROWSER_TEST_F(
+ SitePerProcessBrowserTest,
+ DISABLED_CrossProcessMainFrameNavigationDoesNotOverwriteHistory) {
GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title2.html"));
@@ -9917,7 +10144,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
manager1.WaitForNavigationFinished();
// Make sure the process is live and at the new URL.
- EXPECT_TRUE(b_site_instance->GetProcess()->HasConnection());
+ EXPECT_TRUE(b_site_instance->GetProcess()->IsInitializedAndNotDead());
EXPECT_TRUE(root->current_frame_host()->IsRenderFrameLive());
EXPECT_EQ(root_speculative_rfh, root->current_frame_host());
EXPECT_EQ(new_url_1, root->current_frame_host()->GetLastCommittedURL());
@@ -10009,7 +10236,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
manager2.WaitForNavigationFinished();
// Make sure the process is live and at the new URL.
- EXPECT_TRUE(b_site_instance->GetProcess()->HasConnection());
+ EXPECT_TRUE(b_site_instance->GetProcess()->IsInitializedAndNotDead());
ASSERT_EQ(2U, root->child_count());
EXPECT_TRUE(child->current_frame_host()->IsRenderFrameLive());
EXPECT_EQ(child_speculative_rfh, child->current_frame_host());
@@ -10402,7 +10629,7 @@ IN_PROC_BROWSER_TEST_F(TouchSelectionControllerClientAndroidSiteIsolationTest,
// The child will change with the cross-site navigation. It shouldn't change
// after this.
child = root->child_at(0);
- WaitForChildFrameSurfaceReady(child->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child->current_frame_host());
RenderWidgetHostViewChildFrame* child_view =
static_cast<RenderWidgetHostViewChildFrame*>(
@@ -11061,7 +11288,7 @@ class CommitMessageOrderReverser : public DidCommitProvisionalLoadInterceptor {
void WaitForBothCommits() { outer_run_loop.Run(); }
protected:
- void WillDispatchDidCommitProvisionalLoad(
+ bool WillDispatchDidCommitProvisionalLoad(
RenderFrameHost* render_frame_host,
::FrameHostMsg_DidCommitProvisionalLoad_Params* params,
service_manager::mojom::InterfaceProviderRequest*
@@ -11080,6 +11307,7 @@ class CommitMessageOrderReverser : public DidCommitProvisionalLoadInterceptor {
} else if (nested_loop_quit_) {
std::move(nested_loop_quit_).Run();
}
+ return true;
}
private:
@@ -11210,7 +11438,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
DepictFrameTree(root));
FrameTreeNode* nested_child = root->child_at(0)->child_at(0);
- WaitForChildFrameSurfaceReady(nested_child->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(nested_child->current_frame_host());
EXPECT_TRUE(
ExecuteScript(nested_child->current_frame_host(), "startTest();"));
@@ -11442,8 +11670,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
popup_child->current_frame_host()->GetView());
// Make sure the child frame keeps generating compositor frames.
- ChildFrameCompositorFrameSwapCounter counter(child_view);
- counter.WaitForNewFrames(10u);
+ RenderFrameSubmissionObserver frame_counter(
+ child_view->host_->render_frame_metadata_provider());
+ while (frame_counter.render_frame_count() < 10)
+ frame_counter.WaitForAnyFrameSubmission();
}
IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, FrameDepthSimple) {
@@ -11702,6 +11932,72 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
EXPECT_EQ(start_url, rfh->GetLastCommittedURL());
}
+namespace {
+
+// A helper class that watches for SwapOut ACK messages, allowing them
+// to go through but remembering that the message was received. It also
+// watches for any ShutdownRequests coming from the renderer and ensures that
+// the SwapOut ACK is received prior to those.
+class SwapoutACKReceivedFilter : public BrowserMessageFilter {
+ public:
+ explicit SwapoutACKReceivedFilter(RenderProcessHost* process)
+ : BrowserMessageFilter(FrameMsgStart) {
+ process->AddObserver(&shutdown_observer_);
+ process->AddFilter(this);
+ }
+
+ bool has_received_swapout_ack() { return received_; }
+
+ protected:
+ ~SwapoutACKReceivedFilter() override {}
+
+ private:
+ // BrowserMessageFilter:
+ bool OnMessageReceived(const IPC::Message& message) override {
+ if (message.type() == FrameHostMsg_SwapOut_ACK::ID) {
+ // This ensures that the SwapOut ACK arrived before any
+ // renderer-initiated process shutdown requests.
+ EXPECT_FALSE(shutdown_observer_.has_received_shutdown_request())
+ << " Shutdown request should be received after the swapout ACK";
+ received_ = true;
+ }
+ return false;
+ }
+
+ bool received_ = false;
+ ShutdownObserver shutdown_observer_;
+ DISALLOW_COPY_AND_ASSIGN(SwapoutACKReceivedFilter);
+};
+
+} // namespace
+
+// Verify that when the last active frame in a process is going away as part of
+// OnSwapOut, the SwapOut ACK is received prior to the process starting to shut
+// down, ensuring that any related unload work also happens before shutdown.
+// See https://crbug.com/867274 and https://crbug.com/794625.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ SwapOutACKArrivesPriorToProcessShutdownRequest) {
+ GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), start_url));
+ RenderFrameHostImpl* rfh = web_contents()->GetMainFrame();
+ rfh->DisableSwapOutTimerForTesting();
+
+ // Navigate cross-site. Since the current frame is the last active frame in
+ // the current process, the process will eventually shut down. Once the
+ // process goes away, ensure that the SwapOut ACK was received (i.e., that we
+ // didn't just simulate OnSwappedOut() due to the process erroneously going
+ // away before the SwapOut ACK was received, as in https://crbug.com/867274).
+ RenderProcessHostWatcher watcher(
+ rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+ scoped_refptr<SwapoutACKReceivedFilter> swapout_ack_filter =
+ new SwapoutACKReceivedFilter(rfh->GetProcess());
+ GURL cross_site_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
+ EXPECT_TRUE(NavigateToURLFromRenderer(shell(), cross_site_url));
+ watcher.Wait();
+ EXPECT_TRUE(swapout_ack_filter->has_received_swapout_ack());
+ EXPECT_TRUE(watcher.did_exit_normally());
+}
+
// Class to monitor incoming FrameHostMsg_UpdateViewportIntersection messages.
class UpdateViewportIntersectionMessageFilter
: public content::BrowserMessageFilter {
@@ -11903,7 +12199,9 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
// Verify that OOPIF select element popup menu coordinates account for scroll
// offset in containers embedding frame.
-IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, PopupMenuInTallIframeTest) {
+// TODO(crbug.com/859552): Reenable this.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ DISABLED_PopupMenuInTallIframeTest) {
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_tall_positioned_frame.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -11972,7 +12270,7 @@ class ClosePageBeforeCommitHelper : public DidCommitProvisionalLoadInterceptor {
private:
// DidCommitProvisionalLoadInterceptor:
- void WillDispatchDidCommitProvisionalLoad(
+ bool WillDispatchDidCommitProvisionalLoad(
RenderFrameHost* render_frame_host,
::FrameHostMsg_DidCommitProvisionalLoad_Params* params,
service_manager::mojom::InterfaceProviderRequest*
@@ -11983,6 +12281,7 @@ class ClosePageBeforeCommitHelper : public DidCommitProvisionalLoadInterceptor {
rvh->ClosePage();
if (run_loop_)
run_loop_->Quit();
+ return true;
}
std::unique_ptr<base::RunLoop> run_loop_;
@@ -12063,7 +12362,7 @@ class SitePerProcessBrowserTouchActionTest : public SitePerProcessBrowserTest {
router->RouteTouchEvent(rwhv_root, &touch_event,
ui::LatencyInfo(ui::SourceEventType::TOUCH));
ack_observer.Wait();
- cc::TouchAction touch_action =
+ base::Optional<cc::TouchAction> touch_action =
static_cast<RenderWidgetHostImpl*>(rwhv_child->GetRenderWidgetHost())
->input_router()
->AllowedTouchAction();
@@ -12081,24 +12380,28 @@ class SitePerProcessBrowserTouchActionTest : public SitePerProcessBrowserTest {
router->RouteTouchEvent(rwhv_root, &touch_event,
ui::LatencyInfo(ui::SourceEventType::TOUCH));
ack_observer.Wait();
- return touch_action;
+ return touch_action.has_value() ? touch_action.value()
+ : cc::kTouchActionAuto;
}
// Waits until the parent frame has had enough time to propagate the effective
// touch action to the child frame and the child frame has had enough time to
// process it.
- void WaitForTouchActionUpdated(MainThreadFrameObserver* observer,
- content::RenderFrameHost* child_frame) {
- // Ensures that main frame has calculated the new effective touch action for
- // child frames.
- observer->Wait();
- // Ensures that if a child frame is in progress we will wait until the next
- // one.
- WaitForChildFrameSurfaceReady(child_frame);
- // This child frame should receive the effective touch action from parent
- // (if the previous one didn't) and propagates it.
- WaitForChildFrameSurfaceReady(child_frame);
- observer->Wait();
+ void WaitForTouchActionUpdated(
+ MainThreadFrameObserver* root_thread_observer,
+ MainThreadFrameObserver* child_thread_observer) {
+ // Sends an event to the root frame's renderer main thread, upon return the
+ // root frame should have calculated the new effective touch action for the
+ // child frame.
+ root_thread_observer->Wait();
+ // Sends an event to the child frame's renderer main thread, upon return the
+ // child frame should have received the effective touch action from parent
+ // and propagated it.
+ child_thread_observer->Wait();
+ // The child's handling of the touch action may lead to further propagation
+ // back to the parent. This sends an event to the root frame's renderer main
+ // thread, upon return it should have handled any touch action update.
+ root_thread_observer->Wait();
}
};
@@ -12113,9 +12416,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
root->current_frame_host()->GetRenderWidgetHost()->GetView());
RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
child->current_frame_host()->GetRenderWidgetHost()->GetView());
- std::unique_ptr<MainThreadFrameObserver> observer(new MainThreadFrameObserver(
- root->current_frame_host()->GetRenderWidgetHost()));
- observer->Wait();
+ std::unique_ptr<MainThreadFrameObserver> root_thread_observer(
+ new MainThreadFrameObserver(
+ root->current_frame_host()->GetRenderWidgetHost()));
+ root_thread_observer->Wait();
GURL b_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
NavigateFrameToURL(child, b_url);
@@ -12124,7 +12428,10 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
EXPECT_TRUE(
ExecuteScript(shell(), "document.body.style.touchAction = 'none'"));
// Waits for the next frame.
- WaitForChildFrameSurfaceReady(child->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child->current_frame_host());
+ std::unique_ptr<MainThreadFrameObserver> child_thread_observer(
+ new MainThreadFrameObserver(
+ child->current_frame_host()->GetRenderWidgetHost()));
RenderWidgetHostViewChildFrame* child_view =
static_cast<RenderWidgetHostViewChildFrame*>(
@@ -12135,7 +12442,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
RenderWidgetHostInputEventRouter* router =
static_cast<WebContentsImpl*>(web_contents())->GetInputEventRouter();
- WaitForTouchActionUpdated(observer.get(), child->current_frame_host());
+ WaitForTouchActionUpdated(root_thread_observer.get(),
+ child_thread_observer.get());
// Gestures are filtered by the intersection of touch-action values of the
// touched element and all its ancestors up to the one that implements the
// gesture. Since iframe allows scrolling, touch action pan restrictions will
@@ -12147,7 +12455,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
EXPECT_TRUE(
ExecuteScript(shell(), "document.body.style.touchAction = 'auto'"));
- WaitForTouchActionUpdated(observer.get(), child->current_frame_host());
+ WaitForTouchActionUpdated(root_thread_observer.get(),
+ child_thread_observer.get());
EXPECT_EQ(cc::TouchAction::kTouchActionAuto,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
point_inside_child));
@@ -12180,15 +12489,19 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
root->current_frame_host()->GetRenderWidgetHost()->GetView());
RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
child->current_frame_host()->GetRenderWidgetHost()->GetView());
- std::unique_ptr<MainThreadFrameObserver> observer(new MainThreadFrameObserver(
- root->current_frame_host()->GetRenderWidgetHost()));
- observer->Wait();
+ std::unique_ptr<MainThreadFrameObserver> root_thread_observer(
+ new MainThreadFrameObserver(
+ root->current_frame_host()->GetRenderWidgetHost()));
+ root_thread_observer->Wait();
EXPECT_TRUE(
ExecuteScript(shell(), "document.body.style.touchAction = 'none'"));
// Wait for child frame ready in order to get the correct point inside child.
- WaitForChildFrameSurfaceReady(child->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child->current_frame_host());
+ std::unique_ptr<MainThreadFrameObserver> child_thread_observer(
+ new MainThreadFrameObserver(
+ child->current_frame_host()->GetRenderWidgetHost()));
RenderWidgetHostViewChildFrame* child_view =
static_cast<RenderWidgetHostViewChildFrame*>(
child->current_frame_host()->GetRenderWidgetHost()->GetView());
@@ -12199,7 +12512,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
static_cast<WebContentsImpl*>(web_contents())->GetInputEventRouter();
// Child should inherit effective touch action none from root.
- WaitForTouchActionUpdated(observer.get(), child->current_frame_host());
+ WaitForTouchActionUpdated(root_thread_observer.get(),
+ child_thread_observer.get());
EXPECT_EQ(cc::TouchAction::kTouchActionPan,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
point_inside_child));
@@ -12210,7 +12524,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
EXPECT_TRUE(ExecuteScript(
parent,
"document.getElementById('parent-div').style.touchAction = 'none';"));
- WaitForTouchActionUpdated(observer.get(), child->current_frame_host());
+ WaitForTouchActionUpdated(root_thread_observer.get(),
+ child_thread_observer.get());
EXPECT_EQ(cc::TouchAction::kTouchActionPan,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
point_inside_child));
@@ -12219,7 +12534,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
EXPECT_TRUE(ExecuteScript(
parent,
"document.getElementById('parent-div').style.touchAction = 'auto'"));
- WaitForTouchActionUpdated(observer.get(), child->current_frame_host());
+ WaitForTouchActionUpdated(root_thread_observer.get(),
+ child_thread_observer.get());
EXPECT_EQ(cc::TouchAction::kTouchActionAuto,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
point_inside_child));
@@ -12247,15 +12563,19 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
root->current_frame_host()->GetRenderWidgetHost()->GetView());
RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
child->current_frame_host()->GetRenderWidgetHost()->GetView());
- std::unique_ptr<MainThreadFrameObserver> observer(new MainThreadFrameObserver(
- root->current_frame_host()->GetRenderWidgetHost()));
- observer->Wait();
+ std::unique_ptr<MainThreadFrameObserver> root_thread_observer(
+ new MainThreadFrameObserver(
+ root->current_frame_host()->GetRenderWidgetHost()));
+ root_thread_observer->Wait();
EXPECT_TRUE(
ExecuteScript(shell(), "document.body.style.touchAction = 'none'"));
// Wait for child frame ready in order to get the correct point inside child.
- WaitForChildFrameSurfaceReady(child->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child->current_frame_host());
+ std::unique_ptr<MainThreadFrameObserver> child_thread_observer(
+ new MainThreadFrameObserver(
+ child->current_frame_host()->GetRenderWidgetHost()));
RenderWidgetHostViewChildFrame* child_view =
static_cast<RenderWidgetHostViewChildFrame*>(
child->current_frame_host()->GetRenderWidgetHost()->GetView());
@@ -12265,7 +12585,8 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
RenderWidgetHostInputEventRouter* router =
static_cast<WebContentsImpl*>(web_contents())->GetInputEventRouter();
// Child should inherit effective touch action none from root.
- WaitForTouchActionUpdated(observer.get(), child->current_frame_host());
+ WaitForTouchActionUpdated(root_thread_observer.get(),
+ child_thread_observer.get());
EXPECT_EQ(cc::TouchAction::kTouchActionPan,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
point_inside_child));
@@ -12273,12 +12594,21 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTouchActionTest,
// After navigation, child should still inherit effective touch action none
// from parent.
GURL new_url(embedded_test_server()->GetURL("c.com", "/title2.html"));
+ // Reset before navigation, as navigation destroys the underlying
+ // RenderWidgetHost being observed.
+ child_thread_observer.reset();
NavigateFrameToURL(child, new_url);
- WaitForChildFrameSurfaceReady(child->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child->current_frame_host());
+ // Navigation destroys the previous RenderWidgetHost, so we need to begin
+ // observing the new renderer main thread associated with the child frame.
+ child_thread_observer.reset(new MainThreadFrameObserver(
+ child->current_frame_host()->GetRenderWidgetHost()));
+
rwhv_child = static_cast<RenderWidgetHostViewBase*>(
child->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForTouchActionUpdated(observer.get(), child->current_frame_host());
+ WaitForTouchActionUpdated(root_thread_observer.get(),
+ child_thread_observer.get());
EXPECT_EQ(cc::TouchAction::kTouchActionPan,
GetEffectiveTouchActionForChild(router, rwhv_root, rwhv_child,
point_inside_child));
@@ -12691,4 +13021,131 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
subframe->effective_frame_policy().sandbox_flags);
}
+// Ensure that when two cross-site frames have subframes with unique origins,
+// and those subframes create blob URLs and navigate to them, the blob URLs end
+// up in different processes. See https://crbug.com/863623.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ TwoBlobURLsWithNullOriginDontShareProcess) {
+ GURL main_url(embedded_test_server()->GetURL(
+ "a.com", "/navigation_controller/page_with_data_iframe.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+ FrameTreeNode* subframe = root->child_at(0);
+
+ // Create a blob URL in the subframe, and navigate to it.
+ TestNavigationObserver observer(shell()->web_contents());
+ std::string blob_script =
+ "var blob = new Blob(['foo'], {type : 'text/html'});"
+ "var url = URL.createObjectURL(blob);"
+ "location = url;";
+ EXPECT_TRUE(ExecuteScript(subframe, blob_script));
+ observer.Wait();
+ RenderFrameHostImpl* subframe_rfh = subframe->current_frame_host();
+ EXPECT_TRUE(subframe_rfh->GetLastCommittedURL().SchemeIsBlob());
+
+ // Open a cross-site popup and repeat these steps.
+ GURL popup_url(embedded_test_server()->GetURL(
+ "b.com", "/navigation_controller/page_with_data_iframe.html"));
+ Shell* new_shell = OpenPopup(root, popup_url, "");
+ FrameTreeNode* popup_root =
+ static_cast<WebContentsImpl*>(new_shell->web_contents())
+ ->GetFrameTree()
+ ->root();
+ FrameTreeNode* popup_subframe = popup_root->child_at(0);
+
+ TestNavigationObserver popup_observer(new_shell->web_contents());
+ EXPECT_TRUE(ExecuteScript(popup_subframe, blob_script));
+ popup_observer.Wait();
+ RenderFrameHostImpl* popup_subframe_rfh =
+ popup_subframe->current_frame_host();
+ EXPECT_TRUE(popup_subframe_rfh->GetLastCommittedURL().SchemeIsBlob());
+
+ // Ensure that the two blob subframes don't share a process or SiteInstance.
+ EXPECT_NE(subframe->current_frame_host()->GetSiteInstance(),
+ popup_subframe->current_frame_host()->GetSiteInstance());
+ EXPECT_NE(
+ subframe->current_frame_host()->GetSiteInstance()->GetProcess(),
+ popup_subframe->current_frame_host()->GetSiteInstance()->GetProcess());
+ EXPECT_NE(
+ subframe->current_frame_host()->GetSiteInstance()->GetSiteURL(),
+ popup_subframe->current_frame_host()->GetSiteInstance()->GetSiteURL());
+}
+
+// Ensure that when a process is about to be destroyed after the last active
+// frame in it goes away, an attempt to reuse a proxy in that process doesn't
+// result in a crash. See https://crbug.com/794625.
+IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest,
+ RenderFrameProxyNotRecreatedDuringProcessShutdown) {
+ GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+
+ GURL popup_url(embedded_test_server()->GetURL(
+ "b.com", "/title1.html"));
+ Shell* new_shell = OpenPopup(root, popup_url, "foo");
+ FrameTreeNode* popup_root =
+ static_cast<WebContentsImpl*>(new_shell->web_contents())
+ ->GetFrameTree()
+ ->root();
+ auto* rfh = popup_root->current_frame_host();
+
+ // Disable the swapout timer to prevent flakiness.
+ rfh->DisableSwapOutTimerForTesting();
+
+ // This will be used to monitor that b.com process exits cleanly.
+ RenderProcessHostWatcher b_process_observer(
+ popup_root->current_frame_host()->GetProcess(),
+ RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION);
+
+ // In the first tab, install a postMessage handler to navigate the popup to a
+ // hung b.com URL once the first message is received.
+ GURL hung_b_url(embedded_test_server()->GetURL("b.com", "/hung"));
+ TestNavigationManager manager(new_shell->web_contents(), hung_b_url);
+ EXPECT_TRUE(ExecuteScript(shell(), base::StringPrintf(R"(
+ window.done = false;
+ window.onmessage = () => {
+ if (!window.done) {
+ window.open('%s', 'foo');
+ window.done = true;
+ }
+ };)", hung_b_url.spec().c_str())));
+
+ // In the popup, install an unload handler to send a lot of postMessages to
+ // the opener. This keeps the MessageLoop in the b.com process busy after
+ // navigating away from the current document. In https://crbug.com/794625,
+ // this was needed so that a subsequent IPC to recreate a proxy arrives
+ // before the process fully shuts down.
+ EXPECT_TRUE(ExecuteScript(new_shell, R"(
+ window.onunload = () => {
+ for (var i=0; i<10000; i++)
+ opener.postMessage('hi','*');
+ })"));
+
+ // Navigate popup to a.com. This swaps out the last active frame in the
+ // b.com process, and hence initiates process shutdown.
+ TestFrameNavigationObserver commit_observer(popup_root);
+ GURL another_a_url(embedded_test_server()->GetURL("a.com", "/title3.html"));
+ EXPECT_TRUE(ExecuteScript(
+ new_shell,
+ base::StringPrintf("location = '%s';", another_a_url.spec().c_str())));
+ commit_observer.WaitForCommit();
+
+ // At this point, popup's original RFH is pending deletion.
+ EXPECT_FALSE(rfh->is_active());
+
+ // When the opener receives a postMessage from the popup's unload handler, it
+ // should start a navigation back to b.com. Wait for it. This navigation
+ // creates a speculative RFH which reuses the proxy that was created as part
+ // of swapping out from |popup_url| to |another_a_url|.
+ EXPECT_TRUE(manager.WaitForRequestStart());
+
+ // Cancel the started navigation (to /hung) in the popup and make sure the
+ // b.com renderer process exits cleanly without a crash. In
+ // https://crbug.com/794625, the crash was caused by trying to recreate the
+ // reused proxy, which had been incorrectly set as non-live.
+ popup_root->ResetNavigationRequest(false, false);
+ b_process_observer.Wait();
+ EXPECT_TRUE(b_process_observer.did_exit_normally());
+}
+
} // namespace content
diff --git a/chromium/content/browser/site_per_process_hit_test_browsertest.cc b/chromium/content/browser/site_per_process_hit_test_browsertest.cc
index 9884d624e54..8f00efa866d 100644
--- a/chromium/content/browser/site_per_process_hit_test_browsertest.cc
+++ b/chromium/content/browser/site_per_process_hit_test_browsertest.cc
@@ -28,6 +28,7 @@
#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/hit_test_region_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "content/shell/common/shell_switches.h"
@@ -41,6 +42,7 @@
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/public/browser/overscroll_configuration.h"
#include "content/test/mock_overscroll_controller_delegate_aura.h"
+#include "ui/aura/window_tree_host.h"
#endif
#if defined(OS_MACOSX)
@@ -240,7 +242,7 @@ void SurfaceHitTestTestHelper(
RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
DispatchMouseEventAndWaitUntilDispatch(web_contents, rwhv_child,
gfx::PointF(5, 5), rwhv_child,
@@ -273,7 +275,7 @@ void OverlapSurfaceHitTestHelper(
RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
gfx::PointF parent_location = gfx::PointF(5, 5);
parent_location =
@@ -320,7 +322,8 @@ void NestedSurfaceHitTestTestHelper(
->GetRenderWidgetHost()
->GetView());
- WaitForChildFrameSurfaceReady(nested_iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(
+ nested_iframe_node->current_frame_host());
DispatchMouseEventAndWaitUntilDispatch(web_contents, rwhv_nested,
gfx::PointF(10, 10), rwhv_nested,
@@ -350,7 +353,7 @@ void HitTestLayerSquashing(
RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
gfx::Vector2dF child_offset = rwhv_child->GetViewBounds().origin() -
rwhv_root->GetViewBounds().origin();
@@ -399,7 +402,7 @@ void HitTestWatermark(
RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
gfx::Vector2dF child_offset = rwhv_child->GetViewBounds().origin() -
rwhv_root->GetViewBounds().origin();
@@ -419,15 +422,48 @@ void HitTestWatermark(
web_contents, rwhv_child, child_location, rwhv_child, child_location);
}
-// This helper accounts for Android devices which use page scale factor
-// different from 1.0. Coordinate targeting needs to be adjusted before
-// hit testing.
-double GetPageScaleFactor(Shell* shell) {
- return RenderWidgetHostImpl::From(
- shell->web_contents()->GetRenderViewHost()->GetWidget())
- ->last_frame_metadata()
- .page_scale_factor;
+#if defined(USE_AURA)
+void HitTestRootWindowTransform(
+ Shell* shell,
+ net::test_server::EmbeddedTestServer* embedded_test_server) {
+ // Apply transform to root window to test that we respect root window
+ // transform when transforming event location.
+ gfx::Transform transform;
+ transform.RotateAboutXAxis(180.f);
+ transform.Translate(0.f,
+ -shell->window()->GetHost()->window()->bounds().height());
+ shell->window()->GetHost()->SetRootTransform(transform);
+
+ GURL main_url(embedded_test_server->GetURL(
+ "/frame_tree/page_with_positioned_frame.html"));
+ EXPECT_TRUE(NavigateToURL(shell, main_url));
+ auto* web_contents = static_cast<WebContentsImpl*>(shell->web_contents());
+
+ // 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());
+
+ FrameTreeNode* child_node = root->child_at(0);
+ GURL site_url(embedded_test_server->GetURL("baz.com", "/title1.html"));
+ EXPECT_EQ(site_url, child_node->current_url());
+ EXPECT_NE(shell->web_contents()->GetSiteInstance(),
+ child_node->current_frame_host()->GetSiteInstance());
+
+ RenderWidgetHostViewBase* rwhv_root = static_cast<RenderWidgetHostViewBase*>(
+ root->current_frame_host()->GetRenderWidgetHost()->GetView());
+ RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
+ child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
+
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
+
+ DispatchMouseEventAndWaitUntilDispatch(web_contents, rwhv_child,
+ gfx::PointF(5, 5), rwhv_child,
+ gfx::PointF(5, 5));
+
+ DispatchMouseEventAndWaitUntilDispatch(
+ web_contents, rwhv_root, gfx::PointF(2, 2), rwhv_root, gfx::PointF(2, 2));
}
+#endif // defined(USE_AURA)
#if defined(USE_AURA)
bool ConvertJSONToPoint(const std::string& str, gfx::PointF* point) {
@@ -550,7 +586,8 @@ class SitePerProcessHitTestBrowserTest
feature_list_.InitAndEnableFeature(
features::kEnableVizHitTestSurfaceLayer);
} else {
- feature_list_.InitAndDisableFeature(features::kEnableVizHitTestDrawQuad);
+ feature_list_.InitWithFeatures({}, {features::kEnableVizHitTestDrawQuad,
+ features::kVizDisplayCompositor});
}
}
@@ -637,7 +674,8 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessInternalsHitTestBrowserTest,
NavigateFrameToURL(parent_iframe_node, site_url);
FrameTreeNode* nested_iframe_node = parent_iframe_node->child_at(0);
- WaitForChildFrameSurfaceReady(nested_iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(
+ nested_iframe_node->current_frame_host());
EXPECT_EQ(
" Site A ------------ proxies for B\n"
@@ -763,7 +801,8 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessInternalsHitTestBrowserTest,
NavigateFrameToURL(parent_iframe_node, site_url);
FrameTreeNode* nested_iframe_node = parent_iframe_node->child_at(0);
- WaitForChildFrameSurfaceReady(nested_iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(
+ nested_iframe_node->current_frame_host());
EXPECT_EQ(
" Site A ------------ proxies for B\n"
@@ -916,17 +955,29 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessInternalsHitTestBrowserTest,
}
#endif // defined(USE_AURA)
+#if defined(OS_CHROMEOS)
+// Times out flakily on Chrome OS. crbug.com/833380
+#define MAYBE_CancelWheelScrollBubblingOnWheelTargetDeletion \
+ DISABLED_CancelWheelScrollBubblingOnWheelTargetDeletion
+#else
+#define MAYBE_CancelWheelScrollBubblingOnWheelTargetDeletion \
+ CancelWheelScrollBubblingOnWheelTargetDeletion
+#endif
+
// Tests that wheel scroll bubbling gets cancelled when the wheel target view
// gets destroyed in the middle of a wheel scroll seqeunce. This happens in
// cases like overscroll navigation from inside an oopif.
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- CancelWheelScrollBubblingOnWheelTargetDeletion) {
+ MAYBE_CancelWheelScrollBubblingOnWheelTargetDeletion) {
ui::GestureConfiguration::GetInstance()->set_scroll_debounce_interval_in_ms(
0);
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_positioned_frame.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ RenderFrameSubmissionObserver render_frame_submission_observer(
+ shell()->web_contents());
+
// 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());
@@ -945,7 +996,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
static_cast<WebContentsImpl*>(shell()->web_contents())
->GetInputEventRouter();
- WaitForChildFrameSurfaceReady(iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(iframe_node->current_frame_host());
InputEventAckWaiter scroll_begin_observer(
root->current_frame_host()->GetRenderWidgetHost(),
@@ -959,7 +1010,9 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
blink::WebInputEvent::GetStaticTimeStampForTests());
gfx::Rect bounds = child_rwhv->GetViewBounds();
- float scale_factor = GetPageScaleFactor(shell());
+ float scale_factor =
+ render_frame_submission_observer.LastRenderFrameMetadata()
+ .page_scale_factor;
gfx::Point position_in_widget(
gfx::ToCeiledInt((bounds.x() - root_view->GetViewBounds().x() + 5) *
scale_factor),
@@ -989,6 +1042,14 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
scroll_end_observer.Wait();
}
+#if defined(OS_LINUX)
+// The test is flaky on Linux: https://crbug.com/833380.
+#define MAYBE_BubbledScrollEventsTransformedCorrectly \
+ DISABLED_BubbledScrollEventsTransformedCorrectly
+#else
+#define MAYBE_BubbledScrollEventsTransformedCorrectly \
+ BubbledScrollEventsTransformedCorrectly
+#endif
// When a scroll event is bubbled, ensure that the bubbled event's coordinates
// are correctly updated to the ancestor's coordinate space. In particular,
// ensure that the transformation considers CSS scaling of the child where
@@ -996,11 +1057,14 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// coordinates in the ancestor's coordinate space.
// See https://crbug.com/817392
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- BubbledScrollEventsTransformedCorrectly) {
+ MAYBE_BubbledScrollEventsTransformedCorrectly) {
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_positioned_scaled_frame.html"));
ASSERT_TRUE(NavigateToURL(shell(), main_url));
+ RenderFrameSubmissionObserver render_frame_submission_observer(
+ shell()->web_contents());
+
// 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());
@@ -1016,9 +1080,11 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
static_cast<WebContentsImpl*>(shell()->web_contents())
->GetInputEventRouter();
- WaitForChildFrameSurfaceReady(iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(iframe_node->current_frame_host());
- const float scale_factor = GetPageScaleFactor(shell());
+ const float scale_factor =
+ render_frame_submission_observer.LastRenderFrameMetadata()
+ .page_scale_factor;
// Due to the CSS scaling of the iframe, the position in the child view's
// coordinates is (96, 96) and not (48, 48) (or approximately these values
// if there's rounding due to the scale factor).
@@ -1062,13 +1128,17 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
class SitePerProcessEmulatedTouchBrowserTest
: public SitePerProcessHitTestBrowserTest {
public:
- enum TestType { ScrollBubbling, PinchGoesToMainFrame };
+ enum TestType { ScrollBubbling, PinchGoesToMainFrame, TouchActionBubbling };
~SitePerProcessEmulatedTouchBrowserTest() override {}
void RunTest(TestType test_type) {
- GURL main_url(embedded_test_server()->GetURL(
- "/frame_tree/page_with_positioned_frame.html"));
+ std::string url;
+ if (test_type == TouchActionBubbling)
+ url = "/frame_tree/page_with_pany_frame.html";
+ else
+ url = "/frame_tree/page_with_positioned_frame.html";
+ GURL main_url(embedded_test_server()->GetURL(url));
ASSERT_TRUE(NavigateToURL(shell(), main_url));
// It is safe to obtain the root frame tree node here, as it doesn't change.
@@ -1091,7 +1161,7 @@ class SitePerProcessEmulatedTouchBrowserTest
static_cast<WebContentsImpl*>(shell()->web_contents())
->GetInputEventRouter();
- WaitForChildFrameSurfaceReady(iframe_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(iframe_node->current_frame_host());
auto expect_gesture_with_position = base::BindRepeating(
[](blink::WebInputEvent::Type expected_type,
@@ -1114,6 +1184,7 @@ class SitePerProcessEmulatedTouchBrowserTest
blink::WebInputEvent::Type expected_gesture_type;
switch (test_type) {
case ScrollBubbling:
+ case TouchActionBubbling:
expected_gesture_type = blink::WebInputEvent::kGestureScrollBegin;
break;
case PinchGoesToMainFrame:
@@ -1186,7 +1257,7 @@ class SitePerProcessEmulatedTouchBrowserTest
router->RouteMouseEvent(root_rwhv, &mouse_drag_event, ui::LatencyInfo());
router->RouteMouseEvent(root_rwhv, &mouse_up_event, ui::LatencyInfo());
- if (test_type == ScrollBubbling) {
+ if (test_type == ScrollBubbling || test_type == TouchActionBubbling) {
// Verify child receives GestureScrollBegin.
child_gesture_event_observer.Wait();
}
@@ -1200,16 +1271,43 @@ class SitePerProcessEmulatedTouchBrowserTest
}
};
+#if defined(OS_CHROMEOS)
+// Flaky: https://crbug.com/833380
+#define MAYBE_EmulatedTouchScrollBubbles DISABLED_EmulatedTouchScrollBubbles
+#else
+#define MAYBE_EmulatedTouchScrollBubbles EmulatedTouchScrollBubbles
+#endif
+
IN_PROC_BROWSER_TEST_P(SitePerProcessEmulatedTouchBrowserTest,
- EmulatedTouchScrollBubbles) {
+ MAYBE_EmulatedTouchScrollBubbles) {
RunTest(ScrollBubbling);
}
+#if defined(OS_LINUX)
+// Flaky: https://crbug.com/833380
+#define MAYBE_EmulatedTouchPinchGoesToMainFrame \
+ DISABLED_EmulatedTouchPinchGoesToMainFrame
+#else
+#define MAYBE_EmulatedTouchPinchGoesToMainFrame \
+ EmulatedTouchPinchGoesToMainFrame
+#endif
IN_PROC_BROWSER_TEST_P(SitePerProcessEmulatedTouchBrowserTest,
- EmulatedTouchPinchGoesToMainFrame) {
+ MAYBE_EmulatedTouchPinchGoesToMainFrame) {
RunTest(PinchGoesToMainFrame);
}
+#if defined(OS_CHROMEOS)
+// Flaky timeouts: https://crbug.com/833380
+#define MAYBE_EmulatedGestureScrollBubbles DISABLED_EmulatedGestureScrollBubbles
+#else
+#define MAYBE_EmulatedGestureScrollBubbles EmulatedGestureScrollBubbles
+#endif
+
+IN_PROC_BROWSER_TEST_P(SitePerProcessEmulatedTouchBrowserTest,
+ MAYBE_EmulatedGestureScrollBubbles) {
+ RunTest(TouchActionBubbling);
+}
+
#if defined(USE_AURA) || defined(OS_ANDROID)
// When unconsumed scrolls in a child bubble to the root and start an
@@ -1230,6 +1328,9 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
"a.com", "/cross_site_iframe_factory.html?a(b)"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ RenderFrameSubmissionObserver render_frame_submission_observer(
+ shell()->web_contents());
+
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root();
@@ -1259,7 +1360,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
static_cast<RenderWidgetHostViewChildFrame*>(
child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
ASSERT_TRUE(rwhv_root->IsScrollOffsetAtTop());
ASSERT_TRUE(rwhv_child->IsScrollOffsetAtTop());
@@ -1273,7 +1374,9 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// to the child.
const gfx::Rect root_bounds = rwhv_root->GetViewBounds();
const gfx::Rect child_bounds = rwhv_child->GetViewBounds();
- const float page_scale_factor = GetPageScaleFactor(shell());
+ const float page_scale_factor =
+ render_frame_submission_observer.LastRenderFrameMetadata()
+ .page_scale_factor;
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);
@@ -1433,7 +1536,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// and is needed for trackpad scrolling on Chromebooks.
#if defined(USE_AURA)
-#if defined(THREAD_SANITIZER)
+#if defined(THREAD_SANITIZER) || defined(OS_CHROMEOS)
// Flaky: https://crbug.com/833380
#define MAYBE_ScrollEventToOOPIF DISABLED_ScrollEventToOOPIF
#else
@@ -1461,7 +1564,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
static_cast<RenderWidgetHostViewAura*>(
root->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
// Create listener for input events.
TestInputEventObserver child_frame_monitor(
@@ -1482,7 +1585,10 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// Verify that this a mouse wheel event was sent to the child frame renderer.
EXPECT_TRUE(child_frame_monitor.EventWasReceived());
- EXPECT_EQ(child_frame_monitor.EventType(), blink::WebInputEvent::kMouseWheel);
+ const auto& child_events = child_frame_monitor.events_received();
+ EXPECT_NE(child_events.end(),
+ std::find(child_events.begin(), child_events.end(),
+ blink::WebInputEvent::kMouseWheel));
}
#if defined(THREAD_SANITIZER)
@@ -1516,7 +1622,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
static_cast<RenderWidgetHostViewAura*>(
root->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
RenderWidgetHostInputEventRouter* router =
web_contents()->GetInputEventRouter();
@@ -1580,9 +1686,10 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// Test that mouse events are being routed to the correct RenderWidgetHostView
// based on coordinates.
-#if defined(THREAD_SANITIZER)
+#if defined(THREAD_SANITIZER) || defined(OS_CHROMEOS)
// The test times out often on TSAN bot.
// https://crbug.com/591170.
+// Also times out flakily on Chrome OS. crbug.com/833380
#define MAYBE_SurfaceHitTestTest DISABLED_SurfaceHitTestTest
#else
#define MAYBE_SurfaceHitTestTest SurfaceHitTestTest
@@ -1624,11 +1731,6 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHighDPIHitTestBrowserTest,
NestedSurfaceHitTestTestHelper(shell(), embedded_test_server());
}
-IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- OverlapSurfaceHitTestTest) {
- OverlapSurfaceHitTestHelper(shell(), embedded_test_server());
-}
-
#if defined(OS_LINUX)
// Flaky timeouts and failures: https://crbug.com/833380
#define MAYBE_OverlapSurfaceHitTestTest DISABLED_OverlapSurfaceHitTestTest
@@ -1640,6 +1742,11 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHighDPIHitTestBrowserTest,
OverlapSurfaceHitTestHelper(shell(), embedded_test_server());
}
+IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
+ MAYBE_OverlapSurfaceHitTestTest) {
+ OverlapSurfaceHitTestHelper(shell(), embedded_test_server());
+}
+
#if defined(OS_LINUX)
// Flaky timeouts and failures: https://crbug.com/833380
#define MAYBE_HitTestLayerSquashing DISABLED_HitTestLayerSquashing
@@ -1672,8 +1779,26 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHighDPIHitTestBrowserTest,
HitTestWatermark(shell(), embedded_test_server());
}
+#if defined(USE_AURA)
+IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest, RootWindowTransform) {
+ HitTestRootWindowTransform(shell(), embedded_test_server());
+}
+
+IN_PROC_BROWSER_TEST_P(SitePerProcessHighDPIHitTestBrowserTest,
+ RootWindowTransform) {
+ HitTestRootWindowTransform(shell(), embedded_test_server());
+}
+#endif // defined(USE_AURA)
+
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
HitTestStaleDataDeletedView) {
+ // TODO(sunxd): Hit test regions are not submitted for overlapping surfaces,
+ // causing /2 to fail outside of Viz. https::/crbug.com/846798
+ if (base::FeatureList::IsEnabled(features::kEnableVizHitTestSurfaceLayer) &&
+ !base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
+ return;
+ }
+
// Have two iframes to avoid going to short circuit path during the second
// targeting.
GURL main_url(
@@ -1705,8 +1830,8 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
static_cast<RenderWidgetHostViewBase*>(
child_node2->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForChildFrameSurfaceReady(child_node1->current_frame_host());
- WaitForChildFrameSurfaceReady(child_node2->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node1->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node2->current_frame_host());
const gfx::PointF child_location(50, 50);
gfx::PointF parent_location =
@@ -1745,7 +1870,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
EXPECT_EQ(result.target_location.value(), parent_location);
}
-#if defined(THREAD_SANITIZER)
+#if defined(THREAD_SANITIZER) || defined(OS_LINUX)
// Flaky: https://crbug.com/833380
#define MAYBE_SurfaceHitTestPointerEventsNone \
DISABLED_SurfaceHitTestPointerEventsNone
@@ -1783,7 +1908,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
root->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
// Target input event to child frame.
blink::WebMouseEvent child_event(
@@ -1805,10 +1930,18 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
EXPECT_FALSE(child_frame_monitor.EventWasReceived());
}
+#if defined(OS_CHROMEOS)
+// Flaky on Chrome OS. crbug.com/833380
+#define MAYBE_AsynchronousHitTestChildTimeout \
+ DISABLED_AsynchronousHitTestChildTimeout
+#else
+#define MAYBE_AsynchronousHitTestChildTimeout AsynchronousHitTestChildTimeout
+#endif
+
// Verify that an event is properly retargeted to the main frame when an
// asynchronous hit test to the child frame times out.
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- AsynchronousHitTestChildTimeout) {
+ MAYBE_AsynchronousHitTestChildTimeout) {
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_positioned_busy_frame.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -1836,7 +1969,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
RenderWidgetHostViewBase* root_view = static_cast<RenderWidgetHostViewBase*>(
root->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
// Target input event to child frame. It should get delivered to the main
// frame instead because the child frame main thread is non-responsive.
@@ -1925,7 +2058,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
TooltipMonitor tooltip_monitor(rwhv_a->GetCursorManager());
- WaitForChildFrameSurfaceReady(b_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(b_node->current_frame_host());
// Make sure the point_in_a_frame value is outside the default 8px margin
// for the body element.
@@ -2026,7 +2159,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// than nullptr. If it did, this test would be unnecessary.
DCHECK(!rwhv_a->GetCursorManager());
- WaitForChildFrameSurfaceReady(b_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(b_node->current_frame_host());
// Make sure the point_in_a_frame value is outside the default 8px margin
// for the body element.
@@ -2104,6 +2237,9 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
"a.com", "/cross_site_iframe_factory.html?a(b,c(d))"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ RenderFrameSubmissionObserver render_frame_submission_observer(
+ shell()->web_contents());
+
FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
->GetFrameTree()
->root();
@@ -2132,8 +2268,8 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// Verifying surfaces are ready in B and D are sufficient, since other
// surfaces contain at least one of them.
- WaitForChildFrameSurfaceReady(b_node->current_frame_host());
- WaitForChildFrameSurfaceReady(d_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(b_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(d_node->current_frame_host());
// Create listeners for mouse events. These are used to verify that the
// RenderWidgetHostInputEventRouter is generating MouseLeave, etc for
@@ -2149,7 +2285,9 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
RenderWidgetHostMouseEventMonitor d_frame_monitor(
d_node->current_frame_host()->GetRenderWidgetHost());
- float scale_factor = GetPageScaleFactor(shell());
+ float scale_factor =
+ render_frame_submission_observer.LastRenderFrameMetadata()
+ .page_scale_factor;
// Get the view bounds of the child iframe, which should account for the
// relative offset of its direct parent within the root frame, for use in
@@ -2211,12 +2349,6 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
EXPECT_TRUE(d_frame_monitor.EventWasReceived());
}
-#if defined(OS_LINUX)
-// Flaky timeouts and failures: https://crbug.com/833380
-#define MAYBE_CrossProcessMouseCapture DISABLED_CrossProcessMouseCapture
-#else
-#define MAYBE_CrossProcessMouseCapture CrossProcessMouseCapture
-#endif
// Verify that mouse capture works on a RenderWidgetHostView level, so that
// dragging scroll bars and selecting text continues even when the mouse
// cursor crosses over cross-process frame boundaries.
@@ -2224,11 +2356,14 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// Other reasons for a node to capture mouse input need to be addressed. See
// https://crbug.com/647378.
IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
- MAYBE_CrossProcessMouseCapture) {
+ CrossProcessMouseCapture) {
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_large_scrollable_frame.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
+ RenderFrameSubmissionObserver render_frame_submission_observer(
+ shell()->web_contents());
+
// 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());
@@ -2255,9 +2390,11 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
- float scale_factor = GetPageScaleFactor(shell());
+ float scale_factor =
+ render_frame_submission_observer.LastRenderFrameMetadata()
+ .page_scale_factor;
// Get the view bounds of the child iframe, which should account for the
// relative offset of its direct parent within the root frame, for use in
@@ -2418,7 +2555,7 @@ void CursorUpdateReceivedFromCrossSiteIframeHelper(
EXPECT_NE(shell->web_contents()->GetSiteInstance(),
child_node->current_frame_host()->GetSiteInstance());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
scoped_refptr<CursorMessageFilter> filter = new CursorMessageFilter();
child_node->current_frame_host()->GetProcess()->AddFilter(filter.get());
@@ -2578,12 +2715,10 @@ class SitePerProcessMouseWheelHitTestBrowserTest
web_contents()->GetRenderWidgetHostView());
set_rwhv_root(rwhv_root);
- if (rwhv_root->wheel_scroll_latching_enabled()) {
- // Set the wheel scroll latching timeout to a large value to make sure
- // that the timer doesn't expire for the duration of the test.
- rwhv_root->event_handler()->set_mouse_wheel_wheel_phase_handler_timeout(
- TestTimeouts::action_max_timeout());
- }
+ // Set the wheel scroll latching timeout to a large value to make sure
+ // that the timer doesn't expire for the duration of the test.
+ rwhv_root->event_handler()->set_mouse_wheel_wheel_phase_handler_timeout(
+ TestTimeouts::action_max_timeout());
InputEventAckWaiter waiter(expected_target->GetRenderWidgetHost(),
blink::WebInputEvent::kMouseWheel);
@@ -2598,19 +2733,13 @@ class SitePerProcessMouseWheelHitTestBrowserTest
SendMouseWheel(pos);
- // If async_wheel_events is disabled, this time only the wheel handler
- // fires, since even numbered scrolls are prevent-defaulted. If it is
- // enabled, then this wheel event will be sent non-blockingly and won't be
- // cancellable.
+ // Even though even number events are prevented by default since the first
+ // wheel event is not prevented by default, the rest of the wheel events
+ // will be handled nonblocking and the scroll will happen.
EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
EXPECT_EQ("\"wheel: 2\"", reply);
- if (base::FeatureList::IsEnabled(features::kAsyncWheelEvents) &&
- base::FeatureList::IsEnabled(
- features::kTouchpadAndWheelScrollLatching)) {
- DCHECK(rwhv_root->wheel_scroll_latching_enabled());
- EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
- EXPECT_EQ("\"scroll: 2\"", reply);
- }
+ EXPECT_TRUE(msg_queue.WaitForMessage(&reply));
+ EXPECT_EQ("\"scroll: 2\"", reply);
SendMouseWheel(pos);
@@ -2626,26 +2755,16 @@ class SitePerProcessMouseWheelHitTestBrowserTest
RenderWidgetHostViewAura* rwhv_root_;
};
-// Subclass to disable wheel scroll latching in failing tests.
-// https://crbug.com/800822
-class SitePerProcessMouseWheelHitTestBrowserTestWheelScrollLatchingDisabled
- : public SitePerProcessMouseWheelHitTestBrowserTest {
- public:
- SitePerProcessMouseWheelHitTestBrowserTestWheelScrollLatchingDisabled() {}
- void SetUp() override {
- feature_list_.InitWithFeatures({},
- {features::kTouchpadAndWheelScrollLatching,
- features::kAsyncWheelEvents});
- SitePerProcessMouseWheelHitTestBrowserTest::SetUp();
- }
-
- private:
- base::test::ScopedFeatureList feature_list_;
-};
-
-IN_PROC_BROWSER_TEST_P(
- SitePerProcessMouseWheelHitTestBrowserTestWheelScrollLatchingDisabled,
- MultipleSubframeWheelEventsOnMainThread) {
+// Fails on Windows official build, see // https://crbug.com/800822
+#if defined(OS_WIN)
+#define MAYBE_MultipleSubframeWheelEventsOnMainThread \
+ DISABLED_MultipleSubframeWheelEventsOnMainThread
+#else
+#define MAYBE_MultipleSubframeWheelEventsOnMainThread \
+ MultipleSubframeWheelEventsOnMainThread
+#endif
+IN_PROC_BROWSER_TEST_P(SitePerProcessMouseWheelHitTestBrowserTest,
+ MAYBE_MultipleSubframeWheelEventsOnMainThread) {
GURL main_url(embedded_test_server()->GetURL(
"/frame_tree/page_with_two_positioned_frames.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -2668,8 +2787,7 @@ IN_PROC_BROWSER_TEST_P(
static_cast<RenderWidgetHostViewBase*>(
root->child_at(frame_index)->current_frame_host()->GetView());
- EXPECT_FALSE(child_rwhv->wheel_scroll_latching_enabled());
- WaitForChildFrameSurfaceReady(
+ WaitForHitTestDataOrChildSurfaceReady(
root->child_at(frame_index)->current_frame_host());
content::RenderFrameHostImpl* child =
@@ -2685,9 +2803,15 @@ IN_PROC_BROWSER_TEST_P(
// Verifies that test in SubframeWheelEventsOnMainThread also makes sense for
// the same page loaded in the mainframe.
-IN_PROC_BROWSER_TEST_P(
- SitePerProcessMouseWheelHitTestBrowserTestWheelScrollLatchingDisabled,
- MainframeWheelEventsOnMainThread) {
+// Fails on Windows official build, see // https://crbug.com/800822
+#if defined(OS_WIN)
+#define MAYBE_MainframeWheelEventsOnMainThread \
+ DISABLED_MainframeWheelEventsOnMainThread
+#else
+#define MAYBE_MainframeWheelEventsOnMainThread MainframeWheelEventsOnMainThread
+#endif
+IN_PROC_BROWSER_TEST_P(SitePerProcessMouseWheelHitTestBrowserTest,
+ MAYBE_MainframeWheelEventsOnMainThread) {
GURL main_url(
embedded_test_server()->GetURL("/page_with_scrollable_div.html"));
EXPECT_TRUE(NavigateToURL(shell(), main_url));
@@ -2696,9 +2820,6 @@ IN_PROC_BROWSER_TEST_P(
content::RenderFrameHostImpl* rfhi = root->current_frame_host();
SetupWheelAndScrollHandlers(rfhi);
- EXPECT_FALSE(
- rfhi->GetRenderWidgetHost()->GetView()->wheel_scroll_latching_enabled());
-
gfx::Point pos(10, 10);
RunTest(pos, rfhi->GetRenderWidgetHost()->GetView());
@@ -2724,7 +2845,8 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessMouseWheelHitTestBrowserTest,
// surface information required for event hit testing is ready.
RenderWidgetHostViewBase* child_rwhv = static_cast<RenderWidgetHostViewBase*>(
root->child_at(0)->current_frame_host()->GetView());
- WaitForChildFrameSurfaceReady(root->child_at(0)->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(
+ root->child_at(0)->current_frame_host());
RenderWidgetHostInputEventRouter* router =
web_contents()->GetInputEventRouter();
@@ -2737,24 +2859,22 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessMouseWheelHitTestBrowserTest,
SendMouseWheel(pos);
waiter.Wait();
- if (child_rwhv->wheel_scroll_latching_enabled())
- EXPECT_EQ(child_rwhv, router->wheel_target_.target);
- else
- EXPECT_EQ(nullptr, router->wheel_target_.target);
+ EXPECT_EQ(child_rwhv, router->wheel_target_.target);
- // Send a mouse wheel event to the main frame. If wheel scroll latching is
- // enabled it will be still routed to child till the end of current scrolling
- // sequence. Since wheel scroll latching is enabled by default, we always do
- // sync targeting so InputEventAckWaiter is not needed here.
+ // Send a mouse wheel event to the main frame. It will be still routed to
+ // child till the end of current scrolling sequence. Since wheel scroll
+ // latching is enabled by default, we always do sync targeting so
+ // InputEventAckWaiter is not needed here.
TestInputEventObserver child_frame_monitor(child_rwhv->GetRenderWidgetHost());
SendMouseWheel(pos);
- if (child_rwhv->wheel_scroll_latching_enabled())
- EXPECT_EQ(child_rwhv, router->wheel_target_.target);
- else
- EXPECT_EQ(nullptr, router->wheel_target_.target);
+ EXPECT_EQ(child_rwhv, router->wheel_target_.target);
+
// Verify that this a mouse wheel event was sent to the child frame renderer.
EXPECT_TRUE(child_frame_monitor.EventWasReceived());
- EXPECT_EQ(child_frame_monitor.EventType(), blink::WebInputEvent::kMouseWheel);
+ const auto& child_events = child_frame_monitor.events_received();
+ EXPECT_NE(child_events.end(),
+ std::find(child_events.begin(), child_events.end(),
+ blink::WebInputEvent::kMouseWheel));
// Kill the wheel target view process. This must reset the wheel_target_.
RenderProcessHost* child_process =
@@ -2784,20 +2904,21 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// Synchronize with the child and parent renderers to guarantee that the
// surface information required for event hit testing is ready.
- WaitForChildFrameSurfaceReady(root->child_at(0)->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(
+ root->child_at(0)->current_frame_host());
// There's no intrinsic reason the following values can't be equal, but they
// aren't at present, and if they become the same this test will need to be
// updated to accommodate.
EXPECT_NE(cc::kTouchActionAuto, cc::kTouchActionNone);
- // Verify the child's input router is initially set for kTouchActionAuto. The
- // TouchStart event will trigger kTouchActionNone being sent back to the
- // browser.
+ // Verify the child's input router is initially not set. The TouchStart event
+ // will trigger kTouchActionNone being sent back to the browser.
RenderWidgetHostImpl* child_render_widget_host =
root->child_at(0)->current_frame_host()->GetRenderWidgetHost();
- EXPECT_EQ(cc::kTouchActionAuto,
- child_render_widget_host->input_router()->AllowedTouchAction());
+ EXPECT_EQ(true, child_render_widget_host->input_router()
+ ->AllowedTouchAction()
+ .has_value());
InputEventAckWaiter waiter(child_render_widget_host,
blink::WebInputEvent::kTouchStart);
@@ -2866,14 +2987,14 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// updated to accommodate.
EXPECT_NE(cc::kTouchActionAuto, cc::kTouchActionNone);
- // Verify the main frame's input router is initially set for
- // kTouchActionAuto. The
+ // Verify the main frame's input router is initially not set. The
// TouchStart event will trigger kTouchActionNone being sent back to the
// browser.
RenderWidgetHostImpl* render_widget_host =
root->current_frame_host()->GetRenderWidgetHost();
- EXPECT_EQ(cc::kTouchActionAuto,
- render_widget_host->input_router()->AllowedTouchAction());
+ EXPECT_EQ(
+ true,
+ render_widget_host->input_router()->AllowedTouchAction().has_value());
// Simulate touch event to sub-frame.
gfx::Point frame_center(150, 150);
@@ -2941,7 +3062,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// Synchronize with the child and parent renderers to guarantee that the
// surface information required for event hit testing is ready.
- WaitForChildFrameSurfaceReady(child_frame_host);
+ WaitForHitTestDataOrChildSurfaceReady(child_frame_host);
// There have been no GestureTaps sent yet.
{
@@ -3130,6 +3251,7 @@ void SendTouchpadPinchSequenceWithExpectedTarget(
ui::GestureEventDetails pinch_update_details(ui::ET_GESTURE_PINCH_UPDATE);
pinch_update_details.set_device_type(ui::GestureDeviceType::DEVICE_TOUCHPAD);
+ pinch_update_details.set_scale(1.23);
ui::GestureEvent pinch_update(gesture_point.x(), gesture_point.y(), 0,
ui::EventTimeForNow(), pinch_update_details);
UpdateEventRootLocation(&pinch_update, root_view_aura);
@@ -3146,9 +3268,9 @@ void SendTouchpadPinchSequenceWithExpectedTarget(
ui::EventTimeForNow(), pinch_end_details);
UpdateEventRootLocation(&pinch_end, root_view_aura);
root_view_aura->OnGestureEvent(&pinch_end);
- EXPECT_EQ(expected_target, router_touchpad_gesture_target);
EXPECT_TRUE(target_monitor.EventWasReceived());
EXPECT_EQ(target_monitor.EventType(), blink::WebInputEvent::kGesturePinchEnd);
+ EXPECT_EQ(nullptr, router_touchpad_gesture_target);
}
#if !defined(OS_WIN)
@@ -3156,22 +3278,14 @@ void SendTouchpadPinchSequenceWithExpectedTarget(
void SendTouchpadFlingSequenceWithExpectedTarget(
RenderWidgetHostViewBase* root_view,
const gfx::Point& gesture_point,
- RenderWidgetHostViewBase*& router_touchpad_gesture_target,
+ RenderWidgetHostViewBase*& router_wheel_target,
RenderWidgetHostViewBase* expected_target) {
auto* root_view_aura = static_cast<RenderWidgetHostViewAura*>(root_view);
- if (root_view_aura->wheel_scroll_latching_enabled()) {
- // Touchpad Fling must be sent inside a gesture scroll seqeunce.
- blink::WebGestureEvent gesture_event(
- blink::WebGestureEvent::kGestureScrollBegin,
- blink::WebInputEvent::kNoModifiers,
- blink::WebInputEvent::GetStaticTimeStampForTests(),
- blink::kWebGestureDeviceTouchpad);
- gesture_event.SetPositionInWidget(gfx::PointF(gesture_point));
- gesture_event.data.scroll_begin.delta_x_hint = 0.0f;
- gesture_event.data.scroll_begin.delta_y_hint = 1.0f;
- expected_target->GetRenderWidgetHost()->ForwardGestureEvent(gesture_event);
- }
+ ui::ScrollEvent scroll_begin(ui::ET_SCROLL, gesture_point,
+ ui::EventTimeForNow(), 0, 1, 0, 1, 0, 2);
+ UpdateEventRootLocation(&scroll_begin, root_view_aura);
+ root_view_aura->OnScrollEvent(&scroll_begin);
ui::ScrollEvent fling_start(ui::ET_SCROLL_FLING_START, gesture_point,
ui::EventTimeForNow(), 0, 1, 0, 1, 0, 1);
@@ -3189,7 +3303,7 @@ void SendTouchpadFlingSequenceWithExpectedTarget(
EXPECT_FALSE(target_monitor.EventWasReceived());
fling_start_waiter.Wait();
EXPECT_TRUE(target_monitor.EventWasReceived());
- EXPECT_EQ(expected_target, router_touchpad_gesture_target);
+ EXPECT_EQ(expected_target, router_wheel_target);
target_monitor.ResetEventsReceived();
// Send a GFC event, the fling_controller will process the GFC and stop the
@@ -3198,15 +3312,15 @@ void SendTouchpadFlingSequenceWithExpectedTarget(
InputEventAckWaiter gestrue_scroll_end_waiter(
expected_target->GetRenderWidgetHost(),
blink::WebInputEvent::kGestureScrollEnd);
+ InputEventAckWaiter fling_cancel_waiter(
+ expected_target->GetRenderWidgetHost(),
+ blink::WebInputEvent::kGestureFlingCancel);
ui::ScrollEvent fling_cancel(ui::ET_SCROLL_FLING_CANCEL, gesture_point,
ui::EventTimeForNow(), 0, 1, 0, 1, 0, 1);
UpdateEventRootLocation(&fling_cancel, root_view_aura);
root_view_aura->OnScrollEvent(&fling_cancel);
- EXPECT_EQ(expected_target, router_touchpad_gesture_target);
- EXPECT_TRUE(target_monitor.EventWasReceived());
- EXPECT_EQ(target_monitor.EventType(),
- blink::WebInputEvent::kGestureFlingCancel);
gestrue_scroll_end_waiter.Wait();
+ fling_cancel_waiter.Wait();
}
#endif // !defined(OS_WIN)
@@ -3239,7 +3353,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// Synchronize with the child and parent renderers to guarantee that the
// surface information required for event hit testing is ready.
- WaitForChildFrameSurfaceReady(child_frame_host);
+ WaitForHitTestDataOrChildSurfaceReady(child_frame_host);
// All touches & gestures are sent to the main frame's view, and should be
// routed appropriately from there.
@@ -3335,7 +3449,7 @@ IN_PROC_BROWSER_TEST_P(
// Synchronize with the child and parent renderers to guarantee that the
// surface information required for event hit testing is ready.
- WaitForChildFrameSurfaceReady(child_frame_host);
+ WaitForHitTestDataOrChildSurfaceReady(child_frame_host);
// All touches & gestures are sent to the main frame's view, and should be
// routed appropriately from there.
@@ -3419,7 +3533,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// surface information required for event hit testing is ready.
auto* rwhv_child =
static_cast<RenderWidgetHostViewBase*>(child_frame_host->GetView());
- WaitForChildFrameSurfaceReady(child_frame_host);
+ WaitForHitTestDataOrChildSurfaceReady(child_frame_host);
// All touches & gestures are sent to the main frame's view, and should be
// routed appropriately from there.
@@ -3429,6 +3543,29 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
RenderWidgetHostInputEventRouter* router = contents->GetInputEventRouter();
EXPECT_EQ(nullptr, router->touchpad_gesture_target_.target);
+ // TODO(848050): If we send multiple touchpad pinch sequences to separate
+ // views and the timing of the acks are such that the begin ack of the second
+ // sequence arrives in the root before the end ack of the first sequence, we
+ // would produce an invalid gesture event sequence. For now, we wait for the
+ // root to receive the end ack before sending a pinch sequence to a different
+ // view. The root view should preserve validity of input event sequences
+ // when processing acks from multiple views, so that waiting here is not
+ // necessary.
+ auto wait_for_pinch_sequence_end = base::BindRepeating(
+ [](RenderWidgetHost* rwh) {
+ InputEventAckWaiter pinch_end_observer(
+ rwh, base::BindRepeating([](content::InputEventAckSource,
+ content::InputEventAckState,
+ const blink::WebInputEvent& event) {
+ return event.GetType() ==
+ blink::WebGestureEvent::kGesturePinchEnd &&
+ !static_cast<const blink::WebGestureEvent&>(event)
+ .NeedsWheelEvent();
+ }));
+ pinch_end_observer.Wait();
+ },
+ rwhv_parent->GetRenderWidgetHost());
+
gfx::Point main_frame_point(25, 25);
gfx::Point child_center(150, 150);
@@ -3437,11 +3574,15 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
rwhv_parent, main_frame_point, router->touchpad_gesture_target_.target,
rwhv_parent);
+ wait_for_pinch_sequence_end.Run();
+
// Send touchpad pinch sequence to child.
SendTouchpadPinchSequenceWithExpectedTarget(
rwhv_parent, child_center, router->touchpad_gesture_target_.target,
rwhv_child);
+ wait_for_pinch_sequence_end.Run();
+
// Send another touchpad pinch sequence to main frame.
SendTouchpadPinchSequenceWithExpectedTarget(
rwhv_parent, main_frame_point, router->touchpad_gesture_target_.target,
@@ -3452,20 +3593,79 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
// Send touchpad fling sequence to main-frame.
SendTouchpadFlingSequenceWithExpectedTarget(
- rwhv_parent, main_frame_point, router->touchpad_gesture_target_.target,
- rwhv_parent);
+ rwhv_parent, main_frame_point, router->wheel_target_.target, rwhv_parent);
// Send touchpad fling sequence to child.
SendTouchpadFlingSequenceWithExpectedTarget(
- rwhv_parent, child_center, router->touchpad_gesture_target_.target,
- rwhv_child);
+ rwhv_parent, child_center, router->wheel_target_.target, rwhv_child);
// Send another touchpad fling sequence to main frame.
SendTouchpadFlingSequenceWithExpectedTarget(
- rwhv_parent, main_frame_point, router->touchpad_gesture_target_.target,
- rwhv_parent);
+ rwhv_parent, main_frame_point, router->wheel_target_.target, rwhv_parent);
#endif
}
+
+// Test that performing a touchpad pinch over an OOPIF offers the synthetic
+// wheel events to the child and causes the page scale factor to change for
+// the main frame (given that the child did not consume the wheel).
+IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest,
+ TouchpadPinchOverOOPIF) {
+ // TODO(crbug.com/853761): Flaky with viz hit testing
+ if (features::IsVizHitTestingEnabled()) {
+ LOG(INFO) << "Skipping test due to https://crbug.com/853761";
+ return;
+ }
+
+ GURL main_url(embedded_test_server()->GetURL(
+ "/frame_tree/page_with_positioned_frame.html"));
+ EXPECT_TRUE(NavigateToURL(shell(), main_url));
+
+ RenderFrameSubmissionObserver render_frame_submission_observer(
+ shell()->web_contents());
+
+ WebContentsImpl* contents = web_contents();
+ FrameTreeNode* root = contents->GetFrameTree()->root();
+ ASSERT_EQ(1U, root->child_count());
+
+ GURL frame_url(
+ embedded_test_server()->GetURL("b.com", "/page_with_wheel_handler.html"));
+ NavigateFrameToURL(root->child_at(0), frame_url);
+ auto* child_frame_host = root->child_at(0)->current_frame_host();
+
+ auto* rwhv_child =
+ static_cast<RenderWidgetHostViewBase*>(child_frame_host->GetView());
+ WaitForHitTestDataOrChildSurfaceReady(child_frame_host);
+
+ auto* rwhv_parent = static_cast<RenderWidgetHostViewBase*>(
+ contents->GetRenderWidgetHostView());
+
+ RenderWidgetHostInputEventRouter* router = contents->GetInputEventRouter();
+ EXPECT_EQ(nullptr, router->touchpad_gesture_target_.target);
+
+ const float scale_factor =
+ render_frame_submission_observer.LastRenderFrameMetadata()
+ .page_scale_factor;
+ const gfx::Point point_in_child(gfx::ToCeiledInt(100 * scale_factor),
+ gfx::ToCeiledInt(100 * scale_factor));
+
+ content::TestPageScaleObserver scale_observer(shell()->web_contents());
+ SendTouchpadPinchSequenceWithExpectedTarget(
+ rwhv_parent, point_in_child, router->touchpad_gesture_target_.target,
+ rwhv_child);
+
+ // Ensure the child frame saw the wheel event.
+ bool default_prevented = false;
+ ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
+ child_frame_host,
+ "handlerPromise.then(function(e) {"
+ " window.domAutomationController.send(e.defaultPrevented);"
+ "});",
+ &default_prevented));
+ EXPECT_FALSE(default_prevented);
+
+ scale_observer.WaitForPageScaleUpdate();
+}
+
#endif // defined(USE_AURA)
// A WebContentsDelegate to capture ContextMenu creation events.
@@ -3511,6 +3711,9 @@ void CreateContextMenuTestHelper(
"/frame_tree/page_with_positioned_frame.html"));
EXPECT_TRUE(NavigateToURL(shell, main_url));
+ RenderFrameSubmissionObserver render_frame_submission_observer(
+ shell->web_contents());
+
// 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()
@@ -3531,7 +3734,7 @@ void CreateContextMenuTestHelper(
// Ensure that the child process renderer is ready to have input events
// routed to it. This happens when the browser process has received
// updated compositor surfaces from both renderer processes.
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
// A WebContentsDelegate to listen for the ShowContextMenu message.
ContextMenuObserverDelegate context_menu_delegate;
@@ -3541,7 +3744,9 @@ void CreateContextMenuTestHelper(
static_cast<WebContentsImpl*>(shell->web_contents())
->GetInputEventRouter();
- float scale_factor = GetPageScaleFactor(shell);
+ float scale_factor =
+ render_frame_submission_observer.LastRenderFrameMetadata()
+ .page_scale_factor;
gfx::Rect root_bounds = root_view->GetViewBounds();
gfx::Rect bounds = rwhv_child->GetViewBounds();
@@ -3572,9 +3777,10 @@ void CreateContextMenuTestHelper(
EXPECT_NEAR(point.y(), params.y, 2);
}
-#if defined(OS_ANDROID) || defined(OS_WIN)
+#if defined(OS_ANDROID) || defined(OS_WIN) || defined(OS_LINUX)
// High DPI tests don't work properly on Android, which has fixed scale factor.
// Windows is disabled because of https://crbug.com/545547.
+// The test is flaky on Linux: https://crbug.com/833380.
#define MAYBE_CreateContextMenuTest DISABLED_CreateContextMenuTest
#elif defined(THREAD_SANITIZER)
// TSAN is flaky on both standard and High DPI: https://crbug.com/833380
@@ -3617,7 +3823,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest, PopupMenuTest) {
web_contents()->SendScreenRects();
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
RenderWidgetHostViewBase* rwhv_child = static_cast<RenderWidgetHostViewBase*>(
child_node->current_frame_host()->GetRenderWidgetHost()->GetView());
@@ -3948,7 +4154,7 @@ class SitePerProcessGestureHitTestBrowserTest
rwhva_root_ = static_cast<RenderWidgetHostViewAura*>(
shell()->web_contents()->GetRenderWidgetHostView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
rwhi_child_ = child_node->current_frame_host()->GetRenderWidgetHost();
rwhi_root_ = root_node->current_frame_host()->GetRenderWidgetHost();
@@ -4069,7 +4275,7 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessGestureHitTestBrowserTest,
rwhva_root_ = static_cast<RenderWidgetHostViewAura*>(
shell()->web_contents()->GetRenderWidgetHostView());
- WaitForChildFrameSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
MainThreadFrameObserver observer(rwhv_child_->GetRenderWidgetHost());
observer.Wait();
@@ -4204,7 +4410,8 @@ IN_PROC_BROWSER_TEST_P(SitePerProcessHitTestBrowserTest, HitTestNestedFrames) {
->GetRenderWidgetHost()
->GetView());
- WaitForChildFrameSurfaceReady(grandchild_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(child_node->current_frame_host());
+ WaitForHitTestDataOrChildSurfaceReady(grandchild_node->current_frame_host());
// Create two points to hit test: One in the child of the main frame, and
// one in the frame nested within that. The hit test request is sent to the
@@ -4285,11 +4492,6 @@ INSTANTIATE_TEST_CASE_P(/* no prefix */,
SitePerProcessMouseWheelHitTestBrowserTest,
testing::Combine(testing::ValuesIn(kHitTestOption),
testing::ValuesIn(kOneScale)));
-INSTANTIATE_TEST_CASE_P(
- /* no prefix */,
- SitePerProcessMouseWheelHitTestBrowserTestWheelScrollLatchingDisabled,
- testing::Combine(testing::ValuesIn(kHitTestOption),
- testing::ValuesIn(kOneScale)));
INSTANTIATE_TEST_CASE_P(/* no prefix */,
SitePerProcessGestureHitTestBrowserTest,
testing::Combine(testing::ValuesIn(kHitTestOption),
diff --git a/chromium/content/browser/site_per_process_mac_browsertest.mm b/chromium/content/browser/site_per_process_mac_browsertest.mm
index dc16103b3aa..ca814f4d223 100644
--- a/chromium/content/browser/site_per_process_mac_browsertest.mm
+++ b/chromium/content/browser/site_per_process_mac_browsertest.mm
@@ -12,6 +12,7 @@
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/hit_test_region_observer.h"
#include "content/public/test/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#import "third_party/ocmock/OCMock/OCMock.h"
@@ -190,28 +191,11 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessMacBrowserTest,
scroll_event.momentum_phase = blink::WebMouseWheelEvent::kPhaseNone;
child_rwhv->ProcessMouseWheelEvent(scroll_event, ui::LatencyInfo());
- // If wheel scroll latching is enabled, no wheel event with phase ended will
- // be sent before a wheel event with momentum phase began. So, no
- // GestureScrollEnd and no GestureScrollBegin will be generated between
- // normal scroll and momentum scroll phases.
- if (!child_rwhv->wheel_scroll_latching_enabled()) {
- // End of non-momentum scrolling.
- scroll_event.delta_y = 0.0f;
- 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();
- }
-
// We now go into a fling.
scroll_event.delta_y = -2.0f;
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseNone;
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();
scroll_event.delta_y = -2.0f;
scroll_event.phase = blink::WebMouseWheelEvent::kPhaseNone;
@@ -294,7 +278,7 @@ void SendMacTouchpadPinchSequenceWithExpectedTarget(
[cocoa_view magnifyWithEvent:pinchEndEvent];
if (ShouldSendGestureEvents())
[cocoa_view endGestureWithEvent:pinchEndEvent];
- EXPECT_EQ(expected_target, router_touchpad_gesture_target);
+ EXPECT_EQ(nullptr, router_touchpad_gesture_target);
}
} // namespace
@@ -318,7 +302,7 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessMacBrowserTest,
// surface information required for event hit testing is ready.
auto* rwhv_child =
static_cast<RenderWidgetHostViewBase*>(child_frame_host->GetView());
- WaitForChildFrameSurfaceReady(child_frame_host);
+ WaitForHitTestDataOrChildSurfaceReady(child_frame_host);
// All touches & gestures are sent to the main frame's view, and should be
// routed appropriately from there.
diff --git a/chromium/content/browser/snapshot_browsertest.cc b/chromium/content/browser/snapshot_browsertest.cc
index 2145e19369f..8577567de1c 100644
--- a/chromium/content/browser/snapshot_browsertest.cc
+++ b/chromium/content/browser/snapshot_browsertest.cc
@@ -76,12 +76,8 @@ class SnapshotBrowserTest : public ContentBrowserTest {
return static_cast<content::WebContentsImpl*>(browser->web_contents());
}
- content::RenderViewHostImpl* GetRenderViewHostImpl(Shell* browser) {
- return GetWebContents(browser)->GetRenderViewHost();
- }
-
content::RenderWidgetHostImpl* GetRenderWidgetHostImpl(Shell* browser) {
- return GetRenderViewHostImpl(browser)->GetWidget();
+ return GetWebContents(browser)->GetRenderViewHost()->GetWidget();
}
void SetupTestServer() {
@@ -230,8 +226,8 @@ IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, SingleWindowTest) {
"#%02x%02x%02x", expected.color.r, expected.color.g, expected.color.b);
std::string script = std::string("fillWithColor(\"") + colorString + "\");";
std::string result;
- EXPECT_TRUE(content::ExecuteScriptAndExtractString(
- GetRenderViewHostImpl(shell()), script, &result));
+ EXPECT_TRUE(content::ExecuteScriptAndExtractString(GetWebContents(shell()),
+ script, &result));
EXPECT_EQ(result, colorString);
expected_snapshots_.push_back(expected);
@@ -256,8 +252,7 @@ IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, SingleWindowTest) {
// 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)) || \
+#if (defined(OS_WIN) && !defined(NDEBUG)) || (defined(OS_CHROMEOS)) || \
(defined(OS_LINUX) && defined(THREAD_SANITIZER))
#define MAYBE_SyncMultiWindowTest DISABLED_SyncMultiWindowTest
#define MAYBE_AsyncMultiWindowTest DISABLED_AsyncMultiWindowTest
@@ -272,7 +267,7 @@ IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_SyncMultiWindowTest) {
for (int i = 0; i < 3; ++i) {
bool result = false;
EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
- GetRenderViewHostImpl(shell()), "openNewWindow()", &result));
+ GetWebContents(shell()), "openNewWindow()", &result));
EXPECT_TRUE(result);
}
@@ -283,7 +278,7 @@ IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_SyncMultiWindowTest) {
auto browser_list = Shell::windows();
EXPECT_EQ(4u, browser_list.size());
- for (int i = 0; i < 40; ++i) {
+ for (int i = 0; i < 20; ++i) {
for (int j = 0; j < 4; j++) {
// Start each iteration by taking a snapshot with a different
// browser instance.
@@ -302,7 +297,7 @@ IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_SyncMultiWindowTest) {
std::string("fillWithColor(\"") + colorString + "\");";
std::string result;
EXPECT_TRUE(content::ExecuteScriptAndExtractString(
- GetRenderViewHostImpl(browser), script, &result));
+ GetWebContents(browser), script, &result));
EXPECT_EQ(result, colorString);
expected_snapshots_.push_back(expected);
// Get the snapshot from the surface rather than the window. The
@@ -327,7 +322,7 @@ IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_AsyncMultiWindowTest) {
for (int i = 0; i < 3; ++i) {
bool result = false;
EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
- GetRenderViewHostImpl(shell()), "openNewWindow()", &result));
+ GetWebContents(shell()), "openNewWindow()", &result));
EXPECT_TRUE(result);
}
@@ -345,7 +340,7 @@ IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_AsyncMultiWindowTest) {
// component type.
int divisor = 3;
- for (int i = 0; i < 20 * divisor; ++i) {
+ for (int i = 0; i < 10 * divisor; ++i) {
for (int j = 0; j < 4; j++) {
// Start each iteration by taking a snapshot with a different
// browser instance.
@@ -370,7 +365,7 @@ IN_PROC_BROWSER_TEST_F(SnapshotBrowserTest, MAYBE_AsyncMultiWindowTest) {
std::string("fillWithColor(\"") + colorString + "\");";
std::string result;
EXPECT_TRUE(content::ExecuteScriptAndExtractString(
- GetRenderViewHostImpl(browser), script, &result));
+ GetWebContents(browser), script, &result));
EXPECT_EQ(result, colorString);
// Get the snapshot from the surface rather than the window. The
// on-screen display path is verified by the GPU tests, and it
diff --git a/chromium/content/browser/speech/chunked_byte_buffer.cc b/chromium/content/browser/speech/chunked_byte_buffer.cc
index ae219c75800..5e3f70c45c6 100644
--- a/chromium/content/browser/speech/chunked_byte_buffer.cc
+++ b/chromium/content/browser/speech/chunked_byte_buffer.cc
@@ -89,7 +89,7 @@ void ChunkedByteBuffer::Append(const uint8_t* start, size_t length) {
total_bytes_stored_ += length;
}
-void ChunkedByteBuffer::Append(const std::string& string) {
+void ChunkedByteBuffer::Append(base::StringPiece string) {
Append(reinterpret_cast<const uint8_t*>(string.data()), string.size());
}
diff --git a/chromium/content/browser/speech/chunked_byte_buffer.h b/chromium/content/browser/speech/chunked_byte_buffer.h
index e6afe40e8cd..98bdd925f3f 100644
--- a/chromium/content/browser/speech/chunked_byte_buffer.h
+++ b/chromium/content/browser/speech/chunked_byte_buffer.h
@@ -13,6 +13,7 @@
#include <vector>
#include "base/macros.h"
+#include "base/strings/string_piece.h"
#include "content/common/content_export.h"
namespace content {
@@ -36,7 +37,7 @@ class CONTENT_EXPORT ChunkedByteBuffer {
void Append(const uint8_t* start, size_t length);
// Appends bytes contained in the |string| to the buffer.
- void Append(const std::string& string);
+ void Append(base::StringPiece string);
// Checks whether one or more complete chunks are available in the buffer.
bool HasChunks() const;
diff --git a/chromium/content/browser/speech/speech_recognition_browsertest.cc b/chromium/content/browser/speech/speech_recognition_browsertest.cc
index 90bf96296dc..3288ddad032 100644
--- a/chromium/content/browser/speech/speech_recognition_browsertest.cc
+++ b/chromium/content/browser/speech/speech_recognition_browsertest.cc
@@ -128,16 +128,18 @@ std::string MakeGoodResponse() {
proto::SpeechRecognitionEvent proto_event;
proto_event.set_status(proto::SpeechRecognitionEvent::STATUS_SUCCESS);
proto::SpeechRecognitionResult* proto_result = proto_event.add_result();
- SpeechRecognitionResult result;
- result.hypotheses.push_back(SpeechRecognitionHypothesis(
+ blink::mojom::SpeechRecognitionResultPtr result =
+ blink::mojom::SpeechRecognitionResult::New();
+ result->hypotheses.push_back(blink::mojom::SpeechRecognitionHypothesis::New(
base::UTF8ToUTF16("Pictures of the moon"), 1.0F));
- proto_result->set_final(!result.is_provisional);
- for (size_t i = 0; i < result.hypotheses.size(); ++i) {
+ proto_result->set_final(!result->is_provisional);
+ for (size_t i = 0; i < result->hypotheses.size(); ++i) {
proto::SpeechRecognitionAlternative* proto_alternative =
proto_result->add_alternative();
- const SpeechRecognitionHypothesis& hypothesis = result.hypotheses[i];
- proto_alternative->set_confidence(hypothesis.confidence);
- proto_alternative->set_transcript(base::UTF16ToUTF8(hypothesis.utterance));
+ const blink::mojom::SpeechRecognitionHypothesisPtr& hypothesis =
+ result->hypotheses[i];
+ proto_alternative->set_confidence(hypothesis->confidence);
+ proto_alternative->set_transcript(base::UTF16ToUTF8(hypothesis->utterance));
}
std::string msg_string;
diff --git a/chromium/content/browser/speech/speech_recognition_dispatcher_host.cc b/chromium/content/browser/speech/speech_recognition_dispatcher_host.cc
index 410717dee0f..4e8664ea9da 100644
--- a/chromium/content/browser/speech/speech_recognition_dispatcher_host.cc
+++ b/chromium/content/browser/speech/speech_recognition_dispatcher_host.cc
@@ -20,18 +20,18 @@
#include "content/public/browser/speech_recognition_manager_delegate.h"
#include "content/public/browser/speech_recognition_session_config.h"
#include "content/public/browser/speech_recognition_session_context.h"
+#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_switches.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
namespace content {
SpeechRecognitionDispatcherHost::SpeechRecognitionDispatcherHost(
int render_process_id,
- int render_frame_id,
- scoped_refptr<net::URLRequestContextGetter> context_getter)
+ int render_frame_id)
: render_process_id_(render_process_id),
render_frame_id_(render_frame_id),
- context_getter_(std::move(context_getter)),
weak_factory_(this) {
// Do not add any non-trivial initialization here, instead do it lazily when
// required (e.g. see the method |SpeechRecognitionManager::GetInstance()|) or
@@ -42,12 +42,10 @@ SpeechRecognitionDispatcherHost::SpeechRecognitionDispatcherHost(
void SpeechRecognitionDispatcherHost::Create(
int render_process_id,
int render_frame_id,
- scoped_refptr<net::URLRequestContextGetter> context_getter,
- mojom::SpeechRecognizerRequest request) {
- mojo::MakeStrongBinding(
- std::make_unique<SpeechRecognitionDispatcherHost>(
- render_process_id, render_frame_id, std::move(context_getter)),
- std::move(request));
+ blink::mojom::SpeechRecognizerRequest request) {
+ mojo::MakeStrongBinding(std::make_unique<SpeechRecognitionDispatcherHost>(
+ render_process_id, render_frame_id),
+ std::move(request));
}
SpeechRecognitionDispatcherHost::~SpeechRecognitionDispatcherHost() {}
@@ -57,10 +55,10 @@ SpeechRecognitionDispatcherHost::AsWeakPtr() {
return weak_factory_.GetWeakPtr();
}
-// -------- mojom::SpeechRecognizer interface implementation ------------------
+// -------- blink::mojom::SpeechRecognizer interface implementation ------------
void SpeechRecognitionDispatcherHost::Start(
- mojom::StartSpeechRecognitionRequestParamsPtr params) {
+ blink::mojom::StartSpeechRecognitionRequestParamsPtr params) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// Check that the origin specified by the renderer process is one
@@ -86,7 +84,7 @@ void SpeechRecognitionDispatcherHost::StartRequestOnUI(
speech_recognition_dispatcher_host,
int render_process_id,
int render_frame_id,
- mojom::StartSpeechRecognitionRequestParamsPtr params) {
+ blink::mojom::StartSpeechRecognitionRequestParamsPtr params) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
int embedder_render_process_id = 0;
int embedder_render_frame_id = MSG_ROUTING_NONE;
@@ -133,19 +131,28 @@ void SpeechRecognitionDispatcherHost::StartRequestOnUI(
->delegate()
->FilterProfanities(embedder_render_process_id);
+ StoragePartition* storage_partition = BrowserContext::GetStoragePartition(
+ web_contents->GetBrowserContext(), web_contents->GetSiteInstance());
+
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
- base::BindOnce(&SpeechRecognitionDispatcherHost::StartSessionOnIO,
- speech_recognition_dispatcher_host, std::move(params),
- embedder_render_process_id, embedder_render_frame_id,
- filter_profanities));
+ base::BindOnce(
+ &SpeechRecognitionDispatcherHost::StartSessionOnIO,
+ speech_recognition_dispatcher_host, std::move(params),
+ embedder_render_process_id, embedder_render_frame_id,
+ filter_profanities,
+ storage_partition->GetURLLoaderFactoryForBrowserProcessIOThread(),
+ base::WrapRefCounted(storage_partition->GetURLRequestContext())));
}
void SpeechRecognitionDispatcherHost::StartSessionOnIO(
- mojom::StartSpeechRecognitionRequestParamsPtr params,
+ blink::mojom::StartSpeechRecognitionRequestParamsPtr params,
int embedder_render_process_id,
int embedder_render_frame_id,
- bool filter_profanities) {
+ bool filter_profanities,
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ shared_url_loader_factory_info,
+ scoped_refptr<net::URLRequestContextGetter> deprecated_context_getter) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
SpeechRecognitionSessionContext context;
@@ -163,13 +170,17 @@ void SpeechRecognitionDispatcherHost::StartSessionOnIO(
config.max_hypotheses = params->max_hypotheses;
config.origin = params->origin;
config.initial_context = context;
- config.url_request_context_getter = context_getter_.get();
+ config.shared_url_loader_factory = network::SharedURLLoaderFactory::Create(
+ std::move(shared_url_loader_factory_info));
+ config.deprecated_url_request_context_getter =
+ std::move(deprecated_context_getter);
config.filter_profanities = filter_profanities;
config.continuous = params->continuous;
config.interim_results = params->interim_results;
config.event_listener = session->AsWeakPtr();
- for (mojom::SpeechRecognitionGrammarPtr& grammar_ptr : params->grammars) {
+ for (blink::mojom::SpeechRecognitionGrammarPtr& grammar_ptr :
+ params->grammars) {
config.grammars.push_back(*grammar_ptr);
}
@@ -186,12 +197,18 @@ void SpeechRecognitionDispatcherHost::StartSessionOnIO(
// ---------------------- SpeechRecognizerSession -----------------------------
SpeechRecognitionSession::SpeechRecognitionSession(
- mojom::SpeechRecognitionSessionClientPtrInfo client_ptr_info)
+ blink::mojom::SpeechRecognitionSessionClientPtrInfo client_ptr_info)
: session_id_(SpeechRecognitionManager::kSessionIDInvalid),
client_(std::move(client_ptr_info)),
+ stopped_(false),
weak_factory_(this) {}
-SpeechRecognitionSession::~SpeechRecognitionSession() = default;
+SpeechRecognitionSession::~SpeechRecognitionSession() {
+ // If a connection error happens and the session hasn't been stopped yet,
+ // abort it.
+ if (!stopped_)
+ Abort();
+}
base::WeakPtr<SpeechRecognitionSession> SpeechRecognitionSession::AsWeakPtr() {
return weak_factory_.GetWeakPtr();
@@ -199,11 +216,13 @@ base::WeakPtr<SpeechRecognitionSession> SpeechRecognitionSession::AsWeakPtr() {
void SpeechRecognitionSession::Abort() {
SpeechRecognitionManager::GetInstance()->AbortSession(session_id_);
+ stopped_ = true;
}
void SpeechRecognitionSession::StopCapture() {
SpeechRecognitionManager::GetInstance()->StopAudioCaptureForSession(
session_id_);
+ stopped_ = true;
}
// -------- SpeechRecognitionEventListener interface implementation -----------
@@ -230,18 +249,20 @@ void SpeechRecognitionSession::OnAudioEnd(int session_id) {
void SpeechRecognitionSession::OnRecognitionEnd(int session_id) {
client_->Ended();
+ stopped_ = true;
+ client_.reset();
}
void SpeechRecognitionSession::OnRecognitionResults(
int session_id,
- const SpeechRecognitionResults& results) {
- client_->ResultRetrieved(results);
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results) {
+ client_->ResultRetrieved(mojo::Clone(results));
}
void SpeechRecognitionSession::OnRecognitionError(
int session_id,
- const SpeechRecognitionError& error) {
- client_->ErrorOccurred(error);
+ const blink::mojom::SpeechRecognitionError& error) {
+ client_->ErrorOccurred(blink::mojom::SpeechRecognitionError::New(error));
}
// The events below are currently not used by speech JS APIs implementation.
diff --git a/chromium/content/browser/speech/speech_recognition_dispatcher_host.h b/chromium/content/browser/speech/speech_recognition_dispatcher_host.h
index bce40c3ad6d..ffa9bd51448 100644
--- a/chromium/content/browser/speech/speech_recognition_dispatcher_host.h
+++ b/chromium/content/browser/speech/speech_recognition_dispatcher_host.h
@@ -10,12 +10,16 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
-#include "content/common/speech_recognizer.mojom.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/speech_recognition_event_listener.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/url_request/url_request_context_getter.h"
+#include "third_party/blink/public/mojom/speech/speech_recognizer.mojom.h"
+
+namespace network {
+class SharedURLLoaderFactoryInfo;
+}
namespace content {
@@ -26,21 +30,18 @@ class SpeechRecognitionManager;
// interface that allows a RenderFrame to start a speech recognition session
// in the browser process, by communicating with SpeechRecognitionManager.
class CONTENT_EXPORT SpeechRecognitionDispatcherHost
- : public mojom::SpeechRecognizer {
+ : public blink::mojom::SpeechRecognizer {
public:
- SpeechRecognitionDispatcherHost(
- int render_process_id,
- int render_frame_id,
- scoped_refptr<net::URLRequestContextGetter> context_getter);
+ SpeechRecognitionDispatcherHost(int render_process_id, int render_frame_id);
~SpeechRecognitionDispatcherHost() override;
static void Create(int render_process_id,
int render_frame_id,
- scoped_refptr<net::URLRequestContextGetter> context_getter,
- mojom::SpeechRecognizerRequest request);
+ blink::mojom::SpeechRecognizerRequest request);
base::WeakPtr<SpeechRecognitionDispatcherHost> AsWeakPtr();
- // mojom::SpeechRecognizer implementation
- void Start(mojom::StartSpeechRecognitionRequestParamsPtr params) override;
+ // blink::mojom::SpeechRecognizer implementation
+ void Start(
+ blink::mojom::StartSpeechRecognitionRequestParamsPtr params) override;
private:
static void StartRequestOnUI(
@@ -48,15 +49,18 @@ class CONTENT_EXPORT SpeechRecognitionDispatcherHost
speech_recognition_dispatcher_host,
int render_process_id,
int render_frame_id,
- mojom::StartSpeechRecognitionRequestParamsPtr params);
- void StartSessionOnIO(mojom::StartSpeechRecognitionRequestParamsPtr params,
- int embedder_render_process_id,
- int embedder_render_frame_id,
- bool filter_profanities);
+ blink::mojom::StartSpeechRecognitionRequestParamsPtr params);
+ void StartSessionOnIO(
+ blink::mojom::StartSpeechRecognitionRequestParamsPtr params,
+ int embedder_render_process_id,
+ int embedder_render_frame_id,
+ bool filter_profanities,
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ shared_url_loader_factory_info,
+ scoped_refptr<net::URLRequestContextGetter> deprecated_context_getter);
const int render_process_id_;
const int render_frame_id_;
- scoped_refptr<net::URLRequestContextGetter> context_getter_;
// Used for posting asynchronous tasks (on the IO thread) without worrying
// about this class being destroyed in the meanwhile (due to browser shutdown)
@@ -66,21 +70,22 @@ class CONTENT_EXPORT SpeechRecognitionDispatcherHost
DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionDispatcherHost);
};
-// SpeechRecognitionSession implements the mojom::SpeechRecognitionSession
-// interface for a particular session. It also acts as a proxy for events sent
-// from SpeechRecognitionManager, and forwards the events to the renderer using
-// a SpeechRecognitionSessionClientPtr (that is passed from the render process).
-class SpeechRecognitionSession : public mojom::SpeechRecognitionSession,
+// SpeechRecognitionSession implements the
+// blink::mojom::SpeechRecognitionSession interface for a particular session. It
+// also acts as a proxy for events sent from SpeechRecognitionManager, and
+// forwards the events to the renderer using a SpeechRecognitionSessionClientPtr
+// (that is passed from the render process).
+class SpeechRecognitionSession : public blink::mojom::SpeechRecognitionSession,
public SpeechRecognitionEventListener {
public:
explicit SpeechRecognitionSession(
- mojom::SpeechRecognitionSessionClientPtrInfo client_ptr_info);
+ blink::mojom::SpeechRecognitionSessionClientPtrInfo client_ptr_info);
~SpeechRecognitionSession() override;
base::WeakPtr<SpeechRecognitionSession> AsWeakPtr();
void SetSessionId(int session_id) { session_id_ = session_id; }
- // mojom::SpeechRecognitionSession implementation.
+ // blink::mojom::SpeechRecognitionSession implementation.
void Abort() override;
void StopCapture() override;
@@ -92,17 +97,21 @@ class SpeechRecognitionSession : public mojom::SpeechRecognitionSession,
void OnSoundEnd(int session_id) override;
void OnAudioEnd(int session_id) override;
void OnRecognitionEnd(int session_id) override;
- void OnRecognitionResults(int session_id,
- const SpeechRecognitionResults& results) override;
- void OnRecognitionError(int session_id,
- const SpeechRecognitionError& error) override;
+ void OnRecognitionResults(
+ int session_id,
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results)
+ override;
+ void OnRecognitionError(
+ int session_id,
+ const blink::mojom::SpeechRecognitionError& error) override;
void OnAudioLevelsChange(int session_id,
float volume,
float noise_volume) override;
private:
int session_id_;
- mojom::SpeechRecognitionSessionClientPtr client_;
+ blink::mojom::SpeechRecognitionSessionClientPtr client_;
+ bool stopped_;
base::WeakPtrFactory<SpeechRecognitionSession> weak_factory_;
};
diff --git a/chromium/content/browser/speech/speech_recognition_engine.cc b/chromium/content/browser/speech/speech_recognition_engine.cc
index e05de0f8484..275129d367e 100644
--- a/chromium/content/browser/speech/speech_recognition_engine.cc
+++ b/chromium/content/browser/speech/speech_recognition_engine.cc
@@ -16,9 +16,9 @@
#include "base/time/time.h"
#include "content/browser/speech/audio_buffer.h"
#include "content/browser/speech/proto/google_streaming_api.pb.h"
-#include "content/public/common/speech_recognition_error.h"
-#include "content/public/common/speech_recognition_result.h"
#include "google_apis/google_api_keys.h"
+#include "mojo/public/c/system/types.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
@@ -27,8 +27,11 @@
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_status.h"
-
-using net::URLFetcher;
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+#include "services/network/public/mojom/chunked_data_pipe_getter.mojom.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
namespace content {
namespace {
@@ -44,6 +47,9 @@ const char* web_service_base_url_for_tests = nullptr;
// This matches the maximum maxAlternatives value supported by the server.
const uint32_t kMaxMaxAlternatives = 30;
+// Maximum amount of data written per Mojo write.
+const uint32_t kMaxUploadWrite = 128 * 1024;
+
// TODO(hans): Remove this and other logging when we don't need it anymore.
void DumpResponse(const std::string& response) {
DVLOG(1) << "------------";
@@ -80,6 +86,197 @@ const uint32_t kDefaultMaxHypotheses = 1;
} // namespace
+// Streams sound data up to the server.
+class SpeechRecognitionEngine::UpstreamLoader
+ : public network::mojom::ChunkedDataPipeGetter {
+ public:
+ UpstreamLoader(std::unique_ptr<network::ResourceRequest> resource_request,
+ net::NetworkTrafficAnnotationTag upstream_traffic_annotation,
+ network::mojom::URLLoaderFactory* url_loader_factory,
+ SpeechRecognitionEngine* speech_recognition_engine)
+ : speech_recognition_engine_(speech_recognition_engine) {
+ // Attach a chunked upload body.
+ network::mojom::ChunkedDataPipeGetterPtr data_pipe;
+ binding_set_.AddBinding(this, mojo::MakeRequest(&data_pipe));
+ resource_request->request_body = new network::ResourceRequestBody();
+ resource_request->request_body->SetToChunkedDataPipe(std::move(data_pipe));
+ simple_url_loader_ = network::SimpleURLLoader::Create(
+ std::move(resource_request), upstream_traffic_annotation);
+ simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+ url_loader_factory,
+ base::BindOnce(&UpstreamLoader::OnComplete, base::Unretained(this)));
+ }
+
+ ~UpstreamLoader() override = default;
+
+ void OnComplete(std::unique_ptr<std::string> response_body) {
+ int response_code = -1;
+ if (simple_url_loader_->ResponseInfo() &&
+ simple_url_loader_->ResponseInfo()->headers) {
+ response_code =
+ simple_url_loader_->ResponseInfo()->headers->response_code();
+ }
+ speech_recognition_engine_->OnUpstreamDataComplete(response_body != nullptr,
+ response_code);
+ }
+
+ void AppendChunkToUpload(const std::string& data, bool is_last_chunk) {
+ DCHECK(!has_last_chunk_);
+
+ upload_body_ += data;
+ if (is_last_chunk) {
+ // Send size before the rest of the body. While it doesn't matter much, if
+ // the other side receives the size before the last chunk, which Mojo does
+ // not gaurantee, some protocols can merge the data and the last chunk
+ // itself into a single frame.
+ has_last_chunk_ = is_last_chunk;
+ if (get_size_callback_)
+ std::move(get_size_callback_).Run(net::OK, upload_body_.size());
+ }
+
+ SendData();
+ }
+
+ private:
+ void OnUploadPipeWriteable(MojoResult unused) { SendData(); }
+
+ // Attempts to send more of the upload body, if more data is available, and
+ // |upload_pipe_| is valid.
+ void SendData() {
+ DCHECK_LE(upload_position_, upload_body_.size());
+
+ if (!upload_pipe_.is_valid())
+ return;
+
+ // Nothing more to write yet, or done writing everything.
+ if (upload_position_ == upload_body_.size())
+ return;
+
+ // Since kMaxUploadWrite is a uint32_t, no overflow occurs in this downcast.
+ uint32_t write_bytes = std::min(upload_body_.length() - upload_position_,
+ static_cast<size_t>(kMaxUploadWrite));
+ MojoResult result =
+ upload_pipe_->WriteData(upload_body_.data() + upload_position_,
+ &write_bytes, MOJO_WRITE_DATA_FLAG_NONE);
+
+ // Wait for the pipe to have more capacity available, if needed.
+ if (result == MOJO_RESULT_SHOULD_WAIT) {
+ upload_pipe_watcher_->ArmOrNotify();
+ return;
+ }
+
+ // Do nothing on pipe closure - depend on the SimpleURLLoader to notice the
+ // other pipes being closed on error. Can reach this point if there's a
+ // retry, for instance, so cannot draw any conclusions here.
+ if (result != MOJO_RESULT_OK)
+ return;
+
+ upload_position_ += write_bytes;
+ // If more data is available, arm the watcher again. Don't write again in a
+ // loop, even if WriteData would allow it, to avoid blocking the current
+ // thread.
+ if (upload_position_ < upload_body_.size())
+ upload_pipe_watcher_->ArmOrNotify();
+ }
+
+ // mojom::ChunkedDataPipeGetter implementation:
+
+ void GetSize(GetSizeCallback get_size_callback) override {
+ if (has_last_chunk_) {
+ std::move(get_size_callback).Run(net::OK, upload_body_.size());
+ } else {
+ get_size_callback_ = std::move(get_size_callback);
+ }
+ }
+
+ void StartReading(mojo::ScopedDataPipeProducerHandle pipe) override {
+ // Delete any existing pipe, if any.
+ upload_pipe_watcher_.reset();
+ upload_pipe_ = std::move(pipe);
+ upload_pipe_watcher_ = std::make_unique<mojo::SimpleWatcher>(
+ FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL);
+ upload_pipe_watcher_->Watch(
+ upload_pipe_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+ base::BindRepeating(&UpstreamLoader::OnUploadPipeWriteable,
+ base::Unretained(this)));
+ upload_position_ = 0;
+
+ // Will attempt to start sending the request body, if any data is available.
+ SendData();
+ }
+
+ // Partial upload body. Have to cache the entire thing in memory, in case have
+ // to replay it.
+ std::string upload_body_;
+ // Current position in |upload_body_|. All bytes before this point have been
+ // written to |upload_pipe_|.
+ size_t upload_position_ = 0;
+ // Whether |upload_body_| is complete.
+ bool has_last_chunk_ = false;
+
+ // Current pipe being used to send the |upload_body_| to the URLLoader.
+ mojo::ScopedDataPipeProducerHandle upload_pipe_;
+ // Watches |upload_pipe_| for writeability.
+ std::unique_ptr<mojo::SimpleWatcher> upload_pipe_watcher_;
+
+ // If non-null, invoked once the size of the upload is known.
+ network::mojom::ChunkedDataPipeGetter::GetSizeCallback get_size_callback_;
+
+ SpeechRecognitionEngine* const speech_recognition_engine_;
+ std::unique_ptr<network::SimpleURLLoader> simple_url_loader_;
+ mojo::BindingSet<network::mojom::ChunkedDataPipeGetter> binding_set_;
+
+ DISALLOW_COPY_AND_ASSIGN(UpstreamLoader);
+};
+
+// Streams response data from the server to the SpeechRecognitionEngine.
+class SpeechRecognitionEngine::DownstreamLoader
+ : public network::SimpleURLLoaderStreamConsumer {
+ public:
+ DownstreamLoader(std::unique_ptr<network::ResourceRequest> resource_request,
+ net::NetworkTrafficAnnotationTag upstream_traffic_annotation,
+ network::mojom::URLLoaderFactory* url_loader_factory,
+ SpeechRecognitionEngine* speech_recognition_engine)
+ : speech_recognition_engine_(speech_recognition_engine) {
+ simple_url_loader_ = network::SimpleURLLoader::Create(
+ std::move(resource_request), upstream_traffic_annotation);
+ simple_url_loader_->DownloadAsStream(url_loader_factory, this);
+ }
+
+ ~DownstreamLoader() override = default;
+
+ // SimpleURLLoaderStreamConsumer implementation:
+
+ void OnDataReceived(base::StringPiece string_piece,
+ base::OnceClosure resume) override {
+ speech_recognition_engine_->OnDownstreamDataReceived(string_piece);
+ std::move(resume).Run();
+ }
+
+ void OnComplete(bool success) override {
+ int response_code = -1;
+ if (simple_url_loader_->ResponseInfo() &&
+ simple_url_loader_->ResponseInfo()->headers) {
+ response_code =
+ simple_url_loader_->ResponseInfo()->headers->response_code();
+ }
+
+ speech_recognition_engine_->OnDownstreamDataComplete(success,
+ response_code);
+ }
+
+ void OnRetry(base::OnceClosure start_retry) override {
+ // Retries are not enabled for these requests.
+ NOTREACHED();
+ }
+
+ private:
+ SpeechRecognitionEngine* const speech_recognition_engine_;
+ std::unique_ptr<network::SimpleURLLoader> simple_url_loader_;
+
+ DISALLOW_COPY_AND_ASSIGN(DownstreamLoader);
+};
+
SpeechRecognitionEngine::Config::Config()
: filter_profanities(false),
continuous(true),
@@ -91,15 +288,16 @@ SpeechRecognitionEngine::Config::Config()
SpeechRecognitionEngine::Config::~Config() {}
const int SpeechRecognitionEngine::kAudioPacketIntervalMs = 100;
-const int SpeechRecognitionEngine::kUpstreamUrlFetcherIdForTesting = 0;
-const int SpeechRecognitionEngine::kDownstreamUrlFetcherIdForTesting = 1;
const int SpeechRecognitionEngine::kWebserviceStatusNoError = 0;
const int SpeechRecognitionEngine::kWebserviceStatusErrorNoMatch = 5;
SpeechRecognitionEngine::SpeechRecognitionEngine(
- net::URLRequestContextGetter* context)
- : url_context_(context),
- previous_response_length_(0),
+ scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory,
+ scoped_refptr<net::URLRequestContextGetter>
+ deprecated_url_request_context_getter)
+ : shared_url_loader_factory_(std::move(shared_url_loader_factory)),
+ deprecated_url_request_context_getter_(
+ std::move(deprecated_url_request_context_getter)),
got_last_definitive_result_(false),
is_dispatching_event_(false),
use_framed_post_data_(false),
@@ -139,64 +337,27 @@ void SpeechRecognitionEngine::AudioChunksEnded() {
DispatchEvent(event_args);
}
-void SpeechRecognitionEngine::OnURLFetchComplete(const URLFetcher* source) {
- const bool kResponseComplete = true;
- DispatchHTTPResponse(source, kResponseComplete);
-}
-
-void SpeechRecognitionEngine::OnURLFetchDownloadProgress(
- const URLFetcher* source,
- int64_t current,
- int64_t total,
- int64_t current_network_bytes) {
- const bool kPartialResponse = false;
- DispatchHTTPResponse(source, kPartialResponse);
-}
-
-void SpeechRecognitionEngine::DispatchHTTPResponse(const URLFetcher* source,
- bool end_of_response) {
+void SpeechRecognitionEngine::OnUpstreamDataComplete(bool success,
+ int response_code) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(source);
- const bool response_is_good = source->GetStatus().is_success() &&
- source->GetResponseCode() == 200;
- std::string response;
- if (response_is_good)
- source->GetResponseAsString(&response);
- const size_t current_response_length = response.size();
-
- DVLOG(1) << (source == downstream_fetcher_.get() ? "Downstream" : "Upstream")
- << "HTTP, code: " << source->GetResponseCode()
- << " length: " << current_response_length
- << " eor: " << end_of_response;
-
- // URLFetcher provides always the entire response buffer, but we are only
- // interested in the fresh data introduced by the last chunk. Therefore, we
- // drop the previous content we have already processed.
- if (current_response_length != 0) {
- DCHECK_GE(current_response_length, previous_response_length_);
- response.erase(0, previous_response_length_);
- previous_response_length_ = current_response_length;
- }
- if (!response_is_good && source == downstream_fetcher_.get()) {
- DVLOG(1) << "Downstream error " << source->GetResponseCode();
- FSMEventArgs event_args(EVENT_DOWNSTREAM_ERROR);
- DispatchEvent(event_args);
- return;
- }
- if (!response_is_good && source == upstream_fetcher_.get()) {
- DVLOG(1) << "Upstream error " << source->GetResponseCode()
- << " EOR " << end_of_response;
+ DVLOG(1) << "Upstream complete success: " << success
+ << " response_code: " << response_code;
+
+ if (!success) {
FSMEventArgs event_args(EVENT_UPSTREAM_ERROR);
DispatchEvent(event_args);
return;
}
- // Ignore incoming data on the upstream connection.
- if (source == upstream_fetcher_.get())
- return;
+ // Do nothing on clean completion of upstream request.
+}
- DCHECK(response_is_good && source == downstream_fetcher_.get());
+void SpeechRecognitionEngine::OnDownstreamDataReceived(
+ base::StringPiece new_response_data) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ DVLOG(1) << "Downstream length: " << new_response_data.size();
// The downstream response is organized in chunks, whose size is determined
// by a 4 bytes prefix, transparently handled by the ChunkedByteBuffer class.
@@ -206,7 +367,7 @@ void SpeechRecognitionEngine::DispatchHTTPResponse(const URLFetcher* source,
// url fetcher. However there isn't any particular matching beween our
// protocol chunks and HTTP chunks, in the sense that a single HTTP chunk can
// contain a portion of one chunk or even more chunks together.
- chunked_byte_buffer_.Append(response);
+ chunked_byte_buffer_.Append(new_response_data);
// A single HTTP chunk can contain more than one data chunk, thus the while.
while (chunked_byte_buffer_.HasChunks()) {
@@ -217,10 +378,23 @@ void SpeechRecognitionEngine::DispatchHTTPResponse(const URLFetcher* source,
event_args.response->end()));
DispatchEvent(event_args);
}
- if (end_of_response) {
- FSMEventArgs event_args(EVENT_DOWNSTREAM_CLOSED);
+}
+
+void SpeechRecognitionEngine::OnDownstreamDataComplete(bool success,
+ int response_code) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ DVLOG(1) << "Downstream complete success: " << success
+ << " response_code: " << response_code;
+
+ if (!success) {
+ FSMEventArgs event_args(EVENT_DOWNSTREAM_ERROR);
DispatchEvent(event_args);
+ return;
}
+
+ FSMEventArgs event_args(EVENT_DOWNSTREAM_CLOSED);
+ DispatchEvent(event_args);
}
bool SpeechRecognitionEngine::IsRecognitionPending() const {
@@ -319,8 +493,8 @@ SpeechRecognitionEngine::ExecuteTransitionAndGetNextState(
SpeechRecognitionEngine::FSMState
SpeechRecognitionEngine::ConnectBothStreams(const FSMEventArgs&) {
- DCHECK(!upstream_fetcher_.get());
- DCHECK(!downstream_fetcher_.get());
+ DCHECK(!upstream_loader_.get());
+ DCHECK(!downstream_loader_.get());
encoder_.reset(new AudioEncoder(config_.audio_sample_rate,
config_.audio_num_bits_per_sample));
@@ -391,14 +565,14 @@ SpeechRecognitionEngine::ConnectBothStreams(const FSMEventArgs&) {
}
}
})");
- downstream_fetcher_ =
- URLFetcher::Create(kDownstreamUrlFetcherIdForTesting, downstream_url,
- URLFetcher::GET, this, downstream_traffic_annotation);
- downstream_fetcher_->SetRequestContext(url_context_.get());
- downstream_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SEND_AUTH_DATA);
- downstream_fetcher_->Start();
+ auto downstream_request = std::make_unique<network::ResourceRequest>();
+ downstream_request->load_flags = net::LOAD_DO_NOT_SAVE_COOKIES |
+ net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SEND_AUTH_DATA;
+ downstream_request->url = downstream_url;
+ downstream_loader_ = std::make_unique<DownstreamLoader>(
+ std::move(downstream_request), downstream_traffic_annotation,
+ shared_url_loader_factory_.get(), this);
// Setup upstream fetcher.
// TODO(hans): Support for user-selected grammars.
@@ -418,7 +592,8 @@ SpeechRecognitionEngine::ConnectBothStreams(const FSMEventArgs&) {
base::UintToString(max_alternatives));
}
upstream_args.push_back("app=chromium");
- for (const mojom::SpeechRecognitionGrammar& grammar : config_.grammars) {
+ for (const blink::mojom::SpeechRecognitionGrammar& grammar :
+ config_.grammars) {
std::string grammar_value(base::NumberToString(grammar.weight) + ":" +
grammar.url.spec());
upstream_args.push_back(
@@ -486,20 +661,25 @@ SpeechRecognitionEngine::ConnectBothStreams(const FSMEventArgs&) {
}
}
})");
- upstream_fetcher_ =
- URLFetcher::Create(kUpstreamUrlFetcherIdForTesting, upstream_url,
- URLFetcher::POST, this, upstream_traffic_annotation);
- if (use_framed_post_data_)
- upstream_fetcher_->SetChunkedUpload("application/octet-stream");
- else
- upstream_fetcher_->SetChunkedUpload(encoder_->GetMimeType());
- upstream_fetcher_->SetRequestContext(url_context_.get());
- upstream_fetcher_->SetReferrer(config_.origin_url);
- upstream_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SEND_AUTH_DATA);
- upstream_fetcher_->Start();
- previous_response_length_ = 0;
+
+ auto upstream_request = std::make_unique<network::ResourceRequest>();
+ upstream_request->url = upstream_url;
+ upstream_request->method = "POST";
+ upstream_request->referrer = GURL(config_.origin_url);
+ upstream_request->load_flags = net::LOAD_DO_NOT_SAVE_COOKIES |
+ net::LOAD_DO_NOT_SEND_COOKIES |
+ net::LOAD_DO_NOT_SEND_AUTH_DATA;
+ if (use_framed_post_data_) {
+ upstream_request->headers.SetHeader(net::HttpRequestHeaders::kContentType,
+ "application/octet-stream");
+ } else {
+ upstream_request->headers.SetHeader(net::HttpRequestHeaders::kContentType,
+ encoder_->GetMimeType());
+ }
+
+ upstream_loader_ = std::make_unique<UpstreamLoader>(
+ std::move(upstream_request), upstream_traffic_annotation,
+ shared_url_loader_factory_.get(), this);
if (preamble_encoder_) {
// Encode and send preamble right away.
@@ -518,7 +698,7 @@ SpeechRecognitionEngine::ConnectBothStreams(const FSMEventArgs&) {
SpeechRecognitionEngine::FSMState
SpeechRecognitionEngine::TransmitAudioUpstream(
const FSMEventArgs& event_args) {
- DCHECK(upstream_fetcher_.get());
+ DCHECK(upstream_loader_.get());
DCHECK(event_args.audio_data.get());
const AudioChunk& audio = *(event_args.audio_data.get());
@@ -544,21 +724,23 @@ SpeechRecognitionEngine::ProcessDownstreamResponse(
case proto::SpeechRecognitionEvent::STATUS_SUCCESS:
break;
case proto::SpeechRecognitionEvent::STATUS_NO_SPEECH:
- return Abort(SPEECH_RECOGNITION_ERROR_NO_SPEECH);
+ return Abort(blink::mojom::SpeechRecognitionErrorCode::kNoSpeech);
case proto::SpeechRecognitionEvent::STATUS_ABORTED:
- return Abort(SPEECH_RECOGNITION_ERROR_ABORTED);
+ return Abort(blink::mojom::SpeechRecognitionErrorCode::kAborted);
case proto::SpeechRecognitionEvent::STATUS_AUDIO_CAPTURE:
- return Abort(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE);
+ return Abort(blink::mojom::SpeechRecognitionErrorCode::kAudioCapture);
case proto::SpeechRecognitionEvent::STATUS_NETWORK:
- return Abort(SPEECH_RECOGNITION_ERROR_NETWORK);
+ return Abort(blink::mojom::SpeechRecognitionErrorCode::kNetwork);
case proto::SpeechRecognitionEvent::STATUS_NOT_ALLOWED:
- return Abort(SPEECH_RECOGNITION_ERROR_NOT_ALLOWED);
+ return Abort(blink::mojom::SpeechRecognitionErrorCode::kNotAllowed);
case proto::SpeechRecognitionEvent::STATUS_SERVICE_NOT_ALLOWED:
- return Abort(SPEECH_RECOGNITION_ERROR_SERVICE_NOT_ALLOWED);
+ return Abort(
+ blink::mojom::SpeechRecognitionErrorCode::kServiceNotAllowed);
case proto::SpeechRecognitionEvent::STATUS_BAD_GRAMMAR:
- return Abort(SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR);
+ return Abort(blink::mojom::SpeechRecognitionErrorCode::kBadGrammar);
case proto::SpeechRecognitionEvent::STATUS_LANGUAGE_NOT_SUPPORTED:
- return Abort(SPEECH_RECOGNITION_ERROR_LANGUAGE_NOT_SUPPORTED);
+ return Abort(
+ blink::mojom::SpeechRecognitionErrorCode::kLanguageNotSupported);
}
}
@@ -567,30 +749,31 @@ SpeechRecognitionEngine::ProcessDownstreamResponse(
delegate_->OnSpeechRecognitionEngineEndOfUtterance();
}
- SpeechRecognitionResults results;
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results;
for (int i = 0; i < ws_event.result_size(); ++i) {
const proto::SpeechRecognitionResult& ws_result = ws_event.result(i);
- results.push_back(SpeechRecognitionResult());
- SpeechRecognitionResult& result = results.back();
- result.is_provisional = !(ws_result.has_final() && ws_result.final());
+ results.push_back(blink::mojom::SpeechRecognitionResult::New());
+ blink::mojom::SpeechRecognitionResultPtr& result = results.back();
+ result->is_provisional = !(ws_result.has_final() && ws_result.final());
- if (!result.is_provisional)
+ if (!result->is_provisional)
got_last_definitive_result_ = true;
for (int j = 0; j < ws_result.alternative_size(); ++j) {
const proto::SpeechRecognitionAlternative& ws_alternative =
ws_result.alternative(j);
- SpeechRecognitionHypothesis hypothesis;
+ blink::mojom::SpeechRecognitionHypothesisPtr hypothesis =
+ blink::mojom::SpeechRecognitionHypothesis::New();
if (ws_alternative.has_confidence())
- hypothesis.confidence = ws_alternative.confidence();
+ hypothesis->confidence = ws_alternative.confidence();
else if (ws_result.has_stability())
- hypothesis.confidence = ws_result.stability();
+ hypothesis->confidence = ws_result.stability();
DCHECK(ws_alternative.has_transcript());
// TODO(hans): Perhaps the transcript should be required in the proto?
if (ws_alternative.has_transcript())
- hypothesis.utterance = base::UTF8ToUTF16(ws_alternative.transcript());
+ hypothesis->utterance = base::UTF8ToUTF16(ws_alternative.transcript());
- result.hypotheses.push_back(hypothesis);
+ result->hypotheses.push_back(std::move(hypothesis));
}
}
if (results.size()) {
@@ -606,7 +789,8 @@ SpeechRecognitionEngine::RaiseNoMatchErrorIfGotNoResults(
if (!got_last_definitive_result_) {
// Provide an empty result to notify that recognition is ended with no
// errors, yet neither any further results.
- delegate_->OnSpeechRecognitionEngineResults(SpeechRecognitionResults());
+ delegate_->OnSpeechRecognitionEngineResults(
+ std::vector<blink::mojom::SpeechRecognitionResultPtr>());
}
return AbortSilently(event_args);
}
@@ -614,7 +798,7 @@ SpeechRecognitionEngine::RaiseNoMatchErrorIfGotNoResults(
SpeechRecognitionEngine::FSMState
SpeechRecognitionEngine::CloseUpstreamAndWaitForResults(
const FSMEventArgs&) {
- DCHECK(upstream_fetcher_.get());
+ DCHECK(upstream_loader_.get());
DCHECK(encoder_.get());
DVLOG(1) << "Closing upstream.";
@@ -641,34 +825,35 @@ SpeechRecognitionEngine::CloseUpstreamAndWaitForResults(
SpeechRecognitionEngine::FSMState
SpeechRecognitionEngine::CloseDownstream(const FSMEventArgs&) {
- DCHECK(!upstream_fetcher_.get());
- DCHECK(downstream_fetcher_.get());
+ DCHECK(!upstream_loader_.get());
+ DCHECK(downstream_loader_.get());
DVLOG(1) << "Closing downstream.";
- downstream_fetcher_.reset();
+ downstream_loader_.reset();
return STATE_IDLE;
}
SpeechRecognitionEngine::FSMState
SpeechRecognitionEngine::AbortSilently(const FSMEventArgs&) {
- return Abort(SPEECH_RECOGNITION_ERROR_NONE);
+ return Abort(blink::mojom::SpeechRecognitionErrorCode::kNone);
}
SpeechRecognitionEngine::FSMState
SpeechRecognitionEngine::AbortWithError(const FSMEventArgs&) {
- return Abort(SPEECH_RECOGNITION_ERROR_NETWORK);
+ return Abort(blink::mojom::SpeechRecognitionErrorCode::kNetwork);
}
SpeechRecognitionEngine::FSMState SpeechRecognitionEngine::Abort(
- SpeechRecognitionErrorCode error_code) {
+ blink::mojom::SpeechRecognitionErrorCode error_code) {
DVLOG(1) << "Aborting with error " << error_code;
- if (error_code != SPEECH_RECOGNITION_ERROR_NONE) {
+ if (error_code != blink::mojom::SpeechRecognitionErrorCode::kNone) {
delegate_->OnSpeechRecognitionEngineError(
- SpeechRecognitionError(error_code));
+ blink::mojom::SpeechRecognitionError(
+ error_code, blink::mojom::SpeechAudioErrorDetails::kNone));
}
- downstream_fetcher_.reset();
- upstream_fetcher_.reset();
+ downstream_loader_.reset();
+ upstream_loader_.reset();
encoder_.reset();
return STATE_IDLE;
}
@@ -687,12 +872,12 @@ SpeechRecognitionEngine::NotFeasible(const FSMEventArgs& event_args) {
std::string SpeechRecognitionEngine::GetAcceptedLanguages() const {
std::string langs = config_.language;
- if (langs.empty() && url_context_.get()) {
+ if (langs.empty() && deprecated_url_request_context_getter_.get()) {
// If no language is provided then we use the first from the accepted
// language list. If this list is empty then it defaults to "en-US".
// Example of the contents of this list: "es,en-GB;q=0.8", ""
net::URLRequestContext* request_context =
- url_context_->GetURLRequestContext();
+ deprecated_url_request_context_getter_->GetURLRequestContext();
DCHECK(request_context);
// TODO(pauljensen): SpeechRecognitionEngine should be constructed with
// a reference to the HttpUserAgentSettings rather than accessing the
@@ -730,9 +915,9 @@ void SpeechRecognitionEngine::UploadAudioChunk(const std::string& data,
base::WriteBigEndian(&frame[0], static_cast<uint32_t>(data.size()));
base::WriteBigEndian(&frame[4], static_cast<uint32_t>(type));
frame.replace(8, data.size(), data);
- upstream_fetcher_->AppendChunkToUpload(frame, is_final);
+ upstream_loader_->AppendChunkToUpload(frame, is_final);
} else {
- upstream_fetcher_->AppendChunkToUpload(data, is_final);
+ upstream_loader_->AppendChunkToUpload(data, is_final);
}
}
diff --git a/chromium/content/browser/speech/speech_recognition_engine.h b/chromium/content/browser/speech/speech_recognition_engine.h
index 8a28cb6f86a..5119585cdd2 100644
--- a/chromium/content/browser/speech/speech_recognition_engine.h
+++ b/chromium/content/browser/speech/speech_recognition_engine.h
@@ -13,19 +13,25 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
+#include "base/strings/string_piece.h"
#include "content/browser/speech/audio_encoder.h"
#include "content/browser/speech/chunked_byte_buffer.h"
#include "content/common/content_export.h"
#include "content/public/browser/speech_recognition_session_preamble.h"
-#include "content/public/common/speech_recognition_error.h"
-#include "content/public/common/speech_recognition_grammar.mojom.h"
-#include "content/public/common/speech_recognition_result.h"
-#include "net/url_request/url_fetcher_delegate.h"
+#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_grammar.mojom.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
namespace net {
class URLRequestContextGetter;
}
+namespace network {
+class SharedURLLoaderFactory;
+}
+
namespace content {
class AudioChunk;
@@ -57,16 +63,17 @@ struct SpeechRecognitionError;
// EndRecognition. If a recognition was started, the caller can free the
// SpeechRecognitionEngine only after calling EndRecognition.
-class CONTENT_EXPORT SpeechRecognitionEngine : public net::URLFetcherDelegate {
+class CONTENT_EXPORT SpeechRecognitionEngine {
public:
class Delegate {
public:
// Called whenever a result is retrieved.
virtual void OnSpeechRecognitionEngineResults(
- const SpeechRecognitionResults& results) = 0;
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>&
+ results) = 0;
virtual void OnSpeechRecognitionEngineEndOfUtterance() = 0;
virtual void OnSpeechRecognitionEngineError(
- const SpeechRecognitionError& error) = 0;
+ const blink::mojom::SpeechRecognitionError& error) = 0;
protected:
virtual ~Delegate() {}
@@ -78,7 +85,7 @@ class CONTENT_EXPORT SpeechRecognitionEngine : public net::URLFetcherDelegate {
~Config();
std::string language;
- std::vector<mojom::SpeechRecognitionGrammar> grammars;
+ std::vector<blink::mojom::SpeechRecognitionGrammar> grammars;
bool filter_profanities;
bool continuous;
bool interim_results;
@@ -97,12 +104,15 @@ class CONTENT_EXPORT SpeechRecognitionEngine : public net::URLFetcherDelegate {
// Duration of each audio packet.
static const int kAudioPacketIntervalMs;
- // IDs passed to URLFetcher::Create(). Used for testing.
- static const int kUpstreamUrlFetcherIdForTesting;
- static const int kDownstreamUrlFetcherIdForTesting;
-
- explicit SpeechRecognitionEngine(net::URLRequestContextGetter* context);
- ~SpeechRecognitionEngine() override;
+ // |deprecated_url_request_context_getter| is only for poking at the
+ // Accept-Language header.
+ // TODO(mmenke): Remove |deprecated_url_request_context_getter| as an
+ // argument.
+ SpeechRecognitionEngine(
+ scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory,
+ scoped_refptr<net::URLRequestContextGetter>
+ deprecated_url_request_context_getter);
+ ~SpeechRecognitionEngine();
// Sets the URL requests are sent to for tests.
static void set_web_service_base_url_for_tests(
@@ -116,14 +126,10 @@ class CONTENT_EXPORT SpeechRecognitionEngine : public net::URLFetcherDelegate {
bool IsRecognitionPending() const;
int GetDesiredAudioChunkDurationMs() const;
- // net::URLFetcherDelegate methods.
- void OnURLFetchComplete(const net::URLFetcher* source) override;
- void OnURLFetchDownloadProgress(const net::URLFetcher* source,
- int64_t current,
- int64_t total,
- int64_t current_network_bytes) override;
-
private:
+ class UpstreamLoader;
+ class DownstreamLoader;
+
Delegate* delegate_;
// Response status codes from the speech recognition webservice.
@@ -173,10 +179,10 @@ class CONTENT_EXPORT SpeechRecognitionEngine : public net::URLFetcherDelegate {
DISALLOW_COPY_AND_ASSIGN(FSMEventArgs);
};
- // Invoked by both upstream and downstream URLFetcher callbacks to handle
- // new chunk data, connection closed or errors notifications.
- void DispatchHTTPResponse(const net::URLFetcher* source,
- bool end_of_response);
+ void OnUpstreamDataComplete(bool success, int response_code);
+
+ void OnDownstreamDataReceived(base::StringPiece new_response_data);
+ void OnDownstreamDataComplete(bool success, int response_code);
// Entry point for pushing any new external event into the recognizer FSM.
void DispatchEvent(const FSMEventArgs& event_args);
@@ -194,7 +200,7 @@ class CONTENT_EXPORT SpeechRecognitionEngine : public net::URLFetcherDelegate {
FSMState CloseDownstream(const FSMEventArgs& event_args);
FSMState AbortSilently(const FSMEventArgs& event_args);
FSMState AbortWithError(const FSMEventArgs& event_args);
- FSMState Abort(SpeechRecognitionErrorCode error);
+ FSMState Abort(blink::mojom::SpeechRecognitionErrorCode error);
FSMState DoNothing(const FSMEventArgs& event_args);
FSMState NotFeasible(const FSMEventArgs& event_args);
@@ -206,13 +212,14 @@ class CONTENT_EXPORT SpeechRecognitionEngine : public net::URLFetcherDelegate {
void UploadAudioChunk(const std::string& data, FrameType type, bool is_final);
Config config_;
- std::unique_ptr<net::URLFetcher> upstream_fetcher_;
- std::unique_ptr<net::URLFetcher> downstream_fetcher_;
- scoped_refptr<net::URLRequestContextGetter> url_context_;
+ std::unique_ptr<UpstreamLoader> upstream_loader_;
+ std::unique_ptr<DownstreamLoader> downstream_loader_;
+ scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;
+ scoped_refptr<net::URLRequestContextGetter>
+ deprecated_url_request_context_getter_;
std::unique_ptr<AudioEncoder> encoder_;
std::unique_ptr<AudioEncoder> preamble_encoder_;
ChunkedByteBuffer chunked_byte_buffer_;
- size_t previous_response_length_;
bool got_last_definitive_result_;
bool is_dispatching_event_;
bool use_framed_post_data_;
diff --git a/chromium/content/browser/speech/speech_recognition_engine_unittest.cc b/chromium/content/browser/speech/speech_recognition_engine_unittest.cc
index fd880ae2d36..e5cc0943b11 100644
--- a/chromium/content/browser/speech/speech_recognition_engine_unittest.cc
+++ b/chromium/content/browser/speech/speech_recognition_engine_unittest.cc
@@ -17,19 +17,20 @@
#include "base/sys_byteorder.h"
#include "content/browser/speech/audio_buffer.h"
#include "content/browser/speech/proto/google_streaming_api.pb.h"
-#include "content/public/common/speech_recognition_error.h"
-#include "content/public/common/speech_recognition_result.h"
#include "net/base/net_errors.h"
-#include "net/url_request/test_url_fetcher_factory.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_util.h"
#include "net/url_request/url_request_context_getter.h"
-#include "net/url_request/url_request_status.h"
+#include "services/network/public/cpp/resource_response.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
using base::HostToNet32;
using base::checked_cast;
-using net::URLRequestStatus;
-using net::TestURLFetcher;
-using net::TestURLFetcherFactory;
namespace content {
@@ -46,23 +47,20 @@ class SpeechRecognitionEngineTest
public:
SpeechRecognitionEngineTest()
: last_number_of_upstream_chunks_seen_(0U),
- error_(SPEECH_RECOGNITION_ERROR_NONE),
- end_of_utterance_counter_(0) { }
-
- // Creates a speech recognition request and invokes its URL fetcher delegate
- // with the given test data.
- void CreateAndTestRequest(bool success, const std::string& http_response);
+ error_(blink::mojom::SpeechRecognitionErrorCode::kNone),
+ end_of_utterance_counter_(0) {}
// SpeechRecognitionRequestDelegate methods.
void OnSpeechRecognitionEngineResults(
- const SpeechRecognitionResults& results) override {
- results_.push(results);
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results)
+ override {
+ results_.push(mojo::Clone(results));
}
void OnSpeechRecognitionEngineEndOfUtterance() override {
++end_of_utterance_counter_;
}
void OnSpeechRecognitionEngineError(
- const SpeechRecognitionError& error) override {
+ const blink::mojom::SpeechRecognitionError& error) override {
error_ = error.code;
}
@@ -77,62 +75,72 @@ class SpeechRecognitionEngineTest
DOWNSTREAM_ERROR_NETWORK,
DOWNSTREAM_ERROR_WEBSERVICE_NO_MATCH
};
- static bool ResultsAreEqual(const SpeechRecognitionResults& a,
- const SpeechRecognitionResults& b);
+ static bool ResultsAreEqual(
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& a,
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& b);
static std::string SerializeProtobufResponse(
const proto::SpeechRecognitionEvent& msg);
- TestURLFetcher* GetUpstreamFetcher();
- TestURLFetcher* GetDownstreamFetcher();
+ const network::TestURLLoaderFactory::PendingRequest* GetUpstreamRequest();
+ const network::TestURLLoaderFactory::PendingRequest* GetDownstreamRequest();
void StartMockRecognition();
void EndMockRecognition();
void InjectDummyAudioChunk();
- size_t UpstreamChunksUploadedFromLastCall();
- std::string LastUpstreamChunkUploaded();
+ void ProvideMockResponseStartDownstreamIfNeeded();
void ProvideMockProtoResultDownstream(
const proto::SpeechRecognitionEvent& result);
- void ProvideMockResultDownstream(const SpeechRecognitionResult& result);
- void ExpectResultsReceived(const SpeechRecognitionResults& result);
+ void ProvideMockResultDownstream(
+ const blink::mojom::SpeechRecognitionResultPtr& result);
+ void ExpectResultsReceived(
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& result);
void ExpectFramedChunk(const std::string& chunk, uint32_t type);
+ // Reads and returns all pending upload data from |upstream_data_pipe_|,
+ // initializing the pipe from |GetUpstreamRequest()|, if needed.
+ std::string ConsumeChunkedUploadData();
void CloseMockDownstream(DownstreamError error);
+ base::MessageLoop message_loop_;
+
+ network::TestURLLoaderFactory url_loader_factory_;
+ mojo::ScopedDataPipeProducerHandle downstream_data_pipe_;
+ network::mojom::ChunkedDataPipeGetterPtr chunked_data_pipe_getter_;
+ mojo::ScopedDataPipeConsumerHandle upstream_data_pipe_;
+
std::unique_ptr<SpeechRecognitionEngine> engine_under_test_;
- TestURLFetcherFactory url_fetcher_factory_;
size_t last_number_of_upstream_chunks_seen_;
- base::MessageLoop message_loop_;
std::string response_buffer_;
- SpeechRecognitionErrorCode error_;
+ blink::mojom::SpeechRecognitionErrorCode error_;
int end_of_utterance_counter_;
- base::queue<SpeechRecognitionResults> results_;
+ base::queue<std::vector<blink::mojom::SpeechRecognitionResultPtr>> results_;
};
TEST_F(SpeechRecognitionEngineTest, SingleDefinitiveResult) {
StartMockRecognition();
- ASSERT_TRUE(GetUpstreamFetcher());
- ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_TRUE(GetUpstreamRequest());
+ ASSERT_EQ("", ConsumeChunkedUploadData());
// Inject some dummy audio chunks and check a corresponding chunked upload
// is performed every time on the server.
for (int i = 0; i < 3; ++i) {
InjectDummyAudioChunk();
- ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_FALSE(ConsumeChunkedUploadData().empty());
}
// Ensure that a final (empty) audio chunk is uploaded on chunks end.
engine_under_test_->AudioChunksEnded();
- ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_FALSE(ConsumeChunkedUploadData().empty());
ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
// Simulate a protobuf message streamed from the server containing a single
// result with two hypotheses.
- SpeechRecognitionResults results;
- results.push_back(SpeechRecognitionResult());
- SpeechRecognitionResult& result = results.back();
- result.is_provisional = false;
- result.hypotheses.push_back(
- SpeechRecognitionHypothesis(base::UTF8ToUTF16("hypothesis 1"), 0.1F));
- result.hypotheses.push_back(
- SpeechRecognitionHypothesis(base::UTF8ToUTF16("hypothesis 2"), 0.2F));
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results;
+ results.push_back(blink::mojom::SpeechRecognitionResult::New());
+ blink::mojom::SpeechRecognitionResultPtr& result = results.back();
+ result->is_provisional = false;
+ result->hypotheses.push_back(blink::mojom::SpeechRecognitionHypothesis::New(
+ base::UTF8ToUTF16("hypothesis 1"), 0.1F));
+ result->hypotheses.push_back(blink::mojom::SpeechRecognitionHypothesis::New(
+ base::UTF8ToUTF16("hypothesis 2"), 0.2F));
ProvideMockResultDownstream(result);
ExpectResultsReceived(results);
@@ -142,25 +150,25 @@ TEST_F(SpeechRecognitionEngineTest, SingleDefinitiveResult) {
CloseMockDownstream(DOWNSTREAM_ERROR_NONE);
ASSERT_FALSE(engine_under_test_->IsRecognitionPending());
EndMockRecognition();
- ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ ASSERT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
ASSERT_EQ(0U, results_.size());
}
TEST_F(SpeechRecognitionEngineTest, SeveralStreamingResults) {
StartMockRecognition();
- ASSERT_TRUE(GetUpstreamFetcher());
- ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_TRUE(GetUpstreamRequest());
+ ASSERT_EQ("", ConsumeChunkedUploadData());
for (int i = 0; i < 4; ++i) {
InjectDummyAudioChunk();
- ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
-
- SpeechRecognitionResults results;
- results.push_back(SpeechRecognitionResult());
- SpeechRecognitionResult& result = results.back();
- result.is_provisional = (i % 2 == 0); // Alternate result types.
- float confidence = result.is_provisional ? 0.0F : (i * 0.1F);
- result.hypotheses.push_back(SpeechRecognitionHypothesis(
+ ASSERT_NE("", ConsumeChunkedUploadData());
+
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results;
+ results.push_back(blink::mojom::SpeechRecognitionResult::New());
+ blink::mojom::SpeechRecognitionResultPtr& result = results.back();
+ result->is_provisional = (i % 2 == 0); // Alternate result types.
+ float confidence = result->is_provisional ? 0.0F : (i * 0.1F);
+ result->hypotheses.push_back(blink::mojom::SpeechRecognitionHypothesis::New(
base::UTF8ToUTF16("hypothesis"), confidence));
ProvideMockResultDownstream(result);
@@ -170,16 +178,16 @@ TEST_F(SpeechRecognitionEngineTest, SeveralStreamingResults) {
// Ensure that a final (empty) audio chunk is uploaded on chunks end.
engine_under_test_->AudioChunksEnded();
- ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_NE("", ConsumeChunkedUploadData());
ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
// Simulate a final definitive result.
- SpeechRecognitionResults results;
- results.push_back(SpeechRecognitionResult());
- SpeechRecognitionResult& result = results.back();
- result.is_provisional = false;
- result.hypotheses.push_back(
- SpeechRecognitionHypothesis(base::UTF8ToUTF16("The final result"), 1.0F));
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results;
+ results.push_back(blink::mojom::SpeechRecognitionResult::New());
+ blink::mojom::SpeechRecognitionResultPtr& result = results.back();
+ result->is_provisional = false;
+ result->hypotheses.push_back(blink::mojom::SpeechRecognitionHypothesis::New(
+ base::UTF8ToUTF16("The final result"), 1.0F));
ProvideMockResultDownstream(result);
ExpectResultsReceived(results);
ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
@@ -188,65 +196,122 @@ TEST_F(SpeechRecognitionEngineTest, SeveralStreamingResults) {
CloseMockDownstream(DOWNSTREAM_ERROR_NONE);
ASSERT_FALSE(engine_under_test_->IsRecognitionPending());
EndMockRecognition();
- ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ ASSERT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
ASSERT_EQ(0U, results_.size());
}
TEST_F(SpeechRecognitionEngineTest, NoFinalResultAfterAudioChunksEnded) {
StartMockRecognition();
- ASSERT_TRUE(GetUpstreamFetcher());
- ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_TRUE(GetUpstreamRequest());
+ ASSERT_EQ("", ConsumeChunkedUploadData());
// Simulate one pushed audio chunk.
InjectDummyAudioChunk();
- ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_NE("", ConsumeChunkedUploadData());
// Simulate the corresponding definitive result.
- SpeechRecognitionResults results;
- results.push_back(SpeechRecognitionResult());
- SpeechRecognitionResult& result = results.back();
- result.hypotheses.push_back(
- SpeechRecognitionHypothesis(base::UTF8ToUTF16("hypothesis"), 1.0F));
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results;
+ results.push_back(blink::mojom::SpeechRecognitionResult::New());
+ blink::mojom::SpeechRecognitionResultPtr& result = results.back();
+ result->hypotheses.push_back(blink::mojom::SpeechRecognitionHypothesis::New(
+ base::UTF8ToUTF16("hypothesis"), 1.0F));
ProvideMockResultDownstream(result);
ExpectResultsReceived(results);
ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
// Simulate a silent downstream closure after |AudioChunksEnded|.
engine_under_test_->AudioChunksEnded();
- ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_NE("", ConsumeChunkedUploadData());
ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
CloseMockDownstream(DOWNSTREAM_ERROR_NONE);
// Expect an empty result, aimed at notifying recognition ended with no
// actual results nor errors.
- SpeechRecognitionResults empty_results;
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> empty_results;
ExpectResultsReceived(empty_results);
// Ensure everything is closed cleanly after the downstream is closed.
ASSERT_FALSE(engine_under_test_->IsRecognitionPending());
EndMockRecognition();
- ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ ASSERT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
+ ASSERT_EQ(0U, results_.size());
+}
+
+// Simulate the network service repeatedly re-requesting data (Possibly due to
+// using a stale socket, for instance).
+TEST_F(SpeechRecognitionEngineTest, ReRequestData) {
+ StartMockRecognition();
+ ASSERT_TRUE(GetUpstreamRequest());
+ ASSERT_EQ("", ConsumeChunkedUploadData());
+
+ // Simulate one pushed audio chunk.
+ InjectDummyAudioChunk();
+ std::string uploaded_data = ConsumeChunkedUploadData();
+ ASSERT_NE(uploaded_data, ConsumeChunkedUploadData());
+
+ // The network service closes the data pipe.
+ upstream_data_pipe_.reset();
+
+ // Re-opening the data pipe should result in the data being re-uploaded.
+ ASSERT_EQ(uploaded_data, ConsumeChunkedUploadData());
+
+ // Simulate the corresponding definitive result.
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results;
+ results.push_back(blink::mojom::SpeechRecognitionResult::New());
+ blink::mojom::SpeechRecognitionResultPtr& result = results.back();
+ result->hypotheses.push_back(blink::mojom::SpeechRecognitionHypothesis::New(
+ base::UTF8ToUTF16("hypothesis"), 1.0F));
+ ProvideMockResultDownstream(result);
+ ExpectResultsReceived(results);
+ ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
+
+ // Simulate a silent downstream closure after |AudioChunksEnded|.
+ engine_under_test_->AudioChunksEnded();
+ std::string new_uploaded_data = ConsumeChunkedUploadData();
+ ASSERT_NE(new_uploaded_data, ConsumeChunkedUploadData());
+ uploaded_data += new_uploaded_data;
+
+ // The network service closes the data pipe.
+ upstream_data_pipe_.reset();
+
+ // Re-opening the data pipe should result in the data being re-uploaded.
+ ASSERT_EQ(uploaded_data, ConsumeChunkedUploadData());
+
+ ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
+ CloseMockDownstream(DOWNSTREAM_ERROR_NONE);
+
+ // Expect an empty result, aimed at notifying recognition ended with no
+ // actual results nor errors.
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> empty_results;
+ ExpectResultsReceived(empty_results);
+
+ // Ensure everything is closed cleanly after the downstream is closed.
+ ASSERT_FALSE(engine_under_test_->IsRecognitionPending());
+ EndMockRecognition();
+ ASSERT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
ASSERT_EQ(0U, results_.size());
}
TEST_F(SpeechRecognitionEngineTest, NoMatchError) {
StartMockRecognition();
- ASSERT_TRUE(GetUpstreamFetcher());
- ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_TRUE(GetUpstreamRequest());
+ ASSERT_EQ("", ConsumeChunkedUploadData());
- for (int i = 0; i < 3; ++i)
+ for (int i = 0; i < 3; ++i) {
InjectDummyAudioChunk();
+ ASSERT_NE("", ConsumeChunkedUploadData());
+ }
engine_under_test_->AudioChunksEnded();
- ASSERT_EQ(4U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_NE("", ConsumeChunkedUploadData());
ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
// Simulate only a provisional result.
- SpeechRecognitionResults results;
- results.push_back(SpeechRecognitionResult());
- SpeechRecognitionResult& result = results.back();
- result.is_provisional = true;
- result.hypotheses.push_back(
- SpeechRecognitionHypothesis(base::UTF8ToUTF16("The final result"), 0.0F));
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results;
+ results.push_back(blink::mojom::SpeechRecognitionResult::New());
+ blink::mojom::SpeechRecognitionResultPtr& result = results.back();
+ result->is_provisional = true;
+ result->hypotheses.push_back(blink::mojom::SpeechRecognitionHypothesis::New(
+ base::UTF8ToUTF16("The final result"), 0.0F));
ProvideMockResultDownstream(result);
ExpectResultsReceived(results);
ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
@@ -256,54 +321,56 @@ TEST_F(SpeechRecognitionEngineTest, NoMatchError) {
// Expect an empty result.
ASSERT_FALSE(engine_under_test_->IsRecognitionPending());
EndMockRecognition();
- SpeechRecognitionResults empty_result;
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> empty_result;
ExpectResultsReceived(empty_result);
}
TEST_F(SpeechRecognitionEngineTest, HTTPError) {
StartMockRecognition();
- ASSERT_TRUE(GetUpstreamFetcher());
- ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_TRUE(GetUpstreamRequest());
+ ASSERT_EQ("", ConsumeChunkedUploadData());
InjectDummyAudioChunk();
- ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_NE("", ConsumeChunkedUploadData());
// Close the downstream with a HTTP 500 error.
CloseMockDownstream(DOWNSTREAM_ERROR_HTTP500);
- // Expect a SPEECH_RECOGNITION_ERROR_NETWORK error to be raised.
+ // Expect a blink::mojom::SpeechRecognitionErrorCode::kNetwork error to be
+ // raised.
ASSERT_FALSE(engine_under_test_->IsRecognitionPending());
EndMockRecognition();
- ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NETWORK, error_);
+ ASSERT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNetwork, error_);
ASSERT_EQ(0U, results_.size());
}
TEST_F(SpeechRecognitionEngineTest, NetworkError) {
StartMockRecognition();
- ASSERT_TRUE(GetUpstreamFetcher());
- ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_TRUE(GetUpstreamRequest());
+ ASSERT_EQ("", ConsumeChunkedUploadData());
InjectDummyAudioChunk();
- ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_NE("", ConsumeChunkedUploadData());
// Close the downstream fetcher simulating a network failure.
CloseMockDownstream(DOWNSTREAM_ERROR_NETWORK);
- // Expect a SPEECH_RECOGNITION_ERROR_NETWORK error to be raised.
+ // Expect a blink::mojom::SpeechRecognitionErrorCode::kNetwork error to be
+ // raised.
ASSERT_FALSE(engine_under_test_->IsRecognitionPending());
EndMockRecognition();
- ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NETWORK, error_);
+ ASSERT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNetwork, error_);
ASSERT_EQ(0U, results_.size());
}
TEST_F(SpeechRecognitionEngineTest, Stability) {
StartMockRecognition();
- ASSERT_TRUE(GetUpstreamFetcher());
- ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_TRUE(GetUpstreamRequest());
+ ASSERT_EQ("", ConsumeChunkedUploadData());
// Upload a dummy audio chunk.
InjectDummyAudioChunk();
- ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
+ ASSERT_NE("", ConsumeChunkedUploadData());
engine_under_test_->AudioChunksEnded();
// Simulate a protobuf message with an intermediate result without confidence,
@@ -318,12 +385,12 @@ TEST_F(SpeechRecognitionEngineTest, Stability) {
ProvideMockProtoResultDownstream(proto_event);
// Set up expectations.
- SpeechRecognitionResults results;
- results.push_back(SpeechRecognitionResult());
- SpeechRecognitionResult& result = results.back();
- result.is_provisional = true;
- result.hypotheses.push_back(
- SpeechRecognitionHypothesis(base::UTF8ToUTF16("foo"), 0.5));
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results;
+ results.push_back(blink::mojom::SpeechRecognitionResult::New());
+ blink::mojom::SpeechRecognitionResultPtr& result = results.back();
+ result->is_provisional = true;
+ result->hypotheses.push_back(blink::mojom::SpeechRecognitionHypothesis::New(
+ base::UTF8ToUTF16("foo"), 0.5));
// Check that the protobuf generated the expected result.
ExpectResultsReceived(results);
@@ -337,15 +404,15 @@ TEST_F(SpeechRecognitionEngineTest, Stability) {
EndMockRecognition();
// Since there was no final result, we get an empty "no match" result.
- SpeechRecognitionResults empty_result;
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> empty_result;
ExpectResultsReceived(empty_result);
- ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ ASSERT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
ASSERT_EQ(0U, results_.size());
}
TEST_F(SpeechRecognitionEngineTest, EndOfUtterance) {
StartMockRecognition();
- ASSERT_TRUE(GetUpstreamFetcher());
+ ASSERT_TRUE(GetUpstreamRequest());
// Simulate a END_OF_UTTERANCE proto event with continuous true.
SpeechRecognitionEngine::Config config;
@@ -382,16 +449,16 @@ TEST_F(SpeechRecognitionEngineTest, SendPreamble) {
engine_under_test_->SetConfig(config);
StartMockRecognition();
- ASSERT_TRUE(GetUpstreamFetcher());
+ ASSERT_TRUE(GetUpstreamRequest());
// First chunk uploaded should be the preamble.
- ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
- std::string chunk = LastUpstreamChunkUploaded();
+ std::string chunk = ConsumeChunkedUploadData();
+ ASSERT_NE("", chunk);
ExpectFramedChunk(chunk, kFrameTypePreamble);
for (int i = 0; i < 3; ++i) {
InjectDummyAudioChunk();
- ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall());
- chunk = LastUpstreamChunkUploaded();
+ chunk = ConsumeChunkedUploadData();
+ ASSERT_NE("", chunk);
ExpectFramedChunk(chunk, kFrameTypeRecognitionAudio);
}
engine_under_test_->AudioChunksEnded();
@@ -399,12 +466,12 @@ TEST_F(SpeechRecognitionEngineTest, SendPreamble) {
// Simulate a protobuf message streamed from the server containing a single
// result with one hypotheses.
- SpeechRecognitionResults results;
- results.push_back(SpeechRecognitionResult());
- SpeechRecognitionResult& result = results.back();
- result.is_provisional = false;
- result.hypotheses.push_back(
- SpeechRecognitionHypothesis(base::UTF8ToUTF16("hypothesis 1"), 0.1F));
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results;
+ results.push_back(blink::mojom::SpeechRecognitionResult::New());
+ blink::mojom::SpeechRecognitionResultPtr& result = results.back();
+ result->is_provisional = false;
+ result->hypotheses.push_back(blink::mojom::SpeechRecognitionHypothesis::New(
+ base::UTF8ToUTF16("hypothesis 1"), 0.1F));
ProvideMockResultDownstream(result);
ExpectResultsReceived(results);
@@ -414,13 +481,15 @@ TEST_F(SpeechRecognitionEngineTest, SendPreamble) {
CloseMockDownstream(DOWNSTREAM_ERROR_NONE);
ASSERT_FALSE(engine_under_test_->IsRecognitionPending());
EndMockRecognition();
- ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ ASSERT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
ASSERT_EQ(0U, results_.size());
}
void SpeechRecognitionEngineTest::SetUp() {
- engine_under_test_.reset(
- new SpeechRecognitionEngine(nullptr /*URLRequestContextGetter*/));
+ engine_under_test_.reset(new SpeechRecognitionEngine(
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+ &url_loader_factory_),
+ nullptr /*URLRequestContextGetter*/));
engine_under_test_->set_delegate(this);
}
@@ -428,14 +497,22 @@ void SpeechRecognitionEngineTest::TearDown() {
engine_under_test_.reset();
}
-TestURLFetcher* SpeechRecognitionEngineTest::GetUpstreamFetcher() {
- return url_fetcher_factory_.GetFetcherByID(
- SpeechRecognitionEngine::kUpstreamUrlFetcherIdForTesting);
+const network::TestURLLoaderFactory::PendingRequest*
+SpeechRecognitionEngineTest::GetUpstreamRequest() {
+ for (const auto& pending_request : *url_loader_factory_.pending_requests()) {
+ if (pending_request.request.url.spec().find("/up") != std::string::npos)
+ return &pending_request;
+ }
+ return nullptr;
}
-TestURLFetcher* SpeechRecognitionEngineTest::GetDownstreamFetcher() {
- return url_fetcher_factory_.GetFetcherByID(
- SpeechRecognitionEngine::kDownstreamUrlFetcherIdForTesting);
+const network::TestURLLoaderFactory::PendingRequest*
+SpeechRecognitionEngineTest::GetDownstreamRequest() {
+ for (const auto& pending_request : *url_loader_factory_.pending_requests()) {
+ if (pending_request.request.url.spec().find("/down") != std::string::npos)
+ return &pending_request;
+ }
+ return nullptr;
}
// Starts recognition on the engine, ensuring that both stream fetchers are
@@ -448,13 +525,8 @@ void SpeechRecognitionEngineTest::StartMockRecognition() {
engine_under_test_->StartRecognition();
ASSERT_TRUE(engine_under_test_->IsRecognitionPending());
- TestURLFetcher* upstream_fetcher = GetUpstreamFetcher();
- ASSERT_TRUE(upstream_fetcher);
- upstream_fetcher->set_url(upstream_fetcher->GetOriginalURL());
-
- TestURLFetcher* downstream_fetcher = GetDownstreamFetcher();
- ASSERT_TRUE(downstream_fetcher);
- downstream_fetcher->set_url(downstream_fetcher->GetOriginalURL());
+ ASSERT_TRUE(GetUpstreamRequest());
+ ASSERT_TRUE(GetDownstreamRequest());
}
void SpeechRecognitionEngineTest::EndMockRecognition() {
@@ -470,7 +542,9 @@ void SpeechRecognitionEngineTest::EndMockRecognition() {
}
void SpeechRecognitionEngineTest::InjectDummyAudioChunk() {
- unsigned char dummy_audio_buffer_data[2] = {'\0', '\0'};
+ // Enough data so that the encoder will output something, as can't read 0
+ // bytes from a Mojo stream.
+ unsigned char dummy_audio_buffer_data[2000 * 2] = {'\0'};
scoped_refptr<AudioChunk> dummy_audio_chunk(
new AudioChunk(&dummy_audio_buffer_data[0],
sizeof(dummy_audio_buffer_data),
@@ -479,100 +553,135 @@ void SpeechRecognitionEngineTest::InjectDummyAudioChunk() {
engine_under_test_->TakeAudioChunk(*dummy_audio_chunk.get());
}
-size_t SpeechRecognitionEngineTest::UpstreamChunksUploadedFromLastCall() {
- TestURLFetcher* upstream_fetcher = GetUpstreamFetcher();
- DCHECK(upstream_fetcher);
- const size_t number_of_chunks = upstream_fetcher->upload_chunks().size();
- DCHECK_GE(number_of_chunks, last_number_of_upstream_chunks_seen_);
- const size_t new_chunks = number_of_chunks -
- last_number_of_upstream_chunks_seen_;
- last_number_of_upstream_chunks_seen_ = number_of_chunks;
- return new_chunks;
-}
-
-std::string SpeechRecognitionEngineTest::LastUpstreamChunkUploaded() {
- TestURLFetcher* upstream_fetcher = GetUpstreamFetcher();
- DCHECK(upstream_fetcher);
- DCHECK(!upstream_fetcher->upload_chunks().empty());
- return upstream_fetcher->upload_chunks().back();
+void SpeechRecognitionEngineTest::ProvideMockResponseStartDownstreamIfNeeded() {
+ if (downstream_data_pipe_.get())
+ return;
+ const network::TestURLLoaderFactory::PendingRequest* downstream_request =
+ GetDownstreamRequest();
+ ASSERT_TRUE(downstream_request);
+
+ network::ResourceResponseHead head;
+ std::string headers("HTTP/1.1 200 OK\n\n");
+ head.headers = new net::HttpResponseHeaders(
+ net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
+ downstream_request->client->OnReceiveResponse(head);
+
+ mojo::DataPipe data_pipe;
+ downstream_request->client->OnStartLoadingResponseBody(
+ std::move(data_pipe.consumer_handle));
+ downstream_data_pipe_ = std::move(data_pipe.producer_handle);
}
void SpeechRecognitionEngineTest::ProvideMockProtoResultDownstream(
const proto::SpeechRecognitionEvent& result) {
- TestURLFetcher* downstream_fetcher = GetDownstreamFetcher();
-
- ASSERT_TRUE(downstream_fetcher);
- downstream_fetcher->set_status(URLRequestStatus(/* default=SUCCESS */));
- downstream_fetcher->set_response_code(200);
+ ProvideMockResponseStartDownstreamIfNeeded();
+ ASSERT_TRUE(downstream_data_pipe_.get());
+ ASSERT_TRUE(downstream_data_pipe_.is_valid());
std::string response_string = SerializeProtobufResponse(result);
response_buffer_.append(response_string);
- downstream_fetcher->SetResponseString(response_buffer_);
- downstream_fetcher->delegate()->OnURLFetchDownloadProgress(
- downstream_fetcher, response_buffer_.size(),
- -1 /* total response length not used */, response_buffer_.size());
+ uint32_t written = 0;
+ while (written < response_string.size()) {
+ uint32_t write_bytes = response_string.size() - written;
+ MojoResult result = downstream_data_pipe_->WriteData(
+ response_string.data() + written, &write_bytes,
+ MOJO_WRITE_DATA_FLAG_NONE);
+ if (result == MOJO_RESULT_OK) {
+ written += write_bytes;
+ continue;
+ }
+ if (result == MOJO_RESULT_SHOULD_WAIT) {
+ base::RunLoop().RunUntilIdle();
+ continue;
+ }
+
+ FAIL() << "Mojo pipe unexpectedly closed";
+ }
+ base::RunLoop().RunUntilIdle();
}
void SpeechRecognitionEngineTest::ProvideMockResultDownstream(
- const SpeechRecognitionResult& result) {
+ const blink::mojom::SpeechRecognitionResultPtr& result) {
proto::SpeechRecognitionEvent proto_event;
proto_event.set_status(proto::SpeechRecognitionEvent::STATUS_SUCCESS);
proto::SpeechRecognitionResult* proto_result = proto_event.add_result();
- proto_result->set_final(!result.is_provisional);
- for (size_t i = 0; i < result.hypotheses.size(); ++i) {
+ proto_result->set_final(!result->is_provisional);
+ for (size_t i = 0; i < result->hypotheses.size(); ++i) {
proto::SpeechRecognitionAlternative* proto_alternative =
proto_result->add_alternative();
- const SpeechRecognitionHypothesis& hypothesis = result.hypotheses[i];
- proto_alternative->set_confidence(hypothesis.confidence);
- proto_alternative->set_transcript(base::UTF16ToUTF8(hypothesis.utterance));
+ const blink::mojom::SpeechRecognitionHypothesisPtr& hypothesis =
+ result->hypotheses[i];
+ proto_alternative->set_confidence(hypothesis->confidence);
+ proto_alternative->set_transcript(base::UTF16ToUTF8(hypothesis->utterance));
}
ProvideMockProtoResultDownstream(proto_event);
+ base::RunLoop().RunUntilIdle();
}
void SpeechRecognitionEngineTest::CloseMockDownstream(
DownstreamError error) {
- TestURLFetcher* downstream_fetcher = GetDownstreamFetcher();
- ASSERT_TRUE(downstream_fetcher);
+ if (error == DOWNSTREAM_ERROR_HTTP500) {
+ // Can't provide a network error if already gave the consumer a 200
+ // response.
+ ASSERT_FALSE(downstream_data_pipe_.get());
+
+ const network::TestURLLoaderFactory::PendingRequest* downstream_request =
+ GetDownstreamRequest();
+ ASSERT_TRUE(downstream_request);
+ network::ResourceResponseHead head;
+ std::string headers("HTTP/1.1 500 Server Sad\n\n");
+ head.headers = new net::HttpResponseHeaders(
+ net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
+ downstream_request->client->OnReceiveResponse(head);
+ // Wait for the response to be handled.
+ base::RunLoop().RunUntilIdle();
+ return;
+ }
+
+ ProvideMockResponseStartDownstreamIfNeeded();
+ const network::TestURLLoaderFactory::PendingRequest* downstream_request =
+ GetDownstreamRequest();
+ ASSERT_TRUE(downstream_request);
- const net::Error net_error =
+ network::URLLoaderCompletionStatus status;
+ status.decoded_body_length = response_buffer_.size();
+ status.error_code =
(error == DOWNSTREAM_ERROR_NETWORK) ? net::ERR_FAILED : net::OK;
- downstream_fetcher->set_status(URLRequestStatus::FromError(net_error));
- downstream_fetcher->set_response_code(
- (error == DOWNSTREAM_ERROR_HTTP500) ? 500 : 200);
-
- if (error == DOWNSTREAM_ERROR_WEBSERVICE_NO_MATCH) {
- // Send empty response.
- proto::SpeechRecognitionEvent response;
- response_buffer_.append(SerializeProtobufResponse(response));
- }
- downstream_fetcher->SetResponseString(response_buffer_);
- downstream_fetcher->delegate()->OnURLFetchComplete(downstream_fetcher);
+ downstream_request->client->OnComplete(status);
+ downstream_data_pipe_.reset();
+ // Wait for the completion events to be handled.
+ base::RunLoop().RunUntilIdle();
}
void SpeechRecognitionEngineTest::ExpectResultsReceived(
- const SpeechRecognitionResults& results) {
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results) {
ASSERT_GE(1U, results_.size());
ASSERT_TRUE(ResultsAreEqual(results, results_.front()));
results_.pop();
}
bool SpeechRecognitionEngineTest::ResultsAreEqual(
- const SpeechRecognitionResults& a, const SpeechRecognitionResults& b) {
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& a,
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& b) {
if (a.size() != b.size())
return false;
- SpeechRecognitionResults::const_iterator it_a = a.begin();
- SpeechRecognitionResults::const_iterator it_b = b.begin();
+ std::vector<blink::mojom::SpeechRecognitionResultPtr>::const_iterator it_a =
+ a.begin();
+ std::vector<blink::mojom::SpeechRecognitionResultPtr>::const_iterator it_b =
+ b.begin();
for (; it_a != a.end() && it_b != b.end(); ++it_a, ++it_b) {
- if (it_a->is_provisional != it_b->is_provisional ||
- it_a->hypotheses.size() != it_b->hypotheses.size()) {
+ if ((*it_a)->is_provisional != (*it_b)->is_provisional ||
+ (*it_a)->hypotheses.size() != (*it_b)->hypotheses.size()) {
return false;
}
- for (size_t i = 0; i < it_a->hypotheses.size(); ++i) {
- const SpeechRecognitionHypothesis& hyp_a = it_a->hypotheses[i];
- const SpeechRecognitionHypothesis& hyp_b = it_b->hypotheses[i];
- if (hyp_a.utterance != hyp_b.utterance ||
- hyp_a.confidence != hyp_b.confidence) {
+ for (size_t i = 0; i < (*it_a)->hypotheses.size(); ++i) {
+ const blink::mojom::SpeechRecognitionHypothesisPtr& hyp_a =
+ (*it_a)->hypotheses[i];
+ const blink::mojom::SpeechRecognitionHypothesisPtr& hyp_b =
+ (*it_b)->hypotheses[i];
+ if (hyp_a->utterance != hyp_b->utterance ||
+ hyp_a->confidence != hyp_b->confidence) {
return false;
}
}
@@ -590,6 +699,56 @@ void SpeechRecognitionEngineTest::ExpectFramedChunk(
EXPECT_EQ(type, value);
}
+std::string SpeechRecognitionEngineTest::ConsumeChunkedUploadData() {
+ std::string result;
+ base::RunLoop().RunUntilIdle();
+
+ if (!upstream_data_pipe_.get()) {
+ if (!chunked_data_pipe_getter_) {
+ const network::TestURLLoaderFactory::PendingRequest* upstream_request =
+ GetUpstreamRequest();
+ EXPECT_TRUE(upstream_request);
+ EXPECT_TRUE(upstream_request->request.request_body);
+ EXPECT_EQ(1u, upstream_request->request.request_body->elements()->size());
+ EXPECT_EQ(
+ network::DataElement::TYPE_CHUNKED_DATA_PIPE,
+ (*upstream_request->request.request_body->elements())[0].type());
+ network::TestURLLoaderFactory::PendingRequest* mutable_upstream_request =
+ const_cast<network::TestURLLoaderFactory::PendingRequest*>(
+ upstream_request);
+ chunked_data_pipe_getter_ = (*mutable_upstream_request->request
+ .request_body->elements_mutable())[0]
+ .ReleaseChunkedDataPipeGetter();
+ }
+ mojo::DataPipe data_pipe;
+ chunked_data_pipe_getter_->StartReading(
+ std::move(data_pipe.producer_handle));
+ upstream_data_pipe_ = std::move(data_pipe.consumer_handle);
+ }
+ EXPECT_TRUE(upstream_data_pipe_.is_valid());
+
+ std::string out;
+ while (true) {
+ base::RunLoop().RunUntilIdle();
+
+ const void* data;
+ uint32_t num_bytes;
+ MojoResult result = upstream_data_pipe_->BeginReadData(
+ &data, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
+ if (result == MOJO_RESULT_OK) {
+ out.append(static_cast<const char*>(data), num_bytes);
+ upstream_data_pipe_->EndReadData(num_bytes);
+ continue;
+ }
+ if (result == MOJO_RESULT_SHOULD_WAIT)
+ break;
+
+ ADD_FAILURE() << "Mojo pipe unexpectedly closed";
+ break;
+ }
+ return out;
+}
+
std::string SpeechRecognitionEngineTest::SerializeProtobufResponse(
const proto::SpeechRecognitionEvent& msg) {
std::string msg_string;
diff --git a/chromium/content/browser/speech/speech_recognition_manager_impl.cc b/chromium/content/browser/speech/speech_recognition_manager_impl.cc
index e04810d1d03..0fe2c51770a 100644
--- a/chromium/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/chromium/content/browser/speech/speech_recognition_manager_impl.cc
@@ -21,6 +21,8 @@
#include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
#include "content/browser/speech/speech_recognition_engine.h"
#include "content/browser/speech/speech_recognizer_impl.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/resource_context.h"
@@ -30,9 +32,9 @@
#include "content/public/browser/speech_recognition_session_context.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
-#include "content/public/common/speech_recognition_error.h"
-#include "content/public/common/speech_recognition_result.h"
#include "media/audio/audio_device_description.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
#include "url/gurl.h"
#include "url/origin.h"
@@ -281,7 +283,8 @@ int SpeechRecognitionManagerImpl::CreateSession(
remote_engine_config.preamble = config.preamble;
SpeechRecognitionEngine* google_remote_engine =
- new SpeechRecognitionEngine(config.url_request_context_getter.get());
+ new SpeechRecognitionEngine(config.shared_url_loader_factory,
+ config.deprecated_url_request_context_getter);
google_remote_engine->SetConfig(remote_engine_config);
session->recognizer = new SpeechRecognizerImpl(
@@ -360,8 +363,10 @@ void SpeechRecognitionManagerImpl::RecognitionAllowedCallback(int session_id,
base::BindOnce(&SpeechRecognitionManagerImpl::DispatchEvent,
weak_factory_.GetWeakPtr(), session_id, EVENT_START));
} else {
- OnRecognitionError(session_id, SpeechRecognitionError(
- SPEECH_RECOGNITION_ERROR_NOT_ALLOWED));
+ OnRecognitionError(
+ session_id, blink::mojom::SpeechRecognitionError(
+ blink::mojom::SpeechRecognitionErrorCode::kNotAllowed,
+ blink::mojom::SpeechAudioErrorDetails::kNone));
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&SpeechRecognitionManagerImpl::DispatchEvent,
@@ -539,7 +544,8 @@ void SpeechRecognitionManagerImpl::OnAudioEnd(int session_id) {
}
void SpeechRecognitionManagerImpl::OnRecognitionResults(
- int session_id, const SpeechRecognitionResults& results) {
+ int session_id,
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
@@ -551,7 +557,8 @@ void SpeechRecognitionManagerImpl::OnRecognitionResults(
}
void SpeechRecognitionManagerImpl::OnRecognitionError(
- int session_id, const SpeechRecognitionError& error) {
+ int session_id,
+ const blink::mojom::SpeechRecognitionError& error) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!SessionExists(session_id))
return;
diff --git a/chromium/content/browser/speech/speech_recognition_manager_impl.h b/chromium/content/browser/speech/speech_recognition_manager_impl.h
index cf4468d3bef..8819223a3b6 100644
--- a/chromium/content/browser/speech/speech_recognition_manager_impl.h
+++ b/chromium/content/browser/speech/speech_recognition_manager_impl.h
@@ -16,7 +16,7 @@
#include "content/public/browser/speech_recognition_manager.h"
#include "content/public/browser/speech_recognition_session_config.h"
#include "content/public/browser/speech_recognition_session_context.h"
-#include "content/public/common/speech_recognition_error.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h"
namespace media {
class AudioSystem;
@@ -76,10 +76,13 @@ class CONTENT_EXPORT SpeechRecognitionManagerImpl
void OnSoundEnd(int session_id) override;
void OnAudioEnd(int session_id) override;
void OnRecognitionEnd(int session_id) override;
- void OnRecognitionResults(int session_id,
- const SpeechRecognitionResults& result) override;
- void OnRecognitionError(int session_id,
- const SpeechRecognitionError& error) override;
+ void OnRecognitionResults(
+ int session_id,
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& result)
+ override;
+ void OnRecognitionError(
+ int session_id,
+ const blink::mojom::SpeechRecognitionError& error) override;
void OnAudioLevelsChange(int session_id,
float volume,
float noise_volume) override;
diff --git a/chromium/content/browser/speech/speech_recognizer_impl.cc b/chromium/content/browser/speech/speech_recognizer_impl.cc
index e05b95b8d48..95b6834df4d 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl.cc
@@ -306,9 +306,9 @@ void SpeechRecognizerImpl::OnCaptureError(const std::string& message) {
}
void SpeechRecognizerImpl::OnSpeechRecognitionEngineResults(
- const SpeechRecognitionResults& results) {
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results) {
FSMEventArgs event_args(EVENT_ENGINE_RESULT);
- event_args.engine_results = results;
+ event_args.engine_results = mojo::Clone(results);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&SpeechRecognizerImpl::DispatchEvent, this, event_args));
@@ -320,7 +320,7 @@ void SpeechRecognizerImpl::OnSpeechRecognitionEngineEndOfUtterance() {
}
void SpeechRecognizerImpl::OnSpeechRecognitionEngineError(
- const SpeechRecognitionError& error) {
+ const blink::mojom::SpeechRecognitionError& error) {
FSMEventArgs event_args(EVENT_ENGINE_ERROR);
event_args.engine_error = error;
BrowserThread::PostTask(
@@ -576,8 +576,9 @@ SpeechRecognizerImpl::StartRecording(const FSMEventArgs&) {
if (!device_params_.IsValid()) {
DLOG(ERROR) << "Audio input device not found";
- return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE,
- SPEECH_AUDIO_ERROR_DETAILS_NO_MIC));
+ return Abort(blink::mojom::SpeechRecognitionError(
+ blink::mojom::SpeechRecognitionErrorCode::kAudioCapture,
+ blink::mojom::SpeechAudioErrorDetails::kNoMic));
}
// Audio converter shall provide audio based on these parameters as output.
@@ -670,7 +671,9 @@ SpeechRecognizerImpl::DetectUserSpeechOrTimeout(const FSMEventArgs&) {
listener()->OnSoundStart(session_id());
return STATE_RECOGNIZING;
} else if (GetElapsedTimeMs() >= kNoSpeechTimeoutMs) {
- return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_NO_SPEECH));
+ return Abort(blink::mojom::SpeechRecognitionError(
+ blink::mojom::SpeechRecognitionErrorCode::kNoSpeech,
+ blink::mojom::SpeechAudioErrorDetails::kNone));
}
return STATE_WAITING_FOR_SPEECH;
}
@@ -701,22 +704,27 @@ SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::AbortSilently(const FSMEventArgs& event_args) {
DCHECK_NE(event_args.event, EVENT_AUDIO_ERROR);
DCHECK_NE(event_args.event, EVENT_ENGINE_ERROR);
- return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_NONE));
+ return Abort(blink::mojom::SpeechRecognitionError(
+ blink::mojom::SpeechRecognitionErrorCode::kNone,
+ blink::mojom::SpeechAudioErrorDetails::kNone));
}
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::AbortWithError(const FSMEventArgs& event_args) {
if (event_args.event == EVENT_AUDIO_ERROR) {
- return Abort(
- SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE));
+ return Abort(blink::mojom::SpeechRecognitionError(
+ blink::mojom::SpeechRecognitionErrorCode::kAudioCapture,
+ blink::mojom::SpeechAudioErrorDetails::kNone));
} else if (event_args.event == EVENT_ENGINE_ERROR) {
return Abort(event_args.engine_error);
}
- return Abort(SpeechRecognitionError(SPEECH_RECOGNITION_ERROR_ABORTED));
+ return Abort(blink::mojom::SpeechRecognitionError(
+ blink::mojom::SpeechRecognitionErrorCode::kAborted,
+ blink::mojom::SpeechAudioErrorDetails::kNone));
}
SpeechRecognizerImpl::FSMState SpeechRecognizerImpl::Abort(
- const SpeechRecognitionError& error) {
+ const blink::mojom::SpeechRecognitionError& error) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (IsCapturingAudio())
@@ -741,7 +749,7 @@ SpeechRecognizerImpl::FSMState SpeechRecognizerImpl::Abort(
if (state_ > STATE_STARTING && state_ < STATE_WAITING_FINAL_RESULT)
listener()->OnAudioEnd(session_id());
- if (error.code != SPEECH_RECOGNITION_ERROR_NONE)
+ if (error.code != blink::mojom::SpeechRecognitionErrorCode::kNone)
listener()->OnRecognitionError(session_id(), error);
listener()->OnRecognitionEnd(session_id());
@@ -772,17 +780,19 @@ SpeechRecognizerImpl::FSMState SpeechRecognizerImpl::ProcessIntermediateResult(
SpeechRecognizerImpl::FSMState
SpeechRecognizerImpl::ProcessFinalResult(const FSMEventArgs& event_args) {
- const SpeechRecognitionResults& results = event_args.engine_results;
- SpeechRecognitionResults::const_iterator i = results.begin();
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results =
+ event_args.engine_results;
+ std::vector<blink::mojom::SpeechRecognitionResultPtr>::const_iterator i =
+ results.begin();
bool provisional_results_pending = false;
bool results_are_empty = true;
for (; i != results.end(); ++i) {
- const SpeechRecognitionResult& result = *i;
- if (result.is_provisional) {
+ const blink::mojom::SpeechRecognitionResultPtr& result = *i;
+ if (result->is_provisional) {
DCHECK(provisional_results_);
provisional_results_pending = true;
} else if (results_are_empty) {
- results_are_empty = result.hypotheses.empty();
+ results_are_empty = result->hypotheses.empty();
}
}
@@ -889,12 +899,16 @@ media::AudioCapturerSource* SpeechRecognizerImpl::GetAudioCapturerSource() {
SpeechRecognizerImpl::FSMEventArgs::FSMEventArgs(FSMEvent event_value)
: event(event_value),
audio_data(nullptr),
- engine_error(SPEECH_RECOGNITION_ERROR_NONE) {}
+ engine_error(blink::mojom::SpeechRecognitionErrorCode::kNone,
+ blink::mojom::SpeechAudioErrorDetails::kNone) {}
-SpeechRecognizerImpl::FSMEventArgs::FSMEventArgs(const FSMEventArgs& other) =
- default;
-
-SpeechRecognizerImpl::FSMEventArgs::~FSMEventArgs() {
+SpeechRecognizerImpl::FSMEventArgs::FSMEventArgs(const FSMEventArgs& other)
+ : event(other.event),
+ audio_data(other.audio_data),
+ engine_error(other.engine_error) {
+ engine_results = mojo::Clone(other.engine_results);
}
+SpeechRecognizerImpl::FSMEventArgs::~FSMEventArgs() {}
+
} // namespace content
diff --git a/chromium/content/browser/speech/speech_recognizer_impl.h b/chromium/content/browser/speech/speech_recognizer_impl.h
index d489585409f..fd6d57b8b8f 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl.h
+++ b/chromium/content/browser/speech/speech_recognizer_impl.h
@@ -14,10 +14,10 @@
#include "content/browser/speech/endpointer/endpointer.h"
#include "content/browser/speech/speech_recognition_engine.h"
#include "content/browser/speech/speech_recognizer.h"
-#include "content/public/common/speech_recognition_error.h"
-#include "content/public/common/speech_recognition_result.h"
#include "media/base/audio_capturer_source.h"
#include "net/url_request/url_request_context_getter.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
namespace media {
class AudioBus;
@@ -96,8 +96,8 @@ class CONTENT_EXPORT SpeechRecognizerImpl
FSMEvent event;
scoped_refptr<AudioChunk> audio_data;
- SpeechRecognitionResults engine_results;
- SpeechRecognitionError engine_error;
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> engine_results;
+ blink::mojom::SpeechRecognitionError engine_error;
};
~SpeechRecognizerImpl() override;
@@ -126,7 +126,7 @@ class CONTENT_EXPORT SpeechRecognizerImpl
FSMState ProcessFinalResult(const FSMEventArgs& event_args);
FSMState AbortSilently(const FSMEventArgs& event_args);
FSMState AbortWithError(const FSMEventArgs& event_args);
- FSMState Abort(const SpeechRecognitionError& error);
+ FSMState Abort(const blink::mojom::SpeechRecognitionError& error);
FSMState DetectEndOfSpeech(const FSMEventArgs& event_args);
FSMState DoNothing(const FSMEventArgs& event_args) const;
FSMState NotFeasible(const FSMEventArgs& event_args);
@@ -151,10 +151,11 @@ class CONTENT_EXPORT SpeechRecognizerImpl
// SpeechRecognitionEngineDelegate methods.
void OnSpeechRecognitionEngineResults(
- const SpeechRecognitionResults& results) override;
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results)
+ override;
void OnSpeechRecognitionEngineEndOfUtterance() override;
void OnSpeechRecognitionEngineError(
- const SpeechRecognitionError& error) override;
+ const blink::mojom::SpeechRecognitionError& error) override;
media::AudioSystem* GetAudioSystem();
void CreateAudioCapturerSource();
diff --git a/chromium/content/browser/speech/speech_recognizer_impl_android.cc b/chromium/content/browser/speech/speech_recognizer_impl_android.cc
index 5ca639cd1fd..a2f7a606f30 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl_android.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl_android.cc
@@ -16,8 +16,8 @@
#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"
-#include "content/public/common/speech_recognition_result.h"
#include "jni/SpeechRecognitionImpl_jni.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
using base::android::AppendJavaStringArrayToStringVector;
using base::android::AttachCurrentThread;
@@ -174,24 +174,24 @@ void SpeechRecognizerImplAndroid::OnRecognitionResults(
std::vector<float> scores(options.size(), 0.0);
if (floats != NULL)
JavaFloatArrayToFloatVector(env, floats, &scores);
- SpeechRecognitionResults results;
- results.push_back(SpeechRecognitionResult());
- SpeechRecognitionResult& result = results.back();
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results;
+ results.push_back(blink::mojom::SpeechRecognitionResult::New());
+ blink::mojom::SpeechRecognitionResultPtr& result = results.back();
CHECK_EQ(options.size(), scores.size());
for (size_t i = 0; i < options.size(); ++i) {
- result.hypotheses.push_back(SpeechRecognitionHypothesis(
+ result->hypotheses.push_back(blink::mojom::SpeechRecognitionHypothesis::New(
options[i], static_cast<double>(scores[i])));
}
- result.is_provisional = provisional;
+ result->is_provisional = provisional;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
&SpeechRecognizerImplAndroid::OnRecognitionResultsOnIOThread, this,
- results));
+ std::move(results)));
}
void SpeechRecognizerImplAndroid::OnRecognitionResultsOnIOThread(
- SpeechRecognitionResults const &results) {
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
listener()->OnRecognitionResults(session_id(), results);
}
@@ -208,9 +208,11 @@ void SpeechRecognizerImplAndroid::OnRecognitionError(
return;
}
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- SpeechRecognitionErrorCode code =
- static_cast<SpeechRecognitionErrorCode>(error);
- listener()->OnRecognitionError(session_id(), SpeechRecognitionError(code));
+ listener()->OnRecognitionError(
+ session_id(),
+ blink::mojom::SpeechRecognitionError(
+ static_cast<blink::mojom::SpeechRecognitionErrorCode>(error),
+ blink::mojom::SpeechAudioErrorDetails::kNone));
}
void SpeechRecognizerImplAndroid::OnRecognitionEnd(
diff --git a/chromium/content/browser/speech/speech_recognizer_impl_android.h b/chromium/content/browser/speech/speech_recognizer_impl_android.h
index 9f12627dcac..c15356fec44 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl_android.h
+++ b/chromium/content/browser/speech/speech_recognizer_impl_android.h
@@ -13,8 +13,8 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/speech/speech_recognizer.h"
-#include "content/public/common/speech_recognition_error.h"
-#include "content/public/common/speech_recognition_result.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
namespace content {
@@ -61,7 +61,8 @@ class CONTENT_EXPORT SpeechRecognizerImplAndroid : public SpeechRecognizer {
void StartRecognitionOnUIThread(const std::string& language,
bool continuous,
bool interim_results);
- void OnRecognitionResultsOnIOThread(SpeechRecognitionResults const &results);
+ void OnRecognitionResultsOnIOThread(
+ std::vector<blink::mojom::SpeechRecognitionResultPtr> results);
~SpeechRecognizerImplAndroid() override;
diff --git a/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc b/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
index 21c79cb7445..0ef14a5d5ea 100644
--- a/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
+++ b/chromium/content/browser/speech/speech_recognizer_impl_unittest.cc
@@ -8,7 +8,10 @@
#include <vector>
#include "base/bind_helpers.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
+#include "base/stl_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/sys_byteorder.h"
#include "base/threading/thread.h"
@@ -26,9 +29,15 @@
#include "media/audio/test_audio_thread.h"
#include "media/base/audio_bus.h"
#include "media/base/test_helpers.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/data_pipe_utils.h"
#include "net/base/net_errors.h"
-#include "net/url_request/test_url_fetcher_factory.h"
-#include "net/url_request/url_request_status.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/http_util.h"
+#include "services/network/public/cpp/resource_response.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
using media::AudioInputStream;
@@ -70,11 +79,13 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener,
audio_ended_(false),
sound_started_(false),
sound_ended_(false),
- error_(SPEECH_RECOGNITION_ERROR_NONE),
+ error_(blink::mojom::SpeechRecognitionErrorCode::kNone),
volume_(-1.0f) {
// SpeechRecognizer takes ownership of sr_engine.
- SpeechRecognitionEngine* sr_engine =
- new SpeechRecognitionEngine(nullptr /* URLRequestContextGetter */);
+ SpeechRecognitionEngine* sr_engine = new SpeechRecognitionEngine(
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+ &url_loader_factory_),
+ nullptr /* URLRequestContextGetter */);
SpeechRecognitionEngine::Config config;
config.audio_num_bits_per_sample =
SpeechRecognizerImpl::kNumBitsPerAudioSample;
@@ -115,6 +126,31 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener,
audio_manager_->Shutdown();
}
+ bool GetUpstreamRequest(const network::TestURLLoaderFactory::PendingRequest**
+ pending_request_out) WARN_UNUSED_RESULT {
+ return GetPendingRequest(pending_request_out, "/up");
+ }
+
+ bool GetDownstreamRequest(
+ const network::TestURLLoaderFactory::PendingRequest** pending_request_out)
+ WARN_UNUSED_RESULT {
+ return GetPendingRequest(pending_request_out, "/down");
+ }
+
+ bool GetPendingRequest(
+ const network::TestURLLoaderFactory::PendingRequest** pending_request_out,
+ const char* url_substring) WARN_UNUSED_RESULT {
+ for (const auto& pending_request :
+ *url_loader_factory_.pending_requests()) {
+ if (pending_request.request.url.spec().find(url_substring) !=
+ std::string::npos) {
+ *pending_request_out = &pending_request;
+ return true;
+ }
+ }
+ return false;
+ }
+
void CheckEventsConsistency() {
// Note: "!x || y" == "x implies y".
EXPECT_TRUE(!recognition_ended_ || recognition_started_);
@@ -144,13 +180,16 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener,
CheckEventsConsistency();
}
- void OnRecognitionResults(int session_id,
- const SpeechRecognitionResults& results) override {
+ void OnRecognitionResults(
+ int session_id,
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results)
+ override {
result_received_ = true;
}
- void OnRecognitionError(int session_id,
- const SpeechRecognitionError& error) override {
+ void OnRecognitionError(
+ int session_id,
+ const blink::mojom::SpeechRecognitionError& error) override {
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(recognition_ended_);
error_ = error.code;
@@ -234,6 +273,7 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener,
protected:
TestBrowserThreadBundle thread_bundle_;
+ network::TestURLLoaderFactory url_loader_factory_;
scoped_refptr<SpeechRecognizerImpl> recognizer_;
std::unique_ptr<media::MockAudioManager> audio_manager_;
std::unique_ptr<media::AudioSystem> audio_system_;
@@ -245,8 +285,7 @@ class SpeechRecognizerImplTest : public SpeechRecognitionEventListener,
bool audio_ended_;
bool sound_started_;
bool sound_ended_;
- SpeechRecognitionErrorCode error_;
- net::TestURLFetcherFactory url_fetcher_factory_;
+ blink::mojom::SpeechRecognitionErrorCode error_;
std::vector<uint8_t> audio_packet_;
std::unique_ptr<media::AudioBus> audio_bus_;
int bytes_per_sample_;
@@ -265,7 +304,7 @@ TEST_F(SpeechRecognizerImplTest, StartNoInputDevices) {
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(audio_started_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kAudioCapture, error_);
CheckFinalEventsConsistency();
}
@@ -293,7 +332,7 @@ TEST_F(SpeechRecognizerImplTest, StopBeforeDeviceInfoReceived) {
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(audio_started_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
CheckFinalEventsConsistency();
}
@@ -321,7 +360,7 @@ TEST_F(SpeechRecognizerImplTest, CancelBeforeDeviceInfoReceived) {
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(audio_started_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
CheckFinalEventsConsistency();
}
@@ -336,7 +375,7 @@ TEST_F(SpeechRecognizerImplTest, StopNoData) {
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(audio_started_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
CheckFinalEventsConsistency();
}
@@ -352,7 +391,7 @@ TEST_F(SpeechRecognizerImplTest, CancelNoData) {
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(audio_started_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_ABORTED, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kAborted, error_);
CheckFinalEventsConsistency();
}
@@ -370,12 +409,56 @@ TEST_F(SpeechRecognizerImplTest, StopWithData) {
// that we are streaming out encoded data as chunks without waiting for the
// full recording to complete.
const size_t kNumChunks = 5;
+ network::mojom::ChunkedDataPipeGetterPtr chunked_data_pipe_getter;
+ mojo::DataPipe data_pipe;
for (size_t i = 0; i < kNumChunks; ++i) {
Capture(audio_bus_.get());
- base::RunLoop().RunUntilIdle();
- net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
- ASSERT_TRUE(fetcher);
- EXPECT_EQ(i + 1, fetcher->upload_chunks().size());
+
+ if (i == 0) {
+ // Set up data channel to read chunked upload data. Must be done after the
+ // first OnData() call.
+ base::RunLoop().RunUntilIdle();
+ const network::TestURLLoaderFactory::PendingRequest* upstream_request;
+ ASSERT_TRUE(GetUpstreamRequest(&upstream_request));
+ ASSERT_TRUE(upstream_request->request.request_body);
+ ASSERT_EQ(1u, upstream_request->request.request_body->elements()->size());
+ ASSERT_EQ(
+ network::DataElement::TYPE_CHUNKED_DATA_PIPE,
+ (*upstream_request->request.request_body->elements())[0].type());
+ network::TestURLLoaderFactory::PendingRequest* mutable_upstream_request =
+ const_cast<network::TestURLLoaderFactory::PendingRequest*>(
+ upstream_request);
+ chunked_data_pipe_getter = (*mutable_upstream_request->request
+ .request_body->elements_mutable())[0]
+ .ReleaseChunkedDataPipeGetter();
+ chunked_data_pipe_getter->StartReading(
+ std::move(data_pipe.producer_handle));
+ }
+
+ std::string data;
+ while (true) {
+ base::RunLoop().RunUntilIdle();
+
+ const void* buffer;
+ uint32_t num_bytes;
+ MojoResult result = data_pipe.consumer_handle->BeginReadData(
+ &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
+ if (result == MOJO_RESULT_OK) {
+ data.append(static_cast<const char*>(buffer), num_bytes);
+ data_pipe.consumer_handle->EndReadData(num_bytes);
+ continue;
+ }
+ if (result == MOJO_RESULT_SHOULD_WAIT) {
+ // Some data has already been read, assume there's no more to read.
+ if (!data.empty())
+ break;
+ continue;
+ }
+
+ FAIL() << "Mojo pipe closed unexpectedly";
+ }
+
+ EXPECT_FALSE(data.empty());
}
recognizer_->StopAudioCapture();
@@ -384,7 +467,7 @@ TEST_F(SpeechRecognizerImplTest, StopWithData) {
EXPECT_TRUE(audio_ended_);
EXPECT_FALSE(recognition_ended_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
// Create a response string.
proto::SpeechRecognitionEvent proto_event;
@@ -402,19 +485,15 @@ TEST_F(SpeechRecognizerImplTest, StopWithData) {
msg_string.insert(0, reinterpret_cast<char*>(&prefix), sizeof(prefix));
// Issue the network callback to complete the process.
- net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(
- SpeechRecognitionEngine::kDownstreamUrlFetcherIdForTesting);
- ASSERT_TRUE(fetcher);
- fetcher->set_url(fetcher->GetOriginalURL());
- fetcher->set_status(net::URLRequestStatus());
- fetcher->set_response_code(200);
- fetcher->SetResponseString(msg_string);
- fetcher->delegate()->OnURLFetchComplete(fetcher);
-
+ const network::TestURLLoaderFactory::PendingRequest* downstream_request;
+ ASSERT_TRUE(GetDownstreamRequest(&downstream_request));
+ url_loader_factory_.AddResponse(downstream_request->request.url.spec(),
+ msg_string);
base::RunLoop().RunUntilIdle();
+
EXPECT_TRUE(recognition_ended_);
EXPECT_TRUE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
CheckFinalEventsConsistency();
}
@@ -429,11 +508,12 @@ TEST_F(SpeechRecognizerImplTest, CancelWithData) {
base::RunLoop().RunUntilIdle();
recognizer_->AbortRecognition();
base::RunLoop().RunUntilIdle();
- ASSERT_TRUE(url_fetcher_factory_.GetFetcherByID(0));
+ // There should be both upstream and downstream pending requests.
+ ASSERT_EQ(2u, url_loader_factory_.pending_requests()->size());
EXPECT_TRUE(recognition_started_);
EXPECT_TRUE(audio_started_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_ABORTED, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kAborted, error_);
CheckFinalEventsConsistency();
}
@@ -447,8 +527,8 @@ TEST_F(SpeechRecognizerImplTest, ConnectionError) {
base::RunLoop().RunUntilIdle(); // EVENT_START processing.
Capture(audio_bus_.get());
base::RunLoop().RunUntilIdle();
- net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
- ASSERT_TRUE(fetcher);
+ // There should be both upstream and downstream pending requests.
+ ASSERT_EQ(2u, url_loader_factory_.pending_requests()->size());
recognizer_->StopAudioCapture();
base::RunLoop().RunUntilIdle();
@@ -456,19 +536,19 @@ TEST_F(SpeechRecognizerImplTest, ConnectionError) {
EXPECT_TRUE(audio_ended_);
EXPECT_FALSE(recognition_ended_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
// Issue the network callback to complete the process.
- fetcher->set_url(fetcher->GetOriginalURL());
- fetcher->set_status(
- net::URLRequestStatus::FromError(net::ERR_CONNECTION_REFUSED));
- fetcher->set_response_code(0);
- fetcher->SetResponseString(std::string());
- fetcher->delegate()->OnURLFetchComplete(fetcher);
+ const network::TestURLLoaderFactory::PendingRequest* pending_request;
+ ASSERT_TRUE(GetUpstreamRequest(&pending_request));
+ url_loader_factory_.AddResponse(
+ pending_request->request.url, network::ResourceResponseHead(), "",
+ network::URLLoaderCompletionStatus(net::ERR_CONNECTION_REFUSED));
+
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(recognition_ended_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NETWORK, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNetwork, error_);
CheckFinalEventsConsistency();
}
@@ -482,8 +562,8 @@ TEST_F(SpeechRecognizerImplTest, ServerError) {
base::RunLoop().RunUntilIdle(); // EVENT_START processing.
Capture(audio_bus_.get());
base::RunLoop().RunUntilIdle();
- net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
- ASSERT_TRUE(fetcher);
+ // There should be both upstream and downstream pending requests.
+ ASSERT_EQ(2u, url_loader_factory_.pending_requests()->size());
recognizer_->StopAudioCapture();
base::RunLoop().RunUntilIdle();
@@ -491,18 +571,21 @@ TEST_F(SpeechRecognizerImplTest, ServerError) {
EXPECT_TRUE(audio_ended_);
EXPECT_FALSE(recognition_ended_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
+
+ const network::TestURLLoaderFactory::PendingRequest* pending_request;
+ ASSERT_TRUE(GetUpstreamRequest(&pending_request));
+ network::ResourceResponseHead response;
+ const char kHeaders[] = "HTTP/1.0 500 Internal Server Error";
+ response.headers = base::MakeRefCounted<net::HttpResponseHeaders>(
+ net::HttpUtil::AssembleRawHeaders(kHeaders, base::size(kHeaders)));
+ url_loader_factory_.AddResponse(pending_request->request.url, response, "",
+ network::URLLoaderCompletionStatus());
- // Issue the network callback to complete the process.
- fetcher->set_url(fetcher->GetOriginalURL());
- fetcher->set_status(net::URLRequestStatus());
- fetcher->set_response_code(500);
- fetcher->SetResponseString("Internal Server Error");
- fetcher->delegate()->OnURLFetchComplete(fetcher);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(recognition_ended_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NETWORK, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNetwork, error_);
CheckFinalEventsConsistency();
}
@@ -519,7 +602,7 @@ TEST_F(SpeechRecognizerImplTest, OnCaptureError_PropagatesError) {
EXPECT_TRUE(recognition_started_);
EXPECT_FALSE(audio_started_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kAudioCapture, error_);
CheckFinalEventsConsistency();
}
@@ -542,7 +625,7 @@ TEST_F(SpeechRecognizerImplTest, NoSpeechCallbackIssued) {
EXPECT_TRUE(recognition_started_);
EXPECT_TRUE(audio_started_);
EXPECT_FALSE(result_received_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NO_SPEECH, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNoSpeech, error_);
CheckFinalEventsConsistency();
}
@@ -571,7 +654,7 @@ TEST_F(SpeechRecognizerImplTest, NoSpeechCallbackNotIssued) {
}
base::RunLoop().RunUntilIdle();
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
EXPECT_TRUE(audio_started_);
EXPECT_FALSE(audio_ended_);
EXPECT_FALSE(recognition_ended_);
@@ -612,7 +695,7 @@ TEST_F(SpeechRecognizerImplTest, SetInputVolumeCallback) {
EXPECT_NEAR(0.89926866f, volume_, 0.00001f);
EXPECT_FLOAT_EQ(0.75071919f, noise_volume_);
- EXPECT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_);
+ EXPECT_EQ(blink::mojom::SpeechRecognitionErrorCode::kNone, error_);
EXPECT_FALSE(audio_ended_);
EXPECT_FALSE(recognition_ended_);
recognizer_->AbortRecognition();
diff --git a/chromium/content/browser/startup_data_impl.cc b/chromium/content/browser/startup_data_impl.cc
new file mode 100644
index 00000000000..625dbe6672e
--- /dev/null
+++ b/chromium/content/browser/startup_data_impl.cc
@@ -0,0 +1,13 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/startup_data_impl.h"
+
+namespace content {
+
+StartupDataImpl::StartupDataImpl() = default;
+
+StartupDataImpl::~StartupDataImpl() = default;
+
+} // namespace content
diff --git a/chromium/content/browser/startup_data_impl.h b/chromium/content/browser/startup_data_impl.h
new file mode 100644
index 00000000000..e3f06271c27
--- /dev/null
+++ b/chromium/content/browser/startup_data_impl.h
@@ -0,0 +1,26 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_STARTUP_DATA_IMPL_H_
+#define CONTENT_BROWSER_STARTUP_DATA_IMPL_H_
+
+#include <memory>
+
+#include "content/browser/browser_process_sub_thread.h"
+#include "content/public/browser/startup_data.h"
+
+namespace content {
+
+// The browser implementation of StartupData.
+struct StartupDataImpl : public StartupData {
+ StartupDataImpl();
+ ~StartupDataImpl() override;
+
+ // TODO(hanxi): add ServiceManagerContext* here.
+ std::unique_ptr<BrowserProcessSubThread> thread;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_STARTUP_DATA_IMPL_H_
diff --git a/chromium/content/browser/startup_task_runner.cc b/chromium/content/browser/startup_task_runner.cc
index 36259dd2ec7..319bc8f10b4 100644
--- a/chromium/content/browser/startup_task_runner.cc
+++ b/chromium/content/browser/startup_task_runner.cc
@@ -10,9 +10,10 @@
namespace content {
StartupTaskRunner::StartupTaskRunner(
- base::Callback<void(int)> const startup_complete_callback,
+ base::OnceCallback<void(int)> startup_complete_callback,
scoped_refptr<base::SingleThreadTaskRunner> proxy)
- : startup_complete_callback_(startup_complete_callback), proxy_(proxy) {}
+ : startup_complete_callback_(std::move(startup_complete_callback)),
+ proxy_(proxy) {}
StartupTaskRunner::~StartupTaskRunner() {}
@@ -25,9 +26,7 @@ void StartupTaskRunner::StartRunningTasksAsync() {
int result = 0;
if (task_list_.empty()) {
if (!startup_complete_callback_.is_null()) {
- startup_complete_callback_.Run(result);
- // Clear the callback to prevent it being called a second time
- startup_complete_callback_.Reset();
+ std::move(startup_complete_callback_).Run(result);
}
} else {
const base::Closure next_task =
@@ -46,9 +45,7 @@ void StartupTaskRunner::RunAllTasksNow() {
}
task_list_.clear();
if (!startup_complete_callback_.is_null()) {
- startup_complete_callback_.Run(result);
- // Clear the callback to prevent it being called a second time
- startup_complete_callback_.Reset();
+ std::move(startup_complete_callback_).Run(result);
}
}
@@ -67,9 +64,7 @@ void StartupTaskRunner::WrappedTask() {
}
if (task_list_.empty()) {
if (!startup_complete_callback_.is_null()) {
- startup_complete_callback_.Run(result);
- // Clear the callback to prevent it being called a second time
- startup_complete_callback_.Reset();
+ std::move(startup_complete_callback_).Run(result);
}
} else {
const base::Closure next_task =
diff --git a/chromium/content/browser/startup_task_runner.h b/chromium/content/browser/startup_task_runner.h
index c5f09f66e45..a38776d147e 100644
--- a/chromium/content/browser/startup_task_runner.h
+++ b/chromium/content/browser/startup_task_runner.h
@@ -37,7 +37,7 @@ class CONTENT_EXPORT StartupTaskRunner {
public:
// Constructor: Note that |startup_complete_callback| is optional. If it is
// not null it will be called once all the startup tasks have run.
- StartupTaskRunner(base::Callback<void(int)> startup_complete_callback,
+ StartupTaskRunner(base::OnceCallback<void(int)> startup_complete_callback,
scoped_refptr<base::SingleThreadTaskRunner> proxy);
~StartupTaskRunner();
@@ -57,7 +57,7 @@ class CONTENT_EXPORT StartupTaskRunner {
std::list<StartupTask> task_list_;
void WrappedTask();
- base::Callback<void(int)> startup_complete_callback_;
+ base::OnceCallback<void(int)> startup_complete_callback_;
scoped_refptr<base::SingleThreadTaskRunner> proxy_;
DISALLOW_COPY_AND_ASSIGN(StartupTaskRunner);
diff --git a/chromium/content/browser/startup_task_runner_unittest.cc b/chromium/content/browser/startup_task_runner_unittest.cc
index 738940a0a07..3e7857c212b 100644
--- a/chromium/content/browser/startup_task_runner_unittest.cc
+++ b/chromium/content/browser/startup_task_runner_unittest.cc
@@ -116,7 +116,7 @@ TEST_F(StartupTaskRunnerTest, SynchronousExecution) {
EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0);
EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _)).Times(0);
- StartupTaskRunner runner(base::Bind(&Observer), proxy);
+ StartupTaskRunner runner(base::BindOnce(&Observer), proxy);
StartupTask task1 =
base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
@@ -154,7 +154,7 @@ TEST_F(StartupTaskRunnerTest, NullObserver) {
EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0);
EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _)).Times(0);
- StartupTaskRunner runner(base::Callback<void(int)>(), proxy);
+ StartupTaskRunner runner(base::OnceCallback<void(int)>(), proxy);
StartupTask task1 =
base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
@@ -189,7 +189,7 @@ TEST_F(StartupTaskRunnerTest, SynchronousExecutionFailedTask) {
EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0);
EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _)).Times(0);
- StartupTaskRunner runner(base::Bind(&Observer), proxy);
+ StartupTaskRunner runner(base::BindOnce(&Observer), proxy);
StartupTask task3 =
base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this));
@@ -230,7 +230,7 @@ TEST_F(StartupTaskRunnerTest, AsynchronousExecution) {
.Times(testing::Between(2, 3))
.WillRepeatedly(testing::Return(true));
- StartupTaskRunner runner(base::Bind(&Observer), proxy);
+ StartupTaskRunner runner(base::BindOnce(&Observer), proxy);
StartupTask task1 =
base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
@@ -276,7 +276,7 @@ TEST_F(StartupTaskRunnerTest, AsynchronousExecutionFailedTask) {
.Times(testing::Between(1, 2))
.WillRepeatedly(testing::Return(true));
- StartupTaskRunner runner(base::Bind(&Observer), proxy);
+ StartupTaskRunner runner(base::BindOnce(&Observer), proxy);
StartupTask task3 =
base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this));
diff --git a/chromium/content/browser/storage_partition_impl.cc b/chromium/content/browser/storage_partition_impl.cc
index b9165dd4ab7..ab6a04d6ec9 100644
--- a/chromium/content/browser/storage_partition_impl.cc
+++ b/chromium/content/browser/storage_partition_impl.cc
@@ -53,6 +53,7 @@
#include "services/network/cookie_manager.h"
#include "services/network/network_context.h"
#include "services/network/network_service.h"
+#include "services/network/public/cpp/cross_thread_shared_url_loader_factory_info.h"
#include "services/network/public/cpp/features.h"
#include "services/service_manager/public/cpp/connector.h"
#include "storage/browser/blob/blob_registry_impl.h"
@@ -221,12 +222,6 @@ void ClearSessionStorageOnUIThread(
special_storage_policy, origin_matcher, callback));
}
-base::WeakPtr<storage::BlobStorageContext> BlobStorageContextGetterForStorage(
- scoped_refptr<ChromeBlobStorageContext> blob_context) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return blob_context->context()->AsWeakPtr();
-}
-
} // namespace
// Class to own the NetworkContext wrapping a storage partitions
@@ -296,9 +291,9 @@ class StoragePartitionImpl::URLLoaderFactoryForBrowserProcess
// SharedURLLoaderFactory implementation:
std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override {
- NOTREACHED() << "This isn't supported. If you need a SharedURLLoaderFactory"
- " on the IO thread, get it from URLLoaderFactoryGetter.";
- return nullptr;
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return std::make_unique<network::CrossThreadSharedURLLoaderFactoryInfo>(
+ this);
}
void Shutdown() { storage_partition_ = nullptr; }
@@ -539,6 +534,9 @@ StoragePartitionImpl::~StoragePartitionImpl() {
if (GetPaymentAppContext())
GetPaymentAppContext()->Shutdown();
+ if (GetBackgroundFetchContext())
+ GetBackgroundFetchContext()->Shutdown();
+
if (GetAppCacheService()) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
@@ -609,7 +607,7 @@ std::unique_ptr<StoragePartitionImpl> StoragePartitionImpl::Create(
partition->service_worker_context_->set_storage_partition(partition.get());
partition->shared_worker_service_ = std::make_unique<SharedWorkerServiceImpl>(
- partition->service_worker_context_);
+ partition.get(), partition->service_worker_context_);
partition->appcache_service_ =
new ChromeAppCacheService(quota_manager_proxy.get());
@@ -630,7 +628,9 @@ std::unique_ptr<StoragePartitionImpl> StoragePartitionImpl::Create(
partition->web_package_context_ = std::make_unique<WebPackageContextImpl>();
partition->background_fetch_context_ =
- new BackgroundFetchContext(context, partition->service_worker_context_);
+ base::MakeRefCounted<BackgroundFetchContext>(
+ context, partition->service_worker_context_,
+ partition->cache_storage_context_);
partition->background_sync_context_ =
base::MakeRefCounted<BackgroundSyncContext>();
@@ -646,14 +646,6 @@ std::unique_ptr<StoragePartitionImpl> StoragePartitionImpl::Create(
scoped_refptr<ChromeBlobStorageContext> blob_context =
ChromeBlobStorageContext::GetFor(context);
- if (base::FeatureList::IsEnabled(network::features::kNetworkService) ||
- ServiceWorkerUtils::IsServicificationEnabled()) {
- BlobURLLoaderFactory::BlobContextGetter blob_getter =
- base::BindOnce(&BlobStorageContextGetterForStorage, blob_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());
@@ -668,8 +660,7 @@ std::unique_ptr<StoragePartitionImpl> StoragePartitionImpl::Create(
partition->url_loader_factory_getter_.get());
partition->prefetch_url_loader_service_ =
- base::MakeRefCounted<PrefetchURLLoaderService>(
- partition->url_loader_factory_getter_);
+ base::MakeRefCounted<PrefetchURLLoaderService>();
partition->cookie_store_context_ = base::MakeRefCounted<CookieStoreContext>();
// Unit tests use the Initialize() callback to crash early if restoring the
@@ -827,10 +818,6 @@ StoragePartitionImpl::GetBluetoothAllowedDevicesMap() {
return bluetooth_allowed_devices_map_.get();
}
-BlobURLLoaderFactory* StoragePartitionImpl::GetBlobURLLoaderFactory() {
- return blob_url_loader_factory_.get();
-}
-
BlobRegistryWrapper* StoragePartitionImpl::GetBlobRegistry() {
return blob_registry_.get();
}
@@ -845,7 +832,7 @@ CookieStoreContext* StoragePartitionImpl::GetCookieStoreContext() {
void StoragePartitionImpl::OpenLocalStorage(
const url::Origin& origin,
- mojom::LevelDBWrapperRequest request) {
+ blink::mojom::StorageAreaRequest request) {
int process_id = bindings_.dispatch_context();
if (!ChildProcessSecurityPolicy::GetInstance()->CanAccessDataForOrigin(
process_id, origin.GetURL())) {
@@ -858,7 +845,7 @@ void StoragePartitionImpl::OpenLocalStorage(
void StoragePartitionImpl::OpenSessionStorage(
const std::string& namespace_id,
- mojom::SessionStorageNamespaceRequest request) {
+ blink::mojom::SessionStorageNamespaceRequest request) {
int process_id = bindings_.dispatch_context();
dom_storage_context_->OpenSessionStorage(process_id, namespace_id,
std::move(request));
@@ -1210,13 +1197,17 @@ void StoragePartitionImpl::WaitForDeletionTasksForTesting() {
}
}
+void StoragePartitionImpl::ResetURLLoaderFactoryForBrowserProcessForTesting() {
+ url_loader_factory_for_browser_process_.reset();
+}
+
BrowserContext* StoragePartitionImpl::browser_context() const {
return browser_context_;
}
mojo::BindingId StoragePartitionImpl::Bind(
int process_id,
- mojo::InterfaceRequest<mojom::StoragePartitionService> request) {
+ mojo::InterfaceRequest<blink::mojom::StoragePartitionService> request) {
return bindings_.AddBinding(this, std::move(request), process_id);
}
@@ -1248,9 +1239,12 @@ void StoragePartitionImpl::GetQuotaSettings(
network::mojom::URLLoaderFactory*
StoragePartitionImpl::GetURLLoaderFactoryForBrowserProcessInternal() {
- // Create the URLLoaderFactory as needed.
+ // Create the URLLoaderFactory as needed, but make sure not to reuse a
+ // previously created one if the test override has changed.
if (url_loader_factory_for_browser_process_ &&
- !url_loader_factory_for_browser_process_.encountered_error()) {
+ !url_loader_factory_for_browser_process_.encountered_error() &&
+ is_test_url_loader_factory_for_browser_process_ !=
+ g_url_loader_factory_callback_for_test.Get().is_null()) {
return url_loader_factory_for_browser_process_.get();
}
@@ -1258,10 +1252,16 @@ StoragePartitionImpl::GetURLLoaderFactoryForBrowserProcessInternal() {
network::mojom::URLLoaderFactoryParams::New();
params->process_id = network::mojom::kBrowserProcessId;
params->is_corb_enabled = false;
+ params->disable_web_security =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableWebSecurity);
if (g_url_loader_factory_callback_for_test.Get().is_null()) {
- GetNetworkContext()->CreateURLLoaderFactory(
- mojo::MakeRequest(&url_loader_factory_for_browser_process_),
- std::move(params));
+ auto request = mojo::MakeRequest(&url_loader_factory_for_browser_process_);
+ GetContentClient()->browser()->WillCreateURLLoaderFactory(
+ browser_context(), nullptr, false /* is_navigation */, &request);
+ GetNetworkContext()->CreateURLLoaderFactory(std::move(request),
+ std::move(params));
+ is_test_url_loader_factory_for_browser_process_ = false;
return url_loader_factory_for_browser_process_.get();
}
@@ -1271,6 +1271,7 @@ StoragePartitionImpl::GetURLLoaderFactoryForBrowserProcessInternal() {
url_loader_factory_for_browser_process_ =
g_url_loader_factory_callback_for_test.Get().Run(
std::move(original_factory));
+ is_test_url_loader_factory_for_browser_process_ = true;
return url_loader_factory_for_browser_process_.get();
}
diff --git a/chromium/content/browser/storage_partition_impl.h b/chromium/content/browser/storage_partition_impl.h
index 102e3ff8e47..e79f8775a1b 100644
--- a/chromium/content/browser/storage_partition_impl.h
+++ b/chromium/content/browser/storage_partition_impl.h
@@ -18,7 +18,6 @@
#include "base/process/process_handle.h"
#include "content/browser/appcache/chrome_appcache_service.h"
#include "content/browser/background_sync/background_sync_context.h"
-#include "content/browser/blob_storage/blob_url_loader_factory.h"
#include "content/browser/bluetooth/bluetooth_allowed_devices_map.h"
#include "content/browser/broadcast_channel/broadcast_channel_provider.h"
#include "content/browser/cache_storage/cache_storage_context_impl.h"
@@ -32,12 +31,12 @@
#include "content/browser/shared_worker/shared_worker_service_impl.h"
#include "content/browser/url_loader_factory_getter.h"
#include "content/common/content_export.h"
-#include "content/common/storage_partition_service.mojom.h"
#include "content/public/browser/storage_partition.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "storage/browser/quota/special_storage_policy.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom.h"
#if !defined(OS_ANDROID)
#include "content/browser/host_zoom_level_context.h"
@@ -48,13 +47,12 @@ namespace content {
class BackgroundFetchContext;
class CookieStoreContext;
class BlobRegistryWrapper;
-class BlobURLLoaderFactory;
class PrefetchURLLoaderService;
class WebPackageContextImpl;
class CONTENT_EXPORT StoragePartitionImpl
: public StoragePartition,
- public mojom::StoragePartitionService {
+ public blink::mojom::StoragePartitionService {
public:
// It is guaranteed that storage partitions are destructed before the
// browser context starts shutting down its corresponding IO thread residents
@@ -134,23 +132,23 @@ class CONTENT_EXPORT StoragePartitionImpl
void ClearBluetoothAllowedDevicesMapForTesting() override;
void FlushNetworkInterfaceForTesting() override;
void WaitForDeletionTasksForTesting() override;
+ void ResetURLLoaderFactoryForBrowserProcessForTesting() override;
BackgroundFetchContext* GetBackgroundFetchContext();
BackgroundSyncContext* GetBackgroundSyncContext();
PaymentAppContextImpl* GetPaymentAppContext();
BroadcastChannelProvider* GetBroadcastChannelProvider();
BluetoothAllowedDevicesMap* GetBluetoothAllowedDevicesMap();
- BlobURLLoaderFactory* GetBlobURLLoaderFactory();
BlobRegistryWrapper* GetBlobRegistry();
PrefetchURLLoaderService* GetPrefetchURLLoaderService();
CookieStoreContext* GetCookieStoreContext();
- // mojom::StoragePartitionService interface.
+ // blink::mojom::StoragePartitionService interface.
void OpenLocalStorage(const url::Origin& origin,
- mojom::LevelDBWrapperRequest request) override;
+ blink::mojom::StorageAreaRequest request) override;
void OpenSessionStorage(
const std::string& namespace_id,
- mojom::SessionStorageNamespaceRequest request) override;
+ blink::mojom::SessionStorageNamespaceRequest request) override;
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter() {
return url_loader_factory_getter_;
@@ -163,7 +161,7 @@ class CONTENT_EXPORT StoragePartitionImpl
// binding.
mojo::BindingId Bind(
int process_id,
- mojo::InterfaceRequest<mojom::StoragePartitionService> request);
+ mojo::InterfaceRequest<blink::mojom::StoragePartitionService> request);
auto& bindings_for_testing() { return bindings_; }
@@ -309,7 +307,6 @@ class CONTENT_EXPORT StoragePartitionImpl
scoped_refptr<PaymentAppContextImpl> payment_app_context_;
scoped_refptr<BroadcastChannelProvider> broadcast_channel_provider_;
scoped_refptr<BluetoothAllowedDevicesMap> bluetooth_allowed_devices_map_;
- scoped_refptr<BlobURLLoaderFactory> blob_url_loader_factory_;
scoped_refptr<BlobRegistryWrapper> blob_registry_;
scoped_refptr<PrefetchURLLoaderService> prefetch_url_loader_service_;
scoped_refptr<CookieStoreContext> cookie_store_context_;
@@ -317,7 +314,7 @@ class CONTENT_EXPORT StoragePartitionImpl
// BindingSet for StoragePartitionService, using the process id as the
// binding context type. The process id can subsequently be used during
// interface method calls to enforce security checks.
- mojo::BindingSet<mojom::StoragePartitionService, int> bindings_;
+ mojo::BindingSet<blink::mojom::StoragePartitionService, int> bindings_;
// This is the NetworkContext used to
// make requests for the StoragePartition. When the network service is
@@ -335,7 +332,8 @@ class CONTENT_EXPORT StoragePartitionImpl
// StoragePartition::GetURLLoaderFactoryForBrowserProcess() for
// more details
network::mojom::URLLoaderFactoryPtr url_loader_factory_for_browser_process_;
- ::network::mojom::CookieManagerPtr cookie_manager_for_browser_process_;
+ bool is_test_url_loader_factory_for_browser_process_ = false;
+ network::mojom::CookieManagerPtr cookie_manager_for_browser_process_;
// When the network service is disabled, a NetworkContext is created on the IO
// thread that wraps access to the URLRequestContext.
diff --git a/chromium/content/browser/storage_partition_impl_browsertest.cc b/chromium/content/browser/storage_partition_impl_browsertest.cc
index e2d5a2c13db..a1f42c9a6be 100644
--- a/chromium/content/browser/storage_partition_impl_browsertest.cc
+++ b/chromium/content/browser/storage_partition_impl_browsertest.cc
@@ -6,20 +6,25 @@
#include <string>
+#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/content_browser_test.h"
+#include "content/public/test/simple_url_loader_test_helper.h"
+#include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h"
#include "content/test/storage_partition_test_utils.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "net/http/http_response_headers.h"
+#include "net/http/http_status_code.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/cpp/features.h"
#include "services/network/public/cpp/resource_response_info.h"
+#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
@@ -29,6 +34,8 @@
namespace content {
+namespace {
+
enum class NetworkServiceState {
kDisabled,
kEnabled,
@@ -54,6 +61,39 @@ class StoragePartititionImplBrowsertest
base::test::ScopedFeatureList feature_list_;
};
+// Creates a SimpleURLLoader and starts it to download |url|. Blocks until the
+// load is complete.
+std::unique_ptr<network::SimpleURLLoader> DownloadUrl(
+ const GURL& url,
+ StoragePartition* partition) {
+ auto request = std::make_unique<network::ResourceRequest>();
+ request->url = url;
+ std::unique_ptr<network::SimpleURLLoader> url_loader =
+ network::SimpleURLLoader::Create(std::move(request),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ SimpleURLLoaderTestHelper url_loader_helper;
+ url_loader->DownloadToString(
+ partition->GetURLLoaderFactoryForBrowserProcess().get(),
+ url_loader_helper.GetCallback(),
+ /*max_body_size=*/1024 * 1024);
+ url_loader_helper.WaitForCallback();
+ return url_loader;
+}
+
+void CheckSimpleURLLoaderState(network::SimpleURLLoader* url_loader,
+ int net_error,
+ net::HttpStatusCode http_status_code) {
+ EXPECT_EQ(net_error, url_loader->NetError());
+ if (net_error != net::OK)
+ return;
+ ASSERT_TRUE(url_loader->ResponseInfo());
+ ASSERT_TRUE(url_loader->ResponseInfo()->headers);
+ EXPECT_EQ(http_status_code,
+ url_loader->ResponseInfo()->headers->response_code());
+}
+
+} // namespace
+
// Make sure that the NetworkContext returned by a StoragePartition works, both
// with the network service enabled and with it disabled, when one is created
// that wraps the URLRequestContext created by the BrowserContext.
@@ -158,6 +198,54 @@ IN_PROC_BROWSER_TEST_P(StoragePartititionImplBrowsertest,
factory_owner->LoadBasicRequestOnIOThread(GetTestURL()));
}
+// Checks that the network::URLLoaderIntercpetor works as expected with the
+// SharedURLLoaderFactory returned by StoragePartititionImpl.
+IN_PROC_BROWSER_TEST_P(StoragePartititionImplBrowsertest,
+ URLLoaderInterceptor) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ const GURL kEchoUrl(embedded_test_server()->GetURL("/echo"));
+
+ base::ScopedAllowBlockingForTesting allow_blocking;
+ std::unique_ptr<ShellBrowserContext> browser_context =
+ std::make_unique<ShellBrowserContext>(true, nullptr);
+ auto* partition =
+ BrowserContext::GetDefaultStoragePartition(browser_context.get());
+
+ // Run a request the first time without the interceptor set, as the
+ // StoragePartitionImpl lazily creates the factory and we want to make sure
+ // it will create a new one once the interceptor is set (and not simply reuse
+ // the cached one).
+ {
+ std::unique_ptr<network::SimpleURLLoader> url_loader =
+ DownloadUrl(kEchoUrl, partition);
+ CheckSimpleURLLoaderState(url_loader.get(), net::OK, net::HTTP_OK);
+ }
+
+ // Use a URLLoaderInterceptor to simulate an error.
+ {
+ URLLoaderInterceptor interceptor(base::BindLambdaForTesting(
+ [&](URLLoaderInterceptor::RequestParams* params) -> bool {
+ if (params->url_request.url != kEchoUrl)
+ return false;
+ params->client->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_NOT_IMPLEMENTED));
+ return true;
+ }));
+ std::unique_ptr<network::SimpleURLLoader> url_loader =
+ DownloadUrl(kEchoUrl, partition);
+ CheckSimpleURLLoaderState(url_loader.get(), net::ERR_NOT_IMPLEMENTED,
+ net::HTTP_OK);
+ }
+
+ // Run one more time without the interceptor, we should be back to the
+ // original behavior.
+ {
+ std::unique_ptr<network::SimpleURLLoader> url_loader =
+ DownloadUrl(kEchoUrl, partition);
+ CheckSimpleURLLoaderState(url_loader.get(), net::OK, net::HTTP_OK);
+ }
+}
+
// NetworkServiceState::kEnabled currently DCHECKs on Android, as Android isn't
// expected to create extra processes.
#if defined(OS_ANDROID)
diff --git a/chromium/content/browser/storage_partition_impl_map.cc b/chromium/content/browser/storage_partition_impl_map.cc
index 3be6979bde8..9f56c4c29c5 100644
--- a/chromium/content/browser/storage_partition_impl_map.cc
+++ b/chromium/content/browser/storage_partition_impl_map.cc
@@ -586,6 +586,11 @@ void StoragePartitionImplMap::PostCreateInitialization(
browser_context_->GetResourceContext(),
base::RetainedRef(partition->GetURLRequestContext())));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&BackgroundFetchContext::InitializeOnIOThread,
+ partition->GetBackgroundFetchContext()));
+
// We do not call InitializeURLRequestContext() for media contexts because,
// other than the HTTP cache, the media contexts share the same backing
// objects as their associated "normal" request context. Thus, the previous
diff --git a/chromium/content/browser/tracing/background_memory_tracing_observer.cc b/chromium/content/browser/tracing/background_memory_tracing_observer.cc
index f3dd9e3cd08..cf1f294d09a 100644
--- a/chromium/content/browser/tracing/background_memory_tracing_observer.cc
+++ b/chromium/content/browser/tracing/background_memory_tracing_observer.cc
@@ -4,23 +4,10 @@
#include "content/browser/tracing/background_memory_tracing_observer.h"
-#include "base/trace_event/heap_profiler_event_filter.h"
-#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/memory_dump_request_args.h"
-#include "base/trace_event/trace_log.h"
-#include "content/browser/tracing/background_tracing_rule.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
-using base::trace_event::MemoryDumpManager;
-using base::trace_event::TraceConfig;
-using base::trace_event::TraceLog;
-
namespace content {
-namespace {
-const char kEnableHeapProfilerModeName[] = "enable_heap_profiler_mode";
-const char kBackgroundModeName[] = "background";
-const char kHeapProfilerCategoryFilter[] = "heap_profiler_category_filter";
-} // namespace
// static
BackgroundMemoryTracingObserver*
@@ -33,65 +20,9 @@ BackgroundMemoryTracingObserver::BackgroundMemoryTracingObserver() {}
BackgroundMemoryTracingObserver::~BackgroundMemoryTracingObserver() {}
void BackgroundMemoryTracingObserver::OnScenarioActivated(
- const BackgroundTracingConfigImpl* config) {
- if (!config) {
- DCHECK(!heap_profiling_enabled_);
- return;
- }
-
- const BackgroundTracingRule* heap_profiling_rule = nullptr;
- for (const auto& rule : config->rules()) {
- if (rule->category_preset() == BackgroundTracingConfigImpl::CategoryPreset::
- BENCHMARK_MEMORY_LIGHT &&
- rule->args()) {
- heap_profiling_rule = rule.get();
- break;
- }
- }
- if (!heap_profiling_rule)
- return;
- std::string mode;
- if (!heap_profiling_rule->args()->GetString(kEnableHeapProfilerModeName,
- &mode) ||
- mode != kBackgroundModeName) {
- return;
- }
-
- heap_profiling_enabled_ = true;
- // TODO(ssid): Add ability to enable profiling on all processes,
- // crbug.com/700245.
- MemoryDumpManager::GetInstance()->EnableHeapProfiling(
- base::trace_event::kHeapProfilingModeBackground);
+ const BackgroundTracingConfigImpl* config) {}
- std::string filter_string;
- if (base::trace_event::AllocationContextTracker::capture_mode() ==
- base::trace_event::AllocationContextTracker::CaptureMode::DISABLED ||
- (TraceLog::GetInstance()->enabled_modes() & TraceLog::FILTERING_MODE) ||
- !heap_profiling_rule->args()->GetString(kHeapProfilerCategoryFilter,
- &filter_string)) {
- return;
- }
- base::trace_event::TraceConfigCategoryFilter category_filter;
- category_filter.InitializeFromString(filter_string);
- TraceConfig::EventFilterConfig heap_profiler_filter_config(
- base::trace_event::HeapProfilerEventFilter::kName);
- heap_profiler_filter_config.SetCategoryFilter(category_filter);
- TraceConfig::EventFilters filters;
- filters.push_back(heap_profiler_filter_config);
- TraceConfig filtering_trace_config;
- filtering_trace_config.SetEventFilters(filters);
- TraceLog::GetInstance()->SetEnabled(filtering_trace_config,
- TraceLog::FILTERING_MODE);
-}
-
-void BackgroundMemoryTracingObserver::OnScenarioAborted() {
- if (!heap_profiling_enabled_)
- return;
- heap_profiling_enabled_ = false;
- MemoryDumpManager::GetInstance()->EnableHeapProfiling(
- base::trace_event::kHeapProfilingModeDisabled);
- TraceLog::GetInstance()->SetDisabled(TraceLog::FILTERING_MODE);
-}
+void BackgroundMemoryTracingObserver::OnScenarioAborted() {}
void BackgroundMemoryTracingObserver::OnTracingEnabled(
BackgroundTracingConfigImpl::CategoryPreset preset) {
diff --git a/chromium/content/browser/tracing/background_memory_tracing_observer.h b/chromium/content/browser/tracing/background_memory_tracing_observer.h
index a49b00e61bb..4123e45f4cd 100644
--- a/chromium/content/browser/tracing/background_memory_tracing_observer.h
+++ b/chromium/content/browser/tracing/background_memory_tracing_observer.h
@@ -19,16 +19,10 @@ class CONTENT_EXPORT BackgroundMemoryTracingObserver
void OnTracingEnabled(
BackgroundTracingConfigImpl::CategoryPreset preset) override;
- bool heap_profiling_enabled_for_testing() const {
- return heap_profiling_enabled_;
- }
-
private:
BackgroundMemoryTracingObserver();
~BackgroundMemoryTracingObserver() override;
- bool heap_profiling_enabled_ = false;
-
DISALLOW_COPY_AND_ASSIGN(BackgroundMemoryTracingObserver);
};
diff --git a/chromium/content/browser/tracing/background_memory_tracing_observer_unittest.cc b/chromium/content/browser/tracing/background_memory_tracing_observer_unittest.cc
deleted file mode 100644
index 68762c78c36..00000000000
--- a/chromium/content/browser/tracing/background_memory_tracing_observer_unittest.cc
+++ /dev/null
@@ -1,176 +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/tracing/background_memory_tracing_observer.h"
-
-#include "base/allocator/buildflags.h"
-#include "base/json/json_reader.h"
-#include "base/json/json_writer.h"
-#include "base/message_loop/message_loop.h"
-#include "base/trace_event/heap_profiler_allocation_context_tracker.h"
-#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"
-
-using base::trace_event::AllocationContextTracker;
-using base::trace_event::MemoryDumpManager;
-using base::trace_event::TraceConfig;
-using base::trace_event::TraceLog;
-using base::trace_event::InitializeMemoryDumpManagerForInProcessTesting;
-
-namespace content {
-namespace {
-
-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 = nullptr;
- if (json_value)
- json_value->GetAsDictionary(&dict);
-
- std::unique_ptr<BackgroundTracingConfigImpl> config(
- static_cast<BackgroundTracingConfigImpl*>(
- BackgroundTracingConfig::FromDict(dict).release()));
- CHECK(config);
- return config;
-}
-
-} // namespace
-
-class BackgroundMemoryTracingObserverTest : public testing::Test {
- public:
- BackgroundMemoryTracingObserverTest()
- : ui_thread_(BrowserThread::UI, &message_loop_) {}
-
- void SetUp() override {
- mdm_ = MemoryDumpManager::CreateInstanceForTesting();
- InitializeMemoryDumpManagerForInProcessTesting(
- /*is_coordinator_process=*/false);
- }
-
- void TearDown() override { mdm_ = nullptr; }
-
- private:
- std::unique_ptr<MemoryDumpManager> mdm_;
- base::MessageLoop message_loop_;
- TestBrowserThread ui_thread_;
-};
-
-TEST_F(BackgroundMemoryTracingObserverTest, NoOpOnNonMemoryConfig) {
- auto* observer = BackgroundMemoryTracingObserver::GetInstance();
- auto config = ReadFromJSONString(
- "{\"mode\":\"REACTIVE_TRACING_MODE\", \"configs\": [{\"category\": "
- "\"BENCHMARK\", \"rule\": "
- "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
- "\"histogram_name\":\"foo\", \"histogram_lower_value\": 1, "
- "\"histogram_upper_value\": 2}]}");
- observer->OnScenarioActivated(config.get());
- EXPECT_FALSE(observer->heap_profiling_enabled_for_testing());
- observer->OnTracingEnabled(BackgroundTracingConfigImpl::BENCHMARK);
- EXPECT_EQ(0u, TraceLog::GetInstance()->enabled_modes());
- EXPECT_EQ(AllocationContextTracker::CaptureMode::DISABLED,
- AllocationContextTracker::capture_mode());
-
- observer->OnScenarioAborted();
- EXPECT_FALSE(observer->heap_profiling_enabled_for_testing());
- EXPECT_EQ(0u, TraceLog::GetInstance()->enabled_modes());
- EXPECT_EQ(AllocationContextTracker::CaptureMode::DISABLED,
- AllocationContextTracker::capture_mode());
-}
-
-TEST_F(BackgroundMemoryTracingObserverTest, OnlyBackgroundDumpConfig) {
- auto* observer = BackgroundMemoryTracingObserver::GetInstance();
- auto config = ReadFromJSONString(
- "{\"mode\":\"REACTIVE_TRACING_MODE\", \"configs\": [{\"category\": "
- "\"BENCHMARK_MEMORY_LIGHT\", \"rule\": "
- "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
- "\"histogram_name\":\"foo\", \"histogram_lower_value\": 1, "
- "\"histogram_upper_value\": 2}]}");
- observer->OnScenarioActivated(config.get());
- EXPECT_FALSE(observer->heap_profiling_enabled_for_testing());
- observer->OnTracingEnabled(BackgroundTracingConfigImpl::BENCHMARK);
- EXPECT_EQ(0u, TraceLog::GetInstance()->enabled_modes());
- EXPECT_EQ(AllocationContextTracker::CaptureMode::DISABLED,
- AllocationContextTracker::capture_mode());
-
- observer->OnScenarioAborted();
- EXPECT_FALSE(observer->heap_profiling_enabled_for_testing());
- EXPECT_EQ(0u, TraceLog::GetInstance()->enabled_modes());
- EXPECT_EQ(AllocationContextTracker::CaptureMode::DISABLED,
- AllocationContextTracker::capture_mode());
-}
-
-TEST_F(BackgroundMemoryTracingObserverTest, DISABLED_HeapProfilingConfig) {
- auto* observer = BackgroundMemoryTracingObserver::GetInstance();
- auto config = ReadFromJSONString(
- "{\"mode\":\"REACTIVE_TRACING_MODE\", \"configs\": [{\"category\": "
- "\"BENCHMARK_MEMORY_LIGHT\", \"rule\": "
- "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
- "\"histogram_name\":\"foo\", \"histogram_lower_value\": 1, "
- "\"histogram_upper_value\": 2, \"args\": {\"enable_heap_profiler_mode\": "
- "\"background\"}}]}");
- observer->OnScenarioActivated(config.get());
- 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());
- EXPECT_EQ(0u, TraceLog::GetInstance()->enabled_modes());
- EXPECT_EQ(AllocationContextTracker::CaptureMode::DISABLED,
- AllocationContextTracker::capture_mode());
-}
-
-TEST_F(BackgroundMemoryTracingObserverTest, DISABLED_HeapProfilingWithFilters) {
- auto* observer = BackgroundMemoryTracingObserver::GetInstance();
- auto config = ReadFromJSONString(
- "{\"mode\":\"REACTIVE_TRACING_MODE\", \"configs\": [{\"category\": "
- "\"BENCHMARK_MEMORY_LIGHT\", \"rule\": "
- "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
- "\"histogram_name\":\"foo\", \"histogram_lower_value\": 1, "
- "\"histogram_upper_value\": 2, \"args\": {\"enable_heap_profiler_mode\": "
- "\"background\", \"heap_profiler_category_filter\": \"cat,dog\"}}]}");
- 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());
- const char kExpectedConfig[] =
- "{\"filter_predicate\":\"heap_profiler_predicate\","
- "\"included_categories\":[\"cat\",\"dog\"]}";
- auto trace_config = TraceLog::GetInstance()->GetCurrentTraceConfig();
- ASSERT_EQ(1u, trace_config.event_filters().size());
- base::DictionaryValue filter_dict;
- trace_config.event_filters()[0].ToDict(&filter_dict);
- 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());
- EXPECT_EQ(0u, TraceLog::GetInstance()->enabled_modes());
- EXPECT_EQ(AllocationContextTracker::CaptureMode::DISABLED,
- AllocationContextTracker::capture_mode());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc b/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
index 374da5bb307..d419bace500 100644
--- a/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
+++ b/chromium/content/browser/tracing/background_tracing_manager_browsertest.cc
@@ -144,6 +144,10 @@ class BackgroundTracingManagerUploadConfigWrapper {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(callback_));
}
+ void SetUploadCallback(base::OnceClosure callback) {
+ callback_ = std::move(callback);
+ }
+
bool TraceHasMatchingString(const char* str) {
return last_file_contents_.find(str) != std::string::npos;
}
@@ -151,8 +155,9 @@ class BackgroundTracingManagerUploadConfigWrapper {
int get_receive_count() const { return receive_count_; }
BackgroundTracingManager::ReceiveCallback get_receive_callback() {
- return base::BindOnce(&BackgroundTracingManagerUploadConfigWrapper::Upload,
- base::Unretained(this));
+ return base::BindRepeating(
+ &BackgroundTracingManagerUploadConfigWrapper::Upload,
+ base::Unretained(this));
}
private:
@@ -1335,6 +1340,57 @@ IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
#if defined(OS_ANDROID)
// Flaky on android: https://crbug.com/639706
+#define MAYBE_ReactiveSecondUpload DISABLED_ReactiveSecondUpload
+#else
+#define MAYBE_ReactiveSecondUpload ReactiveSecondUpload
+#endif
+
+// This tests that reactive mode uploads on a second set of triggers.
+IN_PROC_BROWSER_TEST_F(BackgroundTracingManagerBrowserTest,
+ MAYBE_ReactiveSecondUpload) {
+ {
+ SetupBackgroundTracingManager();
+
+ base::RunLoop run_loop;
+ BackgroundTracingManagerUploadConfigWrapper upload_config_wrapper(
+ run_loop.QuitClosure());
+
+ std::unique_ptr<BackgroundTracingConfig> config = CreateReactiveConfig();
+
+ BackgroundTracingManager::TriggerHandle handle =
+ BackgroundTracingManager::GetInstance()->RegisterTriggerType(
+ "reactive_test");
+
+ EXPECT_TRUE(BackgroundTracingManager::GetInstance()->SetActiveScenario(
+ std::move(config), upload_config_wrapper.get_receive_callback(),
+ BackgroundTracingManager::NO_DATA_FILTERING));
+
+ BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
+ handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
+ // second trigger to terminate.
+ BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
+ handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
+
+ run_loop.Run();
+
+ base::RunLoop second_upload_run_loop;
+ upload_config_wrapper.SetUploadCallback(
+ second_upload_run_loop.QuitClosure());
+
+ BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
+ handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
+ // second trigger to terminate.
+ BackgroundTracingManager::GetInstance()->TriggerNamedEvent(
+ handle, base::Bind(&StartedFinalizingCallback, base::Closure(), true));
+
+ second_upload_run_loop.Run();
+
+ EXPECT_TRUE(upload_config_wrapper.get_receive_count() == 2);
+ }
+}
+
+#if defined(OS_ANDROID)
+// Flaky on android: https://crbug.com/639706
#define MAYBE_ReactiveSecondTriggerMustMatchForTermination \
DISABLED_ReactiveSecondTriggerMustMatchForTermination
#else
diff --git a/chromium/content/browser/tracing/background_tracing_manager_impl.cc b/chromium/content/browser/tracing/background_tracing_manager_impl.cc
index c6aefd65be1..30d131e9d11 100644
--- a/chromium/content/browser/tracing/background_tracing_manager_impl.cc
+++ b/chromium/content/browser/tracing/background_tracing_manager_impl.cc
@@ -507,11 +507,12 @@ void BackgroundTracingManagerImpl::OnFinalizeStarted(
file_contents->size() / 1024);
if (!receive_callback_.is_null()) {
- std::move(receive_callback_)
- .Run(file_contents, std::move(metadata),
- base::BindOnce(&BackgroundTracingManagerImpl::OnFinalizeComplete,
- base::Unretained(this)));
+ receive_callback_.Run(
+ file_contents, std::move(metadata),
+ base::BindOnce(&BackgroundTracingManagerImpl::OnFinalizeComplete,
+ base::Unretained(this)));
}
+
if (!started_finalizing_closure.is_null())
std::move(started_finalizing_closure).Run();
}
diff --git a/chromium/content/browser/tracing/cast_tracing_agent.cc b/chromium/content/browser/tracing/cast_tracing_agent.cc
index 41b62141455..29e016250bc 100644
--- a/chromium/content/browser/tracing/cast_tracing_agent.cc
+++ b/chromium/content/browser/tracing/cast_tracing_agent.cc
@@ -45,7 +45,8 @@ CastTracingAgent::CastTracingAgent(service_manager::Connector* connector)
: BaseAgent(connector,
"systemTraceEvents",
tracing::mojom::TraceDataType::STRING,
- false /* supports_explicit_clock_sync */) {
+ false /* supports_explicit_clock_sync */,
+ base::kNullProcessId) {
task_runner_ =
base::TaskScheduler::GetInstance()->CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::BACKGROUND,
diff --git a/chromium/content/browser/tracing/cros_tracing_agent.cc b/chromium/content/browser/tracing/cros_tracing_agent.cc
index 30bb8757a81..7a1cb3536ab 100644
--- a/chromium/content/browser/tracing/cros_tracing_agent.cc
+++ b/chromium/content/browser/tracing/cros_tracing_agent.cc
@@ -26,7 +26,8 @@ CrOSTracingAgent::CrOSTracingAgent(service_manager::Connector* connector)
: BaseAgent(connector,
kCrOSTraceLabel,
tracing::mojom::TraceDataType::STRING,
- false /* supports_explicit_clock_sync */) {}
+ false /* supports_explicit_clock_sync */,
+ base::kNullProcessId) {}
CrOSTracingAgent::~CrOSTracingAgent() = default;
diff --git a/chromium/content/browser/tracing/etw_tracing_agent_win.cc b/chromium/content/browser/tracing/etw_tracing_agent_win.cc
index f25811775f2..94dba186e96 100644
--- a/chromium/content/browser/tracing/etw_tracing_agent_win.cc
+++ b/chromium/content/browser/tracing/etw_tracing_agent_win.cc
@@ -46,7 +46,8 @@ EtwTracingAgent::EtwTracingAgent(service_manager::Connector* connector)
: BaseAgent(connector,
kETWTraceLabel,
tracing::mojom::TraceDataType::OBJECT,
- false /* supports_explicit_clock_sync */),
+ false /* supports_explicit_clock_sync */,
+ base::kNullProcessId),
thread_("EtwConsumerThread"),
is_tracing_(false) {
DCHECK(!g_etw_tracing_agent);
diff --git a/chromium/content/browser/tracing/memory_instrumentation_browsertest.cc b/chromium/content/browser/tracing/memory_instrumentation_browsertest.cc
index 1eeb12aa138..564cadfff62 100644
--- a/chromium/content/browser/tracing/memory_instrumentation_browsertest.cc
+++ b/chromium/content/browser/tracing/memory_instrumentation_browsertest.cc
@@ -53,15 +53,16 @@ std::unique_ptr<GlobalMemoryDump> DoGlobalDump() {
std::unique_ptr<GlobalMemoryDump> result = nullptr;
base::RunLoop run_loop;
memory_instrumentation::MemoryInstrumentation::GetInstance()
- ->RequestGlobalDump(base::Bind(
- [](base::Closure quit_closure,
- std::unique_ptr<GlobalMemoryDump>* out_result, bool success,
- std::unique_ptr<GlobalMemoryDump> result) {
- EXPECT_TRUE(success);
- *out_result = std::move(result);
- std::move(quit_closure).Run();
- },
- run_loop.QuitClosure(), &result));
+ ->RequestGlobalDump(
+ {}, base::Bind(
+ [](base::Closure quit_closure,
+ std::unique_ptr<GlobalMemoryDump>* out_result,
+ bool success, std::unique_ptr<GlobalMemoryDump> result) {
+ EXPECT_TRUE(success);
+ *out_result = std::move(result);
+ std::move(quit_closure).Run();
+ },
+ run_loop.QuitClosure(), &result));
run_loop.Run();
return result;
}
diff --git a/chromium/content/browser/tracing/power_tracing_agent.cc b/chromium/content/browser/tracing/power_tracing_agent.cc
index 2ae2a4d50da..c1b6bb29b29 100644
--- a/chromium/content/browser/tracing/power_tracing_agent.cc
+++ b/chromium/content/browser/tracing/power_tracing_agent.cc
@@ -43,9 +43,9 @@ PowerTracingAgent::PowerTracingAgent(service_manager::Connector* connector)
// Register this agent.
tracing::mojom::AgentPtr agent;
binding_.Bind(mojo::MakeRequest(&agent));
- agent_registry->RegisterAgent(std::move(agent), kPowerTraceLabel,
- tracing::mojom::TraceDataType::STRING,
- true /* supports_explicit_clock_sync */);
+ agent_registry->RegisterAgent(
+ std::move(agent), kPowerTraceLabel, tracing::mojom::TraceDataType::STRING,
+ true /* supports_explicit_clock_sync */, base::kNullProcessId);
}
PowerTracingAgent::PowerTracingAgent() : binding_(this) {}
diff --git a/chromium/content/browser/tracing/tracing_controller_impl.cc b/chromium/content/browser/tracing/tracing_controller_impl.cc
index 0ae496ae61e..ee4fa86896e 100644
--- a/chromium/content/browser/tracing/tracing_controller_impl.cc
+++ b/chromium/content/browser/tracing/tracing_controller_impl.cc
@@ -21,11 +21,11 @@
#include "base/values.h"
#include "build/build_config.h"
#include "components/tracing/common/trace_startup_config.h"
+#include "content/browser/gpu/gpu_data_manager_impl.h"
#include "content/browser/tracing/file_tracing_provider_impl.h"
#include "content/browser/tracing/tracing_ui.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/browser/tracing_controller.h"
#include "content/public/browser/tracing_delegate.h"
#include "content/public/common/content_client.h"
@@ -236,14 +236,16 @@ TracingControllerImpl::GenerateMetadataDict() const {
metadata_dict->SetString("cpu-brand", cpu.cpu_brand());
// GPU
- gpu::GPUInfo gpu_info = content::GpuDataManager::GetInstance()->GetGPUInfo();
+ const gpu::GPUInfo gpu_info =
+ content::GpuDataManagerImpl::GetInstance()->GetGPUInfo();
+ const gpu::GPUInfo::GPUDevice& active_gpu = gpu_info.active_gpu();
#if !defined(OS_ANDROID)
- metadata_dict->SetInteger("gpu-venid", gpu_info.gpu.vendor_id);
- metadata_dict->SetInteger("gpu-devid", gpu_info.gpu.device_id);
+ metadata_dict->SetInteger("gpu-venid", active_gpu.vendor_id);
+ metadata_dict->SetInteger("gpu-devid", active_gpu.device_id);
#endif
- metadata_dict->SetString("gpu-driver", gpu_info.driver_version);
+ metadata_dict->SetString("gpu-driver", active_gpu.driver_version);
metadata_dict->SetString("gpu-psver", gpu_info.pixel_shader_version);
metadata_dict->SetString("gpu-vsver", gpu_info.vertex_shader_version);
@@ -321,8 +323,23 @@ bool TracingControllerImpl::StartTracing(
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;
+ if (IsTracing()) {
+ // Do not allow updating trace config when process filter is not used.
+ if (trace_config.process_filter_config().empty() ||
+ trace_config_->process_filter_config().empty()) {
+ return false;
+ }
+ // Make sure other parts of trace_config (besides process filter)
+ // did not change.
+ base::trace_event::TraceConfig old_config_copy(*trace_config_);
+ base::trace_event::TraceConfig new_config_copy(trace_config);
+ old_config_copy.SetProcessFilterConfig(
+ base::trace_event::TraceConfig::ProcessFilterConfig());
+ new_config_copy.SetProcessFilterConfig(
+ base::trace_event::TraceConfig::ProcessFilterConfig());
+ if (old_config_copy.ToString() != new_config_copy.ToString())
+ return false;
+ }
trace_config_ =
std::make_unique<base::trace_event::TraceConfig>(trace_config);
coordinator_->StartTracing(
diff --git a/chromium/content/browser/url_loader_factory_getter.cc b/chromium/content/browser/url_loader_factory_getter.cc
index e0593366a2a..d3f03804253 100644
--- a/chromium/content/browser/url_loader_factory_getter.cc
+++ b/chromium/content/browser/url_loader_factory_getter.cc
@@ -8,10 +8,12 @@
#include <utility>
#include "base/bind.h"
+#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/lazy_instance.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/common/content_switches.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/network_service.mojom.h"
@@ -114,13 +116,10 @@ URLLoaderFactoryGetter::URLLoaderFactoryGetter() {}
void URLLoaderFactoryGetter::Initialize(StoragePartitionImpl* partition) {
DCHECK(partition);
DCHECK(!pending_network_factory_request_.is_pending());
- DCHECK(!pending_blob_factory_request_.is_pending());
partition_ = partition;
network::mojom::URLLoaderFactoryPtr network_factory;
- network::mojom::URLLoaderFactoryPtr blob_factory;
pending_network_factory_request_ = MakeRequest(&network_factory);
- pending_blob_factory_request_ = mojo::MakeRequest(&blob_factory);
// If NetworkService is disabled, HandleFactoryRequests should be called after
// NetworkContext in |partition_| is ready.
@@ -130,26 +129,14 @@ void URLLoaderFactoryGetter::Initialize(StoragePartitionImpl* partition) {
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&URLLoaderFactoryGetter::InitializeOnIOThread, this,
- network_factory.PassInterface(),
- blob_factory.PassInterface()));
+ network_factory.PassInterface()));
}
void URLLoaderFactoryGetter::HandleFactoryRequests() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
DCHECK(pending_network_factory_request_.is_pending());
- DCHECK(pending_blob_factory_request_.is_pending());
HandleNetworkFactoryRequestOnUIThread(
std::move(pending_network_factory_request_));
-
- // |partition->blob_url_loader_factory_| is not available without the feature.
- if (base::FeatureList::IsEnabled(network::features::kNetworkService) ||
- ServiceWorkerUtils::IsServicificationEnabled()) {
- DCHECK(partition_->GetBlobURLLoaderFactory());
- partition_->GetBlobURLLoaderFactory()->HandleRequest(
- std::move(pending_blob_factory_request_));
- } else {
- pending_blob_factory_request_ = nullptr;
- }
}
void URLLoaderFactoryGetter::OnStoragePartitionDestroyed() {
@@ -195,11 +182,6 @@ void URLLoaderFactoryGetter::CloneNetworkFactory(
GetURLLoaderFactory()->Clone(std::move(network_factory_request));
}
-network::mojom::URLLoaderFactory* URLLoaderFactoryGetter::GetBlobFactory() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- return blob_factory_.get();
-}
-
void URLLoaderFactoryGetter::SetNetworkFactoryForTesting(
network::mojom::URLLoaderFactory* test_factory) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -236,10 +218,8 @@ void URLLoaderFactoryGetter::FlushNetworkInterfaceForTesting() {
URLLoaderFactoryGetter::~URLLoaderFactoryGetter() {}
void URLLoaderFactoryGetter::InitializeOnIOThread(
- network::mojom::URLLoaderFactoryPtrInfo network_factory,
- network::mojom::URLLoaderFactoryPtrInfo blob_factory) {
+ network::mojom::URLLoaderFactoryPtrInfo network_factory) {
network_factory_.Bind(std::move(network_factory));
- blob_factory_.Bind(std::move(blob_factory));
}
void URLLoaderFactoryGetter::HandleNetworkFactoryRequestOnUIThread(
@@ -253,6 +233,9 @@ void URLLoaderFactoryGetter::HandleNetworkFactoryRequestOnUIThread(
network::mojom::URLLoaderFactoryParams::New();
params->process_id = network::mojom::kBrowserProcessId;
params->is_corb_enabled = false;
+ params->disable_web_security =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableWebSecurity);
partition_->GetNetworkContext()->CreateURLLoaderFactory(
std::move(network_factory_request), std::move(params));
}
diff --git a/chromium/content/browser/url_loader_factory_getter.h b/chromium/content/browser/url_loader_factory_getter.h
index da31f8cf52e..39bfbab5b7e 100644
--- a/chromium/content/browser/url_loader_factory_getter.h
+++ b/chromium/content/browser/url_loader_factory_getter.h
@@ -66,11 +66,6 @@ class URLLoaderFactoryGetter
CONTENT_EXPORT void CloneNetworkFactory(
network::mojom::URLLoaderFactoryRequest network_factory_request);
- // Called on the IO thread to get the URLLoaderFactory to the blob service.
- // Must be used only if the network service or servicified service worker is
- // enabled. The pointer shouldn't be cached.
- CONTENT_EXPORT network::mojom::URLLoaderFactory* GetBlobFactory();
-
// Overrides the network URLLoaderFactory for subsequent requests. Passing a
// null pointer will restore the default behavior.
CONTENT_EXPORT void SetNetworkFactoryForTesting(
@@ -102,8 +97,7 @@ class URLLoaderFactoryGetter
CONTENT_EXPORT ~URLLoaderFactoryGetter();
void InitializeOnIOThread(
- network::mojom::URLLoaderFactoryPtrInfo network_factory,
- network::mojom::URLLoaderFactoryPtrInfo blob_factory);
+ network::mojom::URLLoaderFactoryPtrInfo network_factory);
// Send |network_factory_request| to cached |StoragePartitionImpl|.
void HandleNetworkFactoryRequestOnUIThread(
@@ -118,11 +112,9 @@ class URLLoaderFactoryGetter
// Bound with appropriate URLLoaderFactories at HandleFactoryRequests().
network::mojom::URLLoaderFactoryRequest pending_network_factory_request_;
- network::mojom::URLLoaderFactoryRequest pending_blob_factory_request_;
// Only accessed on IO thread.
network::mojom::URLLoaderFactoryPtr network_factory_;
- network::mojom::URLLoaderFactoryPtr blob_factory_;
network::mojom::URLLoaderFactory* test_factory_ = nullptr;
// Used to re-create |network_factory_| when connection error happens. Can
diff --git a/chromium/content/browser/utility_process_host.cc b/chromium/content/browser/utility_process_host.cc
index 3b6dfc16d83..9d7c9791bd9 100644
--- a/chromium/content/browser/utility_process_host.cc
+++ b/chromium/content/browser/utility_process_host.cc
@@ -11,6 +11,7 @@
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
+#include "base/i18n/base_i18n_switches.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "components/network_session_configurator/common/network_switches.h"
@@ -41,6 +42,7 @@
#if defined(OS_WIN)
#include "sandbox/win/src/sandbox_policy.h"
#include "sandbox/win/src/sandbox_types.h"
+#include "services/audio/audio_sandbox_win.h"
#include "services/network/network_sandbox_win.h"
#endif
@@ -74,7 +76,8 @@ class UtilitySandboxedProcessLauncherDelegate
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;
+ sandbox_type_ == service_manager::SANDBOX_TYPE_PPAPI ||
+ sandbox_type_ == service_manager::SANDBOX_TYPE_AUDIO;
DCHECK(supported_sandbox_type);
#endif // DCHECK_IS_ON()
}
@@ -91,6 +94,9 @@ class UtilitySandboxedProcessLauncherDelegate
if (sandbox_type_ == service_manager::SANDBOX_TYPE_NETWORK)
return network::NetworkPreSpawnTarget(policy);
+ if (sandbox_type_ == service_manager::SANDBOX_TYPE_AUDIO)
+ return audio::AudioPreSpawnTarget(policy);
+
return true;
}
#endif // OS_WIN
@@ -187,6 +193,10 @@ void UtilityProcessHost::BindInterface(
std::move(interface_pipe));
}
+void UtilityProcessHost::SetMetricsName(const std::string& metrics_name) {
+ metrics_name_ = metrics_name;
+}
+
void UtilityProcessHost::SetName(const base::string16& name) {
name_ = name;
}
@@ -208,6 +218,7 @@ bool UtilityProcessHost::StartProcess() {
started_ = true;
process_->SetName(name_);
+ process_->SetMetricsName(metrics_name_);
process_->GetHost()->CreateChannelMojo();
if (RenderProcessHost::run_renderer_in_process()) {
@@ -217,7 +228,7 @@ bool UtilityProcessHost::StartProcess() {
in_process_thread_.reset(
g_utility_main_thread_factory(InProcessChildThreadParams(
BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
- process_->GetInProcessBrokerClientInvitation(),
+ process_->GetInProcessMojoInvitation(),
process_->child_connection()->service_token())));
in_process_thread_->Start();
} else {
@@ -279,11 +290,15 @@ bool UtilityProcessHost::StartProcess() {
#if defined(OS_MACOSX)
service_manager::switches::kEnableSandboxLogging,
#endif
+ switches::kForceTextDirection,
+ switches::kForceUIDirection,
switches::kIgnoreCertificateErrors,
switches::kOverrideUseSoftwareGLForTests,
switches::kOverrideEnabledCdmInterfaceVersion,
switches::kProxyServer,
+ switches::kDisableAcceleratedMjpegDecode,
switches::kUseFakeDeviceForMediaStream,
+ switches::kUseFakeJpegDecodeAccelerator,
switches::kUseFileForFakeVideoCapture,
switches::kUseMockCertVerifierForTesting,
switches::kUtilityStartupDialog,
@@ -374,22 +389,4 @@ void UtilityProcessHost::OnProcessCrashed(int exit_code) {
client_, exit_code));
}
-void UtilityProcessHost::NotifyAndDelete(int error_code) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::BindOnce(&UtilityProcessHost::NotifyLaunchFailedAndDelete,
- weak_ptr_factory_.GetWeakPtr(), error_code));
-}
-
-// static
-void UtilityProcessHost::NotifyLaunchFailedAndDelete(
- base::WeakPtr<UtilityProcessHost> host,
- int error_code) {
- if (!host)
- return;
-
- host->OnProcessLaunchFailed(error_code);
- delete host.get();
-}
-
} // namespace content
diff --git a/chromium/content/browser/utility_process_host.h b/chromium/content/browser/utility_process_host.h
index 0185b68cc8a..39edbdf0dbc 100644
--- a/chromium/content/browser/utility_process_host.h
+++ b/chromium/content/browser/utility_process_host.h
@@ -89,6 +89,11 @@ class CONTENT_EXPORT UtilityProcessHost
// Sets the name of the process to appear in the task manager.
void SetName(const base::string16& name);
+ // Sets the name used for metrics reporting. This should not be a localized
+ // name. This is recorded to metrics, so update UtilityProcessNameHash enum in
+ // enums.xml if new values are passed here.
+ void SetMetricsName(const std::string& metrics_name);
+
void set_child_flags(int flags) { child_flags_ = flags; }
// Used when the utility process is going to host a service. |identity| is
@@ -113,14 +118,6 @@ class CONTENT_EXPORT UtilityProcessHost
void OnProcessLaunchFailed(int error_code) override;
void OnProcessCrashed(int exit_code) override;
- // Cleans up |this| as a result of a failed Start().
- void NotifyAndDelete(int error_code);
-
- // Notifies the client that the launch failed and deletes |host|.
- static void NotifyLaunchFailedAndDelete(
- base::WeakPtr<UtilityProcessHost> host,
- int error_code);
-
// Pointer to our client interface used for progress notifications.
scoped_refptr<UtilityProcessHostClient> client_;
@@ -142,6 +139,9 @@ class CONTENT_EXPORT UtilityProcessHost
// The process name used to identify the process in task manager.
base::string16 name_;
+ // The non-localized name used for metrics reporting.
+ std::string metrics_name_;
+
// Child process host implementation.
std::unique_ptr<BrowserChildProcessHostImpl> process_;
diff --git a/chromium/content/browser/utility_process_host_browsertest.cc b/chromium/content/browser/utility_process_host_browsertest.cc
index 44ed195c008..670a457de87 100644
--- a/chromium/content/browser/utility_process_host_browsertest.cc
+++ b/chromium/content/browser/utility_process_host_browsertest.cc
@@ -8,33 +8,67 @@
#include "build/build_config.h"
#include "content/browser/utility_process_host.h"
#include "content/browser/utility_process_host_client.h"
+#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/child_process_data.h"
+#include "content/public/browser/child_process_termination_info.h"
#include "content/public/common/bind_interface_helpers.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_service.mojom.h"
+#if defined(OS_MACOSX) || defined(OS_LINUX)
+#include <sys/wait.h>
+#endif
+
+#if defined(OS_WIN)
+#include <windows.h>
+#endif // OS_WIN
+
namespace content {
-class UtilityProcessHostBrowserTest : public ContentBrowserTest {
+namespace {
+
+const char kTestProcessName[] = "test_process";
+
+} // namespace
+
+class UtilityProcessHostBrowserTest : public BrowserChildProcessObserver,
+ public ContentBrowserTest {
public:
- void RunUtilityProcess(bool elevated) {
+ void RunUtilityProcess(bool elevated, bool crash) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserChildProcessObserver::Add(this);
+ has_launched = false;
+ has_crashed = false;
base::RunLoop run_loop;
- done_closure_ = run_loop.QuitClosure();
+ done_closure_ =
+ base::BindOnce(&UtilityProcessHostBrowserTest::DoneRunning,
+ base::Unretained(this), run_loop.QuitClosure(), crash);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(
&UtilityProcessHostBrowserTest::RunUtilityProcessOnIOThread,
- base::Unretained(this), elevated));
+ base::Unretained(this), elevated, crash));
run_loop.Run();
}
protected:
- void RunUtilityProcessOnIOThread(bool elevated) {
+ void DoneRunning(base::OnceClosure quit_closure, bool expect_crashed) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ BrowserChildProcessObserver::Remove(this);
+ EXPECT_EQ(true, has_launched);
+ EXPECT_EQ(expect_crashed, has_crashed);
+ std::move(quit_closure).Run();
+ }
+
+ void RunUtilityProcessOnIOThread(bool elevated, bool crash) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
UtilityProcessHost* host =
new UtilityProcessHost(/*client=*/nullptr,
/*client_task_runner=*/nullptr);
host->SetName(base::ASCIIToUTF16("TestProcess"));
+ host->SetMetricsName(kTestProcessName);
#if defined(OS_WIN)
if (elevated)
host->SetSandboxType(service_manager::SandboxType::
@@ -43,26 +77,102 @@ class UtilityProcessHostBrowserTest : public ContentBrowserTest {
EXPECT_TRUE(host->Start());
BindInterface(host, &service_);
- service_->DoSomething(base::BindOnce(
- &UtilityProcessHostBrowserTest::OnSomething, base::Unretained(this)));
+ if (crash) {
+ service_->DoCrashImmediately(
+ base::BindOnce(&UtilityProcessHostBrowserTest::OnSomethingOnIOThread,
+ base::Unretained(this), crash));
+ } else {
+ service_->DoSomething(
+ base::BindOnce(&UtilityProcessHostBrowserTest::OnSomethingOnIOThread,
+ base::Unretained(this), crash));
+ }
}
- void OnSomething() {
+ void ResetServiceOnIOThread() {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
service_.reset();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done_closure_);
+ }
+
+ void OnSomethingOnIOThread(bool expect_crash) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ // If service crashes then this never gets called.
+ ASSERT_EQ(false, expect_crash);
+ ResetServiceOnIOThread();
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ std::move(done_closure_));
}
mojom::TestServicePtr service_;
- base::Closure done_closure_;
+ base::OnceClosure done_closure_;
+
+ // Access on UI thread.
+ bool has_launched;
+ bool has_crashed;
+
+ private:
+ // content::BrowserChildProcessObserver implementation:
+ void BrowserChildProcessKilled(
+ const ChildProcessData& data,
+ const ChildProcessTerminationInfo& info) override {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+#if defined(OS_ANDROID)
+ // Android does not send crash notifications but sends kills. See comment in
+ // browser_child_process_observer.h.
+ BrowserChildProcessCrashed(data, info);
+#else
+ FAIL() << "Killed notifications should only happen on Android.";
+#endif
+ }
+
+ void BrowserChildProcessCrashed(
+ const ChildProcessData& data,
+ const ChildProcessTerminationInfo& info) override {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ EXPECT_EQ(true, has_launched);
+#if defined(OS_WIN)
+ EXPECT_EQ(EXCEPTION_BREAKPOINT, DWORD{info.exit_code});
+#elif defined(OS_MACOSX) || defined(OS_LINUX)
+ EXPECT_TRUE(WIFSIGNALED(info.exit_code));
+ EXPECT_EQ(SIGTRAP, WTERMSIG(info.exit_code));
+#endif
+ EXPECT_EQ(kTestProcessName, data.metrics_name);
+ EXPECT_EQ(false, has_crashed);
+ has_crashed = true;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::BindOnce(&UtilityProcessHostBrowserTest::ResetServiceOnIOThread,
+ base::Unretained(this)));
+ std::move(done_closure_).Run();
+ }
+
+ void BrowserChildProcessLaunchedAndConnected(
+ const ChildProcessData& data) override {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Multiple child processes might be launched, check just for ours.
+ if (data.metrics_name == kTestProcessName) {
+ EXPECT_EQ(false, has_launched);
+ has_launched = true;
+ }
+ }
};
IN_PROC_BROWSER_TEST_F(UtilityProcessHostBrowserTest, LaunchProcess) {
- RunUtilityProcess(false);
+ RunUtilityProcess(false, false);
+}
+
+IN_PROC_BROWSER_TEST_F(UtilityProcessHostBrowserTest, LaunchProcessAndCrash) {
+ RunUtilityProcess(false, true);
}
#if defined(OS_WIN)
IN_PROC_BROWSER_TEST_F(UtilityProcessHostBrowserTest, LaunchElevatedProcess) {
- RunUtilityProcess(true);
+ RunUtilityProcess(true, false);
+}
+
+// Disabled because currently this causes a WER dialog to appear.
+IN_PROC_BROWSER_TEST_F(UtilityProcessHostBrowserTest,
+ LaunchElevatedProcessAndCrash_DISABLED) {
+ RunUtilityProcess(true, true);
}
#endif
diff --git a/chromium/content/browser/vibration_browsertest.cc b/chromium/content/browser/vibration_browsertest.cc
index ec6b12a21c7..842c049b978 100644
--- a/chromium/content/browser/vibration_browsertest.cc
+++ b/chromium/content/browser/vibration_browsertest.cc
@@ -26,9 +26,7 @@ namespace {
class VibrationTest : public ContentBrowserTest,
public device::mojom::VibrationManager {
public:
- VibrationTest() : binding_(this){};
-
- void SetUpOnMainThread() override {
+ VibrationTest() : binding_(this) {
// Because Device Service also runs in this process(browser process), here
// we can directly set our binder to intercept interface requests against
// it.
@@ -38,6 +36,11 @@ class VibrationTest : public ContentBrowserTest,
base::Unretained(this)));
}
+ ~VibrationTest() override {
+ service_manager::ServiceContext::ClearGlobalBindersForTesting(
+ device::mojom::kServiceName);
+ }
+
void BindVibrationManager(
const std::string& interface_name,
mojo::ScopedMessagePipeHandle handle,
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 559ee9bdcfd..bf1f7668e32 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
@@ -9,8 +9,8 @@
#include <vector>
#include "base/macros.h"
-#include "base/test/histogram_tester.h"
-#include "base/test/user_action_tester.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/metrics/user_action_tester.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/web_contents/aura/types.h"
#include "content/browser/web_contents/web_contents_view.h"
diff --git a/chromium/content/browser/web_contents/web_contents_android.cc b/chromium/content/browser/web_contents/web_contents_android.cc
index 634d995b762..8cb3bf4b93e 100644
--- a/chromium/content/browser/web_contents/web_contents_android.cc
+++ b/chromium/content/browser/web_contents/web_contents_android.cc
@@ -6,6 +6,7 @@
#include <stdint.h>
#include <string>
+#include <utility>
#include <vector>
#include "base/android/callback_android.h"
@@ -21,7 +22,6 @@
#include "base/task_scheduler/post_task.h"
#include "content/browser/accessibility/browser_accessibility_android.h"
#include "content/browser/accessibility/browser_accessibility_manager_android.h"
-#include "content/browser/android/content_view_core.h"
#include "content/browser/android/java/gin_java_bridge_dispatcher_host.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/media/android/browser_media_player_manager.h"
@@ -644,7 +644,7 @@ void WebContentsAndroid::SetOverscrollRefreshHandler(
overscroll_refresh_handler));
}
-void WebContentsAndroid::GetContentBitmap(
+void WebContentsAndroid::WriteContentBitmapToDisk(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
jint width,
@@ -769,7 +769,6 @@ void WebContentsAndroid::OnFinishGetContentBitmap(
const std::string& path,
const SkBitmap& bitmap) {
JNIEnv* env = base::android::AttachCurrentThread();
- ScopedJavaLocalRef<jobject> java_bitmap;
if (!bitmap.drawsNothing()) {
auto task_runner = base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
@@ -843,10 +842,24 @@ void WebContentsAndroid::OnScaleFactorChanged(
if (rwhva) {
// |SendScreenRects()| indirectly calls GetViewSize() that asks Java layer.
web_contents_->SendScreenRects();
- rwhva->SynchronizeVisualProperties();
+ rwhva->SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
+ base::nullopt);
}
}
+void WebContentsAndroid::SetFocus(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ jboolean focused) {
+ WebContentsViewAndroid* view =
+ static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
+ view->SetFocus(focused);
+}
+
+bool WebContentsAndroid::IsBeingDestroyed(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
+ return web_contents_->IsBeingDestroyed();
+}
+
int WebContentsAndroid::GetTopControlsShrinkBlinkHeightPixForTesting(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
@@ -857,4 +870,15 @@ int WebContentsAndroid::GetTopControlsShrinkBlinkHeightPixForTesting(
: 0;
}
+void WebContentsAndroid::SetDisplayCutoutSafeArea(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ int top,
+ int left,
+ int bottom,
+ int right) {
+ web_contents()->SetDisplayCutoutSafeArea(
+ gfx::Insets(top, left, bottom, right));
+}
+
} // namespace content
diff --git a/chromium/content/browser/web_contents/web_contents_android.h b/chromium/content/browser/web_contents/web_contents_android.h
index 04455bd0666..d5094a6ad5c 100644
--- a/chromium/content/browser/web_contents/web_contents_android.h
+++ b/chromium/content/browser/web_contents/web_contents_android.h
@@ -178,12 +178,13 @@ class CONTENT_EXPORT WebContentsAndroid
const base::android::JavaParamRef<jobject>& overscroll_refresh_handler);
// Relay the access from Java layer to RWHV::CopyFromSurface() through JNI.
- void GetContentBitmap(JNIEnv* env,
- const base::android::JavaParamRef<jobject>& obj,
- jint width,
- jint height,
- const base::android::JavaParamRef<jstring>& jpath,
- const base::android::JavaParamRef<jobject>& jcallback);
+ void WriteContentBitmapToDisk(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jint width,
+ jint height,
+ const base::android::JavaParamRef<jstring>& jpath,
+ const base::android::JavaParamRef<jobject>& jcallback);
void ReloadLoFiImages(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
@@ -236,6 +237,11 @@ class CONTENT_EXPORT WebContentsAndroid
void OnScaleFactorChanged(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
+ void SetFocus(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ jboolean focused);
+ bool IsBeingDestroyed(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
// Returns the amount of the top controls height if controls are in the state
// of shrinking Blink's view size, otherwise 0.
@@ -243,6 +249,13 @@ class CONTENT_EXPORT WebContentsAndroid
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
+ void SetDisplayCutoutSafeArea(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ int top,
+ int left,
+ int bottom,
+ int right);
+
private:
RenderWidgetHostViewAndroid* GetRenderWidgetHostViewAndroid();
diff --git a/chromium/content/browser/web_contents/web_contents_impl.cc b/chromium/content/browser/web_contents/web_contents_impl.cc
index 6ae9bf2f9c6..26384f823b5 100644
--- a/chromium/content/browser/web_contents/web_contents_impl.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl.cc
@@ -42,6 +42,7 @@
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/devtools/protocol/page_handler.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
+#include "content/browser/display_cutout/display_cutout_host_impl.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
#include "content/browser/download/mhtml_generation_manager.h"
@@ -113,6 +114,7 @@
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents_binding_set.h"
#include "content/public/browser/web_contents_delegate.h"
+#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/child_process_host.h"
@@ -136,6 +138,7 @@
#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/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/frame/sandbox_flags.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
#include "third_party/blink/public/platform/web_security_style.h"
@@ -152,7 +155,6 @@
#endif
#if defined(OS_ANDROID)
-#include "content/browser/android/content_video_view.h"
#include "content/browser/android/date_time_chooser_android.h"
#include "content/browser/android/java_interfaces_impl.h"
#include "content/browser/media/android/media_web_contents_observer_android.h"
@@ -238,6 +240,25 @@ RenderFrameHostImpl* FindOpenerRFH(const WebContents::CreateParams& params) {
return opener_rfh;
}
+// Returns |true| if |type| is the kind of user input that should trigger the
+// user interaction observers.
+bool IsUserInteractionInputType(blink::WebInputEvent::Type type) {
+ // Ideally, this list would be based more off of
+ // https://whatwg.org/C/interaction.html#triggered-by-user-activation.
+ return type == blink::WebInputEvent::kMouseDown ||
+ type == blink::WebInputEvent::kGestureScrollBegin ||
+ type == blink::WebInputEvent::kTouchStart ||
+ type == blink::WebInputEvent::kRawKeyDown;
+}
+
+// Returns |true| if |type| is the kind of user input that should be used as
+// a user gesture signal for resource load dispatches.
+bool IsResourceLoadUserInteractionInputType(blink::WebInputEvent::Type type) {
+ return type == blink::WebInputEvent::kMouseDown ||
+ type == blink::WebInputEvent::kTouchStart ||
+ type == blink::WebInputEvent::kRawKeyDown;
+}
+
// Ensures that OnDialogClosed is only called once.
class CloseDialogCallbackWrapper
: public base::RefCountedThreadSafe<CloseDialogCallbackWrapper> {
@@ -516,7 +537,6 @@ WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
fullscreen_widget_process_id_(ChildProcessHost::kInvalidUniqueID),
fullscreen_widget_routing_id_(MSG_ROUTING_NONE),
fullscreen_widget_had_focus_at_shutdown_(false),
- is_subframe_(false),
force_disable_overscroll_content_(false),
last_dialog_suppressed_(false),
accessibility_mode_(
@@ -549,6 +569,14 @@ WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
host_zoom_map_observer_.reset(new HostZoomMapObserver(this));
#endif // !defined(OS_ANDROID)
+#if defined(OS_ANDROID)
+ if (base::FeatureList::IsEnabled(features::kDisplayCutoutAPI)) {
+ display_cutout_host_impl_ = std::make_unique<DisplayCutoutHostImpl>(
+ this, base::BindRepeating(&WebContentsImpl::NotifyViewportFitChanged,
+ base::Unretained(this)));
+ }
+#endif
+
registry_.AddInterface(base::BindRepeating(
&WebContentsImpl::OnColorChooserFactoryRequest, base::Unretained(this)));
}
@@ -634,6 +662,17 @@ WebContentsImpl::~WebContentsImpl() {
pepper_playback_observer_.reset();
#endif // defined(ENABLED_PLUGINS)
+ // If audio is playing then notify external observers of the audio stream
+ // disappearing.
+ if (is_currently_audible_) {
+ is_currently_audible_ = false;
+ for (auto& observer : observers_)
+ observer.OnAudioStateChanged(false);
+
+ if (GetOuterWebContents())
+ GetOuterWebContents()->OnAudioStateChanged();
+ }
+
for (auto& observer : observers_)
observer.FrameDeleted(root->current_frame_host());
@@ -692,9 +731,6 @@ std::unique_ptr<WebContentsImpl> WebContentsImpl::CreateWithOpener(
// This makes |new_contents| act as a guest.
// For more info, see comment above class BrowserPluginGuest.
BrowserPluginGuest::Create(new_contents.get(), params.guest_delegate);
- // We are instantiating a WebContents for browser plugin. Set its subframe
- // bit to true.
- new_contents->is_subframe_ = true;
}
new_contents->Init(params);
@@ -1005,7 +1041,7 @@ WebContentsView* WebContentsImpl::GetView() const {
void WebContentsImpl::OnScreenOrientationChange() {
DCHECK(screen_orientation_provider_);
- return screen_orientation_provider_->OnOrientationChange();
+ screen_orientation_provider_->OnOrientationChange();
}
SkColor WebContentsImpl::GetThemeColor() const {
@@ -1105,27 +1141,22 @@ void WebContentsImpl::RecursiveRequestAXTreeSnapshotOnFrame(
}
}
-#if !defined(OS_ANDROID)
-void WebContentsImpl::SetTemporaryZoomLevel(double level,
- bool temporary_zoom_enabled) {
- SendPageMessage(new PageMsg_SetZoomLevel(
- MSG_ROUTING_NONE,
- temporary_zoom_enabled ? PageMsg_SetZoomLevel_Command::SET_TEMPORARY
- : PageMsg_SetZoomLevel_Command::CLEAR_TEMPORARY,
- level));
+void WebContentsImpl::NotifyViewportFitChanged(
+ blink::mojom::ViewportFit value) {
+ for (auto& observer : observers_)
+ observer.ViewportFitChanged(value);
}
-void WebContentsImpl::UpdateZoom(double level) {
- // Individual frames may still ignore the new zoom level if their RenderView
- // contains a plugin document or if it uses a temporary zoom level.
- SendPageMessage(new PageMsg_SetZoomLevel(
- MSG_ROUTING_NONE,
- PageMsg_SetZoomLevel_Command::USE_CURRENT_TEMPORARY_MODE, level));
+#if !defined(OS_ANDROID)
+void WebContentsImpl::UpdateZoom() {
+ RenderWidgetHostImpl* rwh = GetRenderViewHost()->GetWidget();
+ if (rwh->GetView())
+ rwh->SynchronizeVisualProperties();
}
+
void WebContentsImpl::UpdateZoomIfNecessary(const std::string& scheme,
- const std::string& host,
- double level) {
+ const std::string& host) {
NavigationEntry* entry = GetController().GetLastCommittedEntry();
if (!entry)
return;
@@ -1136,7 +1167,7 @@ void WebContentsImpl::UpdateZoomIfNecessary(const std::string& scheme,
return;
}
- UpdateZoom(level);
+ UpdateZoom();
}
#endif // !defined(OS_ANDROID)
@@ -1254,6 +1285,15 @@ const std::string& WebContentsImpl::GetMediaDeviceGroupIDSaltBase() const {
return media_device_group_id_salt_base_;
}
+#if defined(OS_ANDROID)
+
+void WebContentsImpl::SetDisplayCutoutSafeArea(gfx::Insets insets) {
+ if (display_cutout_host_impl_)
+ display_cutout_host_impl_->SetDisplayCutoutSafeArea(insets);
+}
+
+#endif
+
const base::string16& WebContentsImpl::GetTitle() const {
// Transient entries take precedence. They are used for interstitial pages
// that are shown on top of existing pages.
@@ -1435,7 +1475,7 @@ void WebContentsImpl::SetAudioMuted(bool mute) {
}
bool WebContentsImpl::IsCurrentlyAudible() {
- return audio_stream_monitor()->IsCurrentlyAudible();
+ return is_currently_audible_;
}
bool WebContentsImpl::IsConnectedToBluetoothDevice() const {
@@ -1456,14 +1496,29 @@ void WebContentsImpl::SetHasPictureInPictureVideo(
}
bool WebContentsImpl::IsCrashed() const {
- return (crashed_status_ == base::TERMINATION_STATUS_PROCESS_CRASHED ||
- crashed_status_ == base::TERMINATION_STATUS_ABNORMAL_TERMINATION ||
- crashed_status_ == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ||
+ switch (crashed_status_) {
+ case base::TERMINATION_STATUS_PROCESS_CRASHED:
+ case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
+ case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
+ case base::TERMINATION_STATUS_OOM:
+ case base::TERMINATION_STATUS_LAUNCH_FAILED:
#if defined(OS_CHROMEOS)
- crashed_status_ ==
- base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM ||
+ case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
+#endif
+#if defined(OS_ANDROID)
+ case base::TERMINATION_STATUS_OOM_PROTECTED:
#endif
- crashed_status_ == base::TERMINATION_STATUS_LAUNCH_FAILED);
+ return true;
+ case base::TERMINATION_STATUS_NORMAL_TERMINATION:
+ case base::TERMINATION_STATUS_STILL_RUNNING:
+ return false;
+ case base::TERMINATION_STATUS_MAX_ENUM:
+ NOTREACHED();
+ return false;
+ }
+
+ NOTREACHED();
+ return false;
}
void WebContentsImpl::SetIsCrashed(base::TerminationStatus status,
@@ -1502,26 +1557,40 @@ void WebContentsImpl::NotifyNavigationStateChanged(
GetOuterWebContents()->NotifyNavigationStateChanged(changed_flags);
}
-void WebContentsImpl::OnAudioStateChanged(bool is_audible) {
- SendPageMessage(new PageMsg_AudioStateChanged(MSG_ROUTING_NONE, is_audible));
+void WebContentsImpl::OnAudioStateChanged() {
+ // This notification can come from any embedded contents or from this
+ // WebContents' stream monitor. Aggregate these signals to get the actual
+ // state.
+ bool is_currently_audible =
+ audio_stream_monitor_.IsCurrentlyAudible() ||
+ (browser_plugin_embedder_ &&
+ browser_plugin_embedder_->AreAnyGuestsCurrentlyAudible());
+ if (is_currently_audible == is_currently_audible_)
+ return;
+
+ // Update internal state.
+ is_currently_audible_ = is_currently_audible;
+ was_ever_audible_ = was_ever_audible_ || is_currently_audible_;
+
+ SendPageMessage(
+ new PageMsg_AudioStateChanged(MSG_ROUTING_NONE, is_currently_audible_));
// Notification for UI updates in response to the changed audio state.
NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB);
- was_ever_audible_ = was_ever_audible_ || is_audible;
+ // Ensure that audio state changes propagate from innermost to outermost
+ // WebContents.
+ if (GetOuterWebContents())
+ GetOuterWebContents()->OnAudioStateChanged();
for (auto& observer : observers_)
- observer.OnAudioStateChanged(is_audible);
+ observer.OnAudioStateChanged(is_currently_audible_);
}
base::TimeTicks WebContentsImpl::GetLastActiveTime() const {
return last_active_time_;
}
-void WebContentsImpl::SetLastActiveTime(base::TimeTicks last_active_time) {
- last_active_time_ = last_active_time;
-}
-
void WebContentsImpl::WasShown() {
controller_.SetActive(true);
@@ -1555,9 +1624,10 @@ void WebContentsImpl::WasShown() {
}
void WebContentsImpl::WasHidden() {
- // If there are entities capturing screenshots or video (e.g., mirroring),
- // don't activate the "disable rendering" optimization.
- if (!IsBeingCaptured()) {
+ // If there are entities capturing screenshots or video (e.g. mirroring),
+ // or in Picture-in-Picture mode, don't activate the "disable rendering"
+ // optimization.
+ if (!IsBeingCaptured() && !HasPictureInPictureVideo()) {
// |GetRenderViewHost()| can be NULL if the user middle clicks a link to
// open a tab in the background, then closes the tab before selecting it.
// This is because closing the tab calls WebContentsImpl::Destroy(), which
@@ -1653,9 +1723,16 @@ void WebContentsImpl::DispatchBeforeUnload() {
void WebContentsImpl::AttachToOuterWebContentsFrame(
WebContents* outer_web_contents,
RenderFrameHost* outer_contents_frame) {
- CHECK(GuestMode::IsCrossProcessFrameGuest(this));
+ DCHECK(!node_.outer_web_contents());
+
RenderFrameHostManager* render_manager = GetRenderManager();
+ // When attaching a WebContents as an inner WebContents, we need to replace
+ // the Webcontents' view with a WebContentsViewChildFrame.
+ view_.reset(new WebContentsViewChildFrame(
+ this, GetContentClient()->browser()->GetWebContentsViewDelegate(this),
+ &render_view_host_delegate_view_));
+
// When the WebContents being initialized has an opener, the browser side
// Render{View,Frame}Host must be initialized and the RenderWidgetHostView
// created. This is needed because the usual initialization happens during
@@ -1745,8 +1822,11 @@ void WebContentsImpl::Stop() {
observer.NavigationStopped();
}
-void WebContentsImpl::FreezePage() {
- SendPageMessage(new PageMsg_FreezePage(MSG_ROUTING_NONE));
+void WebContentsImpl::SetPageFrozen(bool frozen) {
+ // A visible page is never frozen.
+ DCHECK_NE(Visibility::VISIBLE, GetVisibility());
+
+ SendPageMessage(new PageMsg_SetPageFrozen(MSG_ROUTING_NONE, frozen));
}
std::unique_ptr<WebContents> WebContentsImpl::Clone() {
@@ -1808,6 +1888,9 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
visibility_ =
params.initially_hidden ? Visibility::HIDDEN : Visibility::VISIBLE;
+ if (!params.last_active_time.is_null())
+ last_active_time_ = params.last_active_time;
+
// The routing ids must either all be set or all be unset.
DCHECK((params.routing_id == MSG_ROUTING_NONE &&
params.main_frame_routing_id == MSG_ROUTING_NONE &&
@@ -1832,10 +1915,13 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
int32_t view_routing_id = params.routing_id;
int32_t main_frame_widget_routing_id = params.main_frame_widget_routing_id;
if (main_frame_widget_routing_id == MSG_ROUTING_NONE) {
- view_routing_id = main_frame_widget_routing_id =
+ view_routing_id = site_instance->GetProcess()->GetNextRoutingID();
+ main_frame_widget_routing_id =
site_instance->GetProcess()->GetNextRoutingID();
}
+ DCHECK_NE(view_routing_id, main_frame_widget_routing_id);
+
GetRenderManager()->Init(
site_instance.get(), view_routing_id, params.main_frame_routing_id,
main_frame_widget_routing_id, params.renderer_initiated_creation);
@@ -1985,6 +2071,10 @@ void WebContentsImpl::LostCapture(RenderWidgetHostImpl* render_widget_host) {
delegate_->LostCapture();
}
+ukm::SourceId WebContentsImpl::GetUkmSourceIdForLastCommittedSource() const {
+ return last_committed_source_id_;
+}
+
void WebContentsImpl::RenderWidgetCreated(
RenderWidgetHostImpl* render_widget_host) {
created_widgets_.insert(render_widget_host);
@@ -2207,12 +2297,6 @@ void WebContentsImpl::ExitFullscreenMode(bool will_cause_resize) {
->ShutdownAndDestroyWidget(true);
}
-#if defined(OS_ANDROID)
- ContentVideoView* video_view = ContentVideoView::GetInstance();
- if (video_view != NULL)
- video_view->ExitFullscreen();
-#endif
-
if (delegate_) {
delegate_->ExitFullscreenModeForTab(this);
@@ -2235,12 +2319,83 @@ void WebContentsImpl::ExitFullscreenMode(bool will_cause_resize) {
}
}
+ // Clear the current fullscreen frame ID.
+ current_fullscreen_frame_tree_node_id_ = RenderFrameHost::kNoFrameTreeNodeId;
+
for (auto& observer : observers_) {
observer.DidToggleFullscreenModeForTab(IsFullscreenForCurrentTab(),
will_cause_resize);
}
}
+void WebContentsImpl::FullscreenStateChanged(RenderFrameHost* rfh,
+ bool is_fullscreen) {
+ int frame_tree_node_id = rfh->GetFrameTreeNodeId();
+ auto it = fullscreen_frame_tree_nodes_.find(frame_tree_node_id);
+ bool changed = false;
+
+ if (is_fullscreen) {
+ // If we are fullscreen then add the FrameTreeNode ID to the set.
+ if (it == fullscreen_frame_tree_nodes_.end()) {
+ fullscreen_frame_tree_nodes_.insert(frame_tree_node_id);
+ changed = true;
+ }
+ } else {
+ FrameTreeNode* ancestor =
+ static_cast<RenderFrameHostImpl*>(rfh)->frame_tree_node();
+ DCHECK(ancestor);
+
+ // If we are not fullscreen then remove this frame and any descendants
+ // from the set.
+ for (it = fullscreen_frame_tree_nodes_.begin();
+ it != fullscreen_frame_tree_nodes_.end();) {
+ FrameTreeNode* node = FrameTreeNode::GloballyFindByID(*it);
+
+ if (!node || frame_tree_node_id == *it ||
+ node->IsDescendantOf(ancestor)) {
+ it = fullscreen_frame_tree_nodes_.erase(it);
+ changed = true;
+ } else {
+ ++it;
+ }
+ }
+ }
+
+ // If we have changed then find the current fullscreen FrameTreeNode
+ // and call the observers. If we have exited fullscreen then this
+ // will be the last frame that was fullscreen.
+ if (changed && fullscreen_frame_tree_nodes_.size() > 0) {
+ unsigned int max_depth = 0;
+ RenderFrameHost* max_depth_rfh = nullptr;
+
+ for (auto node_id : fullscreen_frame_tree_nodes_) {
+ FrameTreeNode* fullscreen_node = FrameTreeNode::GloballyFindByID(node_id);
+ DCHECK(fullscreen_node);
+
+ if (max_depth_rfh == nullptr || fullscreen_node->depth() > max_depth) {
+ max_depth = fullscreen_node->depth();
+ max_depth_rfh = fullscreen_node->current_frame_host();
+ }
+ }
+
+ // If we have already notified observers about this frame then we should not
+ // fire the observers again.
+ DCHECK(max_depth_rfh);
+ if (max_depth_rfh->GetFrameTreeNodeId() ==
+ current_fullscreen_frame_tree_node_id_)
+ return;
+
+ current_fullscreen_frame_tree_node_id_ =
+ max_depth_rfh->GetFrameTreeNodeId();
+
+ for (auto& observer : observers_)
+ observer.DidAcquireFullscreen(max_depth_rfh);
+ } else if (fullscreen_frame_tree_nodes_.size() == 0) {
+ current_fullscreen_frame_tree_node_id_ =
+ RenderFrameHost::kNoFrameTreeNodeId;
+ }
+}
+
bool WebContentsImpl::IsFullscreenForCurrentTab() const {
return delegate_ ? delegate_->IsFullscreenForTabOrPending(this) : false;
}
@@ -2501,6 +2656,10 @@ void WebContentsImpl::CreateNewWindow(
}
// Save the created window associated with the route so we can show it
// later.
+ //
+ // TODO(ajwong): This should be keyed off the RenderFrame routing id or the
+ // FrameTreeNode id instead of the routing id of the Widget for the main
+ // frame. https://crbug.com/545684
DCHECK_NE(MSG_ROUTING_NONE, main_frame_widget_route_id);
pending_contents_[std::make_pair(render_process_id,
main_frame_widget_route_id)] =
@@ -2541,7 +2700,7 @@ void WebContentsImpl::CreateNewWindow(
delegate_->AddNewContents(this, std::move(new_contents),
params.disposition, initial_rect,
- params.user_gesture, &was_blocked);
+ params.mimic_user_gesture, &was_blocked);
if (!weak_new_contents)
return; // The delegate deleted |new_contents| during AddNewContents().
}
@@ -2551,7 +2710,7 @@ void WebContentsImpl::CreateNewWindow(
WindowOpenDisposition::CURRENT_TAB,
ui::PAGE_TRANSITION_LINK,
true /* is_renderer_initiated */);
- open_params.user_gesture = params.user_gesture;
+ open_params.user_gesture = params.mimic_user_gesture;
if (delegate_ && !is_guest &&
!delegate_->ShouldResumeRequestsForCreatedWindow()) {
@@ -2638,7 +2797,7 @@ void WebContentsImpl::ShowCreatedWindow(int process_id,
RenderWidgetHostImpl* rwh =
weak_popup->GetMainFrame()->GetRenderWidgetHost();
DCHECK_EQ(main_frame_widget_route_id, rwh->GetRoutingID());
- rwh->Send(new ViewMsg_Move_ACK(rwh->GetRoutingID()));
+ rwh->Send(new ViewMsg_SetBounds_ACK(rwh->GetRoutingID()));
}
}
@@ -2719,7 +2878,7 @@ std::unique_ptr<WebContents> WebContentsImpl::GetCreatedWindow(
if (BrowserPluginGuest::IsGuest(raw_new_contents))
return new_contents;
- if (!new_contents->GetMainFrame()->GetProcess()->HasConnection() ||
+ if (!new_contents->GetMainFrame()->GetProcess()->IsInitializedAndNotDead() ||
!new_contents->GetMainFrame()->GetView()) {
return nullptr;
}
@@ -2739,7 +2898,7 @@ RenderWidgetHostView* WebContentsImpl::GetCreatedWidget(int process_id,
pending_widget_views_.erase(std::make_pair(process_id, route_id));
RenderWidgetHost* widget_host = widget_host_view->GetRenderWidgetHost();
- if (!widget_host->GetProcess()->HasConnection()) {
+ if (!widget_host->GetProcess()->IsInitializedAndNotDead()) {
// The view has gone away or the renderer crashed. Nothing to do.
return nullptr;
}
@@ -2749,12 +2908,13 @@ RenderWidgetHostView* WebContentsImpl::GetCreatedWidget(int process_id,
void WebContentsImpl::RequestMediaAccessPermission(
const MediaStreamRequest& request,
- const MediaResponseCallback& callback) {
+ MediaResponseCallback callback) {
if (delegate_) {
- delegate_->RequestMediaAccessPermission(this, request, callback);
+ delegate_->RequestMediaAccessPermission(this, request, std::move(callback));
} else {
- callback.Run(MediaStreamDevices(), MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN,
- std::unique_ptr<MediaStreamUI>());
+ std::move(callback).Run(MediaStreamDevices(),
+ MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN,
+ std::unique_ptr<MediaStreamUI>());
}
}
@@ -2810,7 +2970,7 @@ ui::AXMode WebContentsImpl::GetAccessibilityMode() const {
}
void WebContentsImpl::AccessibilityEventReceived(
- const std::vector<AXEventNotificationDetails>& details) {
+ const AXEventNotificationDetails& details) {
for (auto& observer : observers_)
observer.AccessibilityEventReceived(details);
}
@@ -2977,6 +3137,14 @@ void WebContentsImpl::SelectRange(const gfx::Point& base,
focused_frame->GetFrameInputHandler()->SelectRange(base, extent);
}
+#if defined(OS_MACOSX)
+void WebContentsImpl::DidChangeTextSelection(const base::string16& text,
+ const gfx::Range& range) {
+ for (auto& observer : observers_)
+ observer.DidChangeTextSelection(text, range);
+}
+#endif
+
void WebContentsImpl::MoveCaret(const gfx::Point& extent) {
RenderFrameHostImpl* focused_frame = GetFocusedFrame();
if (!focused_frame)
@@ -3039,8 +3207,14 @@ void WebContentsImpl::ResetAutoResizeSize() {
}
WebContents* WebContentsImpl::OpenURL(const OpenURLParams& params) {
- if (!delegate_)
+ if (!delegate_) {
+ // Embedder can delay setting a delegate on new WebContents with
+ // WebContentsDelegate::ShouldResumeRequestsForCreatedWindow. In the mean
+ // time, navigations, including the initial one, that goes through OpenURL
+ // should be delayed until embedder is ready to resume loading.
+ delayed_open_url_params_ = std::make_unique<OpenURLParams>(params);
return nullptr;
+ }
WebContents* new_contents = delegate_->OpenURLFromTab(this, params);
@@ -3211,6 +3385,17 @@ void WebContentsImpl::ReloadLoFiImages() {
SendToAllFrames(new FrameMsg_ReloadLoFiImages(MSG_ROUTING_NONE));
}
+std::vector<blink::mojom::PauseSubresourceLoadingHandlePtr>
+WebContentsImpl::PauseSubresourceLoading() {
+ std::vector<blink::mojom::PauseSubresourceLoadingHandlePtr> handles;
+ for (RenderFrameHost* rfh : GetAllFrames()) {
+ if (!rfh->IsRenderFrameLive())
+ continue;
+ handles.push_back(rfh->PauseSubresourceLoading());
+ }
+ return handles;
+}
+
void WebContentsImpl::Undo() {
RenderFrameHostImpl* focused_frame = GetFocusedFrame();
if (!focused_frame)
@@ -3618,7 +3803,7 @@ void WebContentsImpl::SystemDragEnded(RenderWidgetHost* source_rwh) {
}
void WebContentsImpl::NavigatedByUser() {
- OnUserInteraction(blink::WebInputEvent::kUndefined);
+ SendUserGestureForResourceDispatchHost();
}
void WebContentsImpl::SetClosedByUserGesture(bool value) {
@@ -3747,10 +3932,6 @@ int WebContentsImpl::DownloadImage(
return download_id;
}
-bool WebContentsImpl::IsSubframe() const {
- return is_subframe_;
-}
-
void WebContentsImpl::Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options) {
@@ -3768,12 +3949,6 @@ void WebContentsImpl::StopFinding(StopFindAction action) {
manager->StopFinding(action);
}
-bool WebContentsImpl::WasRecentlyAudible() {
- return audio_stream_monitor_.WasRecentlyAudible() ||
- (browser_plugin_embedder_ &&
- browser_plugin_embedder_->WereAnyGuestsRecentlyAudible());
-}
-
bool WebContentsImpl::WasEverAudible() {
return was_ever_audible_;
}
@@ -3903,6 +4078,7 @@ void WebContentsImpl::ReadyToCommitNavigation(
void WebContentsImpl::DidFinishNavigation(NavigationHandle* navigation_handle) {
TRACE_EVENT1("navigation", "WebContentsImpl::DidFinishNavigation",
"navigation_handle", navigation_handle);
+
for (auto& observer : observers_)
observer.DidFinishNavigation(navigation_handle);
@@ -3922,6 +4098,9 @@ void WebContentsImpl::DidFinishNavigation(NavigationHandle* navigation_handle) {
if (navigation_handle->IsInMainFrame() &&
!navigation_handle->IsSameDocument()) {
was_ever_audible_ = false;
+ last_committed_source_id_ =
+ ukm::ConvertToSourceId(navigation_handle->GetNavigationId(),
+ ukm::SourceIdType::NAVIGATION_ID);
}
}
}
@@ -4698,6 +4877,8 @@ void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host,
for (auto& observer : observers_)
observer.RenderViewHostChanged(old_host, new_host);
+ view_->RenderViewHostChanged(old_host, new_host);
+
// Ensure that the associated embedder gets cleared after a RenderViewHost
// gets swapped, so we don't reuse the same embedder next time a
// RenderViewHost is attached to this WebContents.
@@ -4705,7 +4886,8 @@ void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host,
}
void WebContentsImpl::NotifyFrameSwapped(RenderFrameHost* old_host,
- RenderFrameHost* new_host) {
+ RenderFrameHost* new_host,
+ bool is_main_frame) {
#if defined(OS_ANDROID)
// Copy importance from |old_host| if |new_host| is a main frame.
if (old_host && !new_host->GetParent()) {
@@ -4811,6 +4993,9 @@ void WebContentsImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
#if BUILDFLAG(ENABLE_PLUGINS)
pepper_playback_observer_->RenderFrameDeleted(render_frame_host);
#endif
+
+ // Remove any fullscreen state that the frame has stored.
+ FullscreenStateChanged(render_frame_host, false /* is_fullscreen */);
}
void WebContentsImpl::ShowContextMenu(RenderFrameHost* render_frame_host,
@@ -4974,7 +5159,7 @@ WebContents* WebContentsImpl::GetAsWebContents() {
}
#if !defined(OS_ANDROID)
-double WebContentsImpl::GetPendingPageZoomLevel() {
+double WebContentsImpl::GetPendingPageZoomLevel() const {
NavigationEntry* pending_entry = GetController().GetPendingEntry();
if (!pending_entry)
return HostZoomMap::GetZoomLevel(this);
@@ -5058,7 +5243,7 @@ WebContentsImpl* WebContentsImpl::GetOuterWebContents() {
if (browser_plugin_guest_)
return browser_plugin_guest_->embedder_web_contents();
- return nullptr;
+ return node_.outer_web_contents();
}
WebContentsImpl* WebContentsImpl::GetFocusedWebContents() {
@@ -5146,6 +5331,8 @@ void WebContentsImpl::RenderViewReady(RenderViewHost* rvh) {
for (auto& observer : observers_)
observer.RenderViewReady();
+
+ view_->RenderViewReady();
}
void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh,
@@ -5161,6 +5348,11 @@ void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh,
if (IsFullscreenForCurrentTab())
ExitFullscreenMode(false);
+ // Ensure any video in Picture-in-Picture is exited in the |delegate_| since
+ // a crashed renderer may not have made a clean exit.
+ if (HasPictureInPictureVideo())
+ ExitPictureInPicture();
+
// Cancel any visible dialogs so they are not left dangling over the sad tab.
CancelActiveAndPendingDialogs();
@@ -5229,9 +5421,9 @@ void WebContentsImpl::Close(RenderViewHost* rvh) {
delegate_->CloseContents(this);
}
-void WebContentsImpl::RequestMove(const gfx::Rect& new_bounds) {
- if (delegate_ && delegate_->IsPopupOrPanel(this))
- delegate_->MoveContents(this, new_bounds);
+void WebContentsImpl::RequestSetBounds(const gfx::Rect& new_bounds) {
+ if (delegate_)
+ delegate_->SetContentsBounds(this, new_bounds);
}
void WebContentsImpl::DidStartLoading(FrameTreeNode* frame_tree_node,
@@ -5639,12 +5831,7 @@ bool WebContentsImpl::DidAddMessageToConsole(int32_t level,
void WebContentsImpl::DidReceiveInputEvent(
RenderWidgetHostImpl* render_widget_host,
const blink::WebInputEvent::Type type) {
- // Ideally, this list would be based more off of
- // https://whatwg.org/C/interaction.html#triggered-by-user-activation.
- if (type != blink::WebInputEvent::kMouseDown &&
- type != blink::WebInputEvent::kGestureScrollBegin &&
- type != blink::WebInputEvent::kTouchStart &&
- type != blink::WebInputEvent::kRawKeyDown)
+ if (!IsUserInteractionInputType(type))
return;
// Ignore unless the widget is currently in the frame tree.
@@ -5654,7 +5841,11 @@ void WebContentsImpl::DidReceiveInputEvent(
if (type != blink::WebInputEvent::kGestureScrollBegin)
last_interactive_input_event_time_ = ui::EventTimeForNow();
- OnUserInteraction(type);
+ for (auto& observer : observers_)
+ observer.DidGetUserInteraction(type);
+
+ if (IsResourceLoadUserInteractionInputType(type))
+ SendUserGestureForResourceDispatchHost();
}
void WebContentsImpl::FocusOwningWebContents(
@@ -5681,7 +5872,8 @@ void WebContentsImpl::OnIgnoredUIEvent() {
}
void WebContentsImpl::RendererUnresponsive(
- RenderWidgetHostImpl* render_widget_host) {
+ RenderWidgetHostImpl* render_widget_host,
+ base::RepeatingClosure hang_monitor_restarter) {
for (auto& observer : observers_)
observer.OnRendererUnresponsive(render_widget_host->GetProcess());
@@ -5692,7 +5884,8 @@ void WebContentsImpl::RendererUnresponsive(
return;
if (delegate_)
- delegate_->RendererUnresponsive(this, render_widget_host);
+ delegate_->RendererUnresponsive(this, render_widget_host,
+ std::move(hang_monitor_restarter));
}
void WebContentsImpl::RendererResponsive(
@@ -5753,21 +5946,20 @@ void WebContentsImpl::NotifySwappedFromRenderManager(RenderFrameHost* old_host,
if (delegate_)
view_->SetOverscrollControllerEnabled(CanOverscrollContent());
- view_->RenderViewSwappedIn(new_host->GetRenderViewHost());
-
RenderWidgetHostViewBase* rwhv =
static_cast<RenderWidgetHostViewBase*>(GetRenderWidgetHostView());
if (rwhv)
rwhv->SetMainFrameAXTreeID(GetMainFrame()->GetAXTreeID());
}
- NotifyFrameSwapped(old_host, new_host);
+ NotifyFrameSwapped(old_host, new_host, is_main_frame);
}
void WebContentsImpl::NotifyMainFrameSwappedFromRenderManager(
- RenderViewHost* old_host,
- RenderViewHost* new_host) {
- NotifyViewSwapped(old_host, new_host);
+ RenderFrameHost* old_host,
+ RenderFrameHost* new_host) {
+ NotifyViewSwapped(old_host ? old_host->GetRenderViewHost() : nullptr,
+ new_host->GetRenderViewHost());
}
NavigationControllerImpl& WebContentsImpl::GetControllerForRenderManager() {
@@ -6041,28 +6233,22 @@ void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) {
delegate_->UpdatePreferredSize(this, new_size);
}
-void WebContentsImpl::OnUserInteraction(const blink::WebInputEvent::Type type) {
- for (auto& observer : observers_)
- observer.DidGetUserInteraction(type);
-
- // TODO(https://crbug.com/827659): This used to check if type != kMouseWheel.
- // However, due to the caller already filtering event types, this would never
- // be called with type == kMouseWheel so checking for that here is pointless.
- // However, mouse wheel events *also* generate a kGestureScrollBegin event...
- // which is *not* filtered out. Maybe they should be?
+void WebContentsImpl::SendUserGestureForResourceDispatchHost() {
+ // This is null in unittests. =(
ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
- if (rdh) // null in unittests. =(
+
+ if (rdh)
rdh->OnUserGesture();
}
std::unique_ptr<WebUIImpl> WebContentsImpl::CreateWebUI(const GURL& url) {
std::unique_ptr<WebUIImpl> web_ui = std::make_unique<WebUIImpl>(this);
- WebUIController* controller =
+ std::unique_ptr<WebUIController> controller(
WebUIControllerFactoryRegistry::GetInstance()
- ->CreateWebUIControllerForURL(web_ui.get(), url);
+ ->CreateWebUIControllerForURL(web_ui.get(), url));
if (controller) {
web_ui->AddMessageHandler(std::make_unique<GenericHandler>());
- web_ui->SetController(controller);
+ web_ui->SetController(std::move(controller));
return web_ui;
}
@@ -6337,13 +6523,6 @@ bool WebContentsImpl::AddDomainInfoToRapporSample(rappor::Sample* sample) {
return true;
}
-void WebContentsImpl::UpdateUrlForUkmSource(ukm::UkmRecorder* service,
- ukm::SourceId ukm_source_id) {
- // Here we associate this metric to the main frame URL regardless of what
- // caused it.
- service->UpdateSourceURL(ukm_source_id, GetLastCommittedURL());
-}
-
void WebContentsImpl::FocusedNodeTouched(bool editable) {
#if defined(OS_WIN)
RenderWidgetHostView* view = GetRenderWidgetHostView();
diff --git a/chromium/content/browser/web_contents/web_contents_impl.h b/chromium/content/browser/web_contents/web_contents_impl.h
index cd1c992c773..d16a9912277 100644
--- a/chromium/content/browser/web_contents/web_contents_impl.h
+++ b/chromium/content/browser/web_contents/web_contents_impl.h
@@ -57,6 +57,7 @@
#include "services/device/public/mojom/wake_lock.mojom.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/public/mojom/color_chooser/color_chooser.mojom.h"
+#include "third_party/blink/public/mojom/page/display_cutout.mojom.h"
#include "third_party/blink/public/platform/web_drag_operation.h"
#include "ui/accessibility/ax_modes.h"
#include "ui/base/page_transition_types.h"
@@ -78,6 +79,7 @@ namespace content {
class BrowserPluginEmbedder;
class BrowserPluginGuest;
class DateTimeChooserAndroid;
+class DisplayCutoutHostImpl;
class FindRequestManager;
class InterstitialPageImpl;
class JavaScriptDialogManager;
@@ -85,6 +87,7 @@ class LoaderIOThreadNotifier;
class ManifestManagerHost;
class MediaWebContentsObserver;
class PluginContentOriginWhitelist;
+class RenderFrameHost;
class RenderViewHost;
class RenderViewHostDelegateView;
class RenderWidgetHostImpl;
@@ -234,20 +237,15 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void AddAccessibilityMode(ui::AXMode mode);
#if !defined(OS_ANDROID)
- // Set a temporary zoom level for the frames associated with this WebContents.
- // If |is_temporary| is true, we are setting a new temporary zoom level,
- // otherwise we are clearing a previously set temporary zoom level.
- void SetTemporaryZoomLevel(double level, bool temporary_zoom_enabled);
-
// Sets the zoom level for frames associated with this WebContents.
- void UpdateZoom(double level);
+ void UpdateZoom();
// Sets the zoom level for frames associated with this WebContents if it
// matches |host| and (if non-empty) |scheme|. Matching is done on the
// last committed entry.
void UpdateZoomIfNecessary(const std::string& scheme,
- const std::string& host,
- double level);
+ const std::string& host);
+
#endif // !defined(OS_ANDROID)
// Adds a new binding set to the WebContents. Returns a closure which may be
@@ -356,9 +354,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
int GetCrashedErrorCode() const override;
bool IsBeingDestroyed() const override;
void NotifyNavigationStateChanged(InvalidateTypes changed_flags) override;
- void OnAudioStateChanged(bool is_audible) override;
+ void OnAudioStateChanged() override;
base::TimeTicks GetLastActiveTime() const override;
- void SetLastActiveTime(base::TimeTicks last_active_time) override;
void WasShown() override;
void WasHidden() override;
void WasOccluded() override;
@@ -373,7 +370,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void NotifyPreferencesChanged() override;
void Stop() override;
- void FreezePage() override;
+ void SetPageFrozen(bool frozen) override;
std::unique_ptr<WebContents> Clone() override;
void ReloadFocusedFrame(bool bypass_cache) override;
void Undo() override;
@@ -391,6 +388,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void NotifyContextMenuClosed(
const CustomContextMenuContext& context) override;
void ReloadLoFiImages() override;
+ std::vector<blink::mojom::PauseSubresourceLoadingHandlePtr>
+ PauseSubresourceLoading() override;
void ExecuteCustomContextMenuCommand(
int action,
const CustomContextMenuContext& context) override;
@@ -445,12 +444,10 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
uint32_t max_bitmap_size,
bool bypass_cache,
ImageDownloadCallback callback) override;
- bool IsSubframe() const override;
void Find(int request_id,
const base::string16& search_text,
const blink::WebFindOptions& options) override;
void StopFinding(StopFindAction action) override;
- bool WasRecentlyAudible() override;
bool WasEverAudible() override;
void GetManifest(GetManifestCallback callback) override;
bool IsFullscreenForCurrentTab() const override;
@@ -523,7 +520,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
bool IsNeverVisible() override;
ui::AXMode GetAccessibilityMode() const override;
void AccessibilityEventReceived(
- const std::vector<AXEventNotificationDetails>& details) override;
+ const AXEventNotificationDetails& details) override;
void AccessibilityLocationChangesReceived(
const std::vector<AXLocationChangeNotificationDetails>& details) override;
RenderFrameHost* GetGuestByInstanceID(
@@ -538,6 +535,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void EnterFullscreenMode(const GURL& origin,
const blink::WebFullscreenOptions& options) override;
void ExitFullscreenMode(bool will_cause_resize) override;
+ void FullscreenStateChanged(RenderFrameHost* rfh,
+ bool is_fullscreen) override;
bool ShouldRouteMessageEvent(
RenderFrameHost* target_rfh,
SiteInstance* source_site_instance) const override;
@@ -600,7 +599,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
void UpdateTargetURL(RenderViewHost* render_view_host,
const GURL& url) override;
void Close(RenderViewHost* render_view_host) override;
- void RequestMove(const gfx::Rect& new_bounds) override;
+ void RequestSetBounds(const gfx::Rect& new_bounds) override;
void DocumentAvailableInMainFrame(RenderViewHost* render_view_host) override;
void RouteCloseEvent(RenderViewHost* rvh) override;
bool DidAddMessageToConsole(int32_t level,
@@ -625,9 +624,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
int route_id,
const gfx::Rect& initial_rect) override;
void ShowCreatedFullscreenWidget(int process_id, int route_id) override;
- void RequestMediaAccessPermission(
- const MediaStreamRequest& request,
- const MediaResponseCallback& callback) override;
+ void RequestMediaAccessPermission(const MediaStreamRequest& request,
+ MediaResponseCallback callback) override;
bool CheckMediaAccessPermission(RenderFrameHost* render_frame_host,
const url::Origin& security_origin,
MediaStreamType type) override;
@@ -635,9 +633,6 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
SessionStorageNamespace* GetSessionStorageNamespace(
SiteInstance* instance) override;
SessionStorageNamespaceMap GetSessionStorageNamespaceMap() override;
-#if !defined(OS_ANDROID)
- double GetPendingPageZoomLevel() override;
-#endif // !defined(OS_ANDROID)
FrameTree* GetFrameTree() override;
bool IsOverridingUserAgent() override;
bool IsJavaScriptDialogShowing() const override;
@@ -683,6 +678,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// RenderWidgetHostDelegate --------------------------------------------------
+ ukm::SourceId GetUkmSourceIdForLastCommittedSource() const override;
void RenderWidgetCreated(RenderWidgetHostImpl* render_widget_host) override;
void RenderWidgetDeleted(RenderWidgetHostImpl* render_widget_host) override;
void RenderWidgetGotFocus(RenderWidgetHostImpl* render_widget_host) override;
@@ -694,6 +690,11 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
const gfx::Size& new_size) override;
gfx::Size GetAutoResizeSize() override;
void ResetAutoResizeSize() override;
+
+#if !defined(OS_ANDROID)
+ double GetPendingPageZoomLevel() const override;
+#endif // !defined(OS_ANDROID)
+
KeyboardEventProcessingResult PreHandleKeyboardEvent(
const NativeWebKeyboardEvent& event) override;
void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override;
@@ -711,6 +712,10 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
const base::Optional<base::string16>& value) override;
void MoveRangeSelectionExtent(const gfx::Point& extent) override;
void SelectRange(const gfx::Point& base, const gfx::Point& extent) override;
+#if defined(OS_MACOSX)
+ void DidChangeTextSelection(const base::string16& text,
+ const gfx::Range& range) override;
+#endif
void MoveCaret(const gfx::Point& extent) override;
void AdjustSelectionByCharacterOffset(int start_adjust,
int end_adjust,
@@ -722,7 +727,9 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
RenderWidgetHostImpl* GetRenderWidgetHostWithPageFocus() override;
void FocusOwningWebContents(
RenderWidgetHostImpl* render_widget_host) override;
- void RendererUnresponsive(RenderWidgetHostImpl* render_widget_host) override;
+ void RendererUnresponsive(
+ RenderWidgetHostImpl* render_widget_host,
+ base::RepeatingClosure hang_monitor_restarter) override;
void RendererResponsive(RenderWidgetHostImpl* render_widget_host) override;
void RequestToLockMouse(RenderWidgetHostImpl* render_widget_host,
bool user_gesture,
@@ -746,8 +753,6 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
bool OnUpdateDragCursor() override;
bool IsWidgetForMainFrame(RenderWidgetHostImpl* render_widget_host) override;
bool AddDomainInfoToRapporSample(rappor::Sample* sample) override;
- void UpdateUrlForUkmSource(ukm::UkmRecorder* service,
- ukm::SourceId ukm_source_id) override;
void FocusedNodeTouched(bool editable) override;
void DidReceiveCompositorFrame() override;
bool IsShowingContextMenuOnPage() const override;
@@ -780,8 +785,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
RenderFrameHost* new_host,
bool is_main_frame) override;
void NotifyMainFrameSwappedFromRenderManager(
- RenderViewHost* old_host,
- RenderViewHost* new_host) override;
+ RenderFrameHost* old_host,
+ RenderFrameHost* new_host) override;
NavigationControllerImpl& GetControllerForRenderManager() override;
NavigationEntry* GetLastCommittedNavigationEntryForRenderManager() override;
InterstitialPageImpl* GetInterstitialForRenderManager() override;
@@ -957,11 +962,18 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// enumerations.
const std::string& GetMediaDeviceGroupIDSaltBase() const;
+#if defined(OS_ANDROID)
+ // Called by WebContentsAndroid to send the Display Cutout safe area to
+ // DisplayCutoutHostImpl.
+ void SetDisplayCutoutSafeArea(gfx::Insets insets);
+#endif
+
private:
friend class WebContentsObserver;
friend class WebContents; // To implement factory methods.
friend class RenderFrameHostImplBeforeUnloadBrowserTest;
+ friend class WebContentsImplBrowserTest;
FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, NoJSMessageOnInterstitials);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, UpdateTitle);
@@ -979,6 +991,12 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest,
ResetJavaScriptDialogOnUserNavigate);
FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, ParseDownloadHeaders);
+ FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
+ NotifyFullscreenAcquired);
+ FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
+ NotifyFullscreenAcquired_Navigate);
+ FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
+ NotifyFullscreenAcquired_SameOrigin);
FRIEND_TEST_ALL_PREFIXES(FormStructureBrowserTest, HTMLFiles);
FRIEND_TEST_ALL_PREFIXES(NavigationControllerTest, HistoryNavigate);
FRIEND_TEST_ALL_PREFIXES(RenderFrameHostManagerTest, PageDoesBackAndReload);
@@ -1304,7 +1322,9 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// Helper functions for sending notifications.
void NotifyViewSwapped(RenderViewHost* old_host, RenderViewHost* new_host);
- void NotifyFrameSwapped(RenderFrameHost* old_host, RenderFrameHost* new_host);
+ void NotifyFrameSwapped(RenderFrameHost* old_host,
+ RenderFrameHost* new_host,
+ bool is_main_frame);
void NotifyDisconnected();
void SetEncoding(const std::string& encoding);
@@ -1326,7 +1346,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// |delegate_|.
void OnPreferredSizeChanged(const gfx::Size& old_size);
- void OnUserInteraction(const blink::WebInputEvent::Type type);
+ void SendUserGestureForResourceDispatchHost();
// Internal helper to create WebUI objects associated with |this|. |url| is
// used to determine which WebUI should be created (if any).
@@ -1370,6 +1390,10 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
AXTreeSnapshotCombiner* combiner,
ui::AXMode ax_mode);
+ // Notify observers that the viewport fit value changed. This is called by
+ // |DisplayCutoutHostImpl|.
+ void NotifyViewportFitChanged(blink::mojom::ViewportFit value);
+
// Data for core operation ---------------------------------------------------
// Delegate for notifying our owner about stuff. Not owned by us.
@@ -1492,6 +1516,9 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// Whether the first visually non-empty paint has occurred.
bool did_first_visually_non_empty_paint_;
+ // SourceId for current page.
+ ukm::SourceId last_committed_source_id_ = ukm::kInvalidSourceId;
+
// Data for misc internal state ----------------------------------------------
// When > 0, the WebContents is currently being captured (e.g., for
@@ -1614,10 +1641,6 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// completed making layout changes to effect an exit from fullscreen mode.
bool fullscreen_widget_had_focus_at_shutdown_;
- // Whether this WebContents is responsible for displaying a subframe in a
- // different process from its parent page.
- bool is_subframe_;
-
// When a new tab is created asynchronously, stores the OpenURLParams needed
// to continue loading the page once the tab is ready.
std::unique_ptr<OpenURLParams> delayed_open_url_params_;
@@ -1724,6 +1747,7 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
bool has_persistent_video_ = false;
+ bool is_currently_audible_ = false;
bool was_ever_audible_ = false;
// Helper variable for resolving races in UpdateTargetURL / ClearTargetURL.
@@ -1732,6 +1756,18 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
// Whether we should override user agent in new tabs.
bool should_override_user_agent_in_new_tabs_ = false;
+ // Gets notified about changes in viewport fit events.
+ std::unique_ptr<DisplayCutoutHostImpl> display_cutout_host_impl_;
+
+ // Stores a set of FrameTreeNode ids that are fullscreen.
+ using FullscreenFrameNodes = std::set<int>;
+ FullscreenFrameNodes fullscreen_frame_tree_nodes_;
+
+ // Stores the ID of the current fullscreen |FrameTreeNode| or
+ // |kNoFrameTreeNodeId| if the tab is not currently fullscreen.
+ int current_fullscreen_frame_tree_node_id_ =
+ RenderFrameHost::kNoFrameTreeNodeId;
+
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 7c85b1f8fe1..4286d9a5c62 100644
--- a/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -6,6 +6,7 @@
#include <utility>
#include <vector>
+#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
@@ -33,9 +34,11 @@
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/resource_dispatcher_host.h"
+#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
@@ -120,6 +123,13 @@ class WebContentsImplBrowserTest : public ContentBrowserTest {
host_resolver()->AddRule("*", "127.0.0.1");
}
+ bool CurrentFullscreenFrameTreeNodeIsEmpty() {
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ return web_contents->current_fullscreen_frame_tree_node_id_ ==
+ RenderFrameHost::kNoFrameTreeNodeId;
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(WebContentsImplBrowserTest);
};
@@ -1735,7 +1745,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
RenderProcessHost* process = web_contents->GetMainFrame()->GetProcess();
int renderer_id = process->GetID();
ASSERT_TRUE(process);
- EXPECT_TRUE(process->HasConnection());
+ EXPECT_TRUE(process->IsInitializedAndNotDead());
// Navigate the WebContents.
GURL url(embedded_test_server()->GetURL("c.com", "/title3.html"));
@@ -1788,7 +1798,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
RenderProcessHost* process = web_contents->GetMainFrame()->GetProcess();
int renderer_id = process->GetID();
ASSERT_TRUE(process);
- EXPECT_FALSE(process->HasConnection());
+ EXPECT_FALSE(process->IsInitializedAndNotDead());
EXPECT_EQ(base::kNullProcessHandle, process->GetProcess().Handle());
// Navigate the WebContents.
@@ -1802,7 +1812,7 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
EXPECT_TRUE(same_tab_observer.last_navigation_succeeded());
// The process should be launched now.
- EXPECT_TRUE(process->HasConnection());
+ EXPECT_TRUE(process->IsInitializedAndNotDead());
EXPECT_NE(base::kNullProcessHandle, process->GetProcess().Handle());
// Check that the RenderProcessHost and its ID didn't change.
@@ -2481,4 +2491,259 @@ IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, PausePageScheduledTasks) {
EXPECT_GT(next_text_length, text_length);
}
+IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
+ PopupWindowBrowserNavResumeLoad) {
+ // This test verifies a pop up that requires navigation from browser side
+ // works with a delegate that delays navigations of pop ups.
+ // Create a file: scheme pop up from a file: scheme page, which requires
+ // requires an OpenURL IPC to the browser process.
+ base::FilePath test_data_dir;
+ CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir));
+ base::FilePath simple_links_path =
+ test_data_dir.Append(GetTestDataFilePath())
+ .Append(FILE_PATH_LITERAL("simple_links.html"));
+ GURL url(base::FilePath::StringType(FILE_PATH_LITERAL("file://")) +
+ simple_links_path.value());
+
+ shell()->set_delay_popup_contents_delegate_for_testing(true);
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+
+ Shell* new_shell = nullptr;
+ WebContents* new_contents = nullptr;
+ {
+ ShellAddedObserver new_shell_observer;
+ bool success = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ shell(),
+ "window.domAutomationController.send(clickDeadFileNewWindowLink());",
+ &success));
+ new_shell = new_shell_observer.GetShell();
+ new_contents = new_shell->web_contents();
+ // Delaying popup holds the initial load.
+ EXPECT_FALSE(WaitForLoadStop(new_contents));
+ }
+
+ EXPECT_FALSE(new_contents->GetDelegate());
+ new_contents->SetDelegate(new_shell);
+ new_contents->ResumeLoadingCreatedWebContents();
+ // Dead file link may or may not load depending on OS. The result is not
+ // relevant for this test, so not checking the the result.
+ WaitForLoadStop(new_contents);
+ EXPECT_TRUE(new_contents->GetLastCommittedURL().SchemeIs("file"));
+}
+
+namespace {
+
+class FullscreenWebContentsObserver : public WebContentsObserver {
+ public:
+ FullscreenWebContentsObserver(WebContents* web_contents,
+ RenderFrameHost* wanted_rfh)
+ : WebContentsObserver(web_contents), wanted_rfh_(wanted_rfh) {}
+
+ // WebContentsObserver override.
+ void DidAcquireFullscreen(RenderFrameHost* rfh) override {
+ EXPECT_EQ(wanted_rfh_, rfh);
+ EXPECT_FALSE(found_value_);
+
+ if (rfh == wanted_rfh_) {
+ found_value_ = true;
+ run_loop_.Quit();
+ }
+ }
+
+ void Wait() {
+ if (!found_value_)
+ run_loop_.Run();
+ }
+
+ private:
+ base::RunLoop run_loop_;
+ bool found_value_ = false;
+ RenderFrameHost* wanted_rfh_;
+
+ DISALLOW_COPY_AND_ASSIGN(FullscreenWebContentsObserver);
+};
+
+} // namespace
+
+IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, NotifyFullscreenAcquired) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ TestWCDelegateForDialogsAndFullscreen test_delegate;
+ web_contents->SetDelegate(&test_delegate);
+
+ GURL url = embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b{allowfullscreen})");
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+ RenderFrameHost* main_frame = web_contents->GetMainFrame();
+ int main_frame_id = main_frame->GetFrameTreeNodeId();
+
+ RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
+ int child_frame_id = child_frame->GetFrameTreeNodeId();
+
+ WebContentsImpl::FullscreenFrameNodes nodes;
+ EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
+ EXPECT_TRUE(CurrentFullscreenFrameTreeNodeIsEmpty());
+
+ // Make the top page fullscreen.
+ {
+ FullscreenWebContentsObserver observer(web_contents, main_frame);
+ EXPECT_TRUE(
+ ExecuteScript(main_frame, "document.body.webkitRequestFullscreen();"));
+ observer.Wait();
+ }
+
+ nodes.insert(main_frame_id);
+ EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
+ EXPECT_EQ(main_frame_id,
+ web_contents->current_fullscreen_frame_tree_node_id_);
+
+ // Make the child frame fullscreen.
+ {
+ FullscreenWebContentsObserver observer(web_contents, child_frame);
+ EXPECT_TRUE(
+ ExecuteScript(child_frame, "document.body.webkitRequestFullscreen();"));
+ observer.Wait();
+ }
+
+ nodes.insert(child_frame_id);
+ EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
+ EXPECT_EQ(child_frame_id,
+ web_contents->current_fullscreen_frame_tree_node_id_);
+
+ // Exit fullscreen on the child frame.
+ // This will not work with --site-per-process until crbug.com/617369
+ // is fixed.
+ if (!SiteIsolationPolicy::UseDedicatedProcessesForAllSites()) {
+ {
+ FullscreenWebContentsObserver observer(web_contents, main_frame);
+ EXPECT_TRUE(
+ ExecuteScript(child_frame, "document.webkitExitFullscreen();"));
+ observer.Wait();
+ }
+
+ nodes.erase(child_frame_id);
+ EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
+ EXPECT_EQ(main_frame_id,
+ web_contents->current_fullscreen_frame_tree_node_id_);
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
+ NotifyFullscreenAcquired_Navigate) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ TestWCDelegateForDialogsAndFullscreen test_delegate;
+ test_delegate.WillWaitForFullscreenExit();
+ web_contents->SetDelegate(&test_delegate);
+
+ GURL url = embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(b{allowfullscreen})");
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+ RenderFrameHost* main_frame = web_contents->GetMainFrame();
+ int main_frame_id = main_frame->GetFrameTreeNodeId();
+
+ RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
+ int child_frame_id = child_frame->GetFrameTreeNodeId();
+
+ WebContentsImpl::FullscreenFrameNodes nodes;
+ EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
+ EXPECT_TRUE(CurrentFullscreenFrameTreeNodeIsEmpty());
+
+ // Make the top page fullscreen.
+ {
+ FullscreenWebContentsObserver observer(web_contents, main_frame);
+ EXPECT_TRUE(
+ ExecuteScript(main_frame, "document.body.webkitRequestFullscreen();"));
+ observer.Wait();
+ }
+
+ nodes.insert(main_frame_id);
+ EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
+ EXPECT_EQ(main_frame_id,
+ web_contents->current_fullscreen_frame_tree_node_id_);
+
+ // Make the child frame fullscreen.
+ {
+ FullscreenWebContentsObserver observer(web_contents, child_frame);
+ EXPECT_TRUE(
+ ExecuteScript(child_frame, "document.body.webkitRequestFullscreen();"));
+ observer.Wait();
+ }
+
+ nodes.insert(child_frame_id);
+ EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
+ EXPECT_EQ(child_frame_id,
+ web_contents->current_fullscreen_frame_tree_node_id_);
+
+ // Perform a cross origin navigation on the main frame.
+ EXPECT_TRUE(
+ NavigateToURL(shell(), embedded_test_server()->GetURL(
+ "c.com", "/cross_site_iframe_factory.html")));
+ EXPECT_EQ(0u, web_contents->fullscreen_frame_tree_nodes_.size());
+ EXPECT_TRUE(CurrentFullscreenFrameTreeNodeIsEmpty());
+}
+
+IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
+ NotifyFullscreenAcquired_SameOrigin) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ TestWCDelegateForDialogsAndFullscreen test_delegate;
+ web_contents->SetDelegate(&test_delegate);
+
+ GURL url = embedded_test_server()->GetURL(
+ "a.com", "/cross_site_iframe_factory.html?a(a{allowfullscreen})");
+ EXPECT_TRUE(NavigateToURL(shell(), url));
+ RenderFrameHost* main_frame = web_contents->GetMainFrame();
+ int main_frame_id = main_frame->GetFrameTreeNodeId();
+
+ RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0);
+ int child_frame_id = child_frame->GetFrameTreeNodeId();
+
+ WebContentsImpl::FullscreenFrameNodes nodes;
+ EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
+ EXPECT_TRUE(CurrentFullscreenFrameTreeNodeIsEmpty());
+
+ // Make the top page fullscreen.
+ {
+ FullscreenWebContentsObserver observer(web_contents, main_frame);
+ EXPECT_TRUE(
+ ExecuteScript(main_frame, "document.body.webkitRequestFullscreen();"));
+ observer.Wait();
+ }
+
+ nodes.insert(main_frame_id);
+ EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
+ EXPECT_EQ(main_frame_id,
+ web_contents->current_fullscreen_frame_tree_node_id_);
+
+ // Make the child frame fullscreen.
+ {
+ FullscreenWebContentsObserver observer(web_contents, child_frame);
+ EXPECT_TRUE(
+ ExecuteScript(child_frame, "document.body.webkitRequestFullscreen();"));
+ observer.Wait();
+ }
+
+ nodes.insert(child_frame_id);
+ EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
+ EXPECT_EQ(child_frame_id,
+ web_contents->current_fullscreen_frame_tree_node_id_);
+
+ // Exit fullscreen on the child frame.
+ {
+ FullscreenWebContentsObserver observer(web_contents, main_frame);
+ EXPECT_TRUE(ExecuteScript(child_frame, "document.webkitExitFullscreen();"));
+ observer.Wait();
+ }
+
+ nodes.erase(child_frame_id);
+ EXPECT_EQ(nodes, web_contents->fullscreen_frame_tree_nodes_);
+ EXPECT_EQ(main_frame_id,
+ web_contents->current_fullscreen_frame_tree_node_id_);
+}
+
} // namespace content
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 9b07e24d464..c403c397331 100644
--- a/chromium/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/chromium/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -34,6 +34,7 @@
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
+#include "content/public/browser/overlay_window.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/ssl_host_state_delegate.h"
#include "content/public/browser/storage_partition.h"
@@ -441,6 +442,10 @@ TEST_F(WebContentsImplTest, DirectNavigationToViewSourceWebUI) {
load_params.is_renderer_initiated = false;
controller().LoadURLWithParams(load_params);
+ NavigationRequest* request =
+ main_test_rfh()->frame_tree_node()->navigation_request();
+ CHECK(request);
+
int entry_id = cont.GetPendingEntry()->GetUniqueID();
// Did we get the expected message?
EXPECT_TRUE(process()->sink().GetFirstMessageMatching(
@@ -454,6 +459,9 @@ TEST_F(WebContentsImplTest, DirectNavigationToViewSourceWebUI) {
FrameHostMsg_DidStartProvisionalLoad(1, kRewrittenURL,
std::vector<GURL>(),
base::TimeTicks::Now()));
+ main_test_rfh()->SimulateCommitProcessed(
+ request->navigation_handle()->GetNavigationId(),
+ true /* was_successful */);
main_test_rfh()->SendNavigateWithParams(&params,
false /* was_within_same_document */);
@@ -472,24 +480,21 @@ TEST_F(WebContentsImplTest, SimpleNavigation) {
SiteInstance* instance1 = contents()->GetSiteInstance();
EXPECT_EQ(nullptr, contents()->GetPendingMainFrame());
- // Navigate to URL
+ // Navigate until ready to commit.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
+ auto navigation =
+ NavigationSimulator::CreateBrowserInitiated(url, contents());
+ navigation->ReadyToCommit();
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(instance1, orig_rfh->GetSiteInstance());
// Controller's pending entry will have a null site instance until we assign
- // it in DidNavigate.
+ // it in Commit.
EXPECT_EQ(
nullptr,
NavigationEntryImpl::FromNavigationEntry(controller().GetVisibleEntry())->
site_instance());
- // DidNavigate from the page
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ navigation->Commit();
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(orig_rfh, main_test_rfh());
EXPECT_EQ(instance1, orig_rfh->GetSiteInstance());
@@ -549,10 +554,10 @@ TEST_F(WebContentsImplTest, CrossSiteBoundaries) {
// Navigate to new site
const GURL url2("http://www.yahoo.com");
- controller().LoadURL(
- url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
+ auto new_site_navigation =
+ NavigationSimulator::CreateBrowserInitiated(url2, contents());
+ new_site_navigation->ReadyToCommit();
int entry_id = controller().GetPendingEntry()->GetUniqueID();
- orig_rfh->PrepareForCommit();
EXPECT_TRUE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(url, contents()->GetLastCommittedURL());
EXPECT_EQ(url2, contents()->GetVisibleURL());
@@ -587,9 +592,10 @@ TEST_F(WebContentsImplTest, CrossSiteBoundaries) {
// Going back should switch SiteInstances again. The first SiteInstance is
// stored in the NavigationEntry, so it should be the same as at the start.
// We should use the same RFH as before, swapping it back in.
- controller().GoBack();
+ auto back_navigation =
+ NavigationSimulator::CreateHistoryNavigation(-1, contents());
+ back_navigation->ReadyToCommit();
entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
TestRenderFrameHost* goback_rfh = contents()->GetPendingMainFrame();
EXPECT_TRUE(contents()->CrossProcessNavigationPending());
@@ -623,13 +629,7 @@ TEST_F(WebContentsImplTest, CrossSiteBoundariesAfterCrash) {
// Navigate to URL. First URL should use first RenderViewHost.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
-
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(orig_rfh->GetRenderViewHost(), contents()->GetRenderViewHost());
@@ -638,21 +638,19 @@ TEST_F(WebContentsImplTest, CrossSiteBoundariesAfterCrash) {
orig_rfh->GetProcess()->SimulateCrash();
EXPECT_FALSE(orig_rfh->IsRenderFrameLive());
- // Navigate to new site. We should not go into PENDING.
+ // Start navigating to a new site. We should not go into PENDING.
const GURL url2("http://www.yahoo.com");
- controller().LoadURL(
- url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
+ auto navigation_to_url2 =
+ NavigationSimulator::CreateBrowserInitiated(url2, contents());
+ navigation_to_url2->ReadyToCommit();
+
TestRenderFrameHost* new_rfh = main_test_rfh();
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(nullptr, contents()->GetPendingMainFrame());
EXPECT_NE(orig_rfh, new_rfh);
EXPECT_EQ(orig_rvh_delete_count, 1);
- // DidNavigate from the new page
- contents()->TestDidNavigate(new_rfh, entry_id, true, url2,
- ui::PAGE_TRANSITION_TYPED);
+ navigation_to_url2->Commit();
SiteInstance* instance2 = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
@@ -669,37 +667,24 @@ TEST_F(WebContentsImplTest, CrossSiteBoundariesAfterCrash) {
// both contentses to a new site will place both contentses in a single
// SiteInstance.
TEST_F(WebContentsImplTest, NavigateTwoTabsCrossSite) {
- TestRenderFrameHost* orig_rfh = main_test_rfh();
SiteInstance* instance1 = contents()->GetSiteInstance();
// Navigate to URL. First URL should use first RenderViewHost.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
// Open a new contents with the same SiteInstance, navigated to the same site.
std::unique_ptr<TestWebContents> contents2(
TestWebContents::Create(browser_context(), instance1));
- contents2->GetController().LoadURL(url, Referrer(),
- ui::PAGE_TRANSITION_TYPED,
- std::string());
- entry_id = contents2->GetController().GetPendingEntry()->GetUniqueID();
- contents2->GetMainFrame()->PrepareForCommit();
- // Need this page id to be 2 since the site instance is the same (which is the
- // scope of page IDs) and we want to consider this a new page.
- contents2->TestDidNavigate(contents2->GetMainFrame(), entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents2.get(), url);
+ EXPECT_EQ(instance1, contents2->GetSiteInstance());
// Navigate first contents to a new site.
const GURL url2a("http://www.yahoo.com");
controller().LoadURL(url2a, Referrer(), ui::PAGE_TRANSITION_LINK,
std::string());
- entry_id = controller().GetPendingEntry()->GetUniqueID();
- orig_rfh->PrepareForCommit();
+ int entry_id = controller().GetPendingEntry()->GetUniqueID();
+ contents()->GetMainFrame()->PrepareForCommit();
TestRenderFrameHost* pending_rfh_a = contents()->GetPendingMainFrame();
if (AreAllSitesIsolatedForTesting())
EXPECT_TRUE(contents()->CrossProcessNavigationPending());
@@ -748,12 +733,7 @@ TEST_F(WebContentsImplTest, NavigateFromSitelessUrl) {
browser_client.set_assign_site_for_url(false);
// Navigate to an URL that will not assign a new SiteInstance.
const GURL native_url("non-site-url://stuffandthings");
- controller().LoadURL(
- native_url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, native_url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), native_url);
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(orig_rfh, main_test_rfh());
@@ -766,16 +746,14 @@ TEST_F(WebContentsImplTest, NavigateFromSitelessUrl) {
browser_client.set_assign_site_for_url(true);
// Navigate to new site (should keep same site instance).
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
+ auto navigation =
+ NavigationSimulator::CreateBrowserInitiated(url, contents());
+ navigation->ReadyToCommit();
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(native_url, contents()->GetLastCommittedURL());
EXPECT_EQ(url, contents()->GetVisibleURL());
EXPECT_FALSE(contents()->GetPendingMainFrame());
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ navigation->Commit();
// Keep the number of active frames in orig_rfh's SiteInstance
// non-zero so that orig_rfh doesn't get deleted when it gets
@@ -791,7 +769,7 @@ TEST_F(WebContentsImplTest, NavigateFromSitelessUrl) {
const GURL url2("http://www.yahoo.com");
controller().LoadURL(
url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- entry_id = controller().GetPendingEntry()->GetUniqueID();
+ int entry_id = controller().GetPendingEntry()->GetUniqueID();
orig_rfh->PrepareForCommit();
EXPECT_TRUE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(url, contents()->GetLastCommittedURL());
@@ -861,12 +839,7 @@ TEST_F(WebContentsImplTest, NavigateFromRestoredSitelessUrl) {
// Navigate to a regular site and verify that the SiteInstance was kept.
browser_client.set_assign_site_for_url(true);
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- entry = controller().GetPendingEntry();
- orig_rfh->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry->GetUniqueID(), true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
EXPECT_EQ(orig_instance, contents()->GetSiteInstance());
// Cleanup.
@@ -907,13 +880,7 @@ TEST_F(WebContentsImplTest, NavigateFromRestoredRegularUrl) {
// Navigate to another site and verify that a new SiteInstance was created.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- entry = controller().GetPendingEntry();
- orig_rfh->PrepareForCommit();
- contents()->TestDidNavigate(contents()->GetPendingMainFrame(),
- entry->GetUniqueID(), true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
EXPECT_NE(orig_instance, contents()->GetSiteInstance());
// Cleanup.
@@ -923,22 +890,16 @@ TEST_F(WebContentsImplTest, NavigateFromRestoredRegularUrl) {
// Test that we can find an opener RVH even if it's pending.
// http://crbug.com/176252.
TEST_F(WebContentsImplTest, FindOpenerRVHWhenPending) {
- TestRenderFrameHost* orig_rfh = main_test_rfh();
// Navigate to a URL.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- orig_rfh->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
// Start to navigate first tab to a new site, so that it has a pending RVH.
const GURL url2("http://www.yahoo.com");
- controller().LoadURL(
- url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- orig_rfh->PrepareForCommit();
+ auto navigation =
+ NavigationSimulator::CreateBrowserInitiated(url2, contents());
+ navigation->ReadyToCommit();
TestRenderFrameHost* pending_rfh = contents()->GetPendingMainFrame();
SiteInstance* instance = pending_rfh->GetSiteInstance();
@@ -961,9 +922,7 @@ TEST_F(WebContentsImplTest, FindOpenerRVHWhenPending) {
EXPECT_EQ(proxy->GetRoutingID(), opener_frame_routing_id);
// Ensure that committing the navigation removes the proxy.
- entry_id = controller().GetPendingEntry()->GetUniqueID();
- contents()->TestDidNavigate(pending_rfh, entry_id, true, url2,
- ui::PAGE_TRANSITION_TYPED);
+ navigation->Commit();
EXPECT_FALSE(
contents()->GetRenderManager()->GetRenderFrameProxyHost(instance));
}
@@ -981,29 +940,20 @@ TEST_F(WebContentsImplTest, CrossSiteComparesAgainstCurrentPage) {
// Navigate to URL.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
// Open a related contents to a second site.
std::unique_ptr<TestWebContents> contents2(
TestWebContents::Create(browser_context(), instance1));
const GURL url2("http://www.yahoo.com");
- contents2->GetController().LoadURL(url2, Referrer(),
- ui::PAGE_TRANSITION_TYPED,
- std::string());
- entry_id = contents2->GetController().GetPendingEntry()->GetUniqueID();
- contents2->GetMainFrame()->PrepareForCommit();
+ auto navigation =
+ NavigationSimulator::CreateBrowserInitiated(url2, contents2.get());
+ navigation->ReadyToCommit();
// The first RVH in contents2 isn't live yet, so we shortcut the cross site
// pending.
- TestRenderFrameHost* rfh2 = contents2->GetMainFrame();
EXPECT_FALSE(contents2->CrossProcessNavigationPending());
- contents2->TestDidNavigate(rfh2, entry_id, true, url2,
- ui::PAGE_TRANSITION_TYPED);
+ navigation->Commit();
SiteInstance* instance2 = contents2->GetSiteInstance();
EXPECT_NE(instance1, instance2);
EXPECT_FALSE(contents2->CrossProcessNavigationPending());
@@ -1018,13 +968,7 @@ TEST_F(WebContentsImplTest, CrossSiteComparesAgainstCurrentPage) {
// Navigate to the new site. Doesn't switch SiteInstancees, because we
// compare against the current URL, not the SiteInstance's site.
const GURL url3("http://mail.yahoo.com");
- controller().LoadURL(
- url3, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- entry_id = controller().GetPendingEntry()->GetUniqueID();
- EXPECT_FALSE(contents()->CrossProcessNavigationPending());
- main_test_rfh()->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url3,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url3);
SiteInstance* instance4 = contents()->GetSiteInstance();
EXPECT_EQ(instance1, instance4);
}
@@ -1037,12 +981,7 @@ TEST_F(WebContentsImplTest, CrossSiteUnloadHandlers) {
// Navigate to URL. First URL should use first RenderViewHost.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(orig_rfh, main_test_rfh());
@@ -1061,7 +1000,7 @@ TEST_F(WebContentsImplTest, CrossSiteUnloadHandlers) {
// Navigate again, but simulate an onbeforeunload approval.
controller().LoadURL(
url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- entry_id = controller().GetPendingEntry()->GetUniqueID();
+ int entry_id = controller().GetPendingEntry()->GetUniqueID();
EXPECT_TRUE(orig_rfh->is_waiting_for_beforeunload_ack());
now = base::TimeTicks::Now();
orig_rfh->PrepareForCommit();
@@ -1090,12 +1029,7 @@ TEST_F(WebContentsImplTest, CrossSiteNavigationPreempted) {
// Navigate to URL. First URL should use first RenderFrameHost.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(orig_rfh, main_test_rfh());
@@ -1213,18 +1147,12 @@ TEST_F(WebContentsImplTest, CrossSiteNavigationBackOldNavigationIgnored) {
// Start with a web ui page, which gets a new RVH with WebUI bindings.
GURL url1(std::string(kChromeUIScheme) + "://" +
std::string(kChromeUIGpuHost));
- controller().LoadURL(url1, Referrer(), ui::PAGE_TRANSITION_TYPED,
- std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
TestRenderFrameHost* webui_rfh = main_test_rfh();
- webui_rfh->PrepareForCommit();
- contents()->TestDidNavigate(webui_rfh, entry_id, true, url1,
- ui::PAGE_TRANSITION_TYPED);
NavigationEntry* entry1 = controller().GetLastCommittedEntry();
SiteInstance* instance1 = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
- EXPECT_EQ(webui_rfh, main_test_rfh());
EXPECT_EQ(url1, entry1->GetURL());
EXPECT_EQ(instance1,
NavigationEntryImpl::FromNavigationEntry(entry1)->site_instance());
@@ -1232,24 +1160,12 @@ TEST_F(WebContentsImplTest, CrossSiteNavigationBackOldNavigationIgnored) {
// Navigate to new site.
const GURL url2("http://www.google.com");
- controller().LoadURL(url2, Referrer(), ui::PAGE_TRANSITION_TYPED,
- std::string());
- entry_id = controller().GetPendingEntry()->GetUniqueID();
- EXPECT_TRUE(contents()->CrossProcessNavigationPending());
- TestRenderFrameHost* google_rfh = contents()->GetPendingMainFrame();
-
- // Simulate beforeunload approval.
- EXPECT_TRUE(webui_rfh->is_waiting_for_beforeunload_ack());
- webui_rfh->PrepareForCommit();
-
- // DidNavigate from the pending page.
- contents()->TestDidNavigate(google_rfh, entry_id, true, url2,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url2);
+ TestRenderFrameHost* google_rfh = main_test_rfh();
NavigationEntry* entry2 = controller().GetLastCommittedEntry();
SiteInstance* instance2 = contents()->GetSiteInstance();
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
- EXPECT_EQ(google_rfh, main_test_rfh());
EXPECT_NE(instance1, instance2);
EXPECT_FALSE(contents()->GetPendingMainFrame());
EXPECT_EQ(url2, entry2->GetURL());
@@ -1259,13 +1175,7 @@ TEST_F(WebContentsImplTest, CrossSiteNavigationBackOldNavigationIgnored) {
// Navigate to third page on same site.
const GURL url3("http://news.google.com");
- controller().LoadURL(url3, Referrer(), ui::PAGE_TRANSITION_TYPED,
- std::string());
- entry_id = controller().GetPendingEntry()->GetUniqueID();
- EXPECT_FALSE(contents()->CrossProcessNavigationPending());
- main_test_rfh()->PrepareForCommit();
- contents()->TestDidNavigate(google_rfh, entry_id, true, url3,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url3);
NavigationEntry* entry3 = controller().GetLastCommittedEntry();
SiteInstance* instance3 = contents()->GetSiteInstance();
@@ -1309,12 +1219,7 @@ TEST_F(WebContentsImplTest, CrossSiteNavigationNotPreemptedByFrame) {
// Navigate to URL. First URL should use the original RenderFrameHost.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
EXPECT_FALSE(contents()->CrossProcessNavigationPending());
EXPECT_EQ(orig_rfh, main_test_rfh());
@@ -1342,7 +1247,7 @@ namespace {
void SetAsNonUserGesture(FrameHostMsg_DidCommitProvisionalLoad_Params* params) {
params->gesture = NavigationGestureAuto;
}
-}
+} // namespace
// Test that a cross-site navigation is not preempted if the previous
// renderer sends a FrameNavigate message just before being told to stop.
@@ -1391,45 +1296,35 @@ TEST_F(WebContentsImplTest, CrossSiteNotPreemptedDuringBeforeUnload) {
// Test that NavigationEntries have the correct page state after going
// forward and back. Prevents regression for bug 1116137.
TEST_F(WebContentsImplTest, NavigationEntryContentState) {
- TestRenderFrameHost* orig_rfh = main_test_rfh();
// Navigate to URL. There should be no committed entry yet.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
+ auto navigation =
+ NavigationSimulator::CreateBrowserInitiated(url, contents());
+ navigation->ReadyToCommit();
NavigationEntry* entry = controller().GetLastCommittedEntry();
EXPECT_EQ(nullptr, entry);
- // Committed entry should have page state after DidNavigate.
- orig_rfh->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ // Committed entry should have page state.
+ navigation->Commit();
entry = controller().GetLastCommittedEntry();
EXPECT_TRUE(entry->GetPageState().IsValid());
// Navigate to same site.
const GURL url2("http://images.google.com");
- controller().LoadURL(
- url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- entry_id = controller().GetPendingEntry()->GetUniqueID();
+ auto navigation2 =
+ NavigationSimulator::CreateBrowserInitiated(url2, contents());
+ navigation2->ReadyToCommit();
entry = controller().GetLastCommittedEntry();
EXPECT_TRUE(entry->GetPageState().IsValid());
- // Committed entry should have page state after DidNavigate.
- orig_rfh->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url2,
- ui::PAGE_TRANSITION_TYPED);
+ // Committed entry should have page state.
+ navigation2->Commit();
entry = controller().GetLastCommittedEntry();
EXPECT_TRUE(entry->GetPageState().IsValid());
// Now go back. Committed entry should still have page state.
- controller().GoBack();
- entry_id = controller().GetPendingEntry()->GetUniqueID();
- orig_rfh->PrepareForCommit();
- contents()->TestDidNavigate(
- orig_rfh, entry_id, false, url,
- controller().GetPendingEntry()->GetTransitionType());
+ NavigationSimulator::GoBack(contents());
entry = controller().GetLastCommittedEntry();
EXPECT_TRUE(entry->GetPageState().IsValid());
}
@@ -1442,9 +1337,7 @@ TEST_F(WebContentsImplTest, NavigationEntryContentStateNewWindow) {
// Navigate to about:blank.
const GURL url(url::kAboutBlankURL);
- orig_rfh->SendRendererInitiatedNavigationRequest(url, false);
- contents()->TestDidNavigate(orig_rfh, 0, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
// Should have a page state here.
NavigationEntry* entry = controller().GetLastCommittedEntry();
@@ -1458,14 +1351,9 @@ TEST_F(WebContentsImplTest, NavigationEntryContentStateNewWindow) {
// Navigating to a normal page should not cause a process swap.
const GURL new_url("http://www.google.com");
- controller().LoadURL(new_url, Referrer(),
- ui::PAGE_TRANSITION_TYPED, std::string());
- entry = controller().GetPendingEntry();
- EXPECT_FALSE(contents()->CrossProcessNavigationPending());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), new_url);
+
EXPECT_EQ(orig_rfh, main_test_rfh());
- orig_rfh->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry->GetUniqueID(), true, new_url,
- ui::PAGE_TRANSITION_TYPED);
NavigationEntryImpl* entry_impl2 = NavigationEntryImpl::FromNavigationEntry(
controller().GetLastCommittedEntry());
EXPECT_EQ(site_instance_id, entry_impl2->site_instance()->GetId());
@@ -1481,12 +1369,7 @@ TEST_F(WebContentsImplTest, NavigationExitsFullscreen) {
// Navigate to a site.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
EXPECT_EQ(orig_rfh, main_test_rfh());
// Toggle fullscreen mode on (as if initiated via IPC from renderer).
@@ -1499,13 +1382,7 @@ TEST_F(WebContentsImplTest, NavigationExitsFullscreen) {
// Navigate to a new site.
const GURL url2("http://www.yahoo.com");
- controller().LoadURL(
- url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
- TestRenderFrameHost* const pending_rfh = contents()->GetPendingMainFrame();
- contents()->TestDidNavigate(pending_rfh, entry_id, true, url2,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url2);
// Confirm fullscreen has exited.
EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
@@ -1523,23 +1400,12 @@ TEST_F(WebContentsImplTest, HistoryNavigationExitsFullscreen) {
// Navigate to a site.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- orig_rfh->PrepareForCommit();
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
EXPECT_EQ(orig_rfh, main_test_rfh());
// Now, navigate to another page on the same site.
const GURL url2("http://www.google.com/search?q=kittens");
- controller().LoadURL(
- url2, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- entry_id = controller().GetPendingEntry()->GetUniqueID();
- orig_rfh->PrepareForCommit();
- EXPECT_FALSE(contents()->CrossProcessNavigationPending());
- contents()->TestDidNavigate(orig_rfh, entry_id, true, url2,
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url2);
EXPECT_EQ(orig_rfh, main_test_rfh());
// Sanity-check: Confirm we're not starting out in fullscreen mode.
@@ -1555,16 +1421,9 @@ TEST_F(WebContentsImplTest, HistoryNavigationExitsFullscreen) {
// Navigate backward (or forward).
if (i == 0)
- controller().GoBack();
+ NavigationSimulator::GoBack(contents());
else
- controller().GoForward();
- entry_id = controller().GetPendingEntry()->GetUniqueID();
- orig_rfh->PrepareForCommit();
- EXPECT_FALSE(contents()->CrossProcessNavigationPending());
- EXPECT_EQ(orig_rfh, main_test_rfh());
- contents()->TestDidNavigate(orig_rfh, entry_id, false, url,
- ui::PAGE_TRANSITION_FORWARD_BACK);
- orig_rfh->SimulateNavigationStop();
+ NavigationSimulator::GoForward(contents());
// Confirm fullscreen has exited.
EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
@@ -1582,12 +1441,7 @@ TEST_F(WebContentsImplTest, CrashExitsFullscreen) {
// Navigate to a site.
const GURL url("http://www.google.com");
- controller().LoadURL(
- url, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
- contents()->TestDidNavigate(main_test_rfh(), entry_id, true,
- url, ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url);
// Toggle fullscreen mode on (as if initiated via IPC from renderer).
EXPECT_FALSE(contents()->IsFullscreenForCurrentTab());
@@ -1618,7 +1472,7 @@ TEST_F(WebContentsImplTest,
ShowInterstitialFromBrowserWithNewNavigationDontProceed) {
// Navigate to a page.
GURL url1("http://www.google.com");
- NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
EXPECT_EQ(1, controller().GetEntryCount());
// Initiate a browser navigation that will trigger the interstitial.
@@ -1764,7 +1618,7 @@ TEST_F(WebContentsImplTest,
ShowInterstitialFromBrowserNewNavigationProceed) {
// Navigate to a page.
GURL url1("http://www.google.com");
- NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
EXPECT_EQ(1, controller().GetEntryCount());
// Initiate a browser navigation that will trigger the interstitial
@@ -1945,7 +1799,7 @@ TEST_F(WebContentsImplTest, ShowInterstitialThenNavigate) {
// While interstitial showing, navigate to a new URL.
const GURL url2("http://www.yahoo.com");
- NavigationSimulator::NavigateAndCommitFromDocument(url2, main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url2);
EXPECT_EQ(TestInterstitialPage::CANCELED, state);
@@ -1957,7 +1811,7 @@ TEST_F(WebContentsImplTest, ShowInterstitialThenNavigate) {
TEST_F(WebContentsImplTest, ShowInterstitialThenGoBack) {
// Navigate to a page so we have a navigation entry in the controller.
GURL url1("http://www.google.com");
- NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
EXPECT_EQ(1, controller().GetEntryCount());
// Show interstitial.
@@ -1997,7 +1851,7 @@ TEST_F(WebContentsImplTest, ShowInterstitialThenGoBack) {
TEST_F(WebContentsImplTest, ShowInterstitialCrashRendererThenGoBack) {
// Navigate to a page so we have a navigation entry in the controller.
GURL url1("http://www.google.com");
- NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
EXPECT_EQ(1, controller().GetEntryCount());
NavigationEntry* entry = controller().GetLastCommittedEntry();
@@ -2039,7 +1893,7 @@ TEST_F(WebContentsImplTest, ShowInterstitialCrashRendererThenGoBack) {
TEST_F(WebContentsImplTest, ShowInterstitialCrashRendererThenNavigate) {
// Navigate to a page so we have a navigation entry in the controller.
GURL url1("http://www.google.com");
- NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
EXPECT_EQ(1, controller().GetEntryCount());
// Show interstitial.
@@ -2119,7 +1973,7 @@ TEST_F(WebContentsImplTest, ShowInterstitialThenCloseAndShutdown) {
TEST_F(WebContentsImplTest, CreateInterstitialForClosingTab) {
// Navigate to a page.
GURL url1("http://www.google.com");
- NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
EXPECT_EQ(1, controller().GetEntryCount());
// Initiate a browser navigation that will trigger an interstitial.
@@ -2169,7 +2023,7 @@ TEST_F(WebContentsImplTest, CreateInterstitialForClosingTab) {
TEST_F(WebContentsImplTest, TabNavigationDoesntRaceInterstitial) {
// Navigate to a page.
GURL url1("http://www.google.com");
- NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
EXPECT_EQ(1, controller().GetEntryCount());
// Initiate a browser navigation that will trigger an interstitial.
@@ -2214,7 +2068,7 @@ TEST_F(WebContentsImplTest, TabNavigationDoesntRaceInterstitial) {
TEST_F(WebContentsImplTest, ShowInterstitialProceedMultipleCommands) {
// Navigate to a page so we have a navigation entry in the controller.
GURL url1("http://www.google.com");
- NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
EXPECT_EQ(1, controller().GetEntryCount());
// Show an interstitial.
@@ -2250,8 +2104,7 @@ TEST_F(WebContentsImplTest, ShowInterstitialProceedMultipleCommands) {
TEST_F(WebContentsImplTest, ShowInterstitialOnInterstitial) {
// Navigate to a page so we have a navigation entry in the controller.
GURL start_url("http://www.google.com");
- NavigationSimulator::NavigateAndCommitFromDocument(start_url,
- main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), start_url);
EXPECT_EQ(1, controller().GetEntryCount());
// Show an interstitial.
@@ -2306,8 +2159,7 @@ TEST_F(WebContentsImplTest, ShowInterstitialOnInterstitial) {
TEST_F(WebContentsImplTest, ShowInterstitialProceedShowInterstitial) {
// Navigate to a page so we have a navigation entry in the controller.
GURL start_url("http://www.google.com");
- NavigationSimulator::NavigateAndCommitFromDocument(start_url,
- main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), start_url);
EXPECT_EQ(1, controller().GetEntryCount());
// Show an interstitial.
@@ -2528,13 +2380,7 @@ TEST_F(WebContentsImplTest, NoJSMessageOnInterstitials) {
const GURL kGURL(kUrl);
// Start a navigation to a page
- contents()->GetController().LoadURL(
- kGURL, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
- int entry_id = controller().GetPendingEntry()->GetUniqueID();
- main_test_rfh()->PrepareForCommit();
- // DidNavigate from the page
- contents()->TestDidNavigate(main_test_rfh(), entry_id, true,
- kGURL, ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kGURL);
// Simulate showing an interstitial while the page is showing.
TestInterstitialPage::InterstitialState state =
@@ -2561,7 +2407,7 @@ TEST_F(WebContentsImplTest, NoJSMessageOnInterstitials) {
TEST_F(WebContentsImplTest, CopyStateFromAndPruneSourceInterstitial) {
// Navigate to a page.
GURL url1("http://www.google.com");
- NavigationSimulator::NavigateAndCommitFromDocument(url1, main_test_rfh());
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), url1);
EXPECT_EQ(1, controller().GetEntryCount());
// Initiate a browser navigation that will trigger the interstitial
@@ -3555,7 +3401,56 @@ class PictureInPictureDelegate : public WebContentsDelegate {
DISALLOW_COPY_AND_ASSIGN(PictureInPictureDelegate);
};
+class TestOverlayWindow : public OverlayWindow {
+ public:
+ TestOverlayWindow() = default;
+ ~TestOverlayWindow() override{};
+
+ static std::unique_ptr<OverlayWindow> Create(
+ PictureInPictureWindowController* controller) {
+ return std::unique_ptr<OverlayWindow>(new TestOverlayWindow());
+ }
+
+ bool IsActive() const override { return false; }
+ void Close() override {}
+ void Show() override {}
+ void Hide() override {}
+ bool IsVisible() const override { return false; }
+ bool IsAlwaysOnTop() const override { return false; }
+ ui::Layer* GetLayer() override { return nullptr; }
+ gfx::Rect GetBounds() const override { return gfx::Rect(); }
+ void UpdateVideoSize(const gfx::Size& natural_size) override {}
+ void SetPlaybackState(PlaybackState playback_state) override {}
+ ui::Layer* GetWindowBackgroundLayer() override { return nullptr; }
+ ui::Layer* GetVideoLayer() override { return nullptr; }
+ gfx::Rect GetVideoBounds() override { return gfx::Rect(); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestOverlayWindow);
+};
+
+class PictureInPictureTestBrowserClient : public TestContentBrowserClient {
+ public:
+ PictureInPictureTestBrowserClient()
+ : original_browser_client_(SetBrowserClientForTesting(this)) {}
+
+ ~PictureInPictureTestBrowserClient() override {
+ SetBrowserClientForTesting(original_browser_client_);
+ }
+
+ std::unique_ptr<OverlayWindow> CreateWindowForPictureInPicture(
+ PictureInPictureWindowController* controller) override {
+ return TestOverlayWindow::Create(controller);
+ }
+
+ private:
+ ContentBrowserClient* original_browser_client_;
+};
+
TEST_F(WebContentsImplTest, EnterPictureInPicture) {
+ PictureInPictureTestBrowserClient browser_client;
+ SetBrowserClientForTesting(&browser_client);
+
const int kPlayerVideoOnlyId = 30; /* arbitrary and used for tests */
PictureInPictureDelegate delegate;
@@ -3583,7 +3478,7 @@ TEST_F(WebContentsImplTest, EnterPictureInPicture) {
gfx::Size(42, 42) /* natural_size */, 1 /* request_id */));
EXPECT_TRUE(observer->GetPictureInPictureVideoMediaPlayerId().has_value());
EXPECT_EQ(kPlayerVideoOnlyId,
- observer->GetPictureInPictureVideoMediaPlayerId()->second);
+ observer->GetPictureInPictureVideoMediaPlayerId()->delegate_id);
// Picture-in-Picture media player id should not be reset when the media is
// destroyed (e.g. video stops playing). This allows the Picture-in-Picture
@@ -3672,19 +3567,20 @@ class TestJavaScriptDialogManager : public JavaScriptDialogManager {
} // namespace
TEST_F(WebContentsImplTest, ResetJavaScriptDialogOnUserNavigate) {
+ const GURL kUrl("http://www.google.com");
+ const GURL kUrl2("http://www.google.com/sub");
TestJavaScriptDialogManager dialog_manager;
contents()->SetJavaScriptDialogManagerForTesting(&dialog_manager);
// A user-initiated navigation.
- contents()->TestDidNavigate(main_test_rfh(), 0, true,
- GURL("about:whatever"),
- ui::PAGE_TRANSITION_TYPED);
+ NavigationSimulator::NavigateAndCommitFromBrowser(contents(), kUrl);
EXPECT_EQ(1u, dialog_manager.reset_count());
// An automatic navigation.
- main_test_rfh()->SendNavigateWithModificationCallback(
- 0, true, GURL(url::kAboutBlankURL), base::Bind(SetAsNonUserGesture));
-
+ auto navigation =
+ NavigationSimulator::CreateRendererInitiated(kUrl2, main_test_rfh());
+ navigation->SetHasUserGesture(false);
+ navigation->Commit();
EXPECT_EQ(1u, dialog_manager.reset_count());
contents()->SetJavaScriptDialogManagerForTesting(nullptr);
diff --git a/chromium/content/browser/web_contents/web_contents_view.h b/chromium/content/browser/web_contents/web_contents_view.h
index cf8c74f4c74..41e44d5d658 100644
--- a/chromium/content/browser/web_contents/web_contents_view.h
+++ b/chromium/content/browser/web_contents/web_contents_view.h
@@ -110,9 +110,13 @@ class WebContentsView {
// fully created.
virtual void RenderViewCreated(RenderViewHost* host) = 0;
- // Invoked when the WebContents is notified that the RenderView has been
- // swapped in.
- virtual void RenderViewSwappedIn(RenderViewHost* host) = 0;
+ // Invoked when the WebContents is notified that the RenderView is ready.
+ virtual void RenderViewReady() = 0;
+
+ // Invoked when the WebContents is notified that the RenderViewHost has been
+ // changed.
+ virtual void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) = 0;
// Invoked to enable/disable overscroll gesture navigation.
virtual void SetOverscrollControllerEnabled(bool enabled) = 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 28c90658587..8990bc7bf6c 100644
--- a/chromium/content/browser/web_contents/web_contents_view_android.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_android.cc
@@ -57,22 +57,6 @@ bool ShouldRequestUnbufferedDispatch() {
!content::GetContentClient()->UsingSynchronousCompositing();
return should_request_unbuffered_dispatch;
}
-
-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
@@ -131,19 +115,22 @@ void WebContentsViewAndroid::SetSelectPopup(
void WebContentsViewAndroid::SetOverscrollRefreshHandler(
std::unique_ptr<ui::OverscrollRefreshHandler> overscroll_refresh_handler) {
overscroll_refresh_handler_ = std::move(overscroll_refresh_handler);
- RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
- if (rwhv)
- rwhv->OnOverscrollRefreshHandlerAvailable();
+ auto* rwhv = web_contents_->GetRenderWidgetHostView();
+ if (rwhv) {
+ static_cast<RenderWidgetHostViewAndroid*>(rwhv)
+ ->OnOverscrollRefreshHandlerAvailable();
+ }
if (web_contents_->ShowingInterstitialPage()) {
- rwhv = static_cast<RenderWidgetHostViewAndroid*>(
- web_contents_->GetInterstitialPage()
- ->GetMainFrame()
- ->GetRenderViewHost()
- ->GetWidget()
- ->GetView());
- if (rwhv)
- rwhv->OnOverscrollRefreshHandlerAvailable();
+ rwhv = web_contents_->GetInterstitialPage()
+ ->GetMainFrame()
+ ->GetRenderViewHost()
+ ->GetWidget()
+ ->GetView();
+ if (rwhv) {
+ static_cast<RenderWidgetHostViewAndroid*>(rwhv)
+ ->OnOverscrollRefreshHandlerAvailable();
+ }
}
}
@@ -167,8 +154,16 @@ gfx::NativeView WebContentsViewAndroid::GetContentNativeView() const {
RenderWidgetHostViewAndroid*
WebContentsViewAndroid::GetRenderWidgetHostViewAndroid() {
- return static_cast<RenderWidgetHostViewAndroid*>(
- web_contents_->GetRenderWidgetHostView());
+ RenderWidgetHostView* rwhv = nullptr;
+ rwhv = web_contents_->GetRenderWidgetHostView();
+ if (web_contents_->ShowingInterstitialPage()) {
+ rwhv = web_contents_->GetInterstitialPage()
+ ->GetMainFrame()
+ ->GetRenderViewHost()
+ ->GetWidget()
+ ->GetView();
+ }
+ return static_cast<RenderWidgetHostViewAndroid*>(rwhv);
}
gfx::NativeWindow WebContentsViewAndroid::GetTopLevelNativeWindow() const {
@@ -191,11 +186,12 @@ void WebContentsViewAndroid::SizeContents(const gfx::Size& size) {
}
void WebContentsViewAndroid::Focus() {
- RenderWidgetHostViewAndroid* rwhv = GetRenderWidgetHostViewAndroid();
if (web_contents_->ShowingInterstitialPage()) {
web_contents_->GetInterstitialPage()->Focus();
- } else if (rwhv) {
- rwhv->Focus();
+ } else {
+ auto* rwhv = web_contents_->GetRenderWidgetHostView();
+ if (rwhv)
+ static_cast<RenderWidgetHostViewAndroid*>(rwhv)->Focus();
}
}
@@ -273,7 +269,42 @@ RenderWidgetHostViewBase* WebContentsViewAndroid::CreateViewForPopupWidget(
void WebContentsViewAndroid::RenderViewCreated(RenderViewHost* host) {
}
-void WebContentsViewAndroid::RenderViewSwappedIn(RenderViewHost* host) {
+void WebContentsViewAndroid::RenderViewReady() {
+ if (device_orientation_ == 0)
+ return;
+ auto* rwhva = GetRenderWidgetHostViewAndroid();
+ if (rwhva)
+ rwhva->UpdateScreenInfo(GetNativeView());
+
+ web_contents_->OnScreenOrientationChange();
+}
+
+void WebContentsViewAndroid::RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) {
+ if (old_host) {
+ auto* rwhv = old_host->GetWidget()->GetView();
+ if (rwhv && rwhv->GetNativeView()) {
+ static_cast<RenderWidgetHostViewAndroid*>(rwhv)->UpdateNativeViewTree(
+ nullptr);
+ }
+ }
+
+ auto* rwhv = new_host->GetWidget()->GetView();
+ if (rwhv && rwhv->GetNativeView()) {
+ static_cast<RenderWidgetHostViewAndroid*>(rwhv)->UpdateNativeViewTree(
+ GetNativeView());
+ SetFocus(view_.HasFocus());
+ }
+}
+
+void WebContentsViewAndroid::SetFocus(bool focused) {
+ auto* rwhva = GetRenderWidgetHostViewAndroid();
+ if (!rwhva)
+ return;
+ if (focused)
+ rwhva->GotFocus();
+ else
+ rwhva->LostFocus();
}
void WebContentsViewAndroid::SetOverscrollControllerEnabled(bool enabled) {
@@ -281,10 +312,11 @@ void WebContentsViewAndroid::SetOverscrollControllerEnabled(bool enabled) {
void WebContentsViewAndroid::ShowContextMenu(
RenderFrameHost* render_frame_host, const ContextMenuParams& params) {
- RenderWidgetHostViewAndroid* view = GetRenderWidgetHostViewAndroid();
+ auto* rwhv = static_cast<RenderWidgetHostViewAndroid*>(
+ web_contents_->GetRenderWidgetHostView());
// See if context menu is handled by SelectionController as a selection menu.
// If not, use the delegate to show it.
- if (view && view->ShowSelectionMenu(params))
+ if (rwhv && rwhv->ShowSelectionMenu(params))
return;
if (delegate_)
@@ -550,10 +582,11 @@ bool WebContentsViewAndroid::ScrollTo(float x, float y) {
}
void WebContentsViewAndroid::OnSizeChanged() {
- auto* rwhv = ::content::GetRenderWidgetHostViewAndroid(web_contents_);
+ auto* rwhv = GetRenderWidgetHostViewAndroid();
if (rwhv) {
web_contents_->SendScreenRects();
- rwhv->SynchronizeVisualProperties();
+ rwhv->SynchronizeVisualProperties(cc::DeadlinePolicy::UseDefaultDeadline(),
+ base::nullopt);
}
}
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 3b6ab05eeac..088fedea3fa 100644
--- a/chromium/content/browser/web_contents/web_contents_view_android.h
+++ b/chromium/content/browser/web_contents/web_contents_view_android.h
@@ -80,7 +80,9 @@ class WebContentsViewAndroid : public WebContentsView,
RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override;
void RenderViewCreated(RenderViewHost* host) override;
- void RenderViewSwappedIn(RenderViewHost* host) override;
+ void RenderViewReady() override;
+ void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) override;
void SetOverscrollControllerEnabled(bool enabled) override;
// Backend implementation of RenderViewHostDelegateView.
@@ -122,10 +124,10 @@ class WebContentsViewAndroid : public WebContentsView,
void OnSizeChanged() override;
void OnPhysicalBackingSizeChanged() override;
+ void SetFocus(bool focused);
void set_device_orientation(int orientation) {
device_orientation_ = orientation;
}
- int device_orientation() { return device_orientation_; }
private:
void OnDragEntered(const std::vector<DropData::Metadata>& metadata,
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 984fa41d064..713b17948ef 100644
--- a/chromium/content/browser/web_contents/web_contents_view_aura.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_aura.cc
@@ -465,9 +465,9 @@ void WebContentsViewAura::InstallCreateHookForTests(
WebContentsViewAura::WebContentsViewAura(WebContentsImpl* web_contents,
WebContentsViewDelegate* delegate)
- : is_mus_browser_plugin_guest_(
- web_contents->GetBrowserPluginGuest() != nullptr &&
- base::FeatureList::IsEnabled(features::kMash)),
+ : is_mus_browser_plugin_guest_(web_contents->GetBrowserPluginGuest() !=
+ nullptr &&
+ !features::IsAshInBrowserProcess()),
web_contents_(web_contents),
delegate_(delegate),
current_drag_op_(blink::kWebDragOperationNone),
@@ -843,8 +843,10 @@ void WebContentsViewAura::SetPageTitle(const base::string16& title) {
void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) {
}
-void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) {
-}
+void WebContentsViewAura::RenderViewReady() {}
+
+void WebContentsViewAura::RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) {}
void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) {
RenderWidgetHostViewAura* view =
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 82807c7f77f..058f3e00d6f 100644
--- a/chromium/content/browser/web_contents/web_contents_view_aura.h
+++ b/chromium/content/browser/web_contents/web_contents_view_aura.h
@@ -119,7 +119,9 @@ class CONTENT_EXPORT WebContentsViewAura
RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override;
void RenderViewCreated(RenderViewHost* host) override;
- void RenderViewSwappedIn(RenderViewHost* host) override;
+ void RenderViewReady() override;
+ void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) override;
void SetOverscrollControllerEnabled(bool enabled) override;
// Overridden from RenderViewHostDelegateView:
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 dbc35b6c764..60ec51cdf3a 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
@@ -448,7 +448,8 @@ IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
// Disabled because the test always fails the first time it runs on the Win Aura
// bots, and usually but not always passes second-try (See crbug.com/179532).
-#if defined(OS_WIN)
+// Flaky on CrOS as well: https://crbug.com/856079
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
#define MAYBE_QuickOverscrollDirectionChange \
DISABLED_QuickOverscrollDirectionChange
#else
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 e95c31d677f..688540cea25 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
@@ -99,7 +99,11 @@ void WebContentsViewChildFrame::SetPageTitle(const base::string16& title) {
void WebContentsViewChildFrame::RenderViewCreated(RenderViewHost* host) {}
-void WebContentsViewChildFrame::RenderViewSwappedIn(RenderViewHost* host) {}
+void WebContentsViewChildFrame::RenderViewReady() {}
+
+void WebContentsViewChildFrame::RenderViewHostChanged(
+ RenderViewHost* old_host,
+ RenderViewHost* new_host) {}
void WebContentsViewChildFrame::SetOverscrollControllerEnabled(bool enabled) {
// This is managed by the outer view.
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 17275be9302..e5485f5609c 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
@@ -45,7 +45,9 @@ class WebContentsViewChildFrame : public WebContentsView,
RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override;
void RenderViewCreated(RenderViewHost* host) override;
- void RenderViewSwappedIn(RenderViewHost* host) override;
+ void RenderViewReady() override;
+ void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) override;
void SetOverscrollControllerEnabled(bool enabled) override;
#if defined(OS_MACOSX)
void SetAllowOtherViews(bool allow) override;
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 699570cc139..44c68ed25b6 100644
--- a/chromium/content/browser/web_contents/web_contents_view_guest.cc
+++ b/chromium/content/browser/web_contents/web_contents_view_guest.cc
@@ -72,14 +72,14 @@ void WebContentsViewGuest::OnGuestAttached(WebContentsView* parent_view) {
// view hierarchy. We add this view as embedder's child here.
// This would go in WebContentsViewGuest::CreateView, but that is too early to
// access embedder_web_contents(). Therefore, we do it here.
- if (!base::FeatureList::IsEnabled(features::kMash))
+ if (features::IsAshInBrowserProcess())
parent_view->GetNativeView()->AddChild(platform_view_->GetNativeView());
#endif // defined(USE_AURA)
}
void WebContentsViewGuest::OnGuestDetached(WebContentsView* old_parent_view) {
#if defined(USE_AURA)
- if (!base::FeatureList::IsEnabled(features::kMash)) {
+ if (features::IsAshInBrowserProcess()) {
old_parent_view->GetNativeView()->RemoveChild(
platform_view_->GetNativeView());
}
@@ -163,8 +163,13 @@ void WebContentsViewGuest::RenderViewCreated(RenderViewHost* host) {
platform_view_->RenderViewCreated(host);
}
-void WebContentsViewGuest::RenderViewSwappedIn(RenderViewHost* host) {
- platform_view_->RenderViewSwappedIn(host);
+void WebContentsViewGuest::RenderViewReady() {
+ platform_view_->RenderViewReady();
+}
+
+void WebContentsViewGuest::RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) {
+ platform_view_->RenderViewHostChanged(old_host, new_host);
}
void WebContentsViewGuest::SetOverscrollControllerEnabled(bool enabled) {
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 4a06fe5f688..9e3511a9dab 100644
--- a/chromium/content/browser/web_contents/web_contents_view_guest.h
+++ b/chromium/content/browser/web_contents/web_contents_view_guest.h
@@ -63,7 +63,9 @@ class WebContentsViewGuest : public WebContentsView,
RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override;
void RenderViewCreated(RenderViewHost* host) override;
- void RenderViewSwappedIn(RenderViewHost* host) override;
+ void RenderViewReady() override;
+ void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) override;
void SetOverscrollControllerEnabled(bool enabled) override;
#if defined(OS_MACOSX)
void SetAllowOtherViews(bool allow) override;
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 4640550b848..7f80c1b1d82 100644
--- a/chromium/content/browser/web_contents/web_contents_view_mac.h
+++ b/chromium/content/browser/web_contents/web_contents_view_mac.h
@@ -7,6 +7,7 @@
#import <Cocoa/Cocoa.h>
+#include <list>
#include <memory>
#include <string>
#include <vector>
@@ -18,7 +19,8 @@
#include "content/browser/web_contents/web_contents_view.h"
#include "content/common/content_export.h"
#include "content/common/drag_event_source_info.h"
-#include "ui/base/cocoa/base_view.h"
+#import "ui/base/cocoa/accessibility_hostable.h"
+#import "ui/base/cocoa/base_view.h"
#include "ui/gfx/geometry/size.h"
@class WebDragDest;
@@ -40,7 +42,7 @@ class Layer;
}
CONTENT_EXPORT
-@interface WebContentsViewCocoa : BaseView {
+@interface WebContentsViewCocoa : BaseView<AccessibilityHostable> {
@private
// Instances of this class are owned by both webContentsView_ and AppKit. It
// is possible for an instance to outlive its webContentsView_. The
@@ -48,6 +50,7 @@ CONTENT_EXPORT
content::WebContentsViewMac* webContentsView_;
base::scoped_nsobject<WebDragSource> dragSource_;
base::scoped_nsobject<WebDragDest> dragDest_;
+ base::scoped_nsobject<id> accessibilityParent_;
BOOL mouseDownCanMoveWindow_;
}
@@ -57,6 +60,7 @@ CONTENT_EXPORT
// NSDraggingSource. It is supposedly deprecated, but the non-deprecated API
// -[NSWindow dragImage:...] still relies on it.
- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal;
+
@end
namespace content {
@@ -98,7 +102,9 @@ class WebContentsViewMac : public WebContentsView,
RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override;
void RenderViewCreated(RenderViewHost* host) override;
- void RenderViewSwappedIn(RenderViewHost* host) override;
+ void RenderViewReady() override;
+ void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) override;
void SetOverscrollControllerEnabled(bool enabled) override;
bool IsEventTracking() const override;
void CloseTabAfterEventTracking() override;
@@ -162,6 +168,13 @@ class WebContentsViewMac : public WebContentsView,
// Whether to allow other views.
bool allow_other_views_;
+ // This contains all RenderWidgetHostViewMacs that have been added as child
+ // NSViews to this NSView. Note that this list may contain RWHVMacs besides
+ // just |web_contents_->GetRenderWidgetHostView()|. The only time that the
+ // RWHVMac's NSView is removed from the WCVMac's NSView is when it is
+ // destroyed.
+ std::list<base::WeakPtr<RenderWidgetHostViewBase>> child_views_;
+
ui::Layer* parent_ui_layer_ = nullptr;
std::unique_ptr<PopupMenuHelper> popup_menu_helper_;
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 00b2d2a729d..94848b56836 100644
--- a/chromium/content/browser/web_contents/web_contents_view_mac.mm
+++ b/chromium/content/browser/web_contents/web_contents_view_mac.mm
@@ -198,9 +198,6 @@ void WebContentsViewMac::Focus() {
gfx::NativeView native_view = GetNativeViewForFocus();
NSWindow* window = [native_view window];
[window makeFirstResponder:native_view];
- if (![window isVisible])
- return;
- [window makeKeyAndOrderFront:nil];
}
void WebContentsViewMac::SetInitialFocus() {
@@ -373,8 +370,10 @@ RenderWidgetHostViewBase* WebContentsViewMac::CreateViewForWidget(
view->SetDelegate(rw_delegate.get());
}
view->SetAllowPauseForResizeOrRepaint(!allow_other_views_);
- if (parent_ui_layer_)
- view->SetParentUiLayer(parent_ui_layer_);
+
+ // Add the RenderWidgetHostView to the ui::Layer heirarchy.
+ child_views_.push_back(view->GetWeakPtr());
+ SetParentUiLayer(parent_ui_layer_);
// Fancy layout comes later; for now just make it our size and resize it
// with us. In case there are other siblings of the content area, we want
@@ -423,8 +422,10 @@ void WebContentsViewMac::RenderViewCreated(RenderViewHost* host) {
host->EnablePreferredSizeMode();
}
-void WebContentsViewMac::RenderViewSwappedIn(RenderViewHost* host) {
-}
+void WebContentsViewMac::RenderViewReady() {}
+
+void WebContentsViewMac::RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) {}
void WebContentsViewMac::SetOverscrollControllerEnabled(bool enabled) {
}
@@ -450,10 +451,13 @@ void WebContentsViewMac::CloseTab() {
void WebContentsViewMac::SetParentUiLayer(ui::Layer* parent_ui_layer) {
parent_ui_layer_ = parent_ui_layer;
- RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
- web_contents_->GetRenderWidgetHostView());
- if (view)
- view->SetParentUiLayer(parent_ui_layer);
+ // Remove any child NSViews that have been destroyed.
+ for (auto iter = child_views_.begin(); iter != child_views_.end();) {
+ if (*iter)
+ (*iter++)->SetParentUiLayer(parent_ui_layer);
+ else
+ iter = child_views_.erase(iter);
+ }
}
} // namespace content
@@ -739,4 +743,18 @@ void WebContentsViewMac::SetParentUiLayer(ui::Layer* parent_ui_layer) {
[self updateWebContentsVisibility];
}
+// AccessibilityHostable protocol implementation.
+- (void)setAccessibilityParentElement:(id)accessibilityParent {
+ accessibilityParent_.reset([accessibilityParent retain]);
+}
+
+// NSAccessibility informal protocol implementation.
+- (id)accessibilityAttributeValue:(NSString*)attribute {
+ if (accessibilityParent_ &&
+ [attribute isEqualToString:NSAccessibilityParentAttribute]) {
+ return accessibilityParent_;
+ }
+ return [super accessibilityAttributeValue:attribute];
+}
+
@end
diff --git a/chromium/content/browser/web_contents/web_contents_view_mac_unittest.mm b/chromium/content/browser/web_contents/web_contents_view_mac_unittest.mm
index d18ac92c06e..8ce3dad6c86 100644
--- a/chromium/content/browser/web_contents/web_contents_view_mac_unittest.mm
+++ b/chromium/content/browser/web_contents/web_contents_view_mac_unittest.mm
@@ -9,6 +9,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_renderer_host.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
#include "ui/base/test/cocoa_helper.h"
#import "ui/base/test/cocoa_helper.h"
@@ -23,6 +24,7 @@ class WebContentsViewCocoaTest : public ui::CocoaTest {
} // namespace
TEST_F(WebContentsViewCocoaTest, NonWebDragSourceTest) {
+ // The designated initializer is private but init should be fine in this case.
base::scoped_nsobject<WebContentsViewCocoa> view(
[[WebContentsViewCocoa alloc] init]);
@@ -36,6 +38,28 @@ TEST_F(WebContentsViewCocoaTest, NonWebDragSourceTest) {
[view draggingSourceOperationMaskForLocal:NO]);
}
+TEST_F(WebContentsViewCocoaTest, AccessibilityParentTest) {
+ // The designated initializer is private but init should be fine in this case.
+ base::scoped_nsobject<WebContentsViewCocoa> view(
+ [[WebContentsViewCocoa alloc] init]);
+
+ // NSBox so it participates in the a11y hierarchy.
+ base::scoped_nsobject<NSView> parent_view([[NSBox alloc] init]);
+ base::scoped_nsobject<NSView> accessibility_parent([[NSView alloc] init]);
+
+ [parent_view addSubview:view];
+ EXPECT_NSEQ([view accessibilityAttributeValue:NSAccessibilityParentAttribute],
+ parent_view);
+
+ [view setAccessibilityParentElement:accessibility_parent];
+ EXPECT_NSEQ([view accessibilityAttributeValue:NSAccessibilityParentAttribute],
+ accessibility_parent);
+
+ [view setAccessibilityParentElement:nil];
+ EXPECT_NSEQ([view accessibilityAttributeValue:NSAccessibilityParentAttribute],
+ parent_view);
+}
+
namespace {
class WebContentsViewMacTest : public RenderViewHostTestHarness {
diff --git a/chromium/content/browser/web_package/signed_exchange_cert_fetcher.cc b/chromium/content/browser/web_package/signed_exchange_cert_fetcher.cc
index 083d6c6fa95..90dd7610d3e 100644
--- a/chromium/content/browser/web_package/signed_exchange_cert_fetcher.cc
+++ b/chromium/content/browser/web_package/signed_exchange_cert_fetcher.cc
@@ -72,14 +72,15 @@ SignedExchangeCertFetcher::CreateAndStart(
bool force_fetch,
SignedExchangeVersion version,
CertificateCallback callback,
- SignedExchangeDevToolsProxy* devtools_proxy) {
+ SignedExchangeDevToolsProxy* devtools_proxy,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
"SignedExchangeCertFetcher::CreateAndStart");
std::unique_ptr<SignedExchangeCertFetcher> cert_fetcher(
new SignedExchangeCertFetcher(
std::move(shared_url_loader_factory), std::move(throttles), cert_url,
std::move(request_initiator), force_fetch, version,
- std::move(callback), devtools_proxy));
+ std::move(callback), devtools_proxy, throttling_profile_id));
cert_fetcher->Start();
return cert_fetcher;
}
@@ -92,7 +93,8 @@ SignedExchangeCertFetcher::SignedExchangeCertFetcher(
bool force_fetch,
SignedExchangeVersion version,
CertificateCallback callback,
- SignedExchangeDevToolsProxy* devtools_proxy)
+ SignedExchangeDevToolsProxy* devtools_proxy,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id)
: shared_url_loader_factory_(std::move(shared_url_loader_factory)),
throttles_(std::move(throttles)),
resource_request_(std::make_unique<network::ResourceRequest>()),
@@ -117,6 +119,7 @@ SignedExchangeCertFetcher::SignedExchangeCertFetcher(
cert_request_id_ = base::UnguessableToken::Create();
resource_request_->enable_load_timing = true;
}
+ resource_request_->throttling_profile_id = throttling_profile_id;
}
SignedExchangeCertFetcher::~SignedExchangeCertFetcher() = default;
@@ -148,8 +151,8 @@ void SignedExchangeCertFetcher::Abort() {
}
void SignedExchangeCertFetcher::OnHandleReady(MojoResult result) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeCertFetcher::OnHandleReady");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeCertFetcher::OnHandleReady");
const void* buffer = nullptr;
uint32_t num_bytes = 0;
MojoResult rv =
@@ -157,8 +160,8 @@ void SignedExchangeCertFetcher::OnHandleReady(MojoResult result) {
if (rv == MOJO_RESULT_OK) {
if (body_string_.size() + num_bytes > g_max_cert_size_for_signed_exchange) {
body_->EndReadData(num_bytes);
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_, "SignedExchangeCertFetcher::OnHandleReady",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_,
"The response body size of certificate message exceeds the limit.");
Abort();
return;
@@ -170,13 +173,11 @@ void SignedExchangeCertFetcher::OnHandleReady(MojoResult result) {
} else {
DCHECK_EQ(MOJO_RESULT_SHOULD_WAIT, rv);
}
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeCertFetcher::OnHandleReady");
}
void SignedExchangeCertFetcher::OnDataComplete() {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeCertFetcher::OnDataComplete");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeCertFetcher::OnDataComplete");
DCHECK(callback_);
url_loader_ = nullptr;
body_.reset();
@@ -188,41 +189,53 @@ void SignedExchangeCertFetcher::OnDataComplete() {
devtools_proxy_);
body_string_.clear();
if (!cert_chain) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_, "SignedExchangeCertFetcher::OnDataComplete",
- "Failed to get certificate chain from message.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_, "Failed to get certificate chain from message.");
std::move(callback_).Run(nullptr);
return;
}
std::move(callback_).Run(std::move(cert_chain));
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeCertFetcher::OnDataComplete");
}
// network::mojom::URLLoaderClient
void SignedExchangeCertFetcher::OnReceiveResponse(
- const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file) {
+ const network::ResourceResponseHead& head) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeCertFetcher::OnReceiveResponse");
if (devtools_proxy_) {
DCHECK(cert_request_id_);
devtools_proxy_->CertificateResponseReceived(*cert_request_id_,
resource_request_->url, head);
}
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeCertFetcher::OnReceiveResponse");
- if (head.headers->response_code() != net::HTTP_OK) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_, "SignedExchangeCertFetcher::OnReceiveResponse",
- base::StringPrintf("Invalid reponse code: %d",
- head.headers->response_code()));
+
+ // |headers| is null when loading data URL.
+ if (head.headers && head.headers->response_code() != net::HTTP_OK) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_, base::StringPrintf("Invalid reponse code: %d",
+ head.headers->response_code()));
Abort();
return;
}
+
+ // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#cert-chain-format
+ // "The resource at a signature's cert-url MUST have the
+ // application/cert-chain+cbor content type" [spec text]
+ if (head.mime_type != "application/cert-chain+cbor") {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_,
+ base::StringPrintf(
+ "Content type of cert-url must be application/cert-chain+cbor. "
+ "Actual content type: %s",
+ head.mime_type.c_str()));
+ Abort();
+ return;
+ }
+
if (head.content_length > 0) {
if (base::checked_cast<size_t>(head.content_length) >
g_max_cert_size_for_signed_exchange) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_, "SignedExchangeCertFetcher::OnReceiveResponse",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_,
base::StringPrintf("Invalid content length: %" PRIu64,
head.content_length));
Abort();
@@ -230,8 +243,6 @@ void SignedExchangeCertFetcher::OnReceiveResponse(
}
body_string_.reserve(head.content_length);
}
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeCertFetcher::OnReceiveResponse");
}
void SignedExchangeCertFetcher::OnReceiveRedirect(
@@ -243,12 +254,6 @@ void SignedExchangeCertFetcher::OnReceiveRedirect(
Abort();
}
-void SignedExchangeCertFetcher::OnDataDownloaded(int64_t data_length,
- int64_t encoded_length) {
- // Cert fetching is not a downloading job.
- NOTREACHED();
-}
-
void SignedExchangeCertFetcher::OnUploadProgress(
int64_t current_position,
int64_t total_size,
diff --git a/chromium/content/browser/web_package/signed_exchange_cert_fetcher.h b/chromium/content/browser/web_package/signed_exchange_cert_fetcher.h
index 23de0610fb8..679ed5f7eba 100644
--- a/chromium/content/browser/web_package/signed_exchange_cert_fetcher.h
+++ b/chromium/content/browser/web_package/signed_exchange_cert_fetcher.h
@@ -54,7 +54,8 @@ class CONTENT_EXPORT SignedExchangeCertFetcher
bool force_fetch,
SignedExchangeVersion version,
CertificateCallback callback,
- SignedExchangeDevToolsProxy* devtools_proxy);
+ SignedExchangeDevToolsProxy* devtools_proxy,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id);
~SignedExchangeCertFetcher() override;
@@ -76,19 +77,17 @@ class CONTENT_EXPORT SignedExchangeCertFetcher
bool force_fetch,
SignedExchangeVersion version,
CertificateCallback callback,
- SignedExchangeDevToolsProxy* devtools_proxy);
+ SignedExchangeDevToolsProxy* devtools_proxy,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id);
void Start();
void Abort();
void OnHandleReady(MojoResult result);
void OnDataComplete();
// network::mojom::URLLoaderClient
- void OnReceiveResponse(
- const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override;
+ void OnReceiveResponse(const network::ResourceResponseHead& head) override;
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
const network::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;
diff --git a/chromium/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc b/chromium/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc
index 20234806225..7cff4e9bf38 100644
--- a/chromium/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc
+++ b/chromium/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc
@@ -4,6 +4,7 @@
#include "content/browser/web_package/signed_exchange_cert_fetcher_factory.h"
+#include "base/unguessable_token.h"
#include "content/public/common/url_loader_throttle.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -17,10 +18,12 @@ class SignedExchangeCertFetcherFactoryImpl
SignedExchangeCertFetcherFactoryImpl(
url::Origin request_initiator,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- URLLoaderThrottlesGetter url_loader_throttles_getter)
+ URLLoaderThrottlesGetter url_loader_throttles_getter,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id)
: request_initiator_(std::move(request_initiator)),
url_loader_factory_(std::move(url_loader_factory)),
- url_loader_throttles_getter_(std::move(url_loader_throttles_getter)) {}
+ url_loader_throttles_getter_(std::move(url_loader_throttles_getter)),
+ throttling_profile_id_(throttling_profile_id) {}
std::unique_ptr<SignedExchangeCertFetcher> CreateFetcherAndStart(
const GURL& cert_url,
@@ -33,6 +36,7 @@ class SignedExchangeCertFetcherFactoryImpl
url::Origin request_initiator_;
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
URLLoaderThrottlesGetter url_loader_throttles_getter_;
+ const base::Optional<base::UnguessableToken> throttling_profile_id_;
};
std::unique_ptr<SignedExchangeCertFetcher>
@@ -49,7 +53,7 @@ SignedExchangeCertFetcherFactoryImpl::CreateFetcherAndStart(
return SignedExchangeCertFetcher::CreateAndStart(
std::move(url_loader_factory_), std::move(throttles), cert_url,
std::move(request_initiator_), force_fetch, version, std::move(callback),
- devtools_proxy);
+ devtools_proxy, throttling_profile_id_);
}
// static
@@ -57,10 +61,11 @@ std::unique_ptr<SignedExchangeCertFetcherFactory>
SignedExchangeCertFetcherFactory::Create(
url::Origin request_initiator,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- URLLoaderThrottlesGetter url_loader_throttles_getter) {
+ URLLoaderThrottlesGetter url_loader_throttles_getter,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id) {
return std::make_unique<SignedExchangeCertFetcherFactoryImpl>(
std::move(request_initiator), std::move(url_loader_factory),
- std::move(url_loader_throttles_getter));
+ std::move(url_loader_throttles_getter), throttling_profile_id);
}
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_cert_fetcher_factory.h b/chromium/content/browser/web_package/signed_exchange_cert_fetcher_factory.h
index dc01c1c3bd2..941334570c5 100644
--- a/chromium/content/browser/web_package/signed_exchange_cert_fetcher_factory.h
+++ b/chromium/content/browser/web_package/signed_exchange_cert_fetcher_factory.h
@@ -9,6 +9,8 @@
#include <vector>
#include "base/callback_forward.h"
+#include "base/optional.h"
+#include "base/unguessable_token.h"
#include "content/browser/web_package/signed_exchange_cert_fetcher.h"
#include "content/common/content_export.h"
#include "url/origin.h"
@@ -41,7 +43,8 @@ class CONTENT_EXPORT SignedExchangeCertFetcherFactory {
static std::unique_ptr<SignedExchangeCertFetcherFactory> Create(
url::Origin request_initiator,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- URLLoaderThrottlesGetter url_loader_throttles_getter);
+ URLLoaderThrottlesGetter url_loader_throttles_getter,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id);
};
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc b/chromium/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
index 19e3ed513c7..9e5ea4406c0 100644
--- a/chromium/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
+++ b/chromium/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
@@ -8,6 +8,8 @@
#include "base/optional.h"
#include "base/strings/string_piece.h"
#include "base/test/scoped_task_environment.h"
+#include "components/cbor/cbor_values.h"
+#include "components/cbor/cbor_writer.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/public/common/resource_type.h"
#include "content/public/common/url_loader_throttle.h"
@@ -37,9 +39,11 @@ class DeferringURLLoaderThrottle final : public URLLoaderThrottle {
*defer = true;
}
- void WillRedirectRequest(const net::RedirectInfo& redirect_info,
- const network::ResourceResponseHead& response_head,
- bool* defer) override {
+ void WillRedirectRequest(
+ const net::RedirectInfo& redirect_info,
+ const network::ResourceResponseHead& response_head,
+ bool* defer,
+ std::vector<std::string>* to_be_removed_headers) override {
will_redirect_request_called_ = true;
*defer = true;
}
@@ -75,8 +79,9 @@ class MockURLLoader final : public network::mojom::URLLoader {
: binding_(this, std::move(url_loader_request)) {}
~MockURLLoader() override = default;
- MOCK_METHOD1(FollowRedirect,
- void(const base::Optional<net::HttpRequestHeaders>&));
+ MOCK_METHOD2(FollowRedirect,
+ void(const base::Optional<std::vector<std::string>>&,
+ const base::Optional<net::HttpRequestHeaders>&));
MOCK_METHOD0(ProceedWithResponse, void());
MOCK_METHOD2(SetPriority,
void(net::RequestPriority priority,
@@ -142,7 +147,7 @@ class SignedExchangeCertFetcherTest : public testing::Test {
SignedExchangeCertFetcherTest()
: url_(GURL("https://www.example.com/cert")),
request_initiator_(
- url::Origin::Create(GURL("https://htxg.example.com/test.htxg"))),
+ url::Origin::Create(GURL("https://sxg.example.com/test.sxg"))),
resource_dispatcher_host_(CreateDownloadHandlerIntercept(),
base::ThreadTaskRunnerHandle::Get(),
true /* enable_resource_scheduler */) {}
@@ -154,30 +159,24 @@ class SignedExchangeCertFetcherTest : public testing::Test {
}
static std::string CreateCertMessage(const base::StringPiece& cert_data) {
- std::string message;
- uint32_t cert_size = cert_data.length();
- uint32_t cert_list_size = cert_size + 3 /* size of "cert data size" */ +
- 2 /* size of "extensions size" */;
- uint32_t message_size = cert_list_size +
- 1 /* size of "request context size" */ +
- 3 /* size of "certificate list size" */;
- // request context size
- message += static_cast<char>(0x00);
- // certificate list size
- message += static_cast<char>(cert_list_size >> 16);
- message += static_cast<char>((cert_list_size & 0xFF00) >> 8);
- message += static_cast<char>(cert_list_size & 0xFF);
- // certificate list size
- message += static_cast<char>(cert_size >> 16);
- message += static_cast<char>((cert_size & 0xFF00) >> 8);
- message += static_cast<char>(cert_size & 0xFF);
- // cert data
- message += std::string(cert_data);
- // extensions size
- message += static_cast<char>(0x00);
- message += static_cast<char>(0x00);
- CHECK_EQ(message_size, message.size());
- return message;
+ cbor::CBORValue::MapValue cbor_map;
+ cbor_map[cbor::CBORValue("sct")] =
+ cbor::CBORValue("SCT", cbor::CBORValue::Type::BYTE_STRING);
+ cbor_map[cbor::CBORValue("cert")] =
+ cbor::CBORValue(cert_data, cbor::CBORValue::Type::BYTE_STRING);
+ cbor_map[cbor::CBORValue("ocsp")] =
+ cbor::CBORValue("OCSP", cbor::CBORValue::Type::BYTE_STRING);
+
+ cbor::CBORValue::ArrayValue cbor_array;
+ cbor_array.push_back(cbor::CBORValue(u8"\U0001F4DC\u26D3"));
+ cbor_array.push_back(cbor::CBORValue(std::move(cbor_map)));
+
+ base::Optional<std::vector<uint8_t>> serialized =
+ cbor::CBORWriter::Write(cbor::CBORValue(std::move(cbor_array)));
+ if (!serialized)
+ return std::string();
+ return std::string(reinterpret_cast<char*>(serialized->data()),
+ serialized->size());
}
static base::StringPiece CreateCertMessageFromCert(
@@ -202,6 +201,7 @@ class SignedExchangeCertFetcherTest : public testing::Test {
void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); }
std::unique_ptr<SignedExchangeCertFetcher> CreateFetcherAndStart(
+ const GURL& url,
bool force_fetch) {
SignedExchangeCertFetcher::CertificateCallback callback = base::BindOnce(
&ForwardCertificateCallback, base::Unretained(&callback_called_),
@@ -210,18 +210,20 @@ class SignedExchangeCertFetcherTest : public testing::Test {
return SignedExchangeCertFetcher::CreateAndStart(
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&mock_loader_factory_),
- std::move(throttles_), url_, request_initiator_, force_fetch,
- SignedExchangeVersion::kB0, std::move(callback),
- nullptr /* devtools_proxy */);
+ std::move(throttles_), url, request_initiator_, force_fetch,
+ SignedExchangeVersion::kB1, std::move(callback),
+ nullptr /* devtools_proxy */,
+ base::nullopt /* throttling_profile_id */);
}
void CallOnReceiveResponse() {
network::ResourceResponseHead resource_response;
resource_response.headers =
base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
-
- mock_loader_factory_.client_ptr()->OnReceiveResponse(
- resource_response, nullptr /* downloaded_file */);
+ resource_response.headers->AddHeader(
+ "Content-Type: application/cert-chain+cbor");
+ resource_response.mime_type = "application/cert-chain+cbor";
+ mock_loader_factory_.client_ptr()->OnReceiveResponse(resource_response);
}
DeferringURLLoaderThrottle* InitializeDeferringURLLoaderThrottle() {
@@ -252,7 +254,7 @@ class SignedExchangeCertFetcherTest : public testing::Test {
TEST_F(SignedExchangeCertFetcherTest, Simple) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
ASSERT_TRUE(mock_loader_factory_.client_ptr());
ASSERT_TRUE(mock_loader_factory_.url_request());
@@ -279,7 +281,7 @@ TEST_F(SignedExchangeCertFetcherTest, Simple) {
TEST_F(SignedExchangeCertFetcherTest, MultipleChunked) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
scoped_refptr<net::X509Certificate> certificate = ImportTestCert();
const std::string message =
@@ -305,7 +307,7 @@ TEST_F(SignedExchangeCertFetcherTest, MultipleChunked) {
TEST_F(SignedExchangeCertFetcherTest, ForceFetchAndFail) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(true /* force_fetch */);
+ CreateFetcherAndStart(url_, true /* force_fetch */);
CallOnReceiveResponse();
ASSERT_TRUE(mock_loader_factory_.url_request());
@@ -333,7 +335,7 @@ TEST_F(SignedExchangeCertFetcherTest, MaxCertSize_Exceeds) {
SignedExchangeCertFetcher::SetMaxCertSizeForTest(message.size() - 1);
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
mojo::DataPipe data_pipe(message.size());
CHECK(mojo::BlockingCopyFromString(message, data_pipe.producer_handle));
@@ -356,7 +358,7 @@ TEST_F(SignedExchangeCertFetcherTest, MaxCertSize_SameSize) {
SignedExchangeCertFetcher::SetMaxCertSizeForTest(message.size());
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
mojo::DataPipe data_pipe(message.size());
CHECK(mojo::BlockingCopyFromString(message, data_pipe.producer_handle));
@@ -379,7 +381,7 @@ TEST_F(SignedExchangeCertFetcherTest, MaxCertSize_MultipleChunked) {
SignedExchangeCertFetcher::SetMaxCertSizeForTest(message.size() - 1);
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
mojo::DataPipe data_pipe(message.size() / 2 + 1);
ASSERT_TRUE(mojo::BlockingCopyFromString(
@@ -406,13 +408,12 @@ TEST_F(SignedExchangeCertFetcherTest, MaxCertSize_ContentLengthCheck) {
SignedExchangeCertFetcher::SetMaxCertSizeForTest(message.size() - 1);
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
network::ResourceResponseHead resource_response;
resource_response.headers =
base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
resource_response.content_length = message.size();
- mock_loader_factory_.client_ptr()->OnReceiveResponse(
- resource_response, nullptr /* downloaded_file */);
+ mock_loader_factory_.client_ptr()->OnReceiveResponse(resource_response);
mojo::DataPipe data_pipe(message.size());
CHECK(mojo::BlockingCopyFromString(message, data_pipe.producer_handle));
data_pipe.producer_handle.reset();
@@ -428,7 +429,7 @@ TEST_F(SignedExchangeCertFetcherTest, MaxCertSize_ContentLengthCheck) {
TEST_F(SignedExchangeCertFetcherTest, Abort_Redirect) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
network::ResourceResponseHead response_head;
net::RedirectInfo redirect_info;
mock_loader_factory_.client_ptr()->OnReceiveRedirect(redirect_info,
@@ -441,12 +442,27 @@ TEST_F(SignedExchangeCertFetcherTest, Abort_Redirect) {
TEST_F(SignedExchangeCertFetcherTest, Abort_404) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
network::ResourceResponseHead resource_response;
resource_response.headers =
base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 404 Not Found");
- mock_loader_factory_.client_ptr()->OnReceiveResponse(
- resource_response, nullptr /* downloaded_file */);
+ mock_loader_factory_.client_ptr()->OnReceiveResponse(resource_response);
+ RunUntilIdle();
+
+ EXPECT_TRUE(callback_called_);
+ EXPECT_FALSE(cert_result_);
+}
+
+TEST_F(SignedExchangeCertFetcherTest, WrongMimeType) {
+ std::unique_ptr<SignedExchangeCertFetcher> fetcher =
+ CreateFetcherAndStart(url_, false /* force_fetch */);
+ network::ResourceResponseHead resource_response;
+ resource_response.headers =
+ base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
+ resource_response.headers->AddHeader(
+ "Content-Type: application/octet-stream");
+ resource_response.mime_type = "application/octet-stream";
+ mock_loader_factory_.client_ptr()->OnReceiveResponse(resource_response);
RunUntilIdle();
EXPECT_TRUE(callback_called_);
@@ -455,7 +471,7 @@ TEST_F(SignedExchangeCertFetcherTest, Abort_404) {
TEST_F(SignedExchangeCertFetcherTest, Invalid_CertData) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
const std::string message = CreateCertMessage("Invalid Cert Data");
mojo::DataPipe data_pipe(message.size());
@@ -473,7 +489,7 @@ TEST_F(SignedExchangeCertFetcherTest, Invalid_CertData) {
TEST_F(SignedExchangeCertFetcherTest, Invalid_CertMessage) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
const std::string message = "Invalid cert message";
@@ -495,7 +511,7 @@ TEST_F(SignedExchangeCertFetcherTest, Invalid_CertMessage) {
TEST_F(SignedExchangeCertFetcherTest, Throttle_Simple) {
DeferringURLLoaderThrottle* throttle = InitializeDeferringURLLoaderThrottle();
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
RunUntilIdle();
EXPECT_TRUE(throttle->will_start_request_called());
@@ -532,7 +548,7 @@ TEST_F(SignedExchangeCertFetcherTest, Throttle_Simple) {
TEST_F(SignedExchangeCertFetcherTest, Throttle_AbortsOnRequest) {
DeferringURLLoaderThrottle* throttle = InitializeDeferringURLLoaderThrottle();
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
RunUntilIdle();
throttle->delegate()->CancelWithError(net::ERR_INVALID_SIGNED_EXCHANGE);
@@ -546,7 +562,7 @@ TEST_F(SignedExchangeCertFetcherTest, Throttle_AbortsOnRequest) {
TEST_F(SignedExchangeCertFetcherTest, Throttle_AbortsOnRedirect) {
DeferringURLLoaderThrottle* throttle = InitializeDeferringURLLoaderThrottle();
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
RunUntilIdle();
throttle->delegate()->Resume();
@@ -572,7 +588,7 @@ TEST_F(SignedExchangeCertFetcherTest, Throttle_AbortsOnRedirect) {
TEST_F(SignedExchangeCertFetcherTest, Throttle_AbortsOnResponse) {
DeferringURLLoaderThrottle* throttle = InitializeDeferringURLLoaderThrottle();
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
RunUntilIdle();
throttle->delegate()->Resume();
@@ -603,7 +619,7 @@ TEST_F(SignedExchangeCertFetcherTest, Throttle_AbortsOnResponse) {
TEST_F(SignedExchangeCertFetcherTest, DeleteFetcher_BeforeReceiveResponse) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
RunUntilIdle();
fetcher.reset();
RunUntilIdle();
@@ -614,7 +630,7 @@ TEST_F(SignedExchangeCertFetcherTest, DeleteFetcher_BeforeReceiveResponse) {
TEST_F(SignedExchangeCertFetcherTest, DeleteFetcher_BeforeResponseBody) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
RunUntilIdle();
fetcher.reset();
@@ -626,7 +642,7 @@ TEST_F(SignedExchangeCertFetcherTest, DeleteFetcher_BeforeResponseBody) {
TEST_F(SignedExchangeCertFetcherTest, DeleteFetcher_WhileReceivingBody) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
scoped_refptr<net::X509Certificate> certificate = ImportTestCert();
const std::string message =
@@ -649,7 +665,7 @@ TEST_F(SignedExchangeCertFetcherTest, DeleteFetcher_WhileReceivingBody) {
TEST_F(SignedExchangeCertFetcherTest, DeleteFetcher_AfterReceivingBody) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
scoped_refptr<net::X509Certificate> certificate = ImportTestCert();
const std::string message =
@@ -671,7 +687,7 @@ TEST_F(SignedExchangeCertFetcherTest, DeleteFetcher_AfterReceivingBody) {
TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_BeforeReceiveResponse) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
RunUntilIdle();
CloseClientPipe();
RunUntilIdle();
@@ -682,7 +698,7 @@ TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_BeforeReceiveResponse) {
TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_BeforeResponseBody) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
RunUntilIdle();
CloseClientPipe();
@@ -694,7 +710,7 @@ TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_BeforeResponseBody) {
TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_WhileReceivingBody) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
scoped_refptr<net::X509Certificate> certificate = ImportTestCert();
const std::string message =
@@ -715,7 +731,7 @@ TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_WhileReceivingBody) {
TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_AfterReceivingBody) {
std::unique_ptr<SignedExchangeCertFetcher> fetcher =
- CreateFetcherAndStart(false /* force_fetch */);
+ CreateFetcherAndStart(url_, false /* force_fetch */);
CallOnReceiveResponse();
scoped_refptr<net::X509Certificate> certificate = ImportTestCert();
const std::string message =
@@ -736,4 +752,39 @@ TEST_F(SignedExchangeCertFetcherTest, CloseClientPipe_AfterReceivingBody) {
cert_result_->cert()->CalculateChainFingerprint256());
}
+TEST_F(SignedExchangeCertFetcherTest, DataURL) {
+ const GURL data_url = GURL("data:application/cert-chain+cbor,foobar");
+ std::unique_ptr<SignedExchangeCertFetcher> fetcher =
+ CreateFetcherAndStart(data_url, false /* force_fetch */);
+ EXPECT_EQ(data_url, mock_loader_factory_.url_request()->url);
+
+ network::ResourceResponseHead resource_response;
+ resource_response.mime_type = "application/cert-chain+cbor";
+ mock_loader_factory_.client_ptr()->OnReceiveResponse(resource_response);
+
+ mock_loader_factory_.client_ptr()->OnStartLoadingResponseBody(
+ CreateTestDataFilledDataPipe());
+ mock_loader_factory_.client_ptr()->OnComplete(
+ network::URLLoaderCompletionStatus(net::OK));
+ RunUntilIdle();
+ EXPECT_TRUE(callback_called_);
+ ASSERT_TRUE(cert_result_);
+ EXPECT_EQ(GetTestDataCertFingerprint256(),
+ cert_result_->cert()->CalculateChainFingerprint256());
+}
+
+TEST_F(SignedExchangeCertFetcherTest, DataURLWithWrongMimeType) {
+ const GURL data_url = GURL("data:application/octet-stream,foobar");
+ std::unique_ptr<SignedExchangeCertFetcher> fetcher =
+ CreateFetcherAndStart(data_url, false /* force_fetch */);
+ EXPECT_EQ(data_url, mock_loader_factory_.url_request()->url);
+
+ network::ResourceResponseHead resource_response;
+ resource_response.mime_type = "application/octet-stream";
+ mock_loader_factory_.client_ptr()->OnReceiveResponse(resource_response);
+ RunUntilIdle();
+
+ EXPECT_TRUE(callback_called_);
+}
+
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_certificate_chain.cc b/chromium/content/browser/web_package/signed_exchange_certificate_chain.cc
index d94125eae13..1fd297d9512 100644
--- a/chromium/content/browser/web_package/signed_exchange_certificate_chain.cc
+++ b/chromium/content/browser/web_package/signed_exchange_certificate_chain.cc
@@ -4,7 +4,6 @@
#include "content/browser/web_package/signed_exchange_certificate_chain.h"
-#include "base/command_line.h"
#include "base/format_macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
@@ -12,87 +11,32 @@
#include "components/cbor/cbor_reader.h"
#include "content/browser/web_package/signed_exchange_consts.h"
#include "content/browser/web_package/signed_exchange_utils.h"
-#include "content/public/common/content_switches.h"
#include "net/cert/x509_certificate.h"
namespace content {
namespace {
-bool ConsumeByte(base::span<const uint8_t>* data, uint8_t* out) {
- if (data->empty())
- return false;
- *out = (*data)[0];
- *data = data->subspan(1);
- return true;
-}
-
-bool Consume2Bytes(base::span<const uint8_t>* data, uint16_t* out) {
- if (data->size() < 2)
- return false;
- *out = ((*data)[0] << 8) | (*data)[1];
- *data = data->subspan(2);
- return true;
-}
-
-bool Consume3Bytes(base::span<const uint8_t>* data, uint32_t* out) {
- if (data->size() < 3)
- return false;
- *out = ((*data)[0] << 16) | ((*data)[1] << 8) | (*data)[2];
- *data = data->subspan(3);
- return true;
-}
-
-std::unique_ptr<SignedExchangeCertificateChain> ParseB0(
- base::span<const uint8_t> message,
- SignedExchangeDevToolsProxy* devtools_proxy) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeCertificateChain::ParseB0");
- base::Optional<std::vector<base::StringPiece>> der_certs =
- SignedExchangeCertificateChain::GetCertChainFromMessage(message);
- if (!der_certs) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB0",
- "Failed to parse the response as a TLS 1.3 Certificate message.");
- return nullptr;
- }
-
- scoped_refptr<net::X509Certificate> cert =
- net::X509Certificate::CreateFromDERCertChain(*der_certs);
- if (!cert) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB0",
- "X509Certificate::CreateFromDERCertChain failed.");
- return nullptr;
- }
-
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeCertificateChain::ParseB1");
- // The V0 certificate format doesn't support OCSP nor SCT.
- return base::WrapUnique(
- new SignedExchangeCertificateChain(cert, "" /* ocsp */, "" /* sct */));
-}
-
// https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#cert-chain-format
std::unique_ptr<SignedExchangeCertificateChain> ParseB1(
base::span<const uint8_t> message,
SignedExchangeDevToolsProxy* devtools_proxy) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeCertificateChain::ParseB1");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeCertificateChain::ParseB1");
cbor::CBORReader::DecoderError error;
base::Optional<cbor::CBORValue> value =
cbor::CBORReader::Read(message, &error);
if (!value.has_value()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf("Failed to decode CBORValue. CBOR error: %s",
cbor::CBORReader::ErrorCodeToString(error)));
return nullptr;
}
if (!value->is_array()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Expected top-level CBORValue to be an array. Actual type: %d",
static_cast<int>(value->type())));
@@ -102,8 +46,8 @@ std::unique_ptr<SignedExchangeCertificateChain> ParseB1(
const cbor::CBORValue::ArrayValue& top_level_array = value->GetArray();
// Expect at least 2 elements (magic string and main certificate).
if (top_level_array.size() < 2) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Expected top-level array to have at least 2 elements."
"Actual element count: %" PRIuS,
@@ -112,8 +56,8 @@ std::unique_ptr<SignedExchangeCertificateChain> ParseB1(
}
if (!top_level_array[0].is_string() ||
top_level_array[0].GetString() != kCertChainCborMagic) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
"First element of cert chain CBOR does not match the magic string.");
return nullptr;
}
@@ -125,8 +69,8 @@ std::unique_ptr<SignedExchangeCertificateChain> ParseB1(
for (size_t i = 1; i < top_level_array.size(); i++) {
if (!top_level_array[i].is_map()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Expected certificate map, got non-map type at index %zu."
" Actual type: %d",
@@ -140,8 +84,8 @@ std::unique_ptr<SignedExchangeCertificateChain> ParseB1(
// properties of this certificate. [spec text]
auto cert_iter = cert_map.find(cbor::CBORValue(kCertKey));
if (cert_iter == cert_map.end() || !cert_iter->second.is_bytestring()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"cert is not found or not a bytestring, at index %zu.", i));
return nullptr;
@@ -154,23 +98,22 @@ std::unique_ptr<SignedExchangeCertificateChain> ParseB1(
// DER-encoded OCSP response for that certificate (using the ASN.1 type
// OCSPResponse defined in [RFC2560]). ... [spec text]
if (ocsp_iter == cert_map.end() || !ocsp_iter->second.is_bytestring()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
"ocsp is not a bytestring, or not found in the first cert map.");
return nullptr;
}
ocsp = ocsp_iter->second.GetBytestringAsString().as_string();
if (ocsp.empty()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
- "ocsp must not be empty.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "ocsp must not be empty.");
return nullptr;
}
} else if (ocsp_iter != cert_map.end()) {
// Step 2. ... Subsequent certificates MUST NOT have an ocsp value. [spec
// text]
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"ocsp value found in a subsequent cert map, at index %zu.", i));
return nullptr;
@@ -187,16 +130,14 @@ std::unique_ptr<SignedExchangeCertificateChain> ParseB1(
auto sct_iter = cert_map.find(cbor::CBORValue(kSctKey));
if (sct_iter != cert_map.end()) {
if (!sct_iter->second.is_bytestring()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
- "sct is not a bytestring.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "sct is not a bytestring.");
return nullptr;
}
sct = sct_iter->second.GetBytestringAsString().as_string();
if (sct.empty()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
- "sct must not be empty.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "sct must not be empty.");
return nullptr;
}
}
@@ -205,14 +146,11 @@ std::unique_ptr<SignedExchangeCertificateChain> ParseB1(
scoped_refptr<net::X509Certificate> cert =
net::X509Certificate::CreateFromDERCertChain(der_certs);
if (!cert) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeCertificateChain::ParseB1",
- "X509Certificate::CreateFromDERCertChain failed.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "X509Certificate::CreateFromDERCertChain failed.");
return nullptr;
}
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeCertificateChain::ParseB1");
return base::WrapUnique(new SignedExchangeCertificateChain(cert, ocsp, sct));
}
@@ -224,71 +162,8 @@ SignedExchangeCertificateChain::Parse(
SignedExchangeVersion version,
base::span<const uint8_t> cert_response_body,
SignedExchangeDevToolsProxy* devtools_proxy) {
- switch (version) {
- case SignedExchangeVersion::kB0:
- return ParseB0(cert_response_body, devtools_proxy);
- case SignedExchangeVersion::kB1:
- return ParseB1(cert_response_body, devtools_proxy);
- }
- NOTREACHED();
- return nullptr;
-}
-
-// static
-base::Optional<std::vector<base::StringPiece>>
-SignedExchangeCertificateChain::GetCertChainFromMessage(
- base::span<const uint8_t> message) {
- uint8_t cert_request_context_size = 0;
- if (!ConsumeByte(&message, &cert_request_context_size)) {
- DVLOG(1) << "Can't read certificate request request context size.";
- return base::nullopt;
- }
- if (cert_request_context_size != 0) {
- DVLOG(1) << "Invalid certificate request context size: "
- << static_cast<int>(cert_request_context_size);
- return base::nullopt;
- }
- uint32_t cert_list_size = 0;
- if (!Consume3Bytes(&message, &cert_list_size)) {
- DVLOG(1) << "Can't read certificate list size.";
- return base::nullopt;
- }
-
- if (cert_list_size != message.size()) {
- DVLOG(1) << "Certificate list size error: cert_list_size=" << cert_list_size
- << " remaining=" << message.size();
- return base::nullopt;
- }
-
- std::vector<base::StringPiece> certs;
- while (!message.empty()) {
- uint32_t cert_data_size = 0;
- if (!Consume3Bytes(&message, &cert_data_size)) {
- DVLOG(1) << "Can't read certificate data size.";
- return base::nullopt;
- }
- if (message.size() < cert_data_size) {
- DVLOG(1) << "Certificate data size error: cert_data_size="
- << cert_data_size << " remaining=" << message.size();
- return base::nullopt;
- }
- certs.emplace_back(base::StringPiece(
- reinterpret_cast<const char*>(message.data()), cert_data_size));
- message = message.subspan(cert_data_size);
-
- uint16_t extensions_size = 0;
- if (!Consume2Bytes(&message, &extensions_size)) {
- DVLOG(1) << "Can't read extensions size.";
- return base::nullopt;
- }
- if (message.size() < extensions_size) {
- DVLOG(1) << "Extensions size error: extensions_size=" << extensions_size
- << " remaining=" << message.size();
- return base::nullopt;
- }
- message = message.subspan(extensions_size);
- }
- return certs;
+ DCHECK_EQ(version, SignedExchangeVersion::kB1);
+ return ParseB1(cert_response_body, devtools_proxy);
}
SignedExchangeCertificateChain::SignedExchangeCertificateChain(
diff --git a/chromium/content/browser/web_package/signed_exchange_certificate_chain.h b/chromium/content/browser/web_package/signed_exchange_certificate_chain.h
index 7b6ece476c3..b20f7349a38 100644
--- a/chromium/content/browser/web_package/signed_exchange_certificate_chain.h
+++ b/chromium/content/browser/web_package/signed_exchange_certificate_chain.h
@@ -37,12 +37,6 @@ class CONTENT_EXPORT SignedExchangeCertificateChain {
SignedExchangeCertificateChain(scoped_refptr<net::X509Certificate> cert,
const std::string& ocsp,
const std::string& sct);
-
- // Parses a TLS 1.3 Certificate message containing X.509v3 certificates and
- // returns a vector of cert_data. Returns nullopt when failed to parse.
- static base::Optional<std::vector<base::StringPiece>> GetCertChainFromMessage(
- base::span<const uint8_t> message);
-
~SignedExchangeCertificateChain();
const scoped_refptr<net::X509Certificate>& cert() const { return cert_; }
diff --git a/chromium/content/browser/web_package/signed_exchange_certificate_chain_fuzzer.cc b/chromium/content/browser/web_package/signed_exchange_certificate_chain_fuzzer.cc
index 56d34a6ad96..8d718db5f0a 100644
--- a/chromium/content/browser/web_package/signed_exchange_certificate_chain_fuzzer.cc
+++ b/chromium/content/browser/web_package/signed_exchange_certificate_chain_fuzzer.cc
@@ -9,8 +9,6 @@
namespace content {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- SignedExchangeCertificateChain::Parse(SignedExchangeVersion::kB0,
- base::make_span(data, size), nullptr);
SignedExchangeCertificateChain::Parse(SignedExchangeVersion::kB1,
base::make_span(data, size), nullptr);
return 0;
diff --git a/chromium/content/browser/web_package/signed_exchange_certificate_chain_unittest.cc b/chromium/content/browser/web_package/signed_exchange_certificate_chain_unittest.cc
index 932f1cbf474..6389105c3a0 100644
--- a/chromium/content/browser/web_package/signed_exchange_certificate_chain_unittest.cc
+++ b/chromium/content/browser/web_package/signed_exchange_certificate_chain_unittest.cc
@@ -21,261 +21,12 @@ namespace content {
namespace {
-base::Optional<std::vector<base::StringPiece>> GetCertChain(
- const uint8_t* input,
- size_t input_size) {
- return SignedExchangeCertificateChain::GetCertChainFromMessage(
- base::make_span(input, input_size));
-}
-
cbor::CBORValue CBORByteString(base::StringPiece str) {
return cbor::CBORValue(str, cbor::CBORValue::Type::BYTE_STRING);
}
} // namespace
-TEST(SignedExchangeCertificateParseB0Test, OneCert) {
- const uint8_t input[] = {
- // clang-format off
- 0x00, // request context size
- 0x00, 0x00, 0x07, // certificate list size
-
- 0x00, 0x00, 0x02, // cert data size
- 0x11, 0x22, // cert data
- 0x00, 0x00, // extensions size
- // clang-format on
- };
- base::Optional<std::vector<base::StringPiece>> certs =
- GetCertChain(input, arraysize(input));
- ASSERT_TRUE(certs);
- ASSERT_EQ(1u, certs->size());
- const uint8_t kExpected[] = {
- // clang-format off
- 0x11, 0x22, // cert data
- // clang-format on
- };
- EXPECT_THAT((*certs)[0],
- testing::ElementsAreArray(kExpected, arraysize(kExpected)));
-}
-
-TEST(SignedExchangeCertificateParseB0Test, OneCertWithExtension) {
- const uint8_t input[] = {
- // clang-format off
- 0x00, // request context size
- 0x00, 0x00, 0x0A, // certificate list size
-
- 0x00, 0x00, 0x02, // cert data size
- 0x11, 0x22, // cert data
- 0x00, 0x03, // extensions size
- 0xE1, 0xE2, 0xE3, // extensions data
- // clang-format on
- };
- base::Optional<std::vector<base::StringPiece>> certs =
- GetCertChain(input, arraysize(input));
- ASSERT_TRUE(certs);
- ASSERT_EQ(1u, certs->size());
- const uint8_t kExpected[] = {
- // clang-format off
- 0x11, 0x22, // cert data
- // clang-format on
- };
- EXPECT_THAT((*certs)[0],
- testing::ElementsAreArray(kExpected, arraysize(kExpected)));
-}
-
-TEST(SignedExchangeCertificateParseB0Test, TwoCerts) {
- const uint8_t input[] = {
- // clang-format off
- 0x00, // request context size
- 0x00, 0x01, 0x13, // certificate list size
-
- 0x00, 0x01, 0x04, // cert data size
-
- // cert data
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
-
- 0x00, 0x00, // extensions size
-
- 0x00, 0x00, 0x05, // cert data size
- 0x33, 0x44, 0x55, 0x66, 0x77, // cert data
- 0x00, 0x00, // extensions size
-
- // clang-format on
- };
-
- const uint8_t kExpected1[] = {
- // clang-format off
- // cert data
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
- // clang-format on
- };
- const uint8_t kExpected2[] = {
- // clang-format off
- 0x33, 0x44, 0x55, 0x66, 0x77, // cert data
- // clang-format on
- };
-
- base::Optional<std::vector<base::StringPiece>> certs =
- GetCertChain(input, sizeof(input));
- ASSERT_TRUE(certs);
- ASSERT_EQ(2u, certs->size());
- EXPECT_THAT((*certs)[0],
- testing::ElementsAreArray(kExpected1, arraysize(kExpected1)));
- EXPECT_THAT((*certs)[1],
- testing::ElementsAreArray(kExpected2, arraysize(kExpected2)));
-}
-
-TEST(SignedExchangeCertificateParseB0Test, Empty) {
- EXPECT_FALSE(GetCertChain(nullptr, 0));
-}
-
-TEST(SignedExchangeCertificateParseB0Test, InvalidRequestContextSize) {
- const uint8_t input[] = {
- // clang-format off
- 0x01, // request context size: must be zero
- 0x20, // request context
- // clang-format on
- };
- EXPECT_FALSE(GetCertChain(input, arraysize(input)));
-}
-
-TEST(SignedExchangeCertificateParseB0Test, CanNotReadCertListSize1) {
- const uint8_t input[] = {
- // clang-format off
- 0x00, // request context size
- 0x01, // certificate list size: must be 3 bytes
- // clang-format on
- };
- EXPECT_FALSE(GetCertChain(input, arraysize(input)));
-}
-
-TEST(SignedExchangeCertificateParseB0Test, CanNotReadCertListSize2) {
- const uint8_t input[] = {
- // clang-format off
- 0x00, // request context size
- 0x00, 0x01, // certificate list size: must be 3 bytes
- // clang-format on
- };
- EXPECT_FALSE(GetCertChain(input, arraysize(input)));
-}
-
-TEST(SignedExchangeCertificateParseB0Test, CertListSizeError) {
- const uint8_t input[] = {
- // clang-format off
- 0x00, // request context size
- 0x00, 0x01, 0x01, // certificate list size: 257 (This must be 7)
-
- 0x00, 0x00, 0x02, // cert data size
- 0x11, 0x22, // cert data
- 0x00, 0x00, // extensions size
- // clang-format on
- };
- EXPECT_FALSE(GetCertChain(input, arraysize(input)));
-}
-
-TEST(SignedExchangeCertificateParseB0Test, CanNotReadCertDataSize) {
- const uint8_t input[] = {
- // clang-format off
- 0x00, // request context size
- 0x00, 0x00, 0x02, // certificate list size
-
- 0x00, 0x01, // cert data size: must be 3 bytes
- // clang-format on
- };
- EXPECT_FALSE(GetCertChain(input, arraysize(input)));
-}
-
-TEST(SignedExchangeCertificateParseB0Test, CertDataSizeError) {
- const uint8_t input[] = {
- // clang-format off
- 0x00, // request context size
- 0x00, 0x00, 0x04, // certificate list size
-
- 0x00, 0x00, 0x02, // cert data size
- 0x11, // cert data: Need 2 bytes
- // clang-format on
- };
- EXPECT_FALSE(GetCertChain(input, arraysize(input)));
-}
-
-TEST(SignedExchangeCertificateParseB0Test, CanNotReadExtensionsSize) {
- const uint8_t input[] = {
- // clang-format off
- 0x00, // request context size
- 0x00, 0x00, 0x06, // certificate list size
-
- 0x00, 0x00, 0x02, // cert data size
- 0x11, 0x22, // cert data
- 0x00, // extensions size : must be 2 bytes
- // clang-format on
- };
- EXPECT_FALSE(GetCertChain(input, arraysize(input)));
-}
-
-TEST(SignedExchangeCertificateParseB0Test, ExtensionsSizeError) {
- const uint8_t input[] = {
- // clang-format off
- 0x00, // request context size
- 0x00, 0x00, 0x07, // certificate list size
-
- 0x00, 0x00, 0x02, // cert data size
- 0x11, 0x22, // cert data
- 0x00, 0x01, // extensions size
- // clang-format on
- };
- EXPECT_FALSE(GetCertChain(input, arraysize(input)));
-}
-
TEST(SignedExchangeCertificateParseB1Test, Empty) {
auto parsed = SignedExchangeCertificateChain::Parse(
SignedExchangeVersion::kB1, base::span<const uint8_t>(), nullptr);
@@ -408,7 +159,7 @@ TEST(SignedExchangeCertificateParseB1Test, TwoCerts) {
EXPECT_EQ(parsed->sct(), base::make_optional<std::string>("SCT"));
}
-TEST(SignedExchangeCertificateParseB1Test, HavingOCSPInSecnodCert) {
+TEST(SignedExchangeCertificateParseB1Test, HavingOCSPInSecondCert) {
net::CertificateList certs;
ASSERT_TRUE(net::LoadCertificateFiles(
{"subjectAltName_sanity_check.pem", "root_ca_cert.pem"}, &certs));
@@ -444,8 +195,8 @@ TEST(SignedExchangeCertificateParseB1Test, HavingOCSPInSecnodCert) {
TEST(SignedExchangeCertificateParseB1Test, ParseGoldenFile) {
base::FilePath path;
base::PathService::Get(content::DIR_TEST_DATA, &path);
- path = path.AppendASCII("htxg").AppendASCII(
- "wildcard_example.org.public.pem.cbor");
+ path =
+ path.AppendASCII("sxg").AppendASCII("test.example.org.public.pem.cbor");
std::string contents;
ASSERT_TRUE(base::ReadFileToString(path, &contents));
diff --git a/chromium/content/browser/web_package/signed_exchange_consts.h b/chromium/content/browser/web_package/signed_exchange_consts.h
index 9dedf00f449..6e8bd5210ae 100644
--- a/chromium/content/browser/web_package/signed_exchange_consts.h
+++ b/chromium/content/browser/web_package/signed_exchange_consts.h
@@ -8,25 +8,24 @@
namespace content {
constexpr char kAcceptHeaderSignedExchangeSuffix[] =
- ",application/signed-exchange;v=b0";
+ ",application/signed-exchange;v=b1";
-enum class SignedExchangeVersion { kB0, kB1 };
+enum class SignedExchangeVersion { kB1 };
// Field names defined in the application/signed-exchange content type:
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#application-signed-exchange
-constexpr char kCertSha256Key[] = "certSha256";
-constexpr char kCertUrl[] = "certUrl";
+constexpr char kCertSha256Key[] = "cert-sha256";
+constexpr char kCertUrl[] = "cert-url";
constexpr char kDateKey[] = "date";
constexpr char kExpiresKey[] = "expires";
constexpr char kHeadersKey[] = "headers";
constexpr char kIntegrity[] = "integrity";
constexpr char kMethodKey[] = ":method";
-constexpr char kSignature[] = "signature";
constexpr char kSig[] = "sig";
constexpr char kStatusKey[] = ":status";
constexpr char kUrlKey[] = ":url";
-constexpr char kValidityUrlKey[] = "validityUrl";
+constexpr char kValidityUrlKey[] = "validity-url";
constexpr char kCertChainCborMagic[] = u8"\U0001F4DC\u26D3"; // "📜⛓"
constexpr char kCertKey[] = "cert";
constexpr char kOcspKey[] = "ocsp";
diff --git a/chromium/content/browser/web_package/signed_exchange_devtools_proxy.cc b/chromium/content/browser/web_package/signed_exchange_devtools_proxy.cc
index 3a04504e15d..44f40ccf461 100644
--- a/chromium/content/browser/web_package/signed_exchange_devtools_proxy.cc
+++ b/chromium/content/browser/web_package/signed_exchange_devtools_proxy.cc
@@ -7,7 +7,8 @@
#include "base/trace_event/trace_event.h"
#include "content/browser/devtools/render_frame_devtools_agent_host.h"
#include "content/browser/frame_host/frame_tree_node.h"
-#include "content/browser/web_package/signed_exchange_header.h"
+#include "content/browser/web_package/signed_exchange_envelope.h"
+#include "content/browser/web_package/signed_exchange_error.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -73,16 +74,17 @@ void OnSignedExchangeReceivedOnUI(
const GURL& outer_request_url,
scoped_refptr<network::ResourceResponse> outer_response,
base::Optional<const base::UnguessableToken> devtools_navigation_token,
- base::Optional<SignedExchangeHeader> header,
+ base::Optional<SignedExchangeEnvelope> envelope,
+ scoped_refptr<net::X509Certificate> certificate,
base::Optional<net::SSLInfo> ssl_info,
- std::vector<std::string> error_messages) {
+ std::vector<SignedExchangeError> errors) {
FrameTreeNode* frame_tree_node =
FrameTreeNode::GloballyFindByID(frame_tree_node_id_getter.Run());
if (!frame_tree_node)
return;
RenderFrameDevToolsAgentHost::OnSignedExchangeReceived(
frame_tree_node, devtools_navigation_token, outer_request_url,
- outer_response->head, header, ssl_info, error_messages);
+ outer_response->head, envelope, certificate, ssl_info, errors);
}
} // namespace
@@ -105,10 +107,11 @@ SignedExchangeDevToolsProxy::~SignedExchangeDevToolsProxy() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
}
-void SignedExchangeDevToolsProxy::ReportErrorMessage(
- const std::string& message) {
+void SignedExchangeDevToolsProxy::ReportError(
+ const std::string& message,
+ base::Optional<SignedExchangeError::FieldIndexPair> error_field) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- error_messages_.push_back(message);
+ errors_.push_back(SignedExchangeError(message, std::move(error_field)));
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&AddErrorMessageToConsoleOnUI, frame_tree_node_id_getter_,
@@ -161,7 +164,8 @@ void SignedExchangeDevToolsProxy::CertificateRequestCompleted(
}
void SignedExchangeDevToolsProxy::OnSignedExchangeReceived(
- const base::Optional<SignedExchangeHeader>& header,
+ const base::Optional<SignedExchangeEnvelope>& envelope,
+ const scoped_refptr<net::X509Certificate>& certificate,
const net::SSLInfo* ssl_info) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!devtools_enabled_)
@@ -178,8 +182,8 @@ void SignedExchangeDevToolsProxy::OnSignedExchangeReceived(
BrowserThread::UI, FROM_HERE,
base::BindOnce(&OnSignedExchangeReceivedOnUI, frame_tree_node_id_getter_,
outer_request_url_, resource_response->DeepCopy(),
- devtools_navigation_token_, header,
- std::move(ssl_info_opt), std::move(error_messages_)));
+ devtools_navigation_token_, envelope, certificate,
+ std::move(ssl_info_opt), std::move(errors_)));
}
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_devtools_proxy.h b/chromium/content/browser/web_package/signed_exchange_devtools_proxy.h
index e73b1119ec5..33ffee7a164 100644
--- a/chromium/content/browser/web_package/signed_exchange_devtools_proxy.h
+++ b/chromium/content/browser/web_package/signed_exchange_devtools_proxy.h
@@ -12,6 +12,7 @@
#include "base/macros.h"
#include "base/optional.h"
#include "base/unguessable_token.h"
+#include "content/browser/web_package/signed_exchange_error.h"
#include "content/common/content_export.h"
#include "services/network/public/cpp/resource_response.h"
@@ -23,6 +24,7 @@ class UnguessableToken;
namespace net {
class SSLInfo;
+class X509Certificate;
} // namespace net
namespace network {
@@ -32,7 +34,7 @@ struct URLLoaderCompletionStatus;
} // namespace network
namespace content {
-class SignedExchangeHeader;
+class SignedExchangeEnvelope;
// SignedExchangeDevToolsProxy lives on the IO thread and sends messages to
// DevTools via the UI thread to show signed exchange related information.
@@ -56,7 +58,10 @@ class CONTENT_EXPORT SignedExchangeDevToolsProxy {
bool report_raw_headers);
~SignedExchangeDevToolsProxy();
- void ReportErrorMessage(const std::string& message);
+ void ReportError(
+ const std::string& message,
+ base::Optional<SignedExchangeError::FieldIndexPair> error_field);
+
void CertificateRequestSent(const base::UnguessableToken& request_id,
const network::ResourceRequest& request);
void CertificateResponseReceived(const base::UnguessableToken& request_id,
@@ -67,7 +72,8 @@ class CONTENT_EXPORT SignedExchangeDevToolsProxy {
const network::URLLoaderCompletionStatus& status);
void OnSignedExchangeReceived(
- const base::Optional<SignedExchangeHeader>& header,
+ const base::Optional<SignedExchangeEnvelope>& envelope,
+ const scoped_refptr<net::X509Certificate>& certificate,
const net::SSLInfo* ssl_info);
private:
@@ -76,7 +82,7 @@ class CONTENT_EXPORT SignedExchangeDevToolsProxy {
const base::RepeatingCallback<int(void)> frame_tree_node_id_getter_;
const base::Optional<const base::UnguessableToken> devtools_navigation_token_;
const bool devtools_enabled_;
- std::vector<std::string> error_messages_;
+ std::vector<SignedExchangeError> errors_;
DISALLOW_COPY_AND_ASSIGN(SignedExchangeDevToolsProxy);
};
diff --git a/chromium/content/browser/web_package/signed_exchange_header.cc b/chromium/content/browser/web_package/signed_exchange_envelope.cc
index e0bfe678b2a..b42ccc07872 100644
--- a/chromium/content/browser/web_package/signed_exchange_header.cc
+++ b/chromium/content/browser/web_package/signed_exchange_envelope.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/web_package/signed_exchange_header.h"
+#include "content/browser/web_package/signed_exchange_envelope.h"
#include <utility>
@@ -16,6 +16,7 @@
#include "content/browser/web_package/signed_exchange_consts.h"
#include "content/browser/web_package/signed_exchange_utils.h"
#include "net/http/http_util.h"
+#include "url/origin.h"
namespace content {
@@ -68,12 +69,12 @@ bool IsMethodCacheable(base::StringPiece method) {
}
bool ParseRequestMap(const cbor::CBORValue& value,
- SignedExchangeHeader* out,
+ SignedExchangeEnvelope* out,
SignedExchangeDevToolsProxy* devtools_proxy) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"), "ParseRequestMap");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), "ParseRequestMap");
if (!value.is_map()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Expected request map, got non-map type. Actual type: %d",
static_cast<int>(value.type())));
@@ -85,20 +86,24 @@ bool ParseRequestMap(const cbor::CBORValue& value,
auto url_iter = request_map.find(
cbor::CBORValue(kUrlKey, cbor::CBORValue::Type::BYTE_STRING));
if (url_iter == request_map.end() || !url_iter->second.is_bytestring()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap",
- ":url is not found or not a bytestring.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, ":url is not found or not a bytestring.");
return false;
}
out->set_request_url(GURL(url_iter->second.GetBytestringAsString()));
if (!out->request_url().is_valid()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap", ":url is not a valid URL.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(devtools_proxy,
+ ":url is not a valid URL.");
return false;
}
if (out->request_url().has_ref()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap", ":url can't have a fragment.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, ":url can't have a fragment.");
+ return false;
+ }
+ if (!out->request_url().SchemeIs("https")) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, ":url scheme must be 'https'.");
return false;
}
@@ -106,9 +111,8 @@ bool ParseRequestMap(const cbor::CBORValue& value,
cbor::CBORValue(kMethodKey, cbor::CBORValue::Type::BYTE_STRING));
if (method_iter == request_map.end() ||
!method_iter->second.is_bytestring()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap",
- ":method is not found or not a bytestring.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, ":method is not found or not a bytestring.");
return false;
}
base::StringPiece method_str = method_iter->second.GetBytestringAsString();
@@ -117,8 +121,8 @@ bool ParseRequestMap(const cbor::CBORValue& value,
// [spec text]
if (!net::HttpUtil::IsMethodSafe(method_str.as_string()) ||
!IsMethodCacheable(method_str)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Request method is not safe or not cacheable. method: %s",
method_str.as_string().c_str()));
@@ -128,9 +132,8 @@ bool ParseRequestMap(const cbor::CBORValue& value,
for (const auto& it : request_map) {
if (!it.first.is_bytestring() || !it.second.is_bytestring()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap",
- "Non-bytestring value in the request map.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "Non-bytestring value in the request map.");
return false;
}
base::StringPiece name_str = it.first.GetBytestringAsString();
@@ -140,8 +143,8 @@ bool ParseRequestMap(const cbor::CBORValue& value,
// TODO(kouhei): Add spec ref here once
// https://github.com/WICG/webpackage/issues/161 is resolved.
if (name_str != base::ToLowerASCII(name_str)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Request header name should be lower-cased. header name: %s",
name_str.as_string().c_str()));
@@ -151,26 +154,24 @@ bool ParseRequestMap(const cbor::CBORValue& value,
// 4. If exchange’s headers contain a stateful header field, as defined in
// Section 4.1, return “invalid”. [spec text]
if (IsStatefulRequestHeader(name_str)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Exchange contains stateful request header. header name: %s",
name_str.as_string().c_str()));
return false;
}
}
-
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"), "ParseRequestMap");
return true;
}
bool ParseResponseMap(const cbor::CBORValue& value,
- SignedExchangeHeader* out,
+ SignedExchangeEnvelope* out,
SignedExchangeDevToolsProxy* devtools_proxy) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"), "ParseResponseMap");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), "ParseResponseMap");
if (!value.is_map()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseResponseMap",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Expected request map, got non-map type. Actual type: %d",
static_cast<int>(value.type())));
@@ -182,35 +183,32 @@ bool ParseResponseMap(const cbor::CBORValue& value,
cbor::CBORValue(kStatusKey, cbor::CBORValue::Type::BYTE_STRING));
if (status_iter == response_map.end() ||
!status_iter->second.is_bytestring()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap",
- ":status is not found or not a bytestring.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, ":status is not found or not a bytestring.");
return false;
}
base::StringPiece response_code_str =
status_iter->second.GetBytestringAsString();
int response_code;
if (!base::StringToInt(response_code_str, &response_code)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap",
- "Failed to parse status code to integer.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "Failed to parse status code to integer.");
return false;
}
out->set_response_code(static_cast<net::HttpStatusCode>(response_code));
for (const auto& it : response_map) {
if (!it.first.is_bytestring() || !it.second.is_bytestring()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap",
- "Non-bytestring value in the response map.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "Non-bytestring value in the response map.");
return false;
}
base::StringPiece name_str = it.first.GetBytestringAsString();
if (name_str == kStatusKey)
continue;
if (!net::HttpUtil::IsValidHeaderName(name_str)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseResponseMap",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf("Invalid header name. header_name: %s",
name_str.as_string().c_str()));
return false;
@@ -219,8 +217,8 @@ bool ParseResponseMap(const cbor::CBORValue& value,
// TODO(kouhei): Add spec ref here once
// https://github.com/WICG/webpackage/issues/161 is resolved.
if (name_str != base::ToLowerASCII(name_str)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseResponseMap",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Response header name should be lower-cased. header_name: %s",
name_str.as_string().c_str()));
@@ -230,8 +228,8 @@ bool ParseResponseMap(const cbor::CBORValue& value,
// 4. If exchange’s headers contain a stateful header field, as defined in
// Section 4.1, return “invalid”. [spec text]
if (IsStatefulResponseHeader(name_str)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseResponseMap",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Exchange contains stateful response header. header_name: %s",
name_str.as_string().c_str()));
@@ -240,53 +238,43 @@ bool ParseResponseMap(const cbor::CBORValue& value,
base::StringPiece value_str = it.second.GetBytestringAsString();
if (!net::HttpUtil::IsValidHeaderValue(value_str)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseRequestMap", "Invalid header value.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(devtools_proxy,
+ "Invalid header value.");
return false;
}
if (!out->AddResponseHeader(name_str, value_str)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "ParseResponseMap",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf("Duplicate header value. header_name: %s",
name_str.as_string().c_str()));
return false;
}
}
-
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"), "ParseResponseMap");
return true;
}
} // namespace
-constexpr size_t SignedExchangeHeader::kEncodedLengthInBytes;
-
-// static
-size_t SignedExchangeHeader::ParseEncodedLength(
- base::span<const uint8_t> input) {
- DCHECK_EQ(input.size(), SignedExchangeHeader::kEncodedLengthInBytes);
- return static_cast<size_t>(input[0]) << 16 |
- static_cast<size_t>(input[1]) << 8 | static_cast<size_t>(input[2]);
-}
-
// static
-base::Optional<SignedExchangeHeader> SignedExchangeHeader::Parse(
- base::span<const uint8_t> input,
+base::Optional<SignedExchangeEnvelope> SignedExchangeEnvelope::Parse(
+ base::StringPiece signature_header_field,
+ base::span<const uint8_t> cbor_header,
SignedExchangeDevToolsProxy* devtools_proxy) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHeader::Parse");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeEnvelope::Parse");
cbor::CBORReader::DecoderError error;
- base::Optional<cbor::CBORValue> value = cbor::CBORReader::Read(input, &error);
+ base::Optional<cbor::CBORValue> value =
+ cbor::CBORReader::Read(cbor_header, &error);
if (!value.has_value()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeader::Parse",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf("Failed to decode CBORValue. CBOR error: %s",
cbor::CBORReader::ErrorCodeToString(error)));
return base::nullopt;
}
if (!value->is_array()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeader::Parse",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Expected top-level CBORValue to be an array. Actual type : %d",
static_cast<int>(value->type())));
@@ -296,64 +284,65 @@ base::Optional<SignedExchangeHeader> SignedExchangeHeader::Parse(
const cbor::CBORValue::ArrayValue& top_level_array = value->GetArray();
constexpr size_t kTopLevelArraySize = 2;
if (top_level_array.size() != kTopLevelArraySize) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeader::Parse",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf("Expected top-level array to have 2 elements. "
"Actual element count: %" PRIuS,
top_level_array.size()));
return base::nullopt;
}
- SignedExchangeHeader ret;
+ SignedExchangeEnvelope ret;
if (!ParseRequestMap(top_level_array[0], &ret, devtools_proxy)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeader::Parse",
- "Failed to parse request map.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "Failed to parse request map.");
return base::nullopt;
}
if (!ParseResponseMap(top_level_array[1], &ret, devtools_proxy)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeader::Parse",
- "Failed to parse response map.");
- return base::nullopt;
- }
-
- auto signature_iter = ret.response_headers_.find(kSignature);
- if (signature_iter == ret.response_headers_.end()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeader::Parse",
- "No signature header found.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "Failed to parse response map.");
return base::nullopt;
}
- base::Optional<std::vector<SignedExchangeHeaderParser::Signature>>
- signatures = SignedExchangeHeaderParser::ParseSignature(
- signature_iter->second, devtools_proxy);
+ base::Optional<std::vector<SignedExchangeSignatureHeaderField::Signature>>
+ signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ signature_header_field, devtools_proxy);
if (!signatures || signatures->empty()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeader::Parse",
- "Failed to parse signature.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "Failed to parse signature header field.");
return base::nullopt;
}
+ // TODO(https://crbug.com/850475): Support multiple signatures.
ret.signature_ = (*signatures)[0];
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHeader::Parse");
+ // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#cross-origin-trust
+ // If the signature’s “validity-url” parameter is not same-origin with
+ // exchange’s effective request URI (Section 5.5 of [RFC7230]), return
+ // “invalid” [spec text]
+ const GURL request_url = ret.request_url();
+ const GURL validity_url = ret.signature().validity_url;
+ if (!url::IsSameOriginWith(request_url, validity_url)) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "Validity URL must be same-origin with request URL.");
+ return base::nullopt;
+ }
+
return std::move(ret);
}
-SignedExchangeHeader::SignedExchangeHeader() = default;
-SignedExchangeHeader::SignedExchangeHeader(const SignedExchangeHeader&) =
+SignedExchangeEnvelope::SignedExchangeEnvelope() = default;
+SignedExchangeEnvelope::SignedExchangeEnvelope(const SignedExchangeEnvelope&) =
default;
-SignedExchangeHeader::SignedExchangeHeader(SignedExchangeHeader&&) = default;
-SignedExchangeHeader::~SignedExchangeHeader() = default;
-SignedExchangeHeader& SignedExchangeHeader::operator=(SignedExchangeHeader&&) =
+SignedExchangeEnvelope::SignedExchangeEnvelope(SignedExchangeEnvelope&&) =
default;
+SignedExchangeEnvelope::~SignedExchangeEnvelope() = default;
+SignedExchangeEnvelope& SignedExchangeEnvelope::operator=(
+ SignedExchangeEnvelope&&) = default;
-bool SignedExchangeHeader::AddResponseHeader(base::StringPiece name,
- base::StringPiece value) {
+bool SignedExchangeEnvelope::AddResponseHeader(base::StringPiece name,
+ base::StringPiece value) {
std::string name_str = name.as_string();
DCHECK_EQ(name_str, base::ToLowerASCII(name))
<< "Response header names should be always lower-cased.";
@@ -365,7 +354,7 @@ bool SignedExchangeHeader::AddResponseHeader(base::StringPiece name,
}
scoped_refptr<net::HttpResponseHeaders>
-SignedExchangeHeader::BuildHttpResponseHeaders() const {
+SignedExchangeEnvelope::BuildHttpResponseHeaders() const {
std::string header_str("HTTP/1.1 ");
header_str.append(base::NumberToString(response_code()));
header_str.append(" ");
diff --git a/chromium/content/browser/web_package/signed_exchange_header.h b/chromium/content/browser/web_package/signed_exchange_envelope.h
index e544f17994e..7d865308062 100644
--- a/chromium/content/browser/web_package/signed_exchange_header.h
+++ b/chromium/content/browser/web_package/signed_exchange_envelope.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_WEB_PACKAGE_SIGNED_EXCHANGE_HEADER_H_
-#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_HEADER_H_
+#ifndef CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_ENVELOPE_H_
+#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_ENVELOPE_H_
#include <map>
#include <string>
@@ -13,7 +13,7 @@
#include "base/optional.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
-#include "content/browser/web_package/signed_exchange_header_parser.h"
+#include "content/browser/web_package/signed_exchange_signature_header_field.h"
#include "content/common/content_export.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
@@ -23,32 +23,27 @@ namespace content {
class SignedExchangeDevToolsProxy;
-// SignedExchangeHeader contains all information captured in signed exchange
-// envelope but the payload.
+// SignedExchangeEnvelope contains all information captured in
+// the "application/signed-exchange" format but the payload.
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html
-class CONTENT_EXPORT SignedExchangeHeader {
+class CONTENT_EXPORT SignedExchangeEnvelope {
public:
- static constexpr size_t kEncodedLengthInBytes = 3;
- // Parse encoded length of the variable-length field in the signed exchange.
- // Note: |input| must be pointing to a valid memory address that has at least
- // |kEncodedLengthInBytes|.
- static size_t ParseEncodedLength(base::span<const uint8_t> input);
-
using HeaderMap = std::map<std::string, std::string>;
// Parse headers from the application/signed-exchange;v=b0 format.
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#application-signed-exchange
//
- // This also performs the step 3 and 4 of "Cross-origin trust" validation.
+ // This also performs the step 1, 3 and 4 of "Cross-origin trust" validation.
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#cross-origin-trust
- static base::Optional<SignedExchangeHeader> Parse(
- base::span<const uint8_t> input,
+ static base::Optional<SignedExchangeEnvelope> Parse(
+ base::StringPiece signature_header_field,
+ base::span<const uint8_t> cbor_header,
SignedExchangeDevToolsProxy* devtools_proxy);
- SignedExchangeHeader();
- SignedExchangeHeader(const SignedExchangeHeader&);
- SignedExchangeHeader(SignedExchangeHeader&&);
- SignedExchangeHeader& operator=(SignedExchangeHeader&&);
- ~SignedExchangeHeader();
+ SignedExchangeEnvelope();
+ SignedExchangeEnvelope(const SignedExchangeEnvelope&);
+ SignedExchangeEnvelope(SignedExchangeEnvelope&&);
+ SignedExchangeEnvelope& operator=(SignedExchangeEnvelope&&);
+ ~SignedExchangeEnvelope();
// AddResponseHeader returns false on duplicated keys. |name| must be
// lower-cased.
@@ -68,11 +63,11 @@ class CONTENT_EXPORT SignedExchangeHeader {
const HeaderMap& response_headers() const { return response_headers_; }
- const SignedExchangeHeaderParser::Signature& signature() const {
+ const SignedExchangeSignatureHeaderField::Signature& signature() const {
return signature_;
}
void SetSignatureForTesting(
- const SignedExchangeHeaderParser::Signature& sig) {
+ const SignedExchangeSignatureHeaderField::Signature& sig) {
signature_ = sig;
}
@@ -82,9 +77,9 @@ class CONTENT_EXPORT SignedExchangeHeader {
net::HttpStatusCode response_code_;
HeaderMap response_headers_;
- SignedExchangeHeaderParser::Signature signature_;
+ SignedExchangeSignatureHeaderField::Signature signature_;
};
} // namespace content
-#endif // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_HEADER_H_
+#endif // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_ENVELOPE_H_
diff --git a/chromium/content/browser/web_package/signed_exchange_envelope_unittest.cc b/chromium/content/browser/web_package/signed_exchange_envelope_unittest.cc
new file mode 100644
index 00000000000..021d7fef021
--- /dev/null
+++ b/chromium/content/browser/web_package/signed_exchange_envelope_unittest.cc
@@ -0,0 +1,230 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_package/signed_exchange_envelope.h"
+
+#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "components/cbor/cbor_values.h"
+#include "components/cbor/cbor_writer.h"
+#include "content/browser/web_package/signed_exchange_consts.h"
+#include "content/browser/web_package/signed_exchange_prologue.h"
+#include "content/public/common/content_paths.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+namespace {
+
+const char kSignatureString[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https://test.example.org/resource.validity.1511128380\";"
+ " cert-url=\"https://example.com/oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+
+cbor::CBORValue CBORByteString(const char* str) {
+ return cbor::CBORValue(str, cbor::CBORValue::Type::BYTE_STRING);
+}
+
+base::Optional<SignedExchangeEnvelope> GenerateHeaderAndParse(
+ base::StringPiece signature,
+ const std::map<const char*, const char*>& request_map,
+ const std::map<const char*, const char*>& response_map) {
+ cbor::CBORValue::MapValue request_cbor_map;
+ cbor::CBORValue::MapValue response_cbor_map;
+ for (auto& pair : request_map)
+ request_cbor_map[CBORByteString(pair.first)] = CBORByteString(pair.second);
+ for (auto& pair : response_map)
+ response_cbor_map[CBORByteString(pair.first)] = CBORByteString(pair.second);
+
+ cbor::CBORValue::ArrayValue array;
+ array.push_back(cbor::CBORValue(std::move(request_cbor_map)));
+ array.push_back(cbor::CBORValue(std::move(response_cbor_map)));
+
+ auto serialized = cbor::CBORWriter::Write(cbor::CBORValue(std::move(array)));
+ return SignedExchangeEnvelope::Parse(
+ signature, base::make_span(serialized->data(), serialized->size()),
+ nullptr /* devtools_proxy */);
+}
+
+} // namespace
+
+TEST(SignedExchangeEnvelopeTest, ParseGoldenFile) {
+ base::FilePath test_sxg_path;
+ base::PathService::Get(content::DIR_TEST_DATA, &test_sxg_path);
+ test_sxg_path =
+ test_sxg_path.AppendASCII("sxg").AppendASCII("test.example.org_test.sxg");
+
+ std::string contents;
+ ASSERT_TRUE(base::ReadFileToString(test_sxg_path, &contents));
+ auto* contents_bytes = reinterpret_cast<const uint8_t*>(contents.data());
+
+ ASSERT_GT(contents.size(), SignedExchangePrologue::kEncodedPrologueInBytes);
+ base::Optional<SignedExchangePrologue> prologue =
+ SignedExchangePrologue::Parse(
+ base::make_span(contents_bytes,
+ SignedExchangePrologue::kEncodedPrologueInBytes),
+ nullptr /* devtools_proxy */);
+ ASSERT_TRUE(prologue.has_value());
+ ASSERT_GT(contents.size(), SignedExchangePrologue::kEncodedPrologueInBytes +
+ prologue->ComputeFollowingSectionsLength());
+
+ base::StringPiece signature_header_field(
+ contents.data() + SignedExchangePrologue::kEncodedPrologueInBytes,
+ prologue->signature_header_field_length());
+ const auto cbor_bytes = base::make_span<const uint8_t>(
+ contents_bytes + SignedExchangePrologue::kEncodedPrologueInBytes +
+ prologue->signature_header_field_length(),
+ prologue->cbor_header_length());
+ const base::Optional<SignedExchangeEnvelope> envelope =
+ SignedExchangeEnvelope::Parse(signature_header_field, cbor_bytes,
+ nullptr /* devtools_proxy */);
+ ASSERT_TRUE(envelope.has_value());
+ EXPECT_EQ(envelope->request_url(), GURL("https://test.example.org/test/"));
+ EXPECT_EQ(envelope->request_method(), "GET");
+ EXPECT_EQ(envelope->response_code(), static_cast<net::HttpStatusCode>(200u));
+ EXPECT_EQ(envelope->response_headers().size(), 3u);
+ EXPECT_EQ(envelope->response_headers().find("content-encoding")->second,
+ "mi-sha256-draft2");
+}
+
+TEST(SignedExchangeEnvelopeTest, ValidHeader) {
+ auto header = GenerateHeaderAndParse(
+ kSignatureString,
+ {
+ {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "GET"},
+ },
+ {{kStatusKey, "200"}, {"content-type", "text/html"}});
+ ASSERT_TRUE(header.has_value());
+ EXPECT_EQ(header->request_url(), GURL("https://test.example.org/test/"));
+ EXPECT_EQ(header->request_method(), "GET");
+ EXPECT_EQ(header->response_code(), static_cast<net::HttpStatusCode>(200u));
+ EXPECT_EQ(header->response_headers().size(), 1u);
+}
+
+TEST(SignedExchangeEnvelopeTest, UnsafeMethod) {
+ auto header = GenerateHeaderAndParse(
+ kSignatureString,
+ {
+ {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "POST"},
+ },
+ {
+ {kStatusKey, "200"},
+ });
+ ASSERT_FALSE(header.has_value());
+}
+
+TEST(SignedExchangeEnvelopeTest, InvalidURL) {
+ auto header = GenerateHeaderAndParse(
+ kSignatureString,
+ {
+ {kUrlKey, "https:://test.example.org/test/"}, {kMethodKey, "GET"},
+ },
+ {
+ {kStatusKey, "200"},
+ });
+ ASSERT_FALSE(header.has_value());
+}
+
+TEST(SignedExchangeEnvelopeTest, URLWithFragment) {
+ auto header = GenerateHeaderAndParse(
+ kSignatureString,
+ {
+ {kUrlKey, "https://test.example.org/test/#foo"}, {kMethodKey, "GET"},
+ },
+ {
+ {kStatusKey, "200"},
+ });
+ ASSERT_FALSE(header.has_value());
+}
+
+TEST(SignedExchangeEnvelopeTest, RelativeURL) {
+ auto header =
+ GenerateHeaderAndParse(kSignatureString,
+ {
+ {kUrlKey, "test/"}, {kMethodKey, "GET"},
+ },
+ {
+ {kStatusKey, "200"},
+ });
+ ASSERT_FALSE(header.has_value());
+}
+
+TEST(SignedExchangeEnvelopeTest, HttpURLShouldFail) {
+ auto header = GenerateHeaderAndParse(
+ kSignatureString,
+ {
+ {kUrlKey, "http://test.example.org/test/"}, {kMethodKey, "GET"},
+ },
+ {
+ {kStatusKey, "200"},
+ });
+ ASSERT_FALSE(header.has_value());
+}
+
+TEST(SignedExchangeEnvelopeTest, StatefulRequestHeader) {
+ auto header =
+ GenerateHeaderAndParse(kSignatureString,
+ {
+ {kUrlKey, "https://test.example.org/test/"},
+ {kMethodKey, "GET"},
+ {"authorization", "Basic Zm9vOmJhcg=="},
+ },
+ {
+ {kStatusKey, "200"},
+ });
+ ASSERT_FALSE(header.has_value());
+}
+
+TEST(SignedExchangeEnvelopeTest, StatefulResponseHeader) {
+ auto header = GenerateHeaderAndParse(
+ kSignatureString,
+ {
+ {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "GET"},
+ },
+ {
+ {kStatusKey, "200"}, {"set-cookie", "foo=bar"},
+ });
+ ASSERT_FALSE(header.has_value());
+}
+
+TEST(SignedExchangeEnvelopeTest, UppercaseRequestMap) {
+ auto header =
+ GenerateHeaderAndParse(kSignatureString,
+ {{kUrlKey, "https://test.example.org/test/"},
+ {kMethodKey, "GET"},
+ {"Accept-Language", "en-us"}},
+ {
+ {kStatusKey, "200"},
+ });
+ ASSERT_FALSE(header.has_value());
+}
+
+TEST(SignedExchangeEnvelopeTest, UppercaseResponseMap) {
+ auto header = GenerateHeaderAndParse(
+ kSignatureString,
+ {
+ {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "GET"},
+ },
+ {{kStatusKey, "200"}, {"Content-Length", "123"}});
+ ASSERT_FALSE(header.has_value());
+}
+
+TEST(SignedExchangeEnvelopeTest, InvalidValidityURLHeader) {
+ auto header = GenerateHeaderAndParse(
+ kSignatureString,
+ {
+ {kUrlKey, "https://test2.example.org/test/"}, {kMethodKey, "GET"},
+ },
+ {{kStatusKey, "200"}, {"content-type", "text/html"}});
+ ASSERT_FALSE(header.has_value());
+}
+
+} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_error.cc b/chromium/content/browser/web_package/signed_exchange_error.cc
new file mode 100644
index 00000000000..c9c914856b7
--- /dev/null
+++ b/chromium/content/browser/web_package/signed_exchange_error.cc
@@ -0,0 +1,48 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_package/signed_exchange_error.h"
+
+namespace content {
+
+// static
+base::Optional<SignedExchangeError::Field>
+SignedExchangeError::GetFieldFromSignatureVerifierResult(
+ SignedExchangeSignatureVerifier::Result verify_result) {
+ switch (verify_result) {
+ case SignedExchangeSignatureVerifier::Result::kSuccess:
+ return base::nullopt;
+ case SignedExchangeSignatureVerifier::Result::kErrNoCertificate:
+ return base::nullopt;
+ case SignedExchangeSignatureVerifier::Result::kErrNoCertificateSHA256:
+ return Field::kSignatureCertSha256;
+ case SignedExchangeSignatureVerifier::Result::kErrCertificateSHA256Mismatch:
+ return Field::kSignatureCertSha256;
+ case SignedExchangeSignatureVerifier::Result::kErrInvalidSignatureFormat:
+ return base::nullopt;
+ case SignedExchangeSignatureVerifier::Result::
+ kErrSignatureVerificationFailed:
+ return Field::kSignatureSig;
+ case SignedExchangeSignatureVerifier::Result::kErrInvalidSignatureIntegrity:
+ return Field::kSignatureIintegrity;
+ case SignedExchangeSignatureVerifier::Result::kErrInvalidTimestamp:
+ return Field::kSignatureTimestamps;
+ case SignedExchangeSignatureVerifier::Result::kErrUnsupportedCertType:
+ return Field::kSignatureCertUrl;
+ }
+
+ NOTREACHED();
+ return base::nullopt;
+}
+
+SignedExchangeError::SignedExchangeError(const std::string& message,
+ base::Optional<FieldIndexPair> field)
+ : message(message), field(field) {}
+
+SignedExchangeError::SignedExchangeError(const SignedExchangeError& other) =
+ default;
+SignedExchangeError::SignedExchangeError(SignedExchangeError&& other) = default;
+SignedExchangeError::~SignedExchangeError() = default;
+
+} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_error.h b/chromium/content/browser/web_package/signed_exchange_error.h
new file mode 100644
index 00000000000..50856c66d4b
--- /dev/null
+++ b/chromium/content/browser/web_package/signed_exchange_error.h
@@ -0,0 +1,50 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_ERROR_H_
+#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_ERROR_H_
+
+#include <string>
+#include <utility>
+
+#include "base/optional.h"
+#include "content/browser/web_package/signed_exchange_signature_verifier.h"
+
+namespace content {
+
+struct SignedExchangeError {
+ public:
+ enum class Field {
+ kSignatureSig,
+ kSignatureIintegrity,
+ kSignatureCertUrl,
+ kSignatureCertSha256,
+ kSignatureValidityUrl,
+ kSignatureTimestamps,
+ };
+
+ // |signature_index| will be used when we will support multiple signatures in
+ // a signed exchange header to indicate which signature is causing the error.
+ using FieldIndexPair = std::pair<int /* signature_index */, Field>;
+
+ static base::Optional<Field> GetFieldFromSignatureVerifierResult(
+ SignedExchangeSignatureVerifier::Result verify_result);
+
+ SignedExchangeError(const std::string& message,
+ base::Optional<FieldIndexPair> field);
+
+ // Copy constructor.
+ SignedExchangeError(const SignedExchangeError& other);
+ // Move constructor.
+ SignedExchangeError(SignedExchangeError&& other);
+
+ ~SignedExchangeError();
+
+ std::string message;
+ base::Optional<FieldIndexPair> field;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_ERROR_H_
diff --git a/chromium/content/browser/web_package/signed_exchange_handler.cc b/chromium/content/browser/web_package/signed_exchange_handler.cc
index 52e127a28e9..b068987cc1f 100644
--- a/chromium/content/browser/web_package/signed_exchange_handler.cc
+++ b/chromium/content/browser/web_package/signed_exchange_handler.cc
@@ -11,20 +11,28 @@
#include "content/browser/web_package/signed_exchange_cert_fetcher_factory.h"
#include "content/browser/web_package/signed_exchange_certificate_chain.h"
#include "content/browser/web_package/signed_exchange_devtools_proxy.h"
-#include "content/browser/web_package/signed_exchange_header.h"
+#include "content/browser/web_package/signed_exchange_envelope.h"
+#include "content/browser/web_package/signed_exchange_prologue.h"
#include "content/browser/web_package/signed_exchange_signature_verifier.h"
#include "content/browser/web_package/signed_exchange_utils.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/url_loader_throttle.h"
#include "mojo/public/cpp/system/string_data_pipe_producer.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
+#include "net/cert/asn1_util.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
+#include "net/cert/ct_policy_enforcer.h"
+#include "net/cert/ct_verifier.h"
#include "net/cert/x509_certificate.h"
+#include "net/cert/x509_util.h"
#include "net/filter/source_stream.h"
+#include "net/http/transport_security_state.h"
#include "net/ssl/ssl_config.h"
#include "net/ssl/ssl_config_service.h"
#include "net/ssl/ssl_info.h"
@@ -39,11 +47,7 @@ namespace content {
namespace {
-// 256KB (Maximum header size) * 2, since signed exchange header contains
-// request and response headers.
-constexpr size_t kMaxHeadersCBORLength = 512 * 1024;
-
-constexpr char kMiHeader[] = "MI";
+constexpr char kMiHeader[] = "MI-Draft2";
net::CertVerifier* g_cert_verifier_for_testing = nullptr;
@@ -74,11 +78,13 @@ SignedExchangeHandler::SignedExchangeHandler(
std::unique_ptr<net::SourceStream> body,
ExchangeHeadersCallback headers_callback,
std::unique_ptr<SignedExchangeCertFetcherFactory> cert_fetcher_factory,
+ int load_flags,
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
std::unique_ptr<SignedExchangeDevToolsProxy> devtools_proxy)
: headers_callback_(std::move(headers_callback)),
source_(std::move(body)),
cert_fetcher_factory_(std::move(cert_fetcher_factory)),
+ load_flags_(load_flags),
request_context_getter_(std::move(request_context_getter)),
net_log_(net::NetLogWithSource::Make(
request_context_getter_->GetURLRequestContext()->net_log(),
@@ -86,39 +92,37 @@ SignedExchangeHandler::SignedExchangeHandler(
devtools_proxy_(std::move(devtools_proxy)),
weak_factory_(this) {
DCHECK(signed_exchange_utils::IsSignedExchangeHandlingEnabled());
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::SignedExchangeHandler");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeHandler::SignedExchangeHandler");
- if (!SignedExchangeHeaderParser::GetVersionParamFromContentType(content_type,
- &version_) ||
- (version_ != SignedExchangeVersion::kB0 &&
- version_ != SignedExchangeVersion::kB1)) {
+ if (!SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
+ content_type, &version_) ||
+ version_ != SignedExchangeVersion::kB1) {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&SignedExchangeHandler::RunErrorCallback,
weak_factory_.GetWeakPtr(),
net::ERR_INVALID_SIGNED_EXCHANGE));
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_.get(), "SignedExchangeHandler::SignedExchangeHandler",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(),
base::StringPrintf("Unsupported version of the content type. Currentry "
"content type must be "
- "\"application/signed-exchange;v={b0,b1}\". But the "
+ "\"application/signed-exchange;v=b1\". But the "
"response content type was \"%s\"",
content_type.c_str()));
return;
}
- // Triggering the read (asynchronously) for the encoded header length.
- SetupBuffers(SignedExchangeHeader::kEncodedLengthInBytes);
+ // Triggering the read (asynchronously) for the prologue bytes.
+ SetupBuffers(SignedExchangePrologue::kEncodedPrologueInBytes);
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&SignedExchangeHandler::DoHeaderLoop,
weak_factory_.GetWeakPtr()));
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::SignedExchangeHandler");
}
SignedExchangeHandler::~SignedExchangeHandler() = default;
-SignedExchangeHandler::SignedExchangeHandler() : weak_factory_(this) {}
+SignedExchangeHandler::SignedExchangeHandler()
+ : load_flags_(net::LOAD_NORMAL), weak_factory_(this) {}
void SignedExchangeHandler::SetupBuffers(size_t size) {
header_buf_ = base::MakeRefCounted<net::IOBuffer>(size);
@@ -127,8 +131,7 @@ void SignedExchangeHandler::SetupBuffers(size_t size) {
}
void SignedExchangeHandler::DoHeaderLoop() {
- DCHECK(state_ == State::kReadingHeadersLength ||
- state_ == State::kReadingHeaders);
+ DCHECK(state_ == State::kReadingPrologue || state_ == State::kReadingHeaders);
int rv = source_->Read(
header_read_buf_.get(), header_read_buf_->BytesRemaining(),
base::BindRepeating(&SignedExchangeHandler::DidReadHeader,
@@ -138,19 +141,21 @@ void SignedExchangeHandler::DoHeaderLoop() {
}
void SignedExchangeHandler::DidReadHeader(bool completed_syncly, int result) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::DidReadHeader");
+ DCHECK(state_ == State::kReadingPrologue || state_ == State::kReadingHeaders);
+
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeHandler::DidReadHeader");
if (result < 0) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_.get(), "SignedExchangeHandler::DidReadHeader",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(),
base::StringPrintf("Error reading body stream. result: %d", result));
RunErrorCallback(static_cast<net::Error>(result));
return;
}
if (result == 0) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_.get(), "SignedExchangeHandler::DidReadHeader",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(),
"Stream ended while reading signed exchange header.");
RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
return;
@@ -159,28 +164,29 @@ void SignedExchangeHandler::DidReadHeader(bool completed_syncly, int result) {
header_read_buf_->DidConsume(result);
if (header_read_buf_->BytesRemaining() == 0) {
switch (state_) {
- case State::kReadingHeadersLength:
- if (!ParseHeadersLength())
+ case State::kReadingPrologue:
+ if (!ParsePrologue()) {
RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
+ return;
+ }
break;
case State::kReadingHeaders:
- if (!ParseHeadersAndFetchCertificate())
+ if (!ParseHeadersAndFetchCertificate()) {
RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
+ return;
+ }
break;
default:
NOTREACHED();
}
}
- if (state_ != State::kReadingHeadersLength &&
- state_ != State::kReadingHeaders) {
- TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::DidReadHeader", "state",
- static_cast<int>(state_));
+ // We have finished reading headers, so return without queueing the next read.
+ if (state_ == State::kFetchingCertificate)
return;
- }
// Trigger the next read.
+ DCHECK(state_ == State::kReadingPrologue || state_ == State::kReadingHeaders);
if (completed_syncly) {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&SignedExchangeHandler::DoHeaderLoop,
@@ -188,76 +194,75 @@ void SignedExchangeHandler::DidReadHeader(bool completed_syncly, int result) {
} else {
DoHeaderLoop();
}
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::DidReadHeader");
}
-bool SignedExchangeHandler::ParseHeadersLength() {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::ParseEncodedLength");
- DCHECK_EQ(state_, State::kReadingHeadersLength);
+bool SignedExchangeHandler::ParsePrologue() {
+ DCHECK_EQ(state_, State::kReadingPrologue);
- headers_length_ = SignedExchangeHeader::ParseEncodedLength(
+ prologue_ = SignedExchangePrologue::Parse(
base::make_span(reinterpret_cast<uint8_t*>(header_buf_->data()),
- SignedExchangeHeader::kEncodedLengthInBytes));
- if (headers_length_ == 0 || headers_length_ > kMaxHeadersCBORLength) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_.get(), "SignedExchangeHandler::ParseEncodedLength",
- base::StringPrintf("Invalid CBOR header length: %zu", headers_length_));
+ SignedExchangePrologue::kEncodedPrologueInBytes),
+ devtools_proxy_.get());
+ if (!prologue_)
return false;
- }
- // Set up a new buffer for CBOR-encoded buffer reading.
- SetupBuffers(headers_length_);
+ // Set up a new buffer for Signature + CBOR-encoded header reading.
+ SetupBuffers(prologue_->ComputeFollowingSectionsLength());
state_ = State::kReadingHeaders;
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::ParseEncodedLength");
return true;
}
bool SignedExchangeHandler::ParseHeadersAndFetchCertificate() {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::ParseHeadersAndFetchCertificate");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeHandler::ParseHeadersAndFetchCertificate");
DCHECK_EQ(state_, State::kReadingHeaders);
- header_ = SignedExchangeHeader::Parse(
- base::make_span(reinterpret_cast<uint8_t*>(header_buf_->data()),
- headers_length_),
- devtools_proxy_.get());
+ base::StringPiece data(header_buf_->data(), header_read_buf_->size());
+ base::StringPiece signature_header_field =
+ data.substr(0, prologue_->signature_header_field_length());
+ base::span<const uint8_t> cbor_header = base::as_bytes(
+ base::make_span(data.substr(prologue_->signature_header_field_length(),
+ prologue_->cbor_header_length())));
+ envelope_ = SignedExchangeEnvelope::Parse(signature_header_field, cbor_header,
+ devtools_proxy_.get());
header_read_buf_ = nullptr;
header_buf_ = nullptr;
- if (!header_) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_.get(),
- "SignedExchangeHandler::ParseHeadersAndFetchCertificate",
- "Failed to parse SignedExchange header.");
+ if (!envelope_) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(), "Failed to parse SignedExchange header.");
return false;
}
- const GURL cert_url = header_->signature().cert_url;
+ const GURL cert_url = envelope_->signature().cert_url;
// TODO(https://crbug.com/819467): When we will support ed25519Key, |cert_url|
// may be empty.
DCHECK(cert_url.is_valid());
DCHECK(version_.has_value());
DCHECK(cert_fetcher_factory_);
+
+ const bool force_fetch = load_flags_ & net::LOAD_BYPASS_CACHE;
+
cert_fetcher_ = std::move(cert_fetcher_factory_)
->CreateFetcherAndStart(
- cert_url, false, *version_,
+ cert_url, force_fetch, *version_,
base::BindOnce(&SignedExchangeHandler::OnCertReceived,
base::Unretained(this)),
devtools_proxy_.get());
state_ = State::kFetchingCertificate;
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::ParseHeadersAndFetchCertificate");
return true;
}
void SignedExchangeHandler::RunErrorCallback(net::Error error) {
DCHECK_NE(state_, State::kHeadersCallbackCalled);
- if (devtools_proxy_)
- devtools_proxy_->OnSignedExchangeReceived(header_, nullptr);
+ if (devtools_proxy_) {
+ devtools_proxy_->OnSignedExchangeReceived(
+ envelope_,
+ unverified_cert_chain_ ? unverified_cert_chain_->cert()
+ : scoped_refptr<net::X509Certificate>(),
+ nullptr);
+ }
std::move(headers_callback_)
.Run(error, GURL(), std::string(), network::ResourceResponseHead(),
nullptr);
@@ -266,39 +271,48 @@ void SignedExchangeHandler::RunErrorCallback(net::Error error) {
void SignedExchangeHandler::OnCertReceived(
std::unique_ptr<SignedExchangeCertificateChain> cert_chain) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::OnCertReceived");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeHandler::OnCertReceived");
DCHECK_EQ(state_, State::kFetchingCertificate);
if (!cert_chain) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_.get(), "SignedExchangeHandler::OnCertReceived",
- "Failed to fetch the certificate.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(), "Failed to fetch the certificate.",
+ std::make_pair(0 /* signature_index */,
+ SignedExchangeError::Field::kSignatureCertUrl));
RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
- if (SignedExchangeSignatureVerifier::Verify(*header_, cert_chain->cert(),
- GetVerificationTime(),
- devtools_proxy_.get()) !=
- SignedExchangeSignatureVerifier::Result::kSuccess) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_.get(), "SignedExchangeHandler::OnCertReceived",
- "Failed to verify the signed exchange header.");
+ unverified_cert_chain_ = std::move(cert_chain);
+
+ const SignedExchangeSignatureVerifier::Result verify_result =
+ SignedExchangeSignatureVerifier::Verify(
+ *envelope_, unverified_cert_chain_->cert(), GetVerificationTime(),
+ devtools_proxy_.get());
+ if (verify_result != SignedExchangeSignatureVerifier::Result::kSuccess) {
+ base::Optional<SignedExchangeError::Field> error_field =
+ SignedExchangeError::GetFieldFromSignatureVerifierResult(verify_result);
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(), "Failed to verify the signed exchange header.",
+ error_field ? base::make_optional(
+ std::make_pair(0 /* signature_index */, *error_field))
+ : base::nullopt);
RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
+
+ // TODO(https://crbug.com/849935): The code below reaching into
+ // URLRequestContext will not work with Network service.
+ DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
net::URLRequestContext* request_context =
request_context_getter_->GetURLRequestContext();
if (!request_context) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_.get(), "SignedExchangeHandler::OnCertReceived",
- "No request context available.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(), "No request context available.");
RunErrorCallback(net::ERR_CONTEXT_SHUT_DOWN);
return;
}
- unverified_cert_chain_ = std::move(cert_chain);
-
net::SSLConfig config;
request_context->ssl_config_service()->GetSSLConfig(&config);
@@ -307,7 +321,7 @@ void SignedExchangeHandler::OnCertReceived(
: request_context->cert_verifier();
int result = cert_verifier->Verify(
net::CertVerifier::RequestParams(
- unverified_cert_chain_->cert(), header_->request_url().host(),
+ unverified_cert_chain_->cert(), envelope_->request_url().host(),
config.GetCertVerifyFlags(), unverified_cert_chain_->ocsp(),
net::CertificateList()),
net::SSLConfigService::GetCRLSet().get(), &cert_verify_result_,
@@ -318,9 +332,19 @@ void SignedExchangeHandler::OnCertReceived(
// explicit state machines (eg: DoLoop() in //net).
if (result != net::ERR_IO_PENDING)
OnCertVerifyComplete(result);
+}
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::OnCertReceived");
+bool SignedExchangeHandler::CheckCertExtension(
+ const net::X509Certificate* verified_cert) {
+ if (base::FeatureList::IsEnabled(
+ features::kAllowSignedHTTPExchangeCertsWithoutExtension))
+ return true;
+
+ // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#cross-origin-trust
+ // Step 6.2. Validate that main-certificate has the CanSignHttpExchanges
+ // extension (Section 4.2). [spec text]
+ return net::asn1::HasCanSignHttpExchangesDraftExtension(
+ net::x509_util::CryptoBufferAsStringPiece(verified_cert->cert_buffer()));
}
bool SignedExchangeHandler::CheckOCSPStatus(
@@ -333,10 +357,6 @@ bool SignedExchangeHandler::CheckOCSPStatus(
// OCSP verification is done in CertVerifier::Verify(), so we just check the
// result here.
- // The b0 implementation checkpoint has no OCSP check.
- if (version_ == SignedExchangeVersion::kB0)
- return true;
-
if (ocsp_result.response_status != net::OCSPVerifyResult::PROVIDED ||
ocsp_result.revocation_status != net::OCSPRevocationStatus::GOOD)
return false;
@@ -344,32 +364,150 @@ bool SignedExchangeHandler::CheckOCSPStatus(
return true;
}
+// TODO(https://crbug.com/815025, https://crbug.com/849935): This is temporary
+// code until we have Network Service friendly CT verification.
+int SignedExchangeHandler::VerifyCT(net::ct::CTVerifyResult* ct_verify_result) {
+ // This function will not work with Network Service.
+ DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
+
+ net::URLRequestContext* request_context =
+ request_context_getter_->GetURLRequestContext();
+ if (!request_context)
+ return net::ERR_CONTEXT_SHUT_DOWN;
+
+ // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#cross-origin-trust
+ // Step 6.4 Validate that valid SCTs from trusted logs are available from any
+ // of:
+ // - The SignedCertificateTimestampList in main-certificate’s sct property
+ // (Section 3.3),
+ const std::string& sct_list_from_cert_cbor = unverified_cert_chain_->sct();
+ // - An OCSP extension in the OCSP response in main-certificate’s ocsp
+ // property, or
+ const std::string& stapled_ocsp_response = unverified_cert_chain_->ocsp();
+ // - An X.509 extension in the certificate in main-certificate’s cert
+ // property,
+ net::X509Certificate* verified_cert = cert_verify_result_.verified_cert.get();
+ // as described by Section 3.3 of [RFC6962]. [spec text]
+ request_context->cert_transparency_verifier()->Verify(
+ envelope_->request_url().host(), verified_cert, stapled_ocsp_response,
+ sct_list_from_cert_cbor, &ct_verify_result->scts, net_log_);
+
+ net::ct::SCTList verified_scts = net::ct::SCTsMatchingStatus(
+ ct_verify_result->scts, net::ct::SCT_STATUS_OK);
+
+ ct_verify_result->policy_compliance =
+ request_context->ct_policy_enforcer()->CheckCompliance(
+ verified_cert, verified_scts, net_log_);
+
+ // TODO(https://crbug.com/803774): We should determine whether EV & SXG
+ // should be a thing (due to the online/offline signing difference)
+ if (cert_verify_result_.cert_status & net::CERT_STATUS_IS_EV &&
+ ct_verify_result->policy_compliance !=
+ net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS &&
+ ct_verify_result->policy_compliance !=
+ net::ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY) {
+ cert_verify_result_.cert_status |= net::CERT_STATUS_CT_COMPLIANCE_FAILED;
+ cert_verify_result_.cert_status &= ~net::CERT_STATUS_IS_EV;
+ }
+
+ net::TransportSecurityState::CTRequirementsStatus ct_requirement_status =
+ request_context->transport_security_state()->CheckCTRequirements(
+ net::HostPortPair::FromURL(envelope_->request_url()),
+ cert_verify_result_.is_issued_by_known_root,
+ cert_verify_result_.public_key_hashes, verified_cert,
+ unverified_cert_chain_->cert().get(), ct_verify_result->scts,
+ net::TransportSecurityState::ENABLE_EXPECT_CT_REPORTS,
+ ct_verify_result->policy_compliance);
+
+ switch (ct_requirement_status) {
+ case net::TransportSecurityState::CT_REQUIREMENTS_NOT_MET:
+ return net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED;
+ case net::TransportSecurityState::CT_REQUIREMENTS_MET:
+ ct_verify_result->policy_compliance_required = true;
+ break;
+ case net::TransportSecurityState::CT_NOT_REQUIRED:
+ // CT is not required if the certificate does not chain to a publicly
+ // trusted root certificate.
+ if (!cert_verify_result_.is_issued_by_known_root) {
+ ct_verify_result->policy_compliance_required = false;
+ break;
+ }
+ // For old certificates (issued before 2018-05-01), CheckCTRequirements()
+ // may return CT_NOT_REQUIRED, so we check the compliance status here.
+ // TODO(https://crbug.com/851778): Remove this condition once we require
+ // signing certificates to have CanSignHttpExchanges extension, because
+ // such certificates should be naturally after 2018-05-01.
+ if (ct_verify_result->policy_compliance ==
+ net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS ||
+ ct_verify_result->policy_compliance ==
+ net::ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY) {
+ ct_verify_result->policy_compliance_required = true;
+ break;
+ }
+ // Require CT compliance, by overriding CT_NOT_REQUIRED and treat it as
+ // ERR_CERTIFICATE_TRANSPARENCY_REQUIRED.
+ return net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED;
+ }
+ return net::OK;
+}
+
void SignedExchangeHandler::OnCertVerifyComplete(int result) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::OnCertVerifyComplete");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeHandler::OnCertVerifyComplete");
if (result != net::OK) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_.get(), "SignedExchangeHandler::OnCertVerifyComplete",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(),
base::StringPrintf("Certificate verification error: %s",
- net::ErrorToShortString(result).c_str()));
+ net::ErrorToShortString(result).c_str()),
+ std::make_pair(0 /* signature_index */,
+ SignedExchangeError::Field::kSignatureCertUrl));
+ RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
+ return;
+ }
+
+ if (!CheckCertExtension(cert_verify_result_.verified_cert.get())) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(),
+ "Certificate must have CanSignHttpExchangesDraft extension. To ignore "
+ "this error for testing, enable "
+ "chrome://flags/#allow-sxg-certs-without-extension.",
+ std::make_pair(0 /* signature_index */,
+ SignedExchangeError::Field::kSignatureCertUrl));
RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
if (!CheckOCSPStatus(cert_verify_result_.ocsp_result)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_.get(), "SignedExchangeHandler::OnCertVerifyComplete",
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(),
base::StringPrintf(
"OCSP check failed. response status: %d, revocation status: %d",
cert_verify_result_.ocsp_result.response_status,
- cert_verify_result_.ocsp_result.revocation_status));
- RunErrorCallback(static_cast<net::Error>(net::ERR_FAILED));
+ cert_verify_result_.ocsp_result.revocation_status),
+ std::make_pair(0 /* signature_index */,
+ SignedExchangeError::Field::kSignatureCertUrl));
+ RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
+ return;
+ }
+
+ net::ct::CTVerifyResult ct_verify_result;
+ int ct_result = VerifyCT(&ct_verify_result);
+ if (ct_result != net::OK) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(),
+ base::StringPrintf(
+ "CT verification failed. result: %s, policy compliance: %d",
+ net::ErrorToShortString(ct_result).c_str(),
+ ct_verify_result.policy_compliance),
+ std::make_pair(0 /* signature_index */,
+ SignedExchangeError::Field::kSignatureCertUrl));
+ RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
network::ResourceResponseHead response_head;
- response_head.headers = header_->BuildHttpResponseHeaders();
+ response_head.headers = envelope_->BuildHttpResponseHeaders();
response_head.headers->GetMimeTypeAndCharset(&response_head.mime_type,
&response_head.charset);
@@ -385,9 +523,8 @@ void SignedExchangeHandler::OnCertVerifyComplete(int result) {
std::string mi_header_value;
if (!response_head.headers->EnumerateHeader(nullptr, kMiHeader,
&mi_header_value)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy_.get(), "SignedExchangeHandler::OnCertVerifyComplete",
- "Signed exchange has no MI: header");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy_.get(), "Signed exchange has no MI-Draft2: header");
RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
return;
}
@@ -405,18 +542,18 @@ void SignedExchangeHandler::OnCertVerifyComplete(int result) {
ssl_info.is_fatal_cert_error =
net::IsCertStatusError(ssl_info.cert_status) &&
!net::IsCertStatusMinorError(ssl_info.cert_status);
+ ssl_info.UpdateCertificateTransparencyInfo(ct_verify_result);
- if (devtools_proxy_)
- devtools_proxy_->OnSignedExchangeReceived(header_, &ssl_info);
+ if (devtools_proxy_) {
+ devtools_proxy_->OnSignedExchangeReceived(
+ envelope_, unverified_cert_chain_->cert(), &ssl_info);
+ }
response_head.ssl_info = std::move(ssl_info);
- // TODO(https://crbug.com/815025): Verify the Certificate Transparency status.
std::move(headers_callback_)
- .Run(net::OK, header_->request_url(), header_->request_method(),
+ .Run(net::OK, envelope_->request_url(), envelope_->request_method(),
response_head, std::move(mi_stream));
state_ = State::kHeadersCallbackCalled;
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHandler::OnCertVerifyComplete");
}
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_handler.h b/chromium/content/browser/web_package/signed_exchange_handler.h
index d1df8d39d5b..b2ded77ac04 100644
--- a/chromium/content/browser/web_package/signed_exchange_handler.h
+++ b/chromium/content/browser/web_package/signed_exchange_handler.h
@@ -11,7 +11,8 @@
#include "base/optional.h"
#include "base/time/time.h"
#include "content/browser/web_package/signed_exchange_consts.h"
-#include "content/browser/web_package/signed_exchange_header.h"
+#include "content/browser/web_package/signed_exchange_envelope.h"
+#include "content/browser/web_package/signed_exchange_prologue.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/completion_callback.h"
@@ -71,6 +72,7 @@ class CONTENT_EXPORT SignedExchangeHandler {
std::unique_ptr<net::SourceStream> body,
ExchangeHeadersCallback headers_callback,
std::unique_ptr<SignedExchangeCertFetcherFactory> cert_fetcher_factory,
+ int load_flags,
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
std::unique_ptr<SignedExchangeDevToolsProxy> devtools_proxy);
~SignedExchangeHandler();
@@ -80,7 +82,7 @@ class CONTENT_EXPORT SignedExchangeHandler {
private:
enum class State {
- kReadingHeadersLength,
+ kReadingPrologue,
kReadingHeaders,
kFetchingCertificate,
kHeadersCallbackCalled,
@@ -89,30 +91,32 @@ class CONTENT_EXPORT SignedExchangeHandler {
void SetupBuffers(size_t size);
void DoHeaderLoop();
void DidReadHeader(bool completed_syncly, int result);
- bool ParseHeadersLength();
+ bool ParsePrologue();
bool ParseHeadersAndFetchCertificate();
void RunErrorCallback(net::Error);
void OnCertReceived(
std::unique_ptr<SignedExchangeCertificateChain> cert_chain);
void OnCertVerifyComplete(int result);
+ bool CheckCertExtension(const net::X509Certificate* verified_cert);
bool CheckOCSPStatus(const net::OCSPVerifyResult& ocsp_result);
+ int VerifyCT(net::ct::CTVerifyResult* ct_verify_result);
ExchangeHeadersCallback headers_callback_;
base::Optional<SignedExchangeVersion> version_;
std::unique_ptr<net::SourceStream> source_;
- State state_ = State::kReadingHeadersLength;
- // Buffer used for header reading.
+ State state_ = State::kReadingPrologue;
+ // Buffer used for prologue and envelope reading.
scoped_refptr<net::IOBuffer> header_buf_;
// Wrapper around |header_buf_| to progressively read fixed-size data.
scoped_refptr<net::DrainableIOBuffer> header_read_buf_;
- size_t headers_length_ = 0;
-
- base::Optional<SignedExchangeHeader> header_;
+ base::Optional<SignedExchangePrologue> prologue_;
+ base::Optional<SignedExchangeEnvelope> envelope_;
std::unique_ptr<SignedExchangeCertFetcherFactory> cert_fetcher_factory_;
std::unique_ptr<SignedExchangeCertFetcher> cert_fetcher_;
+ const int load_flags_;
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
diff --git a/chromium/content/browser/web_package/signed_exchange_handler_unittest.cc b/chromium/content/browser/web_package/signed_exchange_handler_unittest.cc
index 46b4a38736b..54a648fc03b 100644
--- a/chromium/content/browser/web_package/signed_exchange_handler_unittest.cc
+++ b/chromium/content/browser/web_package/signed_exchange_handler_unittest.cc
@@ -4,6 +4,8 @@
#include "content/browser/web_package/signed_exchange_handler.h"
+#include <utility>
+
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_path.h"
@@ -16,9 +18,13 @@
#include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h"
#include "net/base/io_buffer.h"
+#include "net/base/load_flags.h"
#include "net/base/test_completion_callback.h"
+#include "net/cert/ct_policy_enforcer.h"
+#include "net/cert/ct_verifier.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/filter/mock_source_stream.h"
+#include "net/http/transport_security_state.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "net/url_request/url_request_test_util.h"
@@ -26,6 +32,7 @@
#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
+using testing::ElementsAre;
using testing::Property;
using testing::Return;
using testing::SetArgPointee;
@@ -38,10 +45,15 @@ namespace {
const uint64_t kSignatureHeaderDate = 1520834000;
const int kOutputBufferSize = 4096;
+// "wildcard_example.org.public.pem.cbor" has these dummy data in "ocsp" and
+// "sct" fields.
+constexpr base::StringPiece kDummyOCSPDer = "OCSP";
+constexpr base::StringPiece kDummySCTList = "SCT";
+
std::string GetTestFileContents(base::StringPiece name) {
base::FilePath path;
base::PathService::Get(content::DIR_TEST_DATA, &path);
- path = path.AppendASCII("htxg").AppendASCII(name);
+ path = path.AppendASCII("sxg").AppendASCII(name);
std::string contents;
CHECK(base::ReadFileToString(path, &contents));
@@ -50,10 +62,13 @@ std::string GetTestFileContents(base::StringPiece name) {
scoped_refptr<net::X509Certificate> LoadCertificate(
const std::string& cert_file) {
+ base::FilePath dir_path;
+ base::PathService::Get(content::DIR_TEST_DATA, &dir_path);
+ dir_path = dir_path.AppendASCII("sxg");
+
base::ScopedAllowBlockingForTesting allow_io;
return net::CreateCertificateChainFromFile(
- net::GetTestCertsDirectory(), cert_file,
- net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
+ dir_path, cert_file, net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
}
class MockSignedExchangeCertFetcherFactory
@@ -88,15 +103,51 @@ class MockSignedExchangeCertFetcherFactory
class GMockCertVerifier : public net::CertVerifier {
public:
- MOCK_METHOD6(Verify,
+ // net::CompletionOnceCallback is move-only, which GMock does not support.
+ int Verify(const net::CertVerifier::RequestParams& params,
+ net::CRLSet* crl_set,
+ net::CertVerifyResult* verify_result,
+ net::CompletionOnceCallback callback,
+ std::unique_ptr<net::CertVerifier::Request>* out_req,
+ const net::NetLogWithSource& net_log) override {
+ return VerifyImpl(params, crl_set, verify_result, out_req, net_log);
+ }
+
+ MOCK_METHOD5(VerifyImpl,
int(const net::CertVerifier::RequestParams& params,
net::CRLSet* crl_set,
net::CertVerifyResult* verify_result,
- const net::CompletionCallback& callback,
std::unique_ptr<net::CertVerifier::Request>* out_req,
const net::NetLogWithSource& net_log));
};
+class MockCTVerifier : public net::CTVerifier {
+ public:
+ MOCK_METHOD6(Verify,
+ void(base::StringPiece hostname,
+ net::X509Certificate* cert,
+ base::StringPiece stapled_ocsp_response,
+ base::StringPiece sct_list_from_tls_extension,
+ net::SignedCertificateTimestampAndStatusList* output_scts,
+ const net::NetLogWithSource& net_log));
+ MOCK_METHOD1(SetObserver, void(CTVerifier::Observer*));
+ MOCK_CONST_METHOD0(GetObserver, CTVerifier::Observer*());
+};
+
+class MockCTPolicyEnforcer : public net::CTPolicyEnforcer {
+ public:
+ MOCK_METHOD3(
+ CheckCompliance,
+ net::ct::CTPolicyCompliance(net::X509Certificate* cert,
+ const net::ct::SCTList& verified_scts,
+ const net::NetLogWithSource& net_log));
+};
+
+// Matcher to compare two net::X509Certificates
+MATCHER_P(CertEqualsIncludingChain, cert, "") {
+ return arg->EqualsIncludingChain(cert.get());
+}
+
} // namespace
class SignedExchangeHandlerTest
@@ -104,10 +155,10 @@ class SignedExchangeHandlerTest
public:
SignedExchangeHandlerTest()
: request_initiator_(
- url::Origin::Create(GURL("https://htxg.example.com/test.htxg"))) {}
+ url::Origin::Create(GURL("https://sxg.example.com/test.sxg"))) {}
virtual std::string ContentType() {
- return "application/signed-exchange;v=b0";
+ return "application/signed-exchange;v=b1";
}
void SetUp() override {
@@ -116,20 +167,19 @@ class SignedExchangeHandlerTest
base::TimeDelta::FromSeconds(kSignatureHeaderDate));
feature_list_.InitAndEnableFeature(features::kSignedHTTPExchange);
- std::unique_ptr<net::MockSourceStream> source(new net::MockSourceStream());
- source->set_read_one_byte_at_a_time(true);
- source_ = source.get();
- auto cert_fetcher_factory =
+ source_stream_ = std::make_unique<net::MockSourceStream>();
+ source_stream_->set_read_one_byte_at_a_time(true);
+ source_ = source_stream_.get();
+ cert_fetcher_factory_ =
std::make_unique<MockSignedExchangeCertFetcherFactory>();
- mock_cert_fetcher_factory_ = cert_fetcher_factory.get();
- request_context_getter_ = new net::TestURLRequestContextGetter(
- scoped_task_environment_.GetMainThreadTaskRunner());
- handler_ = std::make_unique<SignedExchangeHandler>(
- ContentType(), std::move(source),
- base::BindOnce(&SignedExchangeHandlerTest::OnHeaderFound,
- base::Unretained(this)),
- std::move(cert_fetcher_factory), request_context_getter_,
- nullptr /* devtools_proxy */);
+ mock_cert_fetcher_factory_ = cert_fetcher_factory_.get();
+ mock_ct_policy_enforcer_ = std::make_unique<MockCTPolicyEnforcer>();
+
+ // Lets mock CT policy enforcer return CT_POLICY_COMPLIES_VIA_SCTS by
+ // default. This may be overridden by test cases.
+ EXPECT_CALL(*mock_ct_policy_enforcer_, CheckCompliance(_, _, _))
+ .WillRepeatedly(
+ Return(net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
}
void TearDown() override {
@@ -182,6 +232,30 @@ class SignedExchangeHandlerTest
return resource_response_;
}
+ // Creates a TestURLRequestContext that uses |mock_ct_policy_enforcer_|.
+ std::unique_ptr<net::TestURLRequestContext> CreateTestURLRequestContext() {
+ auto test_url_request_context =
+ std::make_unique<net::TestURLRequestContext>(
+ true /* delay_initialization */);
+ test_url_request_context->set_ct_policy_enforcer(
+ mock_ct_policy_enforcer_.get());
+ test_url_request_context->Init();
+ return test_url_request_context;
+ }
+
+ void CreateSignedExchangeHandler(
+ std::unique_ptr<net::TestURLRequestContext> context) {
+ request_context_getter_ = new net::TestURLRequestContextGetter(
+ scoped_task_environment_.GetMainThreadTaskRunner(), std::move(context));
+
+ handler_ = std::make_unique<SignedExchangeHandler>(
+ ContentType(), std::move(source_stream_),
+ base::BindOnce(&SignedExchangeHandlerTest::OnHeaderFound,
+ base::Unretained(this)),
+ std::move(cert_fetcher_factory_), net::LOAD_NORMAL,
+ request_context_getter_, nullptr /* devtools_proxy */);
+ }
+
void WaitForHeader() {
while (!read_header()) {
while (source_->awaiting_completion())
@@ -193,6 +267,7 @@ class SignedExchangeHandlerTest
protected:
MockSignedExchangeCertFetcherFactory* mock_cert_fetcher_factory_;
std::unique_ptr<net::CertVerifier> cert_verifier_;
+ std::unique_ptr<MockCTPolicyEnforcer> mock_ct_policy_enforcer_;
net::MockSourceStream* source_;
std::unique_ptr<SignedExchangeHandler> handler_;
@@ -212,6 +287,8 @@ class SignedExchangeHandlerTest
base::test::ScopedTaskEnvironment scoped_task_environment_;
scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_;
const url::Origin request_initiator_;
+ std::unique_ptr<net::MockSourceStream> source_stream_;
+ std::unique_ptr<MockSignedExchangeCertFetcherFactory> cert_fetcher_factory_;
bool read_header_ = false;
net::Error error_;
@@ -219,15 +296,10 @@ class SignedExchangeHandlerTest
std::unique_ptr<net::SourceStream> payload_stream_;
};
-class SignedExchangeHandlerB1Test : public SignedExchangeHandlerTest {
- std::string ContentType() override {
- return "application/signed-exchange;v=b1";
- }
-};
-
TEST_P(SignedExchangeHandlerTest, Empty) {
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
@@ -237,24 +309,27 @@ TEST_P(SignedExchangeHandlerTest, Empty) {
TEST_P(SignedExchangeHandlerTest, Simple) {
mock_cert_fetcher_factory_->ExpectFetch(
GURL("https://cert.example.org/cert.msg"),
- GetTestFileContents("wildcard_example.org.public.pem.msg"));
+ GetTestFileContents("test.example.org.public.pem.cbor"));
- // Make the MockCertVerifier treat the certificate "wildcard.pem" as valid for
- // "*.example.org".
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("wildcard.pem");
+ LoadCertificate("prime256v1-sha256.public.pem");
net::CertVerifyResult dummy_result;
dummy_result.verified_cert = original_cert;
dummy_result.cert_status = net::OK;
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
- mock_cert_verifier->AddResultForCertAndHost(original_cert, "*.example.org",
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
dummy_result, net::OK);
SetCertVerifier(std::move(mock_cert_verifier));
- std::string contents = GetTestFileContents("test.example.org_test.htxg");
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
@@ -280,16 +355,27 @@ TEST_P(SignedExchangeHandlerTest, Simple) {
TEST_P(SignedExchangeHandlerTest, MimeType) {
mock_cert_fetcher_factory_->ExpectFetch(
GURL("https://cert.example.org/cert.msg"),
- GetTestFileContents("wildcard_example.org.public.pem.msg"));
+ GetTestFileContents("test.example.org.public.pem.cbor"));
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
+ scoped_refptr<net::X509Certificate> original_cert =
+ LoadCertificate("prime256v1-sha256.public.pem");
+ net::CertVerifyResult dummy_result;
+ dummy_result.verified_cert = original_cert;
+ dummy_result.cert_status = net::OK;
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
- mock_cert_verifier->set_default_result(net::OK);
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
+ dummy_result, net::OK);
SetCertVerifier(std::move(mock_cert_verifier));
- std::string contents = GetTestFileContents("test.example.org_hello.txt.htxg");
+ std::string contents = GetTestFileContents("test.example.org_hello.txt.sxg");
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
@@ -307,10 +393,12 @@ TEST_P(SignedExchangeHandlerTest, MimeType) {
EXPECT_EQ(rv, static_cast<int>(expected_payload.size()));
}
-TEST_P(SignedExchangeHandlerTest, ParseError) {
- const uint8_t data[] = {0x00, 0x00, 0x01, 0x00};
+TEST_P(SignedExchangeHandlerTest, HeaderParseError) {
+ const uint8_t data[] = {'s', 'x', 'g', '1', '-', 'b', '1', '\0',
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00};
source_->AddReadResult(reinterpret_cast<const char*>(data), sizeof(data),
net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
@@ -318,35 +406,42 @@ TEST_P(SignedExchangeHandlerTest, ParseError) {
}
TEST_P(SignedExchangeHandlerTest, TruncatedInHeader) {
- std::string contents = GetTestFileContents("test.example.org_test.htxg");
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
contents.resize(30);
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
}
-TEST_P(SignedExchangeHandlerTest, CertSha256Mismatch) {
- // The certificate is for "127.0.0.1". And the SHA 256 hash of the certificate
- // is different from the certSha256 of the signature in the htxg file. So the
- // certification verification must fail.
+TEST_P(SignedExchangeHandlerTest, CertWithoutExtensionShouldBeRejected) {
mock_cert_fetcher_factory_->ExpectFetch(
GURL("https://cert.example.org/cert.msg"),
- GetTestFileContents("127.0.0.1.public.pem.msg"));
+ GetTestFileContents("test.example.org-noext.public.pem.cbor"));
- // Set the default result of MockCertVerifier to OK, to check that the
- // verification of SignedExchange must fail even if the certificate is valid.
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
+ scoped_refptr<net::X509Certificate> original_cert =
+ LoadCertificate("prime256v1-sha256-noext.public.pem");
+ net::CertVerifyResult dummy_result;
+ dummy_result.verified_cert = original_cert;
+ dummy_result.cert_status = net::OK;
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
- mock_cert_verifier->set_default_result(net::OK);
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
+ dummy_result, net::OK);
SetCertVerifier(std::move(mock_cert_verifier));
- std::string contents = GetTestFileContents("test.example.org_test.htxg");
+ std::string contents = GetTestFileContents("test.example.org_noext_test.sxg");
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
@@ -355,31 +450,65 @@ TEST_P(SignedExchangeHandlerTest, CertSha256Mismatch) {
ReadStream(source_, nullptr);
}
-TEST_P(SignedExchangeHandlerTest, VerifyCertFailure) {
+TEST_P(SignedExchangeHandlerTest, CertWithoutExtensionAllowedByFeatureFlag) {
+ base::test::ScopedFeatureList scoped_feature_list_;
+ scoped_feature_list_.InitAndEnableFeature(
+ features::kAllowSignedHTTPExchangeCertsWithoutExtension);
+
mock_cert_fetcher_factory_->ExpectFetch(
GURL("https://cert.example.org/cert.msg"),
- GetTestFileContents("wildcard_example.org.public.pem.msg"));
+ GetTestFileContents("test.example.org-noext.public.pem.cbor"));
- // Make the MockCertVerifier treat the certificate "wildcard.pem" as valid for
- // "*.example.org".
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("wildcard.pem");
+ LoadCertificate("prime256v1-sha256-noext.public.pem");
net::CertVerifyResult dummy_result;
dummy_result.verified_cert = original_cert;
dummy_result.cert_status = net::OK;
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
- mock_cert_verifier->AddResultForCertAndHost(original_cert, "*.example.org",
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
dummy_result, net::OK);
SetCertVerifier(std::move(mock_cert_verifier));
- // The certificate is for "*.example.com". But the request URL of the htxg
- // file is "https://test.example.com/test/". So the certification verification
- // must fail.
- std::string contents =
- GetTestFileContents("test.example.com_invalid_test.htxg");
+ std::string contents = GetTestFileContents("test.example.org_noext_test.sxg");
+ source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
+ source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
+ WaitForHeader();
+
+ ASSERT_TRUE(read_header());
+ EXPECT_EQ(net::OK, error());
+ std::string payload;
+ int rv = ReadPayloadStream(&payload);
+ std::string expected_payload = GetTestFileContents("test.html");
+
+ EXPECT_EQ(expected_payload, payload);
+ EXPECT_EQ(static_cast<int>(expected_payload.size()), rv);
+}
+
+TEST_P(SignedExchangeHandlerTest, CertSha256Mismatch) {
+ // The certificate is for "127.0.0.1". And the SHA 256 hash of the certificate
+ // is different from the cert-sha256 of the signature in the sxg file. So the
+ // certification verification must fail.
+ mock_cert_fetcher_factory_->ExpectFetch(
+ GURL("https://cert.example.org/cert.msg"),
+ GetTestFileContents("127.0.0.1.public.pem.cbor"));
+
+ // Set the default result of MockCertVerifier to OK, to check that the
+ // verification of SignedExchange must fail even if the certificate is valid.
+ auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
+ mock_cert_verifier->set_default_result(net::OK);
+ SetCertVerifier(std::move(mock_cert_verifier));
+
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
@@ -388,151 +517,143 @@ TEST_P(SignedExchangeHandlerTest, VerifyCertFailure) {
ReadStream(source_, nullptr);
}
-TEST_P(SignedExchangeHandlerB1Test, Simple) {
+TEST_P(SignedExchangeHandlerTest, VerifyCertFailure) {
mock_cert_fetcher_factory_->ExpectFetch(
GURL("https://cert.example.org/cert.msg"),
- GetTestFileContents("wildcard_example.org.public.pem.cbor"));
+ GetTestFileContents("test.example.org.public.pem.cbor"));
- // Make the MockCertVerifier treat the certificate "wildcard.pem" as valid for
- // "*.example.org".
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("wildcard.pem");
+ LoadCertificate("prime256v1-sha256.public.pem");
net::CertVerifyResult dummy_result;
dummy_result.verified_cert = original_cert;
dummy_result.cert_status = net::OK;
- dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
- dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
- mock_cert_verifier->AddResultForCertAndHost(original_cert, "*.example.org",
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
dummy_result, net::OK);
SetCertVerifier(std::move(mock_cert_verifier));
- std::string contents = GetTestFileContents("test.example.org_test.htxg");
+ // The certificate is for "test.example.org". But the request URL of the sxg
+ // file is "https://test.example.com/test/". So the certification verification
+ // must fail.
+ std::string contents =
+ GetTestFileContents("test.example.com_invalid_test.sxg");
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
- EXPECT_EQ(net::OK, error());
- EXPECT_EQ(200, resource_response().headers->response_code());
- EXPECT_EQ("text/html", resource_response().mime_type);
- EXPECT_EQ("utf-8", resource_response().charset);
- EXPECT_FALSE(resource_response().load_timing.request_start_time.is_null());
- EXPECT_FALSE(resource_response().load_timing.request_start.is_null());
- EXPECT_FALSE(resource_response().load_timing.send_start.is_null());
- EXPECT_FALSE(resource_response().load_timing.send_end.is_null());
- EXPECT_FALSE(resource_response().load_timing.receive_headers_end.is_null());
-
- std::string payload;
- int rv = ReadPayloadStream(&payload);
-
- std::string expected_payload = GetTestFileContents("test.html");
-
- EXPECT_EQ(payload, expected_payload);
- EXPECT_EQ(rv, static_cast<int>(expected_payload.size()));
+ EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
+ // Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
+ ReadStream(source_, nullptr);
}
-TEST_P(SignedExchangeHandlerB1Test, OCSPNotChecked) {
+TEST_P(SignedExchangeHandlerTest, OCSPNotChecked) {
mock_cert_fetcher_factory_->ExpectFetch(
GURL("https://cert.example.org/cert.msg"),
- GetTestFileContents("wildcard_example.org.public.pem.cbor"));
+ GetTestFileContents("test.example.org.public.pem.cbor"));
- // Make the MockCertVerifier treat the certificate "wildcard.pem" as valid for
- // "*.example.org".
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("wildcard.pem");
+ LoadCertificate("prime256v1-sha256.public.pem");
net::CertVerifyResult dummy_result;
dummy_result.verified_cert = original_cert;
dummy_result.cert_status = net::OK;
dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::NOT_CHECKED;
auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
- mock_cert_verifier->AddResultForCertAndHost(original_cert, "*.example.org",
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
dummy_result, net::OK);
SetCertVerifier(std::move(mock_cert_verifier));
- std::string contents = GetTestFileContents("test.example.org_test.htxg");
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
- EXPECT_EQ(net::ERR_FAILED, error());
+ EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
ReadStream(source_, nullptr);
}
-TEST_P(SignedExchangeHandlerB1Test, OCSPNotProvided) {
+TEST_P(SignedExchangeHandlerTest, OCSPNotProvided) {
mock_cert_fetcher_factory_->ExpectFetch(
GURL("https://cert.example.org/cert.msg"),
- GetTestFileContents("wildcard_example.org.public.pem.cbor"));
+ GetTestFileContents("test.example.org.public.pem.cbor"));
- // Make the MockCertVerifier treat the certificate "wildcard.pem" as valid for
- // "*.example.org".
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("wildcard.pem");
+ LoadCertificate("prime256v1-sha256.public.pem");
net::CertVerifyResult dummy_result;
dummy_result.verified_cert = original_cert;
dummy_result.cert_status = net::OK;
dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::MISSING;
auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
- mock_cert_verifier->AddResultForCertAndHost(original_cert, "*.example.org",
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
dummy_result, net::OK);
SetCertVerifier(std::move(mock_cert_verifier));
- std::string contents = GetTestFileContents("test.example.org_test.htxg");
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
- EXPECT_EQ(net::ERR_FAILED, error());
+ EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
ReadStream(source_, nullptr);
}
-TEST_P(SignedExchangeHandlerB1Test, OCSPInvalid) {
+TEST_P(SignedExchangeHandlerTest, OCSPInvalid) {
mock_cert_fetcher_factory_->ExpectFetch(
GURL("https://cert.example.org/cert.msg"),
- GetTestFileContents("wildcard_example.org.public.pem.cbor"));
+ GetTestFileContents("test.example.org.public.pem.cbor"));
- // Make the MockCertVerifier treat the certificate "wildcard.pem" as valid for
- // "*.example.org".
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("wildcard.pem");
+ LoadCertificate("prime256v1-sha256.public.pem");
net::CertVerifyResult dummy_result;
dummy_result.verified_cert = original_cert;
dummy_result.cert_status = net::OK;
dummy_result.ocsp_result.response_status =
net::OCSPVerifyResult::INVALID_DATE;
auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
- mock_cert_verifier->AddResultForCertAndHost(original_cert, "*.example.org",
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
dummy_result, net::OK);
SetCertVerifier(std::move(mock_cert_verifier));
- std::string contents = GetTestFileContents("test.example.org_test.htxg");
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
- EXPECT_EQ(net::ERR_FAILED, error());
+ EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
ReadStream(source_, nullptr);
}
-TEST_P(SignedExchangeHandlerB1Test, OCSPRevoked) {
+TEST_P(SignedExchangeHandlerTest, OCSPRevoked) {
mock_cert_fetcher_factory_->ExpectFetch(
GURL("https://cert.example.org/cert.msg"),
- GetTestFileContents("wildcard_example.org.public.pem.cbor"));
+ GetTestFileContents("test.example.org.public.pem.cbor"));
- // Make the MockCertVerifier treat the certificate "wildcard.pem" as valid for
- // "*.example.org".
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("wildcard.pem");
+ LoadCertificate("prime256v1-sha256.public.pem");
net::CertVerifyResult dummy_result;
dummy_result.verified_cert = original_cert;
dummy_result.cert_status = net::OK;
@@ -540,66 +661,262 @@ TEST_P(SignedExchangeHandlerB1Test, OCSPRevoked) {
dummy_result.ocsp_result.revocation_status =
net::OCSPRevocationStatus::REVOKED;
auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
- mock_cert_verifier->AddResultForCertAndHost(original_cert, "*.example.org",
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
dummy_result, net::OK);
SetCertVerifier(std::move(mock_cert_verifier));
- std::string contents = GetTestFileContents("test.example.org_test.htxg");
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
WaitForHeader();
ASSERT_TRUE(read_header());
- EXPECT_EQ(net::ERR_FAILED, error());
+ EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
// Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
ReadStream(source_, nullptr);
}
// Test that fetching a signed exchange properly extracts and
// attempts to verify both the certificate and the OCSP response.
-TEST_P(SignedExchangeHandlerB1Test, CertVerifierParams) {
+TEST_P(SignedExchangeHandlerTest, CertVerifierParams) {
mock_cert_fetcher_factory_->ExpectFetch(
GURL("https://cert.example.org/cert.msg"),
- GetTestFileContents("wildcard_example.org.public.pem.cbor"));
+ GetTestFileContents("test.example.org.public.pem.cbor"));
scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("wildcard.pem");
+ LoadCertificate("prime256v1-sha256.public.pem");
net::CertVerifyResult fake_result;
fake_result.verified_cert = original_cert;
fake_result.cert_status = net::OK;
fake_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
fake_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
- // "wildcard_example.org.public.pem.cbor" has this dummy data instead of a
- // real OCSP response.
- constexpr base::StringPiece kExpectedOCSPDer = "OCSP";
-
std::unique_ptr<GMockCertVerifier> gmock_cert_verifier =
std::make_unique<GMockCertVerifier>();
EXPECT_CALL(
*gmock_cert_verifier,
- Verify(
+ VerifyImpl(
AllOf(Property(&net::CertVerifier::RequestParams::ocsp_response,
- kExpectedOCSPDer),
- Property(
- &net::CertVerifier::RequestParams::certificate,
- Truly([&original_cert](
- const scoped_refptr<net::X509Certificate>& cert) {
- return original_cert->EqualsIncludingChain(cert.get());
- })),
+ kDummyOCSPDer),
+ Property(&net::CertVerifier::RequestParams::certificate,
+ CertEqualsIncludingChain(original_cert)),
Property(&net::CertVerifier::RequestParams::hostname,
"test.example.org")),
- _ /* crl_set */, _ /* verify_result */, _ /* callback */,
- _ /* out_req */, _ /* net_log */
+ _ /* crl_set */, _ /* verify_result */, _ /* out_req */,
+ _ /* net_log */
))
.WillOnce(DoAll(SetArgPointee<2>(fake_result), Return(net::OK)));
SetCertVerifier(std::move(gmock_cert_verifier));
- std::string contents = GetTestFileContents("test.example.org_test.htxg");
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
+ WaitForHeader();
+
+ ASSERT_TRUE(read_header());
+ EXPECT_EQ(net::OK, error());
+ std::string payload;
+ int rv = ReadPayloadStream(&payload);
+ std::string expected_payload = GetTestFileContents("test.html");
+
+ EXPECT_EQ(expected_payload, payload);
+ EXPECT_EQ(static_cast<int>(expected_payload.size()), rv);
+}
+
+TEST_P(SignedExchangeHandlerTest, NotEnoughSCTsFromPubliclyTrustedCert) {
+ mock_cert_fetcher_factory_->ExpectFetch(
+ GURL("https://cert.example.org/cert.msg"),
+ GetTestFileContents("test.example.org.public.pem.cbor"));
+
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
+ scoped_refptr<net::X509Certificate> original_cert =
+ LoadCertificate("prime256v1-sha256.public.pem");
+ net::CertVerifyResult dummy_result;
+ dummy_result.verified_cert = original_cert;
+ dummy_result.is_issued_by_known_root = true;
+ dummy_result.cert_status = net::OK;
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
+ auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
+ dummy_result, net::OK);
+ SetCertVerifier(std::move(mock_cert_verifier));
+
+ // Lets the mock CT policy enforcer return CT_POLICY_NOT_ENOUGH_SCTS.
+ EXPECT_CALL(*mock_ct_policy_enforcer_, CheckCompliance(_, _, _))
+ .WillOnce(Return(net::ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
+ source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
+ source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
+ WaitForHeader();
+
+ ASSERT_TRUE(read_header());
+ EXPECT_EQ(net::ERR_INVALID_SIGNED_EXCHANGE, error());
+ // Drain the MockSourceStream, otherwise its destructer causes DCHECK failure.
+ ReadStream(source_, nullptr);
+}
+
+TEST_P(SignedExchangeHandlerTest, CTRequirementsMetForPubliclyTrustedCert) {
+ mock_cert_fetcher_factory_->ExpectFetch(
+ GURL("https://cert.example.org/cert.msg"),
+ GetTestFileContents("test.example.org.public.pem.cbor"));
+
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
+ scoped_refptr<net::X509Certificate> original_cert =
+ LoadCertificate("prime256v1-sha256.public.pem");
+ net::CertVerifyResult dummy_result;
+ dummy_result.verified_cert = original_cert;
+ dummy_result.is_issued_by_known_root = true;
+ dummy_result.cert_status = net::CERT_STATUS_IS_EV;
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
+ auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
+ dummy_result, net::OK);
+ SetCertVerifier(std::move(mock_cert_verifier));
+
+ // The mock CT policy enforcer will return CT_POLICY_COMPLIES_VIA_SCTS, as
+ // configured in SetUp().
+
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
+ source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
+ source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
+ WaitForHeader();
+
+ ASSERT_TRUE(read_header());
+ EXPECT_EQ(net::OK, error());
+ // EV status should be preserved.
+ EXPECT_TRUE(resource_response().ssl_info->cert_status &
+ net::CERT_STATUS_IS_EV);
+ EXPECT_FALSE(resource_response().ssl_info->cert_status &
+ net::CERT_STATUS_CT_COMPLIANCE_FAILED);
+ EXPECT_TRUE(resource_response().ssl_info->ct_policy_compliance_required);
+ EXPECT_EQ(net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS,
+ resource_response().ssl_info->ct_policy_compliance);
+
+ std::string payload;
+ int rv = ReadPayloadStream(&payload);
+ std::string expected_payload = GetTestFileContents("test.html");
+ EXPECT_EQ(expected_payload, payload);
+ EXPECT_EQ(static_cast<int>(expected_payload.size()), rv);
+}
+
+TEST_P(SignedExchangeHandlerTest, CTNotRequiredForLocalAnchors) {
+ mock_cert_fetcher_factory_->ExpectFetch(
+ GURL("https://cert.example.org/cert.msg"),
+ GetTestFileContents("test.example.org.public.pem.cbor"));
+
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
+ scoped_refptr<net::X509Certificate> original_cert =
+ LoadCertificate("prime256v1-sha256.public.pem");
+ net::CertVerifyResult dummy_result;
+ dummy_result.verified_cert = original_cert;
+
+ // Local anchor.
+ dummy_result.is_issued_by_known_root = false;
+
+ dummy_result.cert_status = net::CERT_STATUS_IS_EV;
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
+ auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
+ dummy_result, net::OK);
+ SetCertVerifier(std::move(mock_cert_verifier));
+ // Lets the mock CT policy enforcer return CT_POLICY_NOT_ENOUGH_SCTS.
+ EXPECT_CALL(*mock_ct_policy_enforcer_, CheckCompliance(_, _, _))
+ .WillOnce(Return(net::ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
+
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
+ source_->AddReadResult(contents.data(), contents.size(), net::OK, GetParam());
+ source_->AddReadResult(nullptr, 0, net::OK, GetParam());
+
+ CreateSignedExchangeHandler(CreateTestURLRequestContext());
+ WaitForHeader();
+
+ ASSERT_TRUE(read_header());
+ EXPECT_EQ(net::OK, error());
+ // EV status should be removed.
+ EXPECT_FALSE(resource_response().ssl_info->cert_status &
+ net::CERT_STATUS_IS_EV);
+ EXPECT_TRUE(resource_response().ssl_info->cert_status &
+ net::CERT_STATUS_CT_COMPLIANCE_FAILED);
+ EXPECT_FALSE(resource_response().ssl_info->ct_policy_compliance_required);
+ EXPECT_EQ(net::ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS,
+ resource_response().ssl_info->ct_policy_compliance);
+
+ std::string payload;
+ int rv = ReadPayloadStream(&payload);
+ std::string expected_payload = GetTestFileContents("test.html");
+ EXPECT_EQ(expected_payload, payload);
+ EXPECT_EQ(static_cast<int>(expected_payload.size()), rv);
+}
+
+// Test that SignedExchangeHandler calls CTVerifier and CTPolicyEnforcer
+// with appropriate arguments.
+TEST_P(SignedExchangeHandlerTest, CTVerifierParams) {
+ mock_cert_fetcher_factory_->ExpectFetch(
+ GURL("https://cert.example.org/cert.msg"),
+ GetTestFileContents("test.example.org.public.pem.cbor"));
+ scoped_refptr<net::X509Certificate> original_cert =
+ LoadCertificate("prime256v1-sha256.public.pem");
+
+ net::SignedCertificateTimestampAndStatusList fake_sct_list;
+ auto good_sct = base::MakeRefCounted<net::ct::SignedCertificateTimestamp>();
+ fake_sct_list.emplace_back(good_sct, net::ct::SCT_STATUS_OK);
+ auto bad_sct = base::MakeRefCounted<net::ct::SignedCertificateTimestamp>();
+ fake_sct_list.emplace_back(bad_sct, net::ct::SCT_STATUS_INVALID_TIMESTAMP);
+
+ EXPECT_CALL(*mock_ct_policy_enforcer_,
+ CheckCompliance(CertEqualsIncludingChain(original_cert),
+ ElementsAre(good_sct), _ /* net_log */))
+ .WillOnce(
+ Return(net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
+
+ std::unique_ptr<MockCTVerifier> ct_verifier =
+ std::make_unique<MockCTVerifier>();
+ EXPECT_CALL(*ct_verifier,
+ Verify(base::StringPiece("test.example.org"),
+ CertEqualsIncludingChain(original_cert), kDummyOCSPDer,
+ kDummySCTList, _ /* output_scts */, _ /* net_log */))
+ .WillOnce(SetArgPointee<4>(fake_sct_list));
+
+ auto test_url_request_context = std::make_unique<net::TestURLRequestContext>(
+ true /* delay_initialization */);
+ test_url_request_context->set_ct_policy_enforcer(
+ mock_ct_policy_enforcer_.get());
+ test_url_request_context->set_cert_transparency_verifier(ct_verifier.get());
+ test_url_request_context->Init();
+
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
+ net::CertVerifyResult dummy_result;
+ dummy_result.verified_cert = original_cert;
+ dummy_result.cert_status = net::OK;
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
+ auto mock_cert_verifier = std::make_unique<net::MockCertVerifier>();
+ mock_cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
+ dummy_result, net::OK);
+ SetCertVerifier(std::move(mock_cert_verifier));
+
+ std::string contents = GetTestFileContents("test.example.org_test.sxg");
+ source_->AddReadResult(contents.data(), contents.size(), net::OK,
+ net::MockSourceStream::ASYNC);
+ source_->AddReadResult(nullptr, 0, net::OK, net::MockSourceStream::ASYNC);
+
+ CreateSignedExchangeHandler(std::move(test_url_request_context));
WaitForHeader();
ASSERT_TRUE(read_header());
@@ -617,9 +934,4 @@ INSTANTIATE_TEST_CASE_P(SignedExchangeHandlerTests,
::testing::Values(net::MockSourceStream::SYNC,
net::MockSourceStream::ASYNC));
-INSTANTIATE_TEST_CASE_P(SignedExchangeHandlerB1Tests,
- SignedExchangeHandlerB1Test,
- ::testing::Values(net::MockSourceStream::SYNC,
- net::MockSourceStream::ASYNC));
-
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_header_parser_unittest.cc b/chromium/content/browser/web_package/signed_exchange_header_parser_unittest.cc
deleted file mode 100644
index 32f912e9490..00000000000
--- a/chromium/content/browser/web_package/signed_exchange_header_parser_unittest.cc
+++ /dev/null
@@ -1,281 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/web_package/signed_exchange_header_parser.h"
-
-#include "base/callback.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-class SignedExchangeHeaderParserTest : public ::testing::Test {
- protected:
- SignedExchangeHeaderParserTest() {}
-};
-
-TEST_F(SignedExchangeHeaderParserTest, ParseSignature) {
- const char hdr_string[] =
- "sig1;"
- " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
- "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
- " integrity=\"mi\";"
- " validityUrl=\"https://example.com/resource.validity.1511128380\";"
- " certUrl=\"https://example.com/oldcerts\";"
- " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
- " date=1511128380; expires=1511733180,"
- "sig2;"
- " sig=*MEQCIGjZRqTRf9iKNkGFyzRMTFgwf/BrY2ZNIP/dykhUV0aYAiBTXg+8wujoT4n/W+"
- "cNgb7pGqQvIUGYZ8u8HZJ5YH26Qg;"
- " integrity=\"mi\";"
- " validityUrl=\"https://example.com/resource.validity.1511128380\";"
- " certUrl=\"https://example.com/newcerts\";"
- " certSha256=*J/lEm9kNRODdCmINbvitpvdYKNQ+YgBj99DlYp4fEXw;"
- " date=1511128380; expires=1511733180";
-
- const uint8_t decoded_sig1[] = {
- 0x30, 0x45, 0x02, 0x21, 0x00, 0xd7, 0x94, 0x8d, 0xa0, 0x37, 0x74, 0x4d,
- 0x06, 0x58, 0x05, 0x8a, 0xe4, 0x4d, 0x16, 0x96, 0x57, 0x70, 0x32, 0x1a,
- 0x52, 0x95, 0xfa, 0x1c, 0x81, 0x30, 0x71, 0x91, 0x1c, 0xd1, 0xc6, 0x58,
- 0x2c, 0x02, 0x20, 0x6b, 0xd0, 0xec, 0x54, 0xe3, 0x0c, 0xfa, 0x0e, 0x58,
- 0xa7, 0x01, 0x01, 0x74, 0x65, 0xb7, 0xb1, 0x2f, 0x9b, 0xbe, 0x79, 0x80,
- 0x24, 0x98, 0x92, 0x33, 0x08, 0x6e, 0x05, 0xda, 0xa9, 0xe5, 0x46};
- const net::SHA256HashValue decoded_cert_sha256_1 = {
- {0x5b, 0xbb, 0x81, 0xf7, 0xaf, 0x5d, 0x15, 0x6d, 0xcc, 0x6f, 0x96,
- 0x5e, 0x7c, 0xf4, 0xbd, 0x4e, 0xae, 0x59, 0x6c, 0x7e, 0x62, 0x4a,
- 0x63, 0x88, 0x2e, 0x98, 0xef, 0xda, 0xa1, 0x00, 0xae, 0x62}};
- const uint8_t decoded_sig2[] = {
- 0x30, 0x44, 0x02, 0x20, 0x68, 0xd9, 0x46, 0xa4, 0xd1, 0x7f, 0xd8, 0x8a,
- 0x36, 0x41, 0x85, 0xcb, 0x34, 0x4c, 0x4c, 0x58, 0x30, 0x7f, 0xf0, 0x6b,
- 0x63, 0x66, 0x4d, 0x20, 0xff, 0xdd, 0xca, 0x48, 0x54, 0x57, 0x46, 0x98,
- 0x02, 0x20, 0x53, 0x5e, 0x0f, 0xbc, 0xc2, 0xe8, 0xe8, 0x4f, 0x89, 0xff,
- 0x5b, 0xe7, 0x0d, 0x81, 0xbe, 0xe9, 0x1a, 0xa4, 0x2f, 0x21, 0x41, 0x98,
- 0x67, 0xcb, 0xbc, 0x1d, 0x92, 0x79, 0x60, 0x7d, 0xba, 0x42};
- const net::SHA256HashValue decoded_cert_sha256_2 = {
- {0x27, 0xf9, 0x44, 0x9b, 0xd9, 0x0d, 0x44, 0xe0, 0xdd, 0x0a, 0x62,
- 0x0d, 0x6e, 0xf8, 0xad, 0xa6, 0xf7, 0x58, 0x28, 0xd4, 0x3e, 0x62,
- 0x00, 0x63, 0xf7, 0xd0, 0xe5, 0x62, 0x9e, 0x1f, 0x11, 0x7c}};
-
- auto signatures = SignedExchangeHeaderParser::ParseSignature(
- hdr_string, nullptr /* devtools_proxy */);
- ASSERT_TRUE(signatures.has_value());
- ASSERT_EQ(signatures->size(), 2u);
-
- EXPECT_EQ(signatures->at(0).label, "sig1");
- EXPECT_EQ(signatures->at(0).sig,
- std::string(reinterpret_cast<const char*>(decoded_sig1),
- sizeof(decoded_sig1)));
- EXPECT_EQ(signatures->at(0).integrity, "mi");
- EXPECT_EQ(signatures->at(0).validity_url,
- "https://example.com/resource.validity.1511128380");
- EXPECT_EQ(signatures->at(0).cert_url, "https://example.com/oldcerts");
- EXPECT_EQ(signatures->at(0).cert_sha256, decoded_cert_sha256_1);
- EXPECT_EQ(signatures->at(0).date, 1511128380ul);
- EXPECT_EQ(signatures->at(0).expires, 1511733180ul);
-
- EXPECT_EQ(signatures->at(1).label, "sig2");
- EXPECT_EQ(signatures->at(1).sig,
- std::string(reinterpret_cast<const char*>(decoded_sig2),
- sizeof(decoded_sig2)));
- EXPECT_EQ(signatures->at(1).integrity, "mi");
- EXPECT_EQ(signatures->at(1).validity_url,
- "https://example.com/resource.validity.1511128380");
- EXPECT_EQ(signatures->at(1).cert_url, "https://example.com/newcerts");
- EXPECT_EQ(signatures->at(1).cert_sha256, decoded_cert_sha256_2);
- EXPECT_EQ(signatures->at(1).date, 1511128380ul);
- EXPECT_EQ(signatures->at(1).expires, 1511733180ul);
-}
-
-TEST_F(SignedExchangeHeaderParserTest, IncompleteSignature) {
- const char hdr_string[] =
- "sig1;"
- " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
- "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
- // no integrity= param
- " validityUrl=\"https://example.com/resource.validity.1511128380\";"
- " certUrl=\"https://example.com/oldcerts\";"
- " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
- " date=1511128380; expires=1511733180";
- auto signatures = SignedExchangeHeaderParser::ParseSignature(
- hdr_string, nullptr /* devtools_proxy */);
- EXPECT_FALSE(signatures.has_value());
-}
-
-TEST_F(SignedExchangeHeaderParserTest, DuplicatedParam) {
- const char hdr_string[] =
- "sig1;"
- " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
- "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
- " integrity=\"mi\";"
- " validityUrl=\"https://example.com/resource.validity.1511128380\";"
- " certUrl=\"https://example.com/oldcerts\";"
- " certUrl=\"https://example.com/oldcerts\";"
- " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
- " date=1511128380; expires=1511733180";
- auto signatures = SignedExchangeHeaderParser::ParseSignature(
- hdr_string, nullptr /* devtools_proxy */);
- EXPECT_FALSE(signatures.has_value());
-}
-
-TEST_F(SignedExchangeHeaderParserTest, InvalidCertURL) {
- const char hdr_string[] =
- "sig1;"
- " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
- "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
- " integrity=\"mi\";"
- " validityUrl=\"https://example.com/resource.validity.1511128380\";"
- " certUrl=\"https:://example.com/oldcerts\";"
- " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
- " date=1511128380; expires=1511733180";
- auto signatures = SignedExchangeHeaderParser::ParseSignature(
- hdr_string, nullptr /* devtools_proxy */);
- EXPECT_FALSE(signatures.has_value());
-}
-
-TEST_F(SignedExchangeHeaderParserTest, CertURLWithFragment) {
- const char hdr_string[] =
- "sig1;"
- " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
- "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
- " integrity=\"mi\";"
- " validityUrl=\"https://example.com/resource.validity.1511128380\";"
- " certUrl=\"https://example.com/oldcerts#test\";"
- " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
- " date=1511128380; expires=1511733180";
- auto signatures = SignedExchangeHeaderParser::ParseSignature(
- hdr_string, nullptr /* devtools_proxy */);
- EXPECT_FALSE(signatures.has_value());
-}
-
-TEST_F(SignedExchangeHeaderParserTest, RelativeCertURL) {
- const char hdr_string[] =
- "sig1;"
- " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
- "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
- " integrity=\"mi\";"
- " validityUrl=\"https://example.com/resource.validity.1511128380\";"
- " certUrl=\"oldcerts\";"
- " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
- " date=1511128380; expires=1511733180";
- auto signatures = SignedExchangeHeaderParser::ParseSignature(
- hdr_string, nullptr /* devtools_proxy */);
- EXPECT_FALSE(signatures.has_value());
-}
-
-TEST_F(SignedExchangeHeaderParserTest, InvalidValidityUrl) {
- const char hdr_string[] =
- "sig1;"
- " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
- "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
- " integrity=\"mi\";"
- " validityUrl=\"https:://example.com/resource.validity.1511128380\";"
- " certUrl=\"https://example.com/oldcerts\";"
- " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
- " date=1511128380; expires=1511733180";
- auto signatures = SignedExchangeHeaderParser::ParseSignature(
- hdr_string, nullptr /* devtools_proxy */);
- EXPECT_FALSE(signatures.has_value());
-}
-
-TEST_F(SignedExchangeHeaderParserTest, ValidityUrlWithFragment) {
- const char hdr_string[] =
- "sig1;"
- " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
- "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
- " integrity=\"mi\";"
- " validityUrl=\"https://example.com/resource.validity.1511128380#test\";"
- " certUrl=\"https://example.com/oldcerts\";"
- " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
- " date=1511128380; expires=1511733180";
- auto signatures = SignedExchangeHeaderParser::ParseSignature(
- hdr_string, nullptr /* devtools_proxy */);
- EXPECT_FALSE(signatures.has_value());
-}
-
-TEST_F(SignedExchangeHeaderParserTest, RelativeValidityUrl) {
- const char hdr_string[] =
- "sig1;"
- " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
- "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
- " integrity=\"mi\";"
- " validityUrl=\"resource.validity.1511128380\";"
- " certUrl=\"https://example.com/oldcerts\";"
- " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
- " date=1511128380; expires=1511733180";
- auto signatures = SignedExchangeHeaderParser::ParseSignature(
- hdr_string, nullptr /* devtools_proxy */);
- EXPECT_FALSE(signatures.has_value());
-}
-
-TEST_F(SignedExchangeHeaderParserTest, InvalidCertSHA256) {
- const char hdr_string[] =
- "sig1;"
- " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
- "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
- " integrity=\"mi\";"
- " validityUrl=\"https://example.com/resource.validity.1511128380\";"
- " certUrl=\"https://example.com/oldcerts\";"
- " certSha256=*W7uB969dFW3Mb5ZefPS9;"
- " date=1511128380; expires=1511733180";
- auto signatures = SignedExchangeHeaderParser::ParseSignature(
- hdr_string, nullptr /* devtools_proxy */);
- EXPECT_FALSE(signatures.has_value());
-}
-
-TEST_F(SignedExchangeHeaderParserTest, OpenQuoteAtEnd) {
- const char hdr_string[] = "sig1; sig=\"";
- auto signatures = SignedExchangeHeaderParser::ParseSignature(
- hdr_string, nullptr /* devtools_proxy */);
- EXPECT_FALSE(signatures.has_value());
-}
-
-TEST_F(SignedExchangeHeaderParserTest, VersionParam_None) {
- const char content_type[] = "application/signed-exchange";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_TRUE(SignedExchangeHeaderParser::GetVersionParamFromContentType(
- content_type, &version));
- EXPECT_FALSE(version);
-}
-
-TEST_F(SignedExchangeHeaderParserTest, VersionParam_NoneWithSemicolon) {
- const char content_type[] = "application/signed-exchange;";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_FALSE(SignedExchangeHeaderParser::GetVersionParamFromContentType(
- content_type, &version));
-}
-
-TEST_F(SignedExchangeHeaderParserTest, VersionParam_EmptyString) {
- const char content_type[] = "application/signed-exchange;v=";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_FALSE(SignedExchangeHeaderParser::GetVersionParamFromContentType(
- content_type, &version));
-}
-
-TEST_F(SignedExchangeHeaderParserTest, VersionParam_Simple) {
- const char content_type[] = "application/signed-exchange;v=b0";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_TRUE(SignedExchangeHeaderParser::GetVersionParamFromContentType(
- content_type, &version));
- ASSERT_TRUE(version);
- EXPECT_EQ(*version, SignedExchangeVersion::kB0);
-}
-
-TEST_F(SignedExchangeHeaderParserTest, VersionParam_SimpleWithSpace) {
- const char content_type[] = "application/signed-exchange; v=b1";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_TRUE(SignedExchangeHeaderParser::GetVersionParamFromContentType(
- content_type, &version));
- ASSERT_TRUE(version);
- EXPECT_EQ(*version, SignedExchangeVersion::kB1);
-}
-
-TEST_F(SignedExchangeHeaderParserTest, VersionParam_SimpleWithDoublequotes) {
- const char content_type[] = "application/signed-exchange;v=\"b0\"";
- base::Optional<SignedExchangeVersion> version;
- EXPECT_TRUE(SignedExchangeHeaderParser::GetVersionParamFromContentType(
- content_type, &version));
- ASSERT_TRUE(version);
- EXPECT_EQ(*version, SignedExchangeVersion::kB0);
-}
-
-} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_header_unittest.cc b/chromium/content/browser/web_package/signed_exchange_header_unittest.cc
deleted file mode 100644
index 9c532156460..00000000000
--- a/chromium/content/browser/web_package/signed_exchange_header_unittest.cc
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/web_package/signed_exchange_header.h"
-
-#include "base/callback.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/path_service.h"
-#include "components/cbor/cbor_values.h"
-#include "components/cbor/cbor_writer.h"
-#include "content/browser/web_package/signed_exchange_consts.h"
-#include "content/public/common/content_paths.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace content {
-
-namespace {
-
-const char kSignatureString[] =
- "sig1;"
- " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
- "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY;"
- " integrity=\"mi\";"
- " validityUrl=\"https://example.com/resource.validity.1511128380\";"
- " certUrl=\"https://example.com/oldcerts\";"
- " certSha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI;"
- " date=1511128380; expires=1511733180";
-
-cbor::CBORValue CBORByteString(const char* str) {
- return cbor::CBORValue(str, cbor::CBORValue::Type::BYTE_STRING);
-}
-
-base::Optional<SignedExchangeHeader> GenerateHeaderAndParse(
- const std::map<const char*, const char*>& request_map,
- const std::map<const char*, const char*>& response_map) {
- cbor::CBORValue::MapValue request_cbor_map;
- cbor::CBORValue::MapValue response_cbor_map;
- for (auto& pair : request_map)
- request_cbor_map[CBORByteString(pair.first)] = CBORByteString(pair.second);
- for (auto& pair : response_map)
- response_cbor_map[CBORByteString(pair.first)] = CBORByteString(pair.second);
-
- cbor::CBORValue::ArrayValue array;
- array.push_back(cbor::CBORValue(std::move(request_cbor_map)));
- array.push_back(cbor::CBORValue(std::move(response_cbor_map)));
-
- auto serialized = cbor::CBORWriter::Write(cbor::CBORValue(std::move(array)));
- return SignedExchangeHeader::Parse(
- base::make_span(serialized->data(), serialized->size()),
- nullptr /* devtools_proxy */);
-}
-
-} // namespace
-
-TEST(SignedExchangeHeaderTest, ParseEncodedLength) {
- constexpr struct {
- uint8_t bytes[SignedExchangeHeader::kEncodedLengthInBytes];
- size_t expected;
- } kTestCases[] = {
- {{0x00, 0x00, 0x01}, 1u}, {{0x01, 0xe2, 0x40}, 123456u},
- };
-
- int test_element_index = 0;
- for (const auto& test_case : kTestCases) {
- SCOPED_TRACE(testing::Message() << "testing case " << test_element_index++);
- EXPECT_EQ(SignedExchangeHeader::ParseEncodedLength(test_case.bytes),
- test_case.expected);
- }
-}
-
-TEST(SignedExchangeHeaderTest, ParseGoldenFile) {
- base::FilePath test_htxg_path;
- base::PathService::Get(content::DIR_TEST_DATA, &test_htxg_path);
- test_htxg_path = test_htxg_path.AppendASCII("htxg").AppendASCII(
- "test.example.org_test.htxg");
-
- std::string contents;
- ASSERT_TRUE(base::ReadFileToString(test_htxg_path, &contents));
- auto* contents_bytes = reinterpret_cast<const uint8_t*>(contents.data());
-
- ASSERT_GT(contents.size(), SignedExchangeHeader::kEncodedLengthInBytes);
- size_t header_size = SignedExchangeHeader::ParseEncodedLength(base::make_span(
- contents_bytes, SignedExchangeHeader::kEncodedLengthInBytes));
- ASSERT_GT(contents.size(),
- SignedExchangeHeader::kEncodedLengthInBytes + header_size);
-
- const auto cbor_bytes = base::make_span<const uint8_t>(
- contents_bytes + SignedExchangeHeader::kEncodedLengthInBytes,
- header_size);
- const base::Optional<SignedExchangeHeader> header =
- SignedExchangeHeader::Parse(cbor_bytes, nullptr /* devtools_proxy */);
- ASSERT_TRUE(header.has_value());
- EXPECT_EQ(header->request_url(), GURL("https://test.example.org/test/"));
- EXPECT_EQ(header->request_method(), "GET");
- EXPECT_EQ(header->response_code(), static_cast<net::HttpStatusCode>(200u));
- EXPECT_EQ(header->response_headers().size(), 4u);
- EXPECT_EQ(header->response_headers().find("content-encoding")->second,
- "mi-sha256");
-}
-
-TEST(SignedExchangeHeaderTest, ValidHeader) {
- auto header = GenerateHeaderAndParse(
- {
- {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "GET"},
- },
- {
- {kStatusKey, "200"}, {kSignature, kSignatureString},
- });
- ASSERT_TRUE(header.has_value());
- EXPECT_EQ(header->request_url(), GURL("https://test.example.org/test/"));
- EXPECT_EQ(header->request_method(), "GET");
- EXPECT_EQ(header->response_code(), static_cast<net::HttpStatusCode>(200u));
- EXPECT_EQ(header->response_headers().size(), 1u);
-}
-
-TEST(SignedExchangeHeaderTest, UnsafeMethod) {
- auto header = GenerateHeaderAndParse(
- {
- {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "POST"},
- },
- {
- {kStatusKey, "200"}, {kSignature, kSignatureString},
- });
- ASSERT_FALSE(header.has_value());
-}
-
-TEST(SignedExchangeHeaderTest, InvalidURL) {
- auto header = GenerateHeaderAndParse(
- {
- {kUrlKey, "https:://test.example.org/test/"}, {kMethodKey, "GET"},
- },
- {
- {kStatusKey, "200"}, {kSignature, kSignatureString},
- });
- ASSERT_FALSE(header.has_value());
-}
-
-TEST(SignedExchangeHeaderTest, URLWithFragment) {
- auto header = GenerateHeaderAndParse(
- {
- {kUrlKey, "https://test.example.org/test/#foo"}, {kMethodKey, "GET"},
- },
- {
- {kStatusKey, "200"}, {kSignature, kSignatureString},
- });
- ASSERT_FALSE(header.has_value());
-}
-
-TEST(SignedExchangeHeaderTest, RelativeURL) {
- auto header = GenerateHeaderAndParse(
- {
- {kUrlKey, "test/"}, {kMethodKey, "GET"},
- },
- {
- {kStatusKey, "200"}, {kSignature, kSignatureString},
- });
- ASSERT_FALSE(header.has_value());
-}
-
-TEST(SignedExchangeHeaderTest, StatefulRequestHeader) {
- auto header = GenerateHeaderAndParse(
- {
- {kUrlKey, "https://test.example.org/test/"},
- {kMethodKey, "GET"},
- {"authorization", "Basic Zm9vOmJhcg=="},
- },
- {
- {kStatusKey, "200"}, {kSignature, kSignatureString},
- });
- ASSERT_FALSE(header.has_value());
-}
-
-TEST(SignedExchangeHeaderTest, StatefulResponseHeader) {
- auto header = GenerateHeaderAndParse(
- {
- {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "GET"},
- },
- {
- {kStatusKey, "200"},
- {kSignature, kSignatureString},
- {"set-cookie", "foo=bar"},
- });
- ASSERT_FALSE(header.has_value());
-}
-
-TEST(SignedExchangeHeaderTest, UppercaseRequestMap) {
- auto header = GenerateHeaderAndParse(
- {{kUrlKey, "https://test.example.org/test/"},
- {kMethodKey, "GET"},
- {"Accept-Language", "en-us"}},
- {
- {kStatusKey, "200"}, {kSignature, kSignatureString},
- });
- ASSERT_FALSE(header.has_value());
-}
-
-TEST(SignedExchangeHeaderTest, UppercaseResponseMap) {
- auto header = GenerateHeaderAndParse(
- {
- {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "GET"},
- },
- {{kStatusKey, "200"},
- {kSignature, kSignatureString},
- {"Content-Length", "123"}});
- ASSERT_FALSE(header.has_value());
-}
-
-} // namespace content
diff --git a/chromium/content/browser/web_package/web_package_loader.cc b/chromium/content/browser/web_package/signed_exchange_loader.cc
index ecd1e160eb0..9ede996006a 100644
--- a/chromium/content/browser/web_package/web_package_loader.cc
+++ b/chromium/content/browser/web_package/signed_exchange_loader.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/web_package/web_package_loader.h"
+#include "content/browser/web_package/signed_exchange_loader.h"
#include <memory>
@@ -16,6 +16,8 @@
#include "content/browser/web_package/signed_exchange_handler.h"
#include "content/browser/web_package/signed_exchange_utils.h"
#include "content/public/common/content_features.h"
+#include "content/public/common/origin_util.h"
+#include "net/base/net_errors.h"
#include "net/cert/cert_status_flags.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request_context_getter.h"
@@ -43,7 +45,7 @@ SignedExchangeHandlerFactory* g_signed_exchange_factory_for_testing_ = nullptr;
} // namespace
-class WebPackageLoader::ResponseTimingInfo {
+class SignedExchangeLoader::ResponseTimingInfo {
public:
explicit ResponseTimingInfo(const network::ResourceResponseHead& response)
: request_start_(response.request_start),
@@ -77,12 +79,15 @@ class WebPackageLoader::ResponseTimingInfo {
DISALLOW_COPY_AND_ASSIGN(ResponseTimingInfo);
};
-WebPackageLoader::WebPackageLoader(
+SignedExchangeLoader::SignedExchangeLoader(
+ const GURL& outer_request_url,
const network::ResourceResponseHead& outer_response,
network::mojom::URLLoaderClientPtr forwarding_client,
network::mojom::URLLoaderClientEndpointsPtr endpoints,
url::Origin request_initiator,
uint32_t url_loader_options,
+ int load_flags,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id,
std::unique_ptr<SignedExchangeDevToolsProxy> devtools_proxy,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
URLLoaderThrottlesGetter url_loader_throttles_getter,
@@ -94,6 +99,8 @@ WebPackageLoader::WebPackageLoader(
url_loader_client_binding_(this),
request_initiator_(request_initiator),
url_loader_options_(url_loader_options),
+ load_flags_(load_flags),
+ throttling_profile_id_(throttling_profile_id),
devtools_proxy_(std::move(devtools_proxy)),
url_loader_factory_(std::move(url_loader_factory)),
url_loader_throttles_getter_(std::move(url_loader_throttles_getter)),
@@ -101,6 +108,46 @@ WebPackageLoader::WebPackageLoader(
weak_factory_(this) {
DCHECK(signed_exchange_utils::IsSignedExchangeHandlingEnabled());
+ // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#privacy-considerations
+ // This can be difficult to determine when the exchange is being loaded from
+ // local disk, but when the client itself requested the exchange over a
+ // network it SHOULD require TLS ([I-D.ietf-tls-tls13]) or a successor
+ // transport layer, and MUST NOT accept exchanges transferred over plain HTTP
+ // without TLS. [spec text]
+ if (!IsOriginSecure(outer_request_url)) {
+ devtools_proxy_->ReportError(
+ "Signed exchange response from non secure origin is not supported.",
+ base::nullopt /* error_field */);
+ // Calls OnSignedExchangeReceived() to show the outer response in DevTool's
+ // Network panel and the error message in the Preview panel.
+ devtools_proxy_->OnSignedExchangeReceived(base::nullopt /* header */,
+ nullptr /* certificate */,
+ nullptr /* ssl_info */);
+ // This will asynchronously delete |this|.
+ forwarding_client_->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_INVALID_SIGNED_EXCHANGE));
+ return;
+ }
+
+ // TODO(https://crbug.com/849935): Remove this once we have Network Service
+ // friendly cert, OCSP, and CT verification.
+ if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ devtools_proxy_->ReportError(
+ "Currently, signed exchange does not work when "
+ "chrome://flags/#network-service is enabled. "
+ "See http://crbug.com/849935 for details.",
+ base::nullopt /* error_field */);
+ // Calls OnSignedExchangeReceived() to show the outer response in DevTool's
+ // Network panel and the error message in the Preview panel.
+ devtools_proxy_->OnSignedExchangeReceived(base::nullopt /* header */,
+ nullptr /* certificate */,
+ nullptr /* ssl_info */);
+ // This will asynchronously delete |this|.
+ forwarding_client_->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_INVALID_SIGNED_EXCHANGE));
+ return;
+ }
+
// Can't use HttpResponseHeaders::GetMimeType() because SignedExchangeHandler
// checks "v=" parameter.
outer_response.headers->EnumerateHeader(nullptr, "content-type",
@@ -125,60 +172,53 @@ WebPackageLoader::WebPackageLoader(
pending_client_request_ = mojo::MakeRequest(&client_);
}
-WebPackageLoader::~WebPackageLoader() = default;
+SignedExchangeLoader::~SignedExchangeLoader() = default;
-void WebPackageLoader::OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) {
- // Must not be called because this WebPackageLoader and the client endpoints
- // were bound after OnReceiveResponse() is called.
+void SignedExchangeLoader::OnReceiveResponse(
+ const network::ResourceResponseHead& response_head) {
+ // Must not be called because this SignedExchangeLoader and the client
+ // endpoints were bound after OnReceiveResponse() is called.
NOTREACHED();
}
-void WebPackageLoader::OnReceiveRedirect(
+void SignedExchangeLoader::OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head) {
- // Must not be called because this WebPackageLoader and the client endpoints
- // were bound after OnReceiveResponse() is called.
- NOTREACHED();
-}
-
-void WebPackageLoader::OnDataDownloaded(int64_t data_len,
- int64_t encoded_data_len) {
- // Must not be called because this WebPackageLoader and the client endpoints
- // were bound after OnReceiveResponse() is called.
+ // Must not be called because this SignedExchangeLoader and the client
+ // endpoints were bound after OnReceiveResponse() is called.
NOTREACHED();
}
-void WebPackageLoader::OnUploadProgress(int64_t current_position,
- int64_t total_size,
- OnUploadProgressCallback ack_callback) {
- // Must not be called because this WebPackageLoader and the client endpoints
- // were bound after OnReceiveResponse() is called.
+void SignedExchangeLoader::OnUploadProgress(
+ int64_t current_position,
+ int64_t total_size,
+ OnUploadProgressCallback ack_callback) {
+ // Must not be called because this SignedExchangeLoader and the client
+ // endpoints were bound after OnReceiveResponse() is called.
NOTREACHED();
}
-void WebPackageLoader::OnReceiveCachedMetadata(
+void SignedExchangeLoader::OnReceiveCachedMetadata(
const std::vector<uint8_t>& data) {
- // Curerntly CachedMetadata for WebPackage is not supported.
+ // Curerntly CachedMetadata for Signed Exchange is not supported.
NOTREACHED();
}
-void WebPackageLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
+void SignedExchangeLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
// TODO(https://crbug.com/803774): Implement this to progressively update the
// encoded data length in DevTools.
}
-void WebPackageLoader::OnStartLoadingResponseBody(
+void SignedExchangeLoader::OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) {
auto cert_fetcher_factory = SignedExchangeCertFetcherFactory::Create(
std::move(request_initiator_), std::move(url_loader_factory_),
- std::move(url_loader_throttles_getter_));
+ std::move(url_loader_throttles_getter_), throttling_profile_id_);
if (g_signed_exchange_factory_for_testing_) {
signed_exchange_handler_ = g_signed_exchange_factory_for_testing_->Create(
std::make_unique<DataPipeToSourceStream>(std::move(body)),
- base::BindOnce(&WebPackageLoader::OnHTTPExchangeFound,
+ base::BindOnce(&SignedExchangeLoader::OnHTTPExchangeFound,
weak_factory_.GetWeakPtr()),
std::move(cert_fetcher_factory));
return;
@@ -186,21 +226,23 @@ void WebPackageLoader::OnStartLoadingResponseBody(
signed_exchange_handler_ = std::make_unique<SignedExchangeHandler>(
content_type_, std::make_unique<DataPipeToSourceStream>(std::move(body)),
- base::BindOnce(&WebPackageLoader::OnHTTPExchangeFound,
+ base::BindOnce(&SignedExchangeLoader::OnHTTPExchangeFound,
weak_factory_.GetWeakPtr()),
- std::move(cert_fetcher_factory), std::move(request_context_getter_),
- std::move(devtools_proxy_));
+ std::move(cert_fetcher_factory), load_flags_,
+ std::move(request_context_getter_), std::move(devtools_proxy_));
}
-void WebPackageLoader::OnComplete(
+void SignedExchangeLoader::OnComplete(
const network::URLLoaderCompletionStatus& status) {}
-void WebPackageLoader::FollowRedirect(
+void SignedExchangeLoader::FollowRedirect(
+ const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
NOTREACHED();
}
-void WebPackageLoader::ProceedWithResponse() {
+void SignedExchangeLoader::ProceedWithResponse() {
// TODO(https://crbug.com/791049): Remove this when NetworkService is
// enabled by default.
DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
@@ -211,27 +253,27 @@ void WebPackageLoader::ProceedWithResponse() {
client_->OnStartLoadingResponseBody(std::move(pending_body_consumer_));
}
-void WebPackageLoader::SetPriority(net::RequestPriority priority,
- int intra_priority_value) {
+void SignedExchangeLoader::SetPriority(net::RequestPriority priority,
+ int intra_priority_value) {
// TODO(https://crbug.com/803774): Implement this.
}
-void WebPackageLoader::PauseReadingBodyFromNet() {
+void SignedExchangeLoader::PauseReadingBodyFromNet() {
// TODO(https://crbug.com/803774): Implement this.
}
-void WebPackageLoader::ResumeReadingBodyFromNet() {
+void SignedExchangeLoader::ResumeReadingBodyFromNet() {
// TODO(https://crbug.com/803774): Implement this.
}
-void WebPackageLoader::ConnectToClient(
+void SignedExchangeLoader::ConnectToClient(
network::mojom::URLLoaderClientPtr client) {
DCHECK(pending_client_request_.is_pending());
mojo::FuseInterface(std::move(pending_client_request_),
client.PassInterface());
}
-void WebPackageLoader::OnHTTPExchangeFound(
+void SignedExchangeLoader::OnHTTPExchangeFound(
net::Error error,
const GURL& request_url,
const std::string& request_method,
@@ -263,10 +305,9 @@ void WebPackageLoader::OnHTTPExchangeFound(
network::mojom::kURLLoadOptionSendSSLInfoWithResponse)) {
network::ResourceResponseHead response_info = resource_response;
response_info.ssl_info = base::nullopt;
- client_->OnReceiveResponse(response_info, nullptr /* downloaded_file */);
+ client_->OnReceiveResponse(response_info);
} else {
- client_->OnReceiveResponse(resource_response,
- nullptr /* downloaded_file */);
+ client_->OnReceiveResponse(resource_response);
}
// Currently we always assume that we have body.
@@ -278,7 +319,7 @@ void WebPackageLoader::OnHTTPExchangeFound(
body_data_pipe_adapter_ = std::make_unique<SourceStreamToDataPipe>(
std::move(payload_stream), std::move(data_pipe.producer_handle),
- base::BindOnce(&WebPackageLoader::FinishReadingBody,
+ base::BindOnce(&SignedExchangeLoader::FinishReadingBody,
base::Unretained(this)));
if (url_loader_options_ &
@@ -292,7 +333,7 @@ void WebPackageLoader::OnHTTPExchangeFound(
client_->OnStartLoadingResponseBody(std::move(pending_body_consumer_));
}
-void WebPackageLoader::FinishReadingBody(int result) {
+void SignedExchangeLoader::FinishReadingBody(int result) {
// TODO(https://crbug.com/803774): Fill the data length information too.
network::URLLoaderCompletionStatus status;
status.error_code = result;
@@ -309,7 +350,7 @@ void WebPackageLoader::FinishReadingBody(int result) {
client_->OnComplete(status);
}
-void WebPackageLoader::SetSignedExchangeHandlerFactoryForTest(
+void SignedExchangeLoader::SetSignedExchangeHandlerFactoryForTest(
SignedExchangeHandlerFactory* factory) {
g_signed_exchange_factory_for_testing_ = factory;
}
diff --git a/chromium/content/browser/web_package/web_package_loader.h b/chromium/content/browser/web_package/signed_exchange_loader.h
index 0bafea07c9a..2ab0d3a1d66 100644
--- a/chromium/content/browser/web_package/web_package_loader.h
+++ b/chromium/content/browser/web_package/signed_exchange_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_BROWSER_WEB_PACKAGE_WEB_PACKAGE_LOADER_H_
-#define CONTENT_BROWSER_WEB_PACKAGE_WEB_PACKAGE_LOADER_H_
+#ifndef CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_LOADER_H_
+#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_LOADER_H_
#include "base/callback.h"
#include "base/optional.h"
@@ -34,38 +34,39 @@ class SignedExchangeHandlerFactory;
class URLLoaderThrottle;
class SourceStreamToDataPipe;
-// WebPackageLoader handles an origin-signed HTTP exchange response. It is
-// created when a WebPackageRequestHandler recieves an origin-signed HTTP
+// SignedExchangeLoader handles an origin-signed HTTP exchange response. It is
+// created when a SignedExchangeRequestHandler recieves an origin-signed HTTP
// exchange response, and is owned by the handler until the StartLoaderCallback
-// of WebPackageRequestHandler::StartResponse is called. After that, it is
+// of SignedExchangeRequestHandler::StartResponse is called. After that, it is
// owned by the URLLoader mojo endpoint.
-class WebPackageLoader final : public network::mojom::URLLoaderClient,
- public network::mojom::URLLoader {
+class SignedExchangeLoader final : public network::mojom::URLLoaderClient,
+ public network::mojom::URLLoader {
public:
using URLLoaderThrottlesGetter = base::RepeatingCallback<
std::vector<std::unique_ptr<content::URLLoaderThrottle>>()>;
- WebPackageLoader(
+ SignedExchangeLoader(
+ const GURL& outer_request_url,
const network::ResourceResponseHead& outer_response,
network::mojom::URLLoaderClientPtr forwarding_client,
network::mojom::URLLoaderClientEndpointsPtr endpoints,
url::Origin request_initiator,
uint32_t url_loader_options,
+ int load_flags,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id,
std::unique_ptr<SignedExchangeDevToolsProxy> devtools_proxy,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
URLLoaderThrottlesGetter url_loader_throttles_getter,
scoped_refptr<net::URLRequestContextGetter> request_context_getter);
- ~WebPackageLoader() override;
+ ~SignedExchangeLoader() override;
// network::mojom::URLLoaderClient implementation
// Only OnStartLoadingResponseBody() and OnComplete() are called.
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override;
+ const network::ResourceResponseHead& response_head) override;
void OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const network::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;
@@ -76,7 +77,9 @@ class WebPackageLoader final : public network::mojom::URLLoaderClient,
void OnComplete(const network::URLLoaderCompletionStatus& status) override;
// network::mojom::URLLoader implementation
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
@@ -133,6 +136,8 @@ class WebPackageLoader final : public network::mojom::URLLoaderClient,
url::Origin request_initiator_;
const uint32_t url_loader_options_;
+ const int load_flags_;
+ const base::Optional<base::UnguessableToken> throttling_profile_id_;
std::unique_ptr<SignedExchangeDevToolsProxy> devtools_proxy_;
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
URLLoaderThrottlesGetter url_loader_throttles_getter_;
@@ -142,11 +147,11 @@ class WebPackageLoader final : public network::mojom::URLLoaderClient,
std::string content_type_;
- base::WeakPtrFactory<WebPackageLoader> weak_factory_;
+ base::WeakPtrFactory<SignedExchangeLoader> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(WebPackageLoader);
+ DISALLOW_COPY_AND_ASSIGN(SignedExchangeLoader);
};
} // namespace content
-#endif // CONTENT_BROWSER_WEB_PACKAGE_WEB_PACKAGE_LOADER_H_
+#endif // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_LOADER_H_
diff --git a/chromium/content/browser/web_package/web_package_prefetch_handler.cc b/chromium/content/browser/web_package/signed_exchange_prefetch_handler.cc
index b8ced15cd0c..c28252bf4df 100644
--- a/chromium/content/browser/web_package/web_package_prefetch_handler.cc
+++ b/chromium/content/browser/web_package/signed_exchange_prefetch_handler.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/browser/web_package/web_package_prefetch_handler.h"
+#include "content/browser/web_package/signed_exchange_prefetch_handler.h"
#include "base/callback.h"
#include "base/feature_list.h"
#include "content/browser/web_package/signed_exchange_devtools_proxy.h"
+#include "content/browser/web_package/signed_exchange_loader.h"
#include "content/browser/web_package/signed_exchange_url_loader_factory_for_non_network_service.h"
-#include "content/browser/web_package/web_package_loader.h"
#include "content/public/common/content_features.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/url_request/url_request_context_getter.h"
@@ -18,9 +18,11 @@
namespace content {
-WebPackagePrefetchHandler::WebPackagePrefetchHandler(
+SignedExchangePrefetchHandler::SignedExchangePrefetchHandler(
base::RepeatingCallback<int(void)> frame_tree_node_id_getter,
bool report_raw_headers,
+ int load_flags,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id,
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr network_loader,
network::mojom::URLLoaderClientRequest network_client_request,
@@ -46,9 +48,10 @@ WebPackagePrefetchHandler::WebPackagePrefetchHandler(
} else {
url_loader_factory = std::move(network_loader_factory);
}
- web_package_loader_ = std::make_unique<WebPackageLoader>(
- response, std::move(client), std::move(endpoints),
+ signed_exchange_loader_ = std::make_unique<SignedExchangeLoader>(
+ outer_request_url, response, std::move(client), std::move(endpoints),
std::move(request_initiator), network::mojom::kURLLoadOptionNone,
+ load_flags, throttling_profile_id,
std::make_unique<SignedExchangeDevToolsProxy>(
outer_request_url, response, std::move(frame_tree_node_id_getter),
base::nullopt /* devtools_navigation_token */, report_raw_headers),
@@ -56,60 +59,54 @@ WebPackagePrefetchHandler::WebPackagePrefetchHandler(
request_context_getter);
}
-WebPackagePrefetchHandler::~WebPackagePrefetchHandler() = default;
+SignedExchangePrefetchHandler::~SignedExchangePrefetchHandler() = default;
network::mojom::URLLoaderClientRequest
-WebPackagePrefetchHandler::FollowRedirect(
+SignedExchangePrefetchHandler::FollowRedirect(
network::mojom::URLLoaderRequest loader_request) {
- DCHECK(web_package_loader_);
+ DCHECK(signed_exchange_loader_);
network::mojom::URLLoaderClientPtr client;
auto pending_request = mojo::MakeRequest(&client);
- web_package_loader_->ConnectToClient(std::move(client));
- mojo::MakeStrongBinding(std::move(web_package_loader_),
+ signed_exchange_loader_->ConnectToClient(std::move(client));
+ mojo::MakeStrongBinding(std::move(signed_exchange_loader_),
std::move(loader_request));
return pending_request;
}
-void WebPackagePrefetchHandler::OnReceiveResponse(
- const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file) {
+void SignedExchangePrefetchHandler::OnReceiveResponse(
+ const network::ResourceResponseHead& head) {
NOTREACHED();
}
-void WebPackagePrefetchHandler::OnReceiveRedirect(
+void SignedExchangePrefetchHandler::OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& head) {
forwarding_client_->OnReceiveRedirect(redirect_info, head);
}
-void WebPackagePrefetchHandler::OnDataDownloaded(int64_t data_length,
- int64_t encoded_length) {
- NOTREACHED();
-}
-
-void WebPackagePrefetchHandler::OnUploadProgress(
+void SignedExchangePrefetchHandler::OnUploadProgress(
int64_t current_position,
int64_t total_size,
base::OnceCallback<void()> callback) {
NOTREACHED();
}
-void WebPackagePrefetchHandler::OnReceiveCachedMetadata(
+void SignedExchangePrefetchHandler::OnReceiveCachedMetadata(
const std::vector<uint8_t>& data) {
NOTREACHED();
}
-void WebPackagePrefetchHandler::OnTransferSizeUpdated(
+void SignedExchangePrefetchHandler::OnTransferSizeUpdated(
int32_t transfer_size_diff) {
NOTREACHED();
}
-void WebPackagePrefetchHandler::OnStartLoadingResponseBody(
+void SignedExchangePrefetchHandler::OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) {
NOTREACHED();
}
-void WebPackagePrefetchHandler::OnComplete(
+void SignedExchangePrefetchHandler::OnComplete(
const network::URLLoaderCompletionStatus& status) {
forwarding_client_->OnComplete(status);
}
diff --git a/chromium/content/browser/web_package/web_package_prefetch_handler.h b/chromium/content/browser/web_package/signed_exchange_prefetch_handler.h
index f6fc27cbdca..0c3551f4108 100644
--- a/chromium/content/browser/web_package/web_package_prefetch_handler.h
+++ b/chromium/content/browser/web_package/signed_exchange_prefetch_handler.h
@@ -2,11 +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_WEB_PACKAGE_WEB_PACKAGE_PREFETCH_HANDLER_H_
-#define CONTENT_BROWSER_WEB_PACKAGE_WEB_PACKAGE_PREFETCH_HANDLER_H_
+#ifndef CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_PREFETCH_HANDLER_H_
+#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_PREFETCH_HANDLER_H_
#include "base/callback_forward.h"
#include "base/macros.h"
+#include "base/optional.h"
+#include "base/unguessable_token.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/network/public/mojom/url_loader.mojom.h"
@@ -22,21 +24,24 @@ namespace content {
class ResourceContext;
class URLLoaderThrottle;
-class WebPackageLoader;
+class SignedExchangeLoader;
// Attached to each PrefetchURLLoader if the prefetch is for a signed exchange.
-class WebPackagePrefetchHandler final : public network::mojom::URLLoaderClient {
+class SignedExchangePrefetchHandler final
+ : public network::mojom::URLLoaderClient {
public:
using URLLoaderThrottlesGetter = base::RepeatingCallback<
std::vector<std::unique_ptr<content::URLLoaderThrottle>>()>;
// This takes |network_loader| and |network_client| to set up the
- // WebPackageLoader (so that the loader can load data from the network).
+ // SignedExchangeLoader (so that the loader can load data from the network).
// |forwarding_client| is a pointer to the downstream client (typically who
// creates this handler).
- WebPackagePrefetchHandler(
+ SignedExchangePrefetchHandler(
base::RepeatingCallback<int(void)> frame_tree_node_id_getter,
bool report_raw_headers,
+ int load_flags,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id,
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr network_loader,
network::mojom::URLLoaderClientRequest network_client_request,
@@ -48,24 +53,21 @@ class WebPackagePrefetchHandler final : public network::mojom::URLLoaderClient {
scoped_refptr<net::URLRequestContextGetter> request_context_getter,
network::mojom::URLLoaderClient* forwarding_client);
- ~WebPackagePrefetchHandler() override;
+ ~SignedExchangePrefetchHandler() override;
- // This connects |loader_request| to the WebPackageLoader, and returns the
+ // This connects |loader_request| to the SignedExchangeLoader, and returns the
// pending client request to the loader.
// The returned client request can be bound to the downstream client so that
- // they can start directly receiving upcalls from the WebPackageLoader.
+ // they can start directly receiving upcalls from the SignedExchangeLoader.
// After this point |this| can be destructed.
network::mojom::URLLoaderClientRequest FollowRedirect(
network::mojom::URLLoaderRequest loader_request);
private:
// network::mojom::URLLoaderClient overrides:
- void OnReceiveResponse(
- const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override;
+ void OnReceiveResponse(const network::ResourceResponseHead& head) override;
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& head) override;
- void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override;
void OnUploadProgress(int64_t current_position,
int64_t total_size,
base::OnceCallback<void()> callback) override;
@@ -77,13 +79,13 @@ class WebPackagePrefetchHandler final : public network::mojom::URLLoaderClient {
mojo::Binding<network::mojom::URLLoaderClient> loader_client_binding_;
- std::unique_ptr<WebPackageLoader> web_package_loader_;
+ std::unique_ptr<SignedExchangeLoader> signed_exchange_loader_;
network::mojom::URLLoaderClient* forwarding_client_;
- DISALLOW_COPY_AND_ASSIGN(WebPackagePrefetchHandler);
+ DISALLOW_COPY_AND_ASSIGN(SignedExchangePrefetchHandler);
};
} // namespace content
-#endif // CONTENT_BROWSER_WEB_PACKAGE_WEB_PACKAGE_PREFETCH_HANDLER_H_
+#endif // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_PREFETCH_HANDLER_H_
diff --git a/chromium/content/browser/web_package/signed_exchange_prologue.cc b/chromium/content/browser/web_package/signed_exchange_prologue.cc
new file mode 100644
index 00000000000..8f45dc93d90
--- /dev/null
+++ b/chromium/content/browser/web_package/signed_exchange_prologue.cc
@@ -0,0 +1,83 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_package/signed_exchange_prologue.h"
+
+#include "base/strings/stringprintf.h"
+#include "base/trace_event/trace_event.h"
+#include "content/browser/web_package/signed_exchange_utils.h"
+
+namespace content {
+
+namespace {
+
+constexpr char kSignedExchangeMagic[] = "sxg1-b1";
+constexpr size_t kMaximumSignatureHeaderFieldLength = 16 * 1024;
+constexpr size_t kMaximumCBORHeaderLength = 512 * 1024;
+
+} // namespace
+
+constexpr size_t SignedExchangePrologue::kEncodedLengthInBytes;
+size_t SignedExchangePrologue::kEncodedPrologueInBytes =
+ sizeof(kSignedExchangeMagic) +
+ SignedExchangePrologue::kEncodedLengthInBytes * 2;
+
+// static
+size_t SignedExchangePrologue::ParseEncodedLength(
+ base::span<const uint8_t> input) {
+ DCHECK_EQ(input.size(), SignedExchangePrologue::kEncodedLengthInBytes);
+ return static_cast<size_t>(input[0]) << 16 |
+ static_cast<size_t>(input[1]) << 8 | static_cast<size_t>(input[2]);
+}
+
+// static
+base::Optional<SignedExchangePrologue> SignedExchangePrologue::Parse(
+ base::span<const uint8_t> input,
+ SignedExchangeDevToolsProxy* devtools_proxy) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangePrologue::Parse");
+
+ CHECK_EQ(input.size(), kEncodedPrologueInBytes);
+
+ const auto magic_string = input.subspan(0, sizeof(kSignedExchangeMagic));
+ const auto encoded_signature_header_field_length =
+ input.subspan(sizeof(kSignedExchangeMagic), kEncodedLengthInBytes);
+ const auto encoded_cbor_header_length =
+ input.subspan(sizeof(kSignedExchangeMagic) + kEncodedLengthInBytes,
+ kEncodedLengthInBytes);
+
+ if (memcmp(magic_string.data(), kSignedExchangeMagic,
+ sizeof(kSignedExchangeMagic)) != 0) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(devtools_proxy,
+ "Wrong magic string");
+ return base::nullopt;
+ }
+
+ size_t signature_header_field_length =
+ ParseEncodedLength(encoded_signature_header_field_length);
+ size_t cbor_header_length = ParseEncodedLength(encoded_cbor_header_length);
+
+ if (signature_header_field_length > kMaximumSignatureHeaderFieldLength) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
+ base::StringPrintf("Signature header field too long: %zu",
+ signature_header_field_length));
+ return base::nullopt;
+ }
+ if (cbor_header_length > kMaximumCBORHeaderLength) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
+ base::StringPrintf("CBOR header too long: %zu", cbor_header_length));
+ return base::nullopt;
+ }
+
+ return SignedExchangePrologue(signature_header_field_length,
+ cbor_header_length);
+}
+
+size_t SignedExchangePrologue::ComputeFollowingSectionsLength() const {
+ return signature_header_field_length_ + cbor_header_length_;
+}
+
+} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_prologue.h b/chromium/content/browser/web_package/signed_exchange_prologue.h
new file mode 100644
index 00000000000..2106d417e42
--- /dev/null
+++ b/chromium/content/browser/web_package/signed_exchange_prologue.h
@@ -0,0 +1,74 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_PROLOGUE_H_
+#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_PROLOGUE_H_
+
+#include <string>
+
+#include "base/containers/span.h"
+#include "base/gtest_prod_util.h"
+#include "base/optional.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class SignedExchangeDevToolsProxy;
+
+// SignedExchangePrologue maps to the first bytes of
+// the "application/signed-exchange" format.
+// SignedExchangePrologue derives the lengths of the variable-length sections
+// following the prologue bytes.
+class CONTENT_EXPORT SignedExchangePrologue {
+ public:
+ // Parse encoded length of the variable-length field in the signed exchange.
+ // Note: |input| must be pointing to a valid memory address that has at least
+ // |kEncodedLengthInBytes|.
+ static size_t ParseEncodedLength(base::span<const uint8_t> input);
+
+ // Size of the prologue bytes of the "application/signed-exchange" format
+ // which maps to this class.
+ static size_t kEncodedPrologueInBytes;
+
+ // Parses the first bytes of the "application/signed-exchange" format.
+ // |input| must be a valid span with length of kEncodedPrologueInBytes.
+ // If success, returns the result. Otherwise, returns nullopt and
+ // reports the error to |devtools_proxy|.
+ static base::Optional<SignedExchangePrologue> Parse(
+ base::span<const uint8_t> input,
+ SignedExchangeDevToolsProxy* devtools_proxy);
+
+ SignedExchangePrologue(size_t signature_header_field_length,
+ size_t cbor_header_length)
+ : signature_header_field_length_(signature_header_field_length),
+ cbor_header_length_(cbor_header_length) {}
+ SignedExchangePrologue(const SignedExchangePrologue&) = default;
+ ~SignedExchangePrologue() = default;
+
+ size_t signature_header_field_length() const {
+ return signature_header_field_length_;
+ }
+ size_t cbor_header_length() const { return cbor_header_length_; }
+
+ size_t ComputeFollowingSectionsLength() const;
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(SignedExchangePrologueTest, ParseEncodedLength);
+
+ static constexpr size_t kEncodedLengthInBytes = 3;
+
+ // Corresponds to `sigLength` in the spec text.
+ // Encoded length of the Signature header field's value.
+ // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#application-signed-exchange
+ size_t signature_header_field_length_;
+
+ // Corresponds to `headerLength` in the spec text.
+ // Length of the CBOR representation of the request and response headers.
+ // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#application-signed-exchange
+ size_t cbor_header_length_;
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_PROLOGUE_H_
diff --git a/chromium/content/browser/web_package/signed_exchange_prologue_unittest.cc b/chromium/content/browser/web_package/signed_exchange_prologue_unittest.cc
new file mode 100644
index 00000000000..befb942e039
--- /dev/null
+++ b/chromium/content/browser/web_package/signed_exchange_prologue_unittest.cc
@@ -0,0 +1,63 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_package/signed_exchange_prologue.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+TEST(SignedExchangePrologueTest, ParseEncodedLength) {
+ constexpr struct {
+ uint8_t bytes[SignedExchangePrologue::kEncodedLengthInBytes];
+ size_t expected;
+ } kTestCases[] = {
+ {{0x00, 0x00, 0x01}, 1u}, {{0x01, 0xe2, 0x40}, 123456u},
+ };
+
+ int test_element_index = 0;
+ for (const auto& test_case : kTestCases) {
+ SCOPED_TRACE(testing::Message() << "testing case " << test_element_index++);
+ EXPECT_EQ(SignedExchangePrologue::ParseEncodedLength(test_case.bytes),
+ test_case.expected);
+ }
+}
+
+TEST(SignedExchangePrologueTest, Simple) {
+ uint8_t bytes[] = {'s', 'x', 'g', '1', '-', 'b', '1',
+ '\0', 0x00, 0x12, 0x34, 0x00, 0x23, 0x45};
+
+ auto prologue = SignedExchangePrologue::Parse(base::make_span(bytes),
+ nullptr /* devtools_proxy */);
+ EXPECT_TRUE(prologue);
+ EXPECT_EQ(0x1234u, prologue->signature_header_field_length());
+ EXPECT_EQ(0x2345u, prologue->cbor_header_length());
+ EXPECT_EQ(0x3579u, prologue->ComputeFollowingSectionsLength());
+}
+
+TEST(SignedExchangePrologueTest, WrongMagic) {
+ uint8_t bytes[] = {'s', 'x', 'g', '!', '-', 'b', '1',
+ '\0', 0x00, 0x12, 0x34, 0x00, 0x23, 0x45};
+
+ EXPECT_FALSE(SignedExchangePrologue::Parse(base::make_span(bytes),
+ nullptr /* devtools_proxy */));
+}
+
+TEST(SignedExchangePrologueTest, LongSignatureHeaderField) {
+ uint8_t bytes[] = {'s', 'x', 'g', '1', '-', 'b', '1',
+ '\0', 0xff, 0x12, 0x34, 0x00, 0x23, 0x45};
+
+ EXPECT_FALSE(SignedExchangePrologue::Parse(base::make_span(bytes),
+ nullptr /* devtools_proxy */));
+}
+
+TEST(SignedExchangePrologueTest, LongCBORHeader) {
+ uint8_t bytes[] = {'s', 'x', 'g', '1', '-', 'b', '1',
+ '\0', 0x00, 0x12, 0x34, 0xff, 0x23, 0x45};
+
+ EXPECT_FALSE(SignedExchangePrologue::Parse(base::make_span(bytes),
+ nullptr /* devtools_proxy */));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/web_package/web_package_request_handler.cc b/chromium/content/browser/web_package/signed_exchange_request_handler.cc
index f67d3068b54..e5d33126395 100644
--- a/chromium/content/browser/web_package/web_package_request_handler.cc
+++ b/chromium/content/browser/web_package/signed_exchange_request_handler.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/browser/web_package/web_package_request_handler.h"
+#include "content/browser/web_package/signed_exchange_request_handler.h"
#include <memory>
#include "base/bind.h"
#include "base/feature_list.h"
#include "content/browser/web_package/signed_exchange_devtools_proxy.h"
+#include "content/browser/web_package/signed_exchange_loader.h"
#include "content/browser/web_package/signed_exchange_utils.h"
-#include "content/browser/web_package/web_package_loader.h"
#include "content/common/throttling_url_loader.h"
#include "content/public/common/content_features.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
@@ -24,18 +24,20 @@
namespace content {
// static
-bool WebPackageRequestHandler::IsSupportedMimeType(
+bool SignedExchangeRequestHandler::IsSupportedMimeType(
const std::string& mime_type) {
return mime_type == "application/signed-exchange";
}
-WebPackageRequestHandler::WebPackageRequestHandler(
+SignedExchangeRequestHandler::SignedExchangeRequestHandler(
url::Origin request_initiator,
const GURL& url,
uint32_t url_loader_options,
int frame_tree_node_id,
const base::UnguessableToken& devtools_navigation_token,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id,
bool report_raw_headers,
+ int load_flags,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
URLLoaderThrottlesGetter url_loader_throttles_getter,
scoped_refptr<net::URLRequestContextGetter> request_context_getter)
@@ -44,7 +46,9 @@ WebPackageRequestHandler::WebPackageRequestHandler(
url_loader_options_(url_loader_options),
frame_tree_node_id_(frame_tree_node_id),
devtools_navigation_token_(devtools_navigation_token),
+ throttling_profile_id_(throttling_profile_id),
report_raw_headers_(report_raw_headers),
+ load_flags_(load_flags),
url_loader_factory_(url_loader_factory),
url_loader_throttles_getter_(std::move(url_loader_throttles_getter)),
request_context_getter_(std::move(request_context_getter)),
@@ -52,9 +56,9 @@ WebPackageRequestHandler::WebPackageRequestHandler(
DCHECK(signed_exchange_utils::IsSignedExchangeHandlingEnabled());
}
-WebPackageRequestHandler::~WebPackageRequestHandler() = default;
+SignedExchangeRequestHandler::~SignedExchangeRequestHandler() = default;
-void WebPackageRequestHandler::MaybeCreateLoader(
+void SignedExchangeRequestHandler::MaybeCreateLoader(
const network::ResourceRequest& resource_request,
ResourceContext* resource_context,
LoaderCallback callback) {
@@ -62,16 +66,17 @@ void WebPackageRequestHandler::MaybeCreateLoader(
// ongoing matching SignedExchangeHandler which was created by a
// WebPackagePrefetcher.
- if (!web_package_loader_) {
+ if (!signed_exchange_loader_) {
std::move(callback).Run({});
return;
}
- std::move(callback).Run(base::BindOnce(
- &WebPackageRequestHandler::StartResponse, weak_factory_.GetWeakPtr()));
+ std::move(callback).Run(
+ base::BindOnce(&SignedExchangeRequestHandler::StartResponse,
+ weak_factory_.GetWeakPtr()));
}
-bool WebPackageRequestHandler::MaybeCreateLoaderForResponse(
+bool SignedExchangeRequestHandler::MaybeCreateLoaderForResponse(
const network::ResourceResponseHead& response,
network::mojom::URLLoaderPtr* loader,
network::mojom::URLLoaderClientRequest* client_request,
@@ -87,11 +92,12 @@ bool WebPackageRequestHandler::MaybeCreateLoaderForResponse(
// TODO(https://crbug.com/803774): Consider creating a new ThrottlingURLLoader
// or reusing the existing ThrottlingURLLoader by reattaching URLLoaderClient,
// to support SafeBrowsing checking of the content of the WebPackage.
- web_package_loader_ = std::make_unique<WebPackageLoader>(
- response, std::move(client), url_loader->Unbind(),
- std::move(request_initiator_), url_loader_options_,
+ signed_exchange_loader_ = std::make_unique<SignedExchangeLoader>(
+ url_, response, std::move(client), url_loader->Unbind(),
+ std::move(request_initiator_), url_loader_options_, load_flags_,
+ throttling_profile_id_,
std::make_unique<SignedExchangeDevToolsProxy>(
- std::move(url_), response,
+ url_, response,
base::BindRepeating([](int id) { return id; }, frame_tree_node_id_),
std::move(devtools_navigation_token_), report_raw_headers_),
std::move(url_loader_factory_), std::move(url_loader_throttles_getter_),
@@ -99,11 +105,12 @@ bool WebPackageRequestHandler::MaybeCreateLoaderForResponse(
return true;
}
-void WebPackageRequestHandler::StartResponse(
+void SignedExchangeRequestHandler::StartResponse(
network::mojom::URLLoaderRequest request,
network::mojom::URLLoaderClientPtr client) {
- web_package_loader_->ConnectToClient(std::move(client));
- mojo::MakeStrongBinding(std::move(web_package_loader_), std::move(request));
+ signed_exchange_loader_->ConnectToClient(std::move(client));
+ mojo::MakeStrongBinding(std::move(signed_exchange_loader_),
+ std::move(request));
}
} // namespace content
diff --git a/chromium/content/browser/web_package/web_package_request_handler.h b/chromium/content/browser/web_package/signed_exchange_request_handler.h
index 40f75c63441..02fbd7af3d5 100644
--- a/chromium/content/browser/web_package/web_package_request_handler.h
+++ b/chromium/content/browser/web_package/signed_exchange_request_handler.h
@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_BROWSER_WEB_PACKAGE_WEB_PACKAGE_REQUEST_HANDLER_H_
-#define CONTENT_BROWSER_WEB_PACKAGE_WEB_PACKAGE_REQUEST_HANDLER_H_
+#ifndef CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_REQUEST_HANDLER_H_
+#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_REQUEST_HANDLER_H_
#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
#include "base/unguessable_token.h"
#include "content/browser/loader/navigation_loader_interceptor.h"
#include "content/public/common/resource_type.h"
@@ -22,26 +23,28 @@ class SharedURLLoaderFactory;
namespace content {
class URLLoaderThrottle;
-class WebPackageLoader;
+class SignedExchangeLoader;
-class WebPackageRequestHandler final : public NavigationLoaderInterceptor {
+class SignedExchangeRequestHandler final : public NavigationLoaderInterceptor {
public:
using URLLoaderThrottlesGetter = base::RepeatingCallback<
std::vector<std::unique_ptr<content::URLLoaderThrottle>>()>;
static bool IsSupportedMimeType(const std::string& mime_type);
- WebPackageRequestHandler(
+ SignedExchangeRequestHandler(
url::Origin request_initiator,
const GURL& url,
uint32_t url_loader_options,
int frame_tree_node_id,
const base::UnguessableToken& devtools_navigation_token,
+ const base::Optional<base::UnguessableToken>& throttling_profile_id,
bool report_raw_headers,
+ int load_flags,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
URLLoaderThrottlesGetter url_loader_throttles_getter,
scoped_refptr<net::URLRequestContextGetter> request_context_getter);
- ~WebPackageRequestHandler() override;
+ ~SignedExchangeRequestHandler() override;
// NavigationLoaderInterceptor implementation
void MaybeCreateLoader(const network::ResourceRequest& resource_request,
@@ -60,23 +63,25 @@ class WebPackageRequestHandler final : public NavigationLoaderInterceptor {
// Valid after MaybeCreateLoaderForResponse intercepts the request and until
// the loader is re-bound to the new client for the redirected request in
// StartResponse.
- std::unique_ptr<WebPackageLoader> web_package_loader_;
+ std::unique_ptr<SignedExchangeLoader> signed_exchange_loader_;
url::Origin request_initiator_;
GURL url_;
const uint32_t url_loader_options_;
const int frame_tree_node_id_;
base::Optional<const base::UnguessableToken> devtools_navigation_token_;
+ const base::Optional<base::UnguessableToken> throttling_profile_id_;
const bool report_raw_headers_;
+ const int load_flags_;
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
URLLoaderThrottlesGetter url_loader_throttles_getter_;
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
- base::WeakPtrFactory<WebPackageRequestHandler> weak_factory_;
+ base::WeakPtrFactory<SignedExchangeRequestHandler> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(WebPackageRequestHandler);
+ DISALLOW_COPY_AND_ASSIGN(SignedExchangeRequestHandler);
};
} // namespace content
-#endif // CONTENT_BROWSER_WEB_PACKAGE_WEB_PACKAGE_REQUEST_HANDLER_H_
+#endif // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_REQUEST_HANDLER_H_
diff --git a/chromium/content/browser/web_package/web_package_request_handler_browsertest.cc b/chromium/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
index 993fb9234c6..a2251cab8ce 100644
--- a/chromium/content/browser/web_package/web_package_request_handler_browsertest.cc
+++ b/chromium/content/browser/web_package/signed_exchange_request_handler_browsertest.cc
@@ -4,6 +4,7 @@
#include "base/files/file_path.h"
#include "base/path_service.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_restrictions.h"
@@ -17,6 +18,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_features.h"
+#include "content/public/common/content_paths.h"
#include "content/public/common/page_type.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
@@ -27,6 +29,7 @@
#include "net/cert/cert_verify_result.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/test/cert_test_util.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/test_data_directory.h"
#include "net/test/url_request/url_request_mock_http_job.h"
@@ -41,15 +44,13 @@ namespace {
const uint64_t kSignatureHeaderDate = 1520834000; // 2018-03-12T05:53:20Z
-const char* kMockHeaderFileSuffix = ".mock-http-headers";
-
class NavigationFailureObserver : public WebContentsObserver {
public:
explicit NavigationFailureObserver(WebContents* web_contents)
: WebContentsObserver(web_contents) {}
~NavigationFailureObserver() override = default;
- void DidStartNavigation(content::NavigationHandle* handle) override {
+ void DidStartNavigation(NavigationHandle* handle) override {
auto throttle = std::make_unique<TestNavigationThrottle>(handle);
throttle->SetCallback(
TestNavigationThrottle::WILL_FAIL_REQUEST,
@@ -71,27 +72,22 @@ class NavigationFailureObserver : public WebContentsObserver {
} // namespace
-class WebPackageRequestHandlerBrowserTest
- : public ContentBrowserTest,
- public testing::WithParamInterface<bool> {
+class SignedExchangeRequestHandlerBrowserTest : public ContentBrowserTest {
public:
- WebPackageRequestHandlerBrowserTest()
- : mock_cert_verifier_(std::make_unique<net::MockCertVerifier>()){};
- ~WebPackageRequestHandlerBrowserTest() = default;
+ SignedExchangeRequestHandlerBrowserTest()
+ : mock_cert_verifier_(std::make_unique<net::MockCertVerifier>()) {
+ // This installs "root_ca_cert.pem" from which our test certificates are
+ // created. (Needed for the tests that use real certificate, i.e.
+ // RealCertVerifier)
+ net::EmbeddedTestServer::RegisterTestCerts();
+ }
void SetUp() override {
SignedExchangeHandler::SetCertVerifierForTesting(mock_cert_verifier_.get());
SignedExchangeHandler::SetVerificationTimeForTesting(
base::Time::UnixEpoch() +
base::TimeDelta::FromSeconds(kSignatureHeaderDate));
-
- if (is_network_service_enabled()) {
- feature_list_.InitWithFeatures(
- {features::kSignedHTTPExchange, network::features::kNetworkService},
- {});
- } else {
- feature_list_.InitWithFeatures({features::kSignedHTTPExchange}, {});
- }
+ SetUpFeatures();
ContentBrowserTest::SetUp();
}
@@ -103,20 +99,28 @@ class WebPackageRequestHandlerBrowserTest
}
protected:
+ virtual void SetUpFeatures() {
+ feature_list_.InitWithFeatures({features::kSignedHTTPExchange},
+ {network::features::kNetworkService});
+ }
+
static scoped_refptr<net::X509Certificate> LoadCertificate(
const std::string& cert_file) {
base::ScopedAllowBlockingForTesting allow_io;
+ base::FilePath dir_path;
+ base::PathService::Get(content::DIR_TEST_DATA, &dir_path);
+ dir_path = dir_path.AppendASCII("sxg");
+
return net::CreateCertificateChainFromFile(
- net::GetTestCertsDirectory(), cert_file,
- net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
+ dir_path, cert_file, net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
}
void InstallUrlInterceptor(const GURL& url, const std::string& data_path) {
if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
if (!interceptor_) {
interceptor_ =
- std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
- &WebPackageRequestHandlerBrowserTest::OnInterceptCallback,
+ std::make_unique<URLLoaderInterceptor>(base::BindRepeating(
+ &SignedExchangeRequestHandlerBrowserTest::OnInterceptCallback,
base::Unretained(this)));
}
interceptor_data_path_map_[url] = data_path;
@@ -127,28 +131,10 @@ class WebPackageRequestHandlerBrowserTest
}
}
+ base::test::ScopedFeatureList feature_list_;
std::unique_ptr<net::MockCertVerifier> mock_cert_verifier_;
private:
- static std::string ReadFile(const std::string& data_path) {
- base::ScopedAllowBlockingForTesting allow_io;
- base::FilePath root_path;
- CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &root_path));
- std::string contents;
- CHECK(base::ReadFileToString(root_path.AppendASCII(data_path), &contents));
- return contents;
- }
-
- static std::string ReadHeaderFile(const std::string& data_path) {
- std::string header_file_relative_path = data_path + kMockHeaderFileSuffix;
- base::ScopedAllowBlockingForTesting allow_io;
- base::FilePath root_path;
- CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &root_path));
- if (!base::PathExists(root_path.AppendASCII(header_file_relative_path)))
- return "HTTP/1.0 200 OK\n";
- return ReadFile(header_file_relative_path);
- }
-
static void InstallMockInterceptors(const GURL& url,
const std::string& data_path) {
DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
@@ -159,53 +145,58 @@ class WebPackageRequestHandlerBrowserTest
root_path.AppendASCII(data_path)));
}
- bool OnInterceptCallback(
- content::URLLoaderInterceptor::RequestParams* params) {
+ bool OnInterceptCallback(URLLoaderInterceptor::RequestParams* params) {
DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
const auto it = interceptor_data_path_map_.find(params->url_request.url);
if (it == interceptor_data_path_map_.end())
return false;
- content::URLLoaderInterceptor::WriteResponse(
- ReadHeaderFile(it->second), ReadFile(it->second), params->client.get());
+ URLLoaderInterceptor::WriteResponse(it->second, params->client.get());
return true;
}
- bool is_network_service_enabled() const { return GetParam(); }
-
- base::test::ScopedFeatureList feature_list_;
-
- std::unique_ptr<content::URLLoaderInterceptor> interceptor_;
+ std::unique_ptr<URLLoaderInterceptor> interceptor_;
std::map<GURL, std::string> interceptor_data_path_map_;
- DISALLOW_COPY_AND_ASSIGN(WebPackageRequestHandlerBrowserTest);
+ DISALLOW_COPY_AND_ASSIGN(SignedExchangeRequestHandlerBrowserTest);
};
-IN_PROC_BROWSER_TEST_P(WebPackageRequestHandlerBrowserTest, Simple) {
+class SignedExchangeRequestHandlerWithNetworkServiceBrowserTest
+ : public SignedExchangeRequestHandlerBrowserTest {
+ void SetUpFeatures() override {
+ feature_list_.InitWithFeatures(
+ {features::kSignedHTTPExchange, network::features::kNetworkService},
+ {});
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest, Simple) {
InstallUrlInterceptor(
GURL("https://cert.example.org/cert.msg"),
- "content/test/data/htxg/wildcard_example.org.public.pem.msg");
+ "content/test/data/sxg/test.example.org.public.pem.cbor");
- // Make the MockCertVerifier treat the certificate "wildcard.pem" as valid for
- // "*.example.org".
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("wildcard.pem");
+ LoadCertificate("prime256v1-sha256.public.pem");
net::CertVerifyResult dummy_result;
dummy_result.verified_cert = original_cert;
dummy_result.cert_status = net::OK;
- mock_cert_verifier_->AddResultForCertAndHost(original_cert, "*.example.org",
- dummy_result, net::OK);
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
+ mock_cert_verifier_->AddResultForCertAndHost(
+ original_cert, "test.example.org", dummy_result, net::OK);
embedded_test_server()->RegisterRequestMonitor(
base::BindRepeating([](const net::test_server::HttpRequest& request) {
- if (request.relative_url == "/htxg/test.example.org_test.htxg") {
+ if (request.relative_url == "/sxg/test.example.org_test.sxg") {
const auto& accept_value = request.headers.find("accept")->second;
EXPECT_THAT(accept_value,
- ::testing::HasSubstr("application/signed-exchange;v=b0"));
+ ::testing::HasSubstr("application/signed-exchange;v=b1"));
}
}));
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(embedded_test_server()->Start());
- GURL url = embedded_test_server()->GetURL("/htxg/test.example.org_test.htxg");
+ GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");
base::string16 title = base::ASCIIToUTF16("https://test.example.org/test/");
TitleWatcher title_watcher(shell()->web_contents(), title);
NavigateToURL(shell(), url);
@@ -218,8 +209,9 @@ IN_PROC_BROWSER_TEST_P(WebPackageRequestHandlerBrowserTest, Simple) {
SSLStatus::DISPLAYED_INSECURE_CONTENT));
ASSERT_TRUE(entry->GetSSL().certificate);
- // "wildcard_example.org.public.pem.msg" is generated from "wildcard.pem". So
- // the SHA256 of the certificates must match.
+ // "test.example.org.public.pem.cbor" is generated from
+ // "prime256v1-sha256.public.pem". So the SHA256 of the certificates must
+ // match.
const net::SHA256HashValue fingerprint =
net::X509Certificate::CalculateFingerprint256(
entry->GetSSL().certificate->cert_buffer());
@@ -229,53 +221,129 @@ IN_PROC_BROWSER_TEST_P(WebPackageRequestHandlerBrowserTest, Simple) {
EXPECT_EQ(original_fingerprint, fingerprint);
}
-IN_PROC_BROWSER_TEST_P(WebPackageRequestHandlerBrowserTest,
+IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest,
InvalidContentType) {
InstallUrlInterceptor(
GURL("https://cert.example.org/cert.msg"),
- "content/test/data/htxg/wildcard_example.org.public.pem.msg");
+ "content/test/data/sxg/test.example.org.public.pem.cbor");
- // Make the MockCertVerifier treat the certificate "wildcard.pem" as valid for
- // "*.example.org".
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
scoped_refptr<net::X509Certificate> original_cert =
- LoadCertificate("wildcard.pem");
+ LoadCertificate("prime256v1-sha256.public.pem");
net::CertVerifyResult dummy_result;
dummy_result.verified_cert = original_cert;
dummy_result.cert_status = net::OK;
- mock_cert_verifier_->AddResultForCertAndHost(original_cert, "*.example.org",
- dummy_result, net::OK);
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
+ mock_cert_verifier_->AddResultForCertAndHost(
+ original_cert, "test.example.org", dummy_result, net::OK);
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(embedded_test_server()->Start());
GURL url = embedded_test_server()->GetURL(
- "/htxg/test.example.org_test_invalid_content_type.htxg");
+ "/sxg/test.example.org_test_invalid_content_type.sxg");
NavigationFailureObserver failure_observer(shell()->web_contents());
NavigateToURL(shell(), url);
EXPECT_TRUE(failure_observer.did_fail());
NavigationEntry* entry =
shell()->web_contents()->GetController().GetVisibleEntry();
- EXPECT_EQ(content::PAGE_TYPE_ERROR, entry->GetPageType());
+ EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
}
-IN_PROC_BROWSER_TEST_P(WebPackageRequestHandlerBrowserTest, CertNotFound) {
+IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest, CertNotFound) {
InstallUrlInterceptor(GURL("https://cert.example.org/cert.msg"),
- "content/test/data/htxg/404.msg");
+ "content/test/data/sxg/404.msg");
embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(embedded_test_server()->Start());
- GURL url = embedded_test_server()->GetURL("/htxg/test.example.org_test.htxg");
+ GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");
NavigationFailureObserver failure_observer(shell()->web_contents());
NavigateToURL(shell(), url);
EXPECT_TRUE(failure_observer.did_fail());
NavigationEntry* entry =
shell()->web_contents()->GetController().GetVisibleEntry();
- EXPECT_EQ(content::PAGE_TYPE_ERROR, entry->GetPageType());
+ EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
}
-INSTANTIATE_TEST_CASE_P(WebPackageRequestHandlerBrowserTest,
- WebPackageRequestHandlerBrowserTest,
- testing::Bool());
+IN_PROC_BROWSER_TEST_F(
+ SignedExchangeRequestHandlerWithNetworkServiceBrowserTest,
+ NetworkServiceEnabled) {
+ InstallUrlInterceptor(
+ GURL("https://test.example.org/cert.msg"),
+ "content/test/data/sxg/test.example.org.public.pem.cbor");
+
+ // Make the MockCertVerifier treat the certificate
+ // "prime256v1-sha256.public.pem" as valid for "test.example.org".
+ scoped_refptr<net::X509Certificate> original_cert =
+ LoadCertificate("prime256v1-sha256.public.pem");
+ net::CertVerifyResult dummy_result;
+ dummy_result.verified_cert = original_cert;
+ dummy_result.cert_status = net::OK;
+ dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
+ dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
+ mock_cert_verifier_->AddResultForCertAndHost(
+ original_cert, "test.example.org", dummy_result, net::OK);
+
+ embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");
+
+ NavigationFailureObserver failure_observer(shell()->web_contents());
+ NavigateToURL(shell(), url);
+ EXPECT_TRUE(failure_observer.did_fail());
+ NavigationEntry* entry =
+ shell()->web_contents()->GetController().GetVisibleEntry();
+ EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
+}
+
+IN_PROC_BROWSER_TEST_F(SignedExchangeRequestHandlerBrowserTest,
+ RealCertVerifier) {
+ InstallUrlInterceptor(
+ GURL("https://cert.example.org/cert.msg"),
+ "content/test/data/sxg/test.example.org.public.pem.cbor");
+
+ // Use "real" CertVerifier.
+ SignedExchangeHandler::SetCertVerifierForTesting(nullptr);
+
+ embedded_test_server()->RegisterRequestMonitor(
+ base::BindRepeating([](const net::test_server::HttpRequest& request) {
+ if (request.relative_url == "/sxg/test.example.org_test.sxg") {
+ const auto& accept_value = request.headers.find("accept")->second;
+ EXPECT_THAT(accept_value,
+ ::testing::HasSubstr("application/signed-exchange;v=b1"));
+ }
+ }));
+ embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data");
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL url = embedded_test_server()->GetURL("/sxg/test.example.org_test.sxg");
+
+ // "test.example.org_test.sxg" should pass CertVerifier::Verify() and then
+ // fail at SignedExchangeHandler::CheckOCSPStatus() because of the dummy OCSP
+ // response.
+ // TODO(https://crbug.com/815024): Make this test pass the OCSP check. We'll
+ // need to either generate an OCSP response on the fly, or override the OCSP
+ // verification time.
+ content::ConsoleObserverDelegate console_observer(shell()->web_contents(),
+ "*OCSP*");
+ shell()->web_contents()->SetDelegate(&console_observer);
+
+ NavigationFailureObserver failure_observer(shell()->web_contents());
+ NavigateToURL(shell(), url);
+ EXPECT_TRUE(failure_observer.did_fail());
+ NavigationEntry* entry =
+ shell()->web_contents()->GetController().GetVisibleEntry();
+ EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType());
+
+ // Verify that it failed at the OCSP check step.
+ // TODO(https://crbug.com/803774): Find a better way than matching against the
+ // error message. We can probably make DevToolsProxy derive some context from
+ // StoragePartition so that we can record and extract the detailed error
+ // status for testing via that.
+ EXPECT_TRUE(base::StartsWith(console_observer.message(), "OCSP check failed.",
+ base::CompareCase::SENSITIVE));
+}
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_header_parser.cc b/chromium/content/browser/web_package/signed_exchange_signature_header_field.cc
index 97cc0a4c7e3..b7bcef2acae 100644
--- a/chromium/content/browser/web_package/signed_exchange_header_parser.cc
+++ b/chromium/content/browser/web_package/signed_exchange_signature_header_field.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/web_package/signed_exchange_header_parser.h"
+#include "content/browser/web_package/signed_exchange_signature_header_field.h"
#include <map>
#include "base/base64.h"
@@ -19,60 +19,51 @@ namespace content {
namespace {
-// This covers the characters allowed in Numbers, Labels, and Binary Content.
-constexpr char kTokenChars[] =
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_+-*/";
+// This covers the characters allowed in Integers and Identifiers.
+// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-04#section-4.5
+// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-04#section-4.8
+constexpr char kTokenChars[] = "0123456789abcdefghijklmnopqrstuvwxyz_-*/";
-struct ParameterisedLabel {
- std::string label;
+struct ParameterisedIdentifier {
+ std::string identifier;
std::map<std::string, std::string> params;
};
// Parser for (a subset of) Structured Headers defined in [SH].
-// [SH] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-02
+// [SH] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-04
class StructuredHeaderParser {
public:
explicit StructuredHeaderParser(const base::StringPiece& str)
: input_(str), failed_(false) {}
+ // Callers should call this after ParseSomething(), to check if parser has
+ // consumed all the input successfully.
bool ParsedSuccessfully() const { return !failed_ && input_.empty(); }
- // Parses a List ([SH] 4.8) of Strings.
- void ParseStringList(std::vector<std::string>* values) {
- values->push_back(ReadString());
+ // Parses a Parameterised List ([SH] 4.3).
+ void ParseParameterisedList(std::vector<ParameterisedIdentifier>* values) {
+ values->push_back(ParameterisedIdentifier());
+ ParseParameterisedIdentifier(&values->back());
while (!failed_) {
SkipWhitespaces();
if (!ConsumeChar(','))
break;
SkipWhitespaces();
- values->push_back(ReadString());
+ values->push_back(ParameterisedIdentifier());
+ ParseParameterisedIdentifier(&values->back());
}
}
- // Parses a List ([SH] 4.8) of Parameterised Labels.
- void ParseParameterisedLabelList(std::vector<ParameterisedLabel>* values) {
- values->push_back(ParameterisedLabel());
- ParseParameterisedLabel(&values->back());
- while (!failed_) {
- SkipWhitespaces();
- if (!ConsumeChar(','))
- break;
- SkipWhitespaces();
- values->push_back(ParameterisedLabel());
- ParseParameterisedLabel(&values->back());
- }
- }
-
- // Parses a Parameterised Label ([SH] 4.4).
- void ParseParameterisedLabel(ParameterisedLabel* out) {
- std::string label = ReadToken();
- if (label.empty()) {
- DVLOG(1) << "ParseParameterisedLabel: Label expected, got '"
+ // Parses a Parameterised Identifier ([SH] 4.3.2).
+ void ParseParameterisedIdentifier(ParameterisedIdentifier* out) {
+ std::string identifier = ReadToken();
+ if (identifier.empty()) {
+ DVLOG(1) << "ParseParameterisedIdentifier: Identifier expected, got '"
<< input_.front() << "'";
failed_ = true;
return;
}
- out->label = label;
+ out->identifier = identifier;
while (!failed_) {
SkipWhitespaces();
@@ -82,7 +73,7 @@ class StructuredHeaderParser {
std::string name = ReadToken();
if (name.empty()) {
- DVLOG(1) << "ParseParameterisedLabel: Label expected, got '"
+ DVLOG(1) << "ParseParameterisedIdentifier: Identifier expected, got '"
<< input_.front() << "'";
failed_ = true;
return;
@@ -91,7 +82,8 @@ class StructuredHeaderParser {
if (ConsumeChar('='))
value = ReadItem();
if (!out->params.insert(std::make_pair(name, value)).second) {
- DVLOG(1) << "ParseParameterisedLabel: duplicated parameter: " << name;
+ DVLOG(1) << "ParseParameterisedIdentifier: duplicated parameter: "
+ << name;
failed_ = true;
return;
}
@@ -120,7 +112,7 @@ class StructuredHeaderParser {
return false;
}
- // [SH] 4.2. Strings
+ // [SH] 4.7. Strings
std::string ReadString() {
std::string s;
if (!ConsumeChar('"')) {
@@ -150,25 +142,31 @@ class StructuredHeaderParser {
return s;
}
- // [SH] 4.5. Binary Content
+ // [SH] 4.9. Binary Content
std::string ReadBinary() {
if (!ConsumeChar('*')) {
DVLOG(1) << "ReadBinary: '*' expected, got '" << input_.front() << "'";
failed_ = true;
return std::string();
}
- std::string base64 = ReadToken();
- // Binary Content does not have padding, so we have to add it.
- base64.resize((base64.size() + 3) / 4 * 4, '=');
+ size_t len = input_.find('*');
+ if (len == base::StringPiece::npos) {
+ DVLOG(1) << "ReadBinary: missing closing '*'";
+ failed_ = true;
+ return std::string();
+ }
+ base::StringPiece base64 = input_.substr(0, len);
std::string binary;
if (!base::Base64Decode(base64, &binary)) {
DVLOG(1) << "ReadBinary: failed to decode base64: " << base64;
failed_ = true;
}
+ input_.remove_prefix(len);
+ ConsumeChar('*');
return binary;
}
- // [SH] 4.6. Items
+ // [SH] 4.4. Items
std::string ReadItem() {
if (input_.empty()) {
DVLOG(1) << "ReadItem: unexpected EOF";
@@ -180,7 +178,7 @@ class StructuredHeaderParser {
return ReadString();
case '*':
return ReadBinary();
- default: // label or number
+ default: // identifier or integer
return ReadToken();
}
}
@@ -192,20 +190,19 @@ class StructuredHeaderParser {
} // namespace
// static
-base::Optional<std::vector<SignedExchangeHeaderParser::Signature>>
-SignedExchangeHeaderParser::ParseSignature(
+base::Optional<std::vector<SignedExchangeSignatureHeaderField::Signature>>
+SignedExchangeSignatureHeaderField::ParseSignature(
base::StringPiece signature_str,
SignedExchangeDevToolsProxy* devtools_proxy) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHeaderParser::ParseSignature");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeSignatureHeaderField::ParseSignature");
StructuredHeaderParser parser(signature_str);
- std::vector<ParameterisedLabel> values;
- parser.ParseParameterisedLabelList(&values);
+ std::vector<ParameterisedIdentifier> values;
+ parser.ParseParameterisedList(&values);
if (!parser.ParsedSuccessfully()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeaderParser::ParseSignature",
- "Failed to parse signature header.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "Failed to parse signature header.");
return base::nullopt;
}
@@ -214,37 +211,38 @@ SignedExchangeHeaderParser::ParseSignature(
for (auto& value : values) {
signatures.push_back(Signature());
Signature& sig = signatures.back();
- sig.label = value.label;
+ sig.label = value.identifier;
sig.sig = value.params[kSig];
if (sig.sig.empty()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeaderParser::ParseSignature",
- "'sig' parameter is not set,");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "'sig' parameter is not set,");
return base::nullopt;
}
sig.integrity = value.params[kIntegrity];
if (sig.integrity.empty()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeaderParser::ParseSignature",
- "'integrity' parameter is not set.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "'integrity' parameter is not set.");
return base::nullopt;
}
sig.cert_url = GURL(value.params[kCertUrl]);
if (!sig.cert_url.is_valid() || sig.cert_url.has_ref()) {
// TODO(https://crbug.com/819467) : When we will support "ed25519Key", the
- // params may not have "certUrl".
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeaderParser::ParseSignature",
- "'certUrl' parameter is not a valid URL.");
+ // params may not have "cert-url".
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "'cert-url' parameter is not a valid URL.");
+ return base::nullopt;
+ }
+ if (!sig.cert_url.SchemeIs("https") && !sig.cert_url.SchemeIs("data")) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "'cert-url' should have 'https' or 'data' scheme.");
return base::nullopt;
}
const std::string cert_sha256_string = value.params[kCertSha256Key];
if (cert_sha256_string.size() != crypto::kSHA256Length) {
// TODO(https://crbug.com/819467) : When we will support "ed25519Key", the
- // params may not have "certSha256".
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeaderParser::ParseSignature",
- "'certSha256' parameter is not a SHA-256 digest.");
+ // params may not have "cert-sha256".
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "'cert-sha256' parameter is not a SHA-256 digest.");
return base::nullopt;
}
net::SHA256HashValue cert_sha256;
@@ -254,52 +252,49 @@ SignedExchangeHeaderParser::ParseSignature(
// sig.ed25519_key = value.params["ed25519Key"];
sig.validity_url = GURL(value.params[kValidityUrlKey]);
if (!sig.validity_url.is_valid()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeaderParser::ParseSignature",
- "'validityUrl' parameter is not a valid URL.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "'validity-url' parameter is not a valid URL.");
return base::nullopt;
}
if (sig.validity_url.has_ref()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeaderParser::ParseSignature",
- "'validityUrl' parameter can't have a fragment.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "'validity-url' parameter can't have a fragment.");
+ return base::nullopt;
+ }
+ if (!sig.validity_url.SchemeIs("https")) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "'validity-url' should have 'https' scheme.");
return base::nullopt;
}
if (!base::StringToUint64(value.params[kDateKey], &sig.date)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeaderParser::ParseSignature",
- "'date' parameter is not a number.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "'date' parameter is not a number.");
return base::nullopt;
}
if (!base::StringToUint64(value.params[kExpiresKey], &sig.expires)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeHeaderParser::ParseSignature",
- "'expires' parameter is not a number.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "'expires' parameter is not a number.");
return base::nullopt;
}
}
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeHeaderParser::ParseSignature");
return signatures;
}
// static
-bool SignedExchangeHeaderParser::GetVersionParamFromContentType(
+bool SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
base::StringPiece content_type,
base::Optional<SignedExchangeVersion>* version_param) {
DCHECK(version_param);
StructuredHeaderParser parser(content_type);
- ParameterisedLabel parameterised_label;
- parser.ParseParameterisedLabel(&parameterised_label);
+ ParameterisedIdentifier parameterised_identifier;
+ parser.ParseParameterisedIdentifier(&parameterised_identifier);
if (!parser.ParsedSuccessfully())
return false;
- const auto it = parameterised_label.params.find("v");
- if (it == parameterised_label.params.end()) {
+ const auto it = parameterised_identifier.params.find("v");
+ if (it == parameterised_identifier.params.end()) {
*version_param = base::nullopt;
} else {
- if (it->second == "b0")
- *version_param = SignedExchangeVersion::kB0;
- else if (it->second == "b1")
+ if (it->second == "b1")
*version_param = SignedExchangeVersion::kB1;
else
return false;
@@ -307,9 +302,9 @@ bool SignedExchangeHeaderParser::GetVersionParamFromContentType(
return true;
}
-SignedExchangeHeaderParser::Signature::Signature() = default;
-SignedExchangeHeaderParser::Signature::Signature(const Signature& other) =
- default;
-SignedExchangeHeaderParser::Signature::~Signature() = default;
+SignedExchangeSignatureHeaderField::Signature::Signature() = default;
+SignedExchangeSignatureHeaderField::Signature::Signature(
+ const Signature& other) = default;
+SignedExchangeSignatureHeaderField::Signature::~Signature() = default;
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_header_parser.h b/chromium/content/browser/web_package/signed_exchange_signature_header_field.h
index 01697eb5362..166850ce21d 100644
--- a/chromium/content/browser/web_package/signed_exchange_header_parser.h
+++ b/chromium/content/browser/web_package/signed_exchange_signature_header_field.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_WEB_PACKAGE_SIGNED_EXCHANGE_HEADER_PARSER_H_
-#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_HEADER_PARSER_H_
+#ifndef CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_SIGNATURE_HEADER_FIELD_H_
+#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_SIGNATURE_HEADER_FIELD_H_
#include <stdint.h>
#include <string>
@@ -22,9 +22,10 @@ namespace content {
class SignedExchangeDevToolsProxy;
-// Provide parsers for signed-exchange headers.
+// SignedExchangeSignatureHeaderField provides parser for signed exchange's
+// `Signature` header field.
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html
-class CONTENT_EXPORT SignedExchangeHeaderParser {
+class CONTENT_EXPORT SignedExchangeSignatureHeaderField {
public:
struct CONTENT_EXPORT Signature {
Signature();
@@ -49,6 +50,7 @@ class CONTENT_EXPORT SignedExchangeHeaderParser {
base::StringPiece signature_str,
SignedExchangeDevToolsProxy* devtools_proxy);
+ // TODO(kouhei): Move this to another class.
// Parses |content_type| to get the value of "v=" parameter of the signed
// exchange, and converts to SignedExchangeVersion. Returns false if failed to
// parse.
@@ -59,4 +61,4 @@ class CONTENT_EXPORT SignedExchangeHeaderParser {
} // namespace content
-#endif // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_HEADER_PARSER_H_
+#endif // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_SIGNATURE_HEADER_FIELD_H_
diff --git a/chromium/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc b/chromium/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc
new file mode 100644
index 00000000000..d47655171a9
--- /dev/null
+++ b/chromium/content/browser/web_package/signed_exchange_signature_header_field_unittest.cc
@@ -0,0 +1,333 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/web_package/signed_exchange_signature_header_field.h"
+
+#include "base/callback.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+class SignedExchangeSignatureHeaderFieldTest : public ::testing::Test {
+ protected:
+ SignedExchangeSignatureHeaderFieldTest() {}
+};
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, ParseSignature) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https://example.com/resource.validity.1511128380\";"
+ " cert-url=\"https://example.com/oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180,"
+ "sig2;"
+ " sig=*MEQCIGjZRqTRf9iKNkGFyzRMTFgwf/BrY2ZNIP/dykhUV0aYAiBTXg+8wujoT4n/W+"
+ "cNgb7pGqQvIUGYZ8u8HZJ5YH26Qg==*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https://example.com/resource.validity.1511128380\";"
+ " cert-url=\"https://example.com/newcerts\";"
+ " cert-sha256=*J/lEm9kNRODdCmINbvitpvdYKNQ+YgBj99DlYp4fEXw=*;"
+ " date=1511128380; expires=1511733180";
+
+ const uint8_t decoded_sig1[] = {
+ 0x30, 0x45, 0x02, 0x21, 0x00, 0xd7, 0x94, 0x8d, 0xa0, 0x37, 0x74, 0x4d,
+ 0x06, 0x58, 0x05, 0x8a, 0xe4, 0x4d, 0x16, 0x96, 0x57, 0x70, 0x32, 0x1a,
+ 0x52, 0x95, 0xfa, 0x1c, 0x81, 0x30, 0x71, 0x91, 0x1c, 0xd1, 0xc6, 0x58,
+ 0x2c, 0x02, 0x20, 0x6b, 0xd0, 0xec, 0x54, 0xe3, 0x0c, 0xfa, 0x0e, 0x58,
+ 0xa7, 0x01, 0x01, 0x74, 0x65, 0xb7, 0xb1, 0x2f, 0x9b, 0xbe, 0x79, 0x80,
+ 0x24, 0x98, 0x92, 0x33, 0x08, 0x6e, 0x05, 0xda, 0xa9, 0xe5, 0x46};
+ const net::SHA256HashValue decoded_cert_sha256_1 = {
+ {0x5b, 0xbb, 0x81, 0xf7, 0xaf, 0x5d, 0x15, 0x6d, 0xcc, 0x6f, 0x96,
+ 0x5e, 0x7c, 0xf4, 0xbd, 0x4e, 0xae, 0x59, 0x6c, 0x7e, 0x62, 0x4a,
+ 0x63, 0x88, 0x2e, 0x98, 0xef, 0xda, 0xa1, 0x00, 0xae, 0x62}};
+ const uint8_t decoded_sig2[] = {
+ 0x30, 0x44, 0x02, 0x20, 0x68, 0xd9, 0x46, 0xa4, 0xd1, 0x7f, 0xd8, 0x8a,
+ 0x36, 0x41, 0x85, 0xcb, 0x34, 0x4c, 0x4c, 0x58, 0x30, 0x7f, 0xf0, 0x6b,
+ 0x63, 0x66, 0x4d, 0x20, 0xff, 0xdd, 0xca, 0x48, 0x54, 0x57, 0x46, 0x98,
+ 0x02, 0x20, 0x53, 0x5e, 0x0f, 0xbc, 0xc2, 0xe8, 0xe8, 0x4f, 0x89, 0xff,
+ 0x5b, 0xe7, 0x0d, 0x81, 0xbe, 0xe9, 0x1a, 0xa4, 0x2f, 0x21, 0x41, 0x98,
+ 0x67, 0xcb, 0xbc, 0x1d, 0x92, 0x79, 0x60, 0x7d, 0xba, 0x42};
+ const net::SHA256HashValue decoded_cert_sha256_2 = {
+ {0x27, 0xf9, 0x44, 0x9b, 0xd9, 0x0d, 0x44, 0xe0, 0xdd, 0x0a, 0x62,
+ 0x0d, 0x6e, 0xf8, 0xad, 0xa6, 0xf7, 0x58, 0x28, 0xd4, 0x3e, 0x62,
+ 0x00, 0x63, 0xf7, 0xd0, 0xe5, 0x62, 0x9e, 0x1f, 0x11, 0x7c}};
+
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ ASSERT_TRUE(signatures.has_value());
+ ASSERT_EQ(signatures->size(), 2u);
+
+ EXPECT_EQ(signatures->at(0).label, "sig1");
+ EXPECT_EQ(signatures->at(0).sig,
+ std::string(reinterpret_cast<const char*>(decoded_sig1),
+ sizeof(decoded_sig1)));
+ EXPECT_EQ(signatures->at(0).integrity, "mi-draft2");
+ EXPECT_EQ(signatures->at(0).validity_url,
+ "https://example.com/resource.validity.1511128380");
+ EXPECT_EQ(signatures->at(0).cert_url, "https://example.com/oldcerts");
+ EXPECT_EQ(signatures->at(0).cert_sha256, decoded_cert_sha256_1);
+ EXPECT_EQ(signatures->at(0).date, 1511128380ul);
+ EXPECT_EQ(signatures->at(0).expires, 1511733180ul);
+
+ EXPECT_EQ(signatures->at(1).label, "sig2");
+ EXPECT_EQ(signatures->at(1).sig,
+ std::string(reinterpret_cast<const char*>(decoded_sig2),
+ sizeof(decoded_sig2)));
+ EXPECT_EQ(signatures->at(1).integrity, "mi-draft2");
+ EXPECT_EQ(signatures->at(1).validity_url,
+ "https://example.com/resource.validity.1511128380");
+ EXPECT_EQ(signatures->at(1).cert_url, "https://example.com/newcerts");
+ EXPECT_EQ(signatures->at(1).cert_sha256, decoded_cert_sha256_2);
+ EXPECT_EQ(signatures->at(1).date, 1511128380ul);
+ EXPECT_EQ(signatures->at(1).expires, 1511733180ul);
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, IncompleteSignature) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ // no integrity= param
+ " validity-url=\"https://example.com/resource.validity.1511128380\";"
+ " cert-url=\"https://example.com/oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, DuplicatedParam) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https://example.com/resource.validity.1511128380\";"
+ " cert-url=\"https://example.com/oldcerts\";"
+ " cert-url=\"https://example.com/oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, InvalidCertURL) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https://example.com/resource.validity.1511128380\";"
+ " cert-url=\"https:://example.com/oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, CertURLWithFragment) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https://example.com/resource.validity.1511128380\";"
+ " cert-url=\"https://example.com/oldcerts#test\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, CertURLHttpShouldFail) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https://example.com/resource.validity.1511128380\";"
+ " cert-url=\"http://example.com/oldcerts#test\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, RelativeCertURL) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https://example.com/resource.validity.1511128380\";"
+ " cert-url=\"oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, InvalidValidityUrl) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https:://example.com/resource.validity.1511128380\";"
+ " cert-url=\"https://example.com/oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, ValidityUrlWithFragment) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https://example.com/resource.validity.1511128380#test\";"
+ " cert-url=\"https://example.com/oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, ValidityUrlHttpShouldFail) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"http://example.com/resource.validity.1511128380#test\";"
+ " cert-url=\"https://example.com/oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, RelativeValidityUrl) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"resource.validity.1511128380\";"
+ " cert-url=\"https://example.com/oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, InvalidCertSHA256) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https://example.com/resource.validity.1511128380\";"
+ " cert-url=\"https://example.com/oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefPS9;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, OpenQuoteAtEnd) {
+ const char hdr_string[] = "sig1; sig=\"";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, AsteriskInTheMiddleOfBinary) {
+ const char hdr_string[] =
+ "sig1;"
+ " sig=*MEUCIQDXlI2gN3RNBlgFiuRNFpZXcDIaUpX6HIEwcZEc0cZYLAIga9DsVOMM+"
+ "g5YpwEBdGW3sS+bvnmAJJiSMwhuBdqp5UY=*;"
+ " integrity=\"mi-draft2\";"
+ " validity-url=\"https://example.com/resource.validity.1511128380\";"
+ " cert-url=\"https://example.com/oldcerts\";"
+ " cert-sha256=*W7uB969dFW3Mb5ZefP*S9Tq5ZbH5iSmOILpjv2qEArmI=*;"
+ " date=1511128380; expires=1511733180";
+ auto signatures = SignedExchangeSignatureHeaderField::ParseSignature(
+ hdr_string, nullptr /* devtools_proxy */);
+ EXPECT_FALSE(signatures.has_value());
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, VersionParam_None) {
+ const char content_type[] = "application/signed-exchange";
+ base::Optional<SignedExchangeVersion> version;
+ EXPECT_TRUE(
+ SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
+ content_type, &version));
+ EXPECT_FALSE(version);
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, VersionParam_NoneWithSemicolon) {
+ const char content_type[] = "application/signed-exchange;";
+ base::Optional<SignedExchangeVersion> version;
+ EXPECT_FALSE(
+ SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
+ content_type, &version));
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, VersionParam_EmptyString) {
+ const char content_type[] = "application/signed-exchange;v=";
+ base::Optional<SignedExchangeVersion> version;
+ EXPECT_FALSE(
+ SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
+ content_type, &version));
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, VersionParam_Simple) {
+ const char content_type[] = "application/signed-exchange;v=b1";
+ base::Optional<SignedExchangeVersion> version;
+ EXPECT_TRUE(
+ SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
+ content_type, &version));
+ ASSERT_TRUE(version);
+ EXPECT_EQ(*version, SignedExchangeVersion::kB1);
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest, VersionParam_SimpleWithSpace) {
+ const char content_type[] = "application/signed-exchange; v=b1";
+ base::Optional<SignedExchangeVersion> version;
+ EXPECT_TRUE(
+ SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
+ content_type, &version));
+ ASSERT_TRUE(version);
+ EXPECT_EQ(*version, SignedExchangeVersion::kB1);
+}
+
+TEST_F(SignedExchangeSignatureHeaderFieldTest,
+ VersionParam_SimpleWithDoublequotes) {
+ const char content_type[] = "application/signed-exchange;v=\"b1\"";
+ base::Optional<SignedExchangeVersion> version;
+ EXPECT_TRUE(
+ SignedExchangeSignatureHeaderField::GetVersionParamFromContentType(
+ content_type, &version));
+ ASSERT_TRUE(version);
+ EXPECT_EQ(*version, SignedExchangeVersion::kB1);
+}
+
+} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc b/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc
index cf1322d96aa..e29e5c8cf49 100644
--- a/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc
+++ b/chromium/content/browser/web_package/signed_exchange_signature_verifier.cc
@@ -14,8 +14,8 @@
#include "base/trace_event/trace_event.h"
#include "components/cbor/cbor_writer.h"
#include "content/browser/web_package/signed_exchange_consts.h"
-#include "content/browser/web_package/signed_exchange_header.h"
-#include "content/browser/web_package/signed_exchange_header_parser.h"
+#include "content/browser/web_package/signed_exchange_envelope.h"
+#include "content/browser/web_package/signed_exchange_signature_header_field.h"
#include "content/browser/web_package/signed_exchange_utils.h"
#include "crypto/signature_verifier.h"
#include "net/cert/asn1_util.h"
@@ -29,7 +29,7 @@ namespace content {
namespace {
-// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#signature-validity
+// https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#signature-validity
// Step 7. "Let message be the concatenation of the following byte strings."
constexpr uint8_t kMessageHeader[] =
// 7.1. "A string that consists of octet 32 (0x20) repeated 64 times."
@@ -38,37 +38,38 @@ constexpr uint8_t kMessageHeader[] =
"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
- // 7.2. "A context string: the ASCII encoding of "HTTP Exchange"."
+ // 7.2. "A context string: the ASCII encoding of "HTTP Exchange 1"." ...
+ // "but implementations of drafts MUST NOT use it and MUST use another
+ // draft-specific string beginning with "HTTP Exchange 1 " instead."
// [spec text]
// 7.3. "A single 0 byte which serves as a separator." [spec text]
- "HTTP Exchange";
+ "HTTP Exchange 1 b1";
base::Optional<cbor::CBORValue> GenerateCanonicalRequestCBOR(
- const SignedExchangeHeader& header) {
+ const SignedExchangeEnvelope& envelope) {
cbor::CBORValue::MapValue map;
map.insert_or_assign(
cbor::CBORValue(kMethodKey, cbor::CBORValue::Type::BYTE_STRING),
- cbor::CBORValue(header.request_method(),
+ cbor::CBORValue(envelope.request_method(),
cbor::CBORValue::Type::BYTE_STRING));
map.insert_or_assign(
cbor::CBORValue(kUrlKey, cbor::CBORValue::Type::BYTE_STRING),
- cbor::CBORValue(header.request_url().spec(),
+ cbor::CBORValue(envelope.request_url().spec(),
cbor::CBORValue::Type::BYTE_STRING));
return cbor::CBORValue(map);
}
base::Optional<cbor::CBORValue> GenerateCanonicalResponseCBOR(
- const SignedExchangeHeader& header) {
- const auto& headers = header.response_headers();
+ const SignedExchangeEnvelope& envelope) {
+ const auto& headers = envelope.response_headers();
cbor::CBORValue::MapValue map;
- std::string response_code_str = base::NumberToString(header.response_code());
+ std::string response_code_str =
+ base::NumberToString(envelope.response_code());
map.insert_or_assign(
cbor::CBORValue(kStatusKey, cbor::CBORValue::Type::BYTE_STRING),
cbor::CBORValue(response_code_str, cbor::CBORValue::Type::BYTE_STRING));
for (const auto& pair : headers) {
- if (pair.first == kSignature)
- continue;
map.insert_or_assign(
cbor::CBORValue(pair.first, cbor::CBORValue::Type::BYTE_STRING),
cbor::CBORValue(pair.second, cbor::CBORValue::Type::BYTE_STRING));
@@ -76,14 +77,14 @@ base::Optional<cbor::CBORValue> GenerateCanonicalResponseCBOR(
return cbor::CBORValue(map);
}
-// Generate CBORValue from |header| as specified in:
+// Generate CBORValue from |envelope| as specified in:
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#cbor-representation
base::Optional<cbor::CBORValue> GenerateCanonicalExchangeHeadersCBOR(
- const SignedExchangeHeader& header) {
- auto req_val = GenerateCanonicalRequestCBOR(header);
+ const SignedExchangeEnvelope& envelope) {
+ auto req_val = GenerateCanonicalRequestCBOR(envelope);
if (!req_val)
return base::nullopt;
- auto res_val = GenerateCanonicalResponseCBOR(header);
+ auto res_val = GenerateCanonicalResponseCBOR(envelope);
if (!res_val)
return base::nullopt;
@@ -94,116 +95,117 @@ base::Optional<cbor::CBORValue> GenerateCanonicalExchangeHeadersCBOR(
}
// Generate a CBOR map value as specified in
-// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#signature-validity
+// https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#signature-validity
// Step 7.4.
base::Optional<cbor::CBORValue> GenerateSignedMessageCBOR(
- const SignedExchangeHeader& header) {
- auto headers_val = GenerateCanonicalExchangeHeadersCBOR(header);
+ const SignedExchangeEnvelope& envelope) {
+ auto headers_val = GenerateCanonicalExchangeHeadersCBOR(envelope);
if (!headers_val)
return base::nullopt;
// 7.4. "The bytes of the canonical CBOR serialization (Section 3.4) of
// a CBOR map mapping:" [spec text]
cbor::CBORValue::MapValue map;
- // 7.4.1. "If certSha256 is set: The text string "certSha256" to the byte
- // string value of certSha256." [spec text]
- if (header.signature().cert_sha256.has_value()) {
+ // 7.4.1. "If cert-sha256 is set: The text string "cert-sha256" to the byte
+ // string value of cert-sha256." [spec text]
+ if (envelope.signature().cert_sha256.has_value()) {
map.insert_or_assign(
cbor::CBORValue(kCertSha256Key),
cbor::CBORValue(
base::StringPiece(reinterpret_cast<const char*>(
- header.signature().cert_sha256->data),
- sizeof(header.signature().cert_sha256->data)),
+ envelope.signature().cert_sha256->data),
+ sizeof(envelope.signature().cert_sha256->data)),
cbor::CBORValue::Type::BYTE_STRING));
}
- // 7.4.2. "The text string "validityUrl" to the byte string value of
- // validityUrl." [spec text]
+ // 7.4.2. "The text string "validity-url" to the byte string value of
+ // validity-url." [spec text]
map.insert_or_assign(cbor::CBORValue(kValidityUrlKey),
- cbor::CBORValue(header.signature().validity_url.spec(),
+ cbor::CBORValue(envelope.signature().validity_url.spec(),
cbor::CBORValue::Type::BYTE_STRING));
// 7.4.3. "The text string "date" to the integer value of date." [spec text]
- if (!base::IsValueInRangeForNumericType<int64_t>(header.signature().date))
+ if (!base::IsValueInRangeForNumericType<int64_t>(envelope.signature().date))
return base::nullopt;
map.insert_or_assign(
cbor::CBORValue(kDateKey),
- cbor::CBORValue(base::checked_cast<int64_t>(header.signature().date)));
+ cbor::CBORValue(base::checked_cast<int64_t>(envelope.signature().date)));
// 7.4.4. "The text string "expires" to the integer value of expires."
// [spec text]
- if (!base::IsValueInRangeForNumericType<int64_t>(header.signature().expires))
+ if (!base::IsValueInRangeForNumericType<int64_t>(
+ envelope.signature().expires))
return base::nullopt;
- map.insert_or_assign(
- cbor::CBORValue(kExpiresKey),
- cbor::CBORValue(base::checked_cast<int64_t>(header.signature().expires)));
+ map.insert_or_assign(cbor::CBORValue(kExpiresKey),
+ cbor::CBORValue(base::checked_cast<int64_t>(
+ envelope.signature().expires)));
// 7.4.5. "The text string "headers" to the CBOR representation
// (Section 3.2) of exchange's headers." [spec text]
map.insert_or_assign(cbor::CBORValue(kHeadersKey), std::move(*headers_val));
return cbor::CBORValue(map);
}
-bool VerifySignature(base::span<const uint8_t> sig,
- base::span<const uint8_t> msg,
- scoped_refptr<net::X509Certificate> cert,
- SignedExchangeDevToolsProxy* devtools_proxy) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"), "VerifySignature");
+base::Optional<crypto::SignatureVerifier::SignatureAlgorithm>
+GetSignatureAlgorithm(scoped_refptr<net::X509Certificate> cert,
+ SignedExchangeDevToolsProxy* devtools_proxy) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), "VerifySignature");
base::StringPiece spki;
if (!net::asn1::ExtractSPKIFromDERCert(
net::x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()),
&spki)) {
- TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("loading"), "VerifySignature",
- "error", "Failed to extract SPKI.");
- return false;
+ signed_exchange_utils::ReportErrorAndTraceEvent(devtools_proxy,
+ "Failed to extract SPKI.");
+ return base::nullopt;
}
- crypto::SignatureVerifier::SignatureAlgorithm algorithm;
CBS cbs;
CBS_init(&cbs, reinterpret_cast<const uint8_t*>(spki.data()), spki.size());
bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_public_key(&cbs));
if (!pkey || CBS_len(&cbs) != 0) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "VerifySignature", "Failed to parse public key.");
- return false;
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "Failed to parse public key.");
+ return base::nullopt;
}
- switch (EVP_PKEY_id(pkey.get())) {
- case EVP_PKEY_RSA:
- algorithm = crypto::SignatureVerifier::RSA_PSS_SHA256;
- break;
- case EVP_PKEY_EC: {
- const EC_GROUP* group =
- EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey.get()));
- switch (EC_GROUP_get_curve_name(group)) {
- case NID_X9_62_prime256v1:
- algorithm = crypto::SignatureVerifier::ECDSA_SHA256;
- break;
- default:
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "VerifySignature", "Unsupported EC group.");
- return false;
- }
- break;
- }
- default:
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "VerifySignature", "Unsupported public key type.");
- return false;
+
+ int pkey_id = EVP_PKEY_id(pkey.get());
+ if (pkey_id != EVP_PKEY_EC) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
+ base::StringPrintf("Unsupported public key type: %d. Only ECDSA keys "
+ "on the secp256r1 curve are supported.",
+ pkey_id));
+ return base::nullopt;
}
+ const EC_GROUP* group = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey.get()));
+ int curve_name = EC_GROUP_get_curve_name(group);
+ if (curve_name == NID_X9_62_prime256v1)
+ return crypto::SignatureVerifier::ECDSA_SHA256;
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
+ base::StringPrintf("Unsupported EC group: %d. Only ECDSA keys on the "
+ "secp256r1 curve are supported.",
+ curve_name));
+ return base::nullopt;
+}
+
+bool VerifySignature(base::span<const uint8_t> sig,
+ base::span<const uint8_t> msg,
+ scoped_refptr<net::X509Certificate> cert,
+ crypto::SignatureVerifier::SignatureAlgorithm algorithm,
+ SignedExchangeDevToolsProxy* devtools_proxy) {
crypto::SignatureVerifier verifier;
if (!net::x509_util::SignatureVerifierInitWithCertificate(
&verifier, algorithm, sig, cert->cert_buffer())) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "VerifySignature",
- "SignatureVerifierInitWithCertificate failed.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "SignatureVerifierInitWithCertificate failed.");
return false;
}
verifier.VerifyUpdate(msg);
if (!verifier.VerifyFinal()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "VerifySignature", "VerifyFinal failed.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(devtools_proxy,
+ "VerifyFinal failed.");
return false;
}
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"), "VerifySignature");
return true;
}
@@ -216,12 +218,13 @@ std::string HexDump(const std::vector<uint8_t>& msg) {
}
base::Optional<std::vector<uint8_t>> GenerateSignedMessage(
- const SignedExchangeHeader& header) {
+ const SignedExchangeEnvelope& envelope) {
TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
"GenerateSignedMessage");
// GenerateSignedMessageCBOR corresponds to Step 7.4.
- base::Optional<cbor::CBORValue> cbor_val = GenerateSignedMessageCBOR(header);
+ base::Optional<cbor::CBORValue> cbor_val =
+ GenerateSignedMessageCBOR(envelope);
if (!cbor_val) {
TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("loading"),
"GenerateSignedMessage", "error",
@@ -259,12 +262,12 @@ base::Time TimeFromSignedExchangeUnixTime(uint64_t t) {
// Implements steps 5-6 of
// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#signature-validity
-bool VerifyTimestamps(const SignedExchangeHeader& header,
+bool VerifyTimestamps(const SignedExchangeEnvelope& envelope,
const base::Time& verification_time) {
base::Time expires_time =
- TimeFromSignedExchangeUnixTime(header.signature().expires);
+ TimeFromSignedExchangeUnixTime(envelope.signature().expires);
base::Time creation_time =
- TimeFromSignedExchangeUnixTime(header.signature().date);
+ TimeFromSignedExchangeUnixTime(envelope.signature().date);
// 5. "If expires is more than 7 days (604800 seconds) after date, return
// "invalid"." [spec text]
@@ -282,84 +285,82 @@ bool VerifyTimestamps(const SignedExchangeHeader& header,
} // namespace
SignedExchangeSignatureVerifier::Result SignedExchangeSignatureVerifier::Verify(
- const SignedExchangeHeader& header,
+ const SignedExchangeEnvelope& envelope,
scoped_refptr<net::X509Certificate> certificate,
const base::Time& verification_time,
SignedExchangeDevToolsProxy* devtools_proxy) {
- TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeSignatureVerifier::Verify");
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeSignatureVerifier::Verify");
- if (!VerifyTimestamps(header, verification_time)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeSignatureVerifier::Verify",
+ if (!VerifyTimestamps(envelope, verification_time)) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
base::StringPrintf(
"Invalid timestamp. creation_time: %" PRIu64
", expires_time: %" PRIu64 ", verification_time: %" PRIu64,
- header.signature().date, header.signature().expires,
+ envelope.signature().date, envelope.signature().expires,
(verification_time - base::Time::UnixEpoch()).InSeconds()));
return Result::kErrInvalidTimestamp;
}
if (!certificate) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeSignatureVerifier::Verify",
- "No certificate set.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(devtools_proxy,
+ "No certificate set.");
return Result::kErrNoCertificate;
}
- if (!header.signature().cert_sha256.has_value()) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeSignatureVerifier::Verify",
- "No certSha256 set.");
+ if (!envelope.signature().cert_sha256.has_value()) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(devtools_proxy,
+ "No cert-sha256 set.");
return Result::kErrNoCertificateSHA256;
}
// The main-certificate is the first certificate in certificate-chain.
- if (*header.signature().cert_sha256 !=
+ if (*envelope.signature().cert_sha256 !=
net::X509Certificate::CalculateFingerprint256(
certificate->cert_buffer())) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeSignatureVerifier::Verify",
- "certSha256 mismatch.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(devtools_proxy,
+ "cert-sha256 mismatch.");
return Result::kErrCertificateSHA256Mismatch;
}
- auto message = GenerateSignedMessage(header);
+ auto message = GenerateSignedMessage(envelope);
if (!message) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeSignatureVerifier::Verify",
- "Failed to reconstruct signed message.");
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "Failed to reconstruct signed message.");
return Result::kErrInvalidSignatureFormat;
}
- const std::string& sig = header.signature().sig;
+ base::Optional<crypto::SignatureVerifier::SignatureAlgorithm> algorithm =
+ GetSignatureAlgorithm(certificate, devtools_proxy);
+ if (!algorithm)
+ return Result::kErrUnsupportedCertType;
+
+ const std::string& sig = envelope.signature().sig;
if (!VerifySignature(
base::make_span(reinterpret_cast<const uint8_t*>(sig.data()),
sig.size()),
- *message, certificate, devtools_proxy)) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeSignatureVerifier::Verify",
- "Failed to verify signature \"sig\".");
+ *message, certificate, *algorithm, devtools_proxy)) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy, "Failed to verify signature \"sig\".");
return Result::kErrSignatureVerificationFailed;
}
- if (!base::EqualsCaseInsensitiveASCII(header.signature().integrity, "mi")) {
- signed_exchange_utils::ReportErrorAndEndTraceEvent(
- devtools_proxy, "SignedExchangeSignatureVerifier::Verify",
+ if (!base::EqualsCaseInsensitiveASCII(envelope.signature().integrity,
+ "mi-draft2")) {
+ signed_exchange_utils::ReportErrorAndTraceEvent(
+ devtools_proxy,
"The current implemention only supports \"mi\" integrity scheme.");
return Result::kErrInvalidSignatureIntegrity;
}
-
- TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
- "SignedExchangeSignatureVerifier::Verify");
return Result::kSuccess;
}
base::Optional<std::vector<uint8_t>>
SignedExchangeSignatureVerifier::EncodeCanonicalExchangeHeaders(
- const SignedExchangeHeader& header) {
+ const SignedExchangeEnvelope& envelope) {
base::Optional<cbor::CBORValue> cbor_val =
- GenerateCanonicalExchangeHeadersCBOR(header);
+ GenerateCanonicalExchangeHeadersCBOR(envelope);
if (!cbor_val)
return base::nullopt;
diff --git a/chromium/content/browser/web_package/signed_exchange_signature_verifier.h b/chromium/content/browser/web_package/signed_exchange_signature_verifier.h
index fe8da78f44a..cca2ea786f5 100644
--- a/chromium/content/browser/web_package/signed_exchange_signature_verifier.h
+++ b/chromium/content/browser/web_package/signed_exchange_signature_verifier.h
@@ -21,7 +21,7 @@ class Time;
namespace content {
-class SignedExchangeHeader;
+class SignedExchangeEnvelope;
class SignedExchangeDevToolsProxy;
// SignedExchangeSignatureVerifier verifies the signature of the given
@@ -44,16 +44,17 @@ class CONTENT_EXPORT SignedExchangeSignatureVerifier final {
kErrInvalidSignatureFormat,
kErrSignatureVerificationFailed,
kErrInvalidSignatureIntegrity,
- kErrInvalidTimestamp
+ kErrInvalidTimestamp,
+ kErrUnsupportedCertType
};
- static Result Verify(const SignedExchangeHeader& header,
+ static Result Verify(const SignedExchangeEnvelope& envelope,
scoped_refptr<net::X509Certificate> certificate,
const base::Time& verification_time,
SignedExchangeDevToolsProxy* devtools_proxy);
static base::Optional<std::vector<uint8_t>> EncodeCanonicalExchangeHeaders(
- const SignedExchangeHeader& header);
+ const SignedExchangeEnvelope& envelope);
};
} // namespace content
diff --git a/chromium/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc b/chromium/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
index b902e1e9f9b..9dbab4e6422 100644
--- a/chromium/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
+++ b/chromium/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
@@ -5,8 +5,8 @@
#include "content/browser/web_package/signed_exchange_signature_verifier.h"
#include "base/callback.h"
-#include "content/browser/web_package/signed_exchange_header.h"
-#include "content/browser/web_package/signed_exchange_header_parser.h"
+#include "content/browser/web_package/signed_exchange_envelope.h"
+#include "content/browser/web_package/signed_exchange_signature_header_field.h"
#include "net/cert/x509_certificate.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -15,15 +15,15 @@ namespace content {
namespace {
TEST(SignedExchangeSignatureVerifier, EncodeCanonicalExchangeHeaders) {
- SignedExchangeHeader header;
- header.set_request_method("GET");
- header.set_request_url(GURL("https://example.com/index.html"));
- header.set_response_code(net::HTTP_OK);
- header.AddResponseHeader("content-type", "text/html; charset=utf-8");
- header.AddResponseHeader("content-encoding", "mi-sha256");
+ SignedExchangeEnvelope envelope;
+ envelope.set_request_method("GET");
+ envelope.set_request_url(GURL("https://example.com/index.html"));
+ envelope.set_response_code(net::HTTP_OK);
+ envelope.AddResponseHeader("content-type", "text/html; charset=utf-8");
+ envelope.AddResponseHeader("content-encoding", "mi-sha256-draft2");
base::Optional<std::vector<uint8_t>> encoded =
- SignedExchangeSignatureVerifier::EncodeCanonicalExchangeHeaders(header);
+ SignedExchangeSignatureVerifier::EncodeCanonicalExchangeHeaders(envelope);
ASSERT_TRUE(encoded.has_value());
static const uint8_t kExpected[] = {
@@ -51,8 +51,9 @@ TEST(SignedExchangeSignatureVerifier, EncodeCanonicalExchangeHeaders) {
0x50, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e,
0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, // bytes "content-encoding"
- 0x49, 0x6d, 0x69, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36,
- // bytes "mi-sha256"
+ 0x50, 0x6d, 0x69, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2d,
+ 0x64, 0x72, 0x61, 0x66, 0x74, 0x32
+ // bytes "mi-sha256-draft2"
// clang-format on
};
EXPECT_THAT(*encoded,
@@ -62,45 +63,11 @@ TEST(SignedExchangeSignatureVerifier, EncodeCanonicalExchangeHeaders) {
const uint64_t kSignatureHeaderDate = 1517892341;
const uint64_t kSignatureHeaderExpires = 1517895941;
+// See content/testdata/sxg/README on how to generate these data.
// clang-format off
-constexpr char kSignatureHeaderRSA[] =
- "sig; "
- "sig=*RhjjWuXi87riQUu90taBHFJgTo8XBhiCe9qTJMP7/XVPu2diRGipo06HoGsyXkidHiiW"
- "743JgoNmO7CjfeVXLXQgKDxtGidATtPsVadAT4JpBDZJWSUg5qAbWcASXjyO38Uhq9gJkeu4w"
- "1MRMGkvpgVXNjYhi5/9NUer1xEUuJh5UbIDhGrfMihwj+c30nW+qz0n5lCrYonk+Sc0jGcLgc"
- "aDLptqRhOG5S+avwKmbQoqtD0JSc/53L5xXjppyvSA2fRmoDlqVQpX4uzRKq9cny7fZ3qgpZ/"
- "YOCuT7wMj7oVEur175QLe2F8ktKH9arSEiquhFJxBIIIXza8PJnmL5w;"
- "validityUrl=\"https://example.com/resource.validity.msg\"; "
- "integrity=\"mi\"; "
- "certUrl=\"https://example.com/cert.msg\"; "
- "certSha256=*3wfzkF4oKGUwoQ0rE7U11FIdcA/8biGzlaACeRQQH6k; "
- "date=1517892341; expires=1517895941";
-// clang-format on
-
-// See content/testdata/htxg/README on how to generate this data.
-// clang-format off
-constexpr char kSignatureHeaderECDSAP256[] =
- "label; "
- "sig=*MEYCIQDQYQAHAlpznkP/btvuNnvGY5ycO+NOOTFXsoBjF22UhAIhAMyzyMikudaQeIPYB"
- "fh2JdqZVBwgsQ6a3Cn8lFA0XYGW; "
- "validityUrl=\"https://example.com/resource.validity.msg\"; "
- "integrity=\"mi\"; "
- "certUrl=\"https://example.com/cert.msg\"; "
- "certSha256=*CfDj40tr5B7oo6IaWwQF2L1uDgsHH0fA2YOCB7E0tAQ; "
- "date=1517892341; expires=1517895941";
-// clang-format on
-
-// See content/testdata/htxg/README on how to generate this data.
-// clang-format off
-constexpr char kSignatureHeaderECDSAP384[] =
- "label; "
- "sig=*MGQCMDtOqWBsWjx1+WZta9tBpuuMJMLMwp8/eHu+PwNw95qCMMjD1xJiLIm0HUtFzdzSC"
- "wIwVxSUD9IB2t4JIHz6IJPddqR1ex38kkSvOYSmFEwqVPRM1sqAcEtvwdpSU+cLJYbS; "
- "validityUrl=\"https://example.com/resource.validity.msg\"; "
- "integrity=\"mi\"; "
- "certUrl=\"https://example.com/cert.msg\"; "
- "certSha256=*8X8y8nj8vDJHSSa0cxn+TCu+8zGpIJfbdzAnd5cW+jA; "
- "date=1517892341; expires=1517895941";
+constexpr char kSignatureHeaderRSA[] = R"(label; sig=*yYFb09i7VXuqsGBxc3RuJzGL4XMD9bZ20kXWSv1JObEf7KIG0MznSE1nu1fE+7DrgWQxH7FQfSWjyseOAvxsBOfkptmCCi/Ffklz3N1UU8LfwfaLWj80oBqDeofiIYwevSSpsaRKBYie7KjiVOjslFLOGe82MmHyF2utFRKY/i6UAHgMrg2FGfbwBaJsxEgtpPcN8/QnFKgt1la+JjwvYbMHpJhHTedDqx9GCxJOzbJjKRL1E2tIBvhDfK2m3eJv/nqvgWkK3MOd/Xp4FkndciS3eNyZZjwvJ6IL/3x4e0AZ36KvglpS092ZftiE4lKQWnHmVeDRmEHW6qOyv1Q3+w==*; validity-url="https://example.com/resource.validity.msg"; integrity="mi-draft2"; cert-url="https://example.com/cert.msg"; cert-sha256=*tJGJP8ej7KCEW8VnVK3bKwpBza/oLrtWA75z5ZPptuc=*; date=1517892341; expires=1517895941)";
+constexpr char kSignatureHeaderECDSAP256[] = R"(label; sig=*MEQCIA0w6auOuWGT6//MO/h43/xkXBchJUOp53GU5dmA8U+/AiAe0FggCblVxzosT2Ow9rrC2Q8zO0DZPLSNbcu29xYP6g==*; validity-url="https://example.com/resource.validity.msg"; integrity="mi-draft2"; cert-url="https://example.com/cert.msg"; cert-sha256=*KX+BYLSMgDOON8Ju65RoId39Qvajxa12HO+WnD4HpS0=*; date=1517892341; expires=1517895941)";
+constexpr char kSignatureHeaderECDSAP384[] = R"(label; sig=*MGYCMQC/P8m0ZnPrIMlI3I412MixcK9cQSirIECUNR7pOIlTiLaH95L72KXqq2aL+lxxKIICMQDU3s/BhoWtR61eKG9SqgGHd0ZtUJVY24xaJ2yHiYWxZU/QhOr5ZArSj3x1khivpRg=*; validity-url="https://example.com/resource.validity.msg"; integrity="mi-draft2"; cert-url="https://example.com/cert.msg"; cert-sha256=*8X8y8nj8vDJHSSa0cxn+TCu+8zGpIJfbdzAnd5cW+jA=*; date=1517892341; expires=1517895941)";
// clang-format on
// |expires| (1518497142) is more than 7 days (604800 seconds) after |date|
@@ -112,55 +79,57 @@ constexpr char kSignatureHeaderInvalidExpires[] =
"743JgoNmO7CjfeVXLXQgKDxtGidATtPsVadAT4JpBDZJWSUg5qAbWcASXjyO38Uhq9gJkeu4w"
"1MRMGkvpgVXNjYhi5/9NUer1xEUuJh5UbIDhGrfMihwj+c30nW+qz0n5lCrYonk+Sc0jGcLgc"
"aDLptqRhOG5S+avwKmbQoqtD0JSc/53L5xXjppyvSA2fRmoDlqVQpX4uzRKq9cny7fZ3qgpZ/"
- "YOCuT7wMj7oVEur175QLe2F8ktKH9arSEiquhFJxBIIIXza8PJnmL5w;"
- "validityUrl=\"https://example.com/resource.validity.msg\"; "
- "integrity=\"mi\"; "
- "certUrl=\"https://example.com/cert.msg\"; "
- "certSha256=*3wfzkF4oKGUwoQ0rE7U11FIdcA/8biGzlaACeRQQH6k; "
+ "YOCuT7wMj7oVEur175QLe2F8ktKH9arSEiquhFJxBIIIXza8PJnmL5w==*;"
+ "validity-url=\"https://example.com/resource.validity.msg\"; "
+ "integrity=\"mi-draft2\"; "
+ "cert-url=\"https://example.com/cert.msg\"; "
+ "cert-sha256=*3wfzkF4oKGUwoQ0rE7U11FIdcA/8biGzlaACeRQQH6k=*; "
"date=1517892341; expires=1518497142";
// clang-format on
constexpr char kCertPEMRSA[] = R"(
-----BEGIN CERTIFICATE-----
-MIID9zCCAt+gAwIBAgIUde2ndSB4271TAGDk0Ft+WuCCGnMwDQYJKoZIhvcNAQEL
-BQAwUDELMAkGA1UEBhMCSlAxEjAQBgNVBAgTCU1pbmF0by1rdTEOMAwGA1UEBxMF
-VG9reW8xEDAOBgNVBAoTB1Rlc3QgQ0ExCzAJBgNVBAsTAkNBMB4XDTE4MDIwNTA0
-NDUwMFoXDTE5MDIwNTA0NDUwMFowbzELMAkGA1UEBhMCSlAxEjAQBgNVBAgTCU1p
-bmF0by1rdTEOMAwGA1UEBxMFVG9reW8xFDASBgNVBAoTC2V4YW1wbGUuY29tMRIw
-EAYDVQQLEwl3ZWJzZXJ2ZXIxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAJv0UV5pK/XMtmHuDHUSvU+mNghsDQsKYSeB
-r/CySBIbLWtkeC7oxuYT2R+Mz4vVs0WQ1f3F/e3HIIQxWmy5VYErER13c53yeCNF
-fcBkwpuCZKEO1BURX+WgjYPnzLYX1xDnpBM++TuEZKdxzUVjs/jQjMNB8sbRYzng
-IIbA4HiRUtPvnGjLmY0HxZyskb52yeTWg40jWPdLaC8GMEZXGKynAnGEMl3c/dVw
-8+nKS1VVe6k32Ubfl1NlaqbOXi0xHHMUhLY/l8Lu49E0ivPS7BWL/0nMR9EAmu+I
-AgK9OD7VRoMA0LEKBzIQUEuK70JxLkV7GNvrtnOX83+EwwdfBdUCAwEAAaOBqTCB
-pjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC
-MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFDzp/0BrXKIfDGe3KfJLyBH8azW2MB8G
-A1UdIwQYMBaAFNAPhK4UBktJcx6TIk5QKwZPit4ZMCcGA1UdEQQgMB6CC2V4YW1w
-bGUuY29tgg93d3cuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBAKSQbsOW
-IX2JDv+Vg1lvbOFx+JqwdhvYTkOF4Z9YbRtlqEIZbc8KWjAOzDB1xVJxhSjD+f8+
-vrj7YN/ggCQk6DzuF4lkztBDO95Fxmx4EeIKdKt83WP09Os/2yIOKToOnHkmauBB
-ijY8oxNs+XxKrPX7DN5QQQhiTsZcL625fcnIwPb0DeeuCT7bJYPv8OojMDTR1uDt
-SQ53HYt0aLun+Br3lCwW8cnpxuezJhg0gNezYp/8gC4kByqoT26atpls08eWUdFD
-U0/55zFz2OzNoAHaoBzMRxn4ZSc3+lxl0K1+cCP8ivhwkxdz/vhz5RfOjpSinxqt
-wYxI2+BLS6X5NpI=
+MIIDyTCCArGgAwIBAgIBBDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE3MDYwNTE3
+MTA0NloXDTI3MDYwMzE3MTA0NlowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
+bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg
+Q0ExEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBANOUHzO0uxUyd3rYUArq33olXC0N1AYNM0wFTjUqUrElLiX48+5hERkG
+hGwC8VG5Zr/2Jw/wtarLiDjg2OfPdwyMp3S7MBTgvXWZ989MUHpx6b0cWM298iOg
+/VeinMphFLDfPDHFWZ7RXBqfk6MGLhI5GgvoooYw2jUmP+elnoizIL/OB08sIYra
+AVrwasoRd+yOmyvQnzw3mZNKpWjeX7NhZCg2nG8B8u78agwAYVWupHnJS2GwhLzy
+19AxU/HmaI9kyyMGmRtbRZ0roCyMDOgEEcWUSYNRP33KLi31uKYqOSblvzmC7kA7
+k5yca3VXlgqg4gnjr9tbOMzMcpeqeaMCAwEAAaOBijCBhzAMBgNVHRMBAf8EAjAA
+MB0GA1UdDgQWBBQYDOtRudM2qckEr/kvFPCZZtJ21DAfBgNVHSMEGDAWgBSbJguK
+mKm7HbkfHOMaQDPtjheIqzAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
+GAYDVR0RBBEwD4INKi5leGFtcGxlLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAvXK0
+UF19i7JkSSdomQwB18WRFaKG8VZpSFsKbEECPRHoxktMl/Pd04wk+W0fZFq433j3
+4D+cjTB6OxAVdPIPSex8U40fYMl9C13K1tejf4o/+rcLxEDdVfv7PUkogrliXzSE
+MCYdcTwruV7hjC2/Ib0t/kdxblRt4dD2I1jdntsFy/VfET/m0J2qRhJWlfYEzCFe
+Hn8H/PZIiIsso5pm2RodTqi9w4/+1r8Yyfmk8TF+EoWDYtbZ+ScgtCH5fldS+onI
+hHgjz/tniqjbY0MRFr9ZxrohmtgOBOvROEKH06c92oOmj2ahyFpM/yU9PL/JvNmF
+SaMW1eOzjHemIWKTMw==
-----END CERTIFICATE-----)";
constexpr char kCertPEMECDSAP256[] = R"(
-----BEGIN CERTIFICATE-----
-MIICQzCCASsCAQEwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxEzARBgNV
-BAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoM
-B1Rlc3QgQ0ExFTATBgNVBAMMDFRlc3QgUm9vdCBDQTAeFw0xODAzMjMwNDU3MzRa
-Fw0xOTAzMTgwNDU3MzRaMDcxGTAXBgNVBAMMEHRlc3QuZXhhbXBsZS5vcmcxDTAL
-BgNVBAoMBFRlc3QxCzAJBgNVBAYTAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
-QgAECQYn3HDPPhtMv2hzyjI7E3FU89EjnzTtvLd9OP55GLAsaE/FCTWbx6rKOxF7
-O4jP0N3PsIzr+nT1lIix+HpxujANBgkqhkiG9w0BAQsFAAOCAQEAhKdVMvKm7gBz
-af6nfCkLGRo56KJasi6lJh2byF17vdqq+mSXR+jHZtsRsRZJyl+C+jaSzrT0TnMA
-kLg+U4ZnKZD5sTo7TWnRlTA4G4tOrWaq1tn89FWqe+hbvn6dEyTZ1XFPaO6hzeNH
-ZM5H+bIpngvGmP1lf7K6PtC3Tx/S938zBdQrfKz/4ZB0S5cmIyIUBnlj3PDWtLsB
-KS4wvSnjPj1EyVKxTQH1PdB2NqC4eT8bgFcryNWrkMOWdOUNhGWB55nVwI8yNPQO
-4OrKJLsDZir3v7dzcU9U1erBp4+udGFIfW86g24FX1gn3SavtO6lZt59AFLptyQ6
-LWh1CMv1aQ==
+MIIC1TCCAb2gAwIBAgIBATANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
+A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE4MDYyODA1
+MTUzMFoXDTE5MDYyMzA1MTUzMFowNzEZMBcGA1UEAwwQdGVzdC5leGFtcGxlLm9y
+ZzENMAsGA1UECgwEVGVzdDELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIBBggqhkjO
+PQMBBwNCAAQJBifccM8+G0y/aHPKMjsTcVTz0SOfNO28t304/nkYsCxoT8UJNZvH
+qso7EXs7iM/Q3c+wjOv6dPWUiLH4enG6o4GKMIGHMAkGA1UdEwQCMAAwEAYKKwYB
+BAHWeQIBFgQCBQAwCwYDVR0PBAQDAgXgMB0GA1UdDgQWBBS6dTuFdAI6uylsw3cy
+H3FXfh9g+jAfBgNVHSMEGDAWgBSbJguKmKm7HbkfHOMaQDPtjheIqzAbBgNVHREE
+FDASghB0ZXN0LmV4YW1wbGUub3JnMA0GCSqGSIb3DQEBCwUAA4IBAQCi/l1E+JDK
+/g3cLa5GD8vthZJuFwYEF6lGaAj1RtZ+UwbtRs1vnkJbEpLD1xX5rKXAdWT5QI99
+yK6gXbbicaJmw0KjeE0qizTT1oEfavQu7FtJZ4gfBjIHLsk8PVqHI3t8hf/pJwOd
+n+E79k3qQ2w1IeeVFZXJfnjhOsxHp2NTbeY+ZnbWsTSyUiL81n5GkuyKNDeZkoXi
+x5M6kp+6ZZJHJvLQFp4CqhU+wvM2lvP5mYYDcSlRnlti+N8xwDUb/yGR0UdNx76K
+7uFRoc8R1W8e4kFvU2NHkrtVbaLL6m+/vHE2LehVPh0QQT34Fv0QugYm+iYNToCT
+k5bUo19UY4w3
-----END CERTIFICATE-----)";
constexpr char kCertPEMECDSAP384[] = R"(
@@ -190,16 +159,16 @@ class SignedExchangeSignatureVerifierTest : public ::testing::Test {
}
void TestVerifierGivenValidInput(
- const SignedExchangeHeader& header,
+ const SignedExchangeEnvelope& envelope,
scoped_refptr<net::X509Certificate> certificate) {
EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kSuccess,
SignedExchangeSignatureVerifier::Verify(
- header, certificate, VerificationTime(),
+ envelope, certificate, VerificationTime(),
nullptr /* devtools_proxy */));
EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kErrInvalidTimestamp,
SignedExchangeSignatureVerifier::Verify(
- header, certificate,
+ envelope, certificate,
base::Time::UnixEpoch() +
base::TimeDelta::FromSeconds(kSignatureHeaderDate - 1),
nullptr /* devtools_proxy */
@@ -207,7 +176,7 @@ class SignedExchangeSignatureVerifierTest : public ::testing::Test {
EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kSuccess,
SignedExchangeSignatureVerifier::Verify(
- header, certificate,
+ envelope, certificate,
base::Time::UnixEpoch() +
base::TimeDelta::FromSeconds(kSignatureHeaderExpires),
nullptr /* devtools_proxy */
@@ -215,52 +184,54 @@ class SignedExchangeSignatureVerifierTest : public ::testing::Test {
EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kErrInvalidTimestamp,
SignedExchangeSignatureVerifier::Verify(
- header, certificate,
+ envelope, certificate,
base::Time::UnixEpoch() +
base::TimeDelta::FromSeconds(kSignatureHeaderExpires + 1),
nullptr /* devtools_proxy */
));
- SignedExchangeHeader invalid_expires_header(header);
- auto invalid_expires_signature = SignedExchangeHeaderParser::ParseSignature(
- kSignatureHeaderInvalidExpires, nullptr /* devtools_proxy */);
+ SignedExchangeEnvelope invalid_expires_envelope(envelope);
+ auto invalid_expires_signature =
+ SignedExchangeSignatureHeaderField::ParseSignature(
+ kSignatureHeaderInvalidExpires, nullptr /* devtools_proxy */);
ASSERT_TRUE(invalid_expires_signature.has_value());
ASSERT_EQ(1u, invalid_expires_signature->size());
- invalid_expires_header.SetSignatureForTesting(
+ invalid_expires_envelope.SetSignatureForTesting(
(*invalid_expires_signature)[0]);
EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kErrInvalidTimestamp,
SignedExchangeSignatureVerifier::Verify(
- invalid_expires_header, certificate, VerificationTime(),
+ invalid_expires_envelope, certificate, VerificationTime(),
nullptr /* devtools_proxy */
));
- SignedExchangeHeader corrupted_header(header);
- corrupted_header.set_request_url(GURL("https://example.com/bad.html"));
+ SignedExchangeEnvelope corrupted_envelope(envelope);
+ corrupted_envelope.set_request_url(GURL("https://example.com/bad.html"));
EXPECT_EQ(SignedExchangeSignatureVerifier::Result::
kErrSignatureVerificationFailed,
SignedExchangeSignatureVerifier::Verify(
- corrupted_header, certificate, VerificationTime(),
+ corrupted_envelope, certificate, VerificationTime(),
nullptr /* devtools_proxy */
));
- SignedExchangeHeader badsig_header(header);
- SignedExchangeHeaderParser::Signature badsig = header.signature();
+ SignedExchangeEnvelope badsig_envelope(envelope);
+ SignedExchangeSignatureHeaderField::Signature badsig = envelope.signature();
badsig.sig[0]++;
- badsig_header.SetSignatureForTesting(badsig);
+ badsig_envelope.SetSignatureForTesting(badsig);
EXPECT_EQ(SignedExchangeSignatureVerifier::Result::
kErrSignatureVerificationFailed,
SignedExchangeSignatureVerifier::Verify(
- badsig_header, certificate, VerificationTime(),
+ badsig_envelope, certificate, VerificationTime(),
nullptr /* devtools_proxy */
));
- SignedExchangeHeader badsigsha256_header(header);
- SignedExchangeHeaderParser::Signature badsigsha256 = header.signature();
+ SignedExchangeEnvelope badsigsha256_envelope(envelope);
+ SignedExchangeSignatureHeaderField::Signature badsigsha256 =
+ envelope.signature();
badsigsha256.cert_sha256->data[0]++;
- badsigsha256_header.SetSignatureForTesting(badsigsha256);
+ badsigsha256_envelope.SetSignatureForTesting(badsigsha256);
EXPECT_EQ(
SignedExchangeSignatureVerifier::Result::kErrCertificateSHA256Mismatch,
- SignedExchangeSignatureVerifier::Verify(badsigsha256_header,
+ SignedExchangeSignatureVerifier::Verify(badsigsha256_envelope,
certificate, VerificationTime(),
nullptr /* devtools_proxy */
));
@@ -268,7 +239,7 @@ class SignedExchangeSignatureVerifierTest : public ::testing::Test {
};
TEST_F(SignedExchangeSignatureVerifierTest, VerifyRSA) {
- auto signature = SignedExchangeHeaderParser::ParseSignature(
+ auto signature = SignedExchangeSignatureHeaderField::ParseSignature(
kSignatureHeaderRSA, nullptr /* devtools_proxy */);
ASSERT_TRUE(signature.has_value());
ASSERT_EQ(1u, signature->size());
@@ -279,21 +250,25 @@ TEST_F(SignedExchangeSignatureVerifierTest, VerifyRSA) {
net::X509Certificate::FORMAT_AUTO);
ASSERT_EQ(1u, certlist.size());
- SignedExchangeHeader header;
- header.set_request_method("GET");
- header.set_request_url(GURL("https://example.com/index.html"));
- header.set_response_code(net::HTTP_OK);
- header.AddResponseHeader("content-type", "text/html; charset=utf-8");
- header.AddResponseHeader("content-encoding", "mi-sha256");
- header.AddResponseHeader(
- "mi", "mi-sha256=4ld4G-h-sQSoLBD39ndIO15O_82NXSzq9UMFEYI02JQ");
- header.SetSignatureForTesting((*signature)[0]);
-
- TestVerifierGivenValidInput(header, certlist[0]);
+ SignedExchangeEnvelope envelope;
+ envelope.set_request_method("GET");
+ envelope.set_request_url(GURL("https://test.example.org/test/"));
+ envelope.set_response_code(net::HTTP_OK);
+ envelope.AddResponseHeader("content-type", "text/html; charset=utf-8");
+ envelope.AddResponseHeader("content-encoding", "mi-sha256-draft2");
+ envelope.AddResponseHeader(
+ "mi-draft2",
+ "mi-sha256-draft2=wmp4dRMYgxP3tSMCwV_I0CWOCiHZpAihKZk19bsN9RI");
+ envelope.SetSignatureForTesting((*signature)[0]);
+
+ EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kErrUnsupportedCertType,
+ SignedExchangeSignatureVerifier::Verify(
+ envelope, certlist[0], VerificationTime(),
+ nullptr /* devtools_proxy */));
}
TEST_F(SignedExchangeSignatureVerifierTest, VerifyECDSAP256) {
- auto signature = SignedExchangeHeaderParser::ParseSignature(
+ auto signature = SignedExchangeSignatureHeaderField::ParseSignature(
kSignatureHeaderECDSAP256, nullptr /* devtools_proxy */);
ASSERT_TRUE(signature.has_value());
ASSERT_EQ(1u, signature->size());
@@ -304,22 +279,23 @@ TEST_F(SignedExchangeSignatureVerifierTest, VerifyECDSAP256) {
net::X509Certificate::FORMAT_AUTO);
ASSERT_EQ(1u, certlist.size());
- SignedExchangeHeader header;
- header.set_request_method("GET");
- header.set_request_url(GURL("https://test.example.org/test/"));
- header.set_response_code(net::HTTP_OK);
- header.AddResponseHeader("content-type", "text/html; charset=utf-8");
- header.AddResponseHeader("content-encoding", "mi-sha256");
- header.AddResponseHeader(
- "mi", "mi-sha256=wmp4dRMYgxP3tSMCwV_I0CWOCiHZpAihKZk19bsN9RI");
+ SignedExchangeEnvelope envelope;
+ envelope.set_request_method("GET");
+ envelope.set_request_url(GURL("https://test.example.org/test/"));
+ envelope.set_response_code(net::HTTP_OK);
+ envelope.AddResponseHeader("content-type", "text/html; charset=utf-8");
+ envelope.AddResponseHeader("content-encoding", "mi-sha256-draft2");
+ envelope.AddResponseHeader(
+ "mi-draft2",
+ "mi-sha256-draft2=wmp4dRMYgxP3tSMCwV_I0CWOCiHZpAihKZk19bsN9RI");
- header.SetSignatureForTesting((*signature)[0]);
+ envelope.SetSignatureForTesting((*signature)[0]);
- TestVerifierGivenValidInput(header, certlist[0]);
+ TestVerifierGivenValidInput(envelope, certlist[0]);
}
TEST_F(SignedExchangeSignatureVerifierTest, VerifyECDSAP384) {
- auto signature = SignedExchangeHeaderParser::ParseSignature(
+ auto signature = SignedExchangeSignatureHeaderField::ParseSignature(
kSignatureHeaderECDSAP384, nullptr /* devtools_proxy */);
ASSERT_TRUE(signature.has_value());
ASSERT_EQ(1u, signature->size());
@@ -330,22 +306,22 @@ TEST_F(SignedExchangeSignatureVerifierTest, VerifyECDSAP384) {
net::X509Certificate::FORMAT_AUTO);
ASSERT_EQ(1u, certlist.size());
- SignedExchangeHeader header;
- header.set_request_method("GET");
- header.set_request_url(GURL("https://test.example.org/test/"));
- header.set_response_code(net::HTTP_OK);
- header.AddResponseHeader("content-type", "text/html; charset=utf-8");
- header.AddResponseHeader("content-encoding", "mi-sha256");
- header.AddResponseHeader(
- "mi", "mi-sha256=wmp4dRMYgxP3tSMCwV_I0CWOCiHZpAihKZk19bsN9RIG");
-
- header.SetSignatureForTesting((*signature)[0]);
-
- EXPECT_EQ(
- SignedExchangeSignatureVerifier::Result::kErrSignatureVerificationFailed,
- SignedExchangeSignatureVerifier::Verify(header, certlist[0],
- VerificationTime(),
- nullptr /* devtools_proxy */));
+ SignedExchangeEnvelope envelope;
+ envelope.set_request_method("GET");
+ envelope.set_request_url(GURL("https://test.example.org/test/"));
+ envelope.set_response_code(net::HTTP_OK);
+ envelope.AddResponseHeader("content-type", "text/html; charset=utf-8");
+ envelope.AddResponseHeader("content-encoding", "mi-sha256-draft2");
+ envelope.AddResponseHeader(
+ "mi-draft2",
+ "mi-sha256-draft2=wmp4dRMYgxP3tSMCwV_I0CWOCiHZpAihKZk19bsN9RIG");
+
+ envelope.SetSignatureForTesting((*signature)[0]);
+
+ EXPECT_EQ(SignedExchangeSignatureVerifier::Result::kErrUnsupportedCertType,
+ SignedExchangeSignatureVerifier::Verify(
+ envelope, certlist[0], VerificationTime(),
+ nullptr /* devtools_proxy */));
}
} // namespace
diff --git a/chromium/content/browser/web_package/signed_exchange_utils.cc b/chromium/content/browser/web_package/signed_exchange_utils.cc
index 4086fd67a6c..bc1a1af246a 100644
--- a/chromium/content/browser/web_package/signed_exchange_utils.cc
+++ b/chromium/content/browser/web_package/signed_exchange_utils.cc
@@ -8,7 +8,8 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/web_package/signed_exchange_devtools_proxy.h"
-#include "content/browser/web_package/web_package_request_handler.h"
+#include "content/browser/web_package/signed_exchange_error.h"
+#include "content/browser/web_package/signed_exchange_request_handler.h"
#include "content/public/common/content_features.h"
#include "services/network/public/cpp/resource_response.h"
#include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
@@ -16,13 +17,15 @@
namespace content {
namespace signed_exchange_utils {
-void ReportErrorAndEndTraceEvent(SignedExchangeDevToolsProxy* devtools_proxy,
- const char* trace_event_name,
- const std::string& error_message) {
+void ReportErrorAndTraceEvent(
+ SignedExchangeDevToolsProxy* devtools_proxy,
+ const std::string& error_message,
+ base::Optional<SignedExchangeError::FieldIndexPair> error_field) {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("loading"),
+ "SignedExchangeError", TRACE_EVENT_SCOPE_THREAD, "error",
+ error_message);
if (devtools_proxy)
- devtools_proxy->ReportErrorMessage(error_message);
- TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("loading"), trace_event_name,
- "error", error_message);
+ devtools_proxy->ReportError(error_message, std::move(error_field));
}
bool IsSignedExchangeHandlingEnabled() {
@@ -38,7 +41,7 @@ bool ShouldHandleAsSignedHTTPExchange(
// TODO(crbug/803774): Decide whether we should support it or not.
if (head.was_fetched_via_service_worker)
return false;
- if (!WebPackageRequestHandler::IsSupportedMimeType(head.mime_type))
+ if (!SignedExchangeRequestHandler::IsSupportedMimeType(head.mime_type))
return false;
if (base::FeatureList::IsEnabled(features::kSignedHTTPExchange))
return true;
diff --git a/chromium/content/browser/web_package/signed_exchange_utils.h b/chromium/content/browser/web_package/signed_exchange_utils.h
index b5c4220daba..105cd892da7 100644
--- a/chromium/content/browser/web_package/signed_exchange_utils.h
+++ b/chromium/content/browser/web_package/signed_exchange_utils.h
@@ -7,6 +7,9 @@
#include <string>
+#include "base/optional.h"
+#include "content/browser/web_package/signed_exchange_error.h"
+
class GURL;
namespace network {
@@ -19,12 +22,14 @@ class SignedExchangeDevToolsProxy;
namespace signed_exchange_utils {
-// Utility method to call SignedExchangeDevToolsProxy::ReportErrorMessage() and
-// TRACE_EVENT_END() to report the error to both DevTools and about:tracing. If
-// |devtools_proxy| is nullptr, it just calls TRACE_EVENT_END().
-void ReportErrorAndEndTraceEvent(SignedExchangeDevToolsProxy* devtools_proxy,
- const char* trace_event_name,
- const std::string& error_message);
+// Utility method to call SignedExchangeDevToolsProxy::ReportError() and
+// TRACE_EVENT_INSTANT1 to report the error to both DevTools and about:tracing.
+// If |devtools_proxy| is nullptr, it just calls TRACE_EVENT_INSTANT1().
+void ReportErrorAndTraceEvent(
+ SignedExchangeDevToolsProxy* devtools_proxy,
+ const std::string& error_message,
+ base::Optional<SignedExchangeError::FieldIndexPair> error_field =
+ base::nullopt);
// Returns true when SignedHTTPExchange feature or SignedHTTPExchangeOriginTrial
// feature is enabled.
diff --git a/chromium/content/browser/webauth/OWNERS b/chromium/content/browser/webauth/OWNERS
index f1f0a3ef8d6..d3733b72b38 100644
--- a/chromium/content/browser/webauth/OWNERS
+++ b/chromium/content/browser/webauth/OWNERS
@@ -1,6 +1,7 @@
engedy@chromium.org
mkwst@chromium.org
-vasilii@chromium.org
+kpaulhamus@chromium.org
+hongjunchoi@chromium.org
per-file *_type_converter*.*=set noparent
per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
diff --git a/chromium/content/browser/webauth/authenticator_impl.cc b/chromium/content/browser/webauth/authenticator_impl.cc
index 2cc796d08e2..80b95998948 100644
--- a/chromium/content/browser/webauth/authenticator_impl.cc
+++ b/chromium/content/browser/webauth/authenticator_impl.cc
@@ -4,6 +4,7 @@
#include "content/browser/webauth/authenticator_impl.h"
+#include <array>
#include <string>
#include <utility>
#include <vector>
@@ -16,6 +17,7 @@
#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/webauth/authenticator_type_converters.h"
+#include "content/public/browser/authenticator_request_client_delegate.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
@@ -27,17 +29,17 @@
#include "content/public/common/origin_util.h"
#include "content/public/common/service_manager_connection.h"
#include "crypto/sha2.h"
+#include "device/base/features.h"
#include "device/fido/authenticator_selection_criteria.h"
#include "device/fido/ctap_get_assertion_request.h"
#include "device/fido/ctap_make_credential_request.h"
+#include "device/fido/fido_authenticator.h"
+#include "device/fido/fido_constants.h"
#include "device/fido/fido_transport_protocol.h"
#include "device/fido/get_assertion_request_handler.h"
#include "device/fido/make_credential_request_handler.h"
#include "device/fido/public_key_credential_descriptor.h"
#include "device/fido/public_key_credential_params.h"
-#include "device/fido/u2f_register.h"
-#include "device/fido/u2f_request.h"
-#include "device/fido/u2f_sign.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
@@ -45,6 +47,10 @@
#include "url/url_constants.h"
#include "url/url_util.h"
+#if defined(OS_MACOSX)
+#include "device/fido/mac/authenticator.h"
+#endif
+
namespace content {
namespace client_data {
@@ -53,7 +59,6 @@ const char kGetType[] = "webauthn.get";
} // namespace client_data
namespace {
-constexpr int32_t kCoseEs256 = -7;
// Ensure that the origin's effective domain is a valid domain.
// Only the domain format of host is valid.
@@ -165,55 +170,16 @@ bool IsAppIdAllowedForOrigin(const GURL& appid, const url::Origin& origin) {
return false;
}
-// Check that at least one of the cryptographic parameters is supported.
-// Only ES256 is currently supported by U2F_V2 (CTAP 1.0).
-bool IsAlgorithmSupportedByU2fAuthenticators(
- const std::vector<webauth::mojom::PublicKeyCredentialParametersPtr>&
- parameters) {
- for (const auto& params : parameters) {
- if (params->algorithm_identifier == kCoseEs256)
- return true;
- }
- return false;
-}
-
-// Verify that the request doesn't contain parameters that U2F authenticators
-// cannot fulfill.
-bool AreOptionsSupportedByU2fAuthenticators(
- const webauth::mojom::PublicKeyCredentialCreationOptionsPtr& options) {
- if (options->authenticator_selection) {
- if (options->authenticator_selection->user_verification ==
- webauth::mojom::UserVerificationRequirement::REQUIRED ||
- options->authenticator_selection->require_resident_key ||
- options->authenticator_selection->authenticator_attachment ==
- webauth::mojom::AuthenticatorAttachment::PLATFORM)
- return false;
- }
- return true;
-}
-
-std::vector<std::vector<uint8_t>> FilterCredentialList(
- const std::vector<webauth::mojom::PublicKeyCredentialDescriptorPtr>&
- descriptors) {
- std::vector<std::vector<uint8_t>> handles;
- for (const auto& credential_descriptor : descriptors) {
- if (credential_descriptor->type ==
- webauth::mojom::PublicKeyCredentialType::PUBLIC_KEY) {
- handles.push_back(credential_descriptor->id);
- }
- }
- return handles;
-}
-
device::CtapMakeCredentialRequest CreateCtapMakeCredentialRequest(
- std::vector<uint8_t> client_data_hash,
- const webauth::mojom::PublicKeyCredentialCreationOptionsPtr& options) {
+ base::span<const uint8_t, device::kClientDataHashLength> client_data_hash,
+ const blink::mojom::PublicKeyCredentialCreationOptionsPtr& options,
+ bool is_individual_attestation) {
auto credential_params = mojo::ConvertTo<
std::vector<device::PublicKeyCredentialParams::CredentialInfo>>(
options->public_key_parameters);
device::CtapMakeCredentialRequest make_credential_param(
- std::move(client_data_hash),
+ client_data_hash,
mojo::ConvertTo<device::PublicKeyCredentialRpEntity>(
options->relying_party),
mojo::ConvertTo<device::PublicKeyCredentialUserEntity>(options->user),
@@ -224,14 +190,17 @@ device::CtapMakeCredentialRequest CreateCtapMakeCredentialRequest(
options->exclude_credentials);
make_credential_param.SetExcludeList(std::move(exclude_list));
+ make_credential_param.SetIsIndividualAttestation(is_individual_attestation);
return make_credential_param;
}
device::CtapGetAssertionRequest CreateCtapGetAssertionRequest(
- std::vector<uint8_t> client_data_hash,
- const webauth::mojom::PublicKeyCredentialRequestOptionsPtr& options) {
- device::CtapGetAssertionRequest request_parameter(
- options->relying_party_id, std::move(client_data_hash));
+ base::span<const uint8_t, device::kClientDataHashLength> client_data_hash,
+ const blink::mojom::PublicKeyCredentialRequestOptionsPtr& options,
+ base::Optional<base::span<const uint8_t, device::kRpIdHashLength>>
+ alternative_application_parameter) {
+ device::CtapGetAssertionRequest request_parameter(options->relying_party_id,
+ client_data_hash);
auto allowed_list =
mojo::ConvertTo<std::vector<device::PublicKeyCredentialDescriptor>>(
@@ -242,6 +211,11 @@ device::CtapGetAssertionRequest CreateCtapGetAssertionRequest(
mojo::ConvertTo<device::UserVerificationRequirement>(
options->user_verification));
+ if (alternative_application_parameter) {
+ request_parameter.SetAlternativeApplicationParameter(
+ std::move(*alternative_application_parameter));
+ }
+
if (!options->cable_authentication_data.empty()) {
request_parameter.SetCableExtension(
mojo::ConvertTo<
@@ -251,9 +225,10 @@ device::CtapGetAssertionRequest CreateCtapGetAssertionRequest(
return request_parameter;
}
-std::vector<uint8_t> ConstructClientDataHash(const std::string& client_data) {
+std::array<uint8_t, crypto::kSHA256Length> ConstructClientDataHash(
+ const std::string& client_data) {
// SHA-256 hash of the JSON data structure.
- std::vector<uint8_t> client_data_hash(crypto::kSHA256Length);
+ std::array<uint8_t, crypto::kSHA256Length> client_data_hash;
crypto::SHA256HashString(client_data, client_data_hash.data(),
client_data_hash.size());
return client_data_hash;
@@ -262,17 +237,16 @@ std::vector<uint8_t> ConstructClientDataHash(const std::string& client_data) {
// 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> CreateApplicationParameter(
+std::array<uint8_t, crypto::kSHA256Length> CreateApplicationParameter(
const std::string& relying_party_id) {
- std::vector<uint8_t> application_parameter(crypto::kSHA256Length);
+ std::array<uint8_t, crypto::kSHA256Length> application_parameter;
crypto::SHA256HashString(relying_party_id, application_parameter.data(),
application_parameter.size());
return application_parameter;
}
-base::Optional<std::vector<uint8_t>> ProcessAppIdExtension(
- std::string appid,
- const url::Origin& caller_origin) {
+base::Optional<std::array<uint8_t, crypto::kSHA256Length>>
+ProcessAppIdExtension(std::string appid, const url::Origin& caller_origin) {
if (appid.empty()) {
// See step two in the comments in |IsAppIdAllowedForOrigin|.
appid = caller_origin.Serialize() + "/";
@@ -287,12 +261,12 @@ base::Optional<std::vector<uint8_t>> ProcessAppIdExtension(
return CreateApplicationParameter(appid);
}
-webauth::mojom::MakeCredentialAuthenticatorResponsePtr
+blink::mojom::MakeCredentialAuthenticatorResponsePtr
CreateMakeCredentialResponse(
const std::string& client_data_json,
device::AuthenticatorMakeCredentialResponse response_data) {
- auto response = webauth::mojom::MakeCredentialAuthenticatorResponse::New();
- auto common_info = webauth::mojom::CommonCredentialInfo::New();
+ auto response = blink::mojom::MakeCredentialAuthenticatorResponse::New();
+ auto common_info = blink::mojom::CommonCredentialInfo::New();
common_info->client_data_json.assign(client_data_json.begin(),
client_data_json.end());
common_info->raw_id = response_data.raw_credential_id();
@@ -303,12 +277,12 @@ CreateMakeCredentialResponse(
return response;
}
-webauth::mojom::GetAssertionAuthenticatorResponsePtr CreateGetAssertionResponse(
+blink::mojom::GetAssertionAuthenticatorResponsePtr CreateGetAssertionResponse(
const std::string& client_data_json,
device::AuthenticatorGetAssertionResponse response_data,
bool echo_appid_extension) {
- auto response = webauth::mojom::GetAssertionAuthenticatorResponse::New();
- auto common_info = webauth::mojom::CommonCredentialInfo::New();
+ auto response = blink::mojom::GetAssertionAuthenticatorResponse::New();
+ auto common_info = blink::mojom::CommonCredentialInfo::New();
common_info->client_data_json.assign(client_data_json.begin(),
client_data_json.end());
common_info->raw_id = response_data.raw_credential_id();
@@ -361,20 +335,29 @@ AuthenticatorImpl::AuthenticatorImpl(RenderFrameHost* render_frame_host,
protocols_.insert(
device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy);
}
-#if defined(OS_MACOSX)
- if (base::FeatureList::IsEnabled(features::kWebAuthTouchId)) {
- protocols_.insert(device::FidoTransportProtocol::kInternal);
- }
-#endif
}
-AuthenticatorImpl::~AuthenticatorImpl() {}
+AuthenticatorImpl::~AuthenticatorImpl() {
+ // This call exists to assert that |render_frame_host_| outlives this object.
+ // If this is violated, ASAN should notice.
+ render_frame_host_->GetRoutingID();
+}
+
+void AuthenticatorImpl::Bind(blink::mojom::AuthenticatorRequest request) {
+ // If |render_frame_host_| is being unloaded then binding requests are
+ // rejected.
+ if (!render_frame_host_->IsCurrent()) {
+ return;
+ }
-void AuthenticatorImpl::Bind(webauth::mojom::AuthenticatorRequest request) {
DCHECK(!binding_.is_bound());
binding_.Bind(std::move(request));
}
+bool AuthenticatorImpl::IsFocused() const {
+ return render_frame_host_->IsCurrent() && request_delegate_->IsFocused();
+}
+
// static
std::string AuthenticatorImpl::SerializeCollectedClientDataToJson(
const std::string& type,
@@ -428,18 +411,29 @@ std::string AuthenticatorImpl::SerializeCollectedClientDataToJson(
// mojom::Authenticator
void AuthenticatorImpl::MakeCredential(
- webauth::mojom::PublicKeyCredentialCreationOptionsPtr options,
+ blink::mojom::PublicKeyCredentialCreationOptionsPtr options,
MakeCredentialCallback callback) {
- if (u2f_request_ || ctap_request_) {
- std::move(callback).Run(
- webauth::mojom::AuthenticatorStatus::PENDING_REQUEST, nullptr);
+ if (request_) {
+ std::move(callback).Run(blink::mojom::AuthenticatorStatus::PENDING_REQUEST,
+ nullptr);
return;
}
- if (!GetContentClient()->browser()->IsFocused(
- WebContents::FromRenderFrameHost(render_frame_host_))) {
- std::move(callback).Run(webauth::mojom::AuthenticatorStatus::NOT_FOCUSED,
- nullptr);
+ DCHECK(!request_delegate_);
+ request_delegate_ =
+ GetContentClient()->browser()->GetWebAuthenticationRequestDelegate(
+ render_frame_host_);
+ if (!request_delegate_) {
+ InvokeCallbackAndCleanup(std::move(callback),
+ blink::mojom::AuthenticatorStatus::PENDING_REQUEST,
+ nullptr, Focus::kDontCheck);
+ return;
+ }
+
+ if (!IsFocused()) {
+ InvokeCallbackAndCleanup(std::move(callback),
+ blink::mojom::AuthenticatorStatus::NOT_FOCUSED,
+ nullptr, Focus::kDontCheck);
return;
}
@@ -449,47 +443,24 @@ void AuthenticatorImpl::MakeCredential(
if (!HasValidEffectiveDomain(caller_origin)) {
bad_message::ReceivedBadMessage(render_frame_host_->GetProcess(),
bad_message::AUTH_INVALID_EFFECTIVE_DOMAIN);
- InvokeCallbackAndCleanup(
- std::move(callback),
- webauth::mojom::AuthenticatorStatus::INVALID_DOMAIN, nullptr,
- Focus::kDontCheck);
+ InvokeCallbackAndCleanup(std::move(callback),
+ blink::mojom::AuthenticatorStatus::INVALID_DOMAIN,
+ nullptr, Focus::kDontCheck);
return;
}
if (!IsRelyingPartyIdValid(relying_party_id_, caller_origin)) {
bad_message::ReceivedBadMessage(render_frame_host_->GetProcess(),
bad_message::AUTH_INVALID_RELYING_PARTY);
- InvokeCallbackAndCleanup(
- std::move(callback),
- webauth::mojom::AuthenticatorStatus::INVALID_DOMAIN, nullptr,
- Focus::kDontCheck);
- return;
- }
-
- // Verify that the request doesn't contain parameters that U2F authenticators
- // cannot fulfill.
- // TODO(crbug.com/819256): Improve messages for "Not Allowed" errors.
- if (!base::FeatureList::IsEnabled(features::kWebAuthCtap2) &&
- !AreOptionsSupportedByU2fAuthenticators(options)) {
- InvokeCallbackAndCleanup(
- std::move(callback),
- webauth::mojom::AuthenticatorStatus::AUTHENTICATOR_CRITERIA_UNSUPPORTED,
- nullptr, Focus::kDontCheck);
- return;
- }
-
- if (!base::FeatureList::IsEnabled(features::kWebAuthCtap2) &&
- !IsAlgorithmSupportedByU2fAuthenticators(
- options->public_key_parameters)) {
- InvokeCallbackAndCleanup(
- std::move(callback),
- webauth::mojom::AuthenticatorStatus::ALGORITHM_UNSUPPORTED, nullptr,
- Focus::kDontCheck);
+ InvokeCallbackAndCleanup(std::move(callback),
+ blink::mojom::AuthenticatorStatus::INVALID_DOMAIN,
+ nullptr, Focus::kDontCheck);
return;
}
DCHECK(make_credential_response_callback_.is_null());
make_credential_response_callback_ = std::move(callback);
+ request_delegate_->DidStartRequest();
timer_->Start(
FROM_HERE, options->adjusted_timeout,
@@ -497,12 +468,6 @@ void AuthenticatorImpl::MakeCredential(
if (!connector_)
connector_ = ServiceManagerConnection::GetForProcess()->GetConnector();
- // 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);
- }
-
// Save client data to return with the authenticator response.
// TODO(kpaulhamus): Fetch and add the Token Binding ID public key used to
// communicate with the origin.
@@ -511,11 +476,9 @@ void AuthenticatorImpl::MakeCredential(
base::nullopt);
const bool individual_attestation =
- GetContentClient()
- ->browser()
- ->ShouldPermitIndividualAttestationForWebauthnRPID(
- render_frame_host_->GetProcess()->GetBrowserContext(),
- relying_party_id_);
+ options->attestation ==
+ blink::mojom::AttestationConveyancePreference::ENTERPRISE &&
+ request_delegate_->ShouldPermitIndividualAttestation(relying_party_id_);
attestation_preference_ = options->attestation;
@@ -524,43 +487,42 @@ void AuthenticatorImpl::MakeCredential(
protocols_.erase(
device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy);
- if (base::FeatureList::IsEnabled(features::kWebAuthCtap2)) {
- auto authenticator_selection_criteria =
- options->authenticator_selection
- ? mojo::ConvertTo<device::AuthenticatorSelectionCriteria>(
- options->authenticator_selection)
- : device::AuthenticatorSelectionCriteria();
-
- ctap_request_ = std::make_unique<device::MakeCredentialRequestHandler>(
- connector_, protocols_,
- CreateCtapMakeCredentialRequest(
- ConstructClientDataHash(client_data_json_), options),
- std::move(authenticator_selection_criteria),
- base::BindOnce(&AuthenticatorImpl::OnRegisterResponse,
- weak_factory_.GetWeakPtr()));
- } else {
- // TODO(kpaulhamus): Mock U2fRegister for unit tests.
- // http://crbug.com/785955.
- // 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).
- u2f_request_ = device::U2fRegister::TryRegistration(
- connector_, protocols_, registered_keys,
- ConstructClientDataHash(client_data_json_),
- CreateApplicationParameter(relying_party_id_), individual_attestation,
- base::BindOnce(&AuthenticatorImpl::OnRegisterResponse,
- weak_factory_.GetWeakPtr()));
- }
+ auto authenticator_selection_criteria =
+ options->authenticator_selection
+ ? mojo::ConvertTo<device::AuthenticatorSelectionCriteria>(
+ options->authenticator_selection)
+ : device::AuthenticatorSelectionCriteria();
+
+ request_ = std::make_unique<device::MakeCredentialRequestHandler>(
+ connector_, protocols_,
+ CreateCtapMakeCredentialRequest(
+ ConstructClientDataHash(client_data_json_), options,
+ individual_attestation),
+ std::move(authenticator_selection_criteria),
+ base::BindOnce(&AuthenticatorImpl::OnRegisterResponse,
+ weak_factory_.GetWeakPtr()),
+ base::BindOnce(&AuthenticatorImpl::MaybeCreatePlatformAuthenticator,
+ base::Unretained(this)));
}
// mojom:Authenticator
void AuthenticatorImpl::GetAssertion(
- webauth::mojom::PublicKeyCredentialRequestOptionsPtr options,
+ blink::mojom::PublicKeyCredentialRequestOptionsPtr options,
GetAssertionCallback callback) {
- if (u2f_request_ || ctap_request_) {
- std::move(callback).Run(
- webauth::mojom::AuthenticatorStatus::PENDING_REQUEST, nullptr);
+ if (request_) {
+ std::move(callback).Run(blink::mojom::AuthenticatorStatus::PENDING_REQUEST,
+ nullptr);
+ return;
+ }
+
+ DCHECK(!request_delegate_);
+ request_delegate_ =
+ GetContentClient()->browser()->GetWebAuthenticationRequestDelegate(
+ render_frame_host_);
+ if (!request_delegate_) {
+ InvokeCallbackAndCleanup(std::move(callback),
+ blink::mojom::AuthenticatorStatus::PENDING_REQUEST,
+ nullptr);
return;
}
@@ -569,41 +531,28 @@ void AuthenticatorImpl::GetAssertion(
if (!HasValidEffectiveDomain(caller_origin)) {
bad_message::ReceivedBadMessage(render_frame_host_->GetProcess(),
bad_message::AUTH_INVALID_EFFECTIVE_DOMAIN);
- InvokeCallbackAndCleanup(
- std::move(callback),
- webauth::mojom::AuthenticatorStatus::INVALID_DOMAIN, nullptr);
+ InvokeCallbackAndCleanup(std::move(callback),
+ blink::mojom::AuthenticatorStatus::INVALID_DOMAIN,
+ nullptr);
return;
}
if (!IsRelyingPartyIdValid(options->relying_party_id, caller_origin)) {
bad_message::ReceivedBadMessage(render_frame_host_->GetProcess(),
bad_message::AUTH_INVALID_RELYING_PARTY);
- InvokeCallbackAndCleanup(
- std::move(callback),
- webauth::mojom::AuthenticatorStatus::INVALID_DOMAIN, nullptr);
- return;
- }
-
- // To use U2F, the relying party must not require user verification.
- if (!base::FeatureList::IsEnabled(features::kWebAuthCtap2) &&
- options->user_verification ==
- webauth::mojom::UserVerificationRequirement::REQUIRED) {
- InvokeCallbackAndCleanup(
- std::move(callback),
- webauth::mojom::AuthenticatorStatus::USER_VERIFICATION_UNSUPPORTED,
- nullptr);
+ InvokeCallbackAndCleanup(std::move(callback),
+ blink::mojom::AuthenticatorStatus::INVALID_DOMAIN,
+ nullptr);
return;
}
- std::vector<uint8_t> application_parameter =
- CreateApplicationParameter(options->relying_party_id);
-
- base::Optional<std::vector<uint8_t>> alternative_application_parameter;
+ base::Optional<std::array<uint8_t, crypto::kSHA256Length>>
+ alternative_application_parameter;
if (options->appid) {
auto appid_hash = ProcessAppIdExtension(*options->appid, caller_origin);
if (!appid_hash) {
- std::move(callback).Run(
- webauth::mojom::AuthenticatorStatus::INVALID_DOMAIN, nullptr);
+ std::move(callback).Run(blink::mojom::AuthenticatorStatus::INVALID_DOMAIN,
+ nullptr);
return;
}
@@ -612,32 +561,9 @@ void AuthenticatorImpl::GetAssertion(
echo_appid_extension_ = true;
}
- // Pass along valid keys from allow_list.
- std::vector<std::vector<uint8_t>> handles =
- FilterCredentialList(std::move(options->allow_credentials));
-
- // There are two different descriptions of what should happen when
- // "allowCredentials" is empty for U2F.
- // a) WebAuthN 6.2.3 step 6[1] implies "NotAllowedError".
- // b) CTAP step 7.2 step 2[2] says the device should error out with
- // "CTAP2_ERR_OPTION_NOT_SUPPORTED". This also resolves to "NotAllowedError".
- // The behavior in both cases is consistent with the current implementation.
- // When CTAP2 is enabled, however, this check is done by handlers in
- // fido/device on a per-device basis.
-
- // [1] https://w3c.github.io/webauthn/#authenticatorgetassertion
- // [2]
- // https://fidoalliance.org/specs/fido-v2.0-ps-20170927/fido-client-to-authenticator-protocol-v2.0-ps-20170927.html
- if (!base::FeatureList::IsEnabled(features::kWebAuthCtap2) &&
- handles.empty()) {
- InvokeCallbackAndCleanup(
- std::move(callback),
- webauth::mojom::AuthenticatorStatus::EMPTY_ALLOW_CREDENTIALS, nullptr);
- return;
- }
-
DCHECK(get_assertion_response_callback_.is_null());
get_assertion_response_callback_ = std::move(callback);
+ request_delegate_->DidStartRequest();
timer_->Start(
FROM_HERE, options->adjusted_timeout,
@@ -653,29 +579,33 @@ void AuthenticatorImpl::GetAssertion(
client_data::kGetType, caller_origin, std::move(options->challenge),
base::nullopt);
- if (base::FeatureList::IsEnabled(features::kWebAuthCtap2)) {
- ctap_request_ = std::make_unique<device::GetAssertionRequestHandler>(
- connector_, protocols_,
- CreateCtapGetAssertionRequest(
- ConstructClientDataHash(client_data_json_), options),
- base::BindOnce(&AuthenticatorImpl::OnSignResponse,
- weak_factory_.GetWeakPtr()));
- } else {
- // Communication using Cable protocol is only supported for CTAP2 devices.
- protocols_.erase(
- device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy);
+ request_ = std::make_unique<device::GetAssertionRequestHandler>(
+ connector_, protocols_,
+ CreateCtapGetAssertionRequest(
+ ConstructClientDataHash(client_data_json_), std::move(options),
+ std::move(alternative_application_parameter)),
+ base::BindOnce(&AuthenticatorImpl::OnSignResponse,
+ weak_factory_.GetWeakPtr()),
+ base::BindOnce(&AuthenticatorImpl::MaybeCreatePlatformAuthenticator,
+ base::Unretained(this)));
+}
- u2f_request_ = device::U2fSign::TrySign(
- connector_, protocols_, handles,
- ConstructClientDataHash(client_data_json_), application_parameter,
- alternative_application_parameter,
- base::BindOnce(&AuthenticatorImpl::OnSignResponse,
- weak_factory_.GetWeakPtr()));
- }
+void AuthenticatorImpl::IsUserVerifyingPlatformAuthenticatorAvailable(
+ IsUserVerifyingPlatformAuthenticatorAvailableCallback callback) {
+ bool result = false;
+#if defined(OS_MACOSX)
+ result = device::fido::mac::TouchIdAuthenticator::IsAvailable();
+#endif
+ std::move(callback).Run(result);
}
void AuthenticatorImpl::DidFinishNavigation(
NavigationHandle* navigation_handle) {
+ // If the RenderFrameHost itself is navigated then this function will cause
+ // request state to be cleaned up. It's also possible for a navigation in the
+ // same frame to use a fresh RenderFrameHost. In this case,
+ // |render_frame_host_->IsCurrent()| will start returning false, causing all
+ // focus checks to fail if any Mojo requests are made in that state.
if (!navigation_handle->HasCommitted() ||
navigation_handle->IsSameDocument() ||
navigation_handle->GetRenderFrameHost() != render_frame_host_) {
@@ -686,27 +616,14 @@ void AuthenticatorImpl::DidFinishNavigation(
Cleanup();
}
-void AuthenticatorImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
- // In tests, the AuthenticatorImpl may outlive the RenderFrameHost, although
- // this cannot happen in a non-test context because, normally,
- // AuthenticatorImpl is owned by RenderFrameHost.
- if (render_frame_host != render_frame_host_) {
- return;
- }
-
- binding_.Close();
- Cleanup();
-}
-
// Callback to handle the async registration response from a U2fDevice.
void AuthenticatorImpl::OnRegisterResponse(
device::FidoReturnCode status_code,
base::Optional<device::AuthenticatorMakeCredentialResponse> response_data) {
- if (!u2f_request_ && !ctap_request_) {
- // Either the callback has been called immediately (in which case
- // |u2f_request_| / |ctap_request_| won't have been set yet), or
- // |RenderFrameDeleted| / |DidFinishNavigation| noticed that this object has
- // been orphaned.
+ if (!request_) {
+ // Either the callback was called immediately and |request_| has not yet
+ // been assigned (this is a bug), or a navigation caused the request to be
+ // canceled while a callback was enqueued.
return;
}
@@ -717,14 +634,14 @@ void AuthenticatorImpl::OnRegisterResponse(
// |exclude_credentials|.
InvokeCallbackAndCleanup(
std::move(make_credential_response_callback_),
- webauth::mojom::AuthenticatorStatus::CREDENTIAL_EXCLUDED, nullptr,
+ blink::mojom::AuthenticatorStatus::CREDENTIAL_EXCLUDED, nullptr,
Focus::kDoCheck);
return;
case device::FidoReturnCode::kAuthenticatorResponseInvalid:
// The response from the authenticator was corrupted.
InvokeCallbackAndCleanup(
std::move(make_credential_response_callback_),
- webauth::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr,
+ blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr,
Focus::kDoCheck);
return;
case device::FidoReturnCode::kUserConsentButCredentialNotRecognized:
@@ -734,21 +651,9 @@ void AuthenticatorImpl::OnRegisterResponse(
DCHECK(response_data.has_value());
if (attestation_preference_ !=
- webauth::mojom::AttestationConveyancePreference::NONE) {
- // Check for focus before (potentially) showing a permissions bubble
- // that might take focus.
- if (!GetContentClient()->browser()->IsFocused(
- WebContents::FromRenderFrameHost(render_frame_host_))) {
- InvokeCallbackAndCleanup(
- std::move(make_credential_response_callback_),
- webauth::mojom::AuthenticatorStatus::NOT_FOCUSED, nullptr,
- Focus::kDontCheck);
- return;
- }
-
- GetContentClient()->browser()->ShouldReturnAttestationForWebauthnRPID(
- render_frame_host_, relying_party_id_,
- render_frame_host_->GetLastCommittedOrigin(),
+ blink::mojom::AttestationConveyancePreference::NONE) {
+ request_delegate_->ShouldReturnAttestation(
+ relying_party_id_,
base::BindOnce(
&AuthenticatorImpl::OnRegisterResponseAttestationDecided,
weak_factory_.GetWeakPtr(), std::move(*response_data)));
@@ -758,7 +663,7 @@ void AuthenticatorImpl::OnRegisterResponse(
response_data->EraseAttestationStatement();
InvokeCallbackAndCleanup(
std::move(make_credential_response_callback_),
- webauth::mojom::AuthenticatorStatus::SUCCESS,
+ blink::mojom::AuthenticatorStatus::SUCCESS,
CreateMakeCredentialResponse(std::move(client_data_json_),
std::move(*response_data)),
Focus::kDoCheck);
@@ -770,24 +675,20 @@ void AuthenticatorImpl::OnRegisterResponse(
void AuthenticatorImpl::OnRegisterResponseAttestationDecided(
device::AuthenticatorMakeCredentialResponse response_data,
bool attestation_permitted) {
- DCHECK(attestation_preference_ !=
- webauth::mojom::AttestationConveyancePreference::NONE);
-
- if (!u2f_request_ && !ctap_request_) {
- // |DidFinishNavigation| / |RenderFrameDeleted| noticed that this object has
- // been orphaned.
+ if (!request_) {
+ // The request has already been cleaned up, probably because a navigation
+ // occured while the permissions prompt was pending.
return;
}
- // At this point, the final focus check has already been done because it's
- // possible that a permissions bubble might have focus and thus, if we did a
- // focus check, it would (incorrectly) fail.
+ DCHECK(attestation_preference_ !=
+ blink::mojom::AttestationConveyancePreference::NONE);
if (!attestation_permitted) {
InvokeCallbackAndCleanup(
std::move(make_credential_response_callback_),
- webauth::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr,
- Focus::kDontCheck);
+ blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr,
+ Focus::kDoCheck);
return;
}
@@ -798,11 +699,8 @@ void AuthenticatorImpl::OnRegisterResponseAttestationDecided(
// requesting direct attestation then it knows that it was one of the tokens
// with inappropriate certs.
if (response_data.IsAttestationCertificateInappropriatelyIdentifying() &&
- !GetContentClient()
- ->browser()
- ->ShouldPermitIndividualAttestationForWebauthnRPID(
- render_frame_host_->GetProcess()->GetBrowserContext(),
- relying_party_id_)) {
+ !request_delegate_->ShouldPermitIndividualAttestation(
+ relying_party_id_)) {
// The attestation response is incorrectly individually identifiable, but
// the consent is for make & model information about a token, not for
// individually-identifiable information. Erase the attestation to stop it
@@ -816,20 +714,19 @@ void AuthenticatorImpl::OnRegisterResponseAttestationDecided(
InvokeCallbackAndCleanup(
std::move(make_credential_response_callback_),
- webauth::mojom::AuthenticatorStatus::SUCCESS,
+ blink::mojom::AuthenticatorStatus::SUCCESS,
CreateMakeCredentialResponse(std::move(client_data_json_),
std::move(response_data)),
- Focus::kDontCheck);
+ Focus::kDoCheck);
}
void AuthenticatorImpl::OnSignResponse(
device::FidoReturnCode status_code,
base::Optional<device::AuthenticatorGetAssertionResponse> response_data) {
- if (!u2f_request_ && !ctap_request_) {
- // Either the callback has been called immediately (in which case
- // |u2f_request_| / |ctap_request_| won't have been set yet), or
- // |DidFinishNavigation| / |RenderFrameDeleted| noticed that this object has
- // been orphaned.
+ if (!request_) {
+ // Either the callback was called immediately and |request_| has not yet
+ // been assigned (this is a bug), or a navigation caused the request to be
+ // canceled while a callback was enqueued.
return;
}
@@ -838,14 +735,14 @@ void AuthenticatorImpl::OnSignResponse(
// No authenticators contained the credential.
InvokeCallbackAndCleanup(
std::move(get_assertion_response_callback_),
- webauth::mojom::AuthenticatorStatus::CREDENTIAL_NOT_RECOGNIZED,
+ blink::mojom::AuthenticatorStatus::CREDENTIAL_NOT_RECOGNIZED,
nullptr);
return;
case device::FidoReturnCode::kAuthenticatorResponseInvalid:
// The response from the authenticator was corrupted.
InvokeCallbackAndCleanup(
std::move(get_assertion_response_callback_),
- webauth::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr);
+ blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr);
return;
case device::FidoReturnCode::kUserConsentButCredentialExcluded:
NOTREACHED();
@@ -854,7 +751,7 @@ void AuthenticatorImpl::OnSignResponse(
DCHECK(response_data.has_value());
InvokeCallbackAndCleanup(
std::move(get_assertion_response_callback_),
- webauth::mojom::AuthenticatorStatus::SUCCESS,
+ blink::mojom::AuthenticatorStatus::SUCCESS,
CreateGetAssertionResponse(std::move(client_data_json_),
std::move(*response_data),
echo_appid_extension_));
@@ -871,24 +768,22 @@ void AuthenticatorImpl::OnTimeout() {
if (make_credential_response_callback_) {
InvokeCallbackAndCleanup(
std::move(make_credential_response_callback_),
- webauth::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr,
+ blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr,
Focus::kDontCheck);
} else if (get_assertion_response_callback_) {
InvokeCallbackAndCleanup(
std::move(get_assertion_response_callback_),
- webauth::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr);
+ blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR, nullptr);
}
}
void AuthenticatorImpl::InvokeCallbackAndCleanup(
MakeCredentialCallback callback,
- webauth::mojom::AuthenticatorStatus status,
- webauth::mojom::MakeCredentialAuthenticatorResponsePtr response,
+ blink::mojom::AuthenticatorStatus status,
+ blink::mojom::MakeCredentialAuthenticatorResponsePtr response,
Focus check_focus) {
- if (check_focus != Focus::kDontCheck &&
- !GetContentClient()->browser()->IsFocused(
- WebContents::FromRenderFrameHost(render_frame_host_))) {
- std::move(callback).Run(webauth::mojom::AuthenticatorStatus::NOT_FOCUSED,
+ if (check_focus != Focus::kDontCheck && !(request_delegate_ && IsFocused())) {
+ std::move(callback).Run(blink::mojom::AuthenticatorStatus::NOT_FOCUSED,
nullptr);
} else {
std::move(callback).Run(status, std::move(response));
@@ -899,20 +794,34 @@ void AuthenticatorImpl::InvokeCallbackAndCleanup(
void AuthenticatorImpl::InvokeCallbackAndCleanup(
GetAssertionCallback callback,
- webauth::mojom::AuthenticatorStatus status,
- webauth::mojom::GetAssertionAuthenticatorResponsePtr response) {
+ blink::mojom::AuthenticatorStatus status,
+ blink::mojom::GetAssertionAuthenticatorResponsePtr response) {
std::move(callback).Run(status, std::move(response));
Cleanup();
}
void AuthenticatorImpl::Cleanup() {
timer_->Stop();
- u2f_request_.reset();
- ctap_request_.reset();
+ request_.reset();
+ request_delegate_.reset();
make_credential_response_callback_.Reset();
get_assertion_response_callback_.Reset();
client_data_json_.clear();
echo_appid_extension_ = false;
}
+std::unique_ptr<device::FidoAuthenticator>
+AuthenticatorImpl::MaybeCreatePlatformAuthenticator() {
+#if defined(OS_MACOSX)
+ auto opt_authenticator_config =
+ request_delegate_->GetTouchIdAuthenticatorConfig();
+ if (opt_authenticator_config) {
+ return device::fido::mac::TouchIdAuthenticator::CreateIfAvailable(
+ std::move(opt_authenticator_config->keychain_access_group),
+ std::move(opt_authenticator_config->metadata_secret));
+ }
+#endif // defined(OS_MACOSX)
+ return nullptr;
+}
+
} // namespace content
diff --git a/chromium/content/browser/webauth/authenticator_impl.h b/chromium/content/browser/webauth/authenticator_impl.h
index 5fe89035a1a..538b06b559c 100644
--- a/chromium/content/browser/webauth/authenticator_impl.h
+++ b/chromium/content/browser/webauth/authenticator_impl.h
@@ -30,7 +30,7 @@ class OneShotTimer;
namespace device {
-class U2fRequest;
+class FidoAuthenticator;
class FidoRequestHandlerBase;
enum class FidoReturnCode : uint8_t;
@@ -47,6 +47,7 @@ class Origin;
namespace content {
+class AuthenticatorRequestClientDelegate;
class RenderFrameHost;
namespace client_data {
@@ -58,7 +59,7 @@ CONTENT_EXPORT extern const char kGetType[];
} // namespace client_data
// Implementation of the public Authenticator interface.
-class CONTENT_EXPORT AuthenticatorImpl : public webauth::mojom::Authenticator,
+class CONTENT_EXPORT AuthenticatorImpl : public blink::mojom::Authenticator,
public WebContentsObserver {
public:
explicit AuthenticatorImpl(RenderFrameHost* render_frame_host);
@@ -76,7 +77,7 @@ class CONTENT_EXPORT AuthenticatorImpl : public webauth::mojom::Authenticator,
// Note that one AuthenticatorImpl instance can be bound to exactly one
// interface connection at a time, and disconnected when the frame navigates
// to a new active document.
- void Bind(webauth::mojom::AuthenticatorRequest request);
+ void Bind(blink::mojom::AuthenticatorRequest request);
private:
friend class AuthenticatorImplTest;
@@ -87,6 +88,8 @@ class CONTENT_EXPORT AuthenticatorImpl : public webauth::mojom::Authenticator,
kDontCheck,
};
+ bool IsFocused() const;
+
// Builds the CollectedClientData[1] dictionary with the given values,
// serializes it to JSON, and returns the resulting string.
// [1] https://w3c.github.io/webauthn/#dictdef-collectedclientdata
@@ -98,15 +101,15 @@ class CONTENT_EXPORT AuthenticatorImpl : public webauth::mojom::Authenticator,
// mojom:Authenticator
void MakeCredential(
- webauth::mojom::PublicKeyCredentialCreationOptionsPtr options,
+ blink::mojom::PublicKeyCredentialCreationOptionsPtr options,
MakeCredentialCallback callback) override;
- void GetAssertion(
- webauth::mojom::PublicKeyCredentialRequestOptionsPtr options,
- GetAssertionCallback callback) override;
+ void GetAssertion(blink::mojom::PublicKeyCredentialRequestOptionsPtr options,
+ GetAssertionCallback callback) override;
+ void IsUserVerifyingPlatformAuthenticatorAvailable(
+ IsUserVerifyingPlatformAuthenticatorAvailableCallback callback) override;
// WebContentsObserver:
void DidFinishNavigation(NavigationHandle* navigation_handle) override;
- void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
// Callback to handle the async response from a U2fDevice.
void OnRegisterResponse(
@@ -130,25 +133,27 @@ class CONTENT_EXPORT AuthenticatorImpl : public webauth::mojom::Authenticator,
void InvokeCallbackAndCleanup(
MakeCredentialCallback callback,
- webauth::mojom::AuthenticatorStatus status,
- webauth::mojom::MakeCredentialAuthenticatorResponsePtr response,
+ blink::mojom::AuthenticatorStatus status,
+ blink::mojom::MakeCredentialAuthenticatorResponsePtr response,
Focus focus_check);
void InvokeCallbackAndCleanup(
GetAssertionCallback callback,
- webauth::mojom::AuthenticatorStatus status,
- webauth::mojom::GetAssertionAuthenticatorResponsePtr response);
+ blink::mojom::AuthenticatorStatus status,
+ blink::mojom::GetAssertionAuthenticatorResponsePtr response);
void Cleanup();
- RenderFrameHost* render_frame_host_;
+ std::unique_ptr<device::FidoAuthenticator> MaybeCreatePlatformAuthenticator();
+
+ RenderFrameHost* const render_frame_host_;
service_manager::Connector* connector_ = nullptr;
base::flat_set<device::FidoTransportProtocol> protocols_;
- std::unique_ptr<device::U2fRequest> u2f_request_;
- std::unique_ptr<device::FidoRequestHandlerBase> ctap_request_;
+ std::unique_ptr<device::FidoRequestHandlerBase> request_;
+ std::unique_ptr<AuthenticatorRequestClientDelegate> request_delegate_;
MakeCredentialCallback make_credential_response_callback_;
GetAssertionCallback get_assertion_response_callback_;
std::string client_data_json_;
- webauth::mojom::AttestationConveyancePreference attestation_preference_;
+ blink::mojom::AttestationConveyancePreference attestation_preference_;
std::string relying_party_id_;
std::unique_ptr<base::OneShotTimer> timer_;
@@ -159,7 +164,7 @@ class CONTENT_EXPORT AuthenticatorImpl : public webauth::mojom::Authenticator,
bool echo_appid_extension_ = false;
// Owns pipes to this Authenticator from |render_frame_host_|.
- mojo::Binding<webauth::mojom::Authenticator> binding_;
+ mojo::Binding<blink::mojom::Authenticator> binding_;
base::WeakPtrFactory<AuthenticatorImpl> weak_factory_;
diff --git a/chromium/content/browser/webauth/authenticator_impl_unittest.cc b/chromium/content/browser/webauth/authenticator_impl_unittest.cc
index 26ad5fd258c..45908fea5bc 100644
--- a/chromium/content/browser/webauth/authenticator_impl_unittest.cc
+++ b/chromium/content/browser/webauth/authenticator_impl_unittest.cc
@@ -9,6 +9,7 @@
#include <utility>
#include <vector>
+#include "base/bind_helpers.h"
#include "base/json/json_parser.h"
#include "base/json/json_writer.h"
#include "base/run_loop.h"
@@ -19,10 +20,12 @@
#include "base/time/time.h"
#include "components/cbor/cbor_reader.h"
#include "components/cbor/cbor_values.h"
+#include "content/public/browser/authenticator_request_client_delegate.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_features.h"
#include "content/public/test/test_service_manager_context.h"
#include "content/test/test_render_frame_host.h"
+#include "device/base/features.h"
#include "device/fido/fake_hid_impl_for_testing.h"
#include "device/fido/scoped_virtual_fido_device.h"
#include "device/fido/test_callback_receiver.h"
@@ -35,28 +38,28 @@ namespace content {
using ::testing::_;
+using blink::mojom::AttestationConveyancePreference;
+using blink::mojom::AuthenticatorPtr;
+using blink::mojom::AuthenticatorSelectionCriteria;
+using blink::mojom::AuthenticatorSelectionCriteriaPtr;
+using blink::mojom::AuthenticatorStatus;
+using blink::mojom::GetAssertionAuthenticatorResponsePtr;
+using blink::mojom::MakeCredentialAuthenticatorResponsePtr;
+using blink::mojom::PublicKeyCredentialCreationOptions;
+using blink::mojom::PublicKeyCredentialCreationOptionsPtr;
+using blink::mojom::PublicKeyCredentialDescriptor;
+using blink::mojom::PublicKeyCredentialDescriptorPtr;
+using blink::mojom::PublicKeyCredentialParameters;
+using blink::mojom::PublicKeyCredentialParametersPtr;
+using blink::mojom::PublicKeyCredentialRequestOptions;
+using blink::mojom::PublicKeyCredentialRequestOptionsPtr;
+using blink::mojom::PublicKeyCredentialRpEntity;
+using blink::mojom::PublicKeyCredentialRpEntityPtr;
+using blink::mojom::PublicKeyCredentialType;
+using blink::mojom::PublicKeyCredentialUserEntity;
+using blink::mojom::PublicKeyCredentialUserEntityPtr;
using cbor::CBORValue;
using cbor::CBORReader;
-using webauth::mojom::AttestationConveyancePreference;
-using webauth::mojom::AuthenticatorPtr;
-using webauth::mojom::AuthenticatorSelectionCriteria;
-using webauth::mojom::AuthenticatorSelectionCriteriaPtr;
-using webauth::mojom::AuthenticatorStatus;
-using webauth::mojom::GetAssertionAuthenticatorResponsePtr;
-using webauth::mojom::MakeCredentialAuthenticatorResponsePtr;
-using webauth::mojom::PublicKeyCredentialCreationOptions;
-using webauth::mojom::PublicKeyCredentialCreationOptionsPtr;
-using webauth::mojom::PublicKeyCredentialDescriptor;
-using webauth::mojom::PublicKeyCredentialDescriptorPtr;
-using webauth::mojom::PublicKeyCredentialParameters;
-using webauth::mojom::PublicKeyCredentialParametersPtr;
-using webauth::mojom::PublicKeyCredentialRequestOptions;
-using webauth::mojom::PublicKeyCredentialRequestOptionsPtr;
-using webauth::mojom::PublicKeyCredentialRpEntity;
-using webauth::mojom::PublicKeyCredentialRpEntityPtr;
-using webauth::mojom::PublicKeyCredentialType;
-using webauth::mojom::PublicKeyCredentialUserEntity;
-using webauth::mojom::PublicKeyCredentialUserEntityPtr;
namespace {
@@ -196,6 +199,7 @@ using TestMakeCredentialCallback = device::test::StatusAndValueCallbackReceiver<
using TestGetAssertionCallback = device::test::StatusAndValueCallbackReceiver<
AuthenticatorStatus,
GetAssertionAuthenticatorResponsePtr>;
+using TestRequestStartedCallback = device::test::TestCallbackReceiver<>;
std::vector<uint8_t> GetTestChallengeBytes() {
return std::vector<uint8_t>(std::begin(kTestChallengeBytes),
@@ -223,7 +227,7 @@ std::vector<PublicKeyCredentialParametersPtr>
GetTestPublicKeyCredentialParameters(int32_t algorithm_identifier) {
std::vector<PublicKeyCredentialParametersPtr> parameters;
auto fake_parameter = PublicKeyCredentialParameters::New();
- fake_parameter->type = webauth::mojom::PublicKeyCredentialType::PUBLIC_KEY;
+ fake_parameter->type = blink::mojom::PublicKeyCredentialType::PUBLIC_KEY;
fake_parameter->algorithm_identifier = algorithm_identifier;
parameters.push_back(std::move(fake_parameter));
return parameters;
@@ -232,10 +236,10 @@ GetTestPublicKeyCredentialParameters(int32_t algorithm_identifier) {
AuthenticatorSelectionCriteriaPtr GetTestAuthenticatorSelectionCriteria() {
auto criteria = AuthenticatorSelectionCriteria::New();
criteria->authenticator_attachment =
- webauth::mojom::AuthenticatorAttachment::NO_PREFERENCE;
+ blink::mojom::AuthenticatorAttachment::NO_PREFERENCE;
criteria->require_resident_key = false;
criteria->user_verification =
- webauth::mojom::UserVerificationRequirement::PREFERRED;
+ blink::mojom::UserVerificationRequirement::PREFERRED;
return criteria;
}
@@ -269,7 +273,7 @@ GetTestPublicKeyCredentialRequestOptions() {
options->challenge.assign(32, 0x0A);
options->adjusted_timeout = base::TimeDelta::FromMinutes(1);
options->user_verification =
- webauth::mojom::UserVerificationRequirement::PREFERRED;
+ blink::mojom::UserVerificationRequirement::PREFERRED;
options->allow_credentials = GetTestAllowCredentials();
return options;
}
@@ -282,6 +286,18 @@ class AuthenticatorImplTest : public content::RenderViewHostTestHarness {
~AuthenticatorImplTest() override {}
protected:
+ void TearDown() override {
+ // The |RenderFrameHost| must outlive |AuthenticatorImpl|.
+ authenticator_impl_.reset();
+ content::RenderViewHostTestHarness::TearDown();
+ }
+
+ void NavigateAndCommit(const GURL& url) {
+ // The |RenderFrameHost| must outlive |AuthenticatorImpl|.
+ authenticator_impl_.reset();
+ content::RenderViewHostTestHarness::NavigateAndCommit(url);
+ }
+
// Simulates navigating to a page and getting the page contents and language
// for that navigation.
void SimulateNavigation(const GURL& url) {
@@ -306,6 +322,24 @@ class AuthenticatorImplTest : public content::RenderViewHostTestHarness {
return authenticator;
}
+ AuthenticatorPtr ConstructAuthenticatorWithTimer(
+ scoped_refptr<base::TestMockTimeTaskRunner> task_runner) {
+ connector_ = service_manager::Connector::Create(&request_);
+ fake_hid_manager_ = std::make_unique<device::FakeHidManager>();
+ service_manager::Connector::TestApi test_api(connector_.get());
+ test_api.OverrideBinderForTesting(
+ service_manager::Identity(device::mojom::kServiceName),
+ device::mojom::HidManager::Name_,
+ base::Bind(&device::FakeHidManager::AddBinding,
+ base::Unretained(fake_hid_manager_.get())));
+
+ // Set up a timer for testing.
+ auto timer =
+ std::make_unique<base::OneShotTimer>(task_runner->GetMockTickClock());
+ timer->SetTaskRunner(task_runner);
+ return ConnectToAuthenticator(connector_.get(), std::move(timer));
+ }
+
url::Origin GetTestOrigin() {
const GURL test_relying_party_url(kTestOrigin1);
CHECK(test_relying_party_url.is_valid());
@@ -347,8 +381,11 @@ class AuthenticatorImplTest : public content::RenderViewHostTestHarness {
return base::ContainsKey(authenticator_impl_->protocols_, protocol);
}
- private:
+ protected:
std::unique_ptr<AuthenticatorImpl> authenticator_impl_;
+ service_manager::mojom::ConnectorRequest request_;
+ std::unique_ptr<service_manager::Connector> connector_;
+ std::unique_ptr<device::FakeHidManager> fake_hid_manager_;
};
// Verify behavior for various combinations of origins and RP IDs.
@@ -371,14 +408,18 @@ TEST_F(AuthenticatorImplTest, MakeCredentialOriginAndRpIds) {
EXPECT_EQ(AuthenticatorStatus::INVALID_DOMAIN, callback_receiver.status());
}
- // These instances pass the origin and relying party checks and return at
- // the algorithm check.
+ // These instances time out with NOT_ALLOWED_ERROR due to unsupported
+ // algorithm.
for (auto test_case : kValidRelyingPartyTestCases) {
SCOPED_TRACE(std::string(test_case.claimed_authority) + " " +
std::string(test_case.origin));
NavigateAndCommit(GURL(test_case.origin));
- AuthenticatorPtr authenticator = ConnectToAuthenticator();
+ device::test::ScopedVirtualFidoDevice scoped_virtual_device;
+ auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+ base::Time::Now(), base::TimeTicks::Now());
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
+
PublicKeyCredentialCreationOptionsPtr options =
GetTestPublicKeyCredentialCreationOptions();
options->relying_party->id = test_case.claimed_authority;
@@ -387,17 +428,23 @@ TEST_F(AuthenticatorImplTest, MakeCredentialOriginAndRpIds) {
TestMakeCredentialCallback callback_receiver;
authenticator->MakeCredential(std::move(options),
callback_receiver.callback());
+ // Trigger timer.
+ base::RunLoop().RunUntilIdle();
+ task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::ALGORITHM_UNSUPPORTED,
+ EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR,
callback_receiver.status());
}
}
-// Test that service returns ALGORITHM_UNSUPPORTED if no parameters contain
-// a supported algorithm.
+// Test that MakeCredential request times out with NOT_ALLOWED_ERROR if no
+// parameters contain a supported algorithm.
TEST_F(AuthenticatorImplTest, MakeCredentialNoSupportedAlgorithm) {
SimulateNavigation(GURL(kTestOrigin1));
- AuthenticatorPtr authenticator = ConnectToAuthenticator();
+ device::test::ScopedVirtualFidoDevice scoped_virtual_device;
+ auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+ base::Time::Now(), base::TimeTicks::Now());
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
PublicKeyCredentialCreationOptionsPtr options =
GetTestPublicKeyCredentialCreationOptions();
@@ -406,52 +453,68 @@ TEST_F(AuthenticatorImplTest, MakeCredentialNoSupportedAlgorithm) {
TestMakeCredentialCallback callback_receiver;
authenticator->MakeCredential(std::move(options),
callback_receiver.callback());
+ // Trigger timer.
+ base::RunLoop().RunUntilIdle();
+ task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::ALGORITHM_UNSUPPORTED,
- callback_receiver.status());
+ EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
}
-// Test that service returns USER_VERIFICATION_UNSUPPORTED if user verification
-// is REQUIRED for get().
+// Test that service returns NOT_ALLOWED_ERROR if user verification is REQUIRED
+// for get().
TEST_F(AuthenticatorImplTest, GetAssertionUserVerification) {
SimulateNavigation(GURL(kTestOrigin1));
- AuthenticatorPtr authenticator = ConnectToAuthenticator();
+ device::test::ScopedVirtualFidoDevice scoped_virtual_device;
+ auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+ base::Time::Now(), base::TimeTicks::Now());
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
PublicKeyCredentialRequestOptionsPtr options =
GetTestPublicKeyCredentialRequestOptions();
options->user_verification =
- webauth::mojom::UserVerificationRequirement::REQUIRED;
+ blink::mojom::UserVerificationRequirement::REQUIRED;
TestGetAssertionCallback callback_receiver;
authenticator->GetAssertion(std::move(options), callback_receiver.callback());
+
+ // Trigger timer.
+ base::RunLoop().RunUntilIdle();
+ task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::USER_VERIFICATION_UNSUPPORTED,
- callback_receiver.status());
+ EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
}
-// Test that service returns AUTHENTICATOR_CRITERIA_UNSUPPORTED if user
-// verification is REQUIRED for create().
+// Test that MakeCredential request times out with NOT_ALLOWED_ERROR if user
+// verification is required for U2F devices.
TEST_F(AuthenticatorImplTest, MakeCredentialUserVerification) {
SimulateNavigation(GURL(kTestOrigin1));
- AuthenticatorPtr authenticator = ConnectToAuthenticator();
+ device::test::ScopedVirtualFidoDevice scoped_virtual_device;
+ auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+ base::Time::Now(), base::TimeTicks::Now());
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
PublicKeyCredentialCreationOptionsPtr options =
GetTestPublicKeyCredentialCreationOptions();
options->authenticator_selection->user_verification =
- webauth::mojom::UserVerificationRequirement::REQUIRED;
+ blink::mojom::UserVerificationRequirement::REQUIRED;
TestMakeCredentialCallback callback_receiver;
authenticator->MakeCredential(std::move(options),
callback_receiver.callback());
+ // Trigger timer.
+ base::RunLoop().RunUntilIdle();
+ task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::AUTHENTICATOR_CRITERIA_UNSUPPORTED,
- callback_receiver.status());
+ EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
}
-// Test that service returns AUTHENTICATOR_CRITERIA_UNSUPPORTED if resident key
-// is requested for create().
+// Test that MakeCredential request times out with NOT_ALLOWED_ERROR if resident
+// key is requested for U2F devices on create().
TEST_F(AuthenticatorImplTest, MakeCredentialResidentKey) {
SimulateNavigation(GURL(kTestOrigin1));
- AuthenticatorPtr authenticator = ConnectToAuthenticator();
+ device::test::ScopedVirtualFidoDevice scoped_virtual_device;
+ auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+ base::Time::Now(), base::TimeTicks::Now());
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
PublicKeyCredentialCreationOptionsPtr options =
GetTestPublicKeyCredentialCreationOptions();
@@ -460,28 +523,34 @@ TEST_F(AuthenticatorImplTest, MakeCredentialResidentKey) {
TestMakeCredentialCallback callback_receiver;
authenticator->MakeCredential(std::move(options),
callback_receiver.callback());
+ // Trigger timer.
+ base::RunLoop().RunUntilIdle();
+ task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::AUTHENTICATOR_CRITERIA_UNSUPPORTED,
- callback_receiver.status());
+ EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
}
-// Test that service returns AUTHENTICATOR_CRITERIA_UNSUPPORTED if a platform
-// authenticator is requested for U2F.
+// Test that MakeCredential request times out with NOT_ALLOWED_ERROR if a
+// platform authenticator is requested for U2F devices.
TEST_F(AuthenticatorImplTest, MakeCredentialPlatformAuthenticator) {
SimulateNavigation(GURL(kTestOrigin1));
- AuthenticatorPtr authenticator = ConnectToAuthenticator();
+ auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+ base::Time::Now(), base::TimeTicks::Now());
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
PublicKeyCredentialCreationOptionsPtr options =
GetTestPublicKeyCredentialCreationOptions();
options->authenticator_selection->authenticator_attachment =
- webauth::mojom::AuthenticatorAttachment::PLATFORM;
+ blink::mojom::AuthenticatorAttachment::PLATFORM;
TestMakeCredentialCallback callback_receiver;
authenticator->MakeCredential(std::move(options),
callback_receiver.callback());
+ // Trigger timer.
+ base::RunLoop().RunUntilIdle();
+ task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::AUTHENTICATOR_CRITERIA_UNSUPPORTED,
- callback_receiver.status());
+ EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
}
// Parses its arguments as JSON and expects that all the keys in the first are
@@ -557,26 +626,9 @@ TEST_F(AuthenticatorImplTest, TestMakeCredentialTimeout) {
GetTestPublicKeyCredentialCreationOptions();
TestMakeCredentialCallback callback_receiver;
- // Set up service_manager::Connector for tests.
- auto fake_hid_manager = std::make_unique<device::FakeHidManager>();
- service_manager::mojom::ConnectorRequest request;
- auto connector = service_manager::Connector::Create(&request);
- service_manager::Connector::TestApi test_api(connector.get());
- test_api.OverrideBinderForTesting(
- service_manager::Identity(device::mojom::kServiceName),
- device::mojom::HidManager::Name_,
- base::Bind(&device::FakeHidManager::AddBinding,
- base::Unretained(fake_hid_manager.get())));
-
- // Set up a timer for testing.
auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
base::Time::Now(), base::TimeTicks::Now());
- auto timer =
- std::make_unique<base::OneShotTimer>(task_runner->GetMockTickClock());
- timer->SetTaskRunner(task_runner);
- AuthenticatorPtr authenticator =
- ConnectToAuthenticator(connector.get(), std::move(timer));
-
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
authenticator->MakeCredential(std::move(options),
callback_receiver.callback());
@@ -661,26 +713,9 @@ TEST_F(AuthenticatorImplTest, TestGetAssertionTimeout) {
GetTestPublicKeyCredentialRequestOptions();
TestGetAssertionCallback callback_receiver;
- // Set up service_manager::Connector for tests.
- auto fake_hid_manager = std::make_unique<device::FakeHidManager>();
- service_manager::mojom::ConnectorRequest request;
- auto connector = service_manager::Connector::Create(&request);
- service_manager::Connector::TestApi test_api(connector.get());
- test_api.OverrideBinderForTesting(
- service_manager::Identity(device::mojom::kServiceName),
- device::mojom::HidManager::Name_,
- base::Bind(&device::FakeHidManager::AddBinding,
- base::Unretained(fake_hid_manager.get())));
-
- // Set up a timer for testing.
auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
base::Time::Now(), base::TimeTicks::Now());
- auto timer =
- std::make_unique<base::OneShotTimer>(task_runner->GetMockTickClock());
- timer->SetTaskRunner(task_runner);
- AuthenticatorPtr authenticator =
- ConnectToAuthenticator(connector.get(), std::move(timer));
-
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
authenticator->GetAssertion(std::move(options), callback_receiver.callback());
// Trigger timer.
@@ -735,8 +770,7 @@ TEST_F(AuthenticatorImplTest, TestCableDiscoveryEnabledWithSwitch) {
TestServiceManagerContext service_manager_context;
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
- std::vector<base::Feature>{features::kWebAuthCtap2,
- features::kWebAuthCable},
+ std::vector<base::Feature>{features::kWebAuthCable},
std::vector<base::Feature>{});
SimulateNavigation(GURL(kTestOrigin1));
@@ -744,25 +778,9 @@ TEST_F(AuthenticatorImplTest, TestCableDiscoveryEnabledWithSwitch) {
GetTestPublicKeyCredentialRequestOptions();
TestGetAssertionCallback callback_receiver;
- // Set up service_manager::Connector for tests.
- auto fake_hid_manager = std::make_unique<device::FakeHidManager>();
- service_manager::mojom::ConnectorRequest request;
- auto connector = service_manager::Connector::Create(&request);
- service_manager::Connector::TestApi test_api(connector.get());
- test_api.OverrideBinderForTesting(
- service_manager::Identity(device::mojom::kServiceName),
- device::mojom::HidManager::Name_,
- base::Bind(&device::FakeHidManager::AddBinding,
- base::Unretained(fake_hid_manager.get())));
-
- // Set up a timer for testing.
auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
base::Time::Now(), base::TimeTicks::Now());
- auto timer =
- std::make_unique<base::OneShotTimer>(task_runner->GetMockTickClock());
- timer->SetTaskRunner(task_runner);
- AuthenticatorPtr authenticator =
- ConnectToAuthenticator(connector.get(), std::move(timer));
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
authenticator->GetAssertion(std::move(options), callback_receiver.callback());
// Trigger timer.
@@ -777,35 +795,16 @@ TEST_F(AuthenticatorImplTest, TestCableDiscoveryEnabledWithSwitch) {
TEST_F(AuthenticatorImplTest, TestCableDiscoveryDisabledForMakeCredential) {
base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitWithFeatures(
- std::vector<base::Feature>{features::kWebAuthCtap2,
- features::kWebAuthCable},
- std::vector<base::Feature>{});
+ scoped_feature_list.InitAndEnableFeature(features::kWebAuthCable);
SimulateNavigation(GURL(kTestOrigin1));
PublicKeyCredentialCreationOptionsPtr options =
GetTestPublicKeyCredentialCreationOptions();
TestMakeCredentialCallback callback_receiver;
- // Set up service_manager::Connector for tests.
- auto fake_hid_manager = std::make_unique<device::FakeHidManager>();
- service_manager::mojom::ConnectorRequest request;
- auto connector = service_manager::Connector::Create(&request);
- service_manager::Connector::TestApi test_api(connector.get());
- test_api.OverrideBinderForTesting(
- service_manager::Identity(device::mojom::kServiceName),
- device::mojom::HidManager::Name_,
- base::Bind(&device::FakeHidManager::AddBinding,
- base::Unretained(fake_hid_manager.get())));
-
- // Set up a timer for testing.
auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
base::Time::Now(), base::TimeTicks::Now());
- auto timer =
- std::make_unique<base::OneShotTimer>(task_runner->GetMockTickClock());
- timer->SetTaskRunner(task_runner);
- AuthenticatorPtr authenticator =
- ConnectToAuthenticator(connector.get(), std::move(timer));
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
authenticator->MakeCredential(std::move(options),
callback_receiver.callback());
@@ -820,33 +819,14 @@ TEST_F(AuthenticatorImplTest, TestCableDiscoveryDisabledForMakeCredential) {
}
TEST_F(AuthenticatorImplTest, TestCableDiscoveryDisabledWithoutSwitch) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kWebAuthCtap2);
-
SimulateNavigation(GURL(kTestOrigin1));
PublicKeyCredentialRequestOptionsPtr options =
GetTestPublicKeyCredentialRequestOptions();
TestGetAssertionCallback callback_receiver;
- // Set up service_manager::Connector for tests.
- auto fake_hid_manager = std::make_unique<device::FakeHidManager>();
- service_manager::mojom::ConnectorRequest request;
- auto connector = service_manager::Connector::Create(&request);
- service_manager::Connector::TestApi test_api(connector.get());
- test_api.OverrideBinderForTesting(
- service_manager::Identity(device::mojom::kServiceName),
- device::mojom::HidManager::Name_,
- base::Bind(&device::FakeHidManager::AddBinding,
- base::Unretained(fake_hid_manager.get())));
-
- // Set up a timer for testing.
auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
base::Time::Now(), base::TimeTicks::Now());
- auto timer =
- std::make_unique<base::OneShotTimer>(task_runner->GetMockTickClock());
- timer->SetTaskRunner(task_runner);
- AuthenticatorPtr authenticator =
- ConnectToAuthenticator(connector.get(), std::move(timer));
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
authenticator->GetAssertion(std::move(options), callback_receiver.callback());
// Trigger timer.
@@ -859,97 +839,37 @@ TEST_F(AuthenticatorImplTest, TestCableDiscoveryDisabledWithoutSwitch) {
device::FidoTransportProtocol::kCloudAssistedBluetoothLowEnergy));
}
-TEST_F(AuthenticatorImplTest, TestU2fDeviceDoesNotSupportMakeCredential) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kWebAuthCtap2);
-
- SimulateNavigation(GURL(kTestOrigin1));
- PublicKeyCredentialCreationOptionsPtr options =
- GetTestPublicKeyCredentialCreationOptions();
- TestMakeCredentialCallback callback_receiver;
-
- // Set up service_manager::Connector for tests.
- auto fake_hid_manager = std::make_unique<device::FakeHidManager>();
- service_manager::mojom::ConnectorRequest request;
- auto connector = service_manager::Connector::Create(&request);
-
- // Set up a timer for testing.
- auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
- base::Time::Now(), base::TimeTicks::Now());
- auto timer =
- std::make_unique<base::OneShotTimer>(task_runner->GetMockTickClock());
- timer->SetTaskRunner(task_runner);
- AuthenticatorPtr authenticator =
- ConnectToAuthenticator(connector.get(), std::move(timer));
-
- device::test::ScopedVirtualFidoDevice virtual_device;
- authenticator->MakeCredential(std::move(options),
- callback_receiver.callback());
-
- // Trigger timer.
- base::RunLoop().RunUntilIdle();
- task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
- callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
-}
-
-TEST_F(AuthenticatorImplTest, TestU2fDeviceDoesNotSupportGetAssertion) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kWebAuthCtap2);
-
+TEST_F(AuthenticatorImplTest, TestGetAssertionU2fDeviceBackwardsCompatibility) {
SimulateNavigation(GURL(kTestOrigin1));
PublicKeyCredentialRequestOptionsPtr options =
GetTestPublicKeyCredentialRequestOptions();
TestGetAssertionCallback callback_receiver;
-
- // Set up service_manager::Connector for tests.
- auto fake_hid_manager = std::make_unique<device::FakeHidManager>();
- service_manager::mojom::ConnectorRequest request;
- auto connector = service_manager::Connector::Create(&request);
-
- // Set up a timer for testing.
auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
base::Time::Now(), base::TimeTicks::Now());
- auto timer =
- std::make_unique<base::OneShotTimer>(task_runner->GetMockTickClock());
- timer->SetTaskRunner(task_runner);
- AuthenticatorPtr authenticator =
- ConnectToAuthenticator(connector.get(), std::move(timer));
-
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
device::test::ScopedVirtualFidoDevice virtual_device;
+ // Inject credential ID to the virtual device so that successful sign in is
+ // possible.
+ ASSERT_TRUE(virtual_device.mutable_state()->InjectRegistration(
+ options->allow_credentials[0]->id, kTestRelyingPartyId));
+
authenticator->GetAssertion(std::move(options), callback_receiver.callback());
// Trigger timer.
- base::RunLoop().RunUntilIdle();
- task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
+ EXPECT_EQ(AuthenticatorStatus::SUCCESS, callback_receiver.status());
}
-TEST_F(AuthenticatorImplTest, Ctap2AcceptsEmptyAllowCredentials) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(features::kWebAuthCtap2);
-
+TEST_F(AuthenticatorImplTest, GetAssertionWithEmptyAllowCredentials) {
SimulateNavigation(GURL(kTestOrigin1));
PublicKeyCredentialRequestOptionsPtr options =
GetTestPublicKeyCredentialRequestOptions();
options->allow_credentials.clear();
TestGetAssertionCallback callback_receiver;
- // Set up service_manager::Connector for tests.
- auto fake_hid_manager = std::make_unique<device::FakeHidManager>();
- service_manager::mojom::ConnectorRequest request;
- auto connector = service_manager::Connector::Create(&request);
-
- // Set up a timer for testing.
auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
base::Time::Now(), base::TimeTicks::Now());
- auto timer =
- std::make_unique<base::OneShotTimer>(task_runner->GetMockTickClock());
- timer->SetTaskRunner(task_runner);
- AuthenticatorPtr authenticator =
- ConnectToAuthenticator(connector.get(), std::move(timer));
-
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
device::test::ScopedVirtualFidoDevice virtual_device;
authenticator->GetAssertion(std::move(options), callback_receiver.callback());
@@ -957,26 +877,7 @@ TEST_F(AuthenticatorImplTest, Ctap2AcceptsEmptyAllowCredentials) {
base::RunLoop().RunUntilIdle();
task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
- // Doesn't error out with EMPTY_ALLOW_CREDENTIALS but continues to a
- // NOT_ALLOWED_ERROR.
- EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, callback_receiver.status());
-}
-
-TEST_F(AuthenticatorImplTest, GetAssertionWithEmptyAllowCredentials) {
- device::test::ScopedVirtualFidoDevice scoped_virtual_device;
- TestServiceManagerContext service_manager_context;
-
- SimulateNavigation(GURL(kTestOrigin1));
- AuthenticatorPtr authenticator = ConnectToAuthenticator();
- PublicKeyCredentialRequestOptionsPtr options =
- GetTestPublicKeyCredentialRequestOptions();
- options->allow_credentials.clear();
-
- TestGetAssertionCallback callback_receiver;
- authenticator->GetAssertion(std::move(options), callback_receiver.callback());
- callback_receiver.WaitForCallback();
-
- EXPECT_EQ(AuthenticatorStatus::EMPTY_ALLOW_CREDENTIALS,
+ EXPECT_EQ(AuthenticatorStatus::CREDENTIAL_NOT_RECOGNIZED,
callback_receiver.status());
}
@@ -1028,6 +929,8 @@ TEST_F(AuthenticatorImplTest, MakeCredentialPendingRequest) {
callback_receiver2.WaitForCallback();
EXPECT_EQ(AuthenticatorStatus::PENDING_REQUEST, callback_receiver2.status());
+
+ callback_receiver.WaitForCallback();
}
TEST_F(AuthenticatorImplTest, GetAssertionPendingRequest) {
@@ -1054,6 +957,41 @@ TEST_F(AuthenticatorImplTest, GetAssertionPendingRequest) {
callback_receiver2.WaitForCallback();
EXPECT_EQ(AuthenticatorStatus::PENDING_REQUEST, callback_receiver2.status());
+
+ callback_receiver.WaitForCallback();
+}
+
+TEST_F(AuthenticatorImplTest, NavigationDuringOperation) {
+ device::test::ScopedVirtualFidoDevice scoped_virtual_device;
+ TestServiceManagerContext service_manager_context;
+
+ SimulateNavigation(GURL(kTestOrigin1));
+ AuthenticatorPtr authenticator = ConnectToAuthenticator();
+
+ base::RunLoop run_loop;
+ authenticator.set_connection_error_handler(run_loop.QuitClosure());
+
+ // Make first request.
+ PublicKeyCredentialRequestOptionsPtr options =
+ GetTestPublicKeyCredentialRequestOptions();
+ TestGetAssertionCallback callback_receiver;
+ authenticator->GetAssertion(std::move(options), callback_receiver.callback());
+
+ // Delete the |AuthenticatorImpl| during the registration operation to
+ // simulate a navigation while waiting for the user to press the token.
+ scoped_virtual_device.mutable_state()->simulate_press_callback =
+ base::BindRepeating(
+ [](std::unique_ptr<AuthenticatorImpl>* ptr) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(
+ [](std::unique_ptr<AuthenticatorImpl>* ptr) {
+ ptr->reset();
+ },
+ ptr));
+ },
+ &authenticator_impl_);
+
+ run_loop.Run();
}
TEST_F(AuthenticatorImplTest, InvalidResponse) {
@@ -1061,9 +999,11 @@ TEST_F(AuthenticatorImplTest, InvalidResponse) {
TestServiceManagerContext service_manager_context;
scoped_virtual_device.mutable_state()->simulate_invalid_response = true;
-
SimulateNavigation(GURL(kTestOrigin1));
- AuthenticatorPtr authenticator = ConnectToAuthenticator();
+
+ auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
+ base::Time::Now(), base::TimeTicks::Now());
+ auto authenticator = ConstructAuthenticatorWithTimer(task_runner);
{
PublicKeyCredentialRequestOptionsPtr options =
@@ -1071,8 +1011,10 @@ TEST_F(AuthenticatorImplTest, InvalidResponse) {
TestGetAssertionCallback callback_receiver;
authenticator->GetAssertion(std::move(options),
callback_receiver.callback());
+ // Trigger timer.
+ base::RunLoop().RunUntilIdle();
+ task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
-
EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR,
callback_receiver.status());
}
@@ -1083,8 +1025,10 @@ TEST_F(AuthenticatorImplTest, InvalidResponse) {
TestMakeCredentialCallback callback_receiver;
authenticator->MakeCredential(std::move(options),
callback_receiver.callback());
+ // Trigger timer.
+ base::RunLoop().RunUntilIdle();
+ task_runner->FastForwardBy(base::TimeDelta::FromMinutes(1));
callback_receiver.WaitForCallback();
-
EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR,
callback_receiver.status());
}
@@ -1100,44 +1044,74 @@ enum class AttestationConsent {
DENIED,
};
-// Implements ContentBrowserClient and allows webauthn-related calls to be
-// mocked.
-class AuthenticatorTestContentBrowserClient : public ContentBrowserClient {
+class TestAuthenticatorRequestDelegate
+ : public AuthenticatorRequestClientDelegate {
public:
- bool ShouldPermitIndividualAttestationForWebauthnRPID(
- content::BrowserContext* browser_context,
- const std::string& rp_id) override {
+ TestAuthenticatorRequestDelegate(RenderFrameHost* render_frame_host,
+ base::OnceClosure did_start_request_callback,
+ IndividualAttestation individual_attestation,
+ AttestationConsent attestation_consent,
+ bool is_focused)
+ : did_start_request_callback_(std::move(did_start_request_callback)),
+ individual_attestation_(individual_attestation),
+ attestation_consent_(attestation_consent),
+ is_focused_(is_focused) {}
+ ~TestAuthenticatorRequestDelegate() override {}
+
+ void DidStartRequest() override {
+ ASSERT_TRUE(did_start_request_callback_) << "DidStartRequest called twice.";
+ std::move(did_start_request_callback_).Run();
+ }
+
+ bool ShouldPermitIndividualAttestation(
+ const std::string& relying_party_id) override {
return individual_attestation_ == IndividualAttestation::REQUESTED;
}
- void ShouldReturnAttestationForWebauthnRPID(
- content::RenderFrameHost* rfh,
- const std::string& rp_id,
- const url::Origin& origin,
+ void ShouldReturnAttestation(
+ const std::string& relying_party_id,
base::OnceCallback<void(bool)> callback) override {
std::move(callback).Run(attestation_consent_ ==
AttestationConsent::GRANTED);
}
- bool IsFocused(content::WebContents* web_contents) override {
- return focused_;
- }
+ bool IsFocused() override { return is_focused_; }
- void set_individual_attestation(IndividualAttestation value) {
- individual_attestation_ = value;
- }
+ base::OnceClosure did_start_request_callback_;
+ const IndividualAttestation individual_attestation_;
+ const AttestationConsent attestation_consent_;
+ const bool is_focused_;
- void set_attestation_consent(AttestationConsent value) {
- attestation_consent_ = value;
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestAuthenticatorRequestDelegate);
+};
+
+class TestAuthenticatorContentBrowserClient : public ContentBrowserClient {
+ public:
+ std::unique_ptr<AuthenticatorRequestClientDelegate>
+ GetWebAuthenticationRequestDelegate(
+ RenderFrameHost* render_frame_host) override {
+ if (return_null_delegate)
+ return nullptr;
+ return std::make_unique<TestAuthenticatorRequestDelegate>(
+ render_frame_host,
+ request_started_callback ? std::move(request_started_callback)
+ : base::DoNothing(),
+ individual_attestation, attestation_consent, is_focused);
}
- void set_focused(bool is_focused) { focused_ = is_focused; }
+ // If set, this closure will be called when the subsequently constructed
+ // delegate is informed that the request has started.
+ base::OnceClosure request_started_callback;
- private:
- IndividualAttestation individual_attestation_ =
+ IndividualAttestation individual_attestation =
IndividualAttestation::NOT_REQUESTED;
- AttestationConsent attestation_consent_ = AttestationConsent::DENIED;
- bool focused_ = true;
+ AttestationConsent attestation_consent = AttestationConsent::DENIED;
+ bool is_focused = true;
+
+ // This emulates scenarios where a nullptr RequestClientDelegate is returned
+ // because a request is already in progress.
+ bool return_null_delegate = false;
};
// A test class that installs and removes an
@@ -1183,8 +1157,8 @@ class AuthenticatorContentBrowserClientTest : public AuthenticatorImplTest {
AttestationConveyancePreferenceToString(test.attestation_requested));
SCOPED_TRACE(i);
- test_client_.set_individual_attestation(test.individual_attestation);
- test_client_.set_attestation_consent(test.attestation_consent);
+ test_client_.individual_attestation = test.individual_attestation;
+ test_client_.attestation_consent = test.attestation_consent;
PublicKeyCredentialCreationOptionsPtr options =
GetTestPublicKeyCredentialCreationOptions();
@@ -1217,7 +1191,7 @@ class AuthenticatorContentBrowserClientTest : public AuthenticatorImplTest {
}
protected:
- AuthenticatorTestContentBrowserClient test_client_;
+ TestAuthenticatorContentBrowserClient test_client_;
device::test::ScopedVirtualFidoDevice virtual_device_;
private:
@@ -1230,6 +1204,8 @@ class AuthenticatorContentBrowserClientTest : public AuthenticatorImplTest {
return "indirect";
case AttestationConveyancePreference::DIRECT:
return "direct";
+ case AttestationConveyancePreference::ENTERPRISE:
+ return "enterprise";
default:
NOTREACHED();
return "";
@@ -1311,7 +1287,7 @@ TEST_F(AuthenticatorContentBrowserClientTest, AttestationBehaviour) {
{
AttestationConveyancePreference::INDIRECT,
IndividualAttestation::REQUESTED, AttestationConsent::GRANTED,
- AuthenticatorStatus::SUCCESS, "fido-u2f", kIndividualCommonName,
+ AuthenticatorStatus::SUCCESS, "fido-u2f", kStandardCommonName,
},
{
AttestationConveyancePreference::DIRECT,
@@ -1331,6 +1307,26 @@ TEST_F(AuthenticatorContentBrowserClientTest, AttestationBehaviour) {
{
AttestationConveyancePreference::DIRECT,
IndividualAttestation::REQUESTED, AttestationConsent::GRANTED,
+ AuthenticatorStatus::SUCCESS, "fido-u2f", kStandardCommonName,
+ },
+ {
+ AttestationConveyancePreference::ENTERPRISE,
+ IndividualAttestation::NOT_REQUESTED, AttestationConsent::DENIED,
+ AuthenticatorStatus::NOT_ALLOWED_ERROR, "", "",
+ },
+ {
+ AttestationConveyancePreference::ENTERPRISE,
+ IndividualAttestation::REQUESTED, AttestationConsent::DENIED,
+ AuthenticatorStatus::NOT_ALLOWED_ERROR, "", "",
+ },
+ {
+ AttestationConveyancePreference::ENTERPRISE,
+ IndividualAttestation::NOT_REQUESTED, AttestationConsent::GRANTED,
+ AuthenticatorStatus::SUCCESS, "fido-u2f", kStandardCommonName,
+ },
+ {
+ AttestationConveyancePreference::ENTERPRISE,
+ IndividualAttestation::REQUESTED, AttestationConsent::GRANTED,
AuthenticatorStatus::SUCCESS, "fido-u2f", kIndividualCommonName,
},
};
@@ -1352,7 +1348,7 @@ TEST_F(AuthenticatorContentBrowserClientTest,
const std::vector<TestCase> kTests = {
{
- AttestationConveyancePreference::DIRECT,
+ AttestationConveyancePreference::ENTERPRISE,
IndividualAttestation::NOT_REQUESTED, AttestationConsent::DENIED,
AuthenticatorStatus::NOT_ALLOWED_ERROR, "", "",
},
@@ -1366,7 +1362,17 @@ TEST_F(AuthenticatorContentBrowserClientTest,
"none", "",
},
{
- AttestationConveyancePreference::DIRECT,
+ AttestationConveyancePreference::ENTERPRISE,
+ IndividualAttestation::NOT_REQUESTED, AttestationConsent::GRANTED,
+ AuthenticatorStatus::SUCCESS,
+ // If individual attestation was not requested then the attestation
+ // certificate will be removed, even if consent is given, because
+ // the consent isn't to be tracked.
+ "none", "",
+ },
+
+ {
+ AttestationConveyancePreference::ENTERPRISE,
IndividualAttestation::REQUESTED, AttestationConsent::GRANTED,
AuthenticatorStatus::SUCCESS, "fido-u2f", kCommonName,
},
@@ -1380,11 +1386,41 @@ TEST_F(AuthenticatorContentBrowserClientTest,
RunTestCases(kTests);
}
+TEST_F(AuthenticatorContentBrowserClientTest,
+ MakeCredentialRequestStartedCallback) {
+ TestServiceManagerContext smc;
+ NavigateAndCommit(GURL(kTestOrigin1));
+ AuthenticatorPtr authenticator = ConnectToAuthenticator();
+
+ PublicKeyCredentialCreationOptionsPtr options =
+ GetTestPublicKeyCredentialCreationOptions();
+
+ TestRequestStartedCallback request_started;
+ test_client_.request_started_callback = request_started.callback();
+ authenticator->MakeCredential(std::move(options), base::DoNothing());
+ request_started.WaitForCallback();
+}
+
+TEST_F(AuthenticatorContentBrowserClientTest,
+ GetAssertionRequestStartedCallback) {
+ TestServiceManagerContext smc;
+ NavigateAndCommit(GURL(kTestOrigin1));
+ AuthenticatorPtr authenticator = ConnectToAuthenticator();
+
+ PublicKeyCredentialRequestOptionsPtr options =
+ GetTestPublicKeyCredentialRequestOptions();
+
+ TestRequestStartedCallback request_started;
+ test_client_.request_started_callback = request_started.callback();
+ authenticator->GetAssertion(std::move(options), base::DoNothing());
+ request_started.WaitForCallback();
+}
+
TEST_F(AuthenticatorContentBrowserClientTest, Unfocused) {
// When the |ContentBrowserClient| considers the tab to be unfocused,
// registration requests should fail with a |NOT_FOCUSED| error, but getting
// assertions should still work.
- test_client_.set_focused(false);
+ test_client_.is_focused = false;
NavigateAndCommit(GURL(kTestOrigin1));
AuthenticatorPtr authenticator = ConnectToAuthenticator();
@@ -1395,9 +1431,14 @@ TEST_F(AuthenticatorContentBrowserClientTest, Unfocused) {
options->public_key_parameters = GetTestPublicKeyCredentialParameters(123);
TestMakeCredentialCallback cb;
+ TestRequestStartedCallback request_started;
+ test_client_.request_started_callback = request_started.callback();
+
authenticator->MakeCredential(std::move(options), cb.callback());
cb.WaitForCallback();
+
EXPECT_EQ(AuthenticatorStatus::NOT_FOCUSED, cb.status());
+ EXPECT_FALSE(request_started.was_called());
}
{
@@ -1414,10 +1455,42 @@ TEST_F(AuthenticatorContentBrowserClientTest, Unfocused) {
options->allow_credentials.emplace_back(std::move(credential));
TestGetAssertionCallback cb;
+ TestRequestStartedCallback request_started;
+ test_client_.request_started_callback = request_started.callback();
+
authenticator->GetAssertion(std::move(options), cb.callback());
cb.WaitForCallback();
EXPECT_EQ(AuthenticatorStatus::SUCCESS, cb.status());
+ EXPECT_TRUE(request_started.was_called());
+ }
+}
+
+TEST_F(AuthenticatorContentBrowserClientTest,
+ NullDelegate_RejectsWithPendingRequest) {
+ test_client_.return_null_delegate = true;
+
+ NavigateAndCommit(GURL(kTestOrigin1));
+ AuthenticatorPtr authenticator = ConnectToAuthenticator();
+
+ {
+ PublicKeyCredentialCreationOptionsPtr options =
+ GetTestPublicKeyCredentialCreationOptions();
+
+ TestMakeCredentialCallback cb;
+ authenticator->MakeCredential(std::move(options), cb.callback());
+ cb.WaitForCallback();
+ EXPECT_EQ(AuthenticatorStatus::PENDING_REQUEST, cb.status());
+ }
+
+ {
+ PublicKeyCredentialRequestOptionsPtr options =
+ GetTestPublicKeyCredentialRequestOptions();
+
+ TestGetAssertionCallback cb;
+ authenticator->GetAssertion(std::move(options), cb.callback());
+ cb.WaitForCallback();
+ EXPECT_EQ(AuthenticatorStatus::PENDING_REQUEST, cb.status());
}
}
diff --git a/chromium/content/browser/webauth/authenticator_type_converters.cc b/chromium/content/browser/webauth/authenticator_type_converters.cc
index 47f14b163a7..28985e8756f 100644
--- a/chromium/content/browser/webauth/authenticator_type_converters.cc
+++ b/chromium/content/browser/webauth/authenticator_type_converters.cc
@@ -11,16 +11,16 @@
namespace mojo {
-using ::webauth::mojom::PublicKeyCredentialUserEntityPtr;
-using ::webauth::mojom::PublicKeyCredentialRpEntityPtr;
-using ::webauth::mojom::AuthenticatorTransport;
-using ::webauth::mojom::PublicKeyCredentialType;
-using ::webauth::mojom::PublicKeyCredentialParametersPtr;
-using ::webauth::mojom::PublicKeyCredentialDescriptorPtr;
-using ::webauth::mojom::AuthenticatorSelectionCriteriaPtr;
-using ::webauth::mojom::AuthenticatorAttachment;
-using ::webauth::mojom::UserVerificationRequirement;
-using ::webauth::mojom::CableAuthenticationPtr;
+using ::blink::mojom::PublicKeyCredentialUserEntityPtr;
+using ::blink::mojom::PublicKeyCredentialRpEntityPtr;
+using ::blink::mojom::AuthenticatorTransport;
+using ::blink::mojom::PublicKeyCredentialType;
+using ::blink::mojom::PublicKeyCredentialParametersPtr;
+using ::blink::mojom::PublicKeyCredentialDescriptorPtr;
+using ::blink::mojom::AuthenticatorSelectionCriteriaPtr;
+using ::blink::mojom::AuthenticatorAttachment;
+using ::blink::mojom::UserVerificationRequirement;
+using ::blink::mojom::CableAuthenticationPtr;
// static
::device::FidoTransportProtocol
@@ -88,7 +88,7 @@ TypeConverter<std::vector<::device::PublicKeyCredentialDescriptor>,
::device::UserVerificationRequirement
TypeConverter<::device::UserVerificationRequirement,
UserVerificationRequirement>::
- Convert(const ::webauth::mojom::UserVerificationRequirement& input) {
+ Convert(const UserVerificationRequirement& input) {
switch (input) {
case UserVerificationRequirement::PREFERRED:
return ::device::UserVerificationRequirement::kPreferred;
@@ -180,13 +180,13 @@ TypeConverter<std::vector<::device::FidoCableDiscovery::CableDiscoveryData>,
std::copy(data->authenticator_eid.begin(), data->authenticator_eid.end(),
authenticator_eid.begin());
- ::device::FidoCableDiscovery::SessionKeyArray session_key;
- DCHECK_EQ(session_key.size(), data->session_pre_key.size());
+ ::device::FidoCableDiscovery::SessionPreKeyArray session_pre_key;
+ DCHECK_EQ(session_pre_key.size(), data->session_pre_key.size());
std::copy(data->session_pre_key.begin(), data->session_pre_key.end(),
- session_key.begin());
+ session_pre_key.begin());
discovery_data.push_back(::device::FidoCableDiscovery::CableDiscoveryData{
- data->version, client_eid, authenticator_eid, session_key});
+ data->version, client_eid, authenticator_eid, session_pre_key});
}
return discovery_data;
diff --git a/chromium/content/browser/webauth/authenticator_type_converters.h b/chromium/content/browser/webauth/authenticator_type_converters.h
index 97431318615..cc4a53db728 100644
--- a/chromium/content/browser/webauth/authenticator_type_converters.h
+++ b/chromium/content/browser/webauth/authenticator_type_converters.h
@@ -24,78 +24,78 @@ namespace mojo {
template <>
struct TypeConverter<::device::FidoTransportProtocol,
- ::webauth::mojom::AuthenticatorTransport> {
+ ::blink::mojom::AuthenticatorTransport> {
static ::device::FidoTransportProtocol Convert(
- const ::webauth::mojom::AuthenticatorTransport& input);
+ const ::blink::mojom::AuthenticatorTransport& input);
};
template <>
struct TypeConverter<::device::CredentialType,
- ::webauth::mojom::PublicKeyCredentialType> {
+ ::blink::mojom::PublicKeyCredentialType> {
static ::device::CredentialType Convert(
- const ::webauth::mojom::PublicKeyCredentialType& input);
+ const ::blink::mojom::PublicKeyCredentialType& input);
};
template <>
struct TypeConverter<
std::vector<::device::PublicKeyCredentialParams::CredentialInfo>,
- std::vector<::webauth::mojom::PublicKeyCredentialParametersPtr>> {
+ std::vector<::blink::mojom::PublicKeyCredentialParametersPtr>> {
static std::vector<::device::PublicKeyCredentialParams::CredentialInfo>
- Convert(const std::vector<::webauth::mojom::PublicKeyCredentialParametersPtr>&
+ Convert(const std::vector<::blink::mojom::PublicKeyCredentialParametersPtr>&
input);
};
template <>
struct TypeConverter<
std::vector<::device::PublicKeyCredentialDescriptor>,
- std::vector<::webauth::mojom::PublicKeyCredentialDescriptorPtr>> {
+ std::vector<::blink::mojom::PublicKeyCredentialDescriptorPtr>> {
static std::vector<::device::PublicKeyCredentialDescriptor> Convert(
- const std::vector<::webauth::mojom::PublicKeyCredentialDescriptorPtr>&
+ const std::vector<::blink::mojom::PublicKeyCredentialDescriptorPtr>&
input);
};
template <>
struct TypeConverter<
::device::AuthenticatorSelectionCriteria::AuthenticatorAttachment,
- ::webauth::mojom::AuthenticatorAttachment> {
+ ::blink::mojom::AuthenticatorAttachment> {
static ::device::AuthenticatorSelectionCriteria::AuthenticatorAttachment
- Convert(const ::webauth::mojom::AuthenticatorAttachment& input);
+ Convert(const ::blink::mojom::AuthenticatorAttachment& input);
};
template <>
struct TypeConverter<::device::UserVerificationRequirement,
- ::webauth::mojom::UserVerificationRequirement> {
+ ::blink::mojom::UserVerificationRequirement> {
static ::device::UserVerificationRequirement Convert(
- const ::webauth::mojom::UserVerificationRequirement& input);
+ const ::blink::mojom::UserVerificationRequirement& input);
};
template <>
struct TypeConverter<::device::AuthenticatorSelectionCriteria,
- ::webauth::mojom::AuthenticatorSelectionCriteriaPtr> {
+ ::blink::mojom::AuthenticatorSelectionCriteriaPtr> {
static ::device::AuthenticatorSelectionCriteria Convert(
- const ::webauth::mojom::AuthenticatorSelectionCriteriaPtr& input);
+ const ::blink::mojom::AuthenticatorSelectionCriteriaPtr& input);
};
template <>
struct TypeConverter<::device::PublicKeyCredentialRpEntity,
- ::webauth::mojom::PublicKeyCredentialRpEntityPtr> {
+ ::blink::mojom::PublicKeyCredentialRpEntityPtr> {
static ::device::PublicKeyCredentialRpEntity Convert(
- const ::webauth::mojom::PublicKeyCredentialRpEntityPtr& input);
+ const ::blink::mojom::PublicKeyCredentialRpEntityPtr& input);
};
template <>
struct TypeConverter<::device::PublicKeyCredentialUserEntity,
- ::webauth::mojom::PublicKeyCredentialUserEntityPtr> {
+ ::blink::mojom::PublicKeyCredentialUserEntityPtr> {
static ::device::PublicKeyCredentialUserEntity Convert(
- const ::webauth::mojom::PublicKeyCredentialUserEntityPtr& input);
+ const ::blink::mojom::PublicKeyCredentialUserEntityPtr& input);
};
template <>
struct TypeConverter<
std::vector<::device::FidoCableDiscovery::CableDiscoveryData>,
- std::vector<::webauth::mojom::CableAuthenticationPtr>> {
+ std::vector<::blink::mojom::CableAuthenticationPtr>> {
static std::vector<::device::FidoCableDiscovery::CableDiscoveryData> Convert(
- const std::vector<::webauth::mojom::CableAuthenticationPtr>& input);
+ const std::vector<::blink::mojom::CableAuthenticationPtr>& input);
};
} // namespace mojo
diff --git a/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.cc b/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.cc
index 630260d0cf8..3f3d4a2df33 100644
--- a/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.cc
+++ b/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.cc
@@ -15,9 +15,9 @@ namespace content {
namespace {
-webauth::test::mojom::VirtualAuthenticatorPtr GetMojoPtrToVirtualAuthenticator(
+blink::test::mojom::VirtualAuthenticatorPtr GetMojoPtrToVirtualAuthenticator(
VirtualAuthenticator* authenticator) {
- webauth::test::mojom::VirtualAuthenticatorPtr mojo_authenticator_ptr;
+ blink::test::mojom::VirtualAuthenticatorPtr mojo_authenticator_ptr;
authenticator->AddBinding(mojo::MakeRequest(&mojo_authenticator_ptr));
return mojo_authenticator_ptr;
}
@@ -37,12 +37,12 @@ ScopedVirtualAuthenticatorEnvironment::
~ScopedVirtualAuthenticatorEnvironment() = default;
void ScopedVirtualAuthenticatorEnvironment::AddBinding(
- webauth::test::mojom::VirtualAuthenticatorManagerRequest request) {
+ blink::test::mojom::VirtualAuthenticatorManagerRequest request) {
bindings_.AddBinding(this, std::move(request));
}
void ScopedVirtualAuthenticatorEnvironment::CreateAuthenticator(
- webauth::test::mojom::VirtualAuthenticatorOptionsPtr options,
+ blink::test::mojom::VirtualAuthenticatorOptionsPtr options,
CreateAuthenticatorCallback callback) {
auto authenticator = std::make_unique<VirtualAuthenticator>(
mojo::ConvertTo<::device::FidoTransportProtocol>(options->transport));
@@ -61,7 +61,7 @@ void ScopedVirtualAuthenticatorEnvironment::CreateAuthenticator(
void ScopedVirtualAuthenticatorEnvironment::GetAuthenticators(
GetAuthenticatorsCallback callback) {
- std::vector<webauth::test::mojom::VirtualAuthenticatorPtrInfo>
+ std::vector<blink::test::mojom::VirtualAuthenticatorPtrInfo>
mojo_authenticators;
for (auto& authenticator : authenticators_) {
mojo_authenticators.push_back(
diff --git a/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.h b/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.h
index 142f6f2af32..378de2ff2db 100644
--- a/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.h
+++ b/chromium/content/browser/webauth/scoped_virtual_authenticator_environment.h
@@ -31,21 +31,21 @@ class VirtualFidoDiscovery;
// lifetime of the browser process and shared by all frames in all WebContents
// and across all BrowserContexts.
class CONTENT_EXPORT ScopedVirtualAuthenticatorEnvironment
- : public webauth::test::mojom::VirtualAuthenticatorManager,
+ : public blink::test::mojom::VirtualAuthenticatorManager,
protected device::internal::ScopedFidoDiscoveryFactory {
public:
static ScopedVirtualAuthenticatorEnvironment* GetInstance();
void AddBinding(
- webauth::test::mojom::VirtualAuthenticatorManagerRequest request);
+ blink::test::mojom::VirtualAuthenticatorManagerRequest request);
protected:
ScopedVirtualAuthenticatorEnvironment();
~ScopedVirtualAuthenticatorEnvironment() override;
- // webauth::test::mojom::VirtualAuthenticatorManager:
+ // blink::test::mojom::VirtualAuthenticatorManager:
void CreateAuthenticator(
- webauth::test::mojom::VirtualAuthenticatorOptionsPtr options,
+ blink::test::mojom::VirtualAuthenticatorOptionsPtr options,
CreateAuthenticatorCallback callback) override;
void GetAuthenticators(GetAuthenticatorsCallback callback) override;
void RemoveAuthenticator(const std::string& id,
@@ -64,7 +64,7 @@ class CONTENT_EXPORT ScopedVirtualAuthenticatorEnvironment
// Called by VirtualFidoDiscoveries when they are destructed.
void OnDiscoveryDestroyed(VirtualFidoDiscovery* discovery);
- mojo::BindingSet<webauth::test::mojom::VirtualAuthenticatorManager> bindings_;
+ mojo::BindingSet<blink::test::mojom::VirtualAuthenticatorManager> bindings_;
// The key is the unique_id of the corresponding value (the authenticator).
std::map<std::string, std::unique_ptr<VirtualAuthenticator>> authenticators_;
diff --git a/chromium/content/browser/webauth/virtual_authenticator.cc b/chromium/content/browser/webauth/virtual_authenticator.cc
index 71cdfac4400..b93637c3189 100644
--- a/chromium/content/browser/webauth/virtual_authenticator.cc
+++ b/chromium/content/browser/webauth/virtual_authenticator.cc
@@ -22,7 +22,7 @@ VirtualAuthenticator::VirtualAuthenticator(
VirtualAuthenticator::~VirtualAuthenticator() = default;
void VirtualAuthenticator::AddBinding(
- webauth::test::mojom::VirtualAuthenticatorRequest request) {
+ blink::test::mojom::VirtualAuthenticatorRequest request) {
binding_set_.AddBinding(this, std::move(request));
}
@@ -35,13 +35,14 @@ void VirtualAuthenticator::GetUniqueId(GetUniqueIdCallback callback) {
}
void VirtualAuthenticator::GetRegistrations(GetRegistrationsCallback callback) {
- std::vector<webauth::test::mojom::RegisteredKeyPtr> mojo_registered_keys;
+ std::vector<blink::test::mojom::RegisteredKeyPtr> mojo_registered_keys;
for (const auto& registration : state_->registrations) {
- auto mojo_registered_key = webauth::test::mojom::RegisteredKey::New();
+ auto mojo_registered_key = blink::test::mojom::RegisteredKey::New();
mojo_registered_key->key_handle = registration.first;
mojo_registered_key->counter = registration.second.counter;
- mojo_registered_key->application_parameter =
- registration.second.application_parameter;
+ mojo_registered_key->application_parameter.assign(
+ registration.second.application_parameter.begin(),
+ registration.second.application_parameter.end());
registration.second.private_key->ExportPrivateKey(
&mojo_registered_key->private_key);
mojo_registered_keys.push_back(std::move(mojo_registered_key));
@@ -50,16 +51,20 @@ void VirtualAuthenticator::GetRegistrations(GetRegistrationsCallback callback) {
}
void VirtualAuthenticator::AddRegistration(
- webauth::test::mojom::RegisteredKeyPtr registration,
+ blink::test::mojom::RegisteredKeyPtr registration,
AddRegistrationCallback callback) {
+ if (registration->application_parameter.size() != device::kRpIdHashLength) {
+ std::move(callback).Run(false);
+ return;
+ }
+
bool success = false;
std::tie(std::ignore, success) = state_->registrations.emplace(
std::move(registration->key_handle),
::device::VirtualFidoDevice::RegistrationData(
crypto::ECPrivateKey::CreateFromPrivateKeyInfo(
registration->private_key),
- std::move(registration->application_parameter),
- registration->counter));
+ registration->application_parameter, registration->counter));
std::move(callback).Run(success);
}
diff --git a/chromium/content/browser/webauth/virtual_authenticator.h b/chromium/content/browser/webauth/virtual_authenticator.h
index c0ee5797447..d048250f30b 100644
--- a/chromium/content/browser/webauth/virtual_authenticator.h
+++ b/chromium/content/browser/webauth/virtual_authenticator.h
@@ -24,12 +24,12 @@ namespace content {
// state of the authenticator, whereas performing all cryptographic operations
// is delegated to the VirtualFidoDevice class.
class CONTENT_EXPORT VirtualAuthenticator
- : public webauth::test::mojom::VirtualAuthenticator {
+ : public blink::test::mojom::VirtualAuthenticator {
public:
explicit VirtualAuthenticator(::device::FidoTransportProtocol transport);
~VirtualAuthenticator() override;
- void AddBinding(webauth::test::mojom::VirtualAuthenticatorRequest request);
+ void AddBinding(blink::test::mojom::VirtualAuthenticatorRequest request);
::device::FidoTransportProtocol transport() const { return transport_; }
const std::string& unique_id() const { return unique_id_; }
@@ -43,11 +43,11 @@ class CONTENT_EXPORT VirtualAuthenticator
std::unique_ptr<::device::FidoDevice> ConstructDevice();
protected:
- // webauth::test::mojom::VirtualAuthenticator:
+ // blink::test::mojom::VirtualAuthenticator:
void GetUniqueId(GetUniqueIdCallback callback) override;
void GetRegistrations(GetRegistrationsCallback callback) override;
- void AddRegistration(webauth::test::mojom::RegisteredKeyPtr registration,
+ void AddRegistration(blink::test::mojom::RegisteredKeyPtr registration,
AddRegistrationCallback callback) override;
void ClearRegistrations(ClearRegistrationsCallback callback) override;
@@ -58,7 +58,7 @@ class CONTENT_EXPORT VirtualAuthenticator
const ::device::FidoTransportProtocol transport_;
const std::string unique_id_;
scoped_refptr<::device::VirtualFidoDevice::State> state_;
- mojo::BindingSet<webauth::test::mojom::VirtualAuthenticator> binding_set_;
+ mojo::BindingSet<blink::test::mojom::VirtualAuthenticator> binding_set_;
DISALLOW_COPY_AND_ASSIGN(VirtualAuthenticator);
};
diff --git a/chromium/content/browser/webauth/webauth_browsertest.cc b/chromium/content/browser/webauth/webauth_browsertest.cc
index 59b558ffc01..3943e65820e 100644
--- a/chromium/content/browser/webauth/webauth_browsertest.cc
+++ b/chromium/content/browser/webauth/webauth_browsertest.cc
@@ -7,13 +7,16 @@
#include <vector>
#include "base/command_line.h"
+#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
+#include "base/values.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/webauth/authenticator_impl.h"
+#include "content/public/browser/authenticator_request_client_delegate.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/web_contents.h"
@@ -24,12 +27,15 @@
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/did_commit_provisional_load_interceptor.h"
+#include "device/base/features.h"
#include "device/fido/fake_fido_discovery.h"
#include "device/fido/fake_hid_impl_for_testing.h"
#include "device/fido/fido_test_data.h"
#include "device/fido/mock_fido_device.h"
+#include "device/fido/scoped_virtual_fido_device.h"
#include "device/fido/test_callback_receiver.h"
#include "net/dns/mock_host_resolver.h"
#include "services/device/public/mojom/constants.mojom.h"
@@ -42,11 +48,11 @@ namespace content {
namespace {
-using webauth::mojom::Authenticator;
-using webauth::mojom::AuthenticatorPtr;
-using webauth::mojom::AuthenticatorStatus;
-using webauth::mojom::GetAssertionAuthenticatorResponsePtr;
-using webauth::mojom::MakeCredentialAuthenticatorResponsePtr;
+using blink::mojom::Authenticator;
+using blink::mojom::AuthenticatorPtr;
+using blink::mojom::AuthenticatorStatus;
+using blink::mojom::GetAssertionAuthenticatorResponsePtr;
+using blink::mojom::MakeCredentialAuthenticatorResponsePtr;
using TestCreateCallbackReceiver =
::device::test::StatusAndValueCallbackReceiver<
@@ -57,33 +63,17 @@ using TestGetCallbackReceiver = ::device::test::StatusAndValueCallbackReceiver<
AuthenticatorStatus,
GetAssertionAuthenticatorResponsePtr>;
+constexpr char kTimeoutErrorMessage[] =
+ "webauth: NotAllowedError: The operation either timed out or was not "
+ "allowed. See: https://w3c.github.io/webauthn/#sec-assertion-privacy.";
+
+constexpr char kInvalidStateErrorMessage[] =
+ "webauth: InvalidStateError: The user attempted to use an authenticator "
+ "that recognized none of the provided credentials.";
+
constexpr char kRelyingPartySecurityErrorMessage[] =
- "SecurityError: The relying party ID 'localhost' is not a registrable "
- "domain suffix of, nor equal to 'https://www.acme.com";
-
-constexpr char kAlgorithmUnsupportedErrorMessage[] =
- "NotSupportedError: None of the algorithms specified in "
- "`pubKeyCredParams` are compatible with "
- "CTAP1/U2F authenticators, and CTAP2 "
- "authenticators are not yet supported.";
-
-constexpr char kAuthenticatorCriteriaErrorMessage[] =
- "NotSupportedError: The specified `authenticatorSelection` "
- "criteria cannot be fulfilled by CTAP1/U2F "
- "authenticators, and CTAP2 authenticators "
- "are not yet supported.";
-
-constexpr char kUserVerificationErrorMessage[] =
- "NotSupportedError: The specified `userVerification` "
- "requirement cannot be fulfilled by "
- "CTAP1/U2F authenticators, and CTAP2 "
- "authenticators are not yet supported.";
-
-constexpr char kEmptyAllowCredentialsErrorMessage[] =
- "NotSupportedError: The `allowCredentials` list cannot be left "
- "empty for CTAP1/U2F authenticators, and "
- "support for CTAP2 authenticators is not yet "
- "implemented.";
+ "webauth: SecurityError: The relying party ID 'localhost' is not a "
+ "registrable domain suffix of, nor equal to 'https://www.acme.com";
// Templates to be used with base::ReplaceStringPlaceholders. Can be
// modified to include up to 9 replacements. The default values for
@@ -99,13 +89,17 @@ constexpr char kCreatePublicKeyTemplate[] =
" displayName: 'Avery A. Jones', "
" icon: 'https://pics.acme.com/00/p/aBjjjpqPb.png'},"
" pubKeyCredParams: [{ type: 'public-key', alg: '$4'}],"
- " timeout: 60000,"
+ " timeout: 1000,"
" excludeCredentials: [],"
- " authenticatorSelection : {"
+ " authenticatorSelection: {"
" requireResidentKey: $1,"
" userVerification: '$2',"
- " authenticatorAttachment: '$5' }}"
- "}).catch(c => window.domAutomationController.send(c.toString()));";
+ " authenticatorAttachment: '$5',"
+ " },"
+ " attestation: '$6',"
+ "}}).then(c => window.domAutomationController.send('webauth: OK'),"
+ " e => window.domAutomationController.send("
+ " 'webauth: ' + e.toString()));";
constexpr char kPlatform[] = "platform";
constexpr char kCrossPlatform[] = "cross-platform";
@@ -119,6 +113,7 @@ struct CreateParameters {
const char* user_verification = kPreferredVerification;
const char* authenticator_attachment = kCrossPlatform;
const char* algorithm_identifier = "-7";
+ const char* attestation = "none";
};
std::string BuildCreateCallWithParameters(const CreateParameters& parameters) {
@@ -128,6 +123,7 @@ std::string BuildCreateCallWithParameters(const CreateParameters& parameters) {
substititions.push_back(parameters.rp_id);
substititions.push_back(parameters.algorithm_identifier);
substititions.push_back(parameters.authenticator_attachment);
+ substititions.push_back(parameters.attestation);
return base::ReplaceStringPlaceholders(kCreatePublicKeyTemplate,
substititions, nullptr);
}
@@ -135,11 +131,12 @@ std::string BuildCreateCallWithParameters(const CreateParameters& parameters) {
constexpr char kGetPublicKeyTemplate[] =
"navigator.credentials.get({ publicKey: {"
" challenge: new TextEncoder().encode('climb a mountain'),"
- " rp: 'acme.com',"
- " timeout: 60000,"
+ " rpId: 'acme.com',"
+ " timeout: 1000,"
" userVerification: '$1',"
" $2}"
- "}).catch(c => window.domAutomationController.send(c.toString()));";
+ "}).catch(c => window.domAutomationController.send("
+ " 'webauth: ' + c.toString()));";
// Default values for kGetPublicKeyTemplate.
struct GetParameters {
@@ -170,13 +167,14 @@ class ClosureExecutorBeforeNavigationCommit
~ClosureExecutorBeforeNavigationCommit() override = default;
protected:
- void WillDispatchDidCommitProvisionalLoad(
+ bool WillDispatchDidCommitProvisionalLoad(
RenderFrameHost* render_frame_host,
::FrameHostMsg_DidCommitProvisionalLoad_Params* params,
service_manager::mojom::InterfaceProviderRequest*
interface_provider_request) override {
if (closure_)
std::move(closure_).Run();
+ return true;
}
private:
@@ -187,14 +185,16 @@ class ClosureExecutorBeforeNavigationCommit
// Cancels all navigations in a WebContents while in scope.
class ScopedNavigationCancellingThrottleInstaller : public WebContentsObserver {
public:
- ScopedNavigationCancellingThrottleInstaller(WebContents* web_contents)
+ explicit ScopedNavigationCancellingThrottleInstaller(
+ WebContents* web_contents)
: WebContentsObserver(web_contents) {}
~ScopedNavigationCancellingThrottleInstaller() override = default;
protected:
class CancellingThrottle : public NavigationThrottle {
public:
- CancellingThrottle(NavigationHandle* handle) : NavigationThrottle(handle) {}
+ explicit CancellingThrottle(NavigationHandle* handle)
+ : NavigationThrottle(handle) {}
~CancellingThrottle() override = default;
protected:
@@ -219,6 +219,87 @@ class ScopedNavigationCancellingThrottleInstaller : public WebContentsObserver {
DISALLOW_COPY_AND_ASSIGN(ScopedNavigationCancellingThrottleInstaller);
};
+struct WebAuthBrowserTestState {
+ // Called when the browser is asked to display an attestation prompt. There is
+ // no default so if no callback is installed then the test will crash.
+ base::OnceCallback<void(base::OnceCallback<void(bool)>)>
+ attestation_prompt_callback_;
+
+ // Set when |IsFocused| is called.
+ bool focus_checked = false;
+
+ // If true, request a new render process for each site (i.e. site isolation).
+ // Otherwise have the default behaviour for |ContentBrowserClient|.
+ bool force_new_render_processes = false;
+
+ // This is incremented when an |AuthenticatorRequestClientDelegate| is
+ // created.
+ int delegate_create_count = 0;
+};
+
+class WebAuthBrowserTestClientDelegate
+ : public AuthenticatorRequestClientDelegate {
+ public:
+ explicit WebAuthBrowserTestClientDelegate(WebAuthBrowserTestState* test_state)
+ : test_state_(test_state) {}
+
+ void ShouldReturnAttestation(
+ const std::string& relying_party_id,
+ base::OnceCallback<void(bool)> callback) override {
+ std::move(test_state_->attestation_prompt_callback_)
+ .Run(std::move(callback));
+ }
+
+ bool IsFocused() override {
+ test_state_->focus_checked = true;
+ return AuthenticatorRequestClientDelegate::IsFocused();
+ }
+
+ private:
+ WebAuthBrowserTestState* const test_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebAuthBrowserTestClientDelegate);
+};
+
+// Implements ContentBrowserClient and allows webauthn-related calls to be
+// mocked.
+class WebAuthBrowserTestContentBrowserClient : public ContentBrowserClient {
+ public:
+ explicit WebAuthBrowserTestContentBrowserClient(
+ WebAuthBrowserTestState* test_state)
+ : test_state_(test_state) {}
+
+ std::unique_ptr<AuthenticatorRequestClientDelegate>
+ GetWebAuthenticationRequestDelegate(
+ RenderFrameHost* render_frame_host) override {
+ test_state_->delegate_create_count++;
+ return std::make_unique<WebAuthBrowserTestClientDelegate>(test_state_);
+ }
+
+ bool ShouldUseProcessPerSite(BrowserContext* browser_context,
+ const GURL& effective_url) override {
+ if (test_state_->force_new_render_processes) {
+ return true;
+ }
+ return ContentBrowserClient::ShouldUseProcessPerSite(browser_context,
+ effective_url);
+ }
+
+ bool DoesSiteRequireDedicatedProcess(BrowserContext* browser_context,
+ const GURL& effective_url) override {
+ if (test_state_->force_new_render_processes) {
+ return true;
+ }
+ return ContentBrowserClient::DoesSiteRequireDedicatedProcess(
+ browser_context, effective_url);
+ }
+
+ private:
+ WebAuthBrowserTestState* const test_state_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebAuthBrowserTestContentBrowserClient);
+};
+
// Test fixture base class for common tasks.
class WebAuthBrowserTestBase : public content::ContentBrowserTest {
protected:
@@ -230,22 +311,32 @@ class WebAuthBrowserTestBase : public content::ContentBrowserTest {
}
void SetUpOnMainThread() override {
+ ContentBrowserTest::SetUpOnMainThread();
+
host_resolver()->AddRule("*", "127.0.0.1");
https_server().ServeFilesFromSourceDirectory("content/test/data");
ASSERT_TRUE(https_server().Start());
+ test_client_.reset(
+ new WebAuthBrowserTestContentBrowserClient(&test_state_));
+ old_client_ = SetBrowserClientForTesting(test_client_.get());
+
NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title1.html"));
}
+ void TearDown() override {
+ CHECK_EQ(SetBrowserClientForTesting(old_client_), test_client_.get());
+ ContentBrowserTest::TearDown();
+ }
+
GURL GetHttpsURL(const std::string& hostname,
const std::string& relative_url) {
return https_server_.GetURL(hostname, relative_url);
}
net::EmbeddedTestServer& https_server() { return https_server_; }
- device::test::ScopedFakeFidoDiscoveryFactory* discovery_factory() {
- return &factory_;
- }
+
+ WebAuthBrowserTestState* test_state() { return &test_state_; }
private:
void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -257,16 +348,16 @@ class WebAuthBrowserTestBase : public content::ContentBrowserTest {
base::test::ScopedFeatureList scoped_feature_list_;
net::EmbeddedTestServer https_server_;
- device::test::ScopedFakeFidoDiscoveryFactory factory_;
+ std::unique_ptr<WebAuthBrowserTestContentBrowserClient> test_client_;
+ WebAuthBrowserTestState test_state_;
+ ContentBrowserClient* old_client_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(WebAuthBrowserTestBase);
};
-} // namespace
-
// WebAuthLocalClientBrowserTest ----------------------------------------------
-// Browser test fixture where the webauth::mojom::Authenticator interface is
+// Browser test fixture where the blink::mojom::Authenticator interface is
// accessed from a testing client in the browser process.
class WebAuthLocalClientBrowserTest : public WebAuthBrowserTestBase {
public:
@@ -290,52 +381,50 @@ class WebAuthLocalClientBrowserTest : public WebAuthBrowserTestBase {
mojo::MakeRequest(&authenticator_ptr_).PassMessagePipe());
}
- webauth::mojom::PublicKeyCredentialCreationOptionsPtr
+ blink::mojom::PublicKeyCredentialCreationOptionsPtr
BuildBasicCreateOptions() {
- auto rp = webauth::mojom::PublicKeyCredentialRpEntity::New(
+ auto rp = blink::mojom::PublicKeyCredentialRpEntity::New(
"acme.com", "acme.com", base::nullopt);
std::vector<uint8_t> kTestUserId{0, 0, 0};
- auto user = webauth::mojom::PublicKeyCredentialUserEntity::New(
+ auto user = blink::mojom::PublicKeyCredentialUserEntity::New(
kTestUserId, "name", base::nullopt, "displayName");
static constexpr int32_t kCOSEAlgorithmIdentifierES256 = -7;
- auto param = webauth::mojom::PublicKeyCredentialParameters::New();
- param->type = webauth::mojom::PublicKeyCredentialType::PUBLIC_KEY;
+ auto param = blink::mojom::PublicKeyCredentialParameters::New();
+ param->type = blink::mojom::PublicKeyCredentialType::PUBLIC_KEY;
param->algorithm_identifier = kCOSEAlgorithmIdentifierES256;
- std::vector<webauth::mojom::PublicKeyCredentialParametersPtr> parameters;
+ std::vector<blink::mojom::PublicKeyCredentialParametersPtr> parameters;
parameters.push_back(std::move(param));
std::vector<uint8_t> kTestChallenge{0, 0, 0};
- auto mojo_options = webauth::mojom::PublicKeyCredentialCreationOptions::New(
+ auto mojo_options = blink::mojom::PublicKeyCredentialCreationOptions::New(
std::move(rp), std::move(user), kTestChallenge, std::move(parameters),
base::TimeDelta::FromSeconds(30),
- std::vector<webauth::mojom::PublicKeyCredentialDescriptorPtr>(),
- nullptr, webauth::mojom::AttestationConveyancePreference::NONE,
- nullptr);
+ std::vector<blink::mojom::PublicKeyCredentialDescriptorPtr>(), nullptr,
+ blink::mojom::AttestationConveyancePreference::NONE, nullptr);
return mojo_options;
}
- webauth::mojom::PublicKeyCredentialRequestOptionsPtr BuildBasicGetOptions() {
- std::vector<webauth::mojom::PublicKeyCredentialDescriptorPtr> credentials;
- std::vector<webauth::mojom::AuthenticatorTransport> transports;
- transports.push_back(webauth::mojom::AuthenticatorTransport::USB);
+ blink::mojom::PublicKeyCredentialRequestOptionsPtr BuildBasicGetOptions() {
+ std::vector<blink::mojom::PublicKeyCredentialDescriptorPtr> credentials;
+ std::vector<blink::mojom::AuthenticatorTransport> transports;
+ transports.push_back(blink::mojom::AuthenticatorTransport::USB);
- auto descriptor = webauth::mojom::PublicKeyCredentialDescriptor::New(
- webauth::mojom::PublicKeyCredentialType::PUBLIC_KEY,
- std::vector<uint8_t>(
- std::begin(device::test_data::kTestGetAssertionCredentialId),
- std::end(device::test_data::kTestGetAssertionCredentialId)),
+ auto descriptor = blink::mojom::PublicKeyCredentialDescriptor::New(
+ blink::mojom::PublicKeyCredentialType::PUBLIC_KEY,
+ device::fido_parsing_utils::Materialize(
+ device::test_data::kTestGetAssertionCredentialId),
transports);
credentials.push_back(std::move(descriptor));
std::vector<uint8_t> kTestChallenge{0, 0, 0};
- auto mojo_options = webauth::mojom::PublicKeyCredentialRequestOptions::New(
+ auto mojo_options = blink::mojom::PublicKeyCredentialRequestOptions::New(
kTestChallenge, base::TimeDelta::FromSeconds(30), "acme.com",
std::move(credentials),
- webauth::mojom::UserVerificationRequirement::PREFERRED, base::nullopt,
- std::vector<webauth::mojom::CableAuthenticationPtr>());
+ blink::mojom::UserVerificationRequirement::PREFERRED, base::nullopt,
+ std::vector<blink::mojom::CableAuthenticationPtr>());
return mojo_options;
}
@@ -362,7 +451,8 @@ class WebAuthLocalClientBrowserTest : public WebAuthBrowserTestBase {
// pending navigator.credentials.create({publicKey: ...}) call.
IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
CreatePublicKeyCredentialThenNavigateAway) {
- auto* fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
+ device::test::ScopedFakeFidoDiscoveryFactory discovery_factory;
+ auto* fake_hid_discovery = discovery_factory.ForgeNextHidDiscovery();
TestCreateCallbackReceiver create_callback_receiver;
authenticator()->MakeCredential(BuildBasicCreateOptions(),
create_callback_receiver.callback());
@@ -374,7 +464,7 @@ IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
// The next active document should be able to successfully call
// navigator.credentials.create({publicKey: ...}) again.
ConnectToAuthenticator();
- fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
+ fake_hid_discovery = discovery_factory.ForgeNextHidDiscovery();
authenticator()->MakeCredential(BuildBasicCreateOptions(),
create_callback_receiver.callback());
fake_hid_discovery->WaitForCallToStartAndSimulateSuccess();
@@ -384,7 +474,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
// pending navigator.credentials.get({publicKey: ...}) call.
IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
GetPublicKeyCredentialThenNavigateAway) {
- auto* fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
+ device::test::ScopedFakeFidoDiscoveryFactory discovery_factory;
+ auto* fake_hid_discovery = discovery_factory.ForgeNextHidDiscovery();
TestGetCallbackReceiver get_callback_receiver;
authenticator()->GetAssertion(BuildBasicGetOptions(),
get_callback_receiver.callback());
@@ -396,13 +487,70 @@ IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
// The next active document should be able to successfully call
// navigator.credentials.get({publicKey: ...}) again.
ConnectToAuthenticator();
- fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
+ fake_hid_discovery = discovery_factory.ForgeNextHidDiscovery();
authenticator()->GetAssertion(BuildBasicGetOptions(),
get_callback_receiver.callback());
fake_hid_discovery->WaitForCallToStartAndSimulateSuccess();
}
-// Tests that the webauth::mojom::Authenticator connection is not closed on a
+enum class AttestationCallbackBehavior {
+ IGNORE_CALLBACK,
+ BEFORE_NAVIGATION,
+ AFTER_NAVIGATION,
+};
+
+const char* AttestationCallbackBehaviorToString(
+ AttestationCallbackBehavior behavior) {
+ switch (behavior) {
+ case AttestationCallbackBehavior::IGNORE_CALLBACK:
+ return "IGNORE_CALLBACK";
+ case AttestationCallbackBehavior::BEFORE_NAVIGATION:
+ return "BEFORE_NAVIGATION";
+ case AttestationCallbackBehavior::AFTER_NAVIGATION:
+ return "AFTER_NAVIGATION";
+ }
+}
+
+const AttestationCallbackBehavior kAllAttestationCallbackBehaviors[] = {
+ AttestationCallbackBehavior::IGNORE_CALLBACK,
+ AttestationCallbackBehavior::BEFORE_NAVIGATION,
+ AttestationCallbackBehavior::AFTER_NAVIGATION,
+};
+
+// Tests navigating while an attestation permission prompt is showing.
+IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
+ PromptForAttestationThenNavigateAway) {
+ for (auto behavior : kAllAttestationCallbackBehaviors) {
+ SCOPED_TRACE(AttestationCallbackBehaviorToString(behavior));
+
+ device::test::ScopedVirtualFidoDevice virtual_device;
+ TestCreateCallbackReceiver create_callback_receiver;
+ auto options = BuildBasicCreateOptions();
+ options->attestation =
+ blink::mojom::AttestationConveyancePreference::DIRECT;
+ authenticator()->MakeCredential(std::move(options),
+ create_callback_receiver.callback());
+ bool attestation_callback_was_invoked = false;
+ test_state()->attestation_prompt_callback_ = base::BindLambdaForTesting(
+ [&](base::OnceCallback<void(bool)> callback) {
+ attestation_callback_was_invoked = true;
+
+ if (behavior == AttestationCallbackBehavior::BEFORE_NAVIGATION) {
+ std::move(callback).Run(false);
+ }
+ NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title2.html"));
+ if (behavior == AttestationCallbackBehavior::AFTER_NAVIGATION) {
+ std::move(callback).Run(false);
+ }
+ });
+
+ WaitForConnectionError();
+ ASSERT_TRUE(attestation_callback_was_invoked);
+ ConnectToAuthenticator();
+ }
+}
+
+// Tests that the blink::mojom::Authenticator connection is not closed on a
// cancelled navigation.
IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
CreatePublicKeyCredentialAfterCancelledNavigation) {
@@ -411,7 +559,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title2.html"));
- auto* fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
+ device::test::ScopedFakeFidoDiscoveryFactory discovery_factory;
+ auto* fake_hid_discovery = discovery_factory.ForgeNextHidDiscovery();
TestCreateCallbackReceiver create_callback_receiver;
authenticator()->MakeCredential(BuildBasicCreateOptions(),
create_callback_receiver.callback());
@@ -432,7 +581,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
create_callback_receiver.callback());
}));
- auto* fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
+ device::test::ScopedFakeFidoDiscoveryFactory discovery_factory;
+ auto* fake_hid_discovery = discovery_factory.ForgeNextHidDiscovery();
NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title2.html"));
WaitForConnectionError();
@@ -447,7 +597,7 @@ IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
// The next active document should be able to successfully call
// navigator.credentials.create({publicKey: ...}) again.
ConnectToAuthenticator();
- fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
+ fake_hid_discovery = discovery_factory.ForgeNextHidDiscovery();
authenticator()->MakeCredential(BuildBasicCreateOptions(),
create_callback_receiver.callback());
fake_hid_discovery->WaitForCallToStartAndSimulateSuccess();
@@ -485,7 +635,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
CreatePublicKeyCredentialWhileRequestIsPending) {
- auto* fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
+ device::test::ScopedFakeFidoDiscoveryFactory discovery_factory;
+ auto* fake_hid_discovery = discovery_factory.ForgeNextHidDiscovery();
TestCreateCallbackReceiver callback_receiver_1;
TestCreateCallbackReceiver callback_receiver_2;
authenticator()->MakeCredential(BuildBasicCreateOptions(),
@@ -502,7 +653,8 @@ IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
GetPublicKeyCredentialWhileRequestIsPending) {
- auto* fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
+ device::test::ScopedFakeFidoDiscoveryFactory discovery_factory;
+ auto* fake_hid_discovery = discovery_factory.ForgeNextHidDiscovery();
TestGetCallbackReceiver callback_receiver_1;
TestGetCallbackReceiver callback_receiver_2;
authenticator()->GetAssertion(BuildBasicGetOptions(),
@@ -519,7 +671,7 @@ IN_PROC_BROWSER_TEST_F(WebAuthLocalClientBrowserTest,
// WebAuthJavascriptClientBrowserTest -----------------------------------------
-// Browser test fixture where the webauth::mojom::Authenticator interface is
+// Browser test fixture where the blink::mojom::Authenticator interface is
// normally accessed from Javascript in the renderer process.
class WebAuthJavascriptClientBrowserTest : public WebAuthBrowserTestBase {
public:
@@ -532,32 +684,8 @@ class WebAuthJavascriptClientBrowserTest : public WebAuthBrowserTestBase {
DISALLOW_COPY_AND_ASSIGN(WebAuthJavascriptClientBrowserTest);
};
-// Tests that when navigator.credentials.create() is called with user
-// verification required we get a NotSupportedError.
-IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
- CreatePublicKeyCredentialWithUserVerification) {
- CreateParameters parameters;
- parameters.user_verification = kRequiredVerification;
- std::string result;
- ASSERT_TRUE(content::ExecuteScriptAndExtractString(
- shell()->web_contents()->GetMainFrame(),
- BuildCreateCallWithParameters(parameters), &result));
- ASSERT_EQ(kAuthenticatorCriteriaErrorMessage, result);
-}
-
-// Tests that when navigator.credentials.create() is called with resident key
-// required, we get a NotSupportedError.
-IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
- CreatePublicKeyCredentialWithResidentKeyRequired) {
- CreateParameters parameters;
- parameters.require_resident_key = true;
- std::string result;
- ASSERT_TRUE(content::ExecuteScriptAndExtractString(
- shell()->web_contents()->GetMainFrame(),
- BuildCreateCallWithParameters(parameters), &result));
-
- ASSERT_EQ(kAuthenticatorCriteriaErrorMessage, result);
-}
+constexpr device::ProtocolVersion kAllProtocols[] = {
+ device::ProtocolVersion::kCtap, device::ProtocolVersion::kU2f};
// Tests that when navigator.credentials.create() is called with an invalid
// relying party id, we get a SecurityError.
@@ -574,58 +702,111 @@ IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
result.substr(0, strlen(kRelyingPartySecurityErrorMessage)));
}
+// Tests that when navigator.credentials.create() is called with user
+// verification required, request times out.
+IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
+ CreatePublicKeyCredentialWithUserVerification) {
+ for (const auto protocol : kAllProtocols) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
+ virtual_device.SetSupportedProtocol(protocol);
+
+ CreateParameters parameters;
+ parameters.user_verification = kRequiredVerification;
+ std::string result;
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(
+ shell()->web_contents()->GetMainFrame(),
+ BuildCreateCallWithParameters(parameters), &result));
+ ASSERT_EQ(kTimeoutErrorMessage, result);
+ }
+}
+
+// Tests that when navigator.credentials.create() is called with resident key
+// required, request times out.
+IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
+ CreatePublicKeyCredentialWithResidentKeyRequired) {
+ for (const auto protocol : kAllProtocols) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
+ virtual_device.SetSupportedProtocol(protocol);
+
+ CreateParameters parameters;
+ parameters.require_resident_key = true;
+ std::string result;
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(
+ shell()->web_contents()->GetMainFrame(),
+ BuildCreateCallWithParameters(parameters), &result));
+
+ ASSERT_EQ(kTimeoutErrorMessage, result);
+ }
+}
+
// Tests that when navigator.credentials.create() is called with an
-// unsupported algorithm, we get a NotSupportedError.
+// unsupported algorithm, request times out.
IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
CreatePublicKeyCredentialAlgorithmNotSupported) {
- CreateParameters parameters;
- parameters.algorithm_identifier = "123";
- std::string result;
- ASSERT_TRUE(content::ExecuteScriptAndExtractString(
- shell()->web_contents()->GetMainFrame(),
- BuildCreateCallWithParameters(parameters), &result));
-
- ASSERT_EQ(kAlgorithmUnsupportedErrorMessage, result);
+ for (const auto protocol : kAllProtocols) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
+ virtual_device.SetSupportedProtocol(protocol);
+
+ CreateParameters parameters;
+ parameters.algorithm_identifier = "123";
+ std::string result;
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(
+ shell()->web_contents()->GetMainFrame(),
+ BuildCreateCallWithParameters(parameters), &result));
+
+ ASSERT_EQ(kTimeoutErrorMessage, result);
+ }
}
// Tests that when navigator.credentials.create() is called with a
-// platform authenticator requested, we get a NotSupportedError.
+// platform authenticator requested, request times out.
IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
CreatePublicKeyCredentialPlatformAuthenticator) {
- CreateParameters parameters;
- parameters.authenticator_attachment = kPlatform;
- std::string result;
- ASSERT_TRUE(content::ExecuteScriptAndExtractString(
- shell()->web_contents()->GetMainFrame(),
- BuildCreateCallWithParameters(parameters), &result));
-
- ASSERT_EQ(kAuthenticatorCriteriaErrorMessage, result);
+ for (const auto protocol : kAllProtocols) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
+ virtual_device.SetSupportedProtocol(protocol);
+
+ CreateParameters parameters;
+ parameters.authenticator_attachment = kPlatform;
+ std::string result;
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(
+ shell()->web_contents()->GetMainFrame(),
+ BuildCreateCallWithParameters(parameters), &result));
+
+ ASSERT_EQ(kTimeoutErrorMessage, result);
+ }
}
// Tests that when navigator.credentials.get() is called with user verification
// required, we get a NotSupportedError.
IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
GetPublicKeyCredentialUserVerification) {
- GetParameters parameters;
- parameters.user_verification = "required";
- std::string result;
- ASSERT_TRUE(content::ExecuteScriptAndExtractString(
- shell()->web_contents()->GetMainFrame(),
- BuildGetCallWithParameters(parameters), &result));
- ASSERT_EQ(kUserVerificationErrorMessage, result);
+ for (const auto protocol : kAllProtocols) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
+ virtual_device.SetSupportedProtocol(protocol);
+
+ GetParameters parameters;
+ parameters.user_verification = "required";
+ std::string result;
+ ASSERT_TRUE(content::ExecuteScriptAndExtractString(
+ shell()->web_contents()->GetMainFrame(),
+ BuildGetCallWithParameters(parameters), &result));
+ ASSERT_EQ(kTimeoutErrorMessage, result);
+ }
}
// Tests that when navigator.credentials.get() is called with an empty
// allowCredentials list, we get a NotSupportedError.
IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
GetPublicKeyCredentialEmptyAllowCredentialsList) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
GetParameters parameters;
parameters.allow_credentials = "";
std::string result;
ASSERT_TRUE(content::ExecuteScriptAndExtractString(
shell()->web_contents()->GetMainFrame(),
BuildGetCallWithParameters(parameters), &result));
- ASSERT_EQ(kEmptyAllowCredentialsErrorMessage, result);
+ ASSERT_EQ(kInvalidStateErrorMessage, result);
}
// WebAuthBrowserBleDisabledTest
@@ -649,8 +830,9 @@ class WebAuthBrowserBleDisabledTest : public WebAuthLocalClientBrowserTest {
// Tests that the BLE discovery does not start when the WebAuthnBle feature
// flag is disabled.
IN_PROC_BROWSER_TEST_F(WebAuthBrowserBleDisabledTest, CheckBleDisabled) {
- auto* fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
- auto* fake_ble_discovery = discovery_factory()->ForgeNextBleDiscovery();
+ device::test::ScopedFakeFidoDiscoveryFactory discovery_factory;
+ auto* fake_hid_discovery = discovery_factory.ForgeNextHidDiscovery();
+ auto* fake_ble_discovery = discovery_factory.ForgeNextBleDiscovery();
// Do something that will start discoveries.
TestCreateCallbackReceiver create_callback_receiver;
@@ -662,70 +844,251 @@ IN_PROC_BROWSER_TEST_F(WebAuthBrowserBleDisabledTest, CheckBleDisabled) {
EXPECT_FALSE(fake_ble_discovery->is_start_requested());
}
+// Executes Javascript in the given WebContents and waits until a string with
+// the given prefix is received. It will ignore values other than strings, and
+// strings without the given prefix. Since messages are broadcast to
+// DOMMessageQueues, this allows other functions that depend on ExecuteScript
+// (and thus trigger the broadcast of values) to run while this function is
+// waiting for a specific result.
+base::Optional<std::string> ExecuteScriptAndExtractPrefixedString(
+ WebContents* web_contents,
+ const std::string& script,
+ const std::string& result_prefix) {
+ DOMMessageQueue dom_message_queue(web_contents);
+ web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
+ base::UTF8ToUTF16(script));
+
+ for (;;) {
+ std::string json;
+ if (!dom_message_queue.WaitForMessage(&json)) {
+ return base::nullopt;
+ }
+
+ base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS);
+ std::unique_ptr<base::Value> result = reader.ReadToValue(json);
+ if (!result) {
+ return base::nullopt;
+ }
+
+ std::string str;
+ if (result->GetAsString(&str) && str.find(result_prefix) == 0) {
+ return str;
+ }
+ }
+}
+
+// Tests that a credentials.create() call triggered by the main frame will
+// successfully complete even if a subframe navigation takes place while the
+// request is waiting for user consent.
+IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
+ NavigateSubframeDuringPress) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
+ bool prompt_callback_was_invoked = false;
+ virtual_device.mutable_state()->simulate_press_callback =
+ base::BindLambdaForTesting([&]() {
+ prompt_callback_was_invoked = true;
+ NavigateIframeToURL(shell()->web_contents(), "test_iframe",
+ GURL("/title2.html"));
+ });
+
+ NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/page_with_iframe.html"));
+
+ // The plain ExecuteScriptAndExtractString cannot be used because
+ // NavigateIframeToURL uses it internally and they get confused about which
+ // message is for whom.
+ base::Optional<std::string> result = ExecuteScriptAndExtractPrefixedString(
+ shell()->web_contents(),
+ BuildCreateCallWithParameters(CreateParameters()), "webauth: ");
+ ASSERT_TRUE(result);
+ ASSERT_EQ("webauth: OK", *result);
+ ASSERT_TRUE(prompt_callback_was_invoked);
+}
+
+IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
+ NavigateSubframeDuringAttestationPrompt) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
+
+ for (auto behavior : kAllAttestationCallbackBehaviors) {
+ if (behavior == AttestationCallbackBehavior::IGNORE_CALLBACK) {
+ // If the callback is ignored, then the registration will not complete and
+ // that hangs the test.
+ continue;
+ }
+
+ SCOPED_TRACE(AttestationCallbackBehaviorToString(behavior));
+
+ bool prompt_callback_was_invoked = false;
+ test_state()->attestation_prompt_callback_ = base::BindOnce(
+ [](WebContents* web_contents, bool* prompt_callback_was_invoked,
+ AttestationCallbackBehavior behavior,
+ base::OnceCallback<void(bool)> callback) {
+ *prompt_callback_was_invoked = true;
+
+ if (behavior == AttestationCallbackBehavior::BEFORE_NAVIGATION) {
+ std::move(callback).Run(true);
+ }
+ // Can't use NavigateIframeToURL here because in the
+ // BEFORE_NAVIGATION case we are racing AuthenticatorImpl and
+ // NavigateIframeToURL can get confused by the "OK" message.
+ base::Optional<std::string> result =
+ ExecuteScriptAndExtractPrefixedString(
+ web_contents,
+ "document.getElementById('test_iframe').src = "
+ "'/title2.html'; "
+ "window.domAutomationController.send('iframe: done');",
+ "iframe: ");
+ CHECK(result);
+ CHECK_EQ("iframe: done", *result);
+ if (behavior == AttestationCallbackBehavior::AFTER_NAVIGATION) {
+ std::move(callback).Run(true);
+ }
+ },
+ shell()->web_contents(), &prompt_callback_was_invoked, behavior);
+
+ NavigateToURL(shell(),
+ GetHttpsURL("www.acme.com", "/page_with_iframe.html"));
+
+ CreateParameters parameters;
+ parameters.attestation = "direct";
+ // The plain ExecuteScriptAndExtractString cannot be used because
+ // NavigateIframeToURL uses it internally and they get confused about which
+ // message is for whom.
+ base::Optional<std::string> result = ExecuteScriptAndExtractPrefixedString(
+ shell()->web_contents(), BuildCreateCallWithParameters(parameters),
+ "webauth: ");
+ ASSERT_TRUE(result);
+ ASSERT_EQ("webauth: OK", *result);
+ ASSERT_TRUE(prompt_callback_was_invoked);
+ }
+}
+
+IN_PROC_BROWSER_TEST_F(WebAuthJavascriptClientBrowserTest,
+ RegisterDuringUnload) {
+ // Request new render processes for each site in order to test concurrent
+ // unloading with a different RenderFrame showing the new page.
+ test_state()->force_new_render_processes = true;
+
+ NavigateToURL(shell(), GetHttpsURL("www.acme.com", "/title1.html"));
+ const std::string script = base::ReplaceStringPlaceholders(
+ R"(
+ window.addEventListener('unload', function(e) {
+ $1
+ });
+
+ // Trigger a webauthn operation so that the bindings are established
+ // before unload.
+ navigator.credentials.get({ publicKey: {
+ challenge: new TextEncoder().encode('climb a mountain'),
+ timeout: 1,
+ }}).catch(c => window.location = '$2');
+ )",
+ {BuildCreateCallWithParameters(CreateParameters()),
+ GetHttpsURL("www.acme2.com", "/title2.html").spec()},
+ nullptr);
+
+ RenderFrameHost* render_frame_host = shell()->web_contents()->GetMainFrame();
+ RenderFrameDeletedObserver observer(render_frame_host);
+ render_frame_host->ExecuteJavaScriptForTests(base::UTF8ToUTF16(script));
+ observer.WaitUntilDeleted();
+
+ // The |MakeCredential| call from the unload handler should not have reached
+ // the point where focus was checked.
+ EXPECT_FALSE(test_state()->focus_checked);
+
+ // Two delegates should have been created: one for the GetAssertion call that
+ // primes the binding and a second for the MakeCredential call in the unload
+ // handler.
+ ASSERT_EQ(2, test_state()->delegate_create_count);
+}
+
// WebAuthBrowserCtapTest ----------------------------------------------
-// A test fixture that enables CTAP only flag.
class WebAuthBrowserCtapTest : public WebAuthLocalClientBrowserTest {
public:
WebAuthBrowserCtapTest() = default;
+ ~WebAuthBrowserCtapTest() override = default;
- protected:
- std::vector<base::Feature> GetFeaturesToEnable() override {
- return {features::kWebAuth, features::kWebAuthCtap2};
- }
-
- private:
- base::test::ScopedFeatureList scoped_feature_list_;
DISALLOW_COPY_AND_ASSIGN(WebAuthBrowserCtapTest);
};
-// TODO(hongjunchoi): Implement VirtualCtap2Device to replace mocking.
-// See: https://crbugs.com/829413
-IN_PROC_BROWSER_TEST_F(WebAuthBrowserCtapTest, TestCtapMakeCredential) {
- auto* fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
+IN_PROC_BROWSER_TEST_F(WebAuthBrowserCtapTest, TestMakeCredential) {
+ for (const auto protocol : kAllProtocols) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
+ virtual_device.SetSupportedProtocol(protocol);
- TestCreateCallbackReceiver create_callback_receiver;
- authenticator()->MakeCredential(BuildBasicCreateOptions(),
- create_callback_receiver.callback());
+ TestCreateCallbackReceiver create_callback_receiver;
+ authenticator()->MakeCredential(BuildBasicCreateOptions(),
+ create_callback_receiver.callback());
- fake_hid_discovery->WaitForCallToStartAndSimulateSuccess();
- auto device = std::make_unique<device::MockFidoDevice>();
- EXPECT_CALL(*device, GetId()).WillRepeatedly(testing::Return("device0"));
- device->ExpectCtap2CommandAndRespondWith(
- device::CtapRequestCommand::kAuthenticatorGetInfo,
- device::test_data::kTestAuthenticatorGetInfoResponse);
- device->ExpectCtap2CommandAndRespondWith(
- device::CtapRequestCommand::kAuthenticatorMakeCredential,
- device::test_data::kTestMakeCredentialResponse);
-
- fake_hid_discovery->AddDevice(std::move(device));
-
- create_callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::SUCCESS, create_callback_receiver.status());
+ create_callback_receiver.WaitForCallback();
+ EXPECT_EQ(AuthenticatorStatus::SUCCESS, create_callback_receiver.status());
+ }
}
-IN_PROC_BROWSER_TEST_F(WebAuthBrowserCtapTest, TestCtapGetAssertion) {
- auto* fake_hid_discovery = discovery_factory()->ForgeNextHidDiscovery();
+IN_PROC_BROWSER_TEST_F(WebAuthBrowserCtapTest,
+ TestMakeCredentialWithDuplicateKeyHandle) {
+ for (const auto protocol : kAllProtocols) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
+ virtual_device.SetSupportedProtocol(protocol);
+ auto make_credential_request = BuildBasicCreateOptions();
+ auto excluded_credential = blink::mojom::PublicKeyCredentialDescriptor::New(
+ blink::mojom::PublicKeyCredentialType::PUBLIC_KEY,
+ device::fido_parsing_utils::Materialize(
+ device::test_data::kCtap2MakeCredentialCredentialId),
+ std::vector<blink::mojom::AuthenticatorTransport>{
+ blink::mojom::AuthenticatorTransport::USB});
+ make_credential_request->exclude_credentials.push_back(
+ std::move(excluded_credential));
+
+ ASSERT_TRUE(virtual_device.mutable_state()->InjectRegistration(
+ device::fido_parsing_utils::Materialize(
+ device::test_data::kCtap2MakeCredentialCredentialId),
+ make_credential_request->relying_party->id));
+
+ TestCreateCallbackReceiver create_callback_receiver;
+ authenticator()->MakeCredential(std::move(make_credential_request),
+ create_callback_receiver.callback());
+
+ create_callback_receiver.WaitForCallback();
+ EXPECT_EQ(AuthenticatorStatus::CREDENTIAL_EXCLUDED,
+ create_callback_receiver.status());
+ }
+}
- TestGetCallbackReceiver get_callback_receiver;
- auto get_assertion_request_params = BuildBasicGetOptions();
- authenticator()->GetAssertion(std::move(get_assertion_request_params),
- get_callback_receiver.callback());
+IN_PROC_BROWSER_TEST_F(WebAuthBrowserCtapTest, TestGetAssertion) {
+ for (const auto protocol : kAllProtocols) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
+ virtual_device.SetSupportedProtocol(protocol);
+ auto get_assertion_request_params = BuildBasicGetOptions();
+ ASSERT_TRUE(virtual_device.mutable_state()->InjectRegistration(
+ device::fido_parsing_utils::Materialize(
+ device::test_data::kTestGetAssertionCredentialId),
+ get_assertion_request_params->relying_party_id));
+
+ TestGetCallbackReceiver get_callback_receiver;
+ authenticator()->GetAssertion(std::move(get_assertion_request_params),
+ get_callback_receiver.callback());
+ get_callback_receiver.WaitForCallback();
+ EXPECT_EQ(AuthenticatorStatus::SUCCESS, get_callback_receiver.status());
+ }
+}
- fake_hid_discovery->WaitForCallToStartAndSimulateSuccess();
- auto device = std::make_unique<device::MockFidoDevice>();
- EXPECT_CALL(*device, GetId()).WillRepeatedly(testing::Return("device0"));
- device->ExpectCtap2CommandAndRespondWith(
- device::CtapRequestCommand::kAuthenticatorGetInfo,
- device::test_data::kTestAuthenticatorGetInfoResponse);
- device->ExpectCtap2CommandAndRespondWith(
- device::CtapRequestCommand::kAuthenticatorGetAssertion,
- device::test_data::kTestGetAssertionResponse);
-
- fake_hid_discovery->AddDevice(std::move(device));
-
- get_callback_receiver.WaitForCallback();
- EXPECT_EQ(AuthenticatorStatus::SUCCESS, get_callback_receiver.status());
+IN_PROC_BROWSER_TEST_F(WebAuthBrowserCtapTest,
+ TestGetAssertionWithNoMatchingKeyHandles) {
+ for (const auto protocol : kAllProtocols) {
+ device::test::ScopedVirtualFidoDevice virtual_device;
+ virtual_device.SetSupportedProtocol(protocol);
+ auto get_assertion_request_params = BuildBasicGetOptions();
+
+ TestGetCallbackReceiver get_callback_receiver;
+ authenticator()->GetAssertion(std::move(get_assertion_request_params),
+ get_callback_receiver.callback());
+ get_callback_receiver.WaitForCallback();
+ EXPECT_EQ(AuthenticatorStatus::CREDENTIAL_NOT_RECOGNIZED,
+ get_callback_receiver.status());
+ }
}
+} // namespace
+
} // namespace content
diff --git a/chromium/content/browser/webrtc/webrtc_audio_browsertest.cc b/chromium/content/browser/webrtc/webrtc_audio_browsertest.cc
index 1a57c79ba8c..d0679ee756a 100644
--- a/chromium/content/browser/webrtc/webrtc_audio_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_audio_browsertest.cc
@@ -19,23 +19,64 @@
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest-param-test.h"
+#if defined(OS_WIN)
+#include "services/service_manager/sandbox/features.h"
+#endif
+
namespace content {
+namespace {
+
+// Temporary enum, used for running the tests with different combination of
+// flags while audio service is under experiment.
+// TODO(https://crbug.com/850878) Remove after enabling sandboxing on all
+// platforms.
+enum class AudioServiceFeatures {
+ kDisabled,
+ kOutOfProcess,
+#if defined(OS_WIN)
+ kSandboxed,
+#endif
+};
+} // namespace
+
// This class tests the scenario when permission to access mic or camera is
// granted.
-class WebRtcAudioBrowserTest : public WebRtcContentBrowserTestBase,
- public testing::WithParamInterface<bool> {
+class WebRtcAudioBrowserTest
+ : public WebRtcContentBrowserTestBase,
+ public testing::WithParamInterface<AudioServiceFeatures> {
public:
WebRtcAudioBrowserTest() {
std::vector<base::Feature> audio_service_oop_features = {
features::kAudioServiceAudioStreams,
features::kAudioServiceOutOfProcess};
- if (GetParam()) {
- // Force audio service out of process to enabled.
- audio_service_features_.InitWithFeatures(audio_service_oop_features, {});
- } else {
- // Force audio service out of process to disabled.
- audio_service_features_.InitWithFeatures({}, audio_service_oop_features);
+ switch (GetParam()) {
+ case AudioServiceFeatures::kDisabled:
+ // Force audio service out of process to disabled.
+ audio_service_features_.InitWithFeatures({},
+ audio_service_oop_features);
+ break;
+ case AudioServiceFeatures::kOutOfProcess:
+ // Force audio service out of process to enabled.
+ audio_service_features_.InitWithFeatures(
+ audio_service_oop_features,
+#if defined(OS_WIN)
+ // Force audio service sandboxing (available only on Windows) to
+ // disabled.
+ {service_manager::features::kAudioServiceSandbox});
+#else
+ {});
+#endif
+ break;
+#if defined(OS_WIN)
+ case AudioServiceFeatures::kSandboxed:
+ // Force audio service out of process and sandboxing to enabled.
+ audio_service_oop_features.push_back(
+ service_manager::features::kAudioServiceSandbox);
+ audio_service_features_.InitWithFeatures(audio_service_oop_features,
+ {});
+ break;
+#endif
}
}
~WebRtcAudioBrowserTest() override {}
@@ -62,8 +103,8 @@ class WebRtcAudioBrowserTest : public WebRtcContentBrowserTestBase,
ASSERT_TRUE(base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseFakeDeviceForMediaStream))
- << "Must run with fake devices since the test will explicitly look "
- << "for the fake device signal.";
+ << "Must run with fake devices since the test will explicitly look "
+ << "for the fake device signal.";
MakeTypicalCall(javascript, "/media/peerconnection-call-audio.html");
}
@@ -129,14 +170,26 @@ IN_PROC_BROWSER_TEST_P(WebRtcAudioBrowserTest,
// We run these tests with the audio service both in and out of the the browser
// process to have waterfall coverage while the feature rolls out. It should be
// removed after launch.
-#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_LINUX) || defined(OS_MACOSX)
// Supported platforms.
-INSTANTIATE_TEST_CASE_P(, WebRtcAudioBrowserTest, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(,
+ WebRtcAudioBrowserTest,
+ ::testing::Values(AudioServiceFeatures::kDisabled,
+ AudioServiceFeatures::kOutOfProcess));
+#elif defined(OS_WIN)
+// On Windows, also run in sandboxed mode.
+INSTANTIATE_TEST_CASE_P(,
+ WebRtcAudioBrowserTest,
+ ::testing::Values(AudioServiceFeatures::kDisabled,
+ AudioServiceFeatures::kOutOfProcess,
+ AudioServiceFeatures::kSandboxed));
#elif defined(OS_ANDROID) && defined(ADDRESS_SANITIZER)
// Renderer crashes under Android ASAN: https://crbug.com/408496.
#else
// Platforms where the out of process audio service isn't supported
-INSTANTIATE_TEST_CASE_P(, WebRtcAudioBrowserTest, ::testing::Values(false));
+INSTANTIATE_TEST_CASE_P(,
+ WebRtcAudioBrowserTest,
+ ::testing::Values(AudioServiceFeatures::kDisabled));
#endif
} // namespace content
diff --git a/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc b/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
index 339d6f044fb..5a997c3dcd8 100644
--- a/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
+++ b/chromium/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
@@ -18,6 +18,7 @@
#include "content/browser/webrtc/webrtc_internals.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/service_manager_connection.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
@@ -26,10 +27,14 @@
#include "media/audio/fake_audio_input_stream.h"
#include "media/base/media_switches.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "services/audio/public/mojom/constants.mojom.h"
+#include "services/audio/public/mojom/testing_api.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
#include "testing/gtest/include/gtest/gtest-param-test.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
+#include "services/service_manager/sandbox/features.h"
#endif
namespace {
@@ -53,6 +58,18 @@ static const char kRenderDuplicatedMediastreamAndStop[] =
// Results returned by JS.
static const char kOK[] = "OK";
+// Temporary enum, used for running the tests with different combination of
+// flags while audio service is under experiment.
+// TODO(https://crbug.com/850878) Remove after enabling sandboxing on all
+// platforms.
+enum class AudioServiceFeatures {
+ kDisabled,
+ kOutOfProcess,
+#if defined(OS_WIN)
+ kSandboxed,
+#endif
+};
+
std::string GenerateGetUserMediaWithMandatorySourceID(
const std::string& function_name,
const std::string& audio_source_id,
@@ -98,8 +115,9 @@ bool VerifyDisableLocalEcho(bool expect_value,
namespace content {
-class WebRtcGetUserMediaBrowserTest : public WebRtcContentBrowserTestBase,
- public testing::WithParamInterface<bool> {
+class WebRtcGetUserMediaBrowserTest
+ : public WebRtcContentBrowserTestBase,
+ public testing::WithParamInterface<AudioServiceFeatures> {
public:
WebRtcGetUserMediaBrowserTest() {
// Automatically grant device permission.
@@ -107,12 +125,33 @@ class WebRtcGetUserMediaBrowserTest : public WebRtcContentBrowserTestBase,
std::vector<base::Feature> audio_service_oop_features = {
features::kAudioServiceAudioStreams,
features::kAudioServiceOutOfProcess};
- if (GetParam()) {
- // Force audio service out of process to enabled.
- audio_service_features_.InitWithFeatures(audio_service_oop_features, {});
- } else {
- // Force audio service out of process to disabled.
- audio_service_features_.InitWithFeatures({}, audio_service_oop_features);
+ switch (GetParam()) {
+ case AudioServiceFeatures::kDisabled:
+ // Force audio service out of process to disabled.
+ audio_service_features_.InitWithFeatures({},
+ audio_service_oop_features);
+ break;
+ case AudioServiceFeatures::kOutOfProcess:
+ // Force audio service out of process to enabled.
+ audio_service_features_.InitWithFeatures(
+ audio_service_oop_features,
+#if defined(OS_WIN)
+ // Force audio service sandboxing (available only on Windows) to
+ // disabled.
+ {service_manager::features::kAudioServiceSandbox});
+#else
+ {});
+#endif
+ break;
+#if defined(OS_WIN)
+ case AudioServiceFeatures::kSandboxed:
+ // Force audio service out of process and sandboxing to enabled.
+ audio_service_oop_features.push_back(
+ service_manager::features::kAudioServiceSandbox);
+ audio_service_features_.InitWithFeatures(audio_service_oop_features,
+ {});
+ break;
+#endif
}
}
~WebRtcGetUserMediaBrowserTest() override {}
@@ -397,8 +436,9 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest, TwoGetUserMediaAndStop) {
"twoGetUserMediaAndStop({video: true, audio: true});");
}
+// Flaky. See https://crbug.com/846741.
IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
- TwoGetUserMediaWithEqualConstraints) {
+ DISABLED_TwoGetUserMediaWithEqualConstraints) {
std::string constraints1 = "{video: true, audio: true}";
const std::string& constraints2 = constraints1;
std::string expected_result = "w=640:h=480-w=640:h=480";
@@ -407,8 +447,9 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
expected_result);
}
+// Flaky. See https://crbug.com/843844.
IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
- TwoGetUserMediaWithSecondVideoCropped) {
+ DISABLED_TwoGetUserMediaWithSecondVideoCropped) {
std::string constraints1 = "{video: true}";
std::string constraints2 =
"{video: {width: {exact: 640}, height: {exact: 360}}}";
@@ -417,16 +458,10 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
expected_result);
}
-// Test fails under MSan, http://crbug.com/445745
-#if defined(MEMORY_SANITIZER)
-#define MAYBE_TwoGetUserMediaWithFirstHdSecondVga \
- DISABLED_TwoGetUserMediaWithFirstHdSecondVga
-#else
-#define MAYBE_TwoGetUserMediaWithFirstHdSecondVga \
- TwoGetUserMediaWithFirstHdSecondVga
-#endif
+// Test fails under MSan, http://crbug.com/445745.
+// Flaky. See https://crbug.com/846960.
IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
- MAYBE_TwoGetUserMediaWithFirstHdSecondVga) {
+ DISABLED_TwoGetUserMediaWithFirstHdSecondVga) {
std::string constraints1 =
"{video: {width : {exact: 1280}, height: {exact: 720}}}";
std::string constraints2 =
@@ -488,8 +523,9 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
// This test makes two getUserMedia requests, one with impossible constraints
// that should trigger an error, and one with valid constraints. The test
// verifies getUserMedia can succeed after being given impossible constraints.
+// Flaky. See https://crbug.com/846984.
IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
- TwoGetUserMediaAndCheckCallbackAfterFailure) {
+ DISABLED_TwoGetUserMediaAndCheckCallbackAfterFailure) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
@@ -539,8 +575,9 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
}
// This test calls getUserMedia and checks for aspect ratio behavior.
+// Flaky: crbug.com/846582.
IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
- TestGetUserMediaAspectRatio16To9) {
+ DISABLED_TestGetUserMediaAspectRatio16To9) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
@@ -690,8 +727,9 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest, SrcObjectAddVideoTrack) {
ExecuteJavascriptAndWaitForOk("srcObjectAddVideoTrack()");
}
+// TODO(crbug.com/848330) Flaky on all platforms
IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
- SrcObjectReplaceInactiveTracks) {
+ DISABLE_SrcObjectReplaceInactiveTracks) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -707,16 +745,9 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
ExecuteJavascriptAndWaitForOk("srcObjectRemoveVideoTrack()");
}
-// Flaky on memory and leak sanitizers. https://crbug.com/843844
-#if defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER)
-#define MAYBE_SrcObjectRemoveFirstOfTwoVideoTracks \
- DISABLED_SrcObjectRemoveFirstOfTwoVideoTracks
-#else
-#define MAYBE_SrcObjectRemoveFirstOfTwoVideoTracks \
- SrcObjectRemoveFirstOfTwoVideoTracks
-#endif
+// Flaky. https://crbug.com/843844
IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
- SrcObjectRemoveFirstOfTwoVideoTracks) {
+ DISABLED_SrcObjectRemoveFirstOfTwoVideoTracks) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
NavigateToURL(shell(), url);
@@ -794,7 +825,7 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
GetAudioStreamAndCheckMutingInitiallyUnmuted) {
// Muting tests do not work with the out-of-process audio service.
// https://crbug.com/843490.
- if (GetParam())
+ if (GetParam() != AudioServiceFeatures::kDisabled)
return;
ASSERT_TRUE(embedded_test_server()->Start());
@@ -823,7 +854,7 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
GetAudioStreamAndCheckMutingInitiallyMuted) {
// Muting tests do not work with the out-of-process audio service.
// https://crbug.com/843490.
- if (GetParam())
+ if (GetParam() != AudioServiceFeatures::kDisabled)
return;
ASSERT_TRUE(embedded_test_server()->Start());
@@ -849,18 +880,51 @@ IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
"failTestAfterTimeout('Got no mute event', 1500);"));
}
+IN_PROC_BROWSER_TEST_P(WebRtcGetUserMediaBrowserTest,
+ RecoverFromCrashInAudioService) {
+ // This test only makes sense with the audio service running out of process,
+ // with or without sandbox.
+ if (GetParam() == AudioServiceFeatures::kDisabled)
+ return;
+
+ ASSERT_TRUE(embedded_test_server()->Start());
+ GURL url(embedded_test_server()->GetURL("/media/getusermedia.html"));
+ NavigateToURL(shell(), url);
+
+ ExecuteJavascriptAndWaitForOk("setUpForAudioServiceCrash()");
+
+ // Crash the utility process for the audio service
+ service_manager::Connector* connector =
+ ServiceManagerConnection::GetForProcess()->GetConnector();
+ audio::mojom::TestingApiPtr service_testing_api;
+ connector->BindInterface(audio::mojom::kServiceName,
+ mojo::MakeRequest(&service_testing_api));
+ service_testing_api->Crash();
+
+ ExecuteJavascriptAndWaitForOk("verifyAfterAudioServiceCrash()");
+}
+
// We run these tests with the audio service both in and out of the the browser
// process to have waterfall coverage while the feature rolls out. It should be
// removed after launch.
-#if (defined(OS_LINUX) && !defined(CHROME_OS)) || defined(OS_MACOSX) || \
- defined(OS_WIN)
+#if (defined(OS_LINUX) && !defined(CHROME_OS)) || defined(OS_MACOSX)
// Supported platforms.
-INSTANTIATE_TEST_CASE_P(, WebRtcGetUserMediaBrowserTest, ::testing::Bool());
+INSTANTIATE_TEST_CASE_P(,
+ WebRtcGetUserMediaBrowserTest,
+ ::testing::Values(AudioServiceFeatures::kDisabled,
+ AudioServiceFeatures::kOutOfProcess));
+#elif defined(OS_WIN)
+// On Windows, also run in sandboxed mode.
+INSTANTIATE_TEST_CASE_P(,
+ WebRtcGetUserMediaBrowserTest,
+ ::testing::Values(AudioServiceFeatures::kDisabled,
+ AudioServiceFeatures::kOutOfProcess,
+ AudioServiceFeatures::kSandboxed));
#else
// Platforms where the out of process audio service is not supported
INSTANTIATE_TEST_CASE_P(,
WebRtcGetUserMediaBrowserTest,
- ::testing::Values(false));
+ ::testing::Values(AudioServiceFeatures::kDisabled));
#endif
} // namespace content
diff --git a/chromium/content/browser/webrtc/webrtc_internals.cc b/chromium/content/browser/webrtc/webrtc_internals.cc
index b8e4b8b1cc5..89f968cb9a9 100644
--- a/chromium/content/browser/webrtc/webrtc_internals.cc
+++ b/chromium/content/browser/webrtc/webrtc_internals.cc
@@ -133,7 +133,8 @@ WebRTCInternals::WebRTCInternals(int aggregate_updates_ms,
command_line_derived_logging_path_.Append(kEventLogFilename);
WebRtcEventLogger* const logger = WebRtcEventLogger::Get();
if (logger) {
- logger->EnableLocalLogging(local_logs_path);
+ logger->EnableLocalLogging(local_logs_path,
+ base::OnceCallback<void(bool)>());
}
// For clarity's sake, though these aren't supposed to be regarded now:
event_log_recordings_ = true;
@@ -376,7 +377,8 @@ void WebRTCInternals::EnableLocalEventLogRecordings(
#if defined(OS_ANDROID)
WebRtcEventLogger* const logger = WebRtcEventLogger::Get();
if (logger) {
- logger->EnableLocalLogging(event_log_recordings_file_path_);
+ logger->EnableLocalLogging(event_log_recordings_file_path_,
+ base::OnceCallback<void(bool)>());
}
#else
DCHECK(web_contents);
@@ -397,7 +399,7 @@ void WebRTCInternals::DisableLocalEventLogRecordings() {
DCHECK(CanToggleEventLogRecordings());
WebRtcEventLogger* const logger = WebRtcEventLogger::Get();
if (logger) {
- logger->DisableLocalLogging();
+ logger->DisableLocalLogging(base::OnceCallback<void(bool)>());
}
}
@@ -446,7 +448,7 @@ void WebRTCInternals::FileSelected(const base::FilePath& path,
event_log_recordings_ = true;
WebRtcEventLogger* const logger = WebRtcEventLogger::Get();
if (logger) {
- logger->EnableLocalLogging(path);
+ logger->EnableLocalLogging(path, base::OnceCallback<void(bool)>());
}
break;
}
diff --git a/chromium/content/browser/webrtc/webrtc_stress_image_capture_browsertest.cc b/chromium/content/browser/webrtc/webrtc_stress_image_capture_browsertest.cc
new file mode 100644
index 00000000000..ef0f94848d5
--- /dev/null
+++ b/chromium/content/browser/webrtc/webrtc_stress_image_capture_browsertest.cc
@@ -0,0 +1,126 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "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_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"
+#include "content/public/test/test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "media/base/media_switches.h"
+#include "media/capture/video/fake_video_capture_device_factory.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+#if defined(OS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
+namespace content {
+
+namespace {
+
+static const char kImageCaptureStressHtmlFile[] =
+ "/media/image_capture_stress_test.html";
+
+enum class TargetVideoCaptureImplementation {
+ DEFAULT,
+#if defined(OS_WIN)
+ WIN_MEDIA_FOUNDATION
+#endif
+};
+
+} // namespace
+
+class WebRtcImageCaptureStressBrowserTest
+ : public UsingRealWebcam_WebRtcWebcamBrowserTest,
+ public testing::WithParamInterface<TargetVideoCaptureImplementation> {
+ public:
+ WebRtcImageCaptureStressBrowserTest() {
+ std::vector<base::Feature> features_to_enable;
+ std::vector<base::Feature> features_to_disable;
+#if defined(OS_WIN)
+ if (GetParam() == TargetVideoCaptureImplementation::WIN_MEDIA_FOUNDATION) {
+ features_to_enable.push_back(media::kMediaFoundationVideoCapture);
+ } else {
+ features_to_disable.push_back(media::kMediaFoundationVideoCapture);
+ }
+#endif
+ scoped_feature_list_.InitWithFeatures(features_to_enable,
+ features_to_disable);
+ }
+ ~WebRtcImageCaptureStressBrowserTest() override = default;
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ UsingRealWebcam_WebRtcWebcamBrowserTest::SetUpCommandLine(command_line);
+
+ ASSERT_FALSE(base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kUseFakeDeviceForMediaStream));
+ }
+
+ void SetUp() override {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
+ UsingRealWebcam_WebRtcWebcamBrowserTest::SetUp();
+ }
+
+ // Tries to run a |command| JS test, returning true if the test can be safely
+ // skipped or it works as intended, or false otherwise.
+ virtual bool RunImageCaptureTestCase(const std::string& command) {
+ GURL url(embedded_test_server()->GetURL(kImageCaptureStressHtmlFile));
+ NavigateToURL(shell(), url);
+
+ if (!IsWebcamAvailableOnSystem(shell()->web_contents())) {
+ LOG(WARNING) << "No video device; skipping test...";
+ return true;
+ }
+
+ LookupAndLogNameAndIdOfFirstCamera();
+
+ std::string result;
+ if (!ExecuteScriptAndExtractString(shell(), command, &result))
+ return false;
+ DLOG_IF(ERROR, result != "OK") << result;
+ return result == "OK";
+ }
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcImageCaptureStressBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_P(WebRtcImageCaptureStressBrowserTest,
+ MANUAL_Take10Photos) {
+ embedded_test_server()->StartAcceptingConnections();
+ ASSERT_TRUE(RunImageCaptureTestCase("testTake10PhotosSucceeds()"));
+}
+
+// Tests on real webcam can only run on platforms for which the image capture
+// API has already been implemented.
+// Note, these tests must be run sequentially, since multiple parallel test runs
+// competing for a single physical webcam typically causes failures.
+#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_ANDROID) || \
+ defined(OS_WIN)
+
+const TargetVideoCaptureImplementation
+ kTargetVideoCaptureImplementationsForRealWebcam[] = {
+ TargetVideoCaptureImplementation::DEFAULT,
+#if defined(OS_WIN)
+ TargetVideoCaptureImplementation::WIN_MEDIA_FOUNDATION
+#endif
+};
+
+INSTANTIATE_TEST_CASE_P(
+ UsingRealWebcam, // This prefix can be used with --gtest_filter to
+ // distinguish the tests using a real camera from the ones
+ // that don't.
+ WebRtcImageCaptureStressBrowserTest,
+ testing::ValuesIn(kTargetVideoCaptureImplementationsForRealWebcam));
+#endif
+
+} // namespace content
diff --git a/chromium/content/browser/webrtc/webrtc_video_capture_service_browsertest.cc b/chromium/content/browser/webrtc/webrtc_video_capture_service_browsertest.cc
new file mode 100644
index 00000000000..f632cd62a5f
--- /dev/null
+++ b/chromium/content/browser/webrtc/webrtc_video_capture_service_browsertest.cc
@@ -0,0 +1,473 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/command_line.h"
+#include "base/run_loop.h"
+#include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
+#include "components/viz/common/gl_helper.h"
+#include "components/viz/common/gpu/context_provider.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/content_features.h"
+#include "content/public/common/content_switches.h"
+#include "content/public/common/service_manager_connection.h"
+#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/shell/browser/shell.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "media/base/bind_to_current_loop.h"
+#include "media/base/media_switches.h"
+#include "media/base/video_frame.h"
+#include "media/base/video_frame_metadata.h"
+#include "media/capture/video/shared_memory_handle_provider.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/video_capture/public/mojom/constants.mojom.h"
+#include "services/video_capture/public/mojom/device_factory_provider.mojom.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/khronos/GLES2/gl2ext.h"
+#include "ui/compositor/compositor.h"
+
+// ImageTransportFactory::GetInstance is not available on all build configs.
+#if defined(USE_AURA) || defined(OS_MACOSX)
+#define CAN_USE_IMAGE_TRANSPORT_FACTORY 1
+#endif
+
+#if defined(CAN_USE_IMAGE_TRANSPORT_FACTORY)
+#include "content/browser/compositor/image_transport_factory.h"
+
+namespace content {
+
+namespace {
+
+class InvokeClosureOnDelete
+ : public video_capture::mojom::ScopedAccessPermission {
+ public:
+ InvokeClosureOnDelete(base::OnceClosure closure)
+ : closure_(std::move(closure)) {}
+
+ ~InvokeClosureOnDelete() override { std::move(closure_).Run(); }
+
+ private:
+ base::OnceClosure closure_;
+};
+
+static const char kVideoCaptureHtmlFile[] = "/media/video_capture_test.html";
+static const char kStartVideoCaptureAndVerifySize[] =
+ "startVideoCaptureFromDeviceNamedVirtualDeviceAndVerifySize()";
+
+static const char kVirtualDeviceId[] = "/virtual/device";
+static const char kVirtualDeviceName[] = "Virtual Device";
+
+static const gfx::Size kDummyFrameDimensions(320, 200);
+static const int kDummyFrameRate = 5;
+
+} // namespace
+
+// Abstraction for logic that is different between exercising
+// DeviceFactory.AddTextureVirtualDevice() and
+// DeviceFactory.AddSharedMemoryVirtualDevice().
+class VirtualDeviceExerciser {
+ public:
+ virtual ~VirtualDeviceExerciser() {}
+ virtual void Initialize() = 0;
+ virtual void RegisterVirtualDeviceAtFactory(
+ video_capture::mojom::DeviceFactoryPtr* factory,
+ const media::VideoCaptureDeviceInfo& info) = 0;
+ virtual void PushNextFrame(base::TimeDelta timestamp) = 0;
+ virtual void ShutDown() = 0;
+};
+
+// A VirtualDeviceExerciser for exercising
+// DeviceFactory.AddTextureVirtualDevice(). It alternates between two texture
+// RGB dummy frames, one dark one and one light one.
+class TextureDeviceExerciser : public VirtualDeviceExerciser {
+ public:
+ TextureDeviceExerciser() : weak_factory_(this) {
+ DETACH_FROM_SEQUENCE(sequence_checker_);
+ }
+
+ void Initialize() override {
+ ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
+ CHECK(factory);
+ context_provider_ =
+ factory->GetContextFactory()->SharedMainThreadContextProvider();
+ CHECK(context_provider_);
+ gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
+ CHECK(gl);
+ auto gl_helper = std::make_unique<viz::GLHelper>(
+ context_provider_->ContextGL(), context_provider_->ContextSupport());
+
+ const uint8_t kDarkFrameByteValue = 0;
+ const uint8_t kLightFrameByteValue = 200;
+ CreateDummyRgbFrame(gl, gl_helper.get(), kDarkFrameByteValue,
+ &dummy_frame_0_mailbox_holder_);
+ CreateDummyRgbFrame(gl, gl_helper.get(), kLightFrameByteValue,
+ &dummy_frame_1_mailbox_holder_);
+ }
+
+ void RegisterVirtualDeviceAtFactory(
+ video_capture::mojom::DeviceFactoryPtr* factory,
+ const media::VideoCaptureDeviceInfo& info) override {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ (*factory)->AddTextureVirtualDevice(info,
+ mojo::MakeRequest(&virtual_device_));
+
+ virtual_device_->OnNewMailboxHolderBufferHandle(
+ 0, media::mojom::MailboxBufferHandleSet::New(
+ std::move(dummy_frame_0_mailbox_holder_)));
+ virtual_device_->OnNewMailboxHolderBufferHandle(
+ 1, media::mojom::MailboxBufferHandleSet::New(
+ std::move(dummy_frame_1_mailbox_holder_)));
+ frame_being_consumed_[0] = false;
+ frame_being_consumed_[1] = false;
+ }
+
+ void PushNextFrame(base::TimeDelta timestamp) override {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (frame_being_consumed_[dummy_frame_index_]) {
+ LOG(INFO) << "Frame " << dummy_frame_index_ << " is still being consumed";
+ return;
+ }
+
+ video_capture::mojom::ScopedAccessPermissionPtr access_permission_proxy;
+ mojo::MakeStrongBinding<video_capture::mojom::ScopedAccessPermission>(
+ std::make_unique<InvokeClosureOnDelete>(
+ base::BindOnce(&TextureDeviceExerciser::OnFrameConsumptionFinished,
+ weak_factory_.GetWeakPtr(), dummy_frame_index_)),
+ mojo::MakeRequest(&access_permission_proxy));
+
+ media::VideoFrameMetadata metadata;
+ metadata.SetDouble(media::VideoFrameMetadata::FRAME_RATE, kDummyFrameRate);
+ metadata.SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME,
+ base::TimeTicks::Now());
+
+ media::mojom::VideoFrameInfoPtr info = media::mojom::VideoFrameInfo::New();
+ info->timestamp = timestamp;
+ info->pixel_format = media::PIXEL_FORMAT_ARGB;
+ info->coded_size = kDummyFrameDimensions;
+ info->visible_rect = gfx::Rect(kDummyFrameDimensions.width(),
+ kDummyFrameDimensions.height());
+ info->metadata = metadata.GetInternalValues().Clone();
+
+ frame_being_consumed_[dummy_frame_index_] = true;
+ virtual_device_->OnFrameReadyInBuffer(dummy_frame_index_,
+ std::move(access_permission_proxy),
+ std::move(info));
+
+ dummy_frame_index_ = (dummy_frame_index_ + 1) % 2;
+ }
+
+ void ShutDown() override {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ virtual_device_ = nullptr;
+ weak_factory_.InvalidateWeakPtrs();
+ }
+
+ private:
+ void CreateDummyRgbFrame(gpu::gles2::GLES2Interface* gl,
+ viz::GLHelper* gl_helper,
+ uint8_t value_for_all_rgb_bytes,
+ std::vector<gpu::MailboxHolder>* target) {
+ const int32_t kBytesPerRGBPixel = 3;
+ int32_t frame_size_in_bytes = kDummyFrameDimensions.width() *
+ kDummyFrameDimensions.height() *
+ kBytesPerRGBPixel;
+ std::unique_ptr<uint8_t[]> dummy_frame_data(
+ new uint8_t[frame_size_in_bytes]);
+ memset(dummy_frame_data.get(), value_for_all_rgb_bytes,
+ frame_size_in_bytes);
+ for (int i = 0; i < media::VideoFrame::kMaxPlanes; i++) {
+ // For RGB formats, only the first plane needs to be filled with an
+ // actual texture.
+ if (i != 0) {
+ target->push_back(gpu::MailboxHolder());
+ continue;
+ }
+ auto texture_id = gl_helper->CreateTexture();
+ auto mailbox_holder =
+ gl_helper->ProduceMailboxHolderFromTexture(texture_id);
+
+ gl->BindTexture(GL_TEXTURE_2D, texture_id);
+ gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kDummyFrameDimensions.width(),
+ kDummyFrameDimensions.height(), 0, GL_RGB,
+ GL_UNSIGNED_BYTE, dummy_frame_data.get());
+ gl->BindTexture(GL_TEXTURE_2D, 0);
+ target->push_back(std::move(mailbox_holder));
+ }
+ gl->ShallowFlushCHROMIUM();
+ CHECK_EQ(gl->GetError(), static_cast<GLenum>(GL_NO_ERROR));
+ }
+
+ void OnFrameConsumptionFinished(int frame_index) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ frame_being_consumed_[frame_index] = false;
+ }
+
+ SEQUENCE_CHECKER(sequence_checker_);
+ scoped_refptr<viz::ContextProvider> context_provider_;
+ video_capture::mojom::TextureVirtualDevicePtr virtual_device_;
+ int dummy_frame_index_ = 0;
+ std::vector<gpu::MailboxHolder> dummy_frame_0_mailbox_holder_;
+ std::vector<gpu::MailboxHolder> dummy_frame_1_mailbox_holder_;
+ std::array<bool, 2> frame_being_consumed_;
+ base::WeakPtrFactory<TextureDeviceExerciser> weak_factory_;
+};
+
+// A VirtualDeviceExerciser for exercising
+// DeviceFactory.AddSharedMemoryVirtualDevice().
+// It generates (dummy) I420 frame data by setting all bytes equal to the
+// current frame count.
+class SharedMemoryDeviceExerciser : public VirtualDeviceExerciser,
+ public video_capture::mojom::Producer {
+ public:
+ SharedMemoryDeviceExerciser()
+ : producer_binding_(this), weak_factory_(this) {}
+
+ // VirtualDeviceExerciser implementation.
+ void Initialize() override {}
+ void RegisterVirtualDeviceAtFactory(
+ video_capture::mojom::DeviceFactoryPtr* factory,
+ const media::VideoCaptureDeviceInfo& info) override {
+ video_capture::mojom::ProducerPtr producer;
+ static const bool kSendBufferHandlesToProducerAsRawFileDescriptors = false;
+ producer_binding_.Bind(mojo::MakeRequest(&producer));
+ (*factory)->AddSharedMemoryVirtualDevice(
+ info, std::move(producer),
+ kSendBufferHandlesToProducerAsRawFileDescriptors,
+ mojo::MakeRequest(&virtual_device_));
+ }
+ void PushNextFrame(base::TimeDelta timestamp) override {
+ virtual_device_->RequestFrameBuffer(
+ kDummyFrameDimensions, media::VideoPixelFormat::PIXEL_FORMAT_I420,
+ base::BindOnce(&SharedMemoryDeviceExerciser::OnFrameBufferReceived,
+ weak_factory_.GetWeakPtr(), timestamp));
+ }
+ void ShutDown() override {
+ virtual_device_ = nullptr;
+ producer_binding_.Close();
+ weak_factory_.InvalidateWeakPtrs();
+ }
+
+ // video_capture::mojom::Producer implementation.
+ void OnNewBuffer(int32_t buffer_id,
+ media::mojom::VideoBufferHandlePtr buffer_handle,
+ OnNewBufferCallback callback) override {
+ CHECK(buffer_handle->is_shared_buffer_handle());
+ auto handle_provider =
+ std::make_unique<media::SharedMemoryHandleProvider>();
+ handle_provider->InitFromMojoHandle(
+ std::move(buffer_handle->get_shared_buffer_handle()));
+ outgoing_buffer_id_to_buffer_map_.insert(
+ std::make_pair(buffer_id, std::move(handle_provider)));
+ std::move(callback).Run();
+ }
+ void OnBufferRetired(int32_t buffer_id) override {
+ outgoing_buffer_id_to_buffer_map_.erase(buffer_id);
+ }
+
+ private:
+ void OnFrameBufferReceived(base::TimeDelta timestamp, int32_t buffer_id) {
+ if (buffer_id == video_capture::mojom::kInvalidBufferId)
+ return;
+
+ media::VideoFrameMetadata metadata;
+ metadata.SetDouble(media::VideoFrameMetadata::FRAME_RATE, kDummyFrameRate);
+ metadata.SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME,
+ base::TimeTicks::Now());
+
+ media::mojom::VideoFrameInfoPtr info = media::mojom::VideoFrameInfo::New();
+ info->timestamp = timestamp;
+ info->pixel_format = media::PIXEL_FORMAT_I420;
+ info->coded_size = kDummyFrameDimensions;
+ info->visible_rect = gfx::Rect(kDummyFrameDimensions.width(),
+ kDummyFrameDimensions.height());
+ info->metadata = metadata.GetInternalValues().Clone();
+
+ auto outgoing_buffer = outgoing_buffer_id_to_buffer_map_.at(buffer_id)
+ ->GetHandleForInProcessAccess();
+
+ static int frame_count = 0;
+ frame_count++;
+ memset(outgoing_buffer->data(), frame_count % 256,
+ outgoing_buffer->mapped_size());
+
+ virtual_device_->OnFrameReadyInBuffer(buffer_id, std::move(info));
+ }
+
+ mojo::Binding<video_capture::mojom::Producer> producer_binding_;
+ video_capture::mojom::SharedMemoryVirtualDevicePtr virtual_device_;
+ std::map<int32_t /*buffer_id*/,
+ std::unique_ptr<media::SharedMemoryHandleProvider>>
+ outgoing_buffer_id_to_buffer_map_;
+ base::WeakPtrFactory<SharedMemoryDeviceExerciser> weak_factory_;
+};
+
+// Integration test that obtains a connection to the video capture service via
+// the Browser process' service manager. It then registers a virtual device at
+// the service and feeds frames to it. It opens the virtual device in a <video>
+// element on a test page and verifies that the element plays in the expected
+// dimenstions and the pixel content on the element changes.
+class WebRtcVideoCaptureServiceBrowserTest : public ContentBrowserTest {
+ public:
+ WebRtcVideoCaptureServiceBrowserTest()
+ : virtual_device_thread_("Virtual Device Thread"), weak_factory_(this) {
+ scoped_feature_list_.InitAndEnableFeature(features::kMojoVideoCapture);
+ virtual_device_thread_.Start();
+ }
+
+ ~WebRtcVideoCaptureServiceBrowserTest() override {}
+
+ void AddVirtualDeviceAndStartCapture(VirtualDeviceExerciser* device_exerciser,
+ base::OnceClosure finish_test_cb) {
+ DCHECK(virtual_device_thread_.task_runner()->RunsTasksInCurrentSequence());
+ connector_->BindInterface(video_capture::mojom::kServiceName, &provider_);
+ provider_->ConnectToDeviceFactory(mojo::MakeRequest(&factory_));
+
+ media::VideoCaptureDeviceInfo info;
+ info.descriptor.device_id = kVirtualDeviceId;
+ info.descriptor.set_display_name(kVirtualDeviceName);
+ info.descriptor.capture_api = media::VideoCaptureApi::VIRTUAL_DEVICE;
+
+ device_exerciser->RegisterVirtualDeviceAtFactory(&factory_, info);
+
+ main_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&WebRtcVideoCaptureServiceBrowserTest::
+ OpenVirtualDeviceInRendererAndWaitForPlaying,
+ base::Unretained(this),
+ media::BindToCurrentLoop(base::BindOnce(
+ &WebRtcVideoCaptureServiceBrowserTest::
+ ShutDownVirtualDeviceAndContinue,
+ base::Unretained(this), device_exerciser,
+ std::move(finish_test_cb)))));
+
+ PushDummyFrameAndScheduleNextPush(device_exerciser);
+ }
+
+ void PushDummyFrameAndScheduleNextPush(
+ VirtualDeviceExerciser* device_exerciser) {
+ DCHECK(virtual_device_thread_.task_runner()->RunsTasksInCurrentSequence());
+ device_exerciser->PushNextFrame(CalculateTimeSinceFirstInvocation());
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&WebRtcVideoCaptureServiceBrowserTest::
+ PushDummyFrameAndScheduleNextPush,
+ weak_factory_.GetWeakPtr(), device_exerciser),
+ base::TimeDelta::FromMilliseconds(1000 / kDummyFrameRate));
+ }
+
+ void ShutDownVirtualDeviceAndContinue(
+ VirtualDeviceExerciser* device_exerciser,
+ base::OnceClosure continuation) {
+ DCHECK(virtual_device_thread_.task_runner()->RunsTasksInCurrentSequence());
+ LOG(INFO) << "Shutting down virtual device";
+ device_exerciser->ShutDown();
+ factory_ = nullptr;
+ provider_ = nullptr;
+ weak_factory_.InvalidateWeakPtrs();
+ std::move(continuation).Run();
+ }
+
+ void OpenVirtualDeviceInRendererAndWaitForPlaying(
+ base::OnceClosure finish_test_cb) {
+ DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
+ embedded_test_server()->StartAcceptingConnections();
+ GURL url(embedded_test_server()->GetURL(kVideoCaptureHtmlFile));
+ NavigateToURL(shell(), url);
+
+ std::string result;
+ // Start video capture and wait until it started rendering
+ ASSERT_TRUE(ExecuteScriptAndExtractString(
+ shell(), kStartVideoCaptureAndVerifySize, &result));
+ ASSERT_EQ("OK", result);
+
+ std::move(finish_test_cb).Run();
+ }
+
+ protected:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ // Note: We are not planning to actually use the fake device, but we want
+ // to avoid enumerating or otherwise calling into real capture devices.
+ command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
+ command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
+ }
+
+ void SetUp() override {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
+ EnablePixelOutput();
+ ContentBrowserTest::SetUp();
+ }
+
+ void Initialize() {
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ main_task_runner_ = base::ThreadTaskRunnerHandle::Get();
+
+ auto* connection = content::ServiceManagerConnection::GetForProcess();
+ ASSERT_TRUE(connection);
+ auto* connector = connection->GetConnector();
+ ASSERT_TRUE(connector);
+ // We need to clone it so that we can use the clone on a different thread.
+ connector_ = connector->Clone();
+ }
+
+ base::Thread virtual_device_thread_;
+ scoped_refptr<base::TaskRunner> main_task_runner_;
+ std::unique_ptr<service_manager::Connector> connector_;
+
+ private:
+ base::TimeDelta CalculateTimeSinceFirstInvocation() {
+ if (first_frame_time_.is_null())
+ first_frame_time_ = base::TimeTicks::Now();
+ return base::TimeTicks::Now() - first_frame_time_;
+ }
+
+ base::test::ScopedFeatureList scoped_feature_list_;
+ video_capture::mojom::DeviceFactoryProviderPtr provider_;
+ video_capture::mojom::DeviceFactoryPtr factory_;
+ base::TimeTicks first_frame_time_;
+ base::WeakPtrFactory<WebRtcVideoCaptureServiceBrowserTest> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcVideoCaptureServiceBrowserTest);
+};
+
+IN_PROC_BROWSER_TEST_F(
+ WebRtcVideoCaptureServiceBrowserTest,
+ FramesSentThroughTextureVirtualDeviceGetDisplayedOnPage) {
+ Initialize();
+ auto device_exerciser = std::make_unique<TextureDeviceExerciser>();
+ device_exerciser->Initialize();
+
+ base::RunLoop run_loop;
+ virtual_device_thread_.task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&WebRtcVideoCaptureServiceBrowserTest::
+ AddVirtualDeviceAndStartCapture,
+ base::Unretained(this), device_exerciser.get(),
+ media::BindToCurrentLoop(run_loop.QuitClosure())));
+ run_loop.Run();
+}
+
+IN_PROC_BROWSER_TEST_F(
+ WebRtcVideoCaptureServiceBrowserTest,
+ FramesSentThroughSharedMemoryVirtualDeviceGetDisplayedOnPage) {
+ Initialize();
+ auto device_exerciser = std::make_unique<SharedMemoryDeviceExerciser>();
+ device_exerciser->Initialize();
+
+ base::RunLoop run_loop;
+ virtual_device_thread_.task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&WebRtcVideoCaptureServiceBrowserTest::
+ AddVirtualDeviceAndStartCapture,
+ base::Unretained(this), device_exerciser.get(),
+ media::BindToCurrentLoop(run_loop.QuitClosure())));
+ run_loop.Run();
+}
+
+} // namespace content
+
+#endif // defined(CAN_USE_IMAGE_TRANSPORT_FACTORY)
diff --git a/chromium/content/browser/websockets/websocket_manager.cc b/chromium/content/browser/websockets/websocket_manager.cc
index c1ae8621402..13db9a3a2df 100644
--- a/chromium/content/browser/websockets/websocket_manager.cc
+++ b/chromium/content/browser/websockets/websocket_manager.cc
@@ -161,6 +161,7 @@ void WebSocketManager::CreateWebSocket(
int process_id,
int frame_id,
url::Origin origin,
+ network::mojom::AuthenticationHandlerPtr auth_handler,
network::mojom::WebSocketRequest request) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -172,9 +173,11 @@ void WebSocketManager::CreateWebSocket(
network::mojom::NetworkContext* network_context =
storage_partition->GetNetworkContext();
network_context->CreateWebSocket(std::move(request), process_id, frame_id,
- origin);
+ origin, std::move(auth_handler));
return;
}
+ // |auth_handler| is provided only for the network service path.
+ DCHECK(!auth_handler);
// Maintain a WebSocketManager per RenderProcessHost. While the instance of
// WebSocketManager is allocated on the UI thread, it must only be used and
@@ -278,7 +281,7 @@ std::unique_ptr<network::WebSocket> WebSocketManager::DoCreateWebSocketInternal(
url::Origin origin,
base::TimeDelta delay) {
return std::make_unique<network::WebSocket>(
- std::move(delegate), std::move(request),
+ std::move(delegate), std::move(request), nullptr,
std::move(pending_connection_tracker), child_id, frame_id,
std::move(origin), delay);
}
diff --git a/chromium/content/browser/websockets/websocket_manager.h b/chromium/content/browser/websockets/websocket_manager.h
index 006b5bd6ae9..c010f09ed04 100644
--- a/chromium/content/browser/websockets/websocket_manager.h
+++ b/chromium/content/browser/websockets/websocket_manager.h
@@ -34,10 +34,12 @@ class CONTENT_EXPORT WebSocketManager
// - For dedicated workers, |frame_id| should be its parent frame's id.
// - For shared workers and service workers, |frame_id| should be
// MSG_ROUTING_NONE because they do not have a frame.
- static void CreateWebSocket(int process_id,
- int frame_id,
- url::Origin origin,
- network::mojom::WebSocketRequest request);
+ static void CreateWebSocket(
+ int process_id,
+ int frame_id,
+ url::Origin origin,
+ network::mojom::AuthenticationHandlerPtr auth_handler,
+ network::mojom::WebSocketRequest request);
// net::URLRequestContextGetterObserver implementation.
void OnContextShuttingDown() override;
diff --git a/chromium/content/browser/websockets/websocket_manager_unittest.cc b/chromium/content/browser/websockets/websocket_manager_unittest.cc
index 1cee833398c..9aa0b834bf2 100644
--- a/chromium/content/browser/websockets/websocket_manager_unittest.cc
+++ b/chromium/content/browser/websockets/websocket_manager_unittest.cc
@@ -32,6 +32,7 @@ class TestWebSocketImpl : public network::WebSocket {
base::TimeDelta delay)
: network::WebSocket(std::move(delegate),
std::move(request),
+ nullptr,
std::move(pending_connection_tracker),
process_id,
frame_id,
diff --git a/chromium/content/browser/webui/content_web_ui_controller_factory.cc b/chromium/content/browser/webui/content_web_ui_controller_factory.cc
index d741b28c8be..5fd3c07d4ef 100644
--- a/chromium/content/browser/webui/content_web_ui_controller_factory.cc
+++ b/chromium/content/browser/webui/content_web_ui_controller_factory.cc
@@ -57,35 +57,37 @@ bool ContentWebUIControllerFactory::UseWebUIBindingsForURL(
return UseWebUIForURL(browser_context, url);
}
-WebUIController* ContentWebUIControllerFactory::CreateWebUIControllerForURL(
- WebUI* web_ui, const GURL& url) const {
+std::unique_ptr<WebUIController>
+ContentWebUIControllerFactory::CreateWebUIControllerForURL(
+ WebUI* web_ui,
+ const GURL& url) const {
if (!url.SchemeIs(kChromeUIScheme))
return nullptr;
if (url.host_piece() == kChromeUIAppCacheInternalsHost)
- return new AppCacheInternalsUI(web_ui);
+ return std::make_unique<AppCacheInternalsUI>(web_ui);
if (url.host_piece() == kChromeUIGpuHost)
- return new GpuInternalsUI(web_ui);
+ return std::make_unique<GpuInternalsUI>(web_ui);
if (url.host_piece() == kChromeUIHistogramHost)
- return new HistogramsInternalsUI(web_ui);
+ return std::make_unique<HistogramsInternalsUI>(web_ui);
if (url.host_piece() == kChromeUIIndexedDBInternalsHost)
- return new IndexedDBInternalsUI(web_ui);
+ return std::make_unique<IndexedDBInternalsUI>(web_ui);
if (url.host_piece() == kChromeUIMediaInternalsHost)
- return new MediaInternalsUI(web_ui);
+ return std::make_unique<MediaInternalsUI>(web_ui);
if (url.host_piece() == kChromeUIAccessibilityHost)
- return new AccessibilityUI(web_ui);
+ return std::make_unique<AccessibilityUI>(web_ui);
if (url.host_piece() == kChromeUIServiceWorkerInternalsHost)
- return new ServiceWorkerInternalsUI(web_ui);
+ return std::make_unique<ServiceWorkerInternalsUI>(web_ui);
if (url.host_piece() == kChromeUINetworkErrorsListingHost)
- return new NetworkErrorsListingUI(web_ui);
+ return std::make_unique<NetworkErrorsListingUI>(web_ui);
#if !defined(OS_ANDROID)
if (url.host_piece() == kChromeUITracingHost)
- return new TracingUI(web_ui);
+ return std::make_unique<TracingUI>(web_ui);
#endif
if (url.host_piece() == kChromeUIWebRTCInternalsHost)
- return new WebRTCInternalsUI(web_ui);
+ return std::make_unique<WebRTCInternalsUI>(web_ui);
if (url.host_piece() == kChromeUIProcessInternalsHost)
- return new ProcessInternalsUI(web_ui);
+ return std::make_unique<ProcessInternalsUI>(web_ui);
return nullptr;
}
diff --git a/chromium/content/browser/webui/content_web_ui_controller_factory.h b/chromium/content/browser/webui/content_web_ui_controller_factory.h
index 15f782c3255..8d5fe5737a6 100644
--- a/chromium/content/browser/webui/content_web_ui_controller_factory.h
+++ b/chromium/content/browser/webui/content_web_ui_controller_factory.h
@@ -15,16 +15,18 @@ namespace content {
class CONTENT_EXPORT ContentWebUIControllerFactory
: public WebUIControllerFactory {
public:
+ static ContentWebUIControllerFactory* GetInstance();
+
+ // WebUIControllerFactory:
WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
const GURL& url) const override;
bool UseWebUIForURL(BrowserContext* browser_context,
const GURL& url) const override;
bool UseWebUIBindingsForURL(BrowserContext* browser_context,
const GURL& url) const override;
- WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
- const GURL& url) const override;
-
- static ContentWebUIControllerFactory* GetInstance();
+ std::unique_ptr<WebUIController> CreateWebUIControllerForURL(
+ WebUI* web_ui,
+ const GURL& url) const override;
protected:
ContentWebUIControllerFactory();
diff --git a/chromium/content/browser/webui/shared_resources_data_source.cc b/chromium/content/browser/webui/shared_resources_data_source.cc
index a883e7e8c15..b00558bd012 100644
--- a/chromium/content/browser/webui/shared_resources_data_source.cc
+++ b/chromium/content/browser/webui/shared_resources_data_source.cc
@@ -7,13 +7,16 @@
#include <stddef.h>
#include "base/containers/hash_tables.h"
+#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
+#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_client.h"
+#include "content/public/common/content_features.h"
#include "content/public/common/url_constants.h"
#include "mojo/public/js/grit/mojo_bindings_resources.h"
#include "mojo/public/js/grit/mojo_bindings_resources_map.h"
@@ -36,16 +39,50 @@ struct IdrGzipped {
};
using ResourcesMap = base::hash_map<std::string, IdrGzipped>;
-// TODO(rkc): Once we have a separate source for apps, remove '*/apps/' aliases.
-const char* const kPathAliases[][2] = {
- {"../../../third_party/polymer/v1_0/components-chromium/", "polymer/v1_0/"},
- {"../../../third_party/web-animations-js/sources/",
- "polymer/v1_0/web-animations-js/"},
- {"../../views/resources/default_100_percent/common/", "images/apps/"},
- {"../../views/resources/default_200_percent/common/", "images/2x/apps/"},
- {"../../webui/resources/cr_components/", "cr_components/"},
- {"../../webui/resources/cr_elements/", "cr_elements/"},
-};
+const std::map<std::string, std::string> CreateAliasesMap() {
+ // TODO(rkc): Once we have a separate source for apps, remove '*/apps/'
+ // aliases.
+ std::map<std::string, std::string> aliases = {
+ {"../../../third_party/polymer/v1_0/components-chromium/",
+ "polymer/v1_0/"},
+ {"../../../third_party/web-animations-js/sources/",
+ "polymer/v1_0/web-animations-js/"},
+ {"../../views/resources/default_100_percent/common/", "images/apps/"},
+ {"../../views/resources/default_200_percent/common/", "images/2x/apps/"},
+ {"../../webui/resources/cr_components/", "cr_components/"},
+ {"../../webui/resources/cr_elements/", "cr_elements/"},
+ };
+
+#if !defined(OS_ANDROID)
+ if (base::FeatureList::IsEnabled(features::kWebUIPolymer2)) {
+ aliases["../../../third_party/polymer/v1_0/components-chromium/polymer2/"] =
+ "polymer/v1_0/polymer/";
+ }
+#endif // !defined(OS_ANDROID)
+ return aliases;
+}
+
+#if !defined(OS_ANDROID)
+bool ShouldIgnore(std::string resource) {
+ if (base::FeatureList::IsEnabled(features::kWebUIPolymer2) &&
+ base::StartsWith(
+ resource,
+ "../../../third_party/polymer/v1_0/components-chromium/polymer/",
+ base::CompareCase::SENSITIVE)) {
+ return true;
+ }
+
+ if (!base::FeatureList::IsEnabled(features::kWebUIPolymer2) &&
+ base::StartsWith(
+ resource,
+ "../../../third_party/polymer/v1_0/components-chromium/polymer2/",
+ base::CompareCase::SENSITIVE)) {
+ return true;
+ }
+
+ return false;
+}
+#endif // !defined(OS_ANDROID)
void AddResource(const std::string& path,
int resource_id,
@@ -57,15 +94,24 @@ void AddResource(const std::string& path,
}
const ResourcesMap* CreateResourcesMap() {
+ std::map<std::string, std::string> aliases = CreateAliasesMap();
+
ResourcesMap* result = new ResourcesMap();
for (size_t i = 0; i < kWebuiResourcesSize; ++i) {
const auto& resource = kWebuiResources[i];
+
+#if !defined(OS_ANDROID)
+ if (ShouldIgnore(resource.name))
+ continue;
+#endif // !defined(OS_ANDROID)
+
AddResource(resource.name, resource.value, resource.gzipped, result);
- for (const char* const (&alias)[2] : kPathAliases) {
- if (base::StartsWith(resource.name, alias[0],
+
+ for (auto it = aliases.begin(); it != aliases.end(); ++it) {
+ if (base::StartsWith(resource.name, it->first,
base::CompareCase::SENSITIVE)) {
std::string resource_name(resource.name);
- AddResource(alias[1] + resource_name.substr(strlen(alias[0])),
+ AddResource(it->second + resource_name.substr(it->first.length()),
resource.value, resource.gzipped, result);
}
}
diff --git a/chromium/content/browser/webui/url_data_manager_backend.cc b/chromium/content/browser/webui/url_data_manager_backend.cc
index 96d91340510..80f12df9d42 100644
--- a/chromium/content/browser/webui/url_data_manager_backend.cc
+++ b/chromium/content/browser/webui/url_data_manager_backend.cc
@@ -16,8 +16,8 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_memory.h"
-#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
+#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
@@ -63,7 +63,7 @@ const char kNetworkErrorKey[] = "netError";
bool SchemeIsInSchemes(const std::string& scheme,
const std::vector<std::string>& schemes) {
- return std::find(schemes.begin(), schemes.end(), scheme) != schemes.end();
+ return base::ContainsValue(schemes, scheme);
}
// Returns a value of 'Origin:' header for the |request| if the header is set.
@@ -119,9 +119,7 @@ class URLRequestChromeJob : public net::URLRequestJob {
is_gzipped_ = is_gzipped;
}
- void SetReplacements(const ui::TemplateReplacements* replacements) {
- replacements_ = replacements;
- }
+ void SetSource(scoped_refptr<URLDataSourceImpl> source) { source_ = source; }
private:
~URLRequestChromeJob() override;
@@ -162,8 +160,10 @@ class URLRequestChromeJob : public net::URLRequestJob {
// resources in resources.pak use compress="gzip".
bool is_gzipped_;
- // Replacement dictionary for i18n.
- const ui::TemplateReplacements* replacements_;
+ // The URLDataSourceImpl that is servicing this request. This is a shared
+ // pointer so that the request can continue to be served even if the source is
+ // detached from the backend that initially owned it.
+ scoped_refptr<URLDataSourceImpl> source_;
// The backend is owned by net::URLRequestContext and always outlives us.
URLDataManagerBackend* const backend_;
@@ -181,7 +181,6 @@ URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request,
data_available_status_(net::OK),
pending_buf_size_(0),
is_gzipped_(false),
- replacements_(nullptr),
backend_(backend),
weak_factory_(this) {
DCHECK(backend);
@@ -247,9 +246,20 @@ std::unique_ptr<net::SourceStream> URLRequestChromeJob::SetUpSourceStream() {
net::SourceStream::TYPE_GZIP);
}
- if (replacements_) {
+ // The URLRequestJob and the SourceStreams we are creating are owned by the
+ // same parent URLRequest, thus it is safe to pass the replacements via a raw
+ // pointer.
+ const ui::TemplateReplacements* replacements = nullptr;
+ if (source_)
+ replacements = source_->GetReplacements();
+ if (replacements) {
+ // It is safe to pass the raw replacements directly to the source stream, as
+ // both this URLRequestChromeJob and the I18nSourceStream are owned by the
+ // same root URLRequest. The replacements are owned by the URLDataSourceImpl
+ // which we keep alive via |source_|, ensuring its lifetime is also bound
+ // to the safe URLRequest.
source_stream = ui::I18nSourceStream::Create(
- std::move(source_stream), net::SourceStream::TYPE_NONE, replacements_);
+ std::move(source_stream), net::SourceStream::TYPE_NONE, replacements);
}
return source_stream;
@@ -404,18 +414,14 @@ class ChromeProtocolHandler
} // namespace
URLDataManagerBackend::URLDataManagerBackend()
- : next_request_id_(0) {
+ : next_request_id_(0), weak_factory_(this) {
URLDataSource* shared_source = new SharedResourcesDataSource();
URLDataSourceImpl* source_impl =
new URLDataSourceImpl(shared_source->GetSource(), shared_source);
AddDataSource(source_impl);
}
-URLDataManagerBackend::~URLDataManagerBackend() {
- for (const auto& i : data_sources_)
- i.second->backend_ = nullptr;
- data_sources_.clear();
-}
+URLDataManagerBackend::~URLDataManagerBackend() = default;
// static
std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler>
@@ -430,14 +436,13 @@ URLDataManagerBackend::CreateProtocolHandler(
void URLDataManagerBackend::AddDataSource(
URLDataSourceImpl* source) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- DataSourceMap::iterator i = data_sources_.find(source->source_name());
- if (i != data_sources_.end()) {
- if (!source->source()->ShouldReplaceExistingSource())
+ if (!source->source()->ShouldReplaceExistingSource()) {
+ DataSourceMap::iterator i = data_sources_.find(source->source_name());
+ if (i != data_sources_.end())
return;
- i->second->backend_ = nullptr;
}
data_sources_[source->source_name()] = source;
- source->backend_ = this;
+ source->backend_ = weak_factory_.GetWeakPtr();
}
void URLDataManagerBackend::UpdateWebUIDataSource(
@@ -493,7 +498,7 @@ bool URLDataManagerBackend::StartRequest(const net::URLRequest* request,
// replacements upon.
std::string mime_type = source->source()->GetMimeType(path);
if (mime_type == "text/html")
- job->SetReplacements(source->GetReplacements());
+ job->SetSource(source);
// Also notifies that the headers are complete.
job->MimeTypeAvailable(mime_type);
diff --git a/chromium/content/browser/webui/url_data_manager_backend.h b/chromium/content/browser/webui/url_data_manager_backend.h
index a6f3ab913fb..d5009883c92 100644
--- a/chromium/content/browser/webui/url_data_manager_backend.h
+++ b/chromium/content/browser/webui/url_data_manager_backend.h
@@ -12,6 +12,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
#include "base/values.h"
#include "content/browser/webui/url_data_manager.h"
@@ -123,6 +124,12 @@ class URLDataManagerBackend : public base::SupportsUserData::Data {
// The ID we'll use for the next request we receive.
RequestID next_request_id_;
+ // Vends weak pointers to URLDataSources, allowing them to continue referring
+ // to the backend that originally owned them, even if they've been replaced
+ // and detached from the backend. This allows outstanding asynchronous queries
+ // to be served and routed to the backend to which they were original issued.
+ base::WeakPtrFactory<URLDataManagerBackend> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(URLDataManagerBackend);
};
diff --git a/chromium/content/browser/webui/url_data_source_impl.h b/chromium/content/browser/webui/url_data_source_impl.h
index 77c2e975d7a..62cbd439883 100644
--- a/chromium/content/browser/webui/url_data_source_impl.h
+++ b/chromium/content/browser/webui/url_data_source_impl.h
@@ -9,6 +9,7 @@
#include <string>
#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner_helpers.h"
#include "content/browser/webui/url_data_manager.h"
#include "content/common/content_export.h"
@@ -90,13 +91,18 @@ class URLDataSourceImpl : public base::RefCountedThreadSafe<
const std::string source_name_;
// This field is set and maintained by URLDataManagerBackend. It is set when
- // the DataSource is added, and unset if the DataSource is removed. A
- // DataSource can be removed in two ways: the URLDataManagerBackend is
- // deleted, or another DataSource is registered with the same name. backend_
- // should only be accessed on the IO thread. This reference can't be via a
- // scoped_refptr else there would be a cycle between the backend and data
- // source.
- URLDataManagerBackend* backend_;
+ // the DataSource is added. A DataSource can be removed in two ways:
+ // (1) The URLDataManagerBackend is deleted, and the weak ptr is invalidated.
+ // In this case queries pending against this data source will implicitly
+ // be dropped as their responses will have no backend for routing.
+ // (2) Another DataSource is registered with the same name. In this case the
+ // backend still exists and remains referenced by this data source,
+ // allowing pending queries to be routed to the backend that formerly
+ // owned them.
+ // This field should only be referenced on the IO thread. This reference can't
+ // be via a scoped_refptr else there would be a cycle between the backend and
+ // the data source.
+ base::WeakPtr<URLDataManagerBackend> backend_;
std::unique_ptr<URLDataSource> source_;
};
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 dd0e955be8d..ab265d71210 100644
--- a/chromium/content/browser/webui/web_ui_controller_factory_registry.cc
+++ b/chromium/content/browser/webui/web_ui_controller_factory_registry.cc
@@ -9,6 +9,7 @@
#include "base/lazy_instance.h"
#include "content/browser/frame_host/debug_urls.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/web_ui_controller.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "url/gurl.h"
@@ -39,13 +40,14 @@ WebUIControllerFactoryRegistry* WebUIControllerFactoryRegistry::GetInstance() {
return base::Singleton<WebUIControllerFactoryRegistry>::get();
}
-WebUIController* WebUIControllerFactoryRegistry::CreateWebUIControllerForURL(
- WebUI* web_ui, const GURL& url) const {
- 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);
+std::unique_ptr<WebUIController>
+WebUIControllerFactoryRegistry::CreateWebUIControllerForURL(
+ WebUI* web_ui,
+ const GURL& url) const {
+ std::vector<WebUIControllerFactory*>& factories =
+ g_web_ui_controller_factories.Get();
+ for (const WebUIControllerFactory* factory : factories) {
+ auto controller = factory->CreateWebUIControllerForURL(web_ui, url);
if (controller)
return controller;
}
diff --git a/chromium/content/browser/webui/web_ui_controller_factory_registry.h b/chromium/content/browser/webui/web_ui_controller_factory_registry.h
index 11020c2da24..466a62d67bb 100644
--- a/chromium/content/browser/webui/web_ui_controller_factory_registry.h
+++ b/chromium/content/browser/webui/web_ui_controller_factory_registry.h
@@ -20,8 +20,9 @@ class CONTENT_EXPORT WebUIControllerFactoryRegistry
// WebUIControllerFactory implementation. Each method loops through the same
// method on all the factories.
- WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
- const GURL& url) const override;
+ std::unique_ptr<WebUIController> CreateWebUIControllerForURL(
+ WebUI* web_ui,
+ const GURL& url) const override;
WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
const GURL& url) const override;
bool UseWebUIForURL(BrowserContext* browser_context,
diff --git a/chromium/content/browser/webui/web_ui_impl.cc b/chromium/content/browser/webui/web_ui_impl.cc
index ceac82cbc8d..1868b575f02 100644
--- a/chromium/content/browser/webui/web_ui_impl.cc
+++ b/chromium/content/browser/webui/web_ui_impl.cc
@@ -177,8 +177,9 @@ WebUIController* WebUIImpl::GetController() const {
return controller_.get();
}
-void WebUIImpl::SetController(WebUIController* controller) {
- controller_.reset(controller);
+void WebUIImpl::SetController(std::unique_ptr<WebUIController> controller) {
+ DCHECK(controller);
+ controller_ = std::move(controller);
}
bool WebUIImpl::CanCallJavascript() {
@@ -250,7 +251,7 @@ void WebUIImpl::CallJavascriptFunctionUnsafe(
void WebUIImpl::RegisterMessageCallback(base::StringPiece message,
const MessageCallback& callback) {
- message_callbacks_.emplace(message, callback);
+ message_callbacks_.emplace(message.as_string(), callback);
}
void WebUIImpl::ProcessWebUIMessage(const GURL& source_url,
diff --git a/chromium/content/browser/webui/web_ui_impl.h b/chromium/content/browser/webui/web_ui_impl.h
index 484f918c98c..a0e36cec6e3 100644
--- a/chromium/content/browser/webui/web_ui_impl.h
+++ b/chromium/content/browser/webui/web_ui_impl.h
@@ -45,7 +45,7 @@ class CONTENT_EXPORT WebUIImpl : public WebUI,
// WebUI implementation:
WebContents* GetWebContents() const override;
WebUIController* GetController() const override;
- void SetController(WebUIController* controller) override;
+ void SetController(std::unique_ptr<WebUIController> controller) override;
float GetDeviceScaleFactor() const override;
const base::string16& GetOverriddenTitle() const override;
void OverrideTitle(const base::string16& title) override;
diff --git a/chromium/content/browser/webui/web_ui_mojo_browsertest.cc b/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
index cf09e884aed..d8ab9ec2be1 100644
--- a/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
+++ b/chromium/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -5,6 +5,8 @@
#include <limits>
#include <utility>
+#include "base/callback.h"
+#include "base/containers/flat_map.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/macros.h"
@@ -13,6 +15,7 @@
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_restrictions.h"
+#include "build/build_config.h"
#include "content/browser/webui/web_ui_controller_factory_registry.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h"
@@ -22,8 +25,10 @@
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_controller.h"
#include "content/public/browser/web_ui_data_source.h"
+#include "content/public/common/bindings_policy.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
@@ -32,7 +37,6 @@
#include "content/test/data/web_ui_test_mojo_bindings.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h"
-#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/service_manager/public/cpp/binder_registry.h"
namespace content {
@@ -101,8 +105,11 @@ class BrowserTargetImpl : public mojom::BrowserTarget {
// WebUIController that sets up mojo bindings.
class TestWebUIController : public WebUIController {
public:
- TestWebUIController(WebUI* web_ui, base::RunLoop* run_loop)
+ TestWebUIController(WebUI* web_ui,
+ base::RunLoop* run_loop,
+ int bindings = BINDINGS_POLICY_MOJO_WEB_UI)
: WebUIController(web_ui), run_loop_(run_loop) {
+ web_ui->SetBindings(bindings);
WebUIDataSource* data_source = WebUIDataSource::Create("mojo-web-ui");
data_source->SetRequestFilter(base::Bind(&GetResource));
WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
@@ -152,36 +159,76 @@ class PingTestWebUIController : public TestWebUIController,
// WebUIControllerFactory that creates TestWebUIController.
class TestWebUIControllerFactory : public WebUIControllerFactory {
public:
- TestWebUIControllerFactory() : run_loop_(nullptr) {}
+ TestWebUIControllerFactory()
+ : run_loop_(nullptr),
+ registered_controllers_(
+ {{"ping", base::BindRepeating(
+ &TestWebUIControllerFactory::CreatePingController,
+ base::Unretained(this))},
+ {"hybrid", base::BindRepeating(
+ &TestWebUIControllerFactory::CreateHybridController,
+ base::Unretained(this))},
+ {"webui_bindings",
+ base::BindRepeating(
+ &TestWebUIControllerFactory::CreateWebUIController,
+ base::Unretained(this))}}) {}
void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
- WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
- const GURL& url) const override {
- if (url.query() == "ping")
- return new PingTestWebUIController(web_ui, run_loop_);
- return new TestWebUIController(web_ui, run_loop_);
+ std::unique_ptr<WebUIController> CreateWebUIControllerForURL(
+ WebUI* web_ui,
+ const GURL& url) const override {
+ if (!web_ui_enabled_ || !url.SchemeIs(kChromeUIScheme))
+ return nullptr;
+
+ auto it = registered_controllers_.find(url.query());
+ if (it != registered_controllers_.end())
+ return it->second.Run(web_ui);
+
+ return std::make_unique<TestWebUIController>(web_ui, run_loop_);
}
+
WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
const GURL& url) const override {
- if (!web_ui_enabled_)
+ if (!web_ui_enabled_ || !url.SchemeIs(kChromeUIScheme))
return WebUI::kNoWebUI;
+
return reinterpret_cast<WebUI::TypeID>(1);
}
+
bool UseWebUIForURL(BrowserContext* browser_context,
const GURL& url) const override {
- return true;
+ return GetWebUIType(browser_context, url) != WebUI::kNoWebUI;
}
bool UseWebUIBindingsForURL(BrowserContext* browser_context,
const GURL& url) const override {
- return true;
+ return GetWebUIType(browser_context, url) != WebUI::kNoWebUI;
}
void set_web_ui_enabled(bool enabled) { web_ui_enabled_ = enabled; }
private:
+ std::unique_ptr<WebUIController> CreatePingController(WebUI* web_ui) {
+ return std::make_unique<PingTestWebUIController>(web_ui, run_loop_);
+ }
+
+ std::unique_ptr<WebUIController> CreateHybridController(WebUI* web_ui) {
+ return std::make_unique<TestWebUIController>(
+ web_ui, run_loop_,
+ BINDINGS_POLICY_WEB_UI | BINDINGS_POLICY_MOJO_WEB_UI);
+ }
+
+ std::unique_ptr<WebUIController> CreateWebUIController(WebUI* web_ui) {
+ return std::make_unique<TestWebUIController>(web_ui, run_loop_,
+ BINDINGS_POLICY_WEB_UI);
+ }
+
base::RunLoop* run_loop_;
bool web_ui_enabled_ = true;
+ const base::flat_map<
+ std::string,
+ base::RepeatingCallback<std::unique_ptr<WebUIController>(WebUI*)>>
+ registered_controllers_;
DISALLOW_COPY_AND_ASSIGN(TestWebUIControllerFactory);
};
@@ -198,6 +245,24 @@ class WebUIMojoTest : public ContentBrowserTest {
TestWebUIControllerFactory* factory() { return &factory_; }
+ void NavigateWithNewWebUI(const std::string& path) {
+ // Load an invalid URL first so that a new WebUI is set up when we load
+ // the URL we're actually interested in.
+ EXPECT_FALSE(NavigateToURL(shell(), GURL()));
+
+ constexpr char kChromeUIMojoWebUIOrigin[] = "chrome://mojo-web-ui/";
+ EXPECT_TRUE(NavigateToURL(shell(), GURL(kChromeUIMojoWebUIOrigin + path)));
+ }
+
+ // Run |script| and return a boolean result.
+ bool RunBoolFunction(const std::string& script) {
+ bool result = false;
+ EXPECT_TRUE(ExecuteScriptAndExtractBool(
+ shell()->web_contents(), "domAutomationController.send(" + script + ")",
+ &result));
+ return result;
+ }
+
private:
TestWebUIControllerFactory factory_;
@@ -225,7 +290,6 @@ IN_PROC_BROWSER_TEST_F(WebUIMojoTest, EndToEndPing) {
return;
g_got_message = false;
- ASSERT_TRUE(embedded_test_server()->Start());
base::RunLoop run_loop;
factory()->set_run_loop(&run_loop);
GURL test_url("chrome://mojo-web-ui/web_ui_mojo.html?ping");
@@ -248,29 +312,60 @@ IN_PROC_BROWSER_TEST_F(WebUIMojoTest, EndToEndPing) {
other_shell->web_contents()->GetMainFrame()->GetProcess());
}
-IN_PROC_BROWSER_TEST_F(WebUIMojoTest, NativeMojoAvailable) {
- ASSERT_TRUE(embedded_test_server()->Start());
- const GURL kTestWebUIUrl("chrome://mojo-web-ui/web_ui_mojo_native.html");
- NavigateToURL(shell(), kTestWebUIUrl);
+// Disabled due to flakiness: crbug.com/860385.
+#if defined(OS_ANDROID)
+#define MAYBE_NativeMojoAvailable DISABLED_NativeMojoAvailable
+#else
+#define MAYBE_NativeMojoAvailable NativeMojoAvailable
+#endif
+IN_PROC_BROWSER_TEST_F(WebUIMojoTest, MAYBE_NativeMojoAvailable) {
+ // Mojo bindings should be enabled.
+ NavigateWithNewWebUI("web_ui_mojo_native.html");
+ EXPECT_TRUE(RunBoolFunction("isNativeMojoAvailable()"));
+
+ // Now navigate again with normal WebUI bindings and ensure chrome.send is
+ // available.
+ NavigateWithNewWebUI("web_ui_mojo_native.html?webui_bindings");
+ EXPECT_FALSE(RunBoolFunction("isNativeMojoAvailable()"));
- bool is_native_mojo_available = false;
- const std::string kTestScript("isNativeMojoAvailable()");
- ASSERT_TRUE(ExecuteScriptAndExtractBool(
- shell()->web_contents(),
- "domAutomationController.send(" + kTestScript + ")",
- &is_native_mojo_available));
- EXPECT_TRUE(is_native_mojo_available);
+ // Now navigate again both WebUI and Mojo bindings and ensure chrome.send is
+ // available.
+ NavigateWithNewWebUI("web_ui_mojo_native.html?hybrid");
+ EXPECT_TRUE(RunBoolFunction("isNativeMojoAvailable()"));
// Now navigate again with WebUI disabled and ensure the native bindings are
// not available.
factory()->set_web_ui_enabled(false);
- const std::string kTestNonWebUIUrl("/web_ui_mojo_native.html");
- NavigateToURL(shell(), embedded_test_server()->GetURL(kTestNonWebUIUrl));
- ASSERT_TRUE(ExecuteScriptAndExtractBool(
- shell()->web_contents(),
- "domAutomationController.send(" + kTestScript + ")",
- &is_native_mojo_available));
- EXPECT_FALSE(is_native_mojo_available);
+ NavigateWithNewWebUI("web_ui_mojo_native.html?hybrid");
+ EXPECT_FALSE(RunBoolFunction("isNativeMojoAvailable()"));
+}
+
+// Disabled due to flakiness: crbug.com/860385.
+#if defined(OS_ANDROID)
+#define MAYBE_ChromeSendAvailable DISABLED_ChromeSendAvailable
+#else
+#define MAYBE_ChromeSendAvailable ChromeSendAvailable
+#endif
+IN_PROC_BROWSER_TEST_F(WebUIMojoTest, MAYBE_ChromeSendAvailable) {
+ // chrome.send is not available on mojo-only WebUIs.
+ NavigateWithNewWebUI("web_ui_mojo_native.html");
+ EXPECT_FALSE(RunBoolFunction("isChromeSendAvailable()"));
+
+ // Now navigate again with normal WebUI bindings and ensure chrome.send is
+ // available.
+ NavigateWithNewWebUI("web_ui_mojo_native.html?webui_bindings");
+ EXPECT_TRUE(RunBoolFunction("isChromeSendAvailable()"));
+
+ // Now navigate again both WebUI and Mojo bindings and ensure chrome.send is
+ // available.
+ NavigateWithNewWebUI("web_ui_mojo_native.html?hybrid");
+ EXPECT_TRUE(RunBoolFunction("isChromeSendAvailable()"));
+
+ // Now navigate again with WebUI disabled and ensure that chrome.send is
+ // not available.
+ factory()->set_web_ui_enabled(false);
+ NavigateWithNewWebUI("web_ui_mojo_native.html?hybrid");
+ EXPECT_FALSE(RunBoolFunction("isChromeSendAvailable()"));
}
} // namespace
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 baa74f4c5e5..653e22e0ee5 100644
--- a/chromium/content/browser/webui/web_ui_url_loader_factory.cc
+++ b/chromium/content/browser/webui/web_ui_url_loader_factory.cc
@@ -66,7 +66,7 @@ void ReadData(scoped_refptr<network::ResourceResponse> headers,
network::mojom::URLLoaderClientPtr client;
client.Bind(std::move(client_info));
- client->OnReceiveResponse(headers->head, nullptr);
+ client->OnReceiveResponse(headers->head);
base::StringPiece input(reinterpret_cast<const char*>(bytes->front()),
bytes->size());
@@ -119,6 +119,7 @@ void ReadData(scoped_refptr<network::ResourceResponse> headers,
network::URLLoaderCompletionStatus status(net::OK);
status.encoded_data_length = output_size;
status.encoded_body_length = output_size;
+ status.decoded_body_length = output_size;
client->OnComplete(status);
}
@@ -244,7 +245,6 @@ class WebUIURLLoaderFactory : public network::mojom::URLLoaderFactory,
const net::MutableNetworkTrafficAnnotationTag&
traffic_annotation) override {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(!request.download_to_file);
if (request.url.scheme() != scheme_) {
DVLOG(1) << "Bad scheme: " << request.url.scheme();
diff --git a/chromium/content/child/BUILD.gn b/chromium/content/child/BUILD.gn
index 7c110b354fa..1f8971c0eb0 100644
--- a/chromium/content/child/BUILD.gn
+++ b/chromium/content/child/BUILD.gn
@@ -67,7 +67,6 @@ target(link_target_type, "child") {
"runtime_features.h",
"scoped_child_process_reference.cc",
"scoped_child_process_reference.h",
- "scoped_web_callbacks.h",
"service_factory.cc",
"service_factory.h",
"thread_safe_sender.cc",
@@ -104,7 +103,7 @@ target(link_target_type, "child") {
"//gpu/command_buffer/client",
"//media",
"//media/blink",
- "//mojo/edk",
+ "//mojo/core/embedder",
"//net",
"//services/device/public/cpp:device_features",
"//services/device/public/cpp/power_monitor",
@@ -146,7 +145,11 @@ target(link_target_type, "child") {
}
if (is_linux) {
- deps += [ "//services/service_manager/zygote" ]
+ deps += [
+ "//components/services/font/public/cpp",
+ "//components/services/font/public/interfaces",
+ "//services/service_manager/zygote",
+ ]
}
if (is_win) {
diff --git a/chromium/content/child/DEPS b/chromium/content/child/DEPS
index c6e3f2d7de2..9cb3d30db75 100644
--- a/chromium/content/child/DEPS
+++ b/chromium/content/child/DEPS
@@ -4,6 +4,7 @@ include_rules = [
"+components/tracing",
"+components/variations/child_process_field_trial_syncer.h",
"+components/webcrypto",
+ "+components/services/font/public",
"+content/app/strings/grit", # For generated headers
"+content/public/child",
diff --git a/chromium/content/child/blink_platform_impl.cc b/chromium/content/child/blink_platform_impl.cc
index d15a8c88c11..49c0dcb3182 100644
--- a/chromium/content/child/blink_platform_impl.cc
+++ b/chromium/content/child/blink_platform_impl.cc
@@ -36,6 +36,7 @@
#include "content/app/resources/grit/content_resources.h"
#include "content/app/strings/grit/content_strings.h"
#include "content/child/child_thread_impl.h"
+#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
@@ -46,7 +47,6 @@
#include "third_party/blink/public/platform/scheduler/child/webthread_base.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_float_point.h"
-#include "third_party/blink/public/platform/web_gesture_curve.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
@@ -71,6 +71,8 @@ static int ToMessageID(WebLocalizedString::Name name) {
switch (name) {
case WebLocalizedString::kAXAMPMFieldText:
return IDS_AX_AM_PM_FIELD_TEXT;
+ case WebLocalizedString::kAXCalendarShowDatePicker:
+ return IDS_AX_CALENDAR_SHOW_DATE_PICKER;
case WebLocalizedString::kAXCalendarShowMonthSelector:
return IDS_AX_CALENDAR_SHOW_MONTH_SELECTOR;
case WebLocalizedString::kAXCalendarShowNextMonth:
@@ -105,6 +107,10 @@ static int ToMessageID(WebLocalizedString::Name name) {
return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON;
case WebLocalizedString::kAXMediaExitFullscreenButton:
return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON;
+ case WebLocalizedString::kAXMediaEnterPictureInPictureButton:
+ return IDS_AX_MEDIA_ENTER_PICTURE_IN_PICTURE_BUTTON;
+ case WebLocalizedString::kAXMediaExitPictureInPictureButton:
+ return IDS_AX_MEDIA_EXIT_PICTURE_IN_PICTURE_BUTTON;
case WebLocalizedString::kAXMediaShowClosedCaptionsButton:
return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON;
case WebLocalizedString::kAXMediaHideClosedCaptionsButton:
@@ -141,6 +147,10 @@ static int ToMessageID(WebLocalizedString::Name name) {
return IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON_HELP;
case WebLocalizedString::kAXMediaExitFullscreenButtonHelp:
return IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON_HELP;
+ case WebLocalizedString::kAXMediaEnterPictureInPictureButtonHelp:
+ return IDS_AX_MEDIA_ENTER_PICTURE_IN_PICTURE_BUTTON_HELP;
+ case WebLocalizedString::kAXMediaExitPictureInPictureButtonHelp:
+ return IDS_AX_MEDIA_EXIT_PICTURE_IN_PICTURE_BUTTON_HELP;
case WebLocalizedString::kAXMediaShowClosedCaptionsButtonHelp:
return IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_BUTTON_HELP;
case WebLocalizedString::kAXMediaHideClosedCaptionsButtonHelp:
@@ -223,8 +233,10 @@ static int ToMessageID(WebLocalizedString::Name name) {
return IDS_MEDIA_OVERFLOW_MENU_PAUSE;
case WebLocalizedString::kOverflowMenuDownload:
return IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD;
- case WebLocalizedString::kOverflowMenuPictureInPicture:
- return IDS_MEDIA_OVERFLOW_MENU_PICTURE_IN_PICTURE;
+ case WebLocalizedString::kOverflowMenuEnterPictureInPicture:
+ return IDS_MEDIA_OVERFLOW_MENU_ENTER_PICTURE_IN_PICTURE;
+ case WebLocalizedString::kOverflowMenuExitPictureInPicture:
+ return IDS_MEDIA_OVERFLOW_MENU_EXIT_PICTURE_IN_PICTURE;
case WebLocalizedString::kPictureInPictureInterstitialText:
return IDS_MEDIA_PICTURE_IN_PICTURE_INTERSTITIAL_TEXT;
case WebLocalizedString::kPlaceholderForDayOfMonthField:
@@ -652,29 +664,6 @@ WebString BlinkPlatformImpl::QueryLocalizedString(WebLocalizedString::Name name,
GetContentClient()->GetLocalizedString(message_id), values, nullptr));
}
-bool BlinkPlatformImpl::IsRendererSideResourceSchedulerEnabled() const {
- // We are assuming that kRendererSideResourceScheduler will be shipped when
- // launching Network Service, so let's act as if
- // kRendererSideResourceScheduler is enabled when kNetworkService is enabled.
- // Note: This is identical to
- // ResourceScheduler::IsRendererSideResourceSchedulerEnabled but we duplicate
- // the logic in order to avoid a DEPS issue.
- return base::FeatureList::IsEnabled(
- network::features::kRendererSideResourceScheduler) ||
- base::FeatureList::IsEnabled(network::features::kNetworkService);
-}
-
-std::unique_ptr<blink::WebGestureCurve>
-BlinkPlatformImpl::CreateFlingAnimationCurve(
- blink::WebGestureDevice device_source,
- const blink::WebFloatPoint& velocity,
- const blink::WebSize& cumulative_scroll) {
- return ui::WebGestureCurveImpl::CreateFromDefaultPlatformCurve(
- device_source, gfx::Vector2dF(velocity.x, velocity.y),
- gfx::Vector2dF(cumulative_scroll.width, cumulative_scroll.height),
- IsMainThread());
-}
-
bool BlinkPlatformImpl::AllowScriptExtensionForServiceWorker(
const blink::WebURL& scriptUrl) {
return GetContentClient()->AllowScriptExtensionForServiceWorker(scriptUrl);
diff --git a/chromium/content/child/blink_platform_impl.h b/chromium/content/child/blink_platform_impl.h
index 4cbfab92679..67329003283 100644
--- a/chromium/content/child/blink_platform_impl.h
+++ b/chromium/content/child/blink_platform_impl.h
@@ -91,11 +91,6 @@ class CONTENT_EXPORT BlinkPlatformImpl : public blink::Platform {
const blink::WebString& value1,
const blink::WebString& value2) override;
void SuddenTerminationChanged(bool enabled) 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;
bool AllowScriptExtensionForServiceWorker(
const blink::WebURL& script_url) override;
blink::WebCrypto* Crypto() override;
diff --git a/chromium/content/child/browser_font_resource_trusted.cc b/chromium/content/child/browser_font_resource_trusted.cc
index fb4a65c7f5e..a43e2d1933f 100644
--- a/chromium/content/child/browser_font_resource_trusted.cc
+++ b/chromium/content/child/browser_font_resource_trusted.cc
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "cc/paint/paint_canvas.h"
#include "cc/paint/skia_paint_canvas.h"
#include "content/public/common/web_preferences.h"
#include "ppapi/proxy/connection.h"
@@ -18,7 +19,6 @@
#include "ppapi/thunk/ppb_image_data_api.h"
#include "ppapi/thunk/thunk.h"
#include "skia/ext/platform_canvas.h"
-#include "third_party/blink/public/platform/web_canvas.h"
#include "third_party/blink/public/platform/web_float_point.h"
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/platform/web_font.h"
@@ -37,7 +37,6 @@ using blink::WebFont;
using blink::WebFontDescription;
using blink::WebRect;
using blink::WebTextRun;
-using blink::WebCanvas;
namespace content {
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 7899935f659..9dd008c8417 100644
--- a/chromium/content/child/child_process_sandbox_support_impl_linux.cc
+++ b/chromium/content/child/child_process_sandbox_support_impl_linux.cc
@@ -15,6 +15,10 @@
#include "base/posix/unix_domain_socket.h"
#include "base/sys_byteorder.h"
#include "base/trace_event/trace_event.h"
+#include "components/services/font/public/cpp/font_loader.h"
+#include "components/services/font/public/interfaces/constants.mojom.h"
+#include "components/services/font/public/interfaces/font_service.mojom.h"
+#include "content/public/common/common_sandbox_support_linux.h"
#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#include "services/service_manager/zygote/common/common_sandbox_support_linux.h"
#include "third_party/blink/public/platform/linux/web_fallback_font.h"
@@ -24,113 +28,70 @@
namespace content {
-void GetFallbackFontForCharacter(int32_t character,
+void GetFallbackFontForCharacter(sk_sp<font_service::FontLoader> font_loader,
+ int32_t character,
const char* preferred_locale,
- blink::WebFallbackFont* fallbackFont) {
- TRACE_EVENT0("sandbox_ipc", "GetFontFamilyForCharacter");
-
- base::Pickle request;
- 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(
- service_manager::GetSandboxFD(), buf, sizeof(buf), nullptr, request);
-
+ blink::WebFallbackFont* fallback_font) {
+ DCHECK(font_loader.get());
+ font_service::mojom::FontIdentityPtr font_identity;
+ bool is_bold = false;
+ bool is_italic = false;
std::string family_name;
- std::string filename;
- int fontconfigInterfaceId = 0;
- int ttcIndex = 0;
- bool isBold = false;
- bool isItalic = false;
- if (n != -1) {
- base::Pickle reply(reinterpret_cast<char*>(buf), n);
- base::PickleIterator pickle_iter(reply);
- if (pickle_iter.ReadString(&family_name) &&
- pickle_iter.ReadString(&filename) &&
- pickle_iter.ReadInt(&fontconfigInterfaceId) &&
- pickle_iter.ReadInt(&ttcIndex) && pickle_iter.ReadBool(&isBold) &&
- pickle_iter.ReadBool(&isItalic)) {
- fallbackFont->name = blink::WebString::FromUTF8(family_name);
- fallbackFont->filename = blink::WebVector<char>(filename);
- fallbackFont->fontconfig_interface_id = fontconfigInterfaceId;
- fallbackFont->ttc_index = ttcIndex;
- fallbackFont->is_bold = isBold;
- fallbackFont->is_italic = isItalic;
- }
+ if (!font_loader->FallbackFontForCharacter(character, preferred_locale,
+ &font_identity, &family_name,
+ &is_bold, &is_italic)) {
+ LOG(ERROR) << "FontService fallback request does not receive a response.";
+ return;
}
+
+ // TODO(drott): Perhaps take WebFallbackFont out of the picture here and pass
+ // mojo FontIdentityPtr directly?
+ fallback_font->name =
+ blink::WebString::FromUTF8(family_name.c_str(), family_name.length());
+ fallback_font->fontconfig_interface_id = font_identity->id;
+ fallback_font->filename.Assign(font_identity->str_representation.c_str(),
+ font_identity->str_representation.length());
+ fallback_font->ttc_index = font_identity->ttc_index;
+ fallback_font->is_bold = is_bold;
+ fallback_font->is_italic = is_italic;
+ return;
}
-void GetRenderStyleForStrike(const char* family,
- int size_and_style,
+void GetRenderStyleForStrike(sk_sp<font_service::FontLoader> font_loader,
+ const char* family,
+ int size,
+ bool is_bold,
+ bool is_italic,
+ float device_scale_factor,
blink::WebFontRenderStyle* out) {
- TRACE_EVENT0("sandbox_ipc", "GetRenderStyleForStrike");
+ DCHECK(font_loader.get());
+ font_service::mojom::FontIdentityPtr font_identity;
*out = blink::WebFontRenderStyle();
- if (size_and_style < 0)
+ if (size < 0 || size > std::numeric_limits<uint16_t>::max())
return;
- const bool bold = size_and_style & 1;
- const bool italic = size_and_style & 2;
- const int pixel_size = size_and_style >> 2;
- if (pixel_size > std::numeric_limits<uint16_t>::max())
+ font_service::mojom::FontRenderStylePtr font_render_style;
+ if (!font_loader->FontRenderStyleForStrike(family, size, is_bold, is_italic,
+ device_scale_factor,
+ &font_render_style) ||
+ font_render_style.is_null()) {
+ LOG(ERROR) << "GetRenderStyleForStrike did not receive a response for "
+ "family and size: "
+ << (family ? family : "<empty>") << ", " << size;
return;
-
- base::Pickle request;
- request.WriteInt(service_manager::SandboxLinux::METHOD_GET_STYLE_FOR_STRIKE);
- request.WriteString(family);
- request.WriteBool(bold);
- request.WriteBool(italic);
- request.WriteUInt16(pixel_size);
-
- uint8_t buf[512];
- const ssize_t n = base::UnixDomainSocket::SendRecvMsg(
- service_manager::GetSandboxFD(), buf, sizeof(buf), nullptr, request);
- if (n == -1)
- return;
-
- base::Pickle reply(reinterpret_cast<char*>(buf), n);
- base::PickleIterator pickle_iter(reply);
- int use_bitmaps, use_autohint, use_hinting, hint_style, use_antialias;
- int use_subpixel_rendering, use_subpixel_positioning;
- if (pickle_iter.ReadInt(&use_bitmaps) && pickle_iter.ReadInt(&use_autohint) &&
- pickle_iter.ReadInt(&use_hinting) && pickle_iter.ReadInt(&hint_style) &&
- pickle_iter.ReadInt(&use_antialias) &&
- pickle_iter.ReadInt(&use_subpixel_rendering) &&
- pickle_iter.ReadInt(&use_subpixel_positioning)) {
- out->use_bitmaps = use_bitmaps;
- out->use_auto_hint = use_autohint;
- out->use_hinting = use_hinting;
- out->hint_style = hint_style;
- out->use_anti_alias = use_antialias;
- out->use_subpixel_rendering = use_subpixel_rendering;
- out->use_subpixel_positioning = use_subpixel_positioning;
}
-}
-
-int MatchFontWithFallback(const std::string& face,
- bool bold,
- bool italic,
- int charset,
- PP_BrowserFont_Trusted_Family fallback_family) {
- TRACE_EVENT0("sandbox_ipc", "MatchFontWithFallback");
- base::Pickle request;
- request.WriteInt(service_manager::SandboxLinux::METHOD_MATCH_WITH_FALLBACK);
- request.WriteString(face);
- request.WriteBool(bold);
- request.WriteBool(italic);
- request.WriteUInt32(charset);
- request.WriteUInt32(fallback_family);
- uint8_t reply_buf[64];
- int fd = -1;
- base::UnixDomainSocket::SendRecvMsg(service_manager::GetSandboxFD(),
- reply_buf, sizeof(reply_buf), &fd,
- request);
- return fd;
+ out->use_bitmaps = static_cast<char>(font_render_style->use_bitmaps);
+ out->use_auto_hint = static_cast<char>(font_render_style->use_autohint);
+ out->use_hinting = static_cast<char>(font_render_style->use_hinting);
+ out->hint_style = font_render_style->hint_style;
+ out->use_anti_alias = static_cast<char>(font_render_style->use_antialias);
+ out->use_subpixel_rendering =
+ static_cast<char>(font_render_style->use_subpixel_rendering);
+ out->use_subpixel_positioning =
+ static_cast<char>(font_render_style->use_subpixel_positioning);
}
} // namespace content
diff --git a/chromium/content/child/child_process_sandbox_support_impl_linux.h b/chromium/content/child/child_process_sandbox_support_impl_linux.h
index c4bf1b696c1..140060cbf14 100644
--- a/chromium/content/child/child_process_sandbox_support_impl_linux.h
+++ b/chromium/content/child/child_process_sandbox_support_impl_linux.h
@@ -7,7 +7,8 @@
#include <stdint.h>
-#include "content/public/child/child_process_sandbox_support_linux.h"
+#include "components/services/font/public/cpp/font_loader.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
namespace blink {
struct WebFallbackFont;
@@ -20,7 +21,8 @@ namespace content {
// specified by |character|, a UTF-32 character. |preferred_locale| contains the
// preferred locale identifier for |character|. The instance has an empty font
// name if the request could not be satisfied.
-void GetFallbackFontForCharacter(const int32_t character,
+void GetFallbackFontForCharacter(sk_sp<font_service::FontLoader> font_loader,
+ const int32_t character,
const char* preferred_locale,
blink::WebFallbackFont* family);
@@ -28,11 +30,12 @@ void GetFallbackFontForCharacter(const int32_t character,
// |size_and_style| stores the bold setting in its least-significant bit, the
// italic setting in its second-least-significant bit, and holds the requested
// size in pixels into its remaining bits.
-// TODO(derat): Update WebSandboxSupport's getWebFontRenderStyleForStrike()
-// method to pass the style and size separately instead of packing them into an
-// int.
-void GetRenderStyleForStrike(const char* family,
- int size_and_style,
+void GetRenderStyleForStrike(sk_sp<font_service::FontLoader> font_loader,
+ const char* family,
+ int size,
+ bool is_bold,
+ bool is_italic,
+ float device_scale_factor,
blink::WebFontRenderStyle* out);
}; // namespace content
diff --git a/chromium/content/child/child_thread_impl.cc b/chromium/content/child/child_thread_impl.cc
index d6898e941c8..53f41fc6b2a 100644
--- a/chromium/content/child/child_thread_impl.cc
+++ b/chromium/content/child/child_thread_impl.cc
@@ -17,9 +17,12 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/memory_pressure_listener.h"
#include "base/message_loop/timer_slack.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
+#include "base/optional.h"
#include "base/process/process.h"
#include "base/process/process_handle.h"
#include "base/run_loop.h"
@@ -42,6 +45,7 @@
#include "content/common/in_process_child_thread_params.h"
#include "content/public/common/connection_filter.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"
@@ -51,12 +55,13 @@
#include "ipc/ipc_platform_file.h"
#include "ipc/ipc_sync_channel.h"
#include "ipc/ipc_sync_message_filter.h"
-#include "mojo/edk/embedder/embedder.h"
-#include "mojo/edk/embedder/incoming_broker_client_invitation.h"
-#include "mojo/edk/embedder/named_platform_channel_pair.h"
-#include "mojo/edk/embedder/platform_channel_pair.h"
-#include "mojo/edk/embedder/scoped_ipc_support.h"
+#include "mojo/core/embedder/scoped_ipc_support.h"
+#include "mojo/public/cpp/platform/named_platform_channel.h"
+#include "mojo/public/cpp/platform/platform_channel.h"
+#include "mojo/public/cpp/platform/platform_channel_endpoint.h"
+#include "mojo/public/cpp/platform/platform_handle.h"
#include "mojo/public/cpp/system/buffer.h"
+#include "mojo/public/cpp/system/invitation.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "services/device/public/cpp/power_monitor/power_monitor_broadcast_source.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.h"
@@ -74,7 +79,7 @@
#endif
#if defined(CLANG_COVERAGE)
-extern "C" int __llvm_profile_write_file(void);
+extern "C" int __llvm_profile_dump(void);
#endif
namespace content {
@@ -82,7 +87,14 @@ namespace {
void WriteClangCoverageProfile() {
#if defined(CLANG_COVERAGE)
- __llvm_profile_write_file();
+ // __llvm_profile_dump() guarantees that it will not dump coverage information
+ // if it is being called twice or more. However, it is not thread safe, as it
+ // is supposed to be called from atexit() handler rather than being called
+ // directly from random places. Since we have to call it ourselves, we must
+ // ensure thread safety in order to prevent duplication of coverage counters.
+ static base::NoDestructor<base::Lock> lock;
+ base::AutoLock auto_lock(*lock);
+ __llvm_profile_dump();
#endif
}
@@ -236,40 +248,34 @@ base::LazyInstance<QuitClosure>::DestructorAtExit g_quit_closure =
LAZY_INSTANCE_INITIALIZER;
#endif
-std::unique_ptr<mojo::edk::IncomingBrokerClientInvitation>
-InitializeMojoIPCChannel() {
+base::Optional<mojo::IncomingInvitation> InitializeMojoIPCChannel() {
TRACE_EVENT0("startup", "InitializeMojoIPCChannel");
- mojo::edk::ScopedInternalPlatformHandle platform_channel;
+ mojo::PlatformChannelEndpoint endpoint;
#if defined(OS_WIN)
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- mojo::edk::PlatformChannelPair::kMojoPlatformChannelHandleSwitch)) {
- platform_channel =
- mojo::edk::PlatformChannelPair::PassClientHandleFromParentProcess(
- *base::CommandLine::ForCurrentProcess());
+ mojo::PlatformChannel::kHandleSwitch)) {
+ endpoint = mojo::PlatformChannel::RecoverPassedEndpointFromCommandLine(
+ *base::CommandLine::ForCurrentProcess());
} else {
// If this process is elevated, it will have a pipe path passed on the
// command line.
- platform_channel =
- mojo::edk::NamedPlatformChannelPair::PassClientHandleFromParentProcess(
- *base::CommandLine::ForCurrentProcess());
+ endpoint = mojo::NamedPlatformChannel::ConnectToServer(
+ *base::CommandLine::ForCurrentProcess());
}
#elif defined(OS_FUCHSIA)
- platform_channel =
- mojo::edk::PlatformChannelPair::PassClientHandleFromParentProcess(
- *base::CommandLine::ForCurrentProcess());
+ endpoint = mojo::PlatformChannel::RecoverPassedEndpointFromCommandLine(
+ *base::CommandLine::ForCurrentProcess());
#elif defined(OS_POSIX)
- platform_channel.reset(mojo::edk::InternalPlatformHandle(
- base::GlobalDescriptors::GetInstance()->Get(
- service_manager::kMojoIPCChannel)));
+ endpoint = mojo::PlatformChannelEndpoint(mojo::PlatformHandle(
+ base::ScopedFD(base::GlobalDescriptors::GetInstance()->Get(
+ service_manager::kMojoIPCChannel))));
#endif
// Mojo isn't supported on all child process types.
// TODO(crbug.com/604282): Support Mojo in the remaining processes.
- if (!platform_channel.is_valid())
- return nullptr;
+ if (!endpoint.is_valid())
+ return base::nullopt;
- return mojo::edk::IncomingBrokerClientInvitation::Accept(
- mojo::edk::ConnectionParams(mojo::edk::TransportProtocol::kLegacy,
- std::move(platform_channel)));
+ return mojo::IncomingInvitation::Accept(std::move(endpoint));
}
class ChannelBootstrapFilter : public ConnectionFilter {
@@ -321,7 +327,7 @@ ChildThreadImpl::Options::Builder::InBrowserProcess(
const InProcessChildThreadParams& params) {
options_.browser_process_io_runner = params.io_runner();
options_.in_process_service_request_token = params.service_request_token();
- options_.broker_client_invitation = params.broker_client_invitation();
+ options_.mojo_invitation = params.mojo_invitation();
return *this;
}
@@ -419,8 +425,7 @@ void ChildThreadImpl::OnFieldTrialGroupFinalized(
field_trial_recorder->FieldTrialActivated(trial_name);
}
-void ChildThreadImpl::ConnectChannel(
- mojo::edk::IncomingBrokerClientInvitation* invitation) {
+void ChildThreadImpl::ConnectChannel() {
DCHECK(service_manager_connection_);
IPC::mojom::ChannelBootstrapPtr bootstrap;
mojo::ScopedMessagePipeHandle handle =
@@ -457,12 +462,12 @@ void ChildThreadImpl::Init(const Options& options) {
IPC::Logging::GetInstance()->SetIPCSender(this);
#endif
- std::unique_ptr<mojo::edk::IncomingBrokerClientInvitation> invitation;
mojo::ScopedMessagePipeHandle service_request_pipe;
if (!IsInBrowserProcess()) {
- mojo_ipc_support_.reset(new mojo::edk::ScopedIPCSupport(
- GetIOTaskRunner(), mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST));
- invitation = InitializeMojoIPCChannel();
+ mojo_ipc_support_.reset(new mojo::core::ScopedIPCSupport(
+ GetIOTaskRunner(), mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST));
+ base::Optional<mojo::IncomingInvitation> invitation =
+ InitializeMojoIPCChannel();
std::string service_request_token =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
@@ -472,9 +477,8 @@ void ChildThreadImpl::Init(const Options& options) {
invitation->ExtractMessagePipe(service_request_token);
}
} else {
- service_request_pipe =
- options.broker_client_invitation->ExtractInProcessMessagePipe(
- options.in_process_service_request_token);
+ service_request_pipe = options.mojo_invitation->ExtractMessagePipe(
+ options.in_process_service_request_token);
}
if (service_request_pipe.is_valid()) {
@@ -551,7 +555,7 @@ void ChildThreadImpl::Init(const Options& options) {
channel_->AddFilter(startup_filter);
}
- ConnectChannel(invitation.get());
+ ConnectChannel();
// This must always be done after ConnectChannel, because ConnectChannel() may
// add a ConnectionFilter to the connection.
@@ -588,6 +592,20 @@ void ChildThreadImpl::Init(const Options& options) {
field_trial_syncer_->InitFieldTrialObserving(
*base::CommandLine::ForCurrentProcess());
}
+
+ if (base::FeatureList::IsEnabled(features::kMemoryCoordinator)) {
+ // Disable MemoryPressureListener when memory coordinator is enabled.
+ base::MemoryPressureListener::SetNotificationsSuppressed(true);
+
+ // TODO(bashi): Revisit how to manage the lifetime of
+ // ChildMemoryCoordinatorImpl.
+ // https://codereview.chromium.org/2094583002/#msg52
+ mojom::MemoryCoordinatorHandlePtr parent_coordinator;
+ GetConnector()->BindInterface(mojom::kBrowserServiceName,
+ mojo::MakeRequest(&parent_coordinator));
+ memory_coordinator_ =
+ CreateChildMemoryCoordinator(std::move(parent_coordinator), this);
+ }
}
void ChildThreadImpl::InitTracing() {
diff --git a/chromium/content/child/child_thread_impl.h b/chromium/content/child/child_thread_impl.h
index 9f4155dfdcf..d44813ed642 100644
--- a/chromium/content/child/child_thread_impl.h
+++ b/chromium/content/child/child_thread_impl.h
@@ -20,6 +20,7 @@
#include "base/single_thread_task_runner.h"
#include "build/build_config.h"
#include "components/variations/child_process_field_trial_syncer.h"
+#include "content/child/memory/child_memory_coordinator_impl.h"
#include "content/common/associated_interfaces.mojom.h"
#include "content/common/child_control.mojom.h"
#include "content/common/content_export.h"
@@ -45,11 +46,10 @@ class SyncMessageFilter;
} // namespace IPC
namespace mojo {
-namespace edk {
-class IncomingBrokerClientInvitation;
-class OutgoingBrokerClientInvitation;
+class OutgoingInvitation;
+namespace core {
class ScopedIPCSupport;
-} // namespace edk
+} // namespace core
} // namespace mojo
namespace content {
@@ -61,6 +61,7 @@ class CONTENT_EXPORT ChildThreadImpl
: public IPC::Listener,
virtual public ChildThread,
private base::FieldTrialList::Observer,
+ public ChildMemoryCoordinatorDelegate,
public mojom::RouteProvider,
public mojom::AssociatedInterfaceProvider,
public mojom::ChildControl {
@@ -107,6 +108,9 @@ class CONTENT_EXPORT ChildThreadImpl
void OnFieldTrialGroupFinalized(const std::string& trial_name,
const std::string& group_name) override;
+ // ChildMemoryCoordinatorDelegate implementation.
+ void OnTrimMemoryImmediately() override {}
+
IPC::SyncChannel* channel() { return channel_.get(); }
IPC::MessageRouter* GetRouter();
@@ -198,7 +202,7 @@ class CONTENT_EXPORT ChildThreadImpl
// 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);
+ void ConnectChannel();
// IPC message handlers.
@@ -218,7 +222,7 @@ class CONTENT_EXPORT ChildThreadImpl
mojom::FontCacheWin* GetFontCacheWin();
#endif
- std::unique_ptr<mojo::edk::ScopedIPCSupport> mojo_ipc_support_;
+ std::unique_ptr<mojo::core::ScopedIPCSupport> mojo_ipc_support_;
std::unique_ptr<ServiceManagerConnection> service_manager_connection_;
mojo::BindingSet<mojom::ChildControl> child_control_bindings_;
@@ -258,6 +262,8 @@ class CONTENT_EXPORT ChildThreadImpl
std::unique_ptr<variations::ChildProcessFieldTrialSyncer> field_trial_syncer_;
+ std::unique_ptr<ChildMemoryCoordinatorImpl> memory_coordinator_;
+
std::unique_ptr<base::WeakPtrFactory<ChildThreadImpl>>
channel_connected_factory_;
@@ -278,7 +284,7 @@ struct ChildThreadImpl::Options {
bool connect_to_browser;
scoped_refptr<base::SingleThreadTaskRunner> browser_process_io_runner;
std::vector<IPC::MessageFilter*> startup_filters;
- mojo::edk::OutgoingBrokerClientInvitation* broker_client_invitation;
+ mojo::OutgoingInvitation* mojo_invitation;
std::string in_process_service_request_token;
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner;
diff --git a/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc b/chromium/content/child/dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc
index 6f8be2d2672..a6cd064c079 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
@@ -17,7 +17,7 @@
#include "content/public/common/service_names.mojom.h"
#include "skia/ext/fontmgr_default_win.h"
#include "third_party/blink/public/web/win/web_font_rendering.h"
-#include "third_party/skia/include/ports/SkFontMgr.h"
+#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/ports/SkTypeface_win.h"
namespace mswr = Microsoft::WRL;
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 39951d3d095..80396e7ce1e 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
@@ -101,7 +101,8 @@ HRESULT DWriteFontCollectionProxy::FindFamilyName(const WCHAR* family_name,
return S_OK;
}
- if (!GetFontProxy().FindFamily(name, &family_index)) {
+ if (!GetFontProxyScopeWrapper().GetFontProxy().FindFamily(name,
+ &family_index)) {
LogFontProxyError(FIND_FAMILY_SEND_FAILED);
return E_FAIL;
}
@@ -145,7 +146,8 @@ UINT32 DWriteFontCollectionProxy::GetFontFamilyCount() {
TRACE_EVENT0("dwrite", "FontProxy::GetFontFamilyCount");
uint32_t family_count = 0;
- if (!GetFontProxy().GetFamilyCount(&family_count)) {
+ if (!GetFontProxyScopeWrapper().GetFontProxy().GetFamilyCount(
+ &family_count)) {
LogFontProxyError(GET_FAMILY_COUNT_SEND_FAILED);
return 0;
}
@@ -197,7 +199,8 @@ HRESULT DWriteFontCollectionProxy::CreateEnumeratorFromKey(
std::vector<base::FilePath> file_names;
std::vector<base::File> file_handles;
- if (!GetFontProxy().GetFontFiles(*family_index, &file_names, &file_handles)) {
+ if (!GetFontProxyScopeWrapper().GetFontProxy().GetFontFiles(
+ *family_index, &file_names, &file_handles)) {
LogFontProxyError(GET_FONT_FILES_SEND_FAILED);
return E_FAIL;
}
@@ -318,7 +321,8 @@ bool DWriteFontCollectionProxy::LoadFamilyNames(
TRACE_EVENT0("dwrite", "FontProxy::LoadFamilyNames");
std::vector<mojom::DWriteStringPairPtr> pairs;
- if (!GetFontProxy().GetFamilyNames(family_index, &pairs)) {
+ if (!GetFontProxyScopeWrapper().GetFontProxy().GetFamilyNames(family_index,
+ &pairs)) {
return false;
}
std::vector<std::pair<base::string16, base::string16>> strings;
@@ -360,7 +364,7 @@ void DWriteFontCollectionProxy::SetProxy(mojom::DWriteFontProxyPtrInfo proxy) {
{base::WithBaseSyncPrimitives()}));
}
-mojom::DWriteFontProxy& DWriteFontCollectionProxy::GetFontProxy() {
+FontProxyScopeWrapper DWriteFontCollectionProxy::GetFontProxyScopeWrapper() {
if (!font_proxy_) {
mojom::DWriteFontProxyPtrInfo dwrite_font_proxy;
if (main_task_runner_->RunsTasksInCurrentSequence()) {
@@ -377,7 +381,9 @@ mojom::DWriteFontProxy& DWriteFontCollectionProxy::GetFontProxy() {
}
SetProxy(std::move(dwrite_font_proxy));
}
- return **font_proxy_;
+ static base::ThreadLocalBoolean font_proxy_method_in_flight;
+
+ return FontProxyScopeWrapper(font_proxy_.get(), &font_proxy_method_in_flight);
}
DWriteFontFamilyProxy::DWriteFontFamilyProxy() = 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 0943acd7dbb..63f66d27338 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
@@ -22,6 +22,39 @@ namespace content {
class DWriteFontFamilyProxy;
+class FontProxyScopeWrapper {
+ public:
+ FontProxyScopeWrapper(mojom::ThreadSafeDWriteFontProxyPtr* font_proxy,
+ base::ThreadLocalBoolean* is_in_flight)
+ : font_proxy_(font_proxy), is_in_flight_(is_in_flight) {
+ // TODO(crbug.com/561873): Turn this into a DCHECK once instances of this
+ // CHECK have been found in crash reports and the referenced bug has been
+ // root-caused.
+ CHECK(!is_in_flight_->Get());
+ is_in_flight_->Set(true);
+ }
+
+ ~FontProxyScopeWrapper() {
+ // TODO(crbug.com/561873): Turn this into a DCHECK once instances of this
+ // CHECK have been found in crash reports and the referenced bug has been
+ // root-caused.
+ CHECK(is_in_flight_->Get());
+ is_in_flight_->Set(false);
+ }
+
+ content::mojom::DWriteFontProxy& GetFontProxy() const {
+ return **font_proxy_;
+ }
+
+ FontProxyScopeWrapper(FontProxyScopeWrapper&&) = default;
+ FontProxyScopeWrapper& operator=(FontProxyScopeWrapper&&) = default;
+
+ private:
+ mojom::ThreadSafeDWriteFontProxyPtr* font_proxy_;
+ base::ThreadLocalBoolean* is_in_flight_;
+ DISALLOW_COPY_AND_ASSIGN(FontProxyScopeWrapper);
+};
+
// Implements a DirectWrite font collection that uses IPC to the browser to do
// font enumeration. If a matching family is found, it will be loaded locally
// into a custom font collection.
@@ -87,7 +120,7 @@ class DWriteFontCollectionProxy
bool CreateFamily(UINT32 family_index);
- mojom::DWriteFontProxy& GetFontProxy();
+ FontProxyScopeWrapper GetFontProxyScopeWrapper();
private:
void SetProxy(mojom::DWriteFontProxyPtrInfo);
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 25dbef9815e..95c5b9fc5e6 100644
--- a/chromium/content/child/dwrite_font_proxy/font_fallback_win.cc
+++ b/chromium/content/child/dwrite_font_proxy/font_fallback_win.cc
@@ -100,7 +100,7 @@ HRESULT FontFallback::MapCharacters(IDWriteTextAnalysisSource* source,
mojom::MapCharactersResultPtr result;
- if (!GetFontProxy().MapCharacters(
+ if (!GetFontProxyScopeWrapper().GetFontProxy().MapCharacters(
text_chunk,
mojom::DWriteFontStyle::New(base_weight, base_style, base_stretch),
locale, source->GetParagraphReadingDirection(), base_family_name,
@@ -222,8 +222,8 @@ void FontFallback::AddCachedFamily(
family_list.pop_back();
}
-mojom::DWriteFontProxy& FontFallback::GetFontProxy() {
- return collection_->GetFontProxy();
+FontProxyScopeWrapper FontFallback::GetFontProxyScopeWrapper() {
+ return collection_->GetFontProxyScopeWrapper();
}
} // namespace content
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 ca22abc69e9..072420351cc 100644
--- a/chromium/content/child/dwrite_font_proxy/font_fallback_win.h
+++ b/chromium/content/child/dwrite_font_proxy/font_fallback_win.h
@@ -65,7 +65,7 @@ class FontFallback
const wchar_t* base_family_name);
private:
- mojom::DWriteFontProxy& GetFontProxy();
+ FontProxyScopeWrapper GetFontProxyScopeWrapper();
Microsoft::WRL::ComPtr<DWriteFontCollectionProxy> collection_;
diff --git a/chromium/content/child/font_warmup_win.cc b/chromium/content/child/font_warmup_win.cc
index d9e98c1f790..be505c8e79d 100644
--- a/chromium/content/child/font_warmup_win.cc
+++ b/chromium/content/child/font_warmup_win.cc
@@ -25,8 +25,8 @@
#include "build/build_config.h"
#include "ppapi/buildflags/buildflags.h"
#include "skia/ext/fontmgr_default_win.h"
+#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkRefCnt.h"
-#include "third_party/skia/include/ports/SkFontMgr.h"
#include "third_party/skia/include/ports/SkTypeface_win.h"
#if BUILDFLAG(ENABLE_PLUGINS)
diff --git a/chromium/content/child/font_warmup_win_unittest.cc b/chromium/content/child/font_warmup_win_unittest.cc
index 9065ae030a7..0dea002d4fc 100644
--- a/chromium/content/child/font_warmup_win_unittest.cc
+++ b/chromium/content/child/font_warmup_win_unittest.cc
@@ -16,11 +16,11 @@
#include "base/sys_byteorder.h"
#include "base/win/windows_version.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkString.h"
#include "third_party/skia/include/core/SkTypeface.h"
-#include "third_party/skia/include/ports/SkFontMgr.h"
namespace content {
diff --git a/chromium/content/child/image_decoder.cc b/chromium/content/child/image_decoder.cc
index b4d7b3ca6d4..0363147ebef 100644
--- a/chromium/content/child/image_decoder.cc
+++ b/chromium/content/child/image_decoder.cc
@@ -33,20 +33,16 @@ ImageDecoder::~ImageDecoder() {
}
SkBitmap ImageDecoder::Decode(const unsigned char* data, size_t size) const {
- const WebImage& image = WebImage::FromData(
- WebData(reinterpret_cast<const char*>(data), size), desired_icon_size_);
- return image.GetSkBitmap();
+ return WebImage::FromData(WebData(reinterpret_cast<const char*>(data), size),
+ desired_icon_size_);
}
// static
std::vector<SkBitmap> ImageDecoder::DecodeAll(
const unsigned char* data, size_t size) {
- const blink::WebVector<WebImage>& images = WebImage::FramesFromData(
- WebData(reinterpret_cast<const char*>(data), size));
- std::vector<SkBitmap> result;
- for (size_t i = 0; i < images.size(); ++i)
- result.push_back(images[i].GetSkBitmap());
- return result;
+ return WebImage::FramesFromData(
+ WebData(reinterpret_cast<const char*>(data), size))
+ .ReleaseVector();
}
} // namespace content
diff --git a/chromium/content/child/runtime_features.cc b/chromium/content/child/runtime_features.cc
index e999f7b68a5..d82d7efe02f 100644
--- a/chromium/content/child/runtime_features.cc
+++ b/chromium/content/child/runtime_features.cc
@@ -18,6 +18,7 @@
#include "media/base/media_switches.h"
#include "services/device/public/cpp/device_features.h"
#include "services/network/public/cpp/features.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "ui/gfx/switches.h"
#include "ui/gl/gl_switches.h"
@@ -51,6 +52,7 @@ static void SetRuntimeFeatureDefaultsForPlatform() {
WebRuntimeFeatures::EnableMediaSession(true);
WebRuntimeFeatures::EnableMediaControlsOverlayPlayButton(true);
WebRuntimeFeatures::EnableRemotePlaybackBackend(true);
+ WebRuntimeFeatures::EnablePictureInPictureAPI(false);
#else // defined(OS_ANDROID)
WebRuntimeFeatures::EnableNavigatorContentUtils(true);
// Tracking bug for the implementation: https://crbug.com/728609
@@ -101,6 +103,12 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
if (!base::FeatureList::IsEnabled(features::kWebUsb))
WebRuntimeFeatures::EnableWebUsb(false);
+ if (base::FeatureList::IsEnabled(features::kBlinkHeapIncrementalMarking))
+ WebRuntimeFeatures::EnableBlinkHeapIncrementalMarking(true);
+
+ if (base::FeatureList::IsEnabled(features::kBloatedRendererDetection))
+ WebRuntimeFeatures::EnableBloatedRendererDetection(true);
+
if (command_line.HasSwitch(switches::kDisableDatabases))
WebRuntimeFeatures::EnableDatabase(false);
@@ -118,7 +126,8 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
base::FeatureList::IsEnabled(features::kWebAssemblyStreaming));
WebRuntimeFeatures::EnableSharedArrayBuffer(
- base::FeatureList::IsEnabled(features::kSharedArrayBuffer));
+ base::FeatureList::IsEnabled(features::kSharedArrayBuffer) ||
+ base::FeatureList::IsEnabled(features::kWebAssemblyThreads));
if (command_line.HasSwitch(switches::kDisableSharedWorkers))
WebRuntimeFeatures::EnableSharedWorker(false);
@@ -132,6 +141,12 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
if (!command_line.HasSwitch(switches::kDisableAcceleratedJpegDecoding))
WebRuntimeFeatures::EnableDecodeToYUV(true);
+#if defined(SUPPORT_WEBGL2_COMPUTE_CONTEXT)
+ if (command_line.HasSwitch(switches::kEnableWebGL2ComputeContext)) {
+ WebRuntimeFeatures::EnableWebGL2ComputeContext(true);
+ }
+#endif
+
if (command_line.HasSwitch(switches::kEnableWebGLDraftExtensions))
WebRuntimeFeatures::EnableWebGLDraftExtensions(true);
@@ -147,8 +162,13 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
!command_line.HasSwitch(switches::kDisable2dCanvasImageChromium) &&
!command_line.HasSwitch(switches::kDisableGpu) &&
base::FeatureList::IsEnabled(features::kCanvas2DImageChromium);
+#elif defined(OS_CHROMEOS)
+ const bool enable_canvas_2d_image_chromium =
+ !command_line.HasSwitch(switches::kDisable2dCanvasImageChromium) &&
+ !command_line.HasSwitch(switches::kDisableGpu) &&
+ base::FeatureList::IsEnabled(features::kCanvas2DImageChromium);
#else
- bool enable_canvas_2d_image_chromium = false;
+ constexpr bool enable_canvas_2d_image_chromium = false;
#endif
WebRuntimeFeatures::EnableCanvas2dImageChromium(
enable_canvas_2d_image_chromium);
@@ -189,10 +209,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
if (command_line.HasSwitch(switches::kReducedReferrerGranularity))
WebRuntimeFeatures::EnableReducedReferrerGranularity(true);
- WebRuntimeFeatures::EnableIntersectionObserverGeometryMapper(
- base::FeatureList::IsEnabled(
- features::kIntersectionObserverGeometryMapper));
-
if (command_line.HasSwitch(switches::kDisablePermissionsAPI))
WebRuntimeFeatures::EnablePermissionsAPI(false);
@@ -201,6 +217,9 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
else
WebRuntimeFeatures::EnableV8IdleTasks(true);
+ if (command_line.HasSwitch(switches::kEnableUnsafeWebGPU))
+ WebRuntimeFeatures::EnableWebGPU(true);
+
if (command_line.HasSwitch(switches::kEnableWebVR))
WebRuntimeFeatures::EnableWebVR(true);
@@ -230,12 +249,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnableScrollAnchorSerialization(true);
WebRuntimeFeatures::EnableFeatureFromString(
- "SlimmingPaintV175",
- base::FeatureList::IsEnabled(features::kSlimmingPaintV175) ||
- command_line.HasSwitch(switches::kEnableSlimmingPaintV175) ||
- enableExperimentalWebPlatformFeatures);
-
- WebRuntimeFeatures::EnableFeatureFromString(
"BlinkGenPropertyTrees",
command_line.HasSwitch(switches::kEnableBlinkGenPropertyTrees));
@@ -273,9 +286,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnableTimerThrottlingForHiddenFrames(
base::FeatureList::IsEnabled(features::kTimerThrottlingForHiddenFrames));
- WebRuntimeFeatures::EnableTouchpadAndWheelScrollLatching(
- base::FeatureList::IsEnabled(features::kTouchpadAndWheelScrollLatching));
-
if (base::FeatureList::IsEnabled(
features::kSendBeaconThrowForBlobWithNonSimpleType))
WebRuntimeFeatures::EnableSendBeaconThrowForBlobWithNonSimpleType(true);
@@ -298,9 +308,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnableNetworkService(
base::FeatureList::IsEnabled(network::features::kNetworkService));
- WebRuntimeFeatures::EnableMojoBlobURLs(
- base::FeatureList::IsEnabled(network::features::kNetworkService));
-
if (base::FeatureList::IsEnabled(features::kGamepadExtensions))
WebRuntimeFeatures::EnableGamepadExtensions(true);
@@ -317,17 +324,20 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
if (base::FeatureList::IsEnabled(features::kCompositorTouchAction))
WebRuntimeFeatures::EnableCompositorTouchAction(true);
- if (base::FeatureList::IsEnabled(features::kGenericSensor)) {
- WebRuntimeFeatures::EnableGenericSensor(true);
- if (base::FeatureList::IsEnabled(features::kGenericSensorExtraClasses))
- WebRuntimeFeatures::EnableGenericSensorExtraClasses(true);
- }
+ if (base::FeatureList::IsEnabled(features::kCSSFragmentIdentifiers))
+ WebRuntimeFeatures::EnableCSSFragmentIdentifiers(true);
+
+ if (!base::FeatureList::IsEnabled(features::kGenericSensor))
+ WebRuntimeFeatures::EnableGenericSensor(false);
+
+ if (base::FeatureList::IsEnabled(features::kGenericSensorExtraClasses))
+ WebRuntimeFeatures::EnableGenericSensorExtraClasses(true);
if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCORS))
WebRuntimeFeatures::EnableOutOfBlinkCORS(true);
- if (base::FeatureList::IsEnabled(features::kOriginManifest))
- WebRuntimeFeatures::EnableOriginManifest(true);
+ if (base::FeatureList::IsEnabled(features::kOriginPolicy))
+ WebRuntimeFeatures::EnableOriginPolicy(true);
WebRuntimeFeatures::EnableMediaCastOverlayButton(
base::FeatureList::IsEnabled(media::kMediaCastOverlayButton));
@@ -368,6 +378,9 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
if (base::FeatureList::IsEnabled(features::kLayeredAPI))
WebRuntimeFeatures::EnableLayeredAPI(true);
+ if (base::FeatureList::IsEnabled(blink::features::kLayoutNG))
+ WebRuntimeFeatures::EnableLayoutNG(true);
+
WebRuntimeFeatures::EnableLazyInitializeMediaControls(
base::FeatureList::IsEnabled(features::kLazyInitializeMediaControls));
@@ -397,11 +410,10 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
"FeaturePolicyForPermissions",
base::FeatureList::IsEnabled(features::kUseFeaturePolicyForPermissions));
- if (base::FeatureList::IsEnabled(features::kKeyboardLockAPI))
- WebRuntimeFeatures::EnableFeatureFromString("KeyboardLock", true);
-
if (base::FeatureList::IsEnabled(features::kLazyFrameLoading))
WebRuntimeFeatures::EnableLazyFrameLoading(true);
+ if (base::FeatureList::IsEnabled(features::kLazyFrameVisibleLoadTimeMetrics))
+ WebRuntimeFeatures::EnableLazyFrameVisibleLoadTimeMetrics(true);
WebRuntimeFeatures::EnableV8ContextSnapshot(
base::FeatureList::IsEnabled(features::kV8ContextSnapshot));
@@ -409,9 +421,6 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
if (base::FeatureList::IsEnabled(features::kStopInBackground))
WebRuntimeFeatures::EnableStopInBackground(true);
- if (base::FeatureList::IsEnabled(features::kStopLoadingInBackground))
- WebRuntimeFeatures::EnableStopLoadingInBackground(true);
-
if (base::FeatureList::IsEnabled(features::kStopNonTimersInBackground))
WebRuntimeFeatures::EnableStopNonTimersInBackground(true);
@@ -434,16 +443,25 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnableOffMainThreadWebSocket(
base::FeatureList::IsEnabled(features::kOffMainThreadWebSocket));
+ WebRuntimeFeatures::EnableNestedWorkers(
+ base::FeatureList::IsEnabled(blink::features::kNestedWorkers));
+
if (base::FeatureList::IsEnabled(
features::kExperimentalProductivityFeatures)) {
WebRuntimeFeatures::EnableExperimentalProductivityFeatures(true);
}
+ if (base::FeatureList::IsEnabled(features::kPageLifecycle))
+ WebRuntimeFeatures::EnablePageLifecycle(true);
+
#if defined(OS_ANDROID)
if (base::FeatureList::IsEnabled(features::kDisplayCutoutAPI))
- WebRuntimeFeatures::EnableDisplayCutoutViewportFit(true);
+ WebRuntimeFeatures::EnableDisplayCutoutAPI(true);
#endif
+ if (command_line.HasSwitch(switches::kEnableAccessibilityObjectModel))
+ WebRuntimeFeatures::EnableAccessibilityObjectModel(true);
+
// End individual features.
// Do not add individual features below this line.
@@ -455,6 +473,11 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnableAutoplayIgnoresWebAudio(
base::FeatureList::IsEnabled(media::kAutoplayIgnoreWebAudio));
+#if defined(OS_ANDROID)
+ WebRuntimeFeatures::EnableMediaControlsExpandGesture(
+ base::FeatureList::IsEnabled(media::kMediaControlsExpandGesture));
+#endif
+
// Enable explicitly enabled features, and then disable explicitly disabled
// ones.
for (const std::string& feature :
diff --git a/chromium/content/child/scoped_web_callbacks.h b/chromium/content/child/scoped_web_callbacks.h
deleted file mode 100644
index 725548f7784..00000000000
--- a/chromium/content/child/scoped_web_callbacks.h
+++ /dev/null
@@ -1,112 +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_CHILD_SCOPED_WEB_CALLBACKS_H_
-#define CONTENT_CHILD_SCOPED_WEB_CALLBACKS_H_
-
-#include <memory>
-#include <utility>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "third_party/blink/public/platform/web_callbacks.h"
-
-// A ScopedWebCallbacks is a move-only scoper which helps manage the lifetime of
-// a blink::WebCallbacks object. This is particularly useful when you're
-// simultaneously dealing with the following two conditions:
-//
-// 1. Your WebCallbacks implementation requires either onSuccess or onError to
-// be called before it's destroyed. This is the case with
-// CallbackPromiseAdapter for example, because its underlying
-// ScriptPromiseResolver must be resolved or rejected before destruction.
-//
-// 2. You are passing ownership of the WebCallbacks to code which may
-// silenty drop it. A common way for this to happen is to bind the
-// WebCallbacks as an argument to a base::Callback which gets destroyed
-// before it can run.
-//
-// While it's possible to individually track the lifetime of pending
-// WebCallbacks, this becomes cumbersome when dealing with many different
-// callbacks types. ScopedWebCallbacks provides a generic and relatively
-// lightweight solution to this problem.
-//
-// Example usage:
-//
-// using FooCallbacks = blink::WebCallbacks<const Foo&, const FooError&>;
-//
-// void RespondWithSuccess(ScopedWebCallbacks<FooCallbacks> callbacks) {
-// callbacks.PassCallbacks()->onSuccess(Foo("everything is great"));
-// }
-//
-// void OnCallbacksDropped(std::unique_ptr<FooCallbacks> callbacks) {
-// // Ownership of the FooCallbacks is passed to this function if
-// // ScopedWebCallbacks::PassCallbacks isn't called before the
-// // ScopedWebCallbacks is destroyed.
-// callbacks->onError(FooError("everything is terrible"));
-// }
-//
-// // Blink client implementation
-// void FooClientImpl::doMagic(FooCallbacks* callbacks) {
-// auto scoped_callbacks = make_scoped_web_callbacks(
-// callbacks, base::Bind(&OnCallbacksDropped));
-//
-// // Call to some lower-level service which may never run the callback we
-// // give it.
-// foo_service_->DoMagic(base::Bind(&RespondWithSuccess,
-// base::Passed(&scoped_callbacks)));
-// }
-//
-// If the bound RespondWithSuccess callback actually runs, PassCallbacks() will
-// reliquish ownership of the WebCallbacks object to a temporary scoped_ptr
-// which will be destroyed immediately after onSuccess is called.
-//
-// If the bound RespondWithSuccess callback is instead destroyed first,
-// the ScopedWebCallbacks destructor will invoke OnCallbacksDropped, executing
-// our desired default behavior before deleting the WebCallbacks.
-template <typename CallbacksType>
-class ScopedWebCallbacks {
- public:
- using DestructionCallback =
- base::Callback<void(std::unique_ptr<CallbacksType> callbacks)>;
-
- ScopedWebCallbacks(std::unique_ptr<CallbacksType> callbacks,
- const DestructionCallback& destruction_callback)
- : callbacks_(std::move(callbacks)),
- destruction_callback_(destruction_callback) {}
-
- ~ScopedWebCallbacks() {
- if (callbacks_)
- destruction_callback_.Run(std::move(callbacks_));
- }
-
- ScopedWebCallbacks(ScopedWebCallbacks&& other) { *this = std::move(other); }
-
- ScopedWebCallbacks& operator=(ScopedWebCallbacks&& other) {
- callbacks_ = std::move(other.callbacks_);
- destruction_callback_ = other.destruction_callback_;
- return *this;
- }
-
- std::unique_ptr<CallbacksType> PassCallbacks() {
- return std::move(callbacks_);
- }
-
- private:
- std::unique_ptr<CallbacksType> callbacks_;
- DestructionCallback destruction_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedWebCallbacks);
-};
-
-template <typename CallbacksType>
-ScopedWebCallbacks<CallbacksType> make_scoped_web_callbacks(
- CallbacksType* callbacks,
- const typename ScopedWebCallbacks<CallbacksType>::DestructionCallback&
- destruction_callback) {
- return ScopedWebCallbacks<CallbacksType>(base::WrapUnique(callbacks),
- destruction_callback);
-}
-
-#endif // CONTENT_CHILD_SCOPED_WEB_CALLBACKS_H_
diff --git a/chromium/content/child/webthemeengine_impl_android.cc b/chromium/content/child/webthemeengine_impl_android.cc
index 6b14c3e23d7..74efb5d67fe 100644
--- a/chromium/content/child/webthemeengine_impl_android.cc
+++ b/chromium/content/child/webthemeengine_impl_android.cc
@@ -11,7 +11,6 @@
#include "third_party/blink/public/platform/web_size.h"
#include "ui/native_theme/native_theme.h"
-using blink::WebCanvas;
using blink::WebRect;
using blink::WebThemeEngine;
@@ -190,8 +189,8 @@ void WebThemeEngineImpl::GetOverlayScrollbarStyle(ScrollbarStyle* style) {
// currently fade out so the fadeOutDuration and Delay Now that this has
// been added into Blink for other platforms we should plumb that through for
// Android as well.
- style->fade_out_delay_seconds = 0;
- style->fade_out_duration_seconds = 0;
+ style->fade_out_delay = base::TimeDelta();
+ style->fade_out_duration = base::TimeDelta();
if (getMajorVersion() >= kVersionLollipop) {
style->thumb_thickness = 4;
style->scrollbar_margin = 0;
@@ -204,7 +203,7 @@ void WebThemeEngineImpl::GetOverlayScrollbarStyle(ScrollbarStyle* style) {
}
void WebThemeEngineImpl::Paint(
- blink::WebCanvas* canvas,
+ cc::PaintCanvas* canvas,
WebThemeEngine::Part part,
WebThemeEngine::State state,
const blink::WebRect& rect,
diff --git a/chromium/content/child/webthemeengine_impl_android.h b/chromium/content/child/webthemeengine_impl_android.h
index b17b2d63cdb..ede02ba2aea 100644
--- a/chromium/content/child/webthemeengine_impl_android.h
+++ b/chromium/content/child/webthemeengine_impl_android.h
@@ -15,7 +15,7 @@ class WebThemeEngineImpl : public blink::WebThemeEngine {
blink::WebSize GetSize(blink::WebThemeEngine::Part) override;
void GetOverlayScrollbarStyle(
blink::WebThemeEngine::ScrollbarStyle*) override;
- void Paint(blink::WebCanvas* canvas,
+ void Paint(cc::PaintCanvas* canvas,
blink::WebThemeEngine::Part part,
blink::WebThemeEngine::State state,
const blink::WebRect& rect,
diff --git a/chromium/content/child/webthemeengine_impl_default.cc b/chromium/content/child/webthemeengine_impl_default.cc
index 13e0a6278c9..ecda4fe4b12 100644
--- a/chromium/content/child/webthemeengine_impl_default.cc
+++ b/chromium/content/child/webthemeengine_impl_default.cc
@@ -11,7 +11,6 @@
#include "ui/native_theme/native_theme.h"
#include "ui/native_theme/overlay_scrollbar_constants_aura.h"
-using blink::WebCanvas;
using blink::WebRect;
using blink::WebThemeEngine;
using blink::WebScrollbarOverlayColorTheme;
@@ -230,7 +229,7 @@ blink::WebSize WebThemeEngineImpl::GetSize(WebThemeEngine::Part part) {
}
void WebThemeEngineImpl::Paint(
- blink::WebCanvas* canvas,
+ cc::PaintCanvas* canvas,
WebThemeEngine::Part part,
WebThemeEngine::State state,
const blink::WebRect& rect,
@@ -244,9 +243,8 @@ void WebThemeEngineImpl::Paint(
}
void WebThemeEngineImpl::GetOverlayScrollbarStyle(ScrollbarStyle* style) {
- style->fade_out_delay_seconds = ui::kOverlayScrollbarFadeDelay.InSecondsF();
- style->fade_out_duration_seconds =
- ui::kOverlayScrollbarFadeDuration.InSecondsF();
+ style->fade_out_delay = ui::kOverlayScrollbarFadeDelay;
+ style->fade_out_duration = ui::kOverlayScrollbarFadeDuration;
// The other fields in this struct are used only on Android to draw solid
// color scrollbars. On other platforms the scrollbars are painted in
// NativeTheme so these fields are unused.
diff --git a/chromium/content/child/webthemeengine_impl_default.h b/chromium/content/child/webthemeengine_impl_default.h
index d3ae6ab2309..421c5f12de9 100644
--- a/chromium/content/child/webthemeengine_impl_default.h
+++ b/chromium/content/child/webthemeengine_impl_default.h
@@ -16,7 +16,7 @@ class WebThemeEngineImpl : public blink::WebThemeEngine {
public:
// WebThemeEngine methods:
blink::WebSize GetSize(blink::WebThemeEngine::Part) override;
- void Paint(blink::WebCanvas* canvas,
+ void Paint(cc::PaintCanvas* canvas,
blink::WebThemeEngine::Part part,
blink::WebThemeEngine::State state,
const blink::WebRect& rect,
diff --git a/chromium/content/common/BUILD.gn b/chromium/content/common/BUILD.gn
index de4c4d2af49..d02f2ea18aa 100644
--- a/chromium/content/common/BUILD.gn
+++ b/chromium/content/common/BUILD.gn
@@ -116,8 +116,6 @@ source_set("common") {
"fileapi/file_system_messages.h",
"fileapi/webblob_messages.h",
"font_cache_dispatcher_win.cc",
- "font_config_ipc_linux.cc",
- "font_config_ipc_linux.h",
"font_list.cc",
"font_list.h",
"font_list_android.cc",
@@ -195,8 +193,6 @@ source_set("common") {
"input_messages.h",
"inter_process_time_ticks_converter.cc",
"inter_process_time_ticks_converter.h",
- "layer_tree_settings_factory.cc",
- "layer_tree_settings_factory.h",
"mac/attributed_string_coder.h",
"mac/attributed_string_coder.mm",
"mac/font_loader.h",
@@ -213,14 +209,14 @@ source_set("common") {
"media/media_stream_param_traits.h",
"media/midi_messages.h",
"media/peer_connection_tracker_messages.h",
- "media/surface_view_manager_messages_android.h",
"media/video_capture.h",
"navigation_gesture.h",
"navigation_params.cc",
"navigation_params.h",
"navigation_subresource_loader_params.cc",
"navigation_subresource_loader_params.h",
- "net/url_fetcher.cc",
+ "net/record_load_histograms.cc",
+ "net/record_load_histograms.h",
"net/url_request_service_worker_data.cc",
"net/url_request_service_worker_data.h",
"net/url_request_user_data.cc",
@@ -230,7 +226,6 @@ source_set("common") {
"origin_util.cc",
"p2p_messages.h",
"p2p_socket_type.h",
- "page_message_enums.h",
"page_messages.h",
"page_state_serialization.cc",
"page_state_serialization.h",
@@ -241,7 +236,7 @@ source_set("common") {
"pepper_plugin_list.h",
"pepper_renderer_instance_data.cc",
"pepper_renderer_instance_data.h",
- "platform_notification_messages.h",
+ "platform_notification_param_traits.h",
"plugin_list.cc",
"plugin_list.h",
"possibly_associated_interface_ptr.h",
@@ -264,18 +259,18 @@ source_set("common") {
"service_worker/service_worker_loader_helpers.cc",
"service_worker/service_worker_loader_helpers.h",
"service_worker/service_worker_messages.h",
- "service_worker/service_worker_provider_host_info.cc",
- "service_worker/service_worker_provider_host_info.h",
- "service_worker/service_worker_status_code.cc",
- "service_worker/service_worker_status_code.h",
"service_worker/service_worker_types.cc",
"service_worker/service_worker_types.h",
"service_worker/service_worker_utils.cc",
"service_worker/service_worker_utils.h",
"single_request_url_loader_factory.cc",
"single_request_url_loader_factory.h",
+ "skia_utils.cc",
+ "skia_utils.h",
"swapped_out_messages.cc",
"swapped_out_messages.h",
+ "tab_switching_time_callback.cc",
+ "tab_switching_time_callback.h",
"task_scheduler.cc",
"task_scheduler.h",
"text_input_client_messages.h",
@@ -336,7 +331,6 @@ source_set("common") {
"//gpu/command_buffer/service",
"//gpu/ipc/client",
"//gpu/ipc/common",
- "//gpu/ipc/common:gpu_preferences_util",
"//gpu/skia_bindings",
"//ipc",
"//media",
@@ -349,7 +343,6 @@ source_set("common") {
"//media/gpu/ipc/common",
"//media/midi",
"//media/midi:mojo",
- "//mojo/edk",
"//mojo/public/cpp/system",
"//net",
"//ppapi/buildflags",
@@ -494,7 +487,10 @@ source_set("common") {
"sandbox_policy_fuchsia.h",
]
- deps += [ "//third_party/fuchsia-sdk:launchpad" ]
+ deps += [
+ "//third_party/fuchsia-sdk:fdio",
+ "//third_party/fuchsia-sdk:fonts",
+ ]
}
}
@@ -538,7 +534,6 @@ mojom("mojo_bindings") {
"input/input_handler.mojom",
"input/input_injector.mojom",
"input/synchronous_compositor.mojom",
- "leveldb_wrapper.mojom",
"manifest_observer.mojom",
"media/media_stream.mojom",
"media/peer_connection_tracker.mojom",
@@ -546,6 +541,7 @@ mojom("mojo_bindings") {
"media/renderer_audio_output_stream_factory.mojom",
"memory_coordinator.mojom",
"native_types.mojom",
+ "navigation_client.mojom",
"navigation_params.mojom",
"page_state.mojom",
"push_messaging.mojom",
@@ -556,11 +552,9 @@ mojom("mojo_bindings") {
"renderer.mojom",
"renderer_host.mojom",
"service_worker/controller_service_worker.mojom",
- "service_worker/dispatch_fetch_event_params.mojom",
"service_worker/embedded_worker.mojom",
"service_worker/service_worker.mojom",
"service_worker/service_worker_container.mojom",
- "service_worker/service_worker_event_dispatcher.mojom",
"service_worker/service_worker_fetch_response_callback.mojom",
"service_worker/service_worker_provider.mojom",
"shared_worker/shared_worker.mojom",
@@ -569,8 +563,6 @@ mojom("mojo_bindings") {
"shared_worker/shared_worker_factory.mojom",
"shared_worker/shared_worker_host.mojom",
"shared_worker/shared_worker_info.mojom",
- "speech_recognizer.mojom",
- "storage_partition_service.mojom",
"url_loader_factory_bundle.mojom",
"widget.mojom",
]
@@ -580,7 +572,10 @@ mojom("mojo_bindings") {
}
if (is_mac) {
- sources += [ "font_loader_mac.mojom" ]
+ sources += [
+ "font_loader_mac.mojom",
+ "render_widget_host_ns_view.mojom",
+ ]
}
enabled_features = []
@@ -610,7 +605,7 @@ mojom("mojo_bindings") {
"//third_party/blink/public:mojo_bindings",
"//third_party/blink/public:web_feature_mojo_bindings",
"//third_party/blink/public/mojom:mojom_core",
- "//ui/base/mojo:mojo_bindings",
+ "//ui/base/mojo",
"//ui/events/mojo:interfaces",
"//ui/gfx/geometry/mojo",
"//ui/gfx/mojo",
diff --git a/chromium/content/common/DEPS b/chromium/content/common/DEPS
index c6649bd23f8..fb1b03bec74 100644
--- a/chromium/content/common/DEPS
+++ b/chromium/content/common/DEPS
@@ -65,8 +65,8 @@ include_rules = [
"+third_party/blink/public/platform/modules/push_messaging/web_push_error.h",
"+third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_availability.h",
"+third_party/blink/public/platform/modules/payments/WebPaymentAppRequest.h",
- "+third_party/blink/public/platform/modules/serviceworker/WebServiceWorkerClientType.h",
- "+third_party/blink/public/platform/modules/serviceworker/web_service_worker_error.h",
+ "+third_party/blink/public/platform/modules/service_worker/WebServiceWorkerClientType.h",
+ "+third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h",
"+third_party/blink/public/web/web_ax_enums.h",
"+third_party/blink/public/web/web_device_emulation_params.h",
"+third_party/blink/public/web/web_drag_status.h",
diff --git a/chromium/content/common/accessibility_messages.h b/chromium/content/common/accessibility_messages.h
index c97b2ae083f..827dd7a21df 100644
--- a/chromium/content/common/accessibility_messages.h
+++ b/chromium/content/common/accessibility_messages.h
@@ -17,6 +17,7 @@
#include "ipc/param_traits_macros.h"
#include "third_party/blink/public/web/web_ax_enums.h"
#include "ui/accessibility/ax_action_data.h"
+#include "ui/accessibility/ax_event.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_relative_bounds.h"
#include "ui/accessibility/ax_tree_update.h"
@@ -94,23 +95,15 @@ IPC_STRUCT_TRAITS_BEGIN(content::AXContentTreeUpdate)
IPC_STRUCT_TRAITS_MEMBER(node_id_to_clear)
IPC_STRUCT_TRAITS_MEMBER(root_id)
IPC_STRUCT_TRAITS_MEMBER(nodes)
+ IPC_STRUCT_TRAITS_MEMBER(event_from)
IPC_STRUCT_TRAITS_END()
-IPC_STRUCT_BEGIN(AccessibilityHostMsg_EventParams)
- // The tree update.
- IPC_STRUCT_MEMBER(content::AXContentTreeUpdate, update)
+IPC_STRUCT_BEGIN(AccessibilityHostMsg_EventBundleParams)
+ // Zero or more updates to the accessibility tree to apply first.
+ IPC_STRUCT_MEMBER(std::vector<content::AXContentTreeUpdate>, updates)
- // Type of event.
- IPC_STRUCT_MEMBER(ax::mojom::Event, event_type)
-
- // ID of the node that the event applies to.
- IPC_STRUCT_MEMBER(int, id)
-
- // The source of this event.
- IPC_STRUCT_MEMBER(ax::mojom::EventFrom, event_from)
-
- // ID of the action request triggering this event.
- IPC_STRUCT_MEMBER(int, action_request_id)
+ // Zero or more events to fire after the tree updates have been applied.
+ IPC_STRUCT_MEMBER(std::vector<ui::AXEvent>, events)
IPC_STRUCT_END()
IPC_STRUCT_BEGIN(AccessibilityHostMsg_LocationChangeParams)
@@ -160,11 +153,11 @@ IPC_MESSAGE_ROUTED3(AccessibilityMsg_HitTest,
ax::mojom::Event /* event to fire */,
int /* action request id */)
-// Tells the render view that a AccessibilityHostMsg_Events
-// message was processed and it can send additional events. The argument
-// must be the same as the ack_token passed to AccessibilityHostMsg_Events.
-IPC_MESSAGE_ROUTED1(AccessibilityMsg_Events_ACK,
- int /* ack_token */)
+// Tells the render view that a AccessibilityHostMsg_EventBundle
+// message was processed and it can send additional updates. The argument
+// must be the same as the ack_token passed to
+// AccessibilityHostMsg_EventBundle.
+IPC_MESSAGE_ROUTED1(AccessibilityMsg_EventBundle_ACK, int /* ack_token */)
// Tell the renderer to reset and send a new accessibility tree from
// scratch because the browser is out of sync. It passes a sequential
@@ -190,17 +183,16 @@ IPC_MESSAGE_ROUTED2(AccessibilityMsg_SnapshotTree,
// Messages sent from the renderer to the browser.
// Sent to notify the browser about renderer accessibility events.
-// The browser responds with a AccessibilityMsg_Events_ACK with the same
+// The browser responds with a AccessibilityMsg_EventBundle_ACK with the same
// ack_token.
-// The second parameter, reset_token, is set if this IPC was sent in response
+// The |reset_token| parameter is set if this IPC was sent in response
// to a reset request from the browser. When the browser requests a reset,
// it ignores incoming IPCs until it sees one with the correct reset token.
// Any other time, it ignores IPCs with a reset token.
-IPC_MESSAGE_ROUTED3(
- AccessibilityHostMsg_Events,
- std::vector<AccessibilityHostMsg_EventParams> /* events */,
- int /* reset_token */,
- int /* ack_token */)
+IPC_MESSAGE_ROUTED3(AccessibilityHostMsg_EventBundle,
+ AccessibilityHostMsg_EventBundleParams /* params */,
+ int /* reset_token */,
+ int /* ack_token */)
// Sent to update the browser of the location of accessibility objects.
IPC_MESSAGE_ROUTED1(
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 e6d7be10266..c399fa94167 100644
--- a/chromium/content/common/background_fetch/background_fetch_struct_traits.cc
+++ b/chromium/content/common/background_fetch/background_fetch_struct_traits.cc
@@ -4,10 +4,12 @@
#include "content/common/background_fetch/background_fetch_struct_traits.h"
-#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker.mojom.h"
#include "content/common/service_worker/service_worker_fetch_request_mojom_traits.h"
#include "content/common/service_worker/service_worker_messages.h"
#include "mojo/public/cpp/bindings/array_data_view.h"
+#include "third_party/blink/public/common/manifest/manifest_mojom_traits.h"
+#include "third_party/blink/public/mojom/manifest/manifest.mojom.h"
namespace mojo {
@@ -49,13 +51,4 @@ bool StructTraits<content::mojom::BackgroundFetchSettledFetchDataView,
data.ReadResponse(&fetch->response);
}
-// static
-bool StructTraits<
- blink::mojom::IconDefinitionDataView,
- content::IconDefinition>::Read(blink::mojom::IconDefinitionDataView data,
- content::IconDefinition* definition) {
- return data.ReadSrc(&definition->src) && data.ReadSizes(&definition->sizes) &&
- data.ReadType(&definition->type);
-}
-
} // namespace mojo
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 aaf094ed9c2..380748dbcf1 100644
--- a/chromium/content/common/background_fetch/background_fetch_struct_traits.h
+++ b/chromium/content/common/background_fetch/background_fetch_struct_traits.h
@@ -11,6 +11,7 @@
#include "content/common/background_fetch/background_fetch_types.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
+#include "third_party/blink/public/common/manifest/manifest.h"
#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h"
namespace content {
@@ -24,7 +25,7 @@ namespace mojo {
template <>
struct CONTENT_EXPORT StructTraits<blink::mojom::BackgroundFetchOptionsDataView,
content::BackgroundFetchOptions> {
- static const std::vector<content::IconDefinition>& icons(
+ static const std::vector<blink::Manifest::ImageResource>& icons(
const content::BackgroundFetchOptions& options) {
return options.icons;
}
@@ -91,23 +92,6 @@ struct CONTENT_EXPORT
content::BackgroundFetchSettledFetch* definition);
};
-template <>
-struct CONTENT_EXPORT StructTraits<blink::mojom::IconDefinitionDataView,
- content::IconDefinition> {
- static const std::string& src(const content::IconDefinition& definition) {
- return definition.src;
- }
- static const std::string& sizes(const content::IconDefinition& definition) {
- return definition.sizes;
- }
- static const std::string& type(const content::IconDefinition& definition) {
- return definition.type;
- }
-
- static bool Read(blink::mojom::IconDefinitionDataView data,
- content::IconDefinition* definition);
-};
-
} // namespace mojo
#endif // CONTENT_BROWSER_BACKGROUND_FETCH_BACKGROUND_FETCH_STRUCT_TRAITS_H_
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 3e8c85f1f56..a4d48582e2a 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
@@ -6,39 +6,38 @@
#include <utility>
+#include "base/strings/utf_string_conversions.h"
#include "content/common/background_fetch/background_fetch_types.h"
+#include "mojo/public/cpp/base/string16_mojom_traits.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/manifest/manifest.h"
+#include "third_party/blink/public/common/manifest/manifest_mojom_traits.h"
+#include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
+#include "ui/gfx/geometry/size.h"
+#include "url/mojom/url_gurl_mojom_traits.h"
namespace content {
namespace {
// Creates a new IconDefinition object for the given arguments.
-IconDefinition CreateIconDefinition(std::string src,
- std::string sizes,
- std::string type) {
- IconDefinition definition;
- definition.src = std::move(src);
- definition.sizes = std::move(sizes);
- definition.type = std::move(type);
-
- return definition;
-}
-
-// Returns whether the given IconDefinition objects are identical.
-bool IconDefinitionsAreIdentical(const IconDefinition& left,
- const IconDefinition& right) {
- return left.src == right.src && left.sizes == right.sizes &&
- left.type == right.type;
+blink::Manifest::ImageResource CreateIcon(const std::string& src,
+ std::vector<gfx::Size> sizes,
+ const std::string& type) {
+ blink::Manifest::ImageResource icon;
+ icon.src = GURL(src);
+ icon.sizes = std::move(sizes);
+ icon.type = base::ASCIIToUTF16(type);
+
+ return icon;
}
} // namespace
TEST(BackgroundFetchStructTraitsTest, BackgroundFetchOptionsRoundtrip) {
BackgroundFetchOptions options;
- options.icons = {
- CreateIconDefinition("my_icon.png", "256x256", "image/png"),
- CreateIconDefinition("my_small_icon.jpg", "128x128", "image/jpg")};
+ options.icons = {CreateIcon("my_icon.png", {{256, 256}}, "image/png"),
+ CreateIcon("my_small_icon.jpg", {{128, 128}}, "image/jpg")};
options.title = "My Background Fetch";
options.download_total = 9001;
@@ -48,10 +47,8 @@ TEST(BackgroundFetchStructTraitsTest, BackgroundFetchOptionsRoundtrip) {
&roundtrip_options));
ASSERT_EQ(roundtrip_options.icons.size(), options.icons.size());
- for (size_t i = 0; i < options.icons.size(); ++i) {
- EXPECT_TRUE(IconDefinitionsAreIdentical(options.icons[i],
- roundtrip_options.icons[i]));
- }
+ for (size_t i = 0; i < options.icons.size(); ++i)
+ EXPECT_EQ(options.icons[i], roundtrip_options.icons[i]);
EXPECT_EQ(roundtrip_options.title, options.title);
EXPECT_EQ(roundtrip_options.download_total, options.download_total);
@@ -75,15 +72,14 @@ TEST(BackgroundFetchStructTraitsTest, BackgroundFetchRegistrationRoundTrip) {
}
TEST(BackgroundFetchStructTraitsTest, IconDefinitionRoundtrip) {
- IconDefinition definition =
- CreateIconDefinition("my_icon.png", "256x256", "image/png");
+ blink::Manifest::ImageResource icon =
+ CreateIcon("my_icon.png", {{256, 256}}, "image/png");
- IconDefinition roundtrip_definition;
- ASSERT_TRUE(blink::mojom::IconDefinition::Deserialize(
- blink::mojom::IconDefinition::Serialize(&definition),
- &roundtrip_definition));
+ blink::Manifest::ImageResource roundtrip_icon;
+ ASSERT_TRUE(blink::mojom::ManifestImageResource::Deserialize(
+ blink::mojom::ManifestImageResource::Serialize(&icon), &roundtrip_icon));
- EXPECT_TRUE(IconDefinitionsAreIdentical(definition, roundtrip_definition));
+ EXPECT_EQ(icon, roundtrip_icon);
}
} // namespace content
diff --git a/chromium/content/common/background_fetch/background_fetch_types.cc b/chromium/content/common/background_fetch/background_fetch_types.cc
index 13325ef1752..2d5ba688181 100644
--- a/chromium/content/common/background_fetch/background_fetch_types.cc
+++ b/chromium/content/common/background_fetch/background_fetch_types.cc
@@ -6,12 +6,6 @@
namespace content {
-IconDefinition::IconDefinition() = default;
-
-IconDefinition::IconDefinition(const IconDefinition& other) = default;
-
-IconDefinition::~IconDefinition() = default;
-
BackgroundFetchOptions::BackgroundFetchOptions() = default;
BackgroundFetchOptions::BackgroundFetchOptions(
diff --git a/chromium/content/common/background_fetch/background_fetch_types.h b/chromium/content/common/background_fetch/background_fetch_types.h
index 685b624c299..fd774420426 100644
--- a/chromium/content/common/background_fetch/background_fetch_types.h
+++ b/chromium/content/common/background_fetch/background_fetch_types.h
@@ -11,26 +11,10 @@
#include "content/common/content_export.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "third_party/blink/public/common/manifest/manifest.h"
namespace content {
-// Represents the definition of an icon developers can optionally provide with a
-// Background Fetch fetch. Analogous to the following structure in the spec:
-// https://wicg.github.io/background-fetch/#background-fetch-manager
-//
-// Parsing of the icon definitions as well as fetching an appropriate icon will
-// be done by Blink in the renderer process. The browser process is expected to
-// treat these values as opaque strings.
-struct CONTENT_EXPORT IconDefinition {
- IconDefinition();
- IconDefinition(const IconDefinition& other);
- ~IconDefinition();
-
- std::string src;
- std::string sizes;
- std::string type;
-};
-
// Represents the optional options a developer can provide when starting a new
// Background Fetch fetch. Analogous to the following structure in the spec:
// https://wicg.github.io/background-fetch/#background-fetch-manager
@@ -39,7 +23,7 @@ struct CONTENT_EXPORT BackgroundFetchOptions {
BackgroundFetchOptions(const BackgroundFetchOptions& other);
~BackgroundFetchOptions();
- std::vector<IconDefinition> icons;
+ std::vector<blink::Manifest::ImageResource> icons;
std::string title;
uint64_t download_total = 0;
};
diff --git a/chromium/content/common/browser_plugin/browser_plugin_messages.h b/chromium/content/common/browser_plugin/browser_plugin_messages.h
index bef070d8e16..f511cb5049f 100644
--- a/chromium/content/common/browser_plugin/browser_plugin_messages.h
+++ b/chromium/content/common/browser_plugin/browser_plugin_messages.h
@@ -215,7 +215,7 @@ IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetCursor,
int /* browser_plugin_instance_id */,
content::WebCursor /* cursor */)
-IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetChildFrameSurface,
+IPC_MESSAGE_CONTROL2(BrowserPluginMsg_FirstSurfaceActivation,
int /* browser_plugin_instance_id */,
viz::SurfaceInfo /* surface_info */)
diff --git a/chromium/content/common/cache_storage/OWNERS b/chromium/content/common/cache_storage/OWNERS
deleted file mode 100644
index 5e0c72bf2bb..00000000000
--- a/chromium/content/common/cache_storage/OWNERS
+++ /dev/null
@@ -1,15 +0,0 @@
-nhiroki@chromium.org
-jkarlin@chromium.org
-jsbell@chromium.org
-
-per-file *_messages*.h=set noparent
-per-file *_messages*.h=file://ipc/SECURITY_OWNERS
-
-per-file *_mojom_traits*.*=set noparent
-per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
-
-per-file *.typemap=set noparent
-per-file *.typemap=file://ipc/SECURITY_OWNERS
-
-# TEAM: storage-dev@chromium.org
-# COMPONENT: Blink>Storage>CacheStorage
diff --git a/chromium/content/common/cache_storage/cache_storage_mojom_traits.h b/chromium/content/common/cache_storage/cache_storage_mojom_traits.h
deleted file mode 100644
index 764b68d4b7d..00000000000
--- a/chromium/content/common/cache_storage/cache_storage_mojom_traits.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_COMMON_CACHE_STORAGE_CACHE_STORAGE_MOJOM_TRAITS_H_
-#define CONTENT_COMMON_CACHE_STORAGE_CACHE_STORAGE_MOJOM_TRAITS_H_
-
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/optional.h"
-#include "base/strings/string16.h"
-#include "content/common/service_worker/service_worker_fetch_request_mojom_traits.h"
-#include "content/common/service_worker/service_worker_fetch_response_mojom_traits.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "mojo/public/cpp/base/string16_mojom_traits.h"
-#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h"
-#include "url/gurl.h"
-
-namespace mojo {
-
-template <>
-struct EnumTraits<blink::mojom::OperationType,
- content::CacheStorageCacheOperationType> {
- static blink::mojom::OperationType ToMojom(
- content::CacheStorageCacheOperationType input);
- static bool FromMojom(blink::mojom::OperationType input,
- content::CacheStorageCacheOperationType* out);
-};
-
-template <>
-struct StructTraits<blink::mojom::QueryParamsDataView,
- content::CacheStorageCacheQueryParams> {
- static bool ignore_search(
- const content::CacheStorageCacheQueryParams& query_params) {
- return query_params.ignore_search;
- }
- static bool ignore_method(
- const content::CacheStorageCacheQueryParams& query_params) {
- return query_params.ignore_method;
- }
- static bool ignore_vary(
- const content::CacheStorageCacheQueryParams& query_params) {
- return query_params.ignore_vary;
- }
- static const base::Optional<base::string16>& cache_name(
- const content::CacheStorageCacheQueryParams& query_params) {
- return query_params.cache_name.as_optional_string16();
- }
- static bool Read(blink::mojom::QueryParamsDataView,
- content::CacheStorageCacheQueryParams* output);
-};
-
-template <>
-struct StructTraits<blink::mojom::BatchOperationDataView,
- content::CacheStorageBatchOperation> {
- static content::CacheStorageCacheOperationType operation_type(
- const content::CacheStorageBatchOperation& batch_operation) {
- return batch_operation.operation_type;
- }
- static content::ServiceWorkerFetchRequest request(
- const content::CacheStorageBatchOperation& batch_operation) {
- return batch_operation.request;
- }
- static content::ServiceWorkerResponse response(
- const content::CacheStorageBatchOperation& batch_operation) {
- return batch_operation.response;
- }
- static content::CacheStorageCacheQueryParams match_params(
- const content::CacheStorageBatchOperation& batch_operation) {
- return batch_operation.match_params;
- }
- static bool Read(blink::mojom::BatchOperationDataView,
- content::CacheStorageBatchOperation* output);
-};
-
-} // namespace mojo
-
-#endif // CONTENT_COMMON_CACHE_STORAGE_CACHE_STORAGE_MOJOM_TRAITS_H_
diff --git a/chromium/content/common/common_sandbox_support_linux.cc b/chromium/content/common/common_sandbox_support_linux.cc
index c80e44a6d2b..507c3558b51 100644
--- a/chromium/content/common/common_sandbox_support_linux.cc
+++ b/chromium/content/common/common_sandbox_support_linux.cc
@@ -15,6 +15,9 @@
namespace content {
+// TODO(drott): This should be removed once we don't need to support PPAPI
+// TrueType functionality anymore, and before that, it should be replaced with
+// using FreeType for the purpose instead of reimplementing table parsing.
bool GetFontTable(int fd,
uint32_t table_tag,
off_t offset,
@@ -90,4 +93,4 @@ bool GetFontTable(int fd,
return true;
}
-} // namespace content \ No newline at end of file
+} // namespace content
diff --git a/chromium/content/common/content_message_generator.h b/chromium/content/common/content_message_generator.h
index 84e0f51ad8d..c895849490e 100644
--- a/chromium/content/common/content_message_generator.h
+++ b/chromium/content/common/content_message_generator.h
@@ -73,10 +73,10 @@
#ifndef CONTENT_COMMON_PAGE_MESSAGES_H_
#error "Failed to include content/common/page_messages.h"
#endif
-#undef CONTENT_COMMON_PLATFORM_NOTIFICATION_MESSAGES_H_
-#include "content/common/platform_notification_messages.h"
-#ifndef CONTENT_COMMON_PLATFORM_NOTIFICATION_MESSAGES_H_
-#error "Failed to include content/common/platform_notification_messages.h"
+#undef CONTENT_COMMON_PLATFORM_NOTIFICATION_PARAM_TRAITS_H_
+#include "content/common/platform_notification_param_traits.h"
+#ifndef CONTENT_COMMON_PLATFORM_NOTIFICATION_PARAM_TRAITS_H_
+#error "Failed to include content/common/platform_notification_param_traits.h"
#endif
#undef CONTENT_COMMON_RESOURCE_MESSAGES_H_
#include "content/common/resource_messages.h"
@@ -124,10 +124,4 @@
#ifndef CONTENT_COMMON_MEDIA_MEDIA_PLAYER_MESSAGES_ANDROID_H_
#error "Failed to include content/common/media/media_player_messages_android.h"
#endif
-#undef CONTENT_COMMON_MEDIA_SURFACE_VIEW_MANAGER_MESSAGES_ANDROID_H_
-#include "content/common/media/surface_view_manager_messages_android.h"
-#ifndef CONTENT_COMMON_MEDIA_SURFACE_VIEW_MANAGER_MESSAGES_ANDROID_H_
-#error \
- "Failed to include content/common/media/surface_view_manager_messages_android.h"
-#endif
#endif // defined(OS_ANDROID)
diff --git a/chromium/content/common/content_param_traits.cc b/chromium/content/common/content_param_traits.cc
index 310cd7f7c6f..450aaaf050a 100644
--- a/chromium/content/common/content_param_traits.cc
+++ b/chromium/content/common/content_param_traits.cc
@@ -148,7 +148,7 @@ void ParamTraits<scoped_refptr<storage::BlobHandle>>::Log(const param_type& p,
void ParamTraits<content::FrameMsg_ViewChanged_Params>::Write(
base::Pickle* m,
const param_type& p) {
- DCHECK(base::FeatureList::IsEnabled(features::kMash) ||
+ DCHECK(!features::IsAshInBrowserProcess() ||
(p.frame_sink_id.has_value() && p.frame_sink_id->is_valid()));
WriteParam(m, p.frame_sink_id);
}
@@ -159,7 +159,7 @@ bool ParamTraits<content::FrameMsg_ViewChanged_Params>::Read(
param_type* r) {
if (!ReadParam(m, iter, &(r->frame_sink_id)))
return false;
- if (!base::FeatureList::IsEnabled(features::kMash) &&
+ if (features::IsAshInBrowserProcess() &&
(!r->frame_sink_id || !r->frame_sink_id->is_valid())) {
NOTREACHED();
return false;
diff --git a/chromium/content/common/content_security_policy/csp_context.cc b/chromium/content/common/content_security_policy/csp_context.cc
index 7791627ad19..aa19c5fd533 100644
--- a/chromium/content/common/content_security_policy/csp_context.cc
+++ b/chromium/content/common/content_security_policy/csp_context.cc
@@ -65,11 +65,11 @@ bool CSPContext::ShouldModifyRequestUrlForCsp(
}
void CSPContext::ModifyRequestUrlForCsp(GURL* url) {
- if (url->scheme() == "http") {
+ if (url->SchemeIs(url::kHttpScheme)) {
+ // Updating the URL's scheme also implicitly updates the URL's port from 80
+ // to 443 if needed.
GURL::Replacements replacements;
- replacements.SetSchemeStr("https");
- if (url->port() == "80")
- replacements.SetPortStr("443");
+ replacements.SetSchemeStr(url::kHttpsScheme);
*url = url->ReplaceComponents(replacements);
}
}
diff --git a/chromium/content/common/dom_storage/dom_storage_map.cc b/chromium/content/common/dom_storage/dom_storage_map.cc
index 0a6b0176a98..fd088fb170b 100644
--- a/chromium/content/common/dom_storage/dom_storage_map.cc
+++ b/chromium/content/common/dom_storage/dom_storage_map.cc
@@ -47,7 +47,8 @@ unsigned DOMStorageMap::Length() const {
return has_only_keys_ ? keys_only_.size() : keys_values_.size();
}
-base::NullableString16 DOMStorageMap::Key(unsigned index) {
+base::NullableString16 DOMStorageMap::Key(unsigned index,
+ bool* did_decrease_iterator) {
if (index >= Length())
return base::NullableString16();
while (last_key_index_ != index) {
@@ -57,6 +58,8 @@ base::NullableString16 DOMStorageMap::Key(unsigned index) {
else
--keys_values_iterator_;
--last_key_index_;
+ if (did_decrease_iterator)
+ *did_decrease_iterator = true;
} else {
if (has_only_keys_)
++keys_only_iterator_;
diff --git a/chromium/content/common/dom_storage/dom_storage_map.h b/chromium/content/common/dom_storage/dom_storage_map.h
index 7c154bc1551..e930d38b522 100644
--- a/chromium/content/common/dom_storage/dom_storage_map.h
+++ b/chromium/content/common/dom_storage/dom_storage_map.h
@@ -28,7 +28,12 @@ class CONTENT_EXPORT DOMStorageMap
explicit DOMStorageMap(size_t quota);
unsigned Length() const;
- base::NullableString16 Key(unsigned index);
+ // If |did_decrease_iterator| is not null it is set to true iff this method
+ // call was made more efficient because iterators are bidirectional. If being
+ // able to decrement the iterator wasn't used |did_decrease_iterator| is left
+ // unmodified.
+ base::NullableString16 Key(unsigned index,
+ bool* did_decrease_iterator = nullptr);
// Sets and removes items from the storage. Old value is wriiten into
// |old_value| if it's not null and |has_only_keys| is false. |old_value| is
diff --git a/chromium/content/common/fileapi/file_system_messages.h b/chromium/content/common/fileapi/file_system_messages.h
index 9edd48cf161..971610bdffe 100644
--- a/chromium/content/common/fileapi/file_system_messages.h
+++ b/chromium/content/common/fileapi/file_system_messages.h
@@ -43,7 +43,7 @@ IPC_ENUM_TRAITS_MAX_VALUE(storage::QuotaLimitType, storage::kQuotaLimitTypeLast)
// File system messages sent from the browser to the child process.
-// WebFrameClient::openFileSystem response messages.
+// WebLocalFrameClient::openFileSystem response messages.
IPC_MESSAGE_CONTROL3(FileSystemMsg_DidOpenFileSystem,
int /* request_id */,
std::string /* name */,
@@ -79,7 +79,7 @@ IPC_MESSAGE_CONTROL2(FileSystemMsg_DidFail,
// File system messages sent from the child process to the browser.
-// WebFrameClient::openFileSystem() message.
+// WebLocalFrameClient::openFileSystem() message.
IPC_MESSAGE_CONTROL3(FileSystemHostMsg_OpenFileSystem,
int /* request_id */,
GURL /* origin_url */,
diff --git a/chromium/content/common/font_config_ipc_linux.cc b/chromium/content/common/font_config_ipc_linux.cc
deleted file mode 100644
index 2596c992bcc..00000000000
--- a/chromium/content/common/font_config_ipc_linux.cc
+++ /dev/null
@@ -1,179 +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/font_config_ipc_linux.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <sys/mman.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/uio.h>
-#include <unistd.h>
-
-#include <functional>
-#include <memory>
-#include <utility>
-
-#include "base/files/file_util.h"
-#include "base/files/memory_mapped_file.h"
-#include "base/memory/ref_counted.h"
-#include "base/pickle.h"
-#include "base/posix/unix_domain_socket.h"
-#include "base/threading/thread_restrictions.h"
-#include "base/trace_event/trace_event.h"
-#include "skia/ext/skia_utils_base.h"
-#include "third_party/skia/include/core/SkData.h"
-#include "third_party/skia/include/core/SkRefCnt.h"
-#include "third_party/skia/include/core/SkStream.h"
-#include "third_party/skia/include/core/SkTypeface.h"
-
-namespace content {
-
-std::size_t SkFontConfigInterfaceFontIdentityHash::operator()(
- const SkFontConfigInterface::FontIdentity& sp) const {
- std::hash<std::string> stringhash;
- std::hash<int> inthash;
- size_t r = inthash(sp.fID);
- r = r * 41 + inthash(sp.fTTCIndex);
- r = r * 41 + stringhash(sp.fString.c_str());
- r = r * 41 + inthash(sp.fStyle.weight());
- r = r * 41 + inthash(sp.fStyle.slant());
- r = r * 41 + inthash(sp.fStyle.width());
- return r;
-}
-
-// Wikpedia's main country selection page activates 21 fallback fonts,
-// doubling this we should be on the generous side as an upper bound,
-// but nevertheless not have the mapped typefaces cache grow excessively.
-const size_t kMaxMappedTypefaces = 42;
-
-void CloseFD(int fd) {
- int err = IGNORE_EINTR(close(fd));
- DCHECK(!err);
-}
-
-FontConfigIPC::FontConfigIPC(int fd)
- : fd_(fd)
- , mapped_typefaces_(kMaxMappedTypefaces) {
-}
-
-FontConfigIPC::~FontConfigIPC() {
- CloseFD(fd_);
-}
-
-bool FontConfigIPC::matchFamilyName(const char familyName[],
- SkFontStyle requestedStyle,
- FontIdentity* outFontIdentity,
- SkString* outFamilyName,
- SkFontStyle* outStyle) {
- TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::matchFamilyName");
- size_t familyNameLen = familyName ? strlen(familyName) : 0;
- if (familyNameLen > kMaxFontFamilyLength)
- return false;
-
- base::Pickle request;
- request.WriteInt(METHOD_MATCH);
- request.WriteData(familyName, familyNameLen);
- skia::WriteSkFontStyle(&request, requestedStyle);
-
- uint8_t reply_buf[2048];
- const ssize_t r = base::UnixDomainSocket::SendRecvMsg(
- fd_, reply_buf, sizeof(reply_buf), nullptr, request);
- if (r == -1)
- return false;
-
- base::Pickle reply(reinterpret_cast<char*>(reply_buf), r);
- base::PickleIterator iter(reply);
- bool result;
- if (!iter.ReadBool(&result))
- return false;
- if (!result)
- return false;
-
- SkString reply_family;
- FontIdentity reply_identity;
- SkFontStyle reply_style;
- if (!skia::ReadSkString(&iter, &reply_family) ||
- !skia::ReadSkFontIdentity(&iter, &reply_identity) ||
- !skia::ReadSkFontStyle(&iter, &reply_style)) {
- return false;
- }
-
- if (outFontIdentity)
- *outFontIdentity = reply_identity;
- if (outFamilyName)
- *outFamilyName = reply_family;
- if (outStyle)
- *outStyle = reply_style;
-
- return true;
-}
-
-static void DestroyMemoryMappedFile(const void*, void* context) {
- base::ThreadRestrictions::ScopedAllowIO allow_munmap;
- delete static_cast<base::MemoryMappedFile*>(context);
-}
-
-SkMemoryStream* FontConfigIPC::mapFileDescriptorToStream(int fd) {
- std::unique_ptr<base::MemoryMappedFile> mapped_font_file(
- new base::MemoryMappedFile);
- base::ThreadRestrictions::ScopedAllowIO allow_mmap;
- mapped_font_file->Initialize(base::File(fd));
- DCHECK(mapped_font_file->IsValid());
-
- sk_sp<SkData> data =
- SkData::MakeWithProc(mapped_font_file->data(), mapped_font_file->length(),
- &DestroyMemoryMappedFile, mapped_font_file.get());
- if (!data)
- return nullptr;
- ignore_result(mapped_font_file.release()); // Ownership transferred to SkDataB
- return new SkMemoryStream(std::move(data));
-}
-
-SkStreamAsset* FontConfigIPC::openStream(const FontIdentity& identity) {
- TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::openStream");
-
- base::Pickle request;
- request.WriteInt(METHOD_OPEN);
- request.WriteUInt32(identity.fID);
-
- int result_fd = -1;
- uint8_t reply_buf[256];
- const ssize_t r = base::UnixDomainSocket::SendRecvMsg(
- fd_, reply_buf, sizeof(reply_buf), &result_fd, request);
- if (r == -1)
- return nullptr;
-
- base::Pickle reply(reinterpret_cast<char*>(reply_buf), r);
- bool result;
- base::PickleIterator iter(reply);
- if (!iter.ReadBool(&result) || !result) {
- if (result_fd)
- CloseFD(result_fd);
- return nullptr;
- }
-
- return mapFileDescriptorToStream(result_fd);
-}
-
-sk_sp<SkTypeface> FontConfigIPC::makeTypeface(
- const SkFontConfigInterface::FontIdentity& identity) {
- base::AutoLock lock(lock_);
- auto mapped_typefaces_it = mapped_typefaces_.Get(identity);
- if (mapped_typefaces_it != mapped_typefaces_.end())
- return mapped_typefaces_it->second;
-
- SkStreamAsset* typeface_stream = openStream(identity);
- if (!typeface_stream)
- return nullptr;
- sk_sp<SkTypeface> typeface_from_stream(
- SkTypeface::MakeFromStream(typeface_stream, identity.fTTCIndex));
- auto mapped_typefaces_insert_it =
- mapped_typefaces_.Put(identity, std::move(typeface_from_stream));
- return mapped_typefaces_insert_it->second;
-}
-
-} // namespace content
diff --git a/chromium/content/common/font_config_ipc_linux.h b/chromium/content/common/font_config_ipc_linux.h
deleted file mode 100644
index 0fc85ec5ef4..00000000000
--- a/chromium/content/common/font_config_ipc_linux.h
+++ /dev/null
@@ -1,81 +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_FONT_CONFIG_IPC_LINUX_H_
-#define CONTENT_COMMON_FONT_CONFIG_IPC_LINUX_H_
-
-#include "base/compiler_specific.h"
-#include "base/containers/mru_cache.h"
-#include "base/macros.h"
-#include "base/synchronization/lock.h"
-#include "third_party/skia/include/core/SkRefCnt.h"
-#include "third_party/skia/include/core/SkStream.h"
-#include "third_party/skia/include/core/SkTypeface.h"
-#include "third_party/skia/include/ports/SkFontConfigInterface.h"
-
-#include <stddef.h>
-
-#include <string>
-
-class SkString;
-
-namespace content {
-
-struct SkFontConfigInterfaceFontIdentityHash {
- std::size_t operator()(const SkFontConfigInterface::FontIdentity& sp) const;
-};
-
-// FontConfig implementation for Skia that proxies out of process to get out
-// of the sandbox. See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandbox_ipc.md
-class FontConfigIPC : public SkFontConfigInterface {
- public:
- explicit FontConfigIPC(int fd);
- ~FontConfigIPC() override;
-
- bool matchFamilyName(const char familyName[],
- SkFontStyle requested,
- FontIdentity* outFontIdentifier,
- SkString* outFamilyName,
- SkFontStyle* outStyle) override;
-
- sk_sp<SkTypeface> makeTypeface(const FontIdentity& identity) override
- WARN_UNUSED_RESULT;
-
- enum Method {
- METHOD_MATCH = 0,
- METHOD_OPEN = 1,
- };
-
- enum {
- kMaxFontFamilyLength = 2048
- };
-
- private:
- // Marking this private in Blink's implementation of SkFontConfigInterface
- // since our caching implementation's efficacy is impaired if both
- // createTypeface and openStream are used in parallel.
- SkStreamAsset* openStream(const FontIdentity&) override;
-
- SkMemoryStream* mapFileDescriptorToStream(int fd);
-
- const int fd_;
- // Lock preventing multiple threads from creating a typeface and removing
- // an element from |mapped_typefaces_| map at the same time.
- base::Lock lock_;
- // Practically, this hash_map definition means that we re-map the same font
- // file multiple times if we receive createTypeface requests for multiple
- // ttc-indices or styles but the same fontconfig interface id. Since the usage
- // frequency of ttc indices is very low, and style is not used by clients of
- // this API, this seems okay.
- base::HashingMRUCache<FontIdentity,
- sk_sp<SkTypeface>,
- SkFontConfigInterfaceFontIdentityHash>
- mapped_typefaces_;
-
- DISALLOW_COPY_AND_ASSIGN(FontConfigIPC);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_FONT_CONFIG_IPC_LINUX_H_
diff --git a/chromium/content/common/frame.mojom b/chromium/content/common/frame.mojom
index 09b5766c079..fb4732e6e66 100644
--- a/chromium/content/common/frame.mojom
+++ b/chromium/content/common/frame.mojom
@@ -4,6 +4,7 @@
module content.mojom;
+import "content/common/navigation_client.mojom";
import "content/common/navigation_params.mojom";
import "content/common/service_worker/controller_service_worker.mojom";
import "content/common/url_loader_factory_bundle.mojom";
@@ -14,6 +15,7 @@ import "content/public/common/window_container_type.mojom";
import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "services/network/public/mojom/url_loader.mojom";
+import "services/network/public/mojom/url_loader_factory.mojom";
import "services/service_manager/public/mojom/interface_provider.mojom";
import "services/viz/public/interfaces/compositing/surface_id.mojom";
import "third_party/blink/public/mojom/blob/blob_url_store.mojom";
@@ -52,6 +54,8 @@ struct RequestNavigationParams;
// Implemented by the frame provider and currently must be associated with the
// legacy IPC channel.
+// KEEP THE COMMIT FUNCTIONS IN SYNC in content/common/navigation_client.mojom.
+// These will eventually be removed from FrameNavigationControl.
interface FrameNavigationControl {
// Tells the renderer that a navigation is ready to commit.
//
@@ -60,8 +64,7 @@ interface FrameNavigationControl {
// be the result of the committed navigation.
//
// Note: |url_loader_client_endpoints| will be empty iff the navigation URL
- // wasn't handled by the network stack (i.e. JavaScript URLs, renderer debug
- // URLs, same document navigations, about:blank, ...)
+ // wasn't handled by the network stack (i.e. about:blank, ...)
//
// When the Network Service is enabled, |subresource_loader_factories| may
// also be provided by the browser as a a means for the renderer to load
@@ -70,6 +73,9 @@ interface FrameNavigationControl {
// |controller_service_worker_info| may also be provided by the browser if the
// frame that is being navigated is supposed to be controlled by a Service
// Worker.
+ // |prefetch_loader_factory| is populated only when Network Service is
+ // enabled. The pointer is used to start a prefetch loading via the browser
+ // process.
//
// For automation driver-initiated navigations over the devtools protocol,
// |devtools_navigation_token_| is used to tag the navigation. This navigation
@@ -89,7 +95,9 @@ interface FrameNavigationControl {
URLLoaderFactoryBundle? subresource_loader_factories,
array<TransferrableURLLoader>? subresource_overrides,
ControllerServiceWorkerInfo? controller_service_worker_info,
- mojo_base.mojom.UnguessableToken devtools_navigation_token);
+ network.mojom.URLLoaderFactory? prefetch_loader_factory,
+ mojo_base.mojom.UnguessableToken devtools_navigation_token)
+ => (blink.mojom.CommitResult commit_result);
// Tells the renderer that a failed navigation is ready to commit.
//
@@ -106,7 +114,8 @@ interface FrameNavigationControl {
bool has_stale_copy_in_cache,
int32 error_code,
string? error_page_content,
- URLLoaderFactoryBundle? subresource_loader_factories);
+ URLLoaderFactoryBundle? subresource_loader_factories)
+ => (blink.mojom.CommitResult commit_result);
// Tells the renderer that a same-document navigation should be committed.
// The renderer will return a status value indicating whether the commit
@@ -150,7 +159,10 @@ interface FrameFactory {
struct CreateNewWindowParams {
// True if this open request came in the context of a user gesture.
- bool user_gesture;
+ //
+ // TODO(mustaq): We have cases where a user gesture is assumed to be
+ // there even when it's not the case. See https://crbug.com/843233.
+ bool mimic_user_gesture;
// Type of window requested.
WindowContainerType window_container_type;
@@ -274,10 +286,16 @@ interface FrameHost {
// cloneable, and thus can't contain mojo interfaces.
// If an invalid BlobURLToken is passed in, or if the token doesn't match the
// url in |common_params|, the navigation will result in a network error.
+ // |navigation_client| is passed to the renderer to allow for further control
+ // of the navigation. Allows for Commit and Cancels/Aborts. It is only valid
+ // when PerNavigationMojoInterface is enabled.
+ // TODO(ahemery): |navigation_client| should not be optional. Make it
+ // mandatory when removing PerNavigationMojoInterface feature flag.
BeginNavigation(
CommonNavigationParams common_params,
BeginNavigationParams begin_params,
- blink.mojom.BlobURLToken? blob_url_token);
+ blink.mojom.BlobURLToken? blob_url_token,
+ associated NavigationClient? navigation_client);
// Sent when a subresource response has started.
// |cert_status| is the bitmask of status info of the SSL certificate. (see
@@ -325,4 +343,8 @@ interface FrameHost {
// correctly set the initial size of the frame in case of a cross-process
// navigation.
FrameSizeChanged(gfx.mojom.Size size);
+
+ // Notifies the browser that the current frame has either become or is no
+ // longer fullscreen.
+ FullscreenStateChanged(bool is_fullscreen);
};
diff --git a/chromium/content/common/frame_message_enums.h b/chromium/content/common/frame_message_enums.h
index ff33814c0d8..c2b16621fde 100644
--- a/chromium/content/common/frame_message_enums.h
+++ b/chromium/content/common/frame_message_enums.h
@@ -61,20 +61,4 @@ struct FrameMsg_Navigate_Type {
}
};
-struct FrameMsg_UILoadMetricsReportType {
- public:
- enum Value {
- // Do not report metrics for this load.
- NO_REPORT,
-
- // Report metrics for this load, that originated from clicking on a link.
- REPORT_LINK,
-
- // Report metrics for this load, that originated from an Android OS intent.
- REPORT_INTENT,
-
- REPORT_TYPE_LAST = REPORT_INTENT,
- };
-};
-
#endif // CONTENT_COMMON_FRAME_MESSAGE_ENUMS_H_
diff --git a/chromium/content/common/frame_messages.h b/chromium/content/common/frame_messages.h
index 98bc62f6c93..4d0712eca8d 100644
--- a/chromium/content/common/frame_messages.h
+++ b/chromium/content/common/frame_messages.h
@@ -58,6 +58,7 @@
#include "ppapi/buildflags/buildflags.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/common/frame/frame_policy.h"
+#include "third_party/blink/public/common/frame/user_activation_update_type.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
#include "third_party/blink/public/common/message_port/transferable_message.h"
#include "third_party/blink/public/platform/web_focus_type.h"
@@ -70,6 +71,7 @@
#include "third_party/blink/public/web/web_frame_owner_properties.h"
#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h"
#include "third_party/blink/public/web/web_fullscreen_options.h"
+#include "third_party/blink/public/web/web_media_player_action.h"
#include "third_party/blink/public/web/web_tree_scope_type.h"
#include "third_party/blink/public/web/web_triggering_event_info.h"
#include "ui/gfx/geometry/rect.h"
@@ -111,8 +113,6 @@ IPC_ENUM_TRAITS_MIN_MAX_VALUE(content::JavaScriptDialogType,
content::JAVASCRIPT_DIALOG_TYPE_PROMPT)
IPC_ENUM_TRAITS_MAX_VALUE(FrameMsg_Navigate_Type::Value,
FrameMsg_Navigate_Type::NAVIGATE_TYPE_LAST)
-IPC_ENUM_TRAITS_MAX_VALUE(FrameMsg_UILoadMetricsReportType::Value,
- FrameMsg_UILoadMetricsReportType::REPORT_TYPE_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebContextMenuData::MediaType,
blink::WebContextMenuData::kMediaTypeLast)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebContextMenuData::InputFieldType,
@@ -137,7 +137,11 @@ IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::FeaturePolicyFeature,
IPC_ENUM_TRAITS_MAX_VALUE(content::CSPDisposition,
content::CSPDisposition::LAST)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebTriggeringEventInfo,
- blink::WebTriggeringEventInfo::kLast)
+ blink::WebTriggeringEventInfo::kMaxValue)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::UserActivationUpdateType,
+ blink::UserActivationUpdateType::kMaxValue)
+IPC_ENUM_TRAITS_MAX_VALUE(blink::WebMediaPlayerAction::Type,
+ blink::WebMediaPlayerAction::Type::kTypeLast)
IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::WebScrollDirection,
blink::kFirstScrollDirection,
blink::kLastScrollDirection)
@@ -252,6 +256,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::FrameVisualProperties)
IPC_STRUCT_TRAITS_MEMBER(screen_space_rect)
IPC_STRUCT_TRAITS_MEMBER(local_frame_size)
IPC_STRUCT_TRAITS_MEMBER(capture_sequence_number)
+ IPC_STRUCT_TRAITS_MEMBER(zoom_level)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(cc::RenderFrameMetadata)
@@ -347,9 +352,6 @@ 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)
@@ -420,13 +422,6 @@ IPC_STRUCT_BEGIN_WITH_PARENT(FrameHostMsg_DidCommitProvisionalLoad_Params,
// RenderFrameProxies.
IPC_STRUCT_MEMBER(url::Origin, origin)
- // How navigation metrics starting on UI action for this load should be
- // reported.
- IPC_STRUCT_MEMBER(FrameMsg_UILoadMetricsReportType::Value, report_type)
-
- // Timestamp at which the UI action that triggered the navigation originated.
- IPC_STRUCT_MEMBER(base::TimeTicks, ui_timestamp)
-
// The insecure request policy the document for the load is enforcing.
IPC_STRUCT_MEMBER(blink::WebInsecureRequestPolicy, insecure_request_policy)
@@ -481,8 +476,6 @@ IPC_STRUCT_TRAITS_BEGIN(content::CommonNavigationParams)
IPC_STRUCT_TRAITS_MEMBER(navigation_type)
IPC_STRUCT_TRAITS_MEMBER(allow_download)
IPC_STRUCT_TRAITS_MEMBER(should_replace_current_entry)
- IPC_STRUCT_TRAITS_MEMBER(ui_timestamp)
- IPC_STRUCT_TRAITS_MEMBER(report_type)
IPC_STRUCT_TRAITS_MEMBER(base_url_for_data_url)
IPC_STRUCT_TRAITS_MEMBER(history_url_for_data_url)
IPC_STRUCT_TRAITS_MEMBER(previews_state)
@@ -495,6 +488,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::CommonNavigationParams)
IPC_STRUCT_TRAITS_MEMBER(started_from_context_menu)
IPC_STRUCT_TRAITS_MEMBER(initiator_csp)
IPC_STRUCT_TRAITS_MEMBER(initiator_self_source)
+ IPC_STRUCT_TRAITS_MEMBER(origin_policy)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::NavigationTiming)
@@ -581,6 +575,7 @@ IPC_STRUCT_BEGIN(FrameHostMsg_DownloadUrl_Params)
IPC_STRUCT_MEMBER(content::Referrer, referrer)
IPC_STRUCT_MEMBER(url::Origin, initiator_origin)
IPC_STRUCT_MEMBER(base::string16, suggested_name)
+ IPC_STRUCT_MEMBER(bool, follow_cross_origin_redirects)
IPC_STRUCT_MEMBER(mojo::MessagePipeHandle, blob_url_token)
IPC_STRUCT_END()
@@ -796,6 +791,11 @@ IPC_STRUCT_TRAITS_BEGIN(content::PepperRendererInstanceData)
IPC_STRUCT_TRAITS_END()
#endif
+IPC_STRUCT_TRAITS_BEGIN(blink::WebMediaPlayerAction)
+ IPC_STRUCT_TRAITS_MEMBER(type)
+ IPC_STRUCT_TRAITS_MEMBER(enable)
+IPC_STRUCT_TRAITS_END()
+
// -----------------------------------------------------------------------------
// Messages sent from the browser to the renderer.
@@ -804,7 +804,7 @@ IPC_STRUCT_TRAITS_END()
IPC_MESSAGE_ROUTED1(FrameMsg_IntrinsicSizingInfoOfChildChanged,
blink::WebIntrinsicSizingInfo)
-IPC_MESSAGE_ROUTED1(FrameMsg_SetChildFrameSurface,
+IPC_MESSAGE_ROUTED1(FrameMsg_FirstSurfaceActivation,
viz::SurfaceInfo /* surface_info */)
// Notifies the embedding frame that the process rendering the child frame's
@@ -1121,12 +1121,15 @@ IPC_MESSAGE_ROUTED0(FrameMsg_EnableViewSourceMode)
// ScopedPageLoadDeferrer is on the stack for SwapOut.
IPC_MESSAGE_ROUTED0(FrameMsg_SuppressFurtherDialogs)
-// Notifies the RenderFrame about a user activation from the browser side.
+// Notifies the RenderFrame about a user activation detected in the browser side
+// (e.g. during Android voice search).
IPC_MESSAGE_ROUTED0(FrameMsg_NotifyUserActivation)
-// Tells the frame to consider itself to have received a user gesture (based
-// on a user gesture processed in a different renderer process).
-IPC_MESSAGE_ROUTED0(FrameMsg_SetHasReceivedUserGesture)
+// Tells the frame to update the user activation state in appropriate part of
+// the frame tree (ancestors for activation notification and all nodes for
+// consumption).
+IPC_MESSAGE_ROUTED1(FrameMsg_UpdateUserActivationState,
+ blink::UserActivationUpdateType /* type of state update */)
// Tells the frame to mark that the previous document on that frame had received
// a user gesture on the same eTLD+1.
@@ -1159,6 +1162,12 @@ IPC_MESSAGE_ROUTED2(FrameMsg_BubbleLogicalScroll,
blink::WebScrollDirection /* direction */,
blink::WebScrollGranularity /* granularity */)
+// Tells the renderer to perform the given action on the media player location
+// at the given point in the view coordinate space.
+IPC_MESSAGE_ROUTED2(FrameMsg_MediaPlayerActionAt,
+ gfx::PointF /* location */,
+ blink::WebMediaPlayerAction)
+
// -----------------------------------------------------------------------------
// Messages sent from the renderer to the browser.
@@ -1262,9 +1271,7 @@ IPC_MESSAGE_CONTROL3(FrameHostMsg_SaveImageFromDataURL,
// in this frame. Sent for top-level frames. |report_type| and |ui_timestamp|
// are used to report navigation metrics starting on the ui input event that
// triggered the navigation timestamp.
-IPC_MESSAGE_ROUTED2(FrameHostMsg_DocumentOnLoadCompleted,
- FrameMsg_UILoadMetricsReportType::Value /* report_type */,
- base::TimeTicks /* ui_timestamp */)
+IPC_MESSAGE_ROUTED0(FrameHostMsg_DocumentOnLoadCompleted)
// Notifies that the initial empty document of a view has been accessed.
// After this, it is no longer safe to show a pending navigation's URL without
@@ -1290,12 +1297,6 @@ IPC_MESSAGE_ROUTED2(FrameHostMsg_DidChangeFrameOwnerProperties,
int32_t /* subframe_routing_id */,
content::FrameOwnerProperties /* frame_owner_properties */)
-// Notifies the browser that document has parsed the body. This is used by the
-// ResourceScheduler as an indication that bandwidth contention won't block
-// first paint.
-IPC_MESSAGE_ROUTED1(FrameHostMsg_WillInsertBody,
- int /* render_view_routing_id */)
-
// Changes the title for the page in the UI when the page is navigated or the
// title changes. Sent for top-level frames.
IPC_MESSAGE_ROUTED2(FrameHostMsg_UpdateTitle,
@@ -1374,13 +1375,6 @@ IPC_MESSAGE_ROUTED1(FrameHostMsg_PepperStartsPlayback,
IPC_MESSAGE_ROUTED1(FrameHostMsg_PepperStopsPlayback,
int32_t /* pp_instance */)
-// Used to get the list of plugins. |main_frame_origin| is used to handle
-// exceptions for plugin content settings.
-IPC_SYNC_MESSAGE_CONTROL2_1(FrameHostMsg_GetPlugins,
- bool /* refresh*/,
- url::Origin /* main_frame_origin */,
- std::vector<content::WebPluginInfo> /* plugins */)
-
// Return information about a plugin for the given URL and MIME
// type. If there is no matching plugin, |found| is false.
// |actual_mime_type| is the actual mime type supported by the
@@ -1516,9 +1510,11 @@ 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)
+// Indicates that the user activation state in the current frame has been
+// updated, so the replicated states need to be synced (in the browser process
+// as well as in all other renderer processes).
+IPC_MESSAGE_ROUTED1(FrameHostMsg_UpdateUserActivationState,
+ blink::UserActivationUpdateType /* type of state update */)
// Indicates that this frame received a user gesture on a previous navigation on
// the same eTLD+1. This ensures the state is propagated to any remote frames.
diff --git a/chromium/content/common/frame_visual_properties.h b/chromium/content/common/frame_visual_properties.h
index 6dc8da06d92..34ab61053ae 100644
--- a/chromium/content/common/frame_visual_properties.h
+++ b/chromium/content/common/frame_visual_properties.h
@@ -36,6 +36,10 @@ struct CONTENT_EXPORT FrameVisualProperties {
gfx::Size local_frame_size;
uint32_t capture_sequence_number = 0u;
+
+ // This represents the page zoom level for a WebContents.
+ // (0 is the default value which results in 1.0 zoom factor.)
+ double zoom_level = 0;
};
} // namespace content
diff --git a/chromium/content/common/in_process_child_thread_params.cc b/chromium/content/common/in_process_child_thread_params.cc
index b52ffd93332..61ff12ab647 100644
--- a/chromium/content/common/in_process_child_thread_params.cc
+++ b/chromium/content/common/in_process_child_thread_params.cc
@@ -8,10 +8,10 @@ namespace content {
InProcessChildThreadParams::InProcessChildThreadParams(
scoped_refptr<base::SingleThreadTaskRunner> io_runner,
- mojo::edk::OutgoingBrokerClientInvitation* broker_client_invitation,
+ mojo::OutgoingInvitation* mojo_invitation,
const std::string& service_request_token)
: io_runner_(std::move(io_runner)),
- broker_client_invitation_(broker_client_invitation),
+ mojo_invitation_(mojo_invitation),
service_request_token_(service_request_token) {}
InProcessChildThreadParams::InProcessChildThreadParams(
diff --git a/chromium/content/common/in_process_child_thread_params.h b/chromium/content/common/in_process_child_thread_params.h
index 2b3bcf57cee..b8a349efa4c 100644
--- a/chromium/content/common/in_process_child_thread_params.h
+++ b/chromium/content/common/in_process_child_thread_params.h
@@ -10,7 +10,7 @@
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "content/common/content_export.h"
-#include "mojo/edk/embedder/outgoing_broker_client_invitation.h"
+#include "mojo/public/cpp/system/invitation.h"
namespace content {
@@ -21,7 +21,7 @@ class CONTENT_EXPORT InProcessChildThreadParams {
public:
InProcessChildThreadParams(
scoped_refptr<base::SingleThreadTaskRunner> io_runner,
- mojo::edk::OutgoingBrokerClientInvitation* broker_client_invitation,
+ mojo::OutgoingInvitation* mojo_invitation,
const std::string& service_request_token);
InProcessChildThreadParams(const InProcessChildThreadParams& other);
~InProcessChildThreadParams();
@@ -30,9 +30,7 @@ class CONTENT_EXPORT InProcessChildThreadParams {
return io_runner_;
}
- mojo::edk::OutgoingBrokerClientInvitation* broker_client_invitation() const {
- return broker_client_invitation_;
- }
+ mojo::OutgoingInvitation* mojo_invitation() const { return mojo_invitation_; }
const std::string& service_request_token() const {
return service_request_token_;
@@ -40,7 +38,7 @@ class CONTENT_EXPORT InProcessChildThreadParams {
private:
scoped_refptr<base::SingleThreadTaskRunner> io_runner_;
- mojo::edk::OutgoingBrokerClientInvitation* const broker_client_invitation_;
+ mojo::OutgoingInvitation* const mojo_invitation_;
std::string service_request_token_;
};
diff --git a/chromium/content/common/indexed_db/OWNERS b/chromium/content/common/indexed_db/OWNERS
index 801d2601aa2..7b4d02967d7 100644
--- a/chromium/content/common/indexed_db/OWNERS
+++ b/chromium/content/common/indexed_db/OWNERS
@@ -10,3 +10,6 @@ per-file *_struct_traits*.*=set noparent
per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
per-file *.typemap=set noparent
per-file *.typemap=file://ipc/SECURITY_OWNERS
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>IndexedDB
diff --git a/chromium/content/common/input/event_with_latency_info_unittest.cc b/chromium/content/common/input/event_with_latency_info_unittest.cc
index 2c135593a3e..3a1d4138568 100644
--- a/chromium/content/common/input/event_with_latency_info_unittest.cc
+++ b/chromium/content/common/input/event_with_latency_info_unittest.cc
@@ -117,21 +117,20 @@ TEST_F(EventWithLatencyInfoTest, LatencyInfoCoalescing) {
MouseEventWithLatencyInfo mouse_0 =
CreateMouseEvent(WebInputEvent::kMouseMove, 5.0);
mouse_0.latency.AddLatencyNumberWithTimestamp(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, base::TimeTicks(), 1);
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, base::TimeTicks(), 1);
MouseEventWithLatencyInfo mouse_1 =
CreateMouseEvent(WebInputEvent::kMouseMove, 10.0);
ASSERT_TRUE(mouse_0.CanCoalesceWith(mouse_1));
- ui::LatencyInfo::LatencyComponent component;
EXPECT_FALSE(mouse_1.latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, &component));
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr));
mouse_0.CoalesceWith(mouse_1);
// Coalescing WebMouseEvent preservers older LatencyInfo.
EXPECT_TRUE(mouse_1.latency.FindLatency(
- ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, &component));
+ ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, nullptr));
}
WebTouchPoint CreateTouchPoint(WebTouchPoint::State state, int id) {
diff --git a/chromium/content/common/input/input_event_struct_traits.cc b/chromium/content/common/input/input_event_struct_traits.cc
index afa97f2064f..c67a68488d4 100644
--- a/chromium/content/common/input/input_event_struct_traits.cc
+++ b/chromium/content/common/input/input_event_struct_traits.cc
@@ -217,11 +217,14 @@ 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 (blink::WebInputEvent::IsPinchGestureEventType(type)) {
+ gesture_event->SetNeedsWheelEvent(false);
+ if (gesture_data->pinch_data &&
+ type == blink::WebInputEvent::Type::kGesturePinchUpdate) {
+ gesture_event->data.pinch_update.zoom_disabled = false;
+ gesture_event->data.pinch_update.scale =
+ gesture_data->pinch_data->scale;
+ }
}
if (gesture_data->tap_data) {
@@ -477,7 +480,6 @@ StructTraits<content::mojom::EventDataView, InputEventUniquePtr>::gesture_data(
break;
case blink::WebInputEvent::Type::kGesturePinchUpdate:
gesture_data->pinch_data = content::mojom::PinchData::New(
- gesture_event->data.pinch_update.zoom_disabled,
gesture_event->data.pinch_update.scale);
break;
}
diff --git a/chromium/content/common/input/input_handler.mojom b/chromium/content/common/input/input_handler.mojom
index 9f8a63e8b72..3f33f6c004f 100644
--- a/chromium/content/common/input/input_handler.mojom
+++ b/chromium/content/common/input/input_handler.mojom
@@ -90,7 +90,6 @@ struct ScrollData {
};
struct PinchData {
- bool zoom_disabled;
float scale;
};
diff --git a/chromium/content/common/input/sync_compositor_messages.h b/chromium/content/common/input/sync_compositor_messages.h
index a608f7eb160..f9d291fd30b 100644
--- a/chromium/content/common/input/sync_compositor_messages.h
+++ b/chromium/content/common/input/sync_compositor_messages.h
@@ -68,6 +68,7 @@ struct SyncCompositorCommonRendererParams {
float max_page_scale_factor = 0.f;
bool need_animate_scroll = false;
uint32_t need_invalidate_count = 0u;
+ bool invalidate_needs_draw = true;
uint32_t did_activate_pending_tree_count = 0u;
};
@@ -102,6 +103,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::SyncCompositorCommonRendererParams)
IPC_STRUCT_TRAITS_MEMBER(max_page_scale_factor)
IPC_STRUCT_TRAITS_MEMBER(need_animate_scroll)
IPC_STRUCT_TRAITS_MEMBER(need_invalidate_count)
+ IPC_STRUCT_TRAITS_MEMBER(invalidate_needs_draw)
IPC_STRUCT_TRAITS_MEMBER(did_activate_pending_tree_count)
IPC_STRUCT_TRAITS_END()
diff --git a/chromium/content/common/input/synchronous_compositor.mojom b/chromium/content/common/input/synchronous_compositor.mojom
index 3c139c417cc..e9b4b10247d 100644
--- a/chromium/content/common/input/synchronous_compositor.mojom
+++ b/chromium/content/common/input/synchronous_compositor.mojom
@@ -57,6 +57,10 @@ interface SynchronousCompositor {
uint32 metadata_version,
viz.mojom.CompositorFrameMetadata? meta_data);
+ // Instead of drawing, allow the compositor to finish the frame and update
+ // tiles if needed.
+ WillSkipDraw();
+
// Zero out the shared memory. This is necessary since most of the time,
// viewport size doesn't change between draws, it's cheaper to zero out
// and reuse the shared memory, instead of allocating and mapping a new
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 5cf6591d784..3bf1ed2b37a 100644
--- a/chromium/content/common/input/synthetic_web_input_event_builders.cc
+++ b/chromium/content/common/input/synthetic_web_input_event_builders.cc
@@ -102,6 +102,9 @@ WebGestureEvent SyntheticWebGestureEventBuilder::Build(
result.data.tap.tap_count = 1;
result.data.tap.width = 10;
result.data.tap.height = 10;
+ } else if (WebInputEvent::IsPinchGestureEventType(type)) {
+ result.SetNeedsWheelEvent(source_device ==
+ blink::kWebGestureDeviceTouchpad);
}
return result;
}
@@ -163,21 +166,26 @@ SyntheticWebTouchEvent::SyntheticWebTouchEvent() : WebTouchEvent() {
void SyntheticWebTouchEvent::ResetPoints() {
int activePointCount = 0;
- for (unsigned int i = 0; i < touches_length; ++i) {
+ unsigned count = 0;
+ for (unsigned int i = 0; i < kTouchesLengthCap; ++i) {
switch (touches[i].state) {
case WebTouchPoint::kStatePressed:
case WebTouchPoint::kStateMoved:
case WebTouchPoint::kStateStationary:
touches[i].state = WebTouchPoint::kStateStationary;
++activePointCount;
+ ++count;
break;
case WebTouchPoint::kStateReleased:
case WebTouchPoint::kStateCancelled:
touches[i] = WebTouchPoint();
+ ++count;
break;
case WebTouchPoint::kStateUndefined:
break;
}
+ if (count >= touches_length)
+ break;
}
touches_length = activePointCount;
type_ = WebInputEvent::kUndefined;
diff --git a/chromium/content/common/layer_tree_settings_factory.cc b/chromium/content/common/layer_tree_settings_factory.cc
deleted file mode 100644
index 5c33f1dcf10..00000000000
--- a/chromium/content/common/layer_tree_settings_factory.cc
+++ /dev/null
@@ -1,35 +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/layer_tree_settings_factory.h"
-
-#include "base/strings/string_number_conversions.h"
-#include "cc/base/switches.h"
-
-namespace content {
-
-// static
-void LayerTreeSettingsFactory::SetBrowserControlsSettings(
- cc::LayerTreeSettings& settings,
- const base::CommandLine& cmd) {
- if (cmd.HasSwitch(cc::switches::kBrowserControlsShowThreshold)) {
- std::string top_threshold_str =
- cmd.GetSwitchValueASCII(cc::switches::kBrowserControlsShowThreshold);
- double show_threshold;
- if (base::StringToDouble(top_threshold_str, &show_threshold) &&
- show_threshold >= 0.f && show_threshold <= 1.f)
- settings.top_controls_show_threshold = show_threshold;
- }
-
- if (cmd.HasSwitch(cc::switches::kBrowserControlsHideThreshold)) {
- std::string top_threshold_str =
- cmd.GetSwitchValueASCII(cc::switches::kBrowserControlsHideThreshold);
- double hide_threshold;
- if (base::StringToDouble(top_threshold_str, &hide_threshold) &&
- hide_threshold >= 0.f && hide_threshold <= 1.f)
- settings.top_controls_hide_threshold = hide_threshold;
- }
-}
-
-} // namespace content
diff --git a/chromium/content/common/layer_tree_settings_factory.h b/chromium/content/common/layer_tree_settings_factory.h
deleted file mode 100644
index cc808f75672..00000000000
--- a/chromium/content/common/layer_tree_settings_factory.h
+++ /dev/null
@@ -1,27 +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_LAYER_TREE_SETTINGS_FACTORY_H_
-#define CONTENT_COMMON_LAYER_TREE_SETTINGS_FACTORY_H_
-
-#include "base/command_line.h"
-#include "base/macros.h"
-#include "cc/trees/layer_tree_settings.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-// LayerTreeSettingsFactory holds utilities functions to generate
-// LayerTreeSettings.
-class CONTENT_EXPORT LayerTreeSettingsFactory {
- // TODO(xingliu): Refactor LayerTreeSettings generation logic.
- // crbug.com/577985
- public:
- static void SetBrowserControlsSettings(cc::LayerTreeSettings& settings,
- const base::CommandLine& command_line);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_LAYER_TREE_SETTINGS_FACTORY_H_
diff --git a/chromium/content/common/leveldb_wrapper.mojom b/chromium/content/common/leveldb_wrapper.mojom
deleted file mode 100644
index c2619016289..00000000000
--- a/chromium/content/common/leveldb_wrapper.mojom
+++ /dev/null
@@ -1,88 +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;
-
-import "components/services/leveldb/public/interfaces/leveldb.mojom";
-
-// Gives information about changes to a LevelDB database.
-// Note that observer methods are called before the callbacks for the
-// LevelDBWrapper methods are run.
-interface LevelDBObserver {
- KeyAdded(array<uint8> key, array<uint8> value, string source);
- KeyChanged(array<uint8> key, array<uint8> new_value, array<uint8> old_value,
- string source);
- KeyDeleted(array<uint8> key, array<uint8> old_value, string source);
- AllDeleted(string source);
-
- // Tells the client if it should send the old values for the key on Put() and
- // Delete() calls for sending notifications. By default the clients are
- // expected to send old values. It is set to true when the leveldb wrapper
- // does not cache values in memory.
- ShouldSendOldValueOnMutations(bool value);
-};
-
-struct KeyValue {
- array<uint8> key;
- array<uint8> value;
-};
-
-// Since the GetAll call is synchronous, LevelDBWrapper users need this
-// asynchronously delivered notification to avoid applying changes to the
-// returned array that it already contains. This is not sent over the
-// normal LevelDBObserver interface as there can be many observers and
-// only the connection that made the GetAll call needs to be notified of
-// its completion.
-interface LevelDBWrapperGetAllCallback {
- Complete(bool success);
-};
-
-// A wrapper around leveldb that supports giving notifications when values
-// change.
-// TODO(dmurph): rename & move LevelDBWrapper to DOMStorageDatabase as the
-// implementation is now tied specifically to that functionality.
-// https://crbug.com/809771
-interface LevelDBWrapper {
- AddObserver(associated LevelDBObserver observer);
-
- // Set the database entry for |key| to |value|.
- // Takes an optional |client_old_value| (see ShouldSendOldValueOnMutations()):
- // 1. If the client is notified to not send old value on mutations
- // |client_old_value| is unused and can be nullopt.
- // 2. If the client is notified to send old values or not notified at all,
- // |client_old_value| must be filled in with old value of the |key|, or
- // nullopt if |key| was not present in database. This value is used to send
- // notifications to LevelDBObserver(s).
- // Returns OK on success.
- Put(array<uint8> key, array<uint8> value, array<uint8>? client_old_value,
- string source) =>
- (bool success);
-
- // Remove the database entry (if any) for |key|.
- // Takes an optional |client_old_value| (see ShouldSendOldValueOnMutations()):
- // 1. If the client is notified to not send old value on mutations,
- // |client_old_value| is unused and can be nullopt.
- // 2. If the client is notified to send old values or not notified at all,
- // |client_old_value| must be filled in with old value of the |key|, or
- // nullopt if |key| was not present in database. This value is used to send
- // notifications to LevelDBObserver(s).
- // Returns OK on success, and a non-OK status on error. It is not an error if
- // |key| did not exist in the database.
- Delete(array<uint8> key, array<uint8>? client_old_value, string source) =>
- (bool success);
-
- // Removes all the entries.
- DeleteAll(string source) => (bool success);
-
- // [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);
-
- // Returns all key/value pairs.
- [Sync]
- GetAll(associated LevelDBWrapperGetAllCallback complete_callback)
- => (leveldb.mojom.DatabaseError status, array<KeyValue> data);
-};
diff --git a/chromium/content/common/media/cdm_info.cc b/chromium/content/common/media/cdm_info.cc
index 4e3dbbc1e71..aaf5347058e 100644
--- a/chromium/content/common/media/cdm_info.cc
+++ b/chromium/content/common/media/cdm_info.cc
@@ -9,29 +9,40 @@
namespace content {
-CdmInfo::CdmInfo(
- const std::string& name,
- const std::string& guid,
- const base::Version& version,
- const base::FilePath& path,
- const std::string& file_system_id,
- const std::vector<media::VideoCodec>& supported_video_codecs,
- bool supports_persistent_license,
- const base::flat_set<media::EncryptionMode>& supported_encryption_schemes,
- const std::string& supported_key_system,
- bool supports_sub_key_systems)
+CdmCapability::CdmCapability() = default;
+
+CdmCapability::CdmCapability(
+ std::vector<media::VideoCodec> video_codecs,
+ base::flat_set<media::EncryptionMode> encryption_schemes,
+ base::flat_set<media::CdmSessionType> session_types,
+ base::flat_set<media::CdmProxy::Protocol> cdm_proxy_protocols)
+ : video_codecs(std::move(video_codecs)),
+ encryption_schemes(std::move(encryption_schemes)),
+ session_types(std::move(session_types)),
+ cdm_proxy_protocols(std::move(cdm_proxy_protocols)) {}
+
+CdmCapability::CdmCapability(const CdmCapability& other) = default;
+
+CdmCapability::~CdmCapability() = default;
+
+CdmInfo::CdmInfo(const std::string& name,
+ const std::string& guid,
+ const base::Version& version,
+ const base::FilePath& path,
+ const std::string& file_system_id,
+ CdmCapability capability,
+ const std::string& supported_key_system,
+ bool supports_sub_key_systems)
: name(name),
guid(guid),
version(version),
path(path),
file_system_id(file_system_id),
- supported_video_codecs(supported_video_codecs),
- supports_persistent_license(supports_persistent_license),
- supported_encryption_schemes(supported_encryption_schemes),
+ capability(std::move(capability)),
supported_key_system(supported_key_system),
supports_sub_key_systems(supports_sub_key_systems) {
DCHECK(base::IsValidGUID(guid));
- DCHECK(!supported_encryption_schemes.empty());
+ DCHECK(!capability.encryption_schemes.empty());
}
CdmInfo::CdmInfo(const CdmInfo& other) = default;
diff --git a/chromium/content/common/media/media_player_delegate_messages.h b/chromium/content/common/media/media_player_delegate_messages.h
index 451ecbd4fbb..0b82193e462 100644
--- a/chromium/content/common/media/media_player_delegate_messages.h
+++ b/chromium/content/common/media/media_player_delegate_messages.h
@@ -59,6 +59,10 @@ IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_BecamePersistentVideo,
IPC_MESSAGE_ROUTED1(MediaPlayerDelegateMsg_EndPictureInPictureMode,
int /* delegate_id, distinguishes instances */)
+IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_ClickPictureInPictureControl,
+ int /* delegate_id, distinguishes instances */,
+ std::string /* control_id */)
+
IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_OnPictureInPictureWindowResize,
int /* delegate_id, distinguishes instances */,
gfx::Size /* window_size */)
diff --git a/chromium/content/common/media/media_player_messages_android.h b/chromium/content/common/media/media_player_messages_android.h
index a52e7f8e023..24b7fe5874c 100644
--- a/chromium/content/common/media/media_player_messages_android.h
+++ b/chromium/content/common/media/media_player_messages_android.h
@@ -176,9 +176,6 @@ IPC_MESSAGE_ROUTED2(MediaPlayerHostMsg_SetPoster,
int /* player_id */,
GURL /* poster url */)
-// Requests the player to enter fullscreen.
-IPC_MESSAGE_ROUTED1(MediaPlayerHostMsg_EnterFullscreen, int /* player_id */)
-
// Play the media on a remote device, if possible.
IPC_MESSAGE_ROUTED1(MediaPlayerHostMsg_RequestRemotePlayback,
int /* player_id */)
diff --git a/chromium/content/common/media/renderer_audio_input_stream_factory.mojom b/chromium/content/common/media/renderer_audio_input_stream_factory.mojom
index 63594e29fa6..8f258d924f9 100644
--- a/chromium/content/common/media/renderer_audio_input_stream_factory.mojom
+++ b/chromium/content/common/media/renderer_audio_input_stream_factory.mojom
@@ -44,7 +44,7 @@ interface RendererAudioInputStreamFactoryClient {
StreamCreated(
media.mojom.AudioInputStream stream,
media.mojom.AudioInputStreamClient& client_request,
- media.mojom.AudioDataPipe data_pipe,
+ media.mojom.ReadOnlyAudioDataPipe data_pipe,
bool initially_muted,
mojo_base.mojom.UnguessableToken? stream_id);
};
diff --git a/chromium/content/common/media/surface_view_manager_messages_android.h b/chromium/content/common/media/surface_view_manager_messages_android.h
deleted file mode 100644
index 50876424549..00000000000
--- a/chromium/content/common/media/surface_view_manager_messages_android.h
+++ /dev/null
@@ -1,30 +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_MEDIA_SURFACE_VIEW_MANAGER_MESSAGES_ANDROID_H_
-#define CONTENT_COMMON_MEDIA_SURFACE_VIEW_MANAGER_MESSAGES_ANDROID_H_
-
-// IPC messages for surface view manager.
-
-#include "content/common/content_export.h"
-#include "ipc/ipc_message_macros.h"
-#include "ui/gfx/geometry/size.h"
-
-#undef IPC_MESSAGE_EXPORT
-#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
-#define IPC_MESSAGE_START SurfaceViewManagerMsgStart
-
-// Message sent from the renderer to the browser
-
-IPC_MESSAGE_ROUTED1(SurfaceViewManagerHostMsg_CreateFullscreenSurface,
- gfx::Size /* video_natural_size */)
-IPC_MESSAGE_ROUTED1(SurfaceViewManagerHostMsg_NaturalSizeChanged,
- gfx::Size /* size */)
-
-// Message sent from the browser to the renderer
-
-IPC_MESSAGE_ROUTED1(SurfaceViewManagerMsg_FullscreenSurfaceCreated,
- int /* surface_id */)
-
-#endif // CONTENT_COMMON_MEDIA_SURFACE_VIEW_MANAGER_MESSAGES_ANDROID_H_
diff --git a/chromium/content/common/native_types.mojom b/chromium/content/common/native_types.mojom
index 08151055452..9ac02ea16b1 100644
--- a/chromium/content/common/native_types.mojom
+++ b/chromium/content/common/native_types.mojom
@@ -8,6 +8,10 @@ module content.mojom;
// ParamTraits for serialization. All of these should eventually be converted to
// proper mojom definitions.
+// NOTE: This type is only mapped and usable on Mac.
+[Native]
+struct EncodedAttributedString;
+
[Native]
struct FrameOwnerProperties;
@@ -40,6 +44,9 @@ struct WebPreferences;
enum NetworkConnectionType;
[Native]
+struct WebCursor;
+
+[Native]
enum WebPopupType;
[Native]
diff --git a/chromium/content/common/native_types.typemap b/chromium/content/common/native_types.typemap
index 35e7fbb50f7..8d6420575db 100644
--- a/chromium/content/common/native_types.typemap
+++ b/chromium/content/common/native_types.typemap
@@ -12,6 +12,7 @@ public_headers = [
"//content/common/visual_properties.h",
"//content/public/common/input_event_ack_source.h",
"//content/public/common/input_event_ack_state.h",
+ "//content/common/cursors/webcursor.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",
@@ -87,6 +88,7 @@ type_mappings = [
"content.mojom.TouchAction=cc::TouchAction",
"content.mojom.TouchActionOptional=cc::TouchAction",
"content.mojom.TouchState=blink::WebTouchPoint::State",
+ "content.mojom.WebCursor=content::WebCursor",
"content.mojom.WebPopupType=blink::WebPopupType",
"content.mojom.WebPreferences=content::WebPreferences",
]
diff --git a/chromium/content/common/native_types_mac.typemap b/chromium/content/common/native_types_mac.typemap
index c35085535e7..01262e1f16a 100644
--- a/chromium/content/common/native_types_mac.typemap
+++ b/chromium/content/common/native_types_mac.typemap
@@ -5,6 +5,7 @@
mojom = "//content/common/native_types.mojom"
os_whitelist = [ "mac" ]
public_headers = [
+ "//content/common/mac/attributed_string_coder.h",
"//third_party/blink/public/platform/web_scrollbar_buttons_placement.h",
"//third_party/blink/public/platform/mac/web_scrollbar_theme.h",
]
@@ -29,6 +30,7 @@ deps = [
"//url/ipc:url_ipc",
]
type_mappings = [
+ "content.mojom.EncodedAttributedString=::mac::AttributedStringCoder::EncodedString",
"content.mojom.ScrollerStyle=::blink::ScrollerStyle",
"content.mojom.ScrollbarButtonsPlacement=::blink::WebScrollbarButtonsPlacement",
]
diff --git a/chromium/content/common/navigation_client.mojom b/chromium/content/common/navigation_client.mojom
new file mode 100644
index 00000000000..d4331b67801
--- /dev/null
+++ b/chromium/content/common/navigation_client.mojom
@@ -0,0 +1,83 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.mojom;
+
+import "services/network/public/mojom/url_loader.mojom";
+import "services/network/public/mojom/url_loader_factory.mojom";
+import "content/common/service_worker/controller_service_worker.mojom";
+import "content/common/url_loader_factory_bundle.mojom";
+import "content/public/common/transferrable_url_loader.mojom";
+import "mojo/public/mojom/base/unguessable_token.mojom";
+import "url/mojom/url.mojom";
+import "third_party/blink/public/web/commit_result.mojom";
+
+// See src/content/common/navigation_params.h
+[Native]
+struct CommonNavigationParams;
+
+// See src/content/common/navigation_params.h
+[Native]
+struct RequestNavigationParams;
+
+interface NavigationClient {
+ // Tells the renderer that a navigation is ready to commit.
+ //
+ // The renderer should bind the |url_loader_client_endpoints| to an
+ // URLLoaderClient implementation to continue loading the document that will
+ // be the result of the committed navigation.
+ //
+ // Note: |url_loader_client_endpoints| will be empty iff the navigation URL
+ // wasn't handled by the network stack (i.e. about:blank, ...)
+ //
+ // When the Network Service is enabled, |subresource_loader_factories| may
+ // also be provided by the browser as a a means for the renderer to load
+ // subresources where applicable.
+ //
+ // |controller_service_worker_info| may also be provided by the browser if the
+ // frame that is being navigated is supposed to be controlled by a Service
+ // Worker.
+ // |prefetch_loader_factory| is populated only when Network Service is
+ // enabled. The pointer is used to start a prefetch loading via the browser
+ // process.
+ //
+ // 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(
+ network.mojom.URLResponseHead head,
+ CommonNavigationParams common_params,
+ RequestNavigationParams request_params,
+ network.mojom.URLLoaderClientEndpoints? url_loader_client_endpoints,
+ URLLoaderFactoryBundle? subresource_loader_factories,
+ array<TransferrableURLLoader>? subresource_overrides,
+ ControllerServiceWorkerInfo? controller_service_worker_info,
+ network.mojom.URLLoaderFactory? prefetch_loader_factory,
+ mojo_base.mojom.UnguessableToken devtools_navigation_token);
+
+ // Tells the renderer that a failed navigation is ready to commit.
+ //
+ // The result of this commit usually results in displaying an error page.
+ // Note |error_page_content| may contain the content of the error page
+ // (i.e. flattened HTML, JS, CSS).
+ //
+ // When the Network Service is enabled, |subresource_loader_factories| may
+ // also be provided by the browser as a means for the renderer to load
+ // subresources where applicable.
+ CommitFailedNavigation(
+ CommonNavigationParams common_params,
+ RequestNavigationParams request_params,
+ bool has_stale_copy_in_cache,
+ int32 error_code,
+ string? error_page_content,
+ URLLoaderFactoryBundle? subresource_loader_factories);
+};
+
diff --git a/chromium/content/common/navigation_params.cc b/chromium/content/common/navigation_params.cc
index e11e92e86c9..1ee0fe12301 100644
--- a/chromium/content/common/navigation_params.cc
+++ b/chromium/content/common/navigation_params.cc
@@ -33,8 +33,6 @@ CommonNavigationParams::CommonNavigationParams(
FrameMsg_Navigate_Type::Value navigation_type,
bool allow_download,
bool should_replace_current_entry,
- base::TimeTicks ui_timestamp,
- FrameMsg_UILoadMetricsReportType::Value report_type,
const GURL& base_url_for_data_url,
const GURL& history_url_for_data_url,
PreviewsState previews_state,
@@ -53,8 +51,6 @@ CommonNavigationParams::CommonNavigationParams(
navigation_type(navigation_type),
allow_download(allow_download),
should_replace_current_entry(should_replace_current_entry),
- ui_timestamp(ui_timestamp),
- report_type(report_type),
base_url_for_data_url(base_url_for_data_url),
history_url_for_data_url(history_url_for_data_url),
previews_state(previews_state),
diff --git a/chromium/content/common/navigation_params.h b/chromium/content/common/navigation_params.h
index e571195b1cb..08a7d0cf8f3 100644
--- a/chromium/content/common/navigation_params.h
+++ b/chromium/content/common/navigation_params.h
@@ -66,8 +66,6 @@ struct CONTENT_EXPORT CommonNavigationParams {
FrameMsg_Navigate_Type::Value navigation_type,
bool allow_download,
bool should_replace_current_entry,
- base::TimeTicks ui_timestamp,
- FrameMsg_UILoadMetricsReportType::Value report_type,
const GURL& base_url_for_data_url,
const GURL& history_url_for_data_url,
PreviewsState previews_state,
@@ -109,15 +107,6 @@ struct CONTENT_EXPORT CommonNavigationParams {
// the navigation commits, it should commit in the existing page.
bool should_replace_current_entry = false;
- // Timestamp of the user input event that triggered this navigation. Empty if
- // the navigation was not triggered by clicking on a link or by receiving an
- // intent on Android.
- base::TimeTicks ui_timestamp;
-
- // The report type to be used when recording the metric using |ui_timestamp|.
- FrameMsg_UILoadMetricsReportType::Value report_type =
- FrameMsg_UILoadMetricsReportType::NO_REPORT;
-
// Base URL for use in Blink's SubstituteData.
// Is only used with data: URLs.
GURL base_url_for_data_url;
@@ -167,6 +156,10 @@ struct CONTENT_EXPORT CommonNavigationParams {
// We require a copy of the relevant CSP to perform navigation checks.
std::vector<ContentSecurityPolicy> initiator_csp;
base::Optional<CSPSource> initiator_self_source;
+
+ // The current origin policy for this request's origin.
+ // (Empty if none applies.)
+ std::string origin_policy;
};
// Provided by the browser -----------------------------------------------------
diff --git a/chromium/content/common/navigation_subresource_loader_params.cc b/chromium/content/common/navigation_subresource_loader_params.cc
index 7c08e6bdda4..de8e9ff41db 100644
--- a/chromium/content/common/navigation_subresource_loader_params.cc
+++ b/chromium/content/common/navigation_subresource_loader_params.cc
@@ -19,7 +19,8 @@ SubresourceLoaderParams& SubresourceLoaderParams::operator=(
loader_factory_info = std::move(other.loader_factory_info);
controller_service_worker_info =
std::move(other.controller_service_worker_info);
- controller_service_worker_handle = other.controller_service_worker_handle;
+ controller_service_worker_object_host =
+ other.controller_service_worker_object_host;
return *this;
}
diff --git a/chromium/content/common/navigation_subresource_loader_params.h b/chromium/content/common/navigation_subresource_loader_params.h
index bb3407579f7..c92e942c043 100644
--- a/chromium/content/common/navigation_subresource_loader_params.h
+++ b/chromium/content/common/navigation_subresource_loader_params.h
@@ -11,7 +11,7 @@
namespace content {
-class ServiceWorkerHandle;
+class ServiceWorkerObjectHost;
// For NetworkService glues:
// Navigation parameters that are necessary to set-up a subresource loader
@@ -34,10 +34,10 @@ struct CONTENT_EXPORT SubresourceLoaderParams {
//
// |controller_service_worker_info->object_info| is "incomplete". It must be
// updated before being sent over Mojo and then registered with
- // |controller_service_worker_handle|. See
- // ServiceWorkerHandle::CreateIncompleteObjectInfo() for details.
+ // |controller_service_worker_object_host|. See
+ // ServiceWorkerObjectHost::CreateIncompleteObjectInfo() for details.
mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info;
- base::WeakPtr<ServiceWorkerHandle> controller_service_worker_handle;
+ base::WeakPtr<ServiceWorkerObjectHost> controller_service_worker_object_host;
};
} // namespace content
diff --git a/chromium/content/common/net/record_load_histograms.cc b/chromium/content/common/net/record_load_histograms.cc
new file mode 100644
index 00000000000..9ba74607b0a
--- /dev/null
+++ b/chromium/content/common/net/record_load_histograms.cc
@@ -0,0 +1,42 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/net/record_load_histograms.h"
+
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/string_piece.h"
+#include "content/public/common/resource_type.h"
+#include "net/base/net_errors.h"
+#include "net/base/url_util.h"
+#include "url/gurl.h"
+
+namespace content {
+
+void RecordLoadHistograms(const GURL& url, int resource_type, int net_error) {
+ // Requests shouldn't complete with net::ERR_IO_PENDING.
+ DCHECK_NE(net::ERR_IO_PENDING, net_error);
+
+ if (resource_type == RESOURCE_TYPE_MAIN_FRAME) {
+ base::UmaHistogramSparse("Net.ErrorCodesForMainFrame4", -net_error);
+ if (url.SchemeIsCryptographic()) {
+ if (url.host_piece() == "www.google.com") {
+ base::UmaHistogramSparse("Net.ErrorCodesForHTTPSGoogleMainFrame3",
+ -net_error);
+ }
+
+ if (net::IsTLS13ExperimentHost(url.host_piece())) {
+ base::UmaHistogramSparse("Net.ErrorCodesForTLS13ExperimentMainFrame2",
+ -net_error);
+ }
+ }
+ } else {
+ if (resource_type == RESOURCE_TYPE_IMAGE) {
+ base::UmaHistogramSparse("Net.ErrorCodesForImages2", -net_error);
+ }
+ base::UmaHistogramSparse("Net.ErrorCodesForSubresources3", -net_error);
+ }
+}
+
+} // namespace content
diff --git a/chromium/content/common/net/record_load_histograms.h b/chromium/content/common/net/record_load_histograms.h
new file mode 100644
index 00000000000..851d5cdf196
--- /dev/null
+++ b/chromium/content/common/net/record_load_histograms.h
@@ -0,0 +1,19 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_NET_RECORD_LOAD_HISTOGRAMS_H_
+#define CONTENT_COMMON_NET_RECORD_LOAD_HISTOGRAMS_H_
+
+class GURL;
+
+namespace content {
+
+// Logs histograms when a resource destined for a renderer (One with a
+// content::ResourceType) finishes loading, or when a load is aborted. Not used
+// for internal network requests initiated by the browser itself.
+void RecordLoadHistograms(const GURL& url, int resource_type, int net_error);
+
+} // namespace content
+
+#endif // CONTENT_COMMON_NET_RECORD_LOAD_HISTOGRAMS_H_
diff --git a/chromium/content/common/net/url_fetcher.cc b/chromium/content/common/net/url_fetcher.cc
deleted file mode 100644
index 9af15ee5ddb..00000000000
--- a/chromium/content/common/net/url_fetcher.cc
+++ /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.
-
-#include "content/public/common/url_fetcher.h"
-
-#include "base/bind.h"
-#include "content/common/net/url_request_user_data.h"
-#include "net/url_request/url_fetcher.h"
-
-namespace content {
-
-namespace {
-
-std::unique_ptr<base::SupportsUserData::Data> CreateURLRequestUserData(
- int render_process_id,
- int render_frame_id) {
- return std::make_unique<URLRequestUserData>(render_process_id,
- render_frame_id);
-}
-
-} // namespace
-
-void AssociateURLFetcherWithRenderFrame(
- net::URLFetcher* url_fetcher,
- const base::Optional<url::Origin>& initiator,
- int render_process_id,
- int render_frame_id) {
- url_fetcher->SetInitiator(initiator);
- url_fetcher->SetURLRequestUserData(
- URLRequestUserData::kUserDataKey,
- base::Bind(&CreateURLRequestUserData, render_process_id,
- render_frame_id));
-}
-
-} // namespace content
diff --git a/chromium/content/common/net/url_request_user_data.h b/chromium/content/common/net/url_request_user_data.h
index fd45591e1f9..c679aeea18e 100644
--- a/chromium/content/common/net/url_request_user_data.h
+++ b/chromium/content/common/net/url_request_user_data.h
@@ -6,12 +6,13 @@
#define CONTENT_COMMON_NET_URL_REQUEST_USER_DATA_H_
#include "base/supports_user_data.h"
+#include "content/common/content_export.h"
namespace content {
// Used to annotate all URLRequests for which the request can be associated
// with a given RenderFrame.
-class URLRequestUserData : public base::SupportsUserData::Data {
+class CONTENT_EXPORT URLRequestUserData : public base::SupportsUserData::Data {
public:
URLRequestUserData(int render_process_id,
int render_frame_id);
diff --git a/chromium/content/common/page_message_enums.h b/chromium/content/common/page_message_enums.h
deleted file mode 100644
index c4e0ce6a2d1..00000000000
--- a/chromium/content/common/page_message_enums.h
+++ /dev/null
@@ -1,15 +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_PAGE_MESSAGE_ENUMS_H_
-#define CONTENT_COMMON_PAGE_MESSAGE_ENUMS_H_
-
-enum class PageMsg_SetZoomLevel_Command {
- SET_TEMPORARY,
- CLEAR_TEMPORARY,
- USE_CURRENT_TEMPORARY_MODE,
- LAST = USE_CURRENT_TEMPORARY_MODE
-};
-
-#endif // CONTENT_COMMON_PAGE_MESSAGE_ENUMS_H_
diff --git a/chromium/content/common/page_messages.h b/chromium/content/common/page_messages.h
index 4e8cf807539..27b26a53ea8 100644
--- a/chromium/content/common/page_messages.h
+++ b/chromium/content/common/page_messages.h
@@ -5,7 +5,6 @@
#ifndef CONTENT_COMMON_PAGE_MESSAGES_H_
#define CONTENT_COMMON_PAGE_MESSAGES_H_
-#include "content/common/page_message_enums.h"
#include "content/public/common/screen_info.h"
#include "ipc/ipc_message_macros.h"
#include "ui/gfx/geometry/rect.h"
@@ -18,19 +17,11 @@
#define IPC_MESSAGE_START PageMsgStart
-IPC_ENUM_TRAITS_MAX_VALUE(
- PageMsg_SetZoomLevel_Command,
- PageMsg_SetZoomLevel_Command::LAST)
-
// Messages sent from the browser to the renderer.
IPC_MESSAGE_ROUTED1(PageMsg_UpdateWindowScreenRect,
gfx::Rect /* window_screen_rect */)
-IPC_MESSAGE_ROUTED2(PageMsg_SetZoomLevel,
- PageMsg_SetZoomLevel_Command /* command */,
- double /* zoom_level */)
-
// Informs the renderer that the page was hidden.
IPC_MESSAGE_ROUTED0(PageMsg_WasHidden)
@@ -54,9 +45,9 @@ IPC_MESSAGE_ROUTED1(PageMsg_PausePageScheduledTasks, bool /* paused */)
IPC_MESSAGE_ROUTED1(PageMsg_UpdateScreenInfo,
content::ScreenInfo /* screen_info */)
-// Sent to all renderers, instructing them to freeze all frames that belongs to
-// this page.
-IPC_MESSAGE_ROUTED0(PageMsg_FreezePage)
+// Sent to all renderers, instructing them to freeze or unfreeze all frames that
+// belongs to this page.
+IPC_MESSAGE_ROUTED1(PageMsg_SetPageFrozen, bool /* frozen */)
// -----------------------------------------------------------------------------
// Messages sent from the renderer to the browser.
diff --git a/chromium/content/common/platform_notification_messages.h b/chromium/content/common/platform_notification_param_traits.h
index b925cdcd4fd..22d6b927e19 100644
--- a/chromium/content/common/platform_notification_messages.h
+++ b/chromium/content/common/platform_notification_param_traits.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_PLATFORM_NOTIFICATION_MESSAGES_H_
-#define CONTENT_COMMON_PLATFORM_NOTIFICATION_MESSAGES_H_
+#ifndef CONTENT_COMMON_PLATFORM_NOTIFICATION_PARAM_TRAITS_H_
+#define CONTENT_COMMON_PLATFORM_NOTIFICATION_PARAM_TRAITS_H_
// Messages for platform-native notifications using the Web Notification API.
@@ -17,13 +17,10 @@
#include "content/public/common/platform_notification_data.h"
#include "ipc/ipc_message_macros.h"
-#define IPC_MESSAGE_START PlatformNotificationMsgStart
-
// TODO(https://crbug.com/841329): Delete this legacy IPC code, use a pure
-// mojo struct instead from ServiceWorkerEventDispatcher mojo interface.
-IPC_ENUM_TRAITS_MAX_VALUE(
- content::PlatformNotificationData::Direction,
- content::PlatformNotificationData::DIRECTION_LAST)
+// mojo struct instead from ServiceWorker mojo interface.
+IPC_ENUM_TRAITS_MAX_VALUE(content::PlatformNotificationData::Direction,
+ content::PlatformNotificationData::DIRECTION_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(content::PlatformNotificationActionType,
content::PLATFORM_NOTIFICATION_ACTION_TYPE_TEXT)
@@ -54,4 +51,4 @@ IPC_STRUCT_TRAITS_BEGIN(content::PlatformNotificationData)
IPC_STRUCT_TRAITS_MEMBER(actions)
IPC_STRUCT_TRAITS_END()
-#endif // CONTENT_COMMON_PLATFORM_NOTIFICATION_MESSAGES_H_
+#endif // CONTENT_COMMON_PLATFORM_NOTIFICATION_PARAM_TRAITS_H_
diff --git a/chromium/content/common/render_frame_metadata.mojom b/chromium/content/common/render_frame_metadata.mojom
index 28573c16b7b..1470abb5978 100644
--- a/chromium/content/common/render_frame_metadata.mojom
+++ b/chromium/content/common/render_frame_metadata.mojom
@@ -43,15 +43,42 @@ struct RenderFrameMetadata {
// The last viz::LocalSurfaceId used to submit a CompositorFrame.
viz.mojom.LocalSurfaceId? local_surface_id;
+ // The page scale factor used on the content.
+ float page_scale_factor;
+
// Used to position the Android location top bar and page content, whose
// precise position is computed by the renderer compositor.
+ [EnableIf=is_android]
float top_controls_height;
+
+ [EnableIf=is_android]
float top_controls_shown_ratio;
// Used to position Android bottom bar, whose position is computed by the
// renderer compositor.
+ [EnableIf=is_android]
float bottom_controls_height;
+
+ [EnableIf=is_android]
float bottom_controls_shown_ratio;
+
+ [EnableIf=is_android]
+ float min_page_scale_factor;
+
+ [EnableIf=is_android]
+ float max_page_scale_factor;
+
+ [EnableIf=is_android]
+ bool root_overflow_y_hidden;
+
+ [EnableIf=is_android]
+ gfx.mojom.SizeF scrollable_viewport_size;
+
+ [EnableIf=is_android]
+ gfx.mojom.SizeF root_layer_size;
+
+ [EnableIf=is_android]
+ bool has_transparent_background;
};
// This interface is provided by the renderer. It can optionally enable
diff --git a/chromium/content/common/render_frame_metadata_struct_traits.cc b/chromium/content/common/render_frame_metadata_struct_traits.cc
index f17bfdf991d..302e4cd3bfa 100644
--- a/chromium/content/common/render_frame_metadata_struct_traits.cc
+++ b/chromium/content/common/render_frame_metadata_struct_traits.cc
@@ -4,6 +4,7 @@
#include "content/common/render_frame_metadata_struct_traits.h"
+#include "build/build_config.h"
#include "services/viz/public/cpp/compositing/selection_struct_traits.h"
#include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
#include "ui/gfx/mojo/selection_bound_struct_traits.h"
@@ -19,12 +20,23 @@ bool StructTraits<content::mojom::RenderFrameMetadataDataView,
out->is_scroll_offset_at_top = data.is_scroll_offset_at_top();
out->is_mobile_optimized = data.is_mobile_optimized();
out->device_scale_factor = data.device_scale_factor();
+ out->page_scale_factor = data.page_scale_factor();
+#if defined(OS_ANDROID)
out->top_controls_height = data.top_controls_height();
out->top_controls_shown_ratio = data.top_controls_shown_ratio();
out->bottom_controls_height = data.bottom_controls_height();
out->bottom_controls_shown_ratio = data.bottom_controls_shown_ratio();
+ out->min_page_scale_factor = data.min_page_scale_factor();
+ out->max_page_scale_factor = data.max_page_scale_factor();
+ out->root_overflow_y_hidden = data.root_overflow_y_hidden();
+ out->has_transparent_background = data.has_transparent_background();
+#endif
return data.ReadRootScrollOffset(&out->root_scroll_offset) &&
data.ReadSelection(&out->selection) &&
+#if defined(OS_ANDROID)
+ data.ReadScrollableViewportSize(&out->scrollable_viewport_size) &&
+ data.ReadRootLayerSize(&out->root_layer_size) &&
+#endif
data.ReadViewportSizeInPixels(&out->viewport_size_in_pixels) &&
data.ReadLocalSurfaceId(&out->local_surface_id);
}
diff --git a/chromium/content/common/render_frame_metadata_struct_traits.h b/chromium/content/common/render_frame_metadata_struct_traits.h
index fbf17edfa65..5f76e36fd52 100644
--- a/chromium/content/common/render_frame_metadata_struct_traits.h
+++ b/chromium/content/common/render_frame_metadata_struct_traits.h
@@ -6,6 +6,7 @@
#define CONTENT_COMMON_RENDER_FRAME_METADATA_STRUCT_TRAITS_H_
#include "base/optional.h"
+#include "build/build_config.h"
#include "cc/trees/render_frame_metadata.h"
#include "content/common/render_frame_metadata.mojom-shared.h"
#include "services/viz/public/cpp/compositing/local_surface_id_struct_traits.h"
@@ -52,6 +53,11 @@ struct StructTraits<content::mojom::RenderFrameMetadataDataView,
return metadata.local_surface_id;
}
+ static float page_scale_factor(const cc::RenderFrameMetadata& metadata) {
+ return metadata.page_scale_factor;
+ }
+
+#if defined(OS_ANDROID)
static float top_controls_height(const cc::RenderFrameMetadata& metadata) {
return metadata.top_controls_height;
}
@@ -70,6 +76,34 @@ struct StructTraits<content::mojom::RenderFrameMetadataDataView,
return metadata.bottom_controls_shown_ratio;
}
+ static float min_page_scale_factor(const cc::RenderFrameMetadata& metadata) {
+ return metadata.min_page_scale_factor;
+ }
+
+ static float max_page_scale_factor(const cc::RenderFrameMetadata& metadata) {
+ return metadata.max_page_scale_factor;
+ }
+
+ static bool root_overflow_y_hidden(const cc::RenderFrameMetadata& metadata) {
+ return metadata.root_overflow_y_hidden;
+ }
+
+ static const gfx::SizeF& scrollable_viewport_size(
+ const cc::RenderFrameMetadata& metadata) {
+ return metadata.scrollable_viewport_size;
+ }
+
+ static const gfx::SizeF& root_layer_size(
+ const cc::RenderFrameMetadata& metadata) {
+ return metadata.root_layer_size;
+ }
+
+ static bool has_transparent_background(
+ const cc::RenderFrameMetadata& metadata) {
+ return metadata.has_transparent_background;
+ }
+#endif
+
static bool Read(content::mojom::RenderFrameMetadataDataView data,
cc::RenderFrameMetadata* out);
};
diff --git a/chromium/content/common/render_widget_host_ns_view.mojom b/chromium/content/common/render_widget_host_ns_view.mojom
new file mode 100644
index 00000000000..08667c119ac
--- /dev/null
+++ b/chromium/content/common/render_widget_host_ns_view.mojom
@@ -0,0 +1,230 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module content.mojom;
+
+import "content/common/native_types.mojom";
+import "content/common/input/input_handler.mojom";
+import "mojo/public/mojom/base/string16.mojom";
+import "services/ui/public/interfaces/ime/ime.mojom";
+import "ui/display/mojo/display.mojom";
+import "ui/events/mojo/event.mojom";
+import "ui/gfx/geometry/mojo/geometry.mojom";
+import "ui/gfx/mojo/ca_layer_params.mojom";
+import "ui/gfx/range/mojo/range.mojom";
+import "ui/platform_window/mojo/text_input_state.mojom";
+
+// The interface through which code in the browser process, in
+// RenderWidgetHostViewMac, sends messages to the app shim process, targeting
+// the RenderWidgetHostViewCocoa NSView. No synchronous communication is allowed
+// in this direction.
+interface RenderWidgetHostNSViewBridge {
+ // Specify that the NSView will a popup (e.g, date/time picker) that will
+ // create its own NSWindow.
+ InitAsPopup(gfx.mojom.Rect content_rect,
+ content.mojom.WebPopupType popup_type);
+
+ // Disable displaying any content (including the background color). This is
+ // to be called on views that are to be displayed via a parent ui::Compositor.
+ DisableDisplay();
+
+ // Make the NSView be the first responder of its NSWindow.
+ MakeFirstResponder();
+
+ // Set the bounds of the NSView or its enclosing NSWindow (depending on the
+ // window type).
+ SetBounds(gfx.mojom.Rect rect);
+
+ // Set the contents to display in the NSView.
+ SetCALayerParams(gfx.mojom.CALayerParams ca_layer_params);
+
+ // Set the background SkColor color of the hosted CALayer.
+ SetBackgroundColor(uint32 color);
+
+ // Call the -[NSView setHidden:] method.
+ SetVisible(bool visible);
+
+ // Call the -[NSView setToolTipAtMousePoint] method.
+ SetTooltipText(mojo_base.mojom.String16 display_text);
+
+ // Forward changes in ui::TextInputType.
+ SetTextInputType(ui.mojom.TextInputType text_input_type);
+
+ // Forward the TextInputManager::TextSelection from the renderer.
+ SetTextSelection(mojo_base.mojom.String16 text,
+ uint64 offset,
+ gfx.mojom.Range range);
+
+ // Forward the TextInputManager::CompositionRangeInfo from the renderer.
+ SetCompositionRangeInfo(gfx.mojom.Range range);
+
+ // Clear the marked range.
+ CancelComposition();
+
+ // Indicate if the WebContext is showing a context menu or not.
+ SetShowingContextMenu(bool showing);
+
+ // Set the cursor type to display.
+ DisplayCursor(WebCursor cursor);
+
+ // Lock or unlock the cursor.
+ SetCursorLocked(bool locked);
+
+ // Open the dictionary overlay for the currently selected string. This
+ // will roundtrip to the NSView to determine the selected range.
+ ShowDictionaryOverlayForSelection();
+
+ // Open the dictionary overlay for the specified string at the specified
+ // point.
+ ShowDictionaryOverlay(EncodedAttributedString attributed_string,
+ gfx.mojom.Point baseline_point);
+
+ // Start intercepting keyboard events for the specified codes.
+ LockKeyboard(array<uint32>? dom_codes);
+
+ // Stop intercepting keyboard events.
+ UnlockKeyboard();
+};
+
+// The interface through which the RenderWidgetHostViewCocoa NSView in the app
+// shim process communicates to the RenderWidgetHostViewMac in the browser
+// process. Synchronous calls are allowed to be made through this interface.
+// TODO(ccameron): This corresponds almost one-to-one with the
+// content::RenderWidgetHostNSViewClient interface. It may be possible to merge
+// these two interfaces, though that may come at the cost of extra work (e.g,
+// de-serializing and re-serializing all events).
+// https://crbug.com/821651
+interface RenderWidgetHostNSViewClient {
+ // Synchronously query if there exists a RenderViewHost for the corresponding
+ // RenderWidgetHostView's RenderWidgetHost, and return the result as
+ // |is_render_view|.
+ [Sync]
+ SyncIsRenderViewHost() => (bool is_render_view);
+
+ // Request that the RenderWidgetHost be shut down (e.g, when a date/time
+ // picker window is closed).
+ RequestShutdown();
+
+ // Indicates whether or not the NSView is its NSWindow's first responder.
+ OnFirstResponderChanged(bool is_first_responder);
+
+ // Indicates whether or not the NSView is its NSWindow's first responder.
+ OnWindowIsKeyChanged(bool is_key);
+
+ // Indicates whether or not the NSView's NSWindow is key.
+ OnBoundsInWindowChanged(
+ gfx.mojom.Rect view_bounds_in_window_dip,
+ bool attached_to_window);
+
+ // Indicates the NSView's bounds in its NSWindow's DIP coordinate system (with
+ // the origin at the upper-left corner), and indicate if the the NSView is
+ // attached to an NSWindow (if it is not, then |view_bounds_in_window_dip|'s
+ // origin is meaningless, but its size is still relevant).
+ OnWindowFrameInScreenChanged(
+ gfx.mojom.Rect window_frame_in_screen_dip);
+
+ // Indicate changes to the NSView's NSScreen's properties.
+ OnDisplayChanged(display.mojom.Display display);
+
+ // Indicate the begin and end block of a keyboard event. The beginning of this
+ // block will record the active RenderWidgetHost, and will forward all
+ // remaining keyboard and Ime messages to that RenderWidgetHost.
+ BeginKeyboardEvent();
+ EndKeyboardEvent();
+
+ // Forward a keyboard event to the RenderWidgetHost that is currently handling
+ // the key-down event.
+ ForwardKeyboardEvent(Event event, bool skip_in_browser);
+ ForwardKeyboardEventWithCommands(
+ Event event,
+ bool skip_in_browser,
+ array<content.mojom.EditCommand> commands);
+
+ // Forward events to the renderer or the input router, as appropriate.
+ RouteOrProcessMouseEvent(Event event);
+ RouteOrProcessWheelEvent(Event event);
+
+ // Special case forwarding of synthetic events to the renderer.
+ ForwardMouseEvent(Event event);
+ ForwardWheelEvent(Event event);
+
+ // Handling pinch gesture events. Note that for GestureBegin, the type of the
+ // event is ignored, and is inferred from subsequent GestureUpdate calls.
+ GestureBegin(Event event, bool is_synthetically_injected);
+ GestureUpdate(Event event);
+ GestureEnd(Event event);
+
+ // Handle a double-tap magnify event.
+ SmartMagnify(Event event);
+
+ // Forward the corresponding Ime commands to the appropriate RenderWidgetHost.
+ // Appropriate, has two meanings here. If this is during a key-down event,
+ // then the target is the RWH that is handling that key-down event. Otherwise,
+ // it is the result of GetActiveWidget.
+ ImeSetComposition(
+ mojo_base.mojom.String16 text,
+ array<ui.mojom.ImeTextSpan> ime_text_spans,
+ gfx.mojom.Range replacement_range,
+ int32 selection_start,
+ int32 selection_end);
+ ImeCommitText(mojo_base.mojom.String16 text,
+ gfx.mojom.Range replacement_range);
+ ImeFinishComposingText();
+ // Note that the function name ImeCancelComposition would conflict with a
+ // method in RenderWidgetHostViewBase.
+ ImeCancelCompositionFromCocoa();
+
+ // Request an overlay dictionary be displayed for the text at the specified
+ // point.
+ LookUpDictionaryOverlayAtPoint(gfx.mojom.PointF root_point);
+
+ // Request an overlay dictionary be displayed for the text in the the
+ // specified character range.
+ LookUpDictionaryOverlayFromRange(gfx.mojom.Range range);
+
+ // Synchronously query the character index for |root_point|. Return UINT32_MAX
+ // if the request fails or is not completed.
+ [Sync]
+ SyncGetCharacterIndexAtPoint(
+ gfx.mojom.PointF root_point) => (uint32 index);
+
+ // Synchronously query the composition character boundary rectangle and return
+ // it as |out_rect|. Return |out_actual_range| as the range actually used for
+ // the returned rectangle. If there was no focused RenderWidgetHost to query,
+ // then return |success| as false.
+ [Sync]
+ SyncGetFirstRectForRange(
+ gfx.mojom.Range
+ requested_range,
+ gfx.mojom.Rect rect,
+ gfx.mojom.Range actual_range) =>
+ (gfx.mojom.Rect out_rect,
+ gfx.mojom.Range out_actual_range,
+ bool success);
+
+ // Forward the corresponding edit menu command to the RenderWidgetHost's
+ // delegate.
+ ExecuteEditCommand(string command);
+ Undo();
+ Redo();
+ Cut();
+ Copy();
+ CopyToFindPboard();
+ Paste();
+ PasteAndMatchStyle();
+ SelectAll();
+
+ // Speak the selected text of the appropriate RenderWidgetHostView using
+ // TextServicesContextMenu.
+ StartSpeaking();
+
+ // Stop speaking using TextServicesContextMenu.
+ StopSpeaking();
+
+ // Synchronously query if TextServicesContextMenu is currently speaking and
+ // return the result as |is_speaking|.
+ [Sync]
+ SyncIsSpeaking() => (bool is_speaking);
+};
+
diff --git a/chromium/content/common/renderer.mojom b/chromium/content/common/renderer.mojom
index 2405622dde3..31266ed6077 100644
--- a/chromium/content/common/renderer.mojom
+++ b/chromium/content/common/renderer.mojom
@@ -13,7 +13,6 @@ import "services/network/public/mojom/network_types.mojom";
import "services/service_manager/public/mojom/interface_provider.mojom";
import "services/service_manager/public/mojom/service.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom";
-import "ui/gfx/mojo/icc_profile.mojom";
struct CreateViewParams {
// Renderer-wide preferences.
@@ -82,9 +81,6 @@ struct CreateViewParams {
// The initial renderer size.
VisualProperties visual_properties;
- // The page zoom level.
- double page_zoom_level;
-
// Whether lookup of frames in the created RenderView (e.g. lookup via
// window.open or via <a target=...>) should be renderer-wide (i.e. going
// beyond the usual opener-relationship-based BrowsingInstance boundaries).
@@ -254,4 +250,16 @@ interface Renderer {
// Tells the renderer process to purge and suspend.
ProcessPurgeAndSuspend();
+
+ // Tells the renderer process that it has been locked to a site (i.e., a
+ // scheme plus eTLD+1, such as https://google.com), or to a more specific
+ // origin.
+ SetIsLockedToSite();
+
+ // Tells the renderer to enable V8's memory saving mode when possible.
+ // This is only used when site-per-process is enabled. If the process
+ // only contains subframes, V8's low memory mode will be enabled.
+ // If a main frame exists or is created, the low memory mode will
+ // be disabled.
+ EnableV8LowMemoryMode();
};
diff --git a/chromium/content/common/renderer_host.mojom b/chromium/content/common/renderer_host.mojom
index eefa2e1535d..9b35f6fb75f 100644
--- a/chromium/content/common/renderer_host.mojom
+++ b/chromium/content/common/renderer_host.mojom
@@ -4,14 +4,9 @@
module content.mojom;
-import "services/network/public/mojom/url_loader_factory.mojom";
-
// The primordial interface implemented by a render process host. This should be
// used for implementing renderer-to-browser messages.
interface RendererHost {
- // Requests a URLLoaderFactory for the blob scheme.
- GetBlobURLLoaderFactory(network.mojom.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.
diff --git a/chromium/content/common/sandbox_init_mac.cc b/chromium/content/common/sandbox_init_mac.cc
index ee6202e3178..6bd5d2b657e 100644
--- a/chromium/content/common/sandbox_init_mac.cc
+++ b/chromium/content/common/sandbox_init_mac.cc
@@ -8,16 +8,16 @@
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
-#include "content/public/common/content_switches.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_info.h"
#include "gpu/config/gpu_info_collector.h"
+#include "gpu/config/gpu_preferences.h"
#include "gpu/config/gpu_switches.h"
#include "gpu/config/gpu_switching.h"
#include "gpu/config/gpu_util.h"
-#include "gpu/ipc/common/gpu_preferences_util.h"
#include "media/gpu/vt_video_decode_accelerator_mac.h"
#include "sandbox/mac/seatbelt.h"
+#include "sandbox/mac/seatbelt_exec.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"
@@ -47,24 +47,18 @@ base::OnceClosure MaybeWrapWithGPUSandboxHook(
if (command_line->HasSwitch(switches::kGpuPreferences)) {
std::string value =
command_line->GetSwitchValueASCII(switches::kGpuPreferences);
- bool success =
- gpu::SwitchValueToGpuPreferences(value, &gpu_preferences);
+ bool success = gpu_preferences.FromSwitchValue(value);
CHECK(success);
}
bool needs_more_info = false;
gpu::GpuFeatureInfo gpu_feature_info = gpu::ComputeGpuFeatureInfo(
- gpu_info, gpu_preferences.ignore_gpu_blacklist,
- gpu_preferences.disable_gpu_driver_bug_workarounds,
- gpu_preferences.log_gpu_control_list_decisions, command_line,
- &needs_more_info);
+ gpu_info, gpu_preferences, command_line, &needs_more_info);
gpu::CacheGpuFeatureInfo(gpu_feature_info);
if (gpu::SwitchableGPUsSupported(gpu_info, *command_line)) {
gpu::InitializeSwitchableGPUs(
gpu_feature_info.enabled_gpu_driver_bug_workarounds);
}
- // Calling ShouldEnableSwiftShader will append the proper command line
- // switch in order to enable SwiftShader if required.
- gpu::ShouldEnableSwiftShader(
+ gpu::EnableSwiftShaderIfNeeded(
command_line, gpu_feature_info,
gpu_preferences.disable_software_rasterizer, needs_more_info);
// Preload either the desktop GL or the osmesa so, depending on the
@@ -92,7 +86,7 @@ bool GetSandboxTypeFromCommandLine(service_manager::SandboxType* sandbox_type) {
if (service_manager::IsUnsandboxedSandboxType(*sandbox_type))
return false;
- if (command_line->HasSwitch(switches::kV2SandboxedEnabled)) {
+ if (command_line->HasSwitch(sandbox::switches::kSeatbeltClientName)) {
CHECK(sandbox::Seatbelt::IsSandboxed());
// Do not enable the sandbox if V2 is already enabled.
return false;
diff --git a/chromium/content/common/sandbox_policy_fuchsia.cc b/chromium/content/common/sandbox_policy_fuchsia.cc
index 26a202b648c..ae20792dbb3 100644
--- a/chromium/content/common/sandbox_policy_fuchsia.cc
+++ b/chromium/content/common/sandbox_policy_fuchsia.cc
@@ -4,12 +4,15 @@
#include "content/common/sandbox_policy_fuchsia.h"
-#include <launchpad/launchpad.h>
+#include <fuchsia/fonts/cpp/fidl.h>
+#include <lib/fdio/spawn.h>
#include <zircon/processargs.h>
#include "base/base_paths_fuchsia.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
+#include "base/fuchsia/component_context.h"
+#include "base/fuchsia/filtered_service_directory.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "content/public/common/content_switches.h"
@@ -17,34 +20,65 @@
namespace content {
-void UpdateLaunchOptionsForSandbox(service_manager::SandboxType type,
- base::LaunchOptions* options) {
+constexpr const char* const kRendererServices[] = {
+ fuchsia::fonts::FontProvider::Name_};
+
+SandboxPolicyFuchsia::SandboxPolicyFuchsia() = default;
+SandboxPolicyFuchsia::~SandboxPolicyFuchsia() = default;
+
+void SandboxPolicyFuchsia::Initialize(service_manager::SandboxType type) {
+ DCHECK_NE(type, service_manager::SANDBOX_TYPE_INVALID);
+ DCHECK_EQ(type_, service_manager::SANDBOX_TYPE_INVALID);
+
+ type_ = type;
+
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
service_manager::switches::kNoSandbox)) {
- type = service_manager::SANDBOX_TYPE_NO_SANDBOX;
+ type_ = service_manager::SANDBOX_TYPE_NO_SANDBOX;
}
- if (type != service_manager::SANDBOX_TYPE_NO_SANDBOX) {
- // Map /pkg (read-only files deployed from the package) and /tmp into the
- // child's namespace.
- options->paths_to_map.push_back(base::GetPackageRoot());
- base::FilePath temp_dir;
- base::GetTempDir(&temp_dir);
- options->paths_to_map.push_back(temp_dir);
+ if (type_ == service_manager::SANDBOX_TYPE_RENDERER) {
+ // Create FilteredServicesDirectory for the renderer process and export all
+ // services in kRendererServices. ServiceDirectoryProxy must be initialized
+ // on a thread that has async_dispatcher.
+ service_directory_ =
+ std::make_unique<base::fuchsia::FilteredServiceDirectory>(
+ base::fuchsia::ComponentContext::GetDefault());
+ for (const char* service_name : kRendererServices)
+ service_directory_->AddService(service_name);
+ }
+}
- // Clear environmental variables to better isolate the child from
- // this process.
- options->clear_environ = true;
+void SandboxPolicyFuchsia::UpdateLaunchOptionsForSandbox(
+ base::LaunchOptions* options) {
+ DCHECK_NE(type_, service_manager::SANDBOX_TYPE_INVALID);
- // Propagate stdout/stderr/stdin to the child.
- options->clone_flags = LP_CLONE_FDIO_STDIO;
+ if (type_ == service_manager::SANDBOX_TYPE_NO_SANDBOX) {
+ options->spawn_flags = FDIO_SPAWN_CLONE_NAMESPACE | FDIO_SPAWN_CLONE_JOB |
+ FDIO_SPAWN_CLONE_STDIO;
+ options->clear_environ = false;
return;
}
- DCHECK_EQ(type, service_manager::SANDBOX_TYPE_NO_SANDBOX);
- options->clone_flags =
- LP_CLONE_FDIO_NAMESPACE | LP_CLONE_DEFAULT_JOB | LP_CLONE_FDIO_STDIO;
- options->clear_environ = false;
+ // Map /pkg (read-only files deployed from the package) and /tmp into the
+ // child's namespace.
+ options->paths_to_clone.push_back(base::GetPackageRoot());
+ base::FilePath temp_dir;
+ base::GetTempDir(&temp_dir);
+ options->paths_to_clone.push_back(temp_dir);
+
+ // Clear environmental variables to better isolate the child from
+ // this process.
+ options->clear_environ = true;
+
+ // Propagate stdout/stderr/stdin to the child.
+ options->spawn_flags = FDIO_SPAWN_CLONE_STDIO;
+
+ if (service_directory_) {
+ // Provide the child process with a restricted set of services.
+ options->paths_to_transfer.push_back(base::PathToTransfer{
+ base::FilePath("/svc"), service_directory_->ConnectClient().release()});
+ }
}
} // namespace content
diff --git a/chromium/content/common/sandbox_policy_fuchsia.h b/chromium/content/common/sandbox_policy_fuchsia.h
index bd6e1a44549..0637e35ce91 100644
--- a/chromium/content/common/sandbox_policy_fuchsia.h
+++ b/chromium/content/common/sandbox_policy_fuchsia.h
@@ -9,16 +9,36 @@
namespace base {
struct LaunchOptions;
+
+namespace fuchsia {
+class FilteredServiceDirectory;
+} // namespace fuchsia
+
} // namespace base
namespace content {
-// Modifies the process launch |options| to achieve the level of isolation
-// appropriate for the sandbox |type|. The caller may then add any
-// descriptors or handles afterward to grant additional capabiltiies to the new
-// process.
-void UpdateLaunchOptionsForSandbox(service_manager::SandboxType type,
- base::LaunchOptions* options);
+class SandboxPolicyFuchsia {
+ public:
+ SandboxPolicyFuchsia();
+ ~SandboxPolicyFuchsia();
+
+ // Initializes the policy of the given sandbox |type|. Must be called on the
+ // IO thread.
+ void Initialize(service_manager::SandboxType type);
+
+ // Modifies the process launch |options| to achieve the level of
+ // isolation appropriate for current the sandbox type. The caller may then add
+ // any descriptors or handles afterward to grant additional capabilities
+ // to the new process.
+ void UpdateLaunchOptionsForSandbox(base::LaunchOptions* options);
+
+ private:
+ service_manager::SandboxType type_ = service_manager::SANDBOX_TYPE_INVALID;
+
+ // Services directory used for the /svc namespace of the child process.
+ std::unique_ptr<base::fuchsia::FilteredServiceDirectory> service_directory_;
+};
} // namespace content
diff --git a/chromium/content/common/service_manager/DEPS b/chromium/content/common/service_manager/DEPS
index b583263b872..c610d2e59f9 100644
--- a/chromium/content/common/service_manager/DEPS
+++ b/chromium/content/common/service_manager/DEPS
@@ -1,5 +1,3 @@
include_rules = [
- "+mojo/converters/network",
- "+mojo/edk/embedder",
"+services/service_manager",
]
diff --git a/chromium/content/common/service_manager/child_connection.cc b/chromium/content/common/service_manager/child_connection.cc
index 3a782444b8d..dd7b1bd3e48 100644
--- a/chromium/content/common/service_manager/child_connection.cc
+++ b/chromium/content/common/service_manager/child_connection.cc
@@ -8,9 +8,10 @@
#include <utility>
#include "base/macros.h"
+#include "base/rand_util.h"
+#include "base/strings/string_number_conversions.h"
#include "content/common/child.mojom.h"
#include "content/public/common/service_manager_connection.h"
-#include "mojo/edk/embedder/embedder.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/identity.h"
@@ -113,15 +114,13 @@ class ChildConnection::IOThreadContext
ChildConnection::ChildConnection(
const service_manager::Identity& child_identity,
- mojo::edk::OutgoingBrokerClientInvitation* invitation,
+ mojo::OutgoingInvitation* invitation,
service_manager::Connector* connector,
scoped_refptr<base::SequencedTaskRunner> io_task_runner)
: context_(new IOThreadContext),
child_identity_(child_identity),
weak_factory_(this) {
- // TODO(rockot): Use a constant name for this pipe attachment rather than a
- // randomly generated token.
- service_token_ = mojo::edk::GenerateRandomToken();
+ service_token_ = base::NumberToString(base::RandUint64());
context_->Initialize(child_identity_, connector,
invitation->AttachMessagePipe(service_token_),
io_task_runner);
diff --git a/chromium/content/common/service_manager/child_connection.h b/chromium/content/common/service_manager/child_connection.h
index 15322fd19f6..96aca647373 100644
--- a/chromium/content/common/service_manager/child_connection.h
+++ b/chromium/content/common/service_manager/child_connection.h
@@ -14,7 +14,7 @@
#include "base/process/process_handle.h"
#include "base/sequenced_task_runner.h"
#include "content/common/content_export.h"
-#include "mojo/edk/embedder/outgoing_broker_client_invitation.h"
+#include "mojo/public/cpp/system/invitation.h"
#include "services/service_manager/public/cpp/identity.h"
#include "services/service_manager/public/mojom/connector.mojom.h"
@@ -35,7 +35,7 @@ class CONTENT_EXPORT ChildConnection {
// service name. |connector| is the connector to use to establish the
// connection.
ChildConnection(const service_manager::Identity& child_identity,
- mojo::edk::OutgoingBrokerClientInvitation* invitation,
+ mojo::OutgoingInvitation* invitation,
service_manager::Connector* connector,
scoped_refptr<base::SequencedTaskRunner> io_task_runner);
~ChildConnection();
diff --git a/chromium/content/common/service_worker/README.md b/chromium/content/common/service_worker/README.md
new file mode 100644
index 00000000000..b31d887790d
--- /dev/null
+++ b/chromium/content/common/service_worker/README.md
@@ -0,0 +1,5 @@
+[content/browser/service_worker]: /content/browser/service_worker/README.md
+
+Common process code for service workers.
+
+See the main service worker documentation in [content/browser/service_worker].
diff --git a/chromium/content/common/service_worker/controller_service_worker.mojom b/chromium/content/common/service_worker/controller_service_worker.mojom
index b08c3a9bcfd..8c5b5201ad1 100644
--- a/chromium/content/common/service_worker/controller_service_worker.mojom
+++ b/chromium/content/common/service_worker/controller_service_worker.mojom
@@ -4,11 +4,11 @@
module content.mojom;
-import "content/common/service_worker/dispatch_fetch_event_params.mojom";
-import "content/common/service_worker/service_worker_event_dispatcher.mojom";
+import "content/common/service_worker/service_worker.mojom";
import "content/common/service_worker/service_worker_fetch_response_callback.mojom";
import "mojo/public/mojom/base/time.mojom";
import "services/network/public/mojom/url_loader.mojom";
+import "third_party/blink/public/mojom/service_worker/dispatch_fetch_event_params.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_object.mojom";
import "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom";
@@ -23,22 +23,21 @@ import "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom"
// service worker runs.
//
// The controllees use this interface to directly talk to the controller. This
-// implements a small subset of ServiceWorkerEventDispatcher, namely dispatch
+// implements a small subset of the ServiceWorker interface, namely dispatch
// methods for Fetch and PostMessage, because ordering must be preserved
// between them: controller.postMessage(...), controller.fetch(‘...’); from
// the page must result in a message event then fetch event dispatched to the
// service worker. They are believed to be the only events whose ordering
// guarantee is observable from the page context.
-//
interface ControllerServiceWorker {
// Dispatches Fetch event for sub-resources. (Fetch for main resource is
- // handled by ServiceWorkerEventDispatcher, as the fetch is initiated
+ // handled by the ServiceWorker interface, as the fetch is initiated
// in the browser-process during the navigation)
// 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().
- DispatchFetchEvent(DispatchFetchEventParams params,
+ DispatchFetchEvent(blink.mojom.DispatchFetchEventParams params,
ServiceWorkerFetchResponseCallback response_callback)
=> (blink.mojom.ServiceWorkerEventStatus status,
mojo_base.mojom.Time dispatch_event_time);
@@ -54,9 +53,14 @@ interface ControllerServiceWorker {
// information from the browser process to the renderer process on navigation
// commit, and also as a parameter of ServiceWorkerContainer.SetController().
struct ControllerServiceWorkerInfo {
- // S13nServiceWorker:
- // Non-null if the controller has fetch event handlers.
+ // Describes whether there is a controller and it has a fetch event handler.
+ blink.mojom.ControllerServiceWorkerMode mode =
+ blink.mojom.ControllerServiceWorkerMode.kNoController;
+
+ // S13nServiceWorker only:
+ // Non-null iff there is a controller and it has a fetch event handler.
ControllerServiceWorker? endpoint;
+
// S13nServiceWorker:
// The client being controlled, used for FetchEvent#clientId. The ID is
// issued by the browser process for this receiving client, and would
@@ -69,3 +73,15 @@ struct ControllerServiceWorkerInfo {
// Null if there is no controller.
blink.mojom.ServiceWorkerObjectInfo? object_info;
};
+
+// A renderer-side interface for talking across threads. The main thread
+// uses this interface to update a ControllerServiceWorkerConnector on a
+// different thread with a new controller service worker.
+// TODO(kinuko): Stop using mojo interface for this, we can just make
+// it work via posting tasks.
+interface ControllerServiceWorkerConnector {
+ // Resets the controller connection with the given |controller|, this
+ // can be called when a new controller is given, e.g. due to claim().
+ // |controller| can be null if it gets no controller.
+ UpdateController(ControllerServiceWorker? controller);
+};
diff --git a/chromium/content/common/service_worker/dispatch_fetch_event_params.mojom b/chromium/content/common/service_worker/dispatch_fetch_event_params.mojom
deleted file mode 100644
index 785d219b776..00000000000
--- a/chromium/content/common/service_worker/dispatch_fetch_event_params.mojom
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module content.mojom;
-
-import "services/network/public/mojom/url_loader.mojom";
-import "third_party/blink/public/mojom/blob/blob.mojom";
-
-// Used for service worker navigation preload, to create
-// FetchEvent#preloadResponse.
-struct FetchEventPreloadHandle {
- network.mojom.URLLoader url_loader;
- network.mojom.URLLoaderClient& url_loader_client_request;
-};
-
-// Parameters used for dispatching a FetchEvent.
-struct DispatchFetchEventParams {
- // FetchEvent#request.
- network.mojom.URLRequest request;
-
- // The following fields are used to create FetchEvent#request#body, depending
- // on whether S13nServiceWorker/NetworkService are enabled.
-
- // (A) S13nServiceWorker with NetworkService on:
- // All information about the request body is provided in
- // |request.request_body|.
-
- // (B) S13nServiceWorker with NetworkService off:
- // All information about the request body except for BlobPtrs is provided in
- // |request.request_body|. These BlobPtrs need to be passed separately.
- // Once the NetworkService is enabled, this will be no longer used since all
- // Blobs are passed as data pipes which can live in |request.request_body|.
- array<blink.mojom.Blob> request_body_blob_ptrs;
-
- // (C) non-S13nServiceWorker:
- // All information to create the request body are packed into a blob. These
- // params are for passing the blob.
- string request_body_blob_uuid;
- uint64 request_body_blob_size;
- blink.mojom.Blob? request_body_blob;
-
- // FetchEvent#clientId.
- string client_id;
- // FetchEvent#preloadResponse.
- FetchEventPreloadHandle? preload_handle;
-};
diff --git a/chromium/content/common/service_worker/embedded_worker.mojom b/chromium/content/common/service_worker/embedded_worker.mojom
index a9c5333ade0..b377941756e 100644
--- a/chromium/content/common/service_worker/embedded_worker.mojom
+++ b/chromium/content/common/service_worker/embedded_worker.mojom
@@ -6,13 +6,14 @@ 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.mojom";
import "content/common/service_worker/service_worker_provider.mojom";
import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/time.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "services/service_manager/public/mojom/interface_provider.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom";
+import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom";
import "third_party/blink/public/platform/web_feature.mojom";
import "third_party/blink/public/web/console_message.mojom";
import "third_party/blink/public/web/devtools_agent.mojom";
@@ -47,11 +48,11 @@ struct EmbeddedWorkerStartParams {
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;
+ // Used to set up fetch requests.
+ RendererPreferences renderer_preferences;
- // Used to dispatch events from (via) the browser process.
- ServiceWorkerEventDispatcher& dispatcher_request;
+ // Used to talk to the service worker from the browser process.
+ ServiceWorker& service_worker_request;
// S13nServiceWorker: cloned and passed to each controllee to directly
// dispatch events from the controllees.
ControllerServiceWorker& controller_request;
@@ -66,11 +67,17 @@ struct EmbeddedWorkerStartParams {
};
// Holds timing information about the start worker sequence for UMA.
+//
+// Keep this in sync with the validation check in
+// EmbeddedWorkerInstance::OnStarted.
+// TODO(falken): Make a typemap just for the validation check?
struct EmbeddedWorkerStartTiming {
- // When this Blink instance finished initializing.
- mojo_base.mojom.TimeTicks blink_initialized_time;
// When the start worker message was received by the renderer.
mojo_base.mojom.TimeTicks start_worker_received_time;
+ // When JavaScript evaluation on the worker thread started.
+ mojo_base.mojom.TimeTicks script_evaluation_start_time;
+ // When JavaScript evaluation on the worker thread finished.
+ mojo_base.mojom.TimeTicks script_evaluation_end_time;
};
// EmbeddedWorkerInstanceClient is the renderer-side ("Client") of
@@ -118,26 +125,31 @@ interface EmbeddedWorkerInstanceHost {
// thread in the renderer process.
CountFeature(blink.mojom.WebFeature feature);
- // Indicates that the worker is ready for inspection.
+ // The following are called during startup:
+ //
+ // Indicates that the worker is ready for inspection. This message is needed
+ // because DevTools requires the shadow page to have been created before
+ // inspecting the worker.
OnReadyForInspection();
- // Indicates that the worker has finished loading the script.
+ // Indicates that the worker has finished loading the main script.
+ //
+ // This is only called for new (non-installed) workers. It's used so the
+ // browser process knows it can resume the paused worker via
+ // ResumeAfterDownloaded().
OnScriptLoaded();
- // Indicates that the worker has failed to load the script.
- OnScriptLoadFailed();
- // Indicates that the worker thread has started. |thread_id| is the actual
- // platform thread id on which the worker runs.
- // This is called after OnScriptLoaded.
- OnThreadStarted(int32 thread_id);
- // Indicates that the worker has evaluated the script. |success| means
- // evaluating the script completed and no uncaught exception occurred.
- // This is called after OnThreadStarted.
- OnScriptEvaluated(bool success);
- // Indicates that the worker has started.
- // This is called after OnScriptEvaluated.
- OnStarted(EmbeddedWorkerStartTiming start_timing);
+ // Indicates that initial JavaScript evaluation is starting. This is useful
+ // for the browser process to start enforcing timeouts on script execution.
+ OnScriptEvaluationStart();
+ // Indicates that the worker has started. |thread_id| is the platform
+ // thread id the worker runs on.
+ OnStarted(blink.mojom.ServiceWorkerStartStatus status,
+ int32 thread_id,
+ EmbeddedWorkerStartTiming start_timing);
+
// Reports that an uncaught exception occurred in the worker.
OnReportException(mojo_base.mojom.String16 error_message, int32 line_number,
int32 column_number, url.mojom.Url source_url);
+
// Reports that a console message was emitted to the worker's console.
OnReportConsoleMessage(int32 source_identifier, int32 message_level,
mojo_base.mojom.String16 message, int32 line_number,
diff --git a/chromium/content/common/service_worker/service_worker.mojom b/chromium/content/common/service_worker/service_worker.mojom
index 154f2af5d17..03b78388227 100644
--- a/chromium/content/common/service_worker/service_worker.mojom
+++ b/chromium/content/common/service_worker/service_worker.mojom
@@ -4,16 +4,195 @@
module content.mojom;
-import "content/common/service_worker/service_worker_provider.mojom";
-
-// Per-process browser-side interface.
-// The renderer uses this interface to tell the browser when potential service
-// worker clients are created and when service workers are starting up.
-interface ServiceWorkerDispatcherHost {
- // Creates a content::ServiceWorkerProviderHost on the browser
- // process. |provider_info| has Mojo endpoints to connect the container host
- // and the container on the renderer together. The lifetime of
- // ServiceWorkerProviderHost will be tied to the
- // mojom::ServiceWorkerContainerHost interface.
- OnProviderCreated(ServiceWorkerProviderHostInfo provider_info);
+import "content/common/service_worker/service_worker_fetch_response_callback.mojom";
+import "mojo/public/mojom/base/string16.mojom";
+import "mojo/public/mojom/base/time.mojom";
+import "services/network/public/mojom/cookie_manager.mojom";
+import "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom";
+import "third_party/blink/public/platform/modules/payments/payment_app.mojom";
+import "third_party/blink/public/mojom/message_port/message_port.mojom";
+import "third_party/blink/public/mojom/service_worker/dispatch_fetch_event_params.mojom";
+import "third_party/blink/public/mojom/service_worker/service_worker.mojom";
+import "third_party/blink/public/mojom/service_worker/service_worker_client.mojom";
+import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom";
+import "third_party/blink/public/mojom/service_worker/service_worker_object.mojom";
+import "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom";
+import "url/mojom/origin.mojom";
+import "url/mojom/url.mojom";
+
+[Native]
+struct PlatformNotificationData;
+
+[Native]
+struct PushEventPayload;
+
+[Native]
+struct ServiceWorkerResponse;
+
+// TODO(peter): Move this to Blink when ServiceWorkerResponse has a Mojo
+// counterpart.
+struct BackgroundFetchSettledFetch {
+ blink.mojom.FetchAPIRequest request;
+ ServiceWorkerResponse response;
+};
+
+enum BackgroundFetchState {
+ PENDING,
+ SUCCEEDED,
+ FAILED
+};
+
+struct ExtendableMessageEvent {
+ blink.mojom.TransferableMessage message;
+ url.mojom.Origin source_origin;
+ // Exactly one of |source_info_for_client| and
+ // |source_info_for_service_worker| should be non-null.
+ blink.mojom.ServiceWorkerClientInfo? source_info_for_client;
+ blink.mojom.ServiceWorkerObjectInfo? source_info_for_service_worker;
+};
+
+// The number of seconds for which a 'push' event should be allowed to run.
+// This is not in the spec but for a Chrome-specific timeout. Each
+// event dispatched to service workers has a 5 minute timeout in the Chrome
+// implementation, but this makes the timeout for push events shorter.
+const int32 kPushEventTimeoutSeconds = 90;
+
+// An interface for talking to a running service worker thread. The browser
+// process uses this interface to request the renderer to do things like
+// dispatch events to the service worker. This interface is bound on the
+// service worker thread and is implemented by ServiceWorkerContextClient.
+//
+// This is the master interface for the Mojo message pipe between the browser
+// process and the service worker thread in the renderer process. Other service
+// worker-related interfaces bound on the service worker thread are associated
+// with this interface. These include:
+// - ServiceWorkerHost for this service worker.
+// - ServiceWorkerRegistrationObject(Host) for this service worker's
+// self.registration property.
+// - ServiceWorkerObjects(Host) for that registration's properties.
+//
+// A similar (but non-associated) interface is ControllerServiceWorker. That
+// interface is used by service worker clients (inside renderer processes) to
+// talk directly to their controller service worker, without going through the
+// browser.
+//
+// USAGE TIP: Those DispatchEvent* messages expecting a
+// (blink.mojom.ServiceWorkerEventStatus, mojo_base.mojom.Time) callback are
+// considered 'simple events'. ServiceWorkerVersion::CreateSimpleEventCallback
+// can be used to create the callback for these.
+interface ServiceWorker {
+ // The first message sent on this interface. It is used to associate service
+ // worker-related interfaces together on the service worker thread, as
+ // ServiceWorker is the first interface available on the
+ // service worker thread. It establishes the |service_worker_host| connection
+ // and passes information used to populate
+ // ServiceWorkerGlobalScope#registration object. JavaScript execution of the
+ // service worker does not start until this message is received.
+ InitializeGlobalScope(
+ associated blink.mojom.ServiceWorkerHost service_worker_host,
+ blink.mojom.ServiceWorkerRegistrationObjectInfo registration_info);
+
+ DispatchInstallEvent()
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ bool has_fetch_handler,
+ mojo_base.mojom.Time dispatch_event_time);
+ DispatchActivateEvent()
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+
+ // These methods dispatch to the ServiceWorkerGlobalScope the events listed on
+ // https://wicg.github.io/background-fetch/#service-worker-global-events.
+ // The callbacks are called once the event handler has run and waitUntil()
+ // promise has settled. |developer_id| and |unique_id| are documented in
+ // content::BackgroundFetchRegistrationId.
+ DispatchBackgroundFetchAbortEvent(string developer_id,
+ string unique_id,
+ array<BackgroundFetchSettledFetch> fetches)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+ DispatchBackgroundFetchClickEvent(string developer_id,
+ BackgroundFetchState state)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+ DispatchBackgroundFetchFailEvent(string developer_id,
+ string unique_id,
+ array<BackgroundFetchSettledFetch> fetches)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+ DispatchBackgroundFetchedEvent(string developer_id,
+ string unique_id,
+ array<BackgroundFetchSettledFetch> fetches)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+
+ // Dispatches the cookie change events in the Async Cookie API specification.
+ // https://github.com/WICG/cookie-store/
+ // The callback is called once the event handler has run and the waitUntil()
+ // promise has settled.
+ DispatchCookieChangeEvent(
+ network.mojom.CanonicalCookie cookie,
+ network.mojom.CookieChangeCause cause)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+
+ // 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().
+ DispatchFetchEvent(blink.mojom.DispatchFetchEventParams params,
+ ServiceWorkerFetchResponseCallback response_callback)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+
+ DispatchNotificationClickEvent(string notification_id,
+ PlatformNotificationData notification_data,
+ int32 action_index,
+ mojo_base.mojom.String16? reply)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+ DispatchNotificationCloseEvent(string notification_id,
+ PlatformNotificationData notification_data)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+ DispatchPushEvent(PushEventPayload payload)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+ // Arguments are passed to the event handler as parameters of SyncEvent.
+ // Ref: https://wicg.github.io/BackgroundSync/spec/#sync-event
+ // S13nServiceWorker: |timeout| is the amount of time to allow this event to
+ // finish.
+ // Non-S13nServiceWorker: |timeout| is just ignored.
+ DispatchSyncEvent(string id,
+ bool last_chance,
+ mojo_base.mojom.TimeDelta timeout)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+ DispatchAbortPaymentEvent(
+ payments.mojom.PaymentHandlerResponseCallback result_of_abort_payment)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+ DispatchCanMakePaymentEvent(
+ payments.mojom.CanMakePaymentEventData event_data,
+ payments.mojom.PaymentHandlerResponseCallback result_of_can_make_payment)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+ DispatchPaymentRequestEvent(
+ payments.mojom.PaymentRequestEventData request_data,
+ payments.mojom.PaymentHandlerResponseCallback response_callback)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+ DispatchExtendableMessageEvent(ExtendableMessageEvent event)
+ => (blink.mojom.ServiceWorkerEventStatus status,
+ mojo_base.mojom.Time dispatch_event_time);
+
+ // Pings the service worker to check if it is responsive. If the callback is
+ // not called within a certain period of time, the browser will terminate the
+ // worker.
+ Ping() => ();
+
+ // S13nServiceWorker:
+ // Lets the idle timer request termination immediately after all inflight
+ // events are handled without delay.
+ SetIdleTimerDelayToZero();
};
diff --git a/chromium/content/common/service_worker/service_worker_event_dispatcher.typemap b/chromium/content/common/service_worker/service_worker.typemap
index f09c55f7fee..e64c14e9c3d 100644
--- a/chromium/content/common/service_worker/service_worker_event_dispatcher.typemap
+++ b/chromium/content/common/service_worker/service_worker.typemap
@@ -2,16 +2,16 @@
# 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_event_dispatcher.mojom"
+mojom = "//content/common/service_worker/service_worker.mojom"
public_headers = [
"//content/common/background_fetch/background_fetch_types.h",
- "//content/common/service_worker/service_worker_status_code.h",
+ "//third_party/blink/public/common/service_worker/service_worker_status_code.h",
"//content/common/service_worker/service_worker_types.h",
"//content/public/common/platform_notification_data.h",
"//content/public/common/push_event_payload.h",
]
traits_headers = [
- "//content/common/platform_notification_messages.h",
+ "//content/common/platform_notification_param_traits.h",
"//content/common/service_worker/service_worker_messages.h",
]
type_mappings = [
diff --git a/chromium/content/common/service_worker/service_worker_container.mojom b/chromium/content/common/service_worker/service_worker_container.mojom
index ef8136d3e89..b7bae47af99 100644
--- a/chromium/content/common/service_worker/service_worker_container.mojom
+++ b/chromium/content/common/service_worker/service_worker_container.mojom
@@ -83,6 +83,14 @@ interface ServiceWorkerContainerHost {
// for this interface and associated interfaces: when the callback is called,
// you know all incoming messages up to the Ping() call have been received.
Ping() => ();
+
+ // S13nServiceWorker:
+ // Gives a hint to the browser process to update the service worker after a
+ // controlled page load. This message is meant to be sent at a time when page
+ // load is no longer busy, so update doesn't adversely affect performance.
+ // The browser process can possibly coalesce hints for the same service
+ // worker into a single update.
+ HintToUpdateServiceWorker();
};
// mojom::ServiceWorkerContainer is a renderer-side interface.
diff --git a/chromium/content/common/service_worker/service_worker_event_dispatcher.mojom b/chromium/content/common/service_worker/service_worker_event_dispatcher.mojom
deleted file mode 100644
index dc52bf442f0..00000000000
--- a/chromium/content/common/service_worker/service_worker_event_dispatcher.mojom
+++ /dev/null
@@ -1,187 +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;
-
-import "content/common/service_worker/dispatch_fetch_event_params.mojom";
-import "content/common/service_worker/service_worker_fetch_response_callback.mojom";
-import "mojo/public/mojom/base/string16.mojom";
-import "mojo/public/mojom/base/time.mojom";
-import "services/network/public/mojom/cookie_manager.mojom";
-import "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom";
-import "third_party/blink/public/platform/modules/payments/payment_app.mojom";
-import "third_party/blink/public/mojom/message_port/message_port.mojom";
-import "third_party/blink/public/mojom/service_worker/service_worker.mojom";
-import "third_party/blink/public/mojom/service_worker/service_worker_client.mojom";
-import "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom";
-import "third_party/blink/public/mojom/service_worker/service_worker_object.mojom";
-import "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom";
-import "url/mojom/origin.mojom";
-import "url/mojom/url.mojom";
-
-[Native]
-struct PlatformNotificationData;
-
-[Native]
-struct PushEventPayload;
-
-[Native]
-struct ServiceWorkerResponse;
-
-// TODO(peter): Move this to Blink when ServiceWorkerResponse has a Mojo
-// counterpart.
-struct BackgroundFetchSettledFetch {
- blink.mojom.FetchAPIRequest request;
- ServiceWorkerResponse response;
-};
-
-enum BackgroundFetchState {
- PENDING,
- SUCCEEDED,
- FAILED
-};
-
-struct ExtendableMessageEvent {
- blink.mojom.TransferableMessage message;
- url.mojom.Origin source_origin;
- // Exactly one of |source_info_for_client| and
- // |source_info_for_service_worker| should be non-null.
- blink.mojom.ServiceWorkerClientInfo? source_info_for_client;
- blink.mojom.ServiceWorkerObjectInfo? source_info_for_service_worker;
-};
-
-// The number of seconds for which a 'push' event should be allowed to run.
-// This is not in the spec but for Chromium specific internal timeouts. Each
-// event dispatched to service workers has 5 minutes timeout in the Chrome
-// implementation, but this makes the timeout for push events shorter.
-const int32 kPushEventTimeoutSeconds = 90;
-
-// An interface for dispatching events to a ServiceWorker. This interface is
-// implemented by ServiceWorkerContextClient that lives in the renderer-side
-// to dispatch events from the browser-side.
-//
-// Those events expecting such response
-// (blink.mojom.ServiceWorkerEventStatus, mojo_base.mojom.Time) are considered
-// 'simple events'. ServiceWorkerVersion::CreateSimpleEventCallback can be used
-// to create the callback for these.
-interface ServiceWorkerEventDispatcher {
- // The first message sent on this interface. It is used to associate service
- // worker-related interfaces together on the service worker thread, as
- // ServiceWorkerEventDispatcher is the first interface available on the
- // service worker thread. It establishes the |service_worker_host| connection
- // and passes information used to populate
- // ServiceWorkerGlobalScope#registration object. JavaScript execution of the
- // service worker does not start until this message is received.
- InitializeGlobalScope(
- associated blink.mojom.ServiceWorkerHost service_worker_host,
- blink.mojom.ServiceWorkerRegistrationObjectInfo registration_info);
-
- DispatchInstallEvent()
- => (blink.mojom.ServiceWorkerEventStatus status,
- bool has_fetch_handler,
- mojo_base.mojom.Time dispatch_event_time);
- DispatchActivateEvent()
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
-
- // These methods dispatch to the ServiceWorkerGlobalScope the events listed on
- // https://wicg.github.io/background-fetch/#service-worker-global-events.
- // The callbacks are called once the event handler has run and waitUntil()
- // promise has settled. |developer_id| and |unique_id| are documented in
- // content::BackgroundFetchRegistrationId.
- DispatchBackgroundFetchAbortEvent(string developer_id,
- string unique_id,
- array<BackgroundFetchSettledFetch> fetches)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
- DispatchBackgroundFetchClickEvent(string developer_id,
- BackgroundFetchState state)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
- DispatchBackgroundFetchFailEvent(string developer_id,
- string unique_id,
- array<BackgroundFetchSettledFetch> fetches)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
- DispatchBackgroundFetchedEvent(string developer_id,
- string unique_id,
- array<BackgroundFetchSettledFetch> fetches)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
-
- // Dispatches the cookie change events in the Async Cookie API specification.
- // https://github.com/WICG/cookie-store/
- // The callback is called once the event handler has run and the waitUntil()
- // promise has settled.
- DispatchCookieChangeEvent(
- network.mojom.CanonicalCookie cookie,
- network.mojom.CookieChangeCause cause)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
-
- // 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().
- DispatchFetchEvent(DispatchFetchEventParams params,
- ServiceWorkerFetchResponseCallback response_callback)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
-
- DispatchNotificationClickEvent(string notification_id,
- PlatformNotificationData notification_data,
- int32 action_index,
- mojo_base.mojom.String16? reply)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
- DispatchNotificationCloseEvent(string notification_id,
- PlatformNotificationData notification_data)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
- DispatchPushEvent(PushEventPayload payload)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
- // Arguments are passed to the event handler as parameters of SyncEvent.
- // Ref: https://wicg.github.io/BackgroundSync/spec/#sync-event
- // S13nServiceWorker: |timeout| is the amount of time to allow this event to
- // finish.
- // Non-S13nServiceWorker: |timeout| is just ignored.
- DispatchSyncEvent(string id,
- bool last_chance,
- mojo_base.mojom.TimeDelta timeout)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
- DispatchAbortPaymentEvent(
- int32 event_id,
- payments.mojom.PaymentHandlerResponseCallback result_of_abort_payment)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
- DispatchCanMakePaymentEvent(
- int32 event_id,
- payments.mojom.CanMakePaymentEventData event_data,
- payments.mojom.PaymentHandlerResponseCallback result_of_can_make_payment)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
- DispatchPaymentRequestEvent(
- int32 payment_request_id,
- payments.mojom.PaymentRequestEventData request_data,
- payments.mojom.PaymentHandlerResponseCallback response_callback)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
- DispatchExtendableMessageEvent(ExtendableMessageEvent event)
- => (blink.mojom.ServiceWorkerEventStatus status,
- mojo_base.mojom.Time dispatch_event_time);
-
- // Pings the service worker to check if it is responsive. If the callback is
- // not called within a certain period of time, the browser will terminate the
- // worker. Unlike the other functions in this interface, Ping() does not
- // dispatch an event.
- Ping() => ();
-
- // S13nServiceWorker:
- // Lets the idle timer request termination immediately after all inflight
- // events are handled without delay.
- SetIdleTimerDelayToZero();
-};
diff --git a/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.cc b/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.cc
index a6b3557e7e3..8962b22faf2 100644
--- a/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.cc
+++ b/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.cc
@@ -230,6 +230,7 @@ bool StructTraits<blink::mojom::FetchAPIRequestDataView,
out->cache_mode = data.cache_mode();
out->keepalive = data.keepalive();
out->is_reload = data.is_reload();
+ out->is_history_navigation = data.is_history_navigation();
return true;
}
diff --git a/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.h b/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.h
index fe8cc4e2e27..40385d395b5 100644
--- a/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.h
+++ b/chromium/content/common/service_worker/service_worker_fetch_request_mojom_traits.h
@@ -106,6 +106,11 @@ struct StructTraits<blink::mojom::FetchAPIRequestDataView,
return request.is_reload;
}
+ static bool is_history_navigation(
+ const content::ServiceWorkerFetchRequest& request) {
+ return request.is_history_navigation;
+ }
+
static bool Read(blink::mojom::FetchAPIRequestDataView data,
content::ServiceWorkerFetchRequest* out);
};
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 105b2639cac..43f64fba119 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
@@ -12,8 +12,8 @@ import "third_party/blink/public/mojom/service_worker/service_worker_stream_hand
struct ServiceWorkerResponse;
// Callback interface which is passed to a controller service worker through
-// DispatchFetchEvent (either via ServiceWorkerEventDispatcher or via
-// ControllerServiceWorker interface).
+// DispatchFetchEvent (either via ServiceWorker or via ControllerServiceWorker
+// interface).
// The receiver service worker uses this interface to respond to a fetch event.
interface ServiceWorkerFetchResponseCallback {
// Responds to the request with |response|. The body is empty.
@@ -25,12 +25,6 @@ interface ServiceWorkerFetchResponseCallback {
OnResponseBlob(ServiceWorkerResponse response,
blink.mojom.Blob body_as_blob,
mojo_base.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_base.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_loader_helpers.cc b/chromium/content/common/service_worker/service_worker_loader_helpers.cc
index 738ed311a07..b01b6825bcf 100644
--- a/chromium/content/common/service_worker/service_worker_loader_helpers.cc
+++ b/chromium/content/common/service_worker/service_worker_loader_helpers.cc
@@ -92,6 +92,7 @@ void ServiceWorkerLoaderHelpers::SaveResponseInfo(
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;
+ out_head->response_time = response.response_time;
out_head->is_in_cache_storage = response.is_in_cache_storage;
out_head->cache_storage_cache_name = response.cache_storage_cache_name;
out_head->cors_exposed_header_names = response.cors_exposed_header_names;
@@ -120,7 +121,8 @@ ServiceWorkerLoaderHelpers::ComputeRedirectInfo(
original_request.referrer_policy,
network::ComputeReferrer(original_request.referrer),
response_head.headers.get(), response_head.headers->response_code(),
- original_request.url.Resolve(new_location), token_binding_negotiated);
+ original_request.url.Resolve(new_location), false,
+ token_binding_negotiated);
}
int ServiceWorkerLoaderHelpers::ReadBlobResponseBody(
diff --git a/chromium/content/common/service_worker/service_worker_messages.h b/chromium/content/common/service_worker/service_worker_messages.h
index 8cba139aba4..3fa8620e6e5 100644
--- a/chromium/content/common/service_worker/service_worker_messages.h
+++ b/chromium/content/common/service_worker/service_worker_messages.h
@@ -12,14 +12,14 @@
#include "base/strings/string16.h"
#include "base/time/time.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/platform_notification_data.h"
#include "content/public/common/push_event_payload.h"
#include "ipc/ipc_message_macros.h"
#include "ipc/ipc_param_traits.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_error.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
#undef IPC_MESSAGE_EXPORT
#define IPC_MESSAGE_EXPORT CONTENT_EXPORT
diff --git a/chromium/content/common/service_worker/service_worker_provider.mojom b/chromium/content/common/service_worker/service_worker_provider.mojom
index 17fdfada95a..1ac547c5547 100644
--- a/chromium/content/common/service_worker/service_worker_provider.mojom
+++ b/chromium/content/common/service_worker/service_worker_provider.mojom
@@ -7,6 +7,7 @@ module content.mojom;
import "content/common/service_worker/service_worker_container.mojom";
import "services/network/public/mojom/url_loader_factory.mojom";
import "services/service_manager/public/mojom/interface_provider.mojom";
+import "third_party/blink/public/mojom/service_worker/service_worker_object.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom";
import "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom";
import "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom";
@@ -50,33 +51,87 @@ struct ServiceWorkerProviderInfoForStartWorker {
service_manager.mojom.InterfaceProvider interface_provider;
};
-// Sent from the renderer to the browser process. Contains parameters that
-// describe a browser-side provider host.
-// See also comments in
-// content/common/service_worker/service_worker_provider_host_info.h.
+// Describes a browser-side provider host. See
+// content::ServiceWorkerProviderHost.
struct ServiceWorkerProviderHostInfo {
+ // |provider_id| may be browser-assigned or renderer-assigned.
+ // Browser-assigned ids are unique among all providers. Renderer-assigned ids
+ // are unique among providers in a given renderer process. Most providers have
+ // browser-assigned ids. The exceptions are about:blank iframes, and shared
+ // workers (in the non-S13nServiceWorker case).
int32 provider_id;
+
+ // When this provider is created for a document, |route_id| is the frame ID of
+ // it. Otherwise |route_id| is MSG_ROUTING_NONE.
int32 route_id;
+
+ // 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;
+ // that is, blink::WebFrame::canHaveSecureChild() returns false. This doesn't
+ // mean the document is necessarily an insecure context, because the document
+ // may have a URL whose scheme is granted an exception that allows bypassing
+ // the ancestor secure context check. See the comment in
+ // blink::Document::isSecureContextImpl for more details. If the provider is
+ // not created for a document, or the document does not have a parent frame,
+ // is_parent_frame_secure| is true.
bool is_parent_frame_secure;
+
+ // Mojo endpoint to send a message from the renderer to the browser. This
+ // will be associated with ServiceWorkerDisptacherHost. |host_request| should
+ // be valid when ServiceWorkerProviderHostInfo is passed to any Mojo method.
+ // After used to create the ServiceWorkerProviderHost, this will be invalid.
associated ServiceWorkerContainerHost& host_request;
+
+ // Mojo endpoint to send a message from the browser to the renderer. This
+ // will be associated with ServiceWorkerDispatcherHost. |client_ptr_info|
+ // should be valid when ServiceWorkerProviderHostInfo is passed to any Mojo
+ // method.
+ // After used to create the ServiceWorkerProviderHost, this will be invalid.
associated ServiceWorkerContainer client_ptr_info;
};
// ServiceWorkerWorkerClient represents a service worker client that is a worker
// (i.e., a shared worker or dedicated worker). We use this interface to let the
-// WorkerFetchContextImpl in the worker thread know about the change of
-// controlling service worker by calling SetControllerServiceWorker() from the
+// WebWorkerFetchContextImpl in the worker thread know about the change of
+// controlling service worker by calling OnControllerChanged() from the
// ServiceWorkerProviderContext in the main thread of the renderer process.
//
// TODO(horo): We should implement ServiceWorkerProvider in the worker thread
-// instead of using this interface to support WorkerNavigator.serviceWorker
-// when we can make the worker thread totally independent from the main thread.
-// Currently we handle synchronous resource loading such as importScripts() and
-// synchronous XHR in the main thread. So we need to know whether the worker is
-// controlled by a service worker or not both in the main thread and in the
-// worker thread.
+// instead of using this interface to support WorkerNavigator.serviceWorker.
interface ServiceWorkerWorkerClient {
- // Called when the worker is controlled by a new service worker.
- SetControllerServiceWorker(int64 controller_version_id);
+ // Called when the worker is controlled by a new service worker. This is only
+ // used to let the worker know that we now have a service worker (while there
+ // may or may not have been one previously), but not the other way around.
+ OnControllerChanged(blink.mojom.ControllerServiceWorkerMode mode);
+};
+
+// ServiceWorkerWorkerClientRegistry is a mojo interface for hosting and
+// registering ServiceWorkerWorkerClients. An instance of this interface is
+// implemented by ServiceWorkerProviderContext and lives in the same renderer
+// process as the worker clients.
+// This interface is useful when one needs to register a new worker client
+// for an existing ServiceWorkerProviderContext on non-main thread, i.e. for
+// nested workers.
+interface ServiceWorkerWorkerClientRegistry {
+ // Adds a new ServiceWorkerWorkerClient.
+ RegisterWorkerClient(ServiceWorkerWorkerClient client);
+
+ // Clones this host.
+ CloneWorkerClientRegistry(ServiceWorkerWorkerClientRegistry& host);
+};
+
+// Per-process browser-side interface.
+// The renderer uses this interface to tell the browser when potential service
+// worker clients are created and when service workers are starting up.
+interface ServiceWorkerDispatcherHost {
+ // Creates a content::ServiceWorkerProviderHost on the browser
+ // process. |provider_info| has Mojo endpoints to connect the container host
+ // and the container on the renderer together. The lifetime of
+ // ServiceWorkerProviderHost will be tied to the
+ // mojom::ServiceWorkerContainerHost interface.
+ OnProviderCreated(ServiceWorkerProviderHostInfo provider_info);
};
diff --git a/chromium/content/common/service_worker/service_worker_provider.typemap b/chromium/content/common/service_worker/service_worker_provider.typemap
deleted file mode 100644
index 757d4a771ea..00000000000
--- a/chromium/content/common/service_worker/service_worker_provider.typemap
+++ /dev/null
@@ -1,12 +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/common/service_worker/service_worker_provider.mojom"
-public_headers =
- [ "//content/common/service_worker/service_worker_provider_host_info.h" ]
-traits_headers = [ "//content/common/service_worker/service_worker_provider_struct_traits.h" ]
-sources = [
- "//content/common/service_worker/service_worker_provider_struct_traits.cc",
-]
-type_mappings = [ "content.mojom.ServiceWorkerProviderHostInfo=::content::ServiceWorkerProviderHostInfo[move_only]" ]
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
deleted file mode 100644
index f387c1b5ae8..00000000000
--- a/chromium/content/common/service_worker/service_worker_provider_host_info.cc
+++ /dev/null
@@ -1,77 +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/service_worker/service_worker_provider_host_info.h"
-
-#include "ipc/ipc_message.h"
-
-namespace content {
-
-namespace {
-
-void SetDefaultValues(ServiceWorkerProviderHostInfo* info) {
- info->provider_id = kInvalidServiceWorkerProviderId;
- info->route_id = MSG_ROUTING_NONE;
- info->type = blink::mojom::ServiceWorkerProviderType::kUnknown;
- info->is_parent_frame_secure = false;
-}
-
-} // namespace
-
-ServiceWorkerProviderHostInfo::ServiceWorkerProviderHostInfo()
- : provider_id(kInvalidServiceWorkerProviderId),
- route_id(MSG_ROUTING_NONE),
- type(blink::mojom::ServiceWorkerProviderType::kUnknown),
- is_parent_frame_secure(false) {}
-
-ServiceWorkerProviderHostInfo::ServiceWorkerProviderHostInfo(
- ServiceWorkerProviderHostInfo&& other)
- : provider_id(other.provider_id),
- route_id(other.route_id),
- type(other.type),
- is_parent_frame_secure(other.is_parent_frame_secure),
- host_request(std::move(other.host_request)),
- client_ptr_info(std::move(other.client_ptr_info)) {
- SetDefaultValues(&other);
-}
-
-ServiceWorkerProviderHostInfo::ServiceWorkerProviderHostInfo(
- ServiceWorkerProviderHostInfo&& other,
- mojom::ServiceWorkerContainerHostAssociatedRequest host_request,
- mojom::ServiceWorkerContainerAssociatedPtrInfo client_ptr_info)
- : provider_id(other.provider_id),
- route_id(other.route_id),
- type(other.type),
- is_parent_frame_secure(other.is_parent_frame_secure),
- host_request(std::move(host_request)),
- client_ptr_info(std::move(client_ptr_info)) {
- DCHECK(!other.host_request.is_pending());
- DCHECK(!other.client_ptr_info.is_valid());
- SetDefaultValues(&other);
-}
-
-ServiceWorkerProviderHostInfo::ServiceWorkerProviderHostInfo(
- int provider_id,
- int route_id,
- blink::mojom::ServiceWorkerProviderType type,
- bool is_parent_frame_secure)
- : provider_id(provider_id),
- route_id(route_id),
- type(type),
- is_parent_frame_secure(is_parent_frame_secure) {}
-
-ServiceWorkerProviderHostInfo::~ServiceWorkerProviderHostInfo() {}
-
-ServiceWorkerProviderHostInfo& ServiceWorkerProviderHostInfo::operator=(
- ServiceWorkerProviderHostInfo&& other) {
- provider_id = other.provider_id;
- route_id = other.route_id;
- type = other.type;
- is_parent_frame_secure = other.is_parent_frame_secure;
-
- SetDefaultValues(&other);
- return *this;
-}
-
-} // namespace content
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
deleted file mode 100644
index d7ebeb3228c..00000000000
--- a/chromium/content/common/service_worker/service_worker_provider_host_info.h
+++ /dev/null
@@ -1,76 +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_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_INFO_H_
-#define CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_INFO_H_
-
-#include "content/common/service_worker/service_worker_container.mojom.h"
-#include "content/common/service_worker/service_worker_types.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
-
-namespace content {
-
-// ServiceWorkerProviderHostInfo contains params for creating a
-// ServiceWorkerProviderHost.
-// mojom::ServiceWorkerProviderHostInfo is mapped to this struct.
-struct CONTENT_EXPORT ServiceWorkerProviderHostInfo {
- ServiceWorkerProviderHostInfo();
- ServiceWorkerProviderHostInfo(ServiceWorkerProviderHostInfo&& other);
- ServiceWorkerProviderHostInfo(
- ServiceWorkerProviderHostInfo&& other,
- mojom::ServiceWorkerContainerHostAssociatedRequest host_request,
- mojom::ServiceWorkerContainerAssociatedPtrInfo client_ptr_info);
- ServiceWorkerProviderHostInfo(int provider_id,
- int route_id,
- blink::mojom::ServiceWorkerProviderType type,
- bool is_parent_frame_secure);
- ~ServiceWorkerProviderHostInfo();
-
- ServiceWorkerProviderHostInfo& operator=(
- ServiceWorkerProviderHostInfo&& other);
-
- // This is unique within its child process except for PlzNavigate. When
- // PlzNavigate is on, |provider_id| is managed on the browser process and it
- // will be unique among all of providers.
- int provider_id;
-
- // When this provider is created for a document, |route_id| is the frame ID of
- // it. Otherwise |route_id| is MSG_ROUTING_NONE.
- int route_id;
-
- // 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;
- // that is, blink::WebFrame::canHaveSecureChild() returns false. This doesn't
- // mean the document is necessarily an insecure context, because the document
- // may have a URL whose scheme is granted an exception that allows bypassing
- // the ancestor secure context check. See the comment in
- // blink::Document::isSecureContextImpl for more details. If the provider is
- // not created for a document, or the document does not have a parent frame,
- // is_parent_frame_secure| is true.
- bool is_parent_frame_secure;
-
- // Mojo endpoint to send a message from the renderer to the browser. This
- // will be associated with ServiceWorkerDisptacherHost. |host_request| should
- // be valid when ServiceWorkerProviderHostInfo is passed to any Mojo method.
- // After used to create the ServiceWorkerProviderHost, this will be invalid.
- mojom::ServiceWorkerContainerHostAssociatedRequest host_request;
-
- // Mojo endpoint to send a message from the browser to the renderer. This
- // will be associated with ServiceWorkerDispatcherHost. |client_ptr_info|
- // should be valid when ServiceWorkerProviderHostInfo is passed to any Mojo
- // method.
- // After used to create the ServiceWorkerProviderHost, this will be invalid.
- mojom::ServiceWorkerContainerAssociatedPtrInfo client_ptr_info;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderHostInfo);
-};
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_INFO_H_
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
deleted file mode 100644
index 59833f84983..00000000000
--- a/chromium/content/common/service_worker/service_worker_provider_struct_traits.cc
+++ /dev/null
@@ -1,25 +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/service_worker/service_worker_provider_struct_traits.h"
-
-namespace mojo {
-
-bool StructTraits<content::mojom::ServiceWorkerProviderHostInfoDataView,
- content::ServiceWorkerProviderHostInfo>::
- Read(content::mojom::ServiceWorkerProviderHostInfoDataView in,
- content::ServiceWorkerProviderHostInfo* out) {
- if (!in.ReadType(&out->type))
- return false;
- out->provider_id = in.provider_id();
- out->route_id = in.route_id();
- out->is_parent_frame_secure = in.is_parent_frame_secure();
- out->host_request = in.TakeHostRequest<
- content::mojom::ServiceWorkerContainerHostAssociatedRequest>();
- out->client_ptr_info = in.TakeClientPtrInfo<
- content::mojom::ServiceWorkerContainerAssociatedPtrInfo>();
- return true;
-}
-
-} // 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
deleted file mode 100644
index 20316209d9d..00000000000
--- a/chromium/content/common/service_worker/service_worker_provider_struct_traits.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_STRUCT_TRAITS_H_
-#define CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_STRUCT_TRAITS_H_
-
-#include "content/common/service_worker/service_worker_provider.mojom.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<content::mojom::ServiceWorkerProviderHostInfoDataView,
- content::ServiceWorkerProviderHostInfo> {
- static int32_t provider_id(
- const content::ServiceWorkerProviderHostInfo& info) {
- return info.provider_id;
- }
-
- static int32_t route_id(const content::ServiceWorkerProviderHostInfo& info) {
- return info.route_id;
- }
-
- static blink::mojom::ServiceWorkerProviderType type(
- const content::ServiceWorkerProviderHostInfo& info) {
- return info.type;
- }
-
- static bool is_parent_frame_secure(
- const content::ServiceWorkerProviderHostInfo& info) {
- return info.is_parent_frame_secure;
- }
-
- static content::mojom::ServiceWorkerContainerHostAssociatedRequest&
- host_request(content::ServiceWorkerProviderHostInfo& info) {
- return info.host_request;
- }
-
- static content::mojom::ServiceWorkerContainerAssociatedPtrInfo&
- client_ptr_info(content::ServiceWorkerProviderHostInfo& info) {
- return info.client_ptr_info;
- }
-
- static bool Read(content::mojom::ServiceWorkerProviderHostInfoDataView in,
- content::ServiceWorkerProviderHostInfo* out);
-};
-
-} // namespace mojo
-
-#endif // CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_STRUCT_TRAITS_H_
diff --git a/chromium/content/common/service_worker/service_worker_status_code.cc b/chromium/content/common/service_worker/service_worker_status_code.cc
deleted file mode 100644
index c0df9c6d96b..00000000000
--- a/chromium/content/common/service_worker/service_worker_status_code.cc
+++ /dev/null
@@ -1,59 +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/service_worker/service_worker_status_code.h"
-
-#include "base/logging.h"
-
-namespace content {
-
-const char* ServiceWorkerStatusToString(ServiceWorkerStatusCode status) {
- switch (status) {
- case SERVICE_WORKER_OK:
- return "Operation has succeeded";
- case SERVICE_WORKER_ERROR_FAILED:
- return "Operation has failed (unknown reason)";
- case SERVICE_WORKER_ERROR_ABORT:
- return "Operation has been aborted";
- case SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND:
- return "Could not find a renderer process to run a service worker";
- case SERVICE_WORKER_ERROR_NOT_FOUND:
- return "Not found";
- case SERVICE_WORKER_ERROR_EXISTS:
- return "Already exists";
- case SERVICE_WORKER_ERROR_START_WORKER_FAILED:
- return "ServiceWorker cannot be started";
- case SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED:
- return "ServiceWorker failed to install";
- case SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED:
- return "ServiceWorker failed to activate";
- case SERVICE_WORKER_ERROR_IPC_FAILED:
- return "IPC connection was closed or IPC error has occurred";
- case SERVICE_WORKER_ERROR_NETWORK:
- return "Operation failed by network issue";
- case SERVICE_WORKER_ERROR_SECURITY:
- return "Operation failed by security issue";
- case SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED:
- return "ServiceWorker failed to handle event (event.waitUntil "
- "Promise rejected)";
- case SERVICE_WORKER_ERROR_STATE:
- return "The ServiceWorker state was not valid";
- case SERVICE_WORKER_ERROR_TIMEOUT:
- return "The ServiceWorker timed out";
- case SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED:
- return "ServiceWorker script evaluation failed";
- case SERVICE_WORKER_ERROR_DISK_CACHE:
- return "Disk cache error";
- case SERVICE_WORKER_ERROR_REDUNDANT:
- return "Redundant worker";
- case SERVICE_WORKER_ERROR_DISALLOWED:
- return "Worker disallowed";
- case SERVICE_WORKER_ERROR_MAX_VALUE:
- NOTREACHED();
- }
- NOTREACHED();
- return "";
-}
-
-} // namespace content
diff --git a/chromium/content/common/service_worker/service_worker_status_code.h b/chromium/content/common/service_worker/service_worker_status_code.h
deleted file mode 100644
index 24be8167310..00000000000
--- a/chromium/content/common/service_worker/service_worker_status_code.h
+++ /dev/null
@@ -1,88 +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_SERVICE_WORKER_SERVICE_WORKER_STATUS_CODE_H_
-#define CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_STATUS_CODE_H_
-
-#include "content/common/content_export.h"
-
-namespace content {
-
-// Generic service worker operation statuses.
-// This enum is used in UMA histograms. Append-only.
-enum ServiceWorkerStatusCode {
- // Operation succeeded.
- SERVICE_WORKER_OK = 0,
-
- // Generic operation error (more specific error code should be used in
- // general).
- SERVICE_WORKER_ERROR_FAILED = 1,
-
- // Operation was aborted (e.g. due to context or child process shutdown).
- SERVICE_WORKER_ERROR_ABORT = 2,
-
- // Starting a new service worker script context failed.
- SERVICE_WORKER_ERROR_START_WORKER_FAILED = 3,
-
- // Could not find a renderer process to run a service worker.
- SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND = 4,
-
- // Generic error code to indicate the specified item is not found.
- SERVICE_WORKER_ERROR_NOT_FOUND = 5,
-
- // Generic error code to indicate the specified item already exists.
- SERVICE_WORKER_ERROR_EXISTS = 6,
-
- // Install event handling failed.
- SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED = 7,
-
- // Activate event handling failed.
- SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED = 8,
-
- // Sending an IPC to the worker failed (often due to child process is
- // terminated).
- SERVICE_WORKER_ERROR_IPC_FAILED = 9,
-
- // Operation is failed by network issue.
- SERVICE_WORKER_ERROR_NETWORK = 10,
-
- // Operation is failed by security issue.
- SERVICE_WORKER_ERROR_SECURITY = 11,
-
- // Event handling failed (event.waitUntil Promise rejected).
- SERVICE_WORKER_ERROR_EVENT_WAITUNTIL_REJECTED = 12,
-
- // An error triggered by invalid worker state.
- SERVICE_WORKER_ERROR_STATE = 13,
-
- // The Service Worker took too long to finish a task.
- SERVICE_WORKER_ERROR_TIMEOUT = 14,
-
- // An error occurred during initial script evaluation.
- SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED = 15,
-
- // Generic error to indicate failure to read/write the disk cache.
- SERVICE_WORKER_ERROR_DISK_CACHE = 16,
-
- // The worker is in REDUNDANT state.
- SERVICE_WORKER_ERROR_REDUNDANT = 17,
-
- // The worker was disallowed (by ContentClient: e.g., due to
- // browser settings).
- SERVICE_WORKER_ERROR_DISALLOWED = 18,
-
- // Obsolete.
- // SERVICE_WORKER_ERROR_DISABLED_WORKER = 19,
-
- // Add new status codes here.
-
- SERVICE_WORKER_ERROR_MAX_VALUE = 20
-};
-
-CONTENT_EXPORT const char* ServiceWorkerStatusToString(
- ServiceWorkerStatusCode code);
-
-} // namespace content
-
-#endif // CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_STATUS_CODE_H_
diff --git a/chromium/content/common/service_worker/service_worker_types.cc b/chromium/content/common/service_worker/service_worker_types.cc
index 97f523803f3..598a7df25d8 100644
--- a/chromium/content/common/service_worker/service_worker_types.cc
+++ b/chromium/content/common/service_worker/service_worker_types.cc
@@ -73,6 +73,7 @@ std::string ServiceWorkerFetchRequest::Serialize() const {
request_proto.set_redirect_mode(static_cast<int>(redirect_mode));
request_proto.set_integrity(integrity);
request_proto.set_keepalive(keepalive);
+ request_proto.set_is_history_navigation(is_history_navigation);
request_proto.set_client_id(client_id);
return request_proto.SerializeAsString();
@@ -120,6 +121,7 @@ ServiceWorkerFetchRequest ServiceWorkerFetchRequest::ParseFromString(
request_proto.redirect_mode());
request.integrity = request_proto.integrity();
request.keepalive = request_proto.keepalive();
+ request.is_history_navigation = request_proto.is_history_navigation();
request.client_id = request_proto.client_id();
return request;
diff --git a/chromium/content/common/service_worker/service_worker_types.h b/chromium/content/common/service_worker/service_worker_types.h
index 15b83155507..cdcade92d1d 100644
--- a/chromium/content/common/service_worker/service_worker_types.h
+++ b/chromium/content/common/service_worker/service_worker_types.h
@@ -118,6 +118,7 @@ struct CONTENT_EXPORT ServiceWorkerFetchRequest {
bool keepalive = false;
std::string client_id;
bool is_reload = false;
+ bool is_history_navigation = false;
};
// Roughly corresponds to the Fetch API's Response type. This struct has several
diff --git a/chromium/content/common/service_worker/service_worker_types.proto b/chromium/content/common/service_worker/service_worker_types.proto
index f4470b521f7..1bb4de05d61 100644
--- a/chromium/content/common/service_worker/service_worker_types.proto
+++ b/chromium/content/common/service_worker/service_worker_types.proto
@@ -38,4 +38,6 @@ message ServiceWorkerFetchRequest {
optional string integrity = 12;
optional bool keepalive = 13;
optional string client_id = 14;
+ reserved 15; // for is_reload_navigation
+ optional bool is_history_navigation = 16;
} \ No newline at end of file
diff --git a/chromium/content/common/service_worker/service_worker_utils.cc b/chromium/content/common/service_worker/service_worker_utils.cc
index 0820aad1064..5abbb6e9dfb 100644
--- a/chromium/content/common/service_worker/service_worker_utils.cc
+++ b/chromium/content/common/service_worker/service_worker_utils.cc
@@ -4,9 +4,6 @@
#include "content/common/service_worker/service_worker_utils.h"
-#include <sstream>
-#include <string>
-
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/logging.h"
@@ -56,6 +53,27 @@ bool ServiceWorkerUtils::IsPathRestrictionSatisfied(
const GURL& script_url,
const std::string* service_worker_allowed_header_value,
std::string* error_message) {
+ return IsPathRestrictionSatisfiedInternal(scope, script_url, true,
+ service_worker_allowed_header_value,
+ error_message);
+}
+
+// static
+bool ServiceWorkerUtils::IsPathRestrictionSatisfiedWithoutHeader(
+ const GURL& scope,
+ const GURL& script_url,
+ std::string* error_message) {
+ return IsPathRestrictionSatisfiedInternal(scope, script_url, false, nullptr,
+ error_message);
+}
+
+// static
+bool ServiceWorkerUtils::IsPathRestrictionSatisfiedInternal(
+ const GURL& scope,
+ const GURL& script_url,
+ bool service_worker_allowed_header_supported,
+ const std::string* service_worker_allowed_header_value,
+ std::string* error_message) {
DCHECK(scope.is_valid());
DCHECK(!scope.has_ref());
DCHECK(script_url.is_valid());
@@ -66,7 +84,8 @@ bool ServiceWorkerUtils::IsPathRestrictionSatisfied(
return false;
std::string max_scope_string;
- if (service_worker_allowed_header_value) {
+ if (service_worker_allowed_header_value &&
+ service_worker_allowed_header_supported) {
GURL max_scope = script_url.Resolve(*service_worker_allowed_header_value);
if (!max_scope.is_valid()) {
*error_message = "An invalid Service-Worker-Allowed header value ('";
@@ -85,13 +104,19 @@ bool ServiceWorkerUtils::IsPathRestrictionSatisfied(
*error_message = "The path of the provided scope ('";
error_message->append(scope_string);
error_message->append("') is not under the max scope allowed (");
- if (service_worker_allowed_header_value)
+ if (service_worker_allowed_header_value &&
+ service_worker_allowed_header_supported)
error_message->append("set by Service-Worker-Allowed: ");
error_message->append("'");
error_message->append(max_scope_string);
- error_message->append(
- "'). Adjust the scope, move the Service Worker script, or use the "
- "Service-Worker-Allowed HTTP header to allow the scope.");
+ if (service_worker_allowed_header_supported) {
+ error_message->append(
+ "'). Adjust the scope, move the Service Worker script, or use the "
+ "Service-Worker-Allowed HTTP header to allow the scope.");
+ } else {
+ error_message->append(
+ "'). Adjust the scope or move the Service Worker script.");
+ }
return false;
}
return true;
@@ -141,28 +166,6 @@ bool ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(
return true;
}
-// static
-bool ServiceWorkerUtils::IsServicificationEnabled() {
- return base::FeatureList::IsEnabled(network::features::kNetworkService) ||
- base::FeatureList::IsEnabled(features::kServiceWorkerServicification);
-}
-
-// static
-std::string ServiceWorkerUtils::ErrorTypeToString(
- blink::mojom::ServiceWorkerErrorType error) {
- std::ostringstream oss;
- oss << error;
- return oss.str();
-}
-
-// static
-std::string ServiceWorkerUtils::ClientTypeToString(
- blink::mojom::ServiceWorkerClientType type) {
- std::ostringstream oss;
- oss << type;
- return oss.str();
-}
-
bool ServiceWorkerUtils::ExtractSinglePartHttpRange(
const net::HttpRequestHeaders& headers,
bool* has_range_out,
diff --git a/chromium/content/common/service_worker/service_worker_utils.h b/chromium/content/common/service_worker/service_worker_utils.h
index e7ce9c975f1..6260688108a 100644
--- a/chromium/content/common/service_worker/service_worker_utils.h
+++ b/chromium/content/common/service_worker/service_worker_utils.h
@@ -5,15 +5,17 @@
#ifndef CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_UTILS_H_
#define CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_UTILS_H_
+#include <sstream>
+#include <string>
+
#include "base/command_line.h"
#include "base/macros.h"
#include "content/common/content_export.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/resource_type.h"
#include "net/http/http_request_headers.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "url/gurl.h"
namespace content {
@@ -37,6 +39,13 @@ class ServiceWorkerUtils {
const std::string* service_worker_allowed_header_value,
std::string* error_message);
+ // Same as above IsPathRestrictionSatisfied, but without considering
+ // 'Service-Worker-Allowed' header.
+ CONTENT_EXPORT static bool IsPathRestrictionSatisfiedWithoutHeader(
+ const GURL& scope,
+ const GURL& script_url,
+ std::string* error_message);
+
static bool ContainsDisallowedCharacter(const GURL& scope,
const GURL& script_url,
std::string* error_message);
@@ -48,19 +57,17 @@ class ServiceWorkerUtils {
CONTENT_EXPORT static bool AllOriginsMatchAndCanAccessServiceWorkers(
const std::vector<GURL>& urls);
- // Returns true if servicified service worker is enabled.
- CONTENT_EXPORT static bool IsServicificationEnabled();
-
// Returns true if the |provider_id| was assigned by the browser process.
static bool IsBrowserAssignedProviderId(int provider_id) {
return provider_id < kInvalidServiceWorkerProviderId;
}
- static std::string ErrorTypeToString(
- blink::mojom::ServiceWorkerErrorType error);
-
- static std::string ClientTypeToString(
- blink::mojom::ServiceWorkerClientType type);
+ template <typename T>
+ static std::string MojoEnumToString(T mojo_enum) {
+ std::ostringstream oss;
+ oss << mojo_enum;
+ return oss.str();
+ }
// Sets |has_range| to true if |headers| specify a single range request, and
// |offset| and |size| to the range. Returns true on valid input (regardless
@@ -74,6 +81,14 @@ class ServiceWorkerUtils {
static bool ShouldBypassCacheDueToUpdateViaCache(
bool is_main_script,
blink::mojom::ServiceWorkerUpdateViaCache cache_mode);
+
+ private:
+ static bool IsPathRestrictionSatisfiedInternal(
+ const GURL& scope,
+ const GURL& script_url,
+ bool service_worker_allowed_header_supported,
+ const std::string* service_worker_allowed_header_value,
+ std::string* error_message);
};
class CONTENT_EXPORT LongestScopeMatcher {
diff --git a/chromium/content/common/shared_worker/shared_worker_connector.mojom b/chromium/content/common/shared_worker/shared_worker_connector.mojom
index 39cd78c7450..a3f52a39f75 100644
--- a/chromium/content/common/shared_worker/shared_worker_connector.mojom
+++ b/chromium/content/common/shared_worker/shared_worker_connector.mojom
@@ -6,6 +6,7 @@ module content.mojom;
import "content/common/shared_worker/shared_worker_client.mojom";
import "content/common/shared_worker/shared_worker_info.mojom";
+import "third_party/blink/public/mojom/blob/blob_url_store.mojom";
import "third_party/blink/public/mojom/shared_worker/shared_worker_creation_context_type.mojom";
// This interface is exposed to enable a client to create and connect to a
@@ -13,8 +14,13 @@ import "third_party/blink/public/mojom/shared_worker/shared_worker_creation_cont
interface SharedWorkerConnector {
// Connect to (and create if necessary) a SharedWorker specified by |info|.
// The SharedWorker will be terminated if all clients go away.
+ // |blob_url_token| should be non-null when the worker is loaded from a blob:
+ // URL. The token will then be used to look up the blob associated with the
+ // blob URL. Without this by the time the worker code starts fetching
+ // the URL the blob URL might no longer be valid.
Connect(SharedWorkerInfo info,
SharedWorkerClient client,
blink.mojom.SharedWorkerCreationContextType creation_context_type,
- handle<message_pipe> message_port);
+ handle<message_pipe> message_port,
+ blink.mojom.BlobURLToken? blob_url_token);
};
diff --git a/chromium/content/common/shared_worker/shared_worker_factory.mojom b/chromium/content/common/shared_worker/shared_worker_factory.mojom
index 13c068af65a..50332f4af33 100644
--- a/chromium/content/common/shared_worker/shared_worker_factory.mojom
+++ b/chromium/content/common/shared_worker/shared_worker_factory.mojom
@@ -4,10 +4,12 @@
module content.mojom;
+import "content/common/native_types.mojom";
import "content/common/service_worker/service_worker_provider.mojom";
import "content/common/shared_worker/shared_worker.mojom";
import "content/common/shared_worker/shared_worker_host.mojom";
import "content/common/shared_worker/shared_worker_info.mojom";
+import "content/common/url_loader_factory_bundle.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "services/network/public/mojom/url_loader_factory.mojom";
import "services/service_manager/public/mojom/interface_provider.mojom";
@@ -30,6 +32,7 @@ interface SharedWorkerFactory {
SharedWorkerInfo info,
bool pause_on_start,
mojo_base.mojom.UnguessableToken devtools_worker_token,
+ RendererPreferences renderer_preferences,
blink.mojom.WorkerContentSettingsProxy content_settings,
// S13nServiceWorker:
@@ -53,6 +56,14 @@ interface SharedWorkerFactory {
// worker execution contexts.
associated network.mojom.URLLoaderFactory? script_loader_factory_ptr_info,
+ // NetworkService:
+ // When the Network Service is enabled, |subresource_loader_factories|
+ // may also be provided a means for the shared worker to load
+ // subresources where applicable. For example, this allows the shared
+ // worker to load chrome-extension:// URLs which the renderer's default
+ // loader factory can't load.
+ URLLoaderFactoryBundle? subresource_loader_factories,
+
SharedWorkerHost host,
SharedWorker& shared_worker,
service_manager.mojom.InterfaceProvider interface_provider);
diff --git a/chromium/content/common/skia_utils.cc b/chromium/content/common/skia_utils.cc
new file mode 100644
index 00000000000..9aec40788c2
--- /dev/null
+++ b/chromium/content/common/skia_utils.cc
@@ -0,0 +1,68 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/skia_utils.h"
+
+#include "base/command_line.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/sys_info.h"
+#include "base/trace_event/memory_dump_manager.h"
+#include "build/build_config.h"
+#include "content/public/common/content_switches.h"
+#include "skia/ext/event_tracer_impl.h"
+#include "skia/ext/skia_memory_dump_provider.h"
+#include "third_party/skia/include/core/SkGraphics.h"
+
+namespace content {
+namespace {
+
+// Maximum allocation size allowed for image scaling filters that
+// require pre-scaling. Skia will fallback to a filter that doesn't
+// require pre-scaling if the default filter would require an
+// allocation that exceeds this limit.
+const size_t kImageCacheSingleAllocationByteLimit = 64 * 1024 * 1024;
+
+} // namespace
+
+void InitializeSkia() {
+ // Make sure that any switches used here are propagated to the renderer and
+ // GPU processes.
+ const base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
+ if (!cmd.HasSwitch(switches::kDisableSkiaRuntimeOpts)) {
+ SkGraphics::Init();
+ }
+
+ const int kMB = 1024 * 1024;
+ size_t font_cache_limit;
+#if defined(OS_ANDROID)
+ font_cache_limit = base::SysInfo::IsLowEndDevice() ? kMB : 8 * kMB;
+ SkGraphics::SetFontCacheLimit(font_cache_limit);
+#else
+ if (cmd.HasSwitch(switches::kSkiaFontCacheLimitMb)) {
+ if (base::StringToSizeT(
+ cmd.GetSwitchValueASCII(switches::kSkiaFontCacheLimitMb),
+ &font_cache_limit)) {
+ SkGraphics::SetFontCacheLimit(font_cache_limit * kMB);
+ }
+ }
+
+ size_t resource_cache_limit;
+ if (cmd.HasSwitch(switches::kSkiaResourceCacheLimitMb)) {
+ if (base::StringToSizeT(
+ cmd.GetSwitchValueASCII(switches::kSkiaResourceCacheLimitMb),
+ &resource_cache_limit)) {
+ SkGraphics::SetResourceCacheTotalByteLimit(resource_cache_limit * kMB);
+ }
+ }
+#endif
+
+ InitSkiaEventTracer();
+ base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+ skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
+
+ SkGraphics::SetResourceCacheSingleAllocationByteLimit(
+ kImageCacheSingleAllocationByteLimit);
+}
+
+} // namespace content
diff --git a/chromium/content/common/skia_utils.h b/chromium/content/common/skia_utils.h
new file mode 100644
index 00000000000..53b6878ceee
--- /dev/null
+++ b/chromium/content/common/skia_utils.h
@@ -0,0 +1,16 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_SKIA_UTILS_H_
+#define CONTENT_COMMON_SKIA_UTILS_H_
+
+namespace content {
+
+// Common utility code for skia initialization done in the renderer process, and
+// also in the GPU process for viz/oop-r which runs skia in the GPU process.
+void InitializeSkia();
+
+} // namespace content
+
+#endif // CONTENT_COMMON_SKIA_UTILS_H_
diff --git a/chromium/content/common/speech_recognizer.mojom b/chromium/content/common/speech_recognizer.mojom
deleted file mode 100644
index f790d4c93cb..00000000000
--- a/chromium/content/common/speech_recognizer.mojom
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module content.mojom;
-
-import "content/public/common/speech_recognition_grammar.mojom";
-import "content/public/common/speech_recognition_result.mojom";
-import "content/public/common/speech_recognition_error.mojom";
-import "url/mojom/origin.mojom";
-
-// Created by the renderer and sent to the browser to start a speech recognition
-// session.
-struct StartSpeechRecognitionRequestParams {
- // Used to create a connection with a SpeechRecognitionSession implementation
- // that will be created when the session is created.
- SpeechRecognitionSession& session_request;
-
- // Used by the browser to communicate with a SpeechRecognitionSessionClient
- // implementation created for the new session.
- SpeechRecognitionSessionClient client;
-
- // Language to use for speech recognition.
- string language;
-
- // Speech grammars to use.
- array<content.mojom.SpeechRecognitionGrammar> grammars;
-
- // URL of the page (or iframe if applicable).
- url.mojom.Origin origin;
-
- // Maximum number of hypotheses allowed for each results.
- uint32 max_hypotheses;
-
- // Whether the user requested continuous recognition.
- bool continuous;
-
- // Whether the user requested interim results.
- bool interim_results;
-};
-
-// API for the renderer process to start a speech recognition session in the
-// browser process.
-interface SpeechRecognizer {
- // Requests the speech recognition service to start speech recognition.
- Start(StartSpeechRecognitionRequestParams params);
-};
-
-// API for the renderer process to stop or abort an existing speech recognition
-// session. An InterfaceRequest is sent to the browser process via
-// SpeechRecognizer::Start, and is bound to an implementation there.
-// SpeechRecognitionSession and SpeechRecognitionSessionClient are 1:1 with each
-// other and with WebSpeechRecognitionHandle.
-interface SpeechRecognitionSession {
- // Requests the speech recognition service to abort speech recognition for the
- // associated session.
- Abort();
-
- // Requests the speech recognition service to stop audio capture for the
- // associated session.
- StopCapture();
-};
-
-// API for the browser process to communicate speech recognition related updates
-// with renderer and cause events to be dispatched to the appropriate speech
-// recognition handle. An InterfacePtr for each handle is sent to the browser
-// process via SpeechRecognizer::Start. SpeechRecognitionSession and
-// SpeechRecognitionSessionClient are 1:1 with each other and with
-// WebSpeechRecognitionHandle.
-interface SpeechRecognitionSessionClient {
- // Called to dispatch the "result" event.
- ResultRetrieved(array<content.mojom.SpeechRecognitionResult> results);
-
- // Called to dispatch the "nomatch" event if the error code passed is of types
- // kNoMatch, otherwise dispatchers an "error" event.
- ErrorOccurred(content.mojom.SpeechRecognitionError error);
-
- // Called to dispatch the "start" event.
- Started();
-
- // Called to dispatch the "audiostart" event.
- AudioStarted();
-
- // Called to dispatch the "soundstart" and "speechstart" events.
- SoundStarted();
-
- // Called to dispatch "soundend" and "speechend" events.
- SoundEnded();
-
- // Called to dispatch the "audioend" event.
- AudioEnded();
-
- // Called to dispatch the "end" event.
- Ended();
-};
diff --git a/chromium/content/common/storage_partition_service.mojom b/chromium/content/common/storage_partition_service.mojom
deleted file mode 100644
index c453cd6bf93..00000000000
--- a/chromium/content/common/storage_partition_service.mojom
+++ /dev/null
@@ -1,27 +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;
-
-import "content/common/leveldb_wrapper.mojom";
-import "url/mojom/origin.mojom";
-
-// Represents a namespace for Session Storage and allows data access and
-// cloning. This is implemented by the browser process.
-interface SessionStorageNamespace {
- OpenArea(url.mojom.Origin origin,
- associated LevelDBWrapper& database);
- // Clones this namespace the new given namespace. Used before navigating to
- // a new frame which would be given this session storage namespace.
- Clone(string clone_to_namespace);
-};
-
-// Returns services related to the current storage partition. This is
-// implemented by the browser process.
-interface StoragePartitionService {
- OpenLocalStorage(url.mojom.Origin origin,
- LevelDBWrapper& database);
- OpenSessionStorage(string namespace_id,
- SessionStorageNamespace& session_namespace);
-};
diff --git a/chromium/content/common/swapped_out_messages.cc b/chromium/content/common/swapped_out_messages.cc
index 65cbd051764..e662d699b12 100644
--- a/chromium/content/common/swapped_out_messages.cc
+++ b/chromium/content/common/swapped_out_messages.cc
@@ -55,9 +55,9 @@ bool SwappedOutMessages::CanHandleWhileSwappedOut(
// We allow closing even if we are in the process of swapping out.
case ViewHostMsg_Close::ID:
// Sends an ACK.
- case ViewHostMsg_RequestMove::ID:
+ case ViewHostMsg_RequestSetBounds::ID:
// Sends an ACK.
- case AccessibilityHostMsg_Events::ID:
+ case AccessibilityHostMsg_EventBundle::ID:
return true;
default:
break;
diff --git a/chromium/content/common/tab_switching_time_callback.cc b/chromium/content/common/tab_switching_time_callback.cc
new file mode 100644
index 00000000000..b15c4950fea
--- /dev/null
+++ b/chromium/content/common/tab_switching_time_callback.cc
@@ -0,0 +1,32 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/common/tab_switching_time_callback.h"
+
+#include "base/bind.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/trace_event/trace_event.h"
+#include "ui/gfx/presentation_feedback.h"
+
+namespace content {
+
+base::OnceCallback<void(const gfx::PresentationFeedback&)>
+CreateTabSwitchingTimeRecorder(base::TimeTicks request_time) {
+ static uint32_t trace_id = 0;
+ TRACE_EVENT_ASYNC_BEGIN0("latency", "TabSwitching::Latency",
+ TRACE_ID_LOCAL(trace_id));
+ return base::BindOnce(
+ [](base::TimeTicks request_timestamp, uint32_t trace_id,
+ const gfx::PresentationFeedback& feedback) {
+ const auto delta = feedback.timestamp - request_timestamp;
+ UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration", delta);
+ TRACE_EVENT_ASYNC_END1("latency", "TabSwitching::Latency",
+ TRACE_ID_LOCAL(trace_id), "latency",
+ delta.InMillisecondsF());
+ },
+ request_time, trace_id);
+ ++trace_id;
+}
+
+} // namespace content
diff --git a/chromium/content/common/tab_switching_time_callback.h b/chromium/content/common/tab_switching_time_callback.h
new file mode 100644
index 00000000000..913e5cbb2eb
--- /dev/null
+++ b/chromium/content/common/tab_switching_time_callback.h
@@ -0,0 +1,22 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_COMMON_TAB_SWITCHING_TIME_CALLBACK_H_
+#define CONTENT_COMMON_TAB_SWITCHING_TIME_CALLBACK_H_
+
+#include "base/callback_forward.h"
+#include "base/time/time.h"
+
+namespace gfx {
+struct PresentationFeedback;
+}
+
+namespace content {
+
+base::OnceCallback<void(const gfx::PresentationFeedback&)>
+CreateTabSwitchingTimeRecorder(base::TimeTicks request_time);
+
+} // namespace content
+
+#endif // CONTENT_COMMON_TAB_SWITCHING_TIME_CALLBACK_H_
diff --git a/chromium/content/common/throttling_url_loader.cc b/chromium/content/common/throttling_url_loader.cc
index 28a8b328015..1a3324800c8 100644
--- a/chromium/content/common/throttling_url_loader.cc
+++ b/chromium/content/common/throttling_url_loader.cc
@@ -125,10 +125,8 @@ ThrottlingURLLoader::StartInfo::StartInfo(
ThrottlingURLLoader::StartInfo::~StartInfo() = default;
ThrottlingURLLoader::ResponseInfo::ResponseInfo(
- const network::ResourceResponseHead& in_response_head,
- network::mojom::DownloadedTempFilePtr in_downloaded_file)
- : response_head(in_response_head),
- downloaded_file(std::move(in_downloaded_file)) {}
+ const network::ResourceResponseHead& in_response_head)
+ : response_head(in_response_head) {}
ThrottlingURLLoader::ResponseInfo::~ResponseInfo() = default;
@@ -179,9 +177,17 @@ ThrottlingURLLoader::~ThrottlingURLLoader() {
}
}
-void ThrottlingURLLoader::FollowRedirect() {
- if (url_loader_)
- url_loader_->FollowRedirect(base::nullopt);
+void ThrottlingURLLoader::FollowRedirect(
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
+ if (url_loader_) {
+ if (to_be_removed_request_headers_.empty()) {
+ url_loader_->FollowRedirect(base::nullopt, modified_request_headers);
+ } else {
+ url_loader_->FollowRedirect(to_be_removed_request_headers_,
+ modified_request_headers);
+ }
+ to_be_removed_request_headers_.clear();
+ }
}
void ThrottlingURLLoader::SetPriority(net::RequestPriority priority,
@@ -307,8 +313,7 @@ void ThrottlingURLLoader::StopDeferringForThrottle(
}
void ThrottlingURLLoader::OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) {
+ const network::ResourceResponseHead& response_head) {
DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
DCHECK(!loader_cancelled_);
DCHECK(deferring_throttles_.empty());
@@ -326,15 +331,13 @@ void ThrottlingURLLoader::OnReceiveResponse(
if (deferred) {
deferred_stage_ = DEFERRED_RESPONSE;
- response_info_ = std::make_unique<ResponseInfo>(
- response_head, std::move(downloaded_file));
+ response_info_ = std::make_unique<ResponseInfo>(response_head);
client_binding_.PauseIncomingMethodCallProcessing();
return;
}
}
- forwarding_client_->OnReceiveResponse(response_head,
- std::move(downloaded_file));
+ forwarding_client_->OnReceiveResponse(response_head);
}
void ThrottlingURLLoader::OnReceiveRedirect(
@@ -350,12 +353,16 @@ void ThrottlingURLLoader::OnReceiveRedirect(
auto* throttle = entry.throttle.get();
bool throttle_deferred = false;
auto weak_ptr = weak_factory_.GetWeakPtr();
+ std::vector<std::string> headers;
throttle->WillRedirectRequest(redirect_info, response_head,
- &throttle_deferred);
+ &throttle_deferred, &headers);
if (!weak_ptr)
return;
if (!HandleThrottleResult(throttle, throttle_deferred, &deferred))
return;
+
+ to_be_removed_request_headers_.insert(
+ to_be_removed_request_headers_.end(), headers.begin(), headers.end());
}
if (deferred) {
@@ -374,14 +381,6 @@ void ThrottlingURLLoader::OnReceiveRedirect(
forwarding_client_->OnReceiveRedirect(redirect_info, response_head);
}
-void ThrottlingURLLoader::OnDataDownloaded(int64_t data_len,
- int64_t encoded_data_len) {
- DCHECK_EQ(DEFERRED_NONE, deferred_stage_);
- DCHECK(!loader_cancelled_);
-
- forwarding_client_->OnDataDownloaded(data_len, encoded_data_len);
-}
-
void ThrottlingURLLoader::OnUploadProgress(
int64_t current_position,
int64_t total_size,
@@ -476,9 +475,7 @@ void ThrottlingURLLoader::Resume() {
}
case DEFERRED_RESPONSE: {
client_binding_.ResumeIncomingMethodCallProcessing();
- forwarding_client_->OnReceiveResponse(
- response_info_->response_head,
- std::move(response_info_->downloaded_file));
+ forwarding_client_->OnReceiveResponse(response_info_->response_head);
// Note: |this| may be deleted here.
break;
}
diff --git a/chromium/content/common/throttling_url_loader.h b/chromium/content/common/throttling_url_loader.h
index af9f50ebead..9fb0cdf9817 100644
--- a/chromium/content/common/throttling_url_loader.h
+++ b/chromium/content/common/throttling_url_loader.h
@@ -50,7 +50,8 @@ class CONTENT_EXPORT ThrottlingURLLoader
~ThrottlingURLLoader() override;
- void FollowRedirect();
+ void FollowRedirect(
+ const base::Optional<net::HttpRequestHeaders>& modified_request_headers);
void SetPriority(net::RequestPriority priority, int32_t intra_priority_value);
// Disconnect the forwarding URLLoaderClient and the URLLoader. Returns the
@@ -101,12 +102,10 @@ class CONTENT_EXPORT ThrottlingURLLoader
// network::mojom::URLLoaderClient implementation:
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override;
+ const network::ResourceResponseHead& response_head) override;
void OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const network::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;
@@ -192,12 +191,11 @@ class CONTENT_EXPORT ThrottlingURLLoader
std::unique_ptr<StartInfo> start_info_;
struct ResponseInfo {
- ResponseInfo(const network::ResourceResponseHead& in_response_head,
- network::mojom::DownloadedTempFilePtr in_downloaded_file);
+ explicit ResponseInfo(
+ const network::ResourceResponseHead& in_response_head);
~ResponseInfo();
network::ResourceResponseHead response_head;
- network::mojom::DownloadedTempFilePtr downloaded_file;
};
// Set if response is deferred.
std::unique_ptr<ResponseInfo> response_info_;
@@ -233,6 +231,8 @@ class CONTENT_EXPORT ThrottlingURLLoader
bool response_intercepted_ = false;
+ std::vector<std::string> to_be_removed_request_headers_;
+
base::WeakPtrFactory<ThrottlingURLLoader> weak_factory_;
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 3f6b1610048..4893336ebb0 100644
--- a/chromium/content/common/throttling_url_loader_unittest.cc
+++ b/chromium/content/common/throttling_url_loader_unittest.cc
@@ -55,7 +55,7 @@ class TestURLLoaderFactory : public network::mojom::URLLoaderFactory,
}
void NotifyClientOnReceiveResponse() {
- client_ptr_->OnReceiveResponse(network::ResourceResponseHead(), nullptr);
+ client_ptr_->OnReceiveResponse(network::ResourceResponseHead());
}
void NotifyClientOnReceiveRedirect() {
@@ -95,7 +95,9 @@ class TestURLLoaderFactory : public network::mojom::URLLoaderFactory,
}
// network::mojom::URLLoader implementation.
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override {}
void ProceedWithResponse() override {}
@@ -154,8 +156,7 @@ class TestURLLoaderClient : public network::mojom::URLLoaderClient {
private:
// network::mojom::URLLoaderClient implementation:
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override {
+ const network::ResourceResponseHead& response_head) override {
on_received_response_called_++;
if (on_received_response_callback_)
on_received_response_callback_.Run();
@@ -167,7 +168,6 @@ class TestURLLoaderClient : public network::mojom::URLLoaderClient {
if (on_received_redirect_callback_)
on_received_redirect_callback_.Run();
}
- 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 {}
@@ -241,9 +241,11 @@ class TestURLLoaderThrottle : public URLLoaderThrottle {
will_start_request_callback_.Run(delegate_, defer);
}
- void WillRedirectRequest(const net::RedirectInfo& redirect_info,
- const network::ResourceResponseHead& response_head,
- bool* defer) override {
+ void WillRedirectRequest(
+ const net::RedirectInfo& redirect_info,
+ const network::ResourceResponseHead& response_head,
+ bool* defer,
+ std::vector<std::string>* to_be_removed_request_headers) override {
will_redirect_request_called_++;
if (will_redirect_request_callback_)
will_redirect_request_callback_.Run(delegate_, defer);
diff --git a/chromium/content/common/typemaps.gni b/chromium/content/common/typemaps.gni
index f1da0657d12..6219420ded5 100644
--- a/chromium/content/common/typemaps.gni
+++ b/chromium/content/common/typemaps.gni
@@ -15,10 +15,9 @@ typemaps = [
"//content/common/notifications/notification_types.typemap",
"//content/common/push_messaging.typemap",
"//content/common/render_frame_metadata.typemap",
- "//content/common/service_worker/service_worker_event_dispatcher.typemap",
+ "//content/common/service_worker/service_worker.typemap",
"//content/common/service_worker/service_worker_fetch_request.typemap",
"//content/common/service_worker/service_worker_fetch_response.typemap",
- "//content/common/service_worker/service_worker_provider.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/url_schemes.cc b/chromium/content/common/url_schemes.cc
index 8e4a1eb7f38..4113e33fb43 100644
--- a/chromium/content/common/url_schemes.cc
+++ b/chromium/content/common/url_schemes.cc
@@ -12,7 +12,6 @@
#include "base/strings/string_util.h"
#include "content/public/common/content_client.h"
#include "content/public/common/url_constants.h"
-#include "services/network/public/cpp/cors/cors_legacy.h"
#include "url/url_util.h"
namespace content {
@@ -108,7 +107,6 @@ void RegisterContentSchemes(bool lock_schemes) {
GetMutableServiceWorkerSchemes() = std::move(schemes.service_worker_schemes);
GetMutableSecureOriginsAndPatterns() = std::move(schemes.secure_origins);
- network::cors::legacy::RegisterSecureOrigins(GetSecureOriginsAndPatterns());
}
const std::vector<std::string>& GetSavableSchemes() {
diff --git a/chromium/content/common/view_messages.h b/chromium/content/common/view_messages.h
index 7411a755dd7..74d2df78226 100644
--- a/chromium/content/common/view_messages.h
+++ b/chromium/content/common/view_messages.h
@@ -22,7 +22,7 @@
#include "cc/input/touch_action.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/quads/compositor_frame.h"
-#include "components/viz/common/quads/shared_bitmap.h"
+#include "components/viz/common/resources/shared_bitmap.h"
#include "content/common/content_export.h"
#include "content/common/content_param_traits.h"
#include "content/common/date_time_suggestion.h"
@@ -52,7 +52,6 @@
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/platform/web_intrinsic_sizing_info.h"
#include "third_party/blink/public/web/web_device_emulation_params.h"
-#include "third_party/blink/public/web/web_media_player_action.h"
#include "third_party/blink/public/web/web_plugin_action.h"
#include "third_party/blink/public/web/web_popup_type.h"
#include "third_party/blink/public/web/web_text_direction.h"
@@ -81,8 +80,6 @@
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebDeviceEmulationParams::ScreenPosition,
blink::WebDeviceEmulationParams::kScreenPositionLast)
-IPC_ENUM_TRAITS_MAX_VALUE(blink::WebMediaPlayerAction::Type,
- blink::WebMediaPlayerAction::Type::kTypeLast)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebPluginAction::Type,
blink::WebPluginAction::Type::kTypeLast)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebPopupType,
@@ -121,11 +118,6 @@ IPC_ENUM_TRAITS_MAX_VALUE(
IPC_ENUM_TRAITS_MAX_VALUE(blink::ScrollerStyle, blink::kScrollerStyleOverlay)
#endif
-IPC_STRUCT_TRAITS_BEGIN(blink::WebMediaPlayerAction)
- IPC_STRUCT_TRAITS_MEMBER(type)
- IPC_STRUCT_TRAITS_MEMBER(enable)
-IPC_STRUCT_TRAITS_END()
-
IPC_STRUCT_TRAITS_BEGIN(blink::WebPluginAction)
IPC_STRUCT_TRAITS_MEMBER(type)
IPC_STRUCT_TRAITS_MEMBER(enable)
@@ -177,6 +169,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::VisualProperties)
IPC_STRUCT_TRAITS_MEMBER(is_fullscreen_granted)
IPC_STRUCT_TRAITS_MEMBER(display_mode)
IPC_STRUCT_TRAITS_MEMBER(capture_sequence_number)
+ IPC_STRUCT_TRAITS_MEMBER(zoom_level)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(content::MenuItem)
@@ -338,7 +331,7 @@ IPC_MESSAGE_ROUTED0(ViewMsg_WasHidden)
// message in response.
IPC_MESSAGE_ROUTED2(ViewMsg_WasShown,
bool /* needs_repainting */,
- ui::LatencyInfo /* latency_info */)
+ base::TimeTicks /* show_request_timestamp */)
// Tells the renderer to focus the first (last if reverse is true) focusable
// node.
@@ -351,12 +344,6 @@ IPC_MESSAGE_ROUTED2(ViewMsg_ShowContextMenu,
ui::MenuSourceType,
gfx::Point /* location where menu should be shown */)
-// Tells the renderer to perform the given action on the media player
-// located at the given point.
-IPC_MESSAGE_ROUTED2(ViewMsg_MediaPlayerActionAt,
- gfx::Point, /* location */
- blink::WebMediaPlayerAction)
-
// Tells the renderer to perform the given action on the plugin located at
// the given point.
IPC_MESSAGE_ROUTED2(ViewMsg_PluginActionAt,
@@ -395,12 +382,13 @@ IPC_MESSAGE_ROUTED2(ViewMsg_UpdateScreenRects,
gfx::Rect /* view_screen_rect */,
gfx::Rect /* window_screen_rect */)
-// Reply to ViewHostMsg_RequestMove, ViewHostMsg_ShowWidget, and
+// Reply to ViewHostMsg_RequestSetBounds, ViewHostMsg_ShowWidget, and
// FrameHostMsg_ShowCreatedWindow, to inform the renderer that the browser has
-// processed the move. The browser may have ignored the move, but it finished
-// processing. This is used because the renderer keeps a temporary cache of the
-// widget position while these asynchronous operations are in progress.
-IPC_MESSAGE_ROUTED0(ViewMsg_Move_ACK)
+// processed the bounds-setting. The browser may have ignored the new bounds,
+// but it finished processing. This is used because the renderer keeps a
+// temporary cache of the widget position while these asynchronous operations
+// are in progress.
+IPC_MESSAGE_ROUTED0(ViewMsg_SetBounds_ACK)
// Used to instruct the RenderView to send back updates to the preferred size.
IPC_MESSAGE_ROUTED0(ViewMsg_EnablePreferredSizeChangedMode)
@@ -480,8 +468,7 @@ IPC_MESSAGE_ROUTED0(ViewMsg_SelectWordAroundCaret)
// Sent by the browser to ask the renderer to redraw. Robust to events that can
// happen in renderer (abortion of the commit or draw, loss of output surface
// etc.).
-IPC_MESSAGE_ROUTED1(ViewMsg_ForceRedraw,
- ui::LatencyInfo /* latency_info */)
+IPC_MESSAGE_ROUTED1(ViewMsg_ForceRedraw, int /* snapshot_id */)
// Sets the viewport intersection and compositor raster area on the widget for
// an out-of-process iframe.
@@ -521,17 +508,20 @@ IPC_MESSAGE_ROUTED1(ViewHostMsg_ShowFullscreenWidget,
// message to close the view.
IPC_MESSAGE_ROUTED0(ViewHostMsg_Close)
+// Sent by the renderer process in response to an earlier ViewMsg_ForceRedraw
+// message. The reply includes the snapshot-id from the request.
+IPC_MESSAGE_ROUTED1(ViewHostMsg_ForceRedrawComplete, int /* snapshot_id */)
+
// Send in response to a ViewMsg_UpdateScreenRects so that the renderer can
// throttle these messages.
IPC_MESSAGE_ROUTED0(ViewHostMsg_UpdateScreenRects_ACK)
-// Sent by the renderer process to request that the browser move the view.
-// This corresponds to the window.resizeTo() and window.moveTo() APIs, and
-// the browser may ignore this message.
-IPC_MESSAGE_ROUTED1(ViewHostMsg_RequestMove,
- gfx::Rect /* position */)
+// Sent by the renderer process to request that the browser change the bounds of
+// the view. This corresponds to the window.resizeTo() and window.moveTo() APIs,
+// and the browser may ignore this message.
+IPC_MESSAGE_ROUTED1(ViewHostMsg_RequestSetBounds, gfx::Rect /* bounds */)
-// Indicates that the render view has been closed in respose to a
+// Indicates that the render view has been closed in response to a
// Close message.
IPC_MESSAGE_CONTROL1(ViewHostMsg_Close_ACK,
int /* old_route_id */)
diff --git a/chromium/content/common/visual_properties.h b/chromium/content/common/visual_properties.h
index dd29af0cb31..259b6ad3957 100644
--- a/chromium/content/common/visual_properties.h
+++ b/chromium/content/common/visual_properties.h
@@ -74,6 +74,10 @@ struct CONTENT_EXPORT VisualProperties {
// incremented, that means the caller wants to synchronize surfaces which
// should cause a new LocalSurfaceId to be generated.
uint32_t capture_sequence_number = 0u;
+
+ // This represents the page zoom level for a WebContents.
+ // (0 is the default value which results in 1.0 zoom factor).
+ double zoom_level = 0;
};
} // namespace content
diff --git a/chromium/content/gpu/BUILD.gn b/chromium/content/gpu/BUILD.gn
index 9a8b1ca6b4f..ee2cf00ba9a 100644
--- a/chromium/content/gpu/BUILD.gn
+++ b/chromium/content/gpu/BUILD.gn
@@ -63,7 +63,6 @@ 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:media_buildflags",
diff --git a/chromium/content/gpu/gpu_child_thread.cc b/chromium/content/gpu/gpu_child_thread.cc
index 97ca63c7942..aa8847f9780 100644
--- a/chromium/content/gpu/gpu_child_thread.cc
+++ b/chromium/content/gpu/gpu_child_thread.cc
@@ -7,9 +7,11 @@
#include <stddef.h>
#include <utility>
+#include "base/allocator/allocator_extension.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/command_line.h"
+#include "base/memory/memory_coordinator_client_registry.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
@@ -33,7 +35,7 @@
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/viz/privileged/interfaces/gl/gpu_service.mojom.h"
-#include "skia/ext/event_tracer_impl.h"
+#include "third_party/skia/include/core/SkGraphics.h"
#if defined(USE_OZONE)
#include "ui/ozone/public/ozone_platform.h"
@@ -89,8 +91,7 @@ class QueueingConnectionFilter : public ConnectionFilter {
void AddInterfaces() {
#if defined(USE_OZONE)
- ui::OzonePlatform::GetInstance()->AddInterfaces(
- &registry_with_source_info_);
+ ui::OzonePlatform::GetInstance()->AddInterfaces(registry_.get());
#endif
}
@@ -106,10 +107,6 @@ class QueueingConnectionFilter : public ConnectionFilter {
mojo::ScopedMessagePipeHandle* interface_pipe,
service_manager::Connector* connector) override {
DCHECK(io_thread_checker_.CalledOnValidThread());
- if (registry_with_source_info_.TryBindInterface(
- interface_name, interface_pipe, source_info)) {
- return;
- }
if (registry_->CanBindInterface(interface_name)) {
if (released_) {
@@ -138,9 +135,6 @@ class QueueingConnectionFilter : public ConnectionFilter {
bool released_ = false;
std::vector<std::unique_ptr<PendingRequest>> pending_requests_;
std::unique_ptr<service_manager::BinderRegistry> registry_;
- service_manager::BinderRegistryWithArgs<
- const service_manager::BindSourceInfo&>
- registry_with_source_info_;
base::WeakPtrFactory<QueueingConnectionFilter> weak_factory_;
@@ -193,7 +187,9 @@ GpuChildThread::GpuChildThread(const ChildThreadImpl::Options& options,
}
}
-GpuChildThread::~GpuChildThread() = default;
+GpuChildThread::~GpuChildThread() {
+ base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this);
+}
void GpuChildThread::Init(const base::Time& process_start_time) {
viz_main_.gpu_service()->set_start_time(process_start_time);
@@ -229,7 +225,10 @@ void GpuChildThread::Init(const base::Time& process_start_time) {
StartServiceManagerConnection();
- InitSkiaEventTracer();
+ base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
+ memory_pressure_listener_ =
+ std::make_unique<base::MemoryPressureListener>(base::BindRepeating(
+ &GpuChildThread::OnMemoryPressure, base::Unretained(this)));
}
void GpuChildThread::CreateVizMainService(
@@ -301,6 +300,23 @@ void GpuChildThread::BindServiceFactoryRequest(
std::move(request));
}
+void GpuChildThread::OnTrimMemoryImmediately() {
+ OnPurgeMemory();
+}
+
+void GpuChildThread::OnMemoryPressure(
+ base::MemoryPressureListener::MemoryPressureLevel level) {
+ if (level == base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
+ OnPurgeMemory();
+}
+
+void GpuChildThread::OnPurgeMemory() {
+ base::allocator::ReleaseFreeMemory();
+ if (viz_main_.discardable_shared_memory_manager())
+ viz_main_.discardable_shared_memory_manager()->ReleaseFreeMemory();
+ SkGraphics::PurgeAllCaches();
+}
+
#if defined(OS_ANDROID)
// static
std::unique_ptr<media::AndroidOverlay> GpuChildThread::CreateAndroidOverlay(
diff --git a/chromium/content/gpu/gpu_child_thread.h b/chromium/content/gpu/gpu_child_thread.h
index 417035ddcb0..6e0481e8ccd 100644
--- a/chromium/content/gpu/gpu_child_thread.h
+++ b/chromium/content/gpu/gpu_child_thread.h
@@ -14,6 +14,7 @@
#include "base/callback.h"
#include "base/command_line.h"
#include "base/macros.h"
+#include "base/memory/memory_coordinator_client.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
@@ -22,9 +23,9 @@
#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"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_info.h"
+#include "gpu/config/gpu_preferences.h"
#include "gpu/ipc/service/gpu_channel.h"
#include "gpu/ipc/service/gpu_channel_manager.h"
#include "gpu/ipc/service/gpu_channel_manager_delegate.h"
@@ -46,7 +47,8 @@ class GpuServiceFactory;
// IPC messages to gpu::GpuChannelManager, which is responsible for issuing
// rendering commands to the GPU.
class GpuChildThread : public ChildThreadImpl,
- public viz::VizMainImpl::Delegate {
+ public viz::VizMainImpl::Delegate,
+ public base::MemoryCoordinatorClient {
public:
GpuChildThread(std::unique_ptr<gpu::GpuInit> gpu_init,
viz::VizMainImpl::LogMessages deferred_messages);
@@ -80,6 +82,13 @@ class GpuChildThread : public ChildThreadImpl,
void PostCompositorThreadCreated(
base::SingleThreadTaskRunner* task_runner) override;
+ // ChildMemoryCoordinatorDelegate implementation.
+ void OnTrimMemoryImmediately() override;
+ // base::MemoryCoordinatorClient implementation:
+ void OnPurgeMemory() override;
+ void OnMemoryPressure(
+ base::MemoryPressureListener::MemoryPressureLevel level);
+
void BindServiceFactoryRequest(
service_manager::mojom::ServiceFactoryRequest request);
@@ -104,6 +113,8 @@ class GpuChildThread : public ChildThreadImpl,
// Holds a closure that releases pending interface requests on the IO thread.
base::Closure release_pending_requests_closure_;
+ std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
+
base::WeakPtrFactory<GpuChildThread> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(GpuChildThread);
diff --git a/chromium/content/gpu/gpu_main.cc b/chromium/content/gpu/gpu_main.cc
index e6a589fb90e..f14c045d47a 100644
--- a/chromium/content/gpu/gpu_main.cc
+++ b/chromium/content/gpu/gpu_main.cc
@@ -24,6 +24,7 @@
#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/common/skia_utils.h"
#include "content/gpu/gpu_child_thread.h"
#include "content/gpu/gpu_process.h"
#include "content/public/common/content_client.h"
@@ -34,16 +35,15 @@
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/config/gpu_driver_bug_list.h"
#include "gpu/config/gpu_info_collector.h"
+#include "gpu/config/gpu_preferences.h"
#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/buildflags.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"
#include "ui/gl/gl_context.h"
@@ -78,12 +78,10 @@
#endif
#if defined(OS_LINUX)
-#include "content/common/font_config_ipc_linux.h"
#include "content/gpu/gpu_sandbox_hook_linux.h"
#include "content/public/common/sandbox_init.h"
#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#include "services/service_manager/zygote/common/common_sandbox_support_linux.h"
-#include "third_party/skia/include/ports/SkFontConfigInterface.h"
#endif
#if defined(OS_MACOSX)
@@ -206,7 +204,7 @@ int GpuMain(const MainFunctionParams& parameters) {
if (command_line.HasSwitch(switches::kGpuPreferences)) {
std::string value =
command_line.GetSwitchValueASCII(switches::kGpuPreferences);
- bool success = gpu::SwitchValueToGpuPreferences(value, &gpu_preferences);
+ bool success = gpu_preferences.FromSwitchValue(value);
CHECK(success);
}
@@ -299,6 +297,10 @@ int GpuMain(const MainFunctionParams& parameters) {
gpu_init->set_sandbox_helper(&sandbox_helper);
+ // Since GPU initialization calls into skia, its important to initialize skia
+ // before it.
+ InitializeSkia();
+
// Gpu initialization may fail for various reasons, in which case we will need
// to tear down this process. However, we can not do so safely until the IPC
// channel is set up, because the detection of early return of a child process
@@ -339,15 +341,6 @@ int GpuMain(const MainFunctionParams& parameters) {
nullptr);
#endif
- if (gpu_preferences.enable_oop_rasterization) {
- SkGraphics::Init();
-#if defined(OS_LINUX)
- // Set up the font IPC so that the GPU process can create typefaces.
- SkFontConfigInterface::SetGlobal(
- sk_make_sp<FontConfigIPC>(service_manager::GetSandboxFD()));
-#endif
- }
-
base::HighResolutionTimerManager hi_res_timer_manager;
{
diff --git a/chromium/content/gpu/gpu_service_factory.cc b/chromium/content/gpu/gpu_service_factory.cc
index fc73e43a5c8..844125a7c6c 100644
--- a/chromium/content/gpu/gpu_service_factory.cc
+++ b/chromium/content/gpu/gpu_service_factory.cc
@@ -8,6 +8,7 @@
#include "base/task_scheduler/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
#include "services/shape_detection/public/mojom/constants.mojom.h"
#include "services/shape_detection/shape_detection_service.h"
@@ -54,9 +55,14 @@ void GpuServiceFactory::RegisterServices(ServiceMap* services) {
// 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".
+#if defined(OS_WIN)
+ // Run everything on the gpu main thread, since that's where the CDM runs.
+ info.task_runner = task_runner_;
+#else
// TODO(crbug.com/786169): Check whether this needs to be single threaded.
info.task_runner = base::CreateSingleThreadTaskRunnerWithTraits(
{base::TaskPriority::USER_BLOCKING});
+#endif // defined(OS_WIN)
services->insert(std::make_pair("media", info));
#endif // BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
diff --git a/chromium/content/gpu/gpu_service_factory.h b/chromium/content/gpu/gpu_service_factory.h
index 6644f0d0079..1316a948e2d 100644
--- a/chromium/content/gpu/gpu_service_factory.h
+++ b/chromium/content/gpu/gpu_service_factory.h
@@ -10,8 +10,8 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "content/child/service_factory.h"
-#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/config/gpu_driver_bug_workarounds.h"
+#include "gpu/config/gpu_preferences.h"
#include "media/base/android_overlay_mojo_factory.h"
#include "media/mojo/buildflags.h"
diff --git a/chromium/content/gpu/in_process_gpu_thread.cc b/chromium/content/gpu/in_process_gpu_thread.cc
index 1efa57c23e7..8c83f439f58 100644
--- a/chromium/content/gpu/in_process_gpu_thread.cc
+++ b/chromium/content/gpu/in_process_gpu_thread.cc
@@ -11,7 +11,7 @@
#include "content/gpu/gpu_process.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
-#include "gpu/command_buffer/service/gpu_preferences.h"
+#include "gpu/config/gpu_preferences.h"
#include "gpu/ipc/service/gpu_init.h"
#if defined(OS_ANDROID)
diff --git a/chromium/content/gpu/in_process_gpu_thread.h b/chromium/content/gpu/in_process_gpu_thread.h
index c8e96e88d47..12b24cad398 100644
--- a/chromium/content/gpu/in_process_gpu_thread.h
+++ b/chromium/content/gpu/in_process_gpu_thread.h
@@ -11,7 +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"
+#include "gpu/config/gpu_preferences.h"
namespace content {
diff --git a/chromium/content/ppapi_plugin/BUILD.gn b/chromium/content/ppapi_plugin/BUILD.gn
index b34b076bfbb..f356fcfa373 100644
--- a/chromium/content/ppapi_plugin/BUILD.gn
+++ b/chromium/content/ppapi_plugin/BUILD.gn
@@ -51,6 +51,7 @@ source_set("ppapi_plugin_sources") {
deps = [
"//base",
"//components/discardable_memory/client",
+ "//components/services/font/public/cpp:cpp",
"//content:export",
"//content/child",
"//content/public/child:child_sources",
diff --git a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc
index cdfffa0cab1..25ca97ea4b8 100644
--- a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc
+++ b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.cc
@@ -40,18 +40,25 @@ namespace content {
class PpapiBlinkPlatformImpl::SandboxSupport : public WebSandboxSupport {
public:
+#if defined(OS_LINUX)
+ explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader)
+ : font_loader_(std::move(font_loader)) {}
+#endif
~SandboxSupport() override {}
#if defined(OS_MACOSX)
bool LoadFont(CTFontRef srcFont, CGFontRef* out, uint32_t* fontID) override;
-#elif defined(OS_POSIX)
+#elif defined(OS_LINUX)
SandboxSupport();
void GetFallbackFontForCharacter(
WebUChar32 character,
const char* preferred_locale,
blink::WebFallbackFont* fallbackFont) override;
void GetWebFontRenderStyleForStrike(const char* family,
- int sizeAndStyle,
+ int size,
+ bool is_bold,
+ bool is_italic,
+ float device_scale_factor,
blink::WebFontRenderStyle* out) override;
private:
@@ -59,8 +66,9 @@ class PpapiBlinkPlatformImpl::SandboxSupport : public WebSandboxSupport {
// unicode code points. It needs this information frequently so we cache it
// here.
std::map<int32_t, blink::WebFallbackFont> unicode_font_families_;
- // For debugging crbug.com/312965
- base::PlatformThreadId creation_thread_;
+ sk_sp<font_service::FontLoader> font_loader_;
+ // For debugging https://crbug.com/312965
+ base::SequenceCheckerImpl creation_thread_sequence_checker_;
#endif
};
@@ -78,9 +86,7 @@ bool PpapiBlinkPlatformImpl::SandboxSupport::LoadFont(CTFontRef src_font,
#elif defined(OS_POSIX)
-PpapiBlinkPlatformImpl::SandboxSupport::SandboxSupport()
- : creation_thread_(base::PlatformThread::CurrentId()) {
-}
+PpapiBlinkPlatformImpl::SandboxSupport::SandboxSupport() {}
void PpapiBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter(
WebUChar32 character,
@@ -88,7 +94,7 @@ void PpapiBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter(
blink::WebFallbackFont* fallbackFont) {
ppapi::ProxyLock::AssertAcquired();
// For debugging crbug.com/312965
- CHECK_EQ(creation_thread_, base::PlatformThread::CurrentId());
+ CHECK(creation_thread_sequence_checker_.CalledOnValidSequence());
const std::map<int32_t, blink::WebFallbackFont>::const_iterator iter =
unicode_font_families_.find(character);
if (iter != unicode_font_families_.end()) {
@@ -102,16 +108,20 @@ void PpapiBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter(
return;
}
- content::GetFallbackFontForCharacter(character, preferred_locale,
- fallbackFont);
+ content::GetFallbackFontForCharacter(font_loader_, character,
+ preferred_locale, fallbackFont);
unicode_font_families_.insert(std::make_pair(character, *fallbackFont));
}
void PpapiBlinkPlatformImpl::SandboxSupport::GetWebFontRenderStyleForStrike(
const char* family,
- int sizeAndStyle,
+ int size,
+ bool is_bold,
+ bool is_italic,
+ float device_scale_factor,
blink::WebFontRenderStyle* out) {
- GetRenderStyleForStrike(family, sizeAndStyle, out);
+ GetRenderStyleForStrike(font_loader_, family, size, is_bold, is_italic,
+ device_scale_factor, out);
}
#endif
@@ -119,8 +129,14 @@ void PpapiBlinkPlatformImpl::SandboxSupport::GetWebFontRenderStyleForStrike(
#endif // !defined(OS_ANDROID) && !defined(OS_WIN)
PpapiBlinkPlatformImpl::PpapiBlinkPlatformImpl() {
-#if !defined(OS_ANDROID) && !defined(OS_WIN)
- sandbox_support_.reset(new PpapiBlinkPlatformImpl::SandboxSupport);
+#if defined(OS_LINUX)
+ font_loader_ =
+ sk_make_sp<font_service::FontLoader>(ChildThread::Get()->GetConnector());
+ SkFontConfigInterface::SetGlobal(font_loader_);
+ sandbox_support_.reset(
+ new PpapiBlinkPlatformImpl::SandboxSupport(font_loader_));
+#elif defined(OS_MACOSX)
+ sandbox_support_.reset(new PpapiBlinkPlatformImpl::SandboxSupport());
#endif
}
@@ -187,13 +203,6 @@ blink::WebThemeEngine* PpapiBlinkPlatformImpl::ThemeEngine() {
return nullptr;
}
-void PpapiBlinkPlatformImpl::GetPluginList(
- bool refresh,
- const blink::WebSecurityOrigin& mainFrameOrigin,
- blink::WebPluginListBuilder* builder) {
- NOTREACHED();
-}
-
blink::WebData PpapiBlinkPlatformImpl::GetDataResource(const char* name) {
NOTREACHED();
return blink::WebData();
diff --git a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h
index 5f245c7d85d..aea9579c6f8 100644
--- a/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h
+++ b/chromium/content/ppapi_plugin/ppapi_blink_platform_impl.h
@@ -13,6 +13,11 @@
#include "build/build_config.h"
#include "content/child/blink_platform_impl.h"
+#if defined(OS_LINUX)
+#include "components/services/font/public/cpp/font_loader.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
+#endif
+
namespace content {
class PpapiBlinkPlatformImpl : public BlinkPlatformImpl {
@@ -37,9 +42,6 @@ class PpapiBlinkPlatformImpl : public BlinkPlatformImpl {
const blink::WebURL& site_for_cookies);
blink::WebString DefaultLocale() override;
blink::WebThemeEngine* ThemeEngine() override;
- void GetPluginList(bool refresh,
- const blink::WebSecurityOrigin& mainFrameOrigin,
- blink::WebPluginListBuilder*) override;
blink::WebData GetDataResource(const char* name) override;
std::unique_ptr<blink::WebStorageNamespace> CreateLocalStorageNamespace()
override;
@@ -56,6 +58,10 @@ class PpapiBlinkPlatformImpl : public BlinkPlatformImpl {
std::unique_ptr<SandboxSupport> sandbox_support_;
#endif
+#if defined(OS_LINUX)
+ sk_sp<font_service::FontLoader> font_loader_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(PpapiBlinkPlatformImpl);
};
diff --git a/chromium/content/ppapi_plugin/ppapi_plugin_main.cc b/chromium/content/ppapi_plugin/ppapi_plugin_main.cc
index c2cf95a216a..0051d878b32 100644
--- a/chromium/content/ppapi_plugin/ppapi_plugin_main.cc
+++ b/chromium/content/ppapi_plugin/ppapi_plugin_main.cc
@@ -137,12 +137,6 @@ int PpapiPluginMain(const MainFunctionParams& parameters) {
gfx::win::MaybeInitializeDirectWrite();
InitializeDWriteFontProxy(ChildThread::Get()->GetConnector());
- double device_scale_factor = 1.0;
- base::StringToDouble(
- command_line.GetSwitchValueASCII(switches::kDeviceScaleFactor),
- &device_scale_factor);
- blink::WebFontRendering::SetDeviceScaleFactor(device_scale_factor);
-
int antialiasing_enabled = 1;
base::StringToInt(
command_line.GetSwitchValueASCII(switches::kPpapiAntialiasedTextEnabled),
diff --git a/chromium/content/ppapi_plugin/ppapi_thread.cc b/chromium/content/ppapi_plugin/ppapi_thread.cc
index bb0abafb6ea..82b1ebfdd54 100644
--- a/chromium/content/ppapi_plugin/ppapi_thread.cc
+++ b/chromium/content/ppapi_plugin/ppapi_thread.cc
@@ -63,6 +63,10 @@
#include "sandbox/win/src/sandbox.h"
#endif
+#if defined(OS_MACOSX)
+#include "sandbox/mac/seatbelt_exec.h"
+#endif
+
#if defined(OS_WIN)
extern sandbox::TargetServices* g_target_services;
@@ -115,7 +119,7 @@ PpapiThread::PpapiThread(const base::CommandLine& command_line, bool is_broker)
// allocator.
if (!command_line.HasSwitch(switches::kSingleProcess)) {
discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr;
- if (features::IsMashEnabled()) {
+ if (!features::IsAshInBrowserProcess()) {
#if defined(USE_AURA)
GetServiceManagerConnection()->GetConnector()->BindInterface(
ui::mojom::kServiceName, &manager_ptr);
@@ -200,6 +204,22 @@ base::SharedMemoryHandle PpapiThread::ShareSharedMemoryHandleWithRemote(
return base::SharedMemory::DuplicateHandle(handle);
}
+base::UnsafeSharedMemoryRegion
+PpapiThread::ShareUnsafeSharedMemoryRegionWithRemote(
+ const base::UnsafeSharedMemoryRegion& region,
+ base::ProcessId remote_pid) {
+ DCHECK(remote_pid != base::kNullProcessId);
+ return region.Duplicate();
+}
+
+base::ReadOnlySharedMemoryRegion
+PpapiThread::ShareReadOnlySharedMemoryRegionWithRemote(
+ const base::ReadOnlySharedMemoryRegion& region,
+ base::ProcessId remote_pid) {
+ DCHECK(remote_pid != base::kNullProcessId);
+ return region.Duplicate();
+}
+
std::set<PP_Instance>* PpapiThread::GetGloballySeenInstanceIDSet() {
return &globally_seen_instance_ids_;
}
@@ -410,7 +430,7 @@ void PpapiThread::OnLoadPlugin(const base::FilePath& path,
#if defined(OS_MACOSX)
// TODO(kerrnel): Delete this once the V2 sandbox is default.
const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
- if (!cmdline->HasSwitch(switches::kEnableV2Sandbox)) {
+ if (!cmdline->HasSwitch(sandbox::switches::kSeatbeltClientName)) {
// We need to do this after getting |PPP_GetInterface()| (or presumably
// doing something nontrivial with the library), else the sandbox
// intercedes.
diff --git a/chromium/content/ppapi_plugin/ppapi_thread.h b/chromium/content/ppapi_plugin/ppapi_thread.h
index f3425cbeaa8..b54f4702ab0 100644
--- a/chromium/content/ppapi_plugin/ppapi_thread.h
+++ b/chromium/content/ppapi_plugin/ppapi_thread.h
@@ -89,6 +89,12 @@ class PpapiThread : public ChildThreadImpl,
base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
const base::SharedMemoryHandle& handle,
base::ProcessId remote_pid) override;
+ base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+ const base::UnsafeSharedMemoryRegion& region,
+ base::ProcessId remote_pid) override;
+ base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+ const base::ReadOnlySharedMemoryRegion& region,
+ base::ProcessId remote_pid) override;
uint32_t Register(ppapi::proxy::PluginDispatcher* plugin_dispatcher) override;
void Unregister(uint32_t plugin_dispatcher_id) override;
diff --git a/chromium/content/public/android/BUILD.gn b/chromium/content/public/android/BUILD.gn
index dedbd8707e9..7c89dce2968 100644
--- a/chromium/content/public/android/BUILD.gn
+++ b/chromium/content/public/android/BUILD.gn
@@ -31,6 +31,24 @@ android_resources("content_java_resources") {
resource_dirs = [ "java/res" ]
}
+action("generate_sandboxed_service_srcjar") {
+ script = "//content/public/android/generate_child_service.py"
+ depfile = "$target_gen_dir/$target_name.d"
+
+ _srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
+ _rebased_srcjar_path = rebase_path(_srcjar_path, root_build_dir)
+
+ args = [
+ "--depfile",
+ rebase_path(depfile, root_build_dir),
+ "40",
+ _rebased_srcjar_path,
+ ]
+ outputs = [
+ _srcjar_path,
+ ]
+}
+
android_library("content_java") {
deps = [
":content_java_resources",
@@ -44,10 +62,10 @@ android_library("content_java") {
"//media/capture/video/android:capture_java",
"//media/midi:midi_java",
"//media/mojo/interfaces:interfaces_java",
- "//mojo/android:system_java",
"//mojo/public/java:base_java",
"//mojo/public/java:bindings_java",
"//mojo/public/java:system_java",
+ "//mojo/public/java/system:system_impl_java",
"//net/android:net_java",
"//services/device:java",
"//services/device/public/java:nfc_java",
@@ -59,6 +77,7 @@ android_library("content_java") {
"//third_party/blink/public:android_mojo_bindings_java",
"//third_party/blink/public:blink_headers_java",
"//third_party/blink/public/mojom:mojom_core_java",
+ "//third_party/blink/public/mojom:speech_recognition_error_code_java",
"//third_party/jsr-305:jsr_305_javalib",
"//ui/android:ui_java",
"//ui/gfx/geometry/mojo:mojo_java",
@@ -66,6 +85,7 @@ android_library("content_java") {
srcjar_deps = [
":common_aidl",
+ ":generate_sandboxed_service_srcjar",
":is_ready_to_pay_service_aidl",
":content_public_android_java_enums_srcjar",
"//content/browser/accessibility:content_browser_accessibility_java_enums_srcjar",
@@ -84,43 +104,20 @@ android_library("content_java") {
"java/src/org/chromium/content/app/PrivilegedProcessService1.java",
"java/src/org/chromium/content/app/PrivilegedProcessService2.java",
"java/src/org/chromium/content/app/SandboxedProcessService.java",
- "java/src/org/chromium/content/app/SandboxedProcessService0.java",
- "java/src/org/chromium/content/app/SandboxedProcessService1.java",
- "java/src/org/chromium/content/app/SandboxedProcessService10.java",
- "java/src/org/chromium/content/app/SandboxedProcessService11.java",
- "java/src/org/chromium/content/app/SandboxedProcessService12.java",
- "java/src/org/chromium/content/app/SandboxedProcessService13.java",
- "java/src/org/chromium/content/app/SandboxedProcessService14.java",
- "java/src/org/chromium/content/app/SandboxedProcessService15.java",
- "java/src/org/chromium/content/app/SandboxedProcessService16.java",
- "java/src/org/chromium/content/app/SandboxedProcessService17.java",
- "java/src/org/chromium/content/app/SandboxedProcessService18.java",
- "java/src/org/chromium/content/app/SandboxedProcessService19.java",
- "java/src/org/chromium/content/app/SandboxedProcessService2.java",
- "java/src/org/chromium/content/app/SandboxedProcessService3.java",
- "java/src/org/chromium/content/app/SandboxedProcessService4.java",
- "java/src/org/chromium/content/app/SandboxedProcessService5.java",
- "java/src/org/chromium/content/app/SandboxedProcessService6.java",
- "java/src/org/chromium/content/app/SandboxedProcessService7.java",
- "java/src/org/chromium/content/app/SandboxedProcessService8.java",
- "java/src/org/chromium/content/app/SandboxedProcessService9.java",
+ "java/src/org/chromium/content/browser/ApiHelperForM.java",
"java/src/org/chromium/content/browser/AppWebMessagePort.java",
- "java/src/org/chromium/content/browser/ActivityContentVideoViewEmbedder.java",
"java/src/org/chromium/content/browser/AudioFocusDelegate.java",
"java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java",
"java/src/org/chromium/content/browser/BindingManager.java",
- "java/src/org/chromium/content/browser/BrowserStartupController.java",
- "java/src/org/chromium/content/browser/ChildProcessCreationParams.java",
- "java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java",
+ "java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java",
+ "java/src/org/chromium/content/browser/ChildProcessCreationParamsImpl.java",
+ "java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java",
"java/src/org/chromium/content/browser/ChildProcessRanking.java",
"java/src/org/chromium/content/browser/ContentChildProcessConstants.java",
"java/src/org/chromium/content/browser/ContentClassFactory.java",
"java/src/org/chromium/content/browser/ContentFeatureList.java",
"java/src/org/chromium/content/browser/ContentNfcDelegate.java",
"java/src/org/chromium/content/browser/ContentUiEventHandler.java",
- "java/src/org/chromium/content/browser/ContentVideoViewImpl.java",
- "java/src/org/chromium/content/browser/ContentViewCoreImpl.java",
- "java/src/org/chromium/content/browser/ContentViewRenderView.java",
"java/src/org/chromium/content/browser/ContentViewStaticsImpl.java",
"java/src/org/chromium/content/browser/DeviceUtilsImpl.java",
"java/src/org/chromium/content/browser/Gamepad.java",
@@ -135,16 +132,16 @@ android_library("content_java") {
"java/src/org/chromium/content/browser/MemoryMonitorAndroid.java",
"java/src/org/chromium/content/browser/MotionEventSynthesizerImpl.java",
"java/src/org/chromium/content/browser/NfcHost.java",
- "java/src/org/chromium/content/browser/PepperPluginManager.java",
"java/src/org/chromium/content/browser/PopupController.java",
"java/src/org/chromium/content/browser/PopupZoomer.java",
"java/src/org/chromium/content/browser/RenderCoordinatesImpl.java",
- "java/src/org/chromium/content/browser/ScreenOrientationProvider.java",
+ "java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java",
"java/src/org/chromium/content/browser/SpareChildConnection.java",
"java/src/org/chromium/content/browser/SpeechRecognitionImpl.java",
"java/src/org/chromium/content/browser/SyntheticGestureTarget.java",
"java/src/org/chromium/content/browser/TapDisambiguator.java",
"java/src/org/chromium/content/browser/TracingControllerAndroid.java",
+ "java/src/org/chromium/content/browser/ViewEventSinkImpl.java",
"java/src/org/chromium/content/browser/WindowEventObserver.java",
"java/src/org/chromium/content/browser/WindowEventObserverManager.java",
"java/src/org/chromium/content/browser/accessibility/KitKatWebContentsAccessibility.java",
@@ -202,13 +199,18 @@ android_library("content_java") {
"java/src/org/chromium/content/browser/picker/WeekPicker.java",
"java/src/org/chromium/content/browser/picker/WeekPickerDialog.java",
"java/src/org/chromium/content/browser/remoteobjects/RemoteObjectAuditorImpl.java",
+ "java/src/org/chromium/content/browser/remoteobjects/RemoteObjectHostImpl.java",
"java/src/org/chromium/content/browser/remoteobjects/RemoteObjectImpl.java",
+ "java/src/org/chromium/content/browser/remoteobjects/RemoteObjectRegistry.java",
"java/src/org/chromium/content/browser/selection/AdditionalMenuItemProvider.java",
+ "java/src/org/chromium/content/browser/selection/AdditionalMenuItemProviderImpl.java",
"java/src/org/chromium/content/browser/selection/FloatingActionModeCallback.java",
"java/src/org/chromium/content/browser/selection/FloatingPastePopupMenu.java",
- "java/src/org/chromium/content/browser/selection/HandleViewResources.java",
"java/src/org/chromium/content/browser/selection/LGEmailActionModeWorkaroundImpl.java",
"java/src/org/chromium/content/browser/selection/LegacyPastePopupMenu.java",
+ "java/src/org/chromium/content/browser/selection/MagnifierAnimator.java",
+ "java/src/org/chromium/content/browser/selection/MagnifierWrapper.java",
+ "java/src/org/chromium/content/browser/selection/MagnifierWrapperImpl.java",
"java/src/org/chromium/content/browser/selection/PastePopupMenu.java",
"java/src/org/chromium/content/browser/selection/SelectionEventProxyImpl.java",
"java/src/org/chromium/content/browser/selection/SelectionIndicesConverter.java",
@@ -226,13 +228,12 @@ android_library("content_java") {
"java/src/org/chromium/content_public/browser/AccessibilitySnapshotCallback.java",
"java/src/org/chromium/content_public/browser/AccessibilitySnapshotNode.java",
"java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java",
- "java/src/org/chromium/content_public/browser/ChildProcessUtils.java",
+ "java/src/org/chromium/content_public/browser/BrowserStartupController.java",
"java/src/org/chromium/content_public/browser/ContentViewStatics.java",
"java/src/org/chromium/content_public/browser/DeviceUtils.java",
"java/src/org/chromium/content_public/browser/InputMethodManagerWrapper.java",
- "java/src/org/chromium/content_public/browser/ContentVideoView.java",
- "java/src/org/chromium/content_public/browser/ContentVideoViewEmbedder.java",
- "java/src/org/chromium/content_public/browser/ContentViewCore.java",
+ "java/src/org/chromium/content_public/browser/ChildProcessCreationParams.java",
+ "java/src/org/chromium/content_public/browser/ChildProcessLauncherHelper.java",
"java/src/org/chromium/content_public/browser/GestureListenerManager.java",
"java/src/org/chromium/content_public/browser/GestureStateListener.java",
"java/src/org/chromium/content_public/browser/ImageDownloadCallback.java",
@@ -252,13 +253,14 @@ android_library("content_java") {
"java/src/org/chromium/content_public/browser/NavigationHistory.java",
"java/src/org/chromium/content_public/browser/RenderFrameHost.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/ScreenOrientationProvider.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/SelectionPopupController.java",
"java/src/org/chromium/content_public/browser/SmartClipProvider.java",
"java/src/org/chromium/content_public/browser/SpeechRecognition.java",
"java/src/org/chromium/content_public/browser/RenderCoordinates.java",
+ "java/src/org/chromium/content_public/browser/ViewEventSink.java",
"java/src/org/chromium/content_public/browser/WebContents.java",
"java/src/org/chromium/content_public/browser/WebContentsAccessibility.java",
"java/src/org/chromium/content_public/browser/WebContentsInternals.java",
@@ -336,7 +338,6 @@ java_cpp_enum("content_public_android_java_enums_srcjar") {
"//content/public/common/browser_controls_state.h",
"//content/public/common/console_message_level.h",
"//content/public/common/screen_orientation_values.h",
- "//content/public/common/speech_recognition_error.h",
]
}
@@ -356,14 +357,11 @@ generate_jni("content_jni_headers") {
"java/src/org/chromium/content/browser/AppWebMessagePort.java",
"java/src/org/chromium/content/browser/AudioFocusDelegate.java",
"java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java",
- "java/src/org/chromium/content/browser/BrowserStartupController.java",
- "java/src/org/chromium/content/browser/ChildProcessLauncherHelper.java",
+ "java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java",
+ "java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java",
"java/src/org/chromium/content/browser/ContentFeatureList.java",
"java/src/org/chromium/content/browser/ContentNfcDelegate.java",
"java/src/org/chromium/content/browser/ContentUiEventHandler.java",
- "java/src/org/chromium/content/browser/ContentVideoViewImpl.java",
- "java/src/org/chromium/content/browser/ContentViewCoreImpl.java",
- "java/src/org/chromium/content/browser/ContentViewRenderView.java",
"java/src/org/chromium/content/browser/ContentViewStaticsImpl.java",
"java/src/org/chromium/content/browser/GestureListenerManagerImpl.java",
"java/src/org/chromium/content/browser/GpuProcessCallback.java",
@@ -373,7 +371,7 @@ generate_jni("content_jni_headers") {
"java/src/org/chromium/content/browser/MediaSessionImpl.java",
"java/src/org/chromium/content/browser/MemoryMonitorAndroid.java",
"java/src/org/chromium/content/browser/NfcHost.java",
- "java/src/org/chromium/content/browser/ScreenOrientationProvider.java",
+ "java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java",
"java/src/org/chromium/content/browser/SpeechRecognitionImpl.java",
"java/src/org/chromium/content/browser/SyntheticGestureTarget.java",
"java/src/org/chromium/content/browser/TapDisambiguator.java",
@@ -389,7 +387,6 @@ generate_jni("content_jni_headers") {
"java/src/org/chromium/content/browser/input/SelectPopup.java",
"java/src/org/chromium/content/browser/input/SuggestionInfo.java",
"java/src/org/chromium/content/browser/input/TextSuggestionHost.java",
- "java/src/org/chromium/content/browser/selection/HandleViewResources.java",
"java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java",
"java/src/org/chromium/content/browser/selection/SmartSelectionClient.java",
"java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java",
@@ -426,19 +423,20 @@ android_library("content_javatests") {
"//content/shell/android:content_shell_apk_java",
"//content/shell/android:content_shell_java",
"//content/shell/android:content_shell_test_java",
- "//device/geolocation:geolocation_java",
- "//device/geolocation:geolocation_java_test_support",
"//media/base/android:media_java",
"//media/capture/content/android:screen_capture_java",
"//media/capture/video/android:capture_java",
"//media/mojo/interfaces:interfaces_java",
- "//mojo/android:system_java",
"//mojo/public/interfaces/bindings/tests:test_interfaces_java",
"//mojo/public/java:bindings_java",
"//mojo/public/java:system_java",
+ "//mojo/public/java/system:system_impl_java",
+ "//mojo/public/java/system:test_support_java",
"//mojo/public/mojom/base:base_java",
"//net/android:net_java",
"//net/android:net_java_test_support",
+ "//services/device/public/java:geolocation_java",
+ "//services/device/public/java:geolocation_java_test_support",
"//services/service_manager/public/java:service_manager_java",
"//services/test/echo/public/mojom:mojom_java",
"//third_party/android_support_test_runner:rules_java",
@@ -504,6 +502,7 @@ android_library("content_javatests") {
"javatests/src/org/chromium/content/browser/input/SelectPopupTest.java",
"javatests/src/org/chromium/content/browser/input/TextSuggestionMenuTest.java",
"javatests/src/org/chromium/content/browser/picker/DateTimePickerDialogTest.java",
+ "javatests/src/org/chromium/content/browser/remoteobjects/RemoteObjectHostImplTest.java",
"javatests/src/org/chromium/content/browser/webcontents/AccessibilitySnapshotTest.java",
"javatests/src/org/chromium/content/browser/webcontents/WebContentsTest.java",
"javatests/src/org/chromium/content/common/ServiceManagerConnectionImplTest.java",
@@ -530,6 +529,8 @@ junit_binary("content_junit_tests") {
"junit/src/org/chromium/content/browser/input/ThreadedInputConnectionTest.java",
"junit/src/org/chromium/content/browser/picker/DateDialogNormalizerTest.java",
"junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectImplTest.java",
+ "junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectRegistryTest.java",
+ "junit/src/org/chromium/content/browser/selection/MagnifierAnimatorTest.java",
"junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java",
"junit/src/org/chromium/content/browser/selection/SmartSelectionMetricsLoggerTest.java",
]
diff --git a/chromium/content/public/android/DEPS b/chromium/content/public/android/DEPS
index e14a66ac666..bc863f385c5 100644
--- a/chromium/content/public/android/DEPS
+++ b/chromium/content/public/android/DEPS
@@ -7,8 +7,6 @@ include_rules = [
"+content/shell/android",
# Needed for device APIs implemented as Mojo services in Java.
"+device",
- # Mojo is needed for Mojo service registry kept in the browser.
- "+mojo/android",
# Needed for implementing Device Service public component in java.
"+services/device/public/java",
]
diff --git a/chromium/content/public/android/generate_child_service.py b/chromium/content/public/android/generate_child_service.py
new file mode 100755
index 00000000000..f29047b6ef1
--- /dev/null
+++ b/chromium/content/public/android/generate_child_service.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+#
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import optparse
+import os
+import sys
+import zipfile
+
+SRC_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
+ '..', '..', '..'))
+sys.path.append(os.path.join(SRC_DIR, 'build', 'android', 'gyp'))
+
+from util import build_utils
+
+def GenerateService(i):
+ template = """// THIS FILE IS GENERATED BY generate_child_service.py
+
+package org.chromium.content.app;
+
+/**
+ * This is needed to register multiple SandboxedProcess services so that we
+ * can have more than one sandboxed process.
+ */
+public class SandboxedProcessService{0} extends SandboxedProcessService {{
+}}"""
+ return template.format(str(i))
+
+
+def DoMain(argv):
+ usage = 'usage: %prog [number] [output]'
+ parser = optparse.OptionParser(usage=usage)
+ build_utils.AddDepfileOption(parser)
+
+ options, args = parser.parse_args(argv)
+
+ if len(args) != 2:
+ parser.error('Need to specify number and output_dir')
+ number, output = args
+ number = int(number)
+
+ path_template = "org/chromium/content/app/SandboxedProcessService{0}.java"
+ with build_utils.AtomicOutput(output) as f:
+ with zipfile.ZipFile(f, 'w', zipfile.ZIP_STORED) as srcjar:
+ for i in xrange(number):
+ build_utils.AddToZipHermetic(srcjar,
+ path_template.format(i),
+ data=GenerateService(i))
+
+ if options.depfile:
+ build_utils.WriteDepfile(options.depfile, output)
+
+if __name__ == '__main__':
+ DoMain(sys.argv[1:])
diff --git a/chromium/content/public/app/BUILD.gn b/chromium/content/public/app/BUILD.gn
index 004f301cbd7..4bf09585be2 100644
--- a/chromium/content/public/app/BUILD.gn
+++ b/chromium/content/public/app/BUILD.gn
@@ -198,15 +198,18 @@ service_manifest("packaged_services_manifest") {
"//services/viz:manifest",
]
- if (enable_mus) {
- packaged_services += [ "//services/ui:manifest" ]
+ if (is_linux) {
+ packaged_services += [ "//components/services/font:manifest" ]
}
}
service_manifest("browser_manifest") {
name = "content_browser"
source = "mojo/content_browser_manifest.json"
- packaged_services = [ "//services/file:manifest" ]
+ packaged_services = [
+ "//services/content:manifest",
+ "//services/file:manifest",
+ ]
}
service_manifest("gpu_manifest") {
diff --git a/chromium/content/public/app/content_main_delegate.h b/chromium/content/public/app/content_main_delegate.h
index b5d8b1889d6..979e25d1c1b 100644
--- a/chromium/content/public/app/content_main_delegate.h
+++ b/chromium/content/public/app/content_main_delegate.h
@@ -125,6 +125,11 @@ class CONTENT_EXPORT ContentMainDelegate {
const base::Closure& quit_closure,
service_manager::BackgroundServiceManager* service_manager);
+ // Allows the embedder to perform platform-specific initializatioion. For
+ // example, things that should be done immediately before the creation of the
+ // main message loop.
+ virtual void PreContentInitialization() {}
+
protected:
friend class ContentClientInitializer;
diff --git a/chromium/content/public/app/content_main_runner.h b/chromium/content/public/app/content_main_runner.h
index 5fec99790b5..308c22d8041 100644
--- a/chromium/content/public/app/content_main_runner.h
+++ b/chromium/content/public/app/content_main_runner.h
@@ -23,7 +23,7 @@ class CONTENT_EXPORT ContentMainRunner {
virtual int Initialize(const ContentMainParams& params) = 0;
// Perform the default run logic.
- virtual int Run() = 0;
+ virtual int Run(bool start_service_manager_only) = 0;
// Shut down the content state.
virtual void Shutdown() = 0;
diff --git a/chromium/content/public/app/mojo/content_browser_manifest.json b/chromium/content/public/app/mojo/content_browser_manifest.json
index a515b68616a..96f8e822a91 100644
--- a/chromium/content/public/app/mojo/content_browser_manifest.json
+++ b/chromium/content/public/app/mojo/content_browser_manifest.json
@@ -6,6 +6,7 @@
"provides": {
// Interfaces needed by a generic client of content browser.
"app": [
+ "content.mojom.MemoryCoordinatorHandle",
"discardable_memory.mojom.DiscardableSharedMemoryManager",
"memory_instrumentation.mojom.Coordinator"
],
@@ -25,6 +26,9 @@
"discardable_memory.mojom.DiscardableSharedMemoryManager",
"media.mojom.AndroidOverlayProvider"
],
+ "gpu_client": [
+ "ui.mojom.Gpu"
+ ],
"plugin": [
"discardable_memory.mojom.DiscardableSharedMemoryManager",
"ui.mojom.Gpu"
@@ -39,24 +43,23 @@
"blink.mojom.LockManager",
"blink.mojom.Hyphenation",
"blink.mojom.MimeRegistry",
+ "blink.mojom.PluginRegistry",
"blink.mojom.ReportingServiceProxy",
+ "blink.mojom.StoragePartitionService",
"blink.mojom.WebDatabaseHost",
"content.mojom.AppCacheBackend",
"content.mojom.ClipboardHost",
"content.mojom.FieldTrialRecorder",
"content.mojom.FrameSinkProvider",
"content.mojom.MediaStreamTrackMetricsHost",
- "content.mojom.MemoryCoordinatorHandle",
"content.mojom.PeerConnectionTrackerHost",
"content.mojom.PushMessaging",
"content.mojom.RendererHost",
"content.mojom.ReportingServiceProxy",
"content.mojom.ServiceWorkerDispatcherHost",
- "content.mojom.StoragePartitionService",
"content.mojom.WorkerURLLoaderFactoryProvider",
"device.mojom.BatteryMonitor",
"device.mojom.GamepadHapticsManager",
- "device.mojom.GamepadMonitor",
"discardable_memory.mojom.DiscardableSharedMemoryManager",
"media.mojom.KeySystemSupport",
"media.mojom.VideoCaptureHost",
@@ -78,9 +81,13 @@
"info",
"debug_recording",
"device_notifier",
- "stream_factory"
+ "log_factory_manager",
+ "stream_factory",
+ "testing_api"
],
"cdm": [ "media:cdm" ],
+ "chromecast": [ "multizone" ],
+ "content": [ "navigation" ],
"content_gpu": [ "browser" ],
"content_plugin": [ "browser" ],
"content_renderer": [ "browser" ],
@@ -140,10 +147,14 @@
// impossible this week. Remove once sky/ken fix this.
"autofill.mojom.AutofillDriver",
"autofill.mojom.PasswordManagerDriver",
+ "blink.mojom.AnchorElementMetricsHost",
+ "blink.mojom.Authenticator",
"blink.mojom.BackgroundFetchService",
"blink.mojom.BudgetService",
"blink.mojom.CacheStorage",
"blink.mojom.ColorChooserFactory",
+ "blink.mojom.CredentialManager",
+ "blink.mojom.DisplayCutoutHost",
"blink.mojom.DedicatedWorkerFactory",
"blink.mojom.LockManager",
"blink.mojom.GeolocationService",
@@ -156,9 +167,12 @@
"blink.mojom.PrefetchURLLoaderService",
"blink.mojom.PresentationService",
"blink.mojom.QuotaDispatcherHost",
+ "blink.mojom.SpeechRecognizer",
"blink.mojom.TextSuggestionHost",
"blink.mojom.UnhandledTapNotifier",
"blink.mojom.WebBluetoothService",
+ "blink.test.mojom.VirtualAuthenticatorManager",
+
// TODO(beng): figure out how to overlay test interfaces like this.
"content.mojom.BrowserTarget",
@@ -170,7 +184,7 @@
"content.mojom.RendererAudioInputStreamFactory",
"content.mojom.RendererAudioOutputStreamFactory",
"content.mojom.SharedWorkerConnector",
- "content.mojom.SpeechRecognizer",
+ "device.mojom.GamepadMonitor",
"device.mojom.Geolocation",
"device.mojom.NFC",
"device.mojom.SensorProvider",
@@ -190,16 +204,13 @@
"mojom.ProcessInternalsHandler",
"network.mojom.RestrictedCookieManager",
"network.mojom.WebSocket",
- "password_manager.mojom.CredentialManager",
"payments.mojom.PaymentManager",
"payments.mojom.PaymentRequest",
"resource_coordinator.mojom.FrameCoordinationUnit",
- "shape_detection.mojom.BarcodeDetection",
+ "shape_detection.mojom.BarcodeDetectionProvider",
"shape_detection.mojom.FaceDetectionProvider",
"shape_detection.mojom.TextDetection",
- "ui.mojom.Gpu",
- "webauth.mojom.Authenticator",
- "webauth.test.mojom.VirtualAuthenticatorManager"
+ "ui.mojom.Gpu"
]
},
"requires": {
@@ -211,6 +222,7 @@
"renderer": [
"blink.mojom.BudgetService",
"blink.mojom.CacheStorage",
+ "blink.mojom.DedicatedWorkerFactory",
"blink.mojom.LockManager",
"blink.mojom.NotificationService",
"blink.mojom.PermissionService",
@@ -218,7 +230,7 @@
"device.mojom.UsbDeviceManager",
"network.mojom.WebSocket",
"payments.mojom.PaymentManager",
- "shape_detection.mojom.BarcodeDetection",
+ "shape_detection.mojom.BarcodeDetectionProvider",
"shape_detection.mojom.FaceDetectionProvider",
"shape_detection.mojom.TextDetection"
]
@@ -238,7 +250,7 @@
"network.mojom.RestrictedCookieManager",
"network.mojom.WebSocket",
"payments.mojom.PaymentManager",
- "shape_detection.mojom.BarcodeDetection",
+ "shape_detection.mojom.BarcodeDetectionProvider",
"shape_detection.mojom.FaceDetectionProvider",
"shape_detection.mojom.TextDetection"
]
@@ -255,7 +267,7 @@
"blink.mojom.QuotaDispatcherHost",
"network.mojom.WebSocket",
"payments.mojom.PaymentManager",
- "shape_detection.mojom.BarcodeDetection",
+ "shape_detection.mojom.BarcodeDetectionProvider",
"shape_detection.mojom.FaceDetectionProvider",
"shape_detection.mojom.TextDetection"
]
diff --git a/chromium/content/public/app/mojo/content_plugin_manifest.json b/chromium/content/public/app/mojo/content_plugin_manifest.json
index 44c6d2bafa5..c00ea402962 100644
--- a/chromium/content/public/app/mojo/content_plugin_manifest.json
+++ b/chromium/content/public/app/mojo/content_plugin_manifest.json
@@ -25,6 +25,7 @@
"plugin"
],
"device": [ "device:power_monitor" ],
+ "font_service": [ "font_service" ],
"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 71bc81d6183..70c678203f2 100644
--- a/chromium/content/public/app/mojo/content_renderer_manifest.json
+++ b/chromium/content/public/app/mojo/content_renderer_manifest.json
@@ -33,6 +33,7 @@
"font_loader",
"renderer"
],
+ "font_service": [ "font_service" ],
"metrics": [ "url_keyed_metrics" ],
"device": [
"device:power_monitor",
diff --git a/chromium/content/public/app/mojo/content_utility_manifest.json b/chromium/content/public/app/mojo/content_utility_manifest.json
index 563c88580bd..2c4dcb1a8cb 100644
--- a/chromium/content/public/app/mojo/content_utility_manifest.json
+++ b/chromium/content/public/app/mojo/content_utility_manifest.json
@@ -29,7 +29,8 @@
"device": [
"device:power_monitor",
"device:time_zone_monitor"
- ]
+ ],
+ "font_service": [ "font_service" ]
}
}
},
diff --git a/chromium/content/public/browser/BUILD.gn b/chromium/content/public/browser/BUILD.gn
index 93b61314c26..cb9b7ba284b 100644
--- a/chromium/content/public/browser/BUILD.gn
+++ b/chromium/content/public/browser/BUILD.gn
@@ -29,7 +29,6 @@ jumbo_source_set("browser_sources") {
"android/compositor.h",
"android/compositor_client.h",
"android/content_protocol_handler.h",
- "android/content_view_layer_renderer.h",
"android/devtools_auth.h",
"android/java_interfaces.h",
"android/motion_event_action.h",
@@ -39,6 +38,8 @@ jumbo_source_set("browser_sources") {
"appcache_service.h",
"audio_service_info.cc",
"audio_service_info.h",
+ "authenticator_request_client_delegate.cc",
+ "authenticator_request_client_delegate.h",
"ax_event_notification_details.cc",
"ax_event_notification_details.h",
"background_fetch_delegate.cc",
@@ -101,6 +102,7 @@ jumbo_source_set("browser_sources") {
"desktop_media_id.cc",
"desktop_media_id.h",
"devtools_agent_host.h",
+ "devtools_agent_host_client.cc",
"devtools_agent_host_client.h",
"devtools_agent_host_observer.cc",
"devtools_agent_host_observer.h",
@@ -119,6 +121,7 @@ jumbo_source_set("browser_sources") {
"download_manager_delegate.cc",
"download_manager_delegate.h",
"download_request_utils.h",
+ "download_utils.h",
"favicon_status.cc",
"favicon_status.h",
"file_url_loader.h",
@@ -152,9 +155,7 @@ jumbo_source_set("browser_sources") {
"local_storage_usage_info.h",
"login_delegate.h",
"manifest_icon_downloader.h",
- "manifest_icon_selector.h",
"media_capture_devices.h",
- "media_controller.h",
"media_device_id.cc",
"media_device_id.h",
"media_request_state.h",
@@ -178,6 +179,8 @@ jumbo_source_set("browser_sources") {
"navigation_throttle.h",
"navigation_type.h",
"navigation_ui_data.h",
+ "network_connection_tracker.cc",
+ "network_connection_tracker.h",
"network_quality_observer_factory.h",
"network_service_instance.h",
"notification_database_data.cc",
@@ -197,7 +200,8 @@ jumbo_source_set("browser_sources") {
"payment_app_provider.h",
"pepper_flash_settings_helper.h",
"pepper_vpn_provider_resource_host_proxy.h",
- "permission_manager.h",
+ "permission_controller.h",
+ "permission_controller_delegate.h",
"permission_type.h",
"picture_in_picture_window_controller.h",
"platform_notification_context.h",
@@ -264,6 +268,7 @@ jumbo_source_set("browser_sources") {
"ssl_host_state_delegate.h",
"ssl_status.cc",
"ssl_status.h",
+ "startup_data.h",
"storage_partition.h",
"stored_payment_app.cc",
"stored_payment_app.h",
@@ -279,6 +284,7 @@ jumbo_source_set("browser_sources") {
"url_data_source.cc",
"url_data_source.h",
"url_loader_request_interceptor.h",
+ "video_capture_device_launcher.cc",
"video_capture_device_launcher.h",
"visibility.h",
"vpn_service_proxy.h",
@@ -342,13 +348,13 @@ jumbo_source_set("browser_sources") {
deps = [
"//cc",
"//content/browser", # Must not be public_deps!
- "//device/geolocation",
"//gpu",
"//gpu/command_buffer/service:gles2",
"//media",
"//media/capture",
"//net",
"//ppapi/c",
+ "//services/device/public/cpp/geolocation",
"//services/service_manager/embedder:embedder_result_codes",
"//ui/accessibility",
"//ui/base",
diff --git a/chromium/content/public/browser/DEPS b/chromium/content/public/browser/DEPS
index 782fb0e3ad4..3b73764c818 100644
--- a/chromium/content/public/browser/DEPS
+++ b/chromium/content/public/browser/DEPS
@@ -3,9 +3,8 @@ include_rules = [
# TODO(qinmin): move it to services/download when download becomes a service.
"+components/download/public/common",
"+components/viz/common",
- "+device/geolocation/public/cpp",
"+device/usb/public/mojom",
- "+services/device/public/mojom",
+ "+services/device/public",
"+services/network/public/cpp",
"+services/service_manager/sandbox",
"+services/resource_coordinator/public",
@@ -27,4 +26,8 @@ specific_include_rules = {
# content/browser and chrome/browser.
"+third_party/webrtc/modules/desktop_capture/desktop_capture_options.h",
],
+
+ ".*unittest\.cc": [
+ "+services/network/network_service.h",
+ ],
}
diff --git a/chromium/content/public/browser/android/content_view_layer_renderer.h b/chromium/content/public/browser/android/content_view_layer_renderer.h
deleted file mode 100644
index 09bf2f6f32d..00000000000
--- a/chromium/content/public/browser/android/content_view_layer_renderer.h
+++ /dev/null
@@ -1,27 +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_ANDROID_CONTENT_VIEW_LAYER_RENDERER_H_
-#define CONTENT_PUBLIC_BROWSER_ANDROID_CONTENT_VIEW_LAYER_RENDERER_H_
-
-namespace cc {
-class Layer;
-}
-
-namespace content {
-
-// This interface is used by consumers of the ContentViewRenderView to
-// attach/detach layers.
-class ContentViewLayerRenderer {
- public:
- virtual void AttachLayer(cc::Layer* layer) = 0;
- virtual void DetachLayer(cc::Layer* layer) = 0;
-
- protected:
- virtual ~ContentViewLayerRenderer() {}
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_BROWSER_ANDROID_CONTENT_VIEW_LAYER_RENDERER_H_
diff --git a/chromium/content/public/browser/authenticator_request_client_delegate.cc b/chromium/content/public/browser/authenticator_request_client_delegate.cc
new file mode 100644
index 00000000000..2f06e057efa
--- /dev/null
+++ b/chromium/content/public/browser/authenticator_request_client_delegate.cc
@@ -0,0 +1,41 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/authenticator_request_client_delegate.h"
+
+#include "base/callback.h"
+#include "base/strings/string_piece.h"
+
+namespace content {
+
+AuthenticatorRequestClientDelegate::AuthenticatorRequestClientDelegate() =
+ default;
+AuthenticatorRequestClientDelegate::~AuthenticatorRequestClientDelegate() =
+ default;
+
+void AuthenticatorRequestClientDelegate::DidStartRequest() {}
+
+bool AuthenticatorRequestClientDelegate::ShouldPermitIndividualAttestation(
+ const std::string& relying_party_id) {
+ return false;
+}
+
+void AuthenticatorRequestClientDelegate::ShouldReturnAttestation(
+ const std::string& relying_party_id,
+ base::OnceCallback<void(bool)> callback) {
+ std::move(callback).Run(true);
+}
+
+bool AuthenticatorRequestClientDelegate::IsFocused() {
+ return true;
+}
+
+#if defined(OS_MACOSX)
+base::Optional<AuthenticatorRequestClientDelegate::TouchIdAuthenticatorConfig>
+AuthenticatorRequestClientDelegate::GetTouchIdAuthenticatorConfig() const {
+ return base::nullopt;
+}
+#endif
+
+} // namespace content
diff --git a/chromium/content/public/browser/authenticator_request_client_delegate.h b/chromium/content/public/browser/authenticator_request_client_delegate.h
new file mode 100644
index 00000000000..55b41750a5d
--- /dev/null
+++ b/chromium/content/public/browser/authenticator_request_client_delegate.h
@@ -0,0 +1,85 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_AUTHENTICATOR_REQUEST_CLIENT_DELEGATE_H_
+#define CONTENT_PUBLIC_BROWSER_AUTHENTICATOR_REQUEST_CLIENT_DELEGATE_H_
+
+#include <string>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "base/optional.h"
+#include "build/build_config.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// Interface that the embedder should implement to provide the //content layer
+// with embedder-specific configuration for a single Web Authentication API [1]
+// request serviced in a given RenderFrame.
+//
+// [1]: See https://www.w3.org/TR/webauthn/.
+class CONTENT_EXPORT AuthenticatorRequestClientDelegate {
+ public:
+ AuthenticatorRequestClientDelegate();
+ virtual ~AuthenticatorRequestClientDelegate();
+
+ // Notifies the delegate that the request is actually starting.
+ virtual void DidStartRequest();
+
+ // Returns true if the given relying party ID is permitted to receive
+ // individual attestation certificates. This:
+ // a) triggers a signal to the security key that returning individual
+ // attestation certificates is permitted, and
+ // b) skips any permission prompt for attestation.
+ virtual bool ShouldPermitIndividualAttestation(
+ const std::string& relying_party_id);
+
+ // Invokes |callback| with |true| if the given relying party ID is permitted
+ // to receive attestation certificates from a device. Otherwise invokes
+ // |callback| with |false|.
+ //
+ // Since these certificates may uniquely identify the authenticator, the
+ // embedder may choose to show a permissions prompt to the user, and only
+ // invoke |callback| afterwards. This may hairpin |callback|.
+ virtual void ShouldReturnAttestation(const std::string& relying_party_id,
+ base::OnceCallback<void(bool)> callback);
+
+ // Returns whether the WebContents corresponding to |render_frame_host| is the
+ // active tab in the focused window. We do not want to allow
+ // authenticatorMakeCredential operations to be triggered by background tabs.
+ //
+ // Note that the default implementation of this function, and the
+ // implementation in ChromeContentBrowserClient for Android, return |true| so
+ // that testing is possible.
+ virtual bool IsFocused();
+
+#if defined(OS_MACOSX)
+ struct TouchIdAuthenticatorConfig {
+ // The keychain-access-group value used for WebAuthn credentials
+ // stored in the macOS keychain by the built-in Touch ID
+ // authenticator. For more information on this, refer to
+ // |device::fido::TouchIdAuthenticator|.
+ std::string keychain_access_group;
+ // The secret used to derive key material when encrypting WebAuthn
+ // credential metadata for storage in the macOS keychain. Chrome returns
+ // different secrets for each user profile in order to logically separate
+ // credentials per profile.
+ std::string metadata_secret;
+ };
+
+ // Returns configuration data for the built-in Touch ID platform
+ // authenticator. May return nullopt if the authenticator is not used or not
+ // available.
+ virtual base::Optional<TouchIdAuthenticatorConfig>
+ GetTouchIdAuthenticatorConfig() const;
+#endif
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AuthenticatorRequestClientDelegate);
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_AUTHENTICATOR_REQUEST_CLIENT_DELEGATE_H_
diff --git a/chromium/content/public/browser/ax_event_notification_details.cc b/chromium/content/public/browser/ax_event_notification_details.cc
index 97dbc5ba3f8..fb2694ea914 100644
--- a/chromium/content/public/browser/ax_event_notification_details.cc
+++ b/chromium/content/public/browser/ax_event_notification_details.cc
@@ -4,14 +4,11 @@
#include "content/public/browser/ax_event_notification_details.h"
+#include "ui/accessibility/ax_event.h"
+
namespace content {
-AXEventNotificationDetails::AXEventNotificationDetails()
- : event_type(ax::mojom::Event::kNone),
- id(-1),
- ax_tree_id(-1),
- event_from(ax::mojom::EventFrom::kNone),
- action_request_id(-1) {}
+AXEventNotificationDetails::AXEventNotificationDetails() : ax_tree_id(-1) {}
AXEventNotificationDetails::AXEventNotificationDetails(
const AXEventNotificationDetails& other) = default;
diff --git a/chromium/content/public/browser/ax_event_notification_details.h b/chromium/content/public/browser/ax_event_notification_details.h
index 6732cc3c0d5..7a38ebe7548 100644
--- a/chromium/content/public/browser/ax_event_notification_details.h
+++ b/chromium/content/public/browser/ax_event_notification_details.h
@@ -8,6 +8,7 @@
#include <vector>
#include "content/common/content_export.h"
+#include "ui/accessibility/ax_event.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_relative_bounds.h"
#include "ui/accessibility/ax_tree_data.h"
@@ -23,12 +24,14 @@ struct CONTENT_EXPORT AXEventNotificationDetails {
AXEventNotificationDetails(const AXEventNotificationDetails& other);
~AXEventNotificationDetails();
- ui::AXTreeUpdate update;
- ax::mojom::Event event_type;
- int id;
+ // The unique ID of the accessibility tree this event bundle applies to.
int ax_tree_id;
- ax::mojom::EventFrom event_from;
- int action_request_id;
+
+ // Zero or more updates to the accessibility tree to apply first.
+ std::vector<ui::AXTreeUpdate> updates;
+
+ // Zero or more events to fire after the tree updates have been applied.
+ std::vector<ui::AXEvent> events;
};
// Use this object in conjunction with the
diff --git a/chromium/content/public/browser/background_fetch_delegate.h b/chromium/content/public/browser/background_fetch_delegate.h
index 275814357b6..bf9e3ff76ab 100644
--- a/chromium/content/public/browser/background_fetch_delegate.h
+++ b/chromium/content/public/browser/background_fetch_delegate.h
@@ -37,6 +37,7 @@ enum class BackgroundFetchReasonToAbort {
CANCELLED_FROM_UI,
ABORTED_BY_DEVELOPER,
TOTAL_DOWNLOAD_SIZE_EXCEEDED,
+ SERVICE_WORKER_UNAVAILABLE,
};
// Interface for launching background fetches. Implementing classes would
@@ -79,6 +80,9 @@ class CONTENT_EXPORT BackgroundFetchDelegate {
const std::string& download_guid,
std::unique_ptr<BackgroundFetchResult> result) = 0;
+ // Called when the UI of a background fetch job is activated.
+ virtual void OnUIActivated(const std::string& job_unique_id) = 0;
+
// Called by the delegate when it's shutting down to signal that the
// delegate is no longer valid.
virtual void OnDelegateShutdown() = 0;
@@ -113,6 +117,11 @@ class CONTENT_EXPORT BackgroundFetchDelegate {
// Aborts any downloads associated with |job_unique_id|.
virtual void Abort(const std::string& job_unique_id) = 0;
+ // Updates the UI shown for the fetch job associated with |job_unique_id| to
+ // display a new |title|.
+ virtual void UpdateUI(const std::string& job_unique_id,
+ const std::string& title) = 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 b27cd14524a..2866062274f 100644
--- a/chromium/content/public/browser/background_fetch_response.cc
+++ b/chromium/content/public/browser/background_fetch_response.cc
@@ -11,20 +11,23 @@ BackgroundFetchResponse::BackgroundFetchResponse(
const scoped_refptr<const net::HttpResponseHeaders>& headers)
: url_chain(url_chain), headers(headers) {}
-BackgroundFetchResponse::~BackgroundFetchResponse() {}
+BackgroundFetchResponse::~BackgroundFetchResponse() = default;
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)
+BackgroundFetchResult::BackgroundFetchResult(
+ base::Time response_time,
+ const base::FilePath& path,
+ base::Optional<storage::BlobDataHandle> blob_handle,
+ uint64_t file_size)
: response_time(response_time),
file_path(path),
+ blob_handle(blob_handle),
file_size(file_size),
failure_reason(FailureReason::NONE) {}
-BackgroundFetchResult::~BackgroundFetchResult() {}
+BackgroundFetchResult::~BackgroundFetchResult() = default;
} // namespace content
diff --git a/chromium/content/public/browser/background_fetch_response.h b/chromium/content/public/browser/background_fetch_response.h
index 00bf91c49ea..9575776194a 100644
--- a/chromium/content/public/browser/background_fetch_response.h
+++ b/chromium/content/public/browser/background_fetch_response.h
@@ -8,9 +8,11 @@
#include <vector>
#include "base/files/file_path.h"
+#include "base/optional.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
#include "net/http/http_response_headers.h"
+#include "storage/browser/blob/blob_data_handle.h"
#include "url/gurl.h"
namespace content {
@@ -60,12 +62,14 @@ struct CONTENT_EXPORT BackgroundFetchResult {
// Constructor for successful downloads.
BackgroundFetchResult(base::Time response_time,
const base::FilePath& path,
+ base::Optional<storage::BlobDataHandle> blob_handle,
uint64_t file_size);
~BackgroundFetchResult();
const base::Time response_time;
const base::FilePath file_path;
+ base::Optional<storage::BlobDataHandle> blob_handle;
const uint64_t file_size = 0;
FailureReason failure_reason;
diff --git a/chromium/content/public/browser/background_tracing_manager.h b/chromium/content/public/browser/background_tracing_manager.h
index dca9d8a3e46..b4cd53f742d 100644
--- a/chromium/content/public/browser/background_tracing_manager.h
+++ b/chromium/content/public/browser/background_tracing_manager.h
@@ -41,9 +41,9 @@ class BackgroundTracingManager {
//
using FinishedProcessingCallback = base::OnceCallback<void(bool success)>;
using ReceiveCallback =
- base::OnceCallback<void(const scoped_refptr<base::RefCountedString>&,
- std::unique_ptr<const base::DictionaryValue>,
- FinishedProcessingCallback)>;
+ base::RepeatingCallback<void(const scoped_refptr<base::RefCountedString>&,
+ std::unique_ptr<const base::DictionaryValue>,
+ FinishedProcessingCallback)>;
// Set the triggering rules for when to start recording.
//
diff --git a/chromium/content/public/browser/browser_child_process_host.h b/chromium/content/public/browser/browser_child_process_host.h
index 3d9a91c4e88..d3e119342c8 100644
--- a/chromium/content/public/browser/browser_child_process_host.h
+++ b/chromium/content/public/browser/browser_child_process_host.h
@@ -83,6 +83,9 @@ class CONTENT_EXPORT BrowserChildProcessHost : public IPC::Sender {
// Sets the user-visible name of the process.
virtual void SetName(const base::string16& name) = 0;
+ // Sets the name of the process used for metrics reporting.
+ virtual void SetMetricsName(const std::string& metrics_name) = 0;
+
// Set the handle of the process. BrowserChildProcessHost will do this when
// the Launch method is used to start the process. However if the owner
// of this object doesn't call Launch and starts the process in another way,
diff --git a/chromium/content/public/browser/browser_context.h b/chromium/content/public/browser/browser_context.h
index b5cad2b7364..4f794e25ac7 100644
--- a/chromium/content/public/browser/browser_context.h
+++ b/chromium/content/public/browser/browser_context.h
@@ -20,6 +20,7 @@
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory.h"
#include "services/service_manager/embedder/embedded_service_info.h"
+#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#if !defined(OS_ANDROID)
#include "content/public/browser/zoom_level_delegate.h"
@@ -66,7 +67,8 @@ class BrowsingDataRemover;
class BrowsingDataRemoverDelegate;
class DownloadManager;
class DownloadManagerDelegate;
-class PermissionManager;
+class PermissionController;
+class PermissionControllerDelegate;
struct PushEventPayload;
class PushMessagingService;
class ResourceContext;
@@ -101,6 +103,10 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData {
// for this |context|.
static BrowsingDataRemover* GetBrowsingDataRemover(BrowserContext* context);
+ // Returns the PermissionController associated with this context. There's
+ // always a PermissionController instance for each BrowserContext.
+ static PermissionController* GetPermissionController(BrowserContext* context);
+
// Returns a StoragePartition for the given SiteInstance. By default this will
// create a new StoragePartition if it doesn't exist, unless |can_create| is
// false.
@@ -147,6 +153,14 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData {
static BlobContextGetter GetBlobStorageContext(
BrowserContext* browser_context);
+ // Returns a mojom::BlobPtr for a specific blob. If no blob exists with the
+ // given UUID, the BlobPtr pipe will close.
+ // This method should be called on the UI thread.
+ // TODO(mek): Blob UUIDs should be entirely internal to the blob system, so
+ // eliminate this method in favor of just passing around the BlobPtr directly.
+ static blink::mojom::BlobPtr GetBlobPtr(BrowserContext* browser_context,
+ const std::string& uuid);
+
// Delivers a push message with |data| to the Service Worker identified by
// |origin| and |service_worker_registration_id|.
static void DeliverPushMessage(
@@ -247,9 +261,12 @@ class CONTENT_EXPORT BrowserContext : public base::SupportsUserData {
// return nullptr, implementing the default exception storage strategy.
virtual SSLHostStateDelegate* GetSSLHostStateDelegate() = 0;
- // Returns the PermissionManager associated with that context if any, nullptr
- // otherwise.
- virtual PermissionManager* GetPermissionManager() = 0;
+ // Returns the PermissionControllerDelegate associated with this context if
+ // any, nullptr otherwise.
+ //
+ // Note: if you want to check a permission status, you probably need
+ // BrowserContext::GetPermissionController() instead.
+ virtual PermissionControllerDelegate* GetPermissionControllerDelegate() = 0;
// Returns the BackgroundFetchDelegate associated with that context if any,
// nullptr otherwise.
diff --git a/chromium/content/public/browser/browser_main_parts.h b/chromium/content/public/browser/browser_main_parts.h
index 4b8b672fd40..2013a970877 100644
--- a/chromium/content/public/browser/browser_main_parts.h
+++ b/chromium/content/public/browser/browser_main_parts.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_PUBLIC_BROWSER_BROWSER_MAIN_PARTS_H_
#define CONTENT_PUBLIC_BROWSER_BROWSER_MAIN_PARTS_H_
+#include "base/callback.h"
#include "content/common/content_export.h"
namespace content {
@@ -95,6 +96,10 @@ class CONTENT_EXPORT BrowserMainParts {
// May set |result_code|, which will be returned by |BrowserMain()|.
virtual bool MainMessageLoopRun(int* result_code);
+ // Provides an embedder with a Closure which will quit the default main
+ // message loop. This is call only if MainMessageLoopRun returns false.
+ virtual void PreDefaultMainMessageLoopRun(base::OnceClosure quit_closure) {}
+
// This happens after the main message loop has stopped, but before
// threads are stopped.
virtual void PostMainMessageLoopRun() {}
diff --git a/chromium/content/public/browser/browsing_data_remover.h b/chromium/content/public/browser/browsing_data_remover.h
index ba4694da241..67596f77697 100644
--- a/chromium/content/public/browser/browsing_data_remover.h
+++ b/chromium/content/public/browser/browsing_data_remover.h
@@ -168,7 +168,7 @@ class BrowsingDataRemover {
// Like Remove(), but in case of URL-keyed only removes data whose URL match
// |filter_builder| (e.g. are on certain origin or domain).
- // RemoveWithFilter() currently only works with FILTERABLE_DATATYPES.
+ // RemoveWithFilter() currently only works with FILTERABLE_DATA_TYPES.
virtual void RemoveWithFilter(
const base::Time& delete_begin,
const base::Time& delete_end,
diff --git a/chromium/content/public/browser/child_process_data.h b/chromium/content/public/browser/child_process_data.h
index 9c19261ca4f..887d06dd084 100644
--- a/chromium/content/public/browser/child_process_data.h
+++ b/chromium/content/public/browser/child_process_data.h
@@ -21,6 +21,9 @@ struct ChildProcessData {
// for workers it might be the domain that it's from.
base::string16 name;
+ // The non-localized name of the process used for metrics reporting.
+ std::string metrics_name;
+
// The unique identifier for this child process. This identifier is NOT a
// process ID, and will be unique for all types of child process for
// one run of the browser.
diff --git a/chromium/content/public/browser/child_process_security_policy.h b/chromium/content/public/browser/child_process_security_policy.h
index 9ebdbd08c7c..1c56f734cfc 100644
--- a/chromium/content/public/browser/child_process_security_policy.h
+++ b/chromium/content/public/browser/child_process_security_policy.h
@@ -162,13 +162,20 @@ class ChildProcessSecurityPolicy {
virtual void GrantDeleteFromFileSystem(int child_id,
const std::string& filesystem_id) = 0;
- // Grants the child process the capability to access URLs with the provided
+ // Grants the child process the capability to commit URLs with the provided
+ // origin. Usage should be extremely rare: the content framework already
+ // automatically grants this privilege as needed on successful navigation to a
+ // URL.
+ // If you think you need this, please reach out to site-isolation-dev@ first.
+ virtual void GrantCommitOrigin(int child_id, const url::Origin& origin) = 0;
+ //
+ // Grants the child process the capability to request URLs with the provided
// origin.
- virtual void GrantOrigin(int child_id, const url::Origin& origin) = 0;
+ virtual void GrantRequestOrigin(int child_id, const url::Origin& origin) = 0;
- // Grants the child process the capability to access URLs of the provided
+ // Grants the child process the capability to request URLs of the provided
// scheme.
- virtual void GrantScheme(int child_id, const std::string& scheme) = 0;
+ virtual void GrantRequestScheme(int child_id, const std::string& scheme) = 0;
// Returns true if read access has been granted to |filesystem_id|.
virtual bool CanReadFileSystem(int child_id,
@@ -205,15 +212,6 @@ class ChildProcessSecurityPolicy {
// AddIsolatedOrigin).
virtual bool CanAccessDataForOrigin(int child_id, const GURL& url) = 0;
- // Returns true if GrantOrigin was called earlier with the same parameters.
- //
- // TODO(alexmos): This currently exists to support checking whether a
- // <webview> guest process has permission to request blob URLs in its
- // embedder's origin on the IO thread. This should be removed once that
- // 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|.
diff --git a/chromium/content/public/browser/child_process_termination_info.h b/chromium/content/public/browser/child_process_termination_info.h
index 37a325679b1..afd672e709d 100644
--- a/chromium/content/public/browser/child_process_termination_info.h
+++ b/chromium/content/public/browser/child_process_termination_info.h
@@ -10,6 +10,10 @@
#include "build/build_config.h"
#include "content/public/common/result_codes.h"
+#if defined(OS_ANDROID)
+#include "base/android/child_process_binding_types.h"
+#endif
+
namespace content {
struct ChildProcessTerminationInfo {
@@ -27,10 +31,16 @@ struct ChildProcessTerminationInfo {
#if defined(OS_ANDROID)
// True if child service has strong or moderate binding at time of death.
- bool has_oom_protection_bindings = false;
+ base::android::ChildBindingState binding_state =
+ base::android::ChildBindingState::UNBOUND;
// True if child service was explicitly killed by browser.
bool was_killed_intentionally_by_browser = false;
+
+ // Counts of remaining child processes with corresponding binding.
+ int remaining_process_with_strong_binding = 0;
+ int remaining_process_with_moderate_binding = 0;
+ int remaining_process_with_waived_binding = 0;
#endif
};
diff --git a/chromium/content/public/browser/content_browser_client.cc b/chromium/content/public/browser/content_browser_client.cc
index a8927d0ba8d..2a896c7072c 100644
--- a/chromium/content/public/browser/content_browser_client.cc
+++ b/chromium/content/public/browser/content_browser_client.cc
@@ -11,6 +11,7 @@
#include "base/guid.h"
#include "base/logging.h"
#include "build/build_config.h"
+#include "content/public/browser/authenticator_request_client_delegate.h"
#include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/login_delegate.h"
#include "content/public/browser/memory_coordinator_delegate.h"
@@ -20,16 +21,16 @@
#include "content/public/browser/url_loader_request_interceptor.h"
#include "content/public/browser/vpn_service_proxy.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_buildflags.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "net/ssl/client_cert_identity.h"
#include "net/ssl/client_cert_store.h"
#include "net/url_request/url_request_context_getter.h"
+#include "services/device/public/cpp/geolocation/location_provider.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/mojom/network_service.mojom.h"
#include "services/service_manager/sandbox/sandbox_type.h"
#include "storage/browser/quota/quota_manager.h"
#include "ui/gfx/image/image_skia.h"
@@ -78,6 +79,10 @@ GURL ContentBrowserClient::GetEffectiveURL(BrowserContext* browser_context,
return url;
}
+bool ContentBrowserClient::ShouldUseMobileFlingCurve() const {
+ return false;
+}
+
bool ContentBrowserClient::ShouldUseProcessPerSite(
BrowserContext* browser_context, const GURL& effective_url) {
return false;
@@ -113,6 +118,11 @@ bool ContentBrowserClient::LogWebUIUrl(const GURL& web_ui_url) const {
return false;
}
+bool ContentBrowserClient::IsWebUIAllowedToMakeNetworkRequests(
+ const url::Origin& origin) {
+ return false;
+}
+
bool ContentBrowserClient::IsHandledURL(const GURL& url) {
return false;
}
@@ -180,9 +190,11 @@ bool ContentBrowserClient::OverridesAudioManager() {
return false;
}
-std::unique_ptr<media::CdmFactory> ContentBrowserClient::CreateCdmFactory() {
- return nullptr;
-}
+void ContentBrowserClient::GetHardwareSecureDecryptionCaps(
+ const std::string& key_system,
+ const base::flat_set<media::CdmProxy::Protocol>& cdm_proxy_protocols,
+ base::flat_set<media::VideoCodec>* video_codecs,
+ base::flat_set<media::EncryptionMode>* encryption_schemes) {}
bool ContentBrowserClient::ShouldAssignSiteForURL(const GURL& url) {
return true;
@@ -258,6 +270,10 @@ bool ContentBrowserClient::IsDataSaverEnabled(BrowserContext* context) {
return false;
}
+void ContentBrowserClient::UpdateRendererPreferencesForWorker(
+ BrowserContext* browser_context,
+ RendererPreferences* out_prefs) {}
+
bool ContentBrowserClient::AllowGetCookie(const GURL& url,
const GURL& first_party,
const net::CookieList& cookie_list,
@@ -272,11 +288,24 @@ bool ContentBrowserClient::AllowSetCookie(const GURL& url,
const net::CanonicalCookie& cookie,
ResourceContext* context,
int render_process_id,
- int render_frame_id,
- const net::CookieOptions& options) {
+ int render_frame_id) {
return true;
}
+void ContentBrowserClient::OnCookiesRead(int process_id,
+ int routing_id,
+ const GURL& url,
+ const GURL& first_party_url,
+ const net::CookieList& cookie_list,
+ bool blocked_by_policy) {}
+
+void ContentBrowserClient::OnCookieChange(int process_id,
+ int routing_id,
+ const GURL& url,
+ const GURL& first_party_url,
+ const net::CanonicalCookie& cookie,
+ bool blocked_by_policy) {}
+
void ContentBrowserClient::AllowWorkerFileSystem(
const GURL& url,
ResourceContext* context,
@@ -345,16 +374,21 @@ ContentBrowserClient::OverrideSystemLocationProvider() {
return nullptr;
}
-void ContentBrowserClient::GetGeolocationRequestContext(
- base::OnceCallback<void(scoped_refptr<net::URLRequestContextGetter>)>
- callback) {
- std::move(callback).Run(scoped_refptr<net::URLRequestContextGetter>(nullptr));
+scoped_refptr<network::SharedURLLoaderFactory>
+ContentBrowserClient::GetSystemSharedURLLoaderFactory() {
+ return nullptr;
}
std::string ContentBrowserClient::GetGeolocationApiKey() {
return std::string();
}
+#if defined(OS_ANDROID)
+bool ContentBrowserClient::ShouldUseGmsCoreGeolocationProvider() {
+ return false;
+}
+#endif
+
std::string ContentBrowserClient::GetStoragePartitionIdForSite(
BrowserContext* browser_context,
const GURL& site) {
@@ -549,16 +583,14 @@ ContentBrowserClient::OutOfProcessServiceInfo::OutOfProcessServiceInfo() =
default;
ContentBrowserClient::OutOfProcessServiceInfo::OutOfProcessServiceInfo(
- const base::string16& process_name)
- : process_name(process_name) {
- DCHECK(!process_name.empty());
-}
+ const ProcessNameCallback& process_name_callback)
+ : process_name_callback(process_name_callback) {}
ContentBrowserClient::OutOfProcessServiceInfo::OutOfProcessServiceInfo(
- const base::string16& process_name,
+ const ProcessNameCallback& process_name_callback,
const std::string& process_group)
- : process_name(process_name), process_group(process_group) {
- DCHECK(!process_name.empty());
+ : process_name_callback(process_name_callback),
+ process_group(process_group) {
DCHECK(!process_group.empty());
}
@@ -575,6 +607,11 @@ ContentBrowserClient::GetExtraServiceManifests() {
return std::vector<ContentBrowserClient::ServiceManifestInfo>();
}
+std::vector<service_manager::Identity>
+ContentBrowserClient::GetStartupServices() {
+ return std::vector<service_manager::Identity>();
+}
+
std::unique_ptr<MemoryCoordinatorDelegate>
ContentBrowserClient::GetMemoryCoordinatorDelegate() {
return std::unique_ptr<MemoryCoordinatorDelegate>();
@@ -609,12 +646,28 @@ void ContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories(
NonNetworkURLLoaderFactoryMap* factories) {}
bool ContentBrowserClient::WillCreateURLLoaderFactory(
+ BrowserContext* browser_context,
RenderFrameHost* frame,
bool is_navigation,
network::mojom::URLLoaderFactoryRequest* factory_request) {
return false;
}
+void ContentBrowserClient::WillCreateWebSocket(
+ RenderFrameHost* frame,
+ network::mojom::WebSocketRequest* request,
+ network::mojom::AuthenticationHandlerPtr* auth_handler) {}
+
+std::vector<std::unique_ptr<URLLoaderRequestInterceptor>>
+ContentBrowserClient::WillCreateURLLoaderRequestInterceptors(
+ NavigationUIData* navigation_ui_data,
+ int frame_tree_node_id) {
+ return std::vector<std::unique_ptr<URLLoaderRequestInterceptor>>();
+}
+
+void ContentBrowserClient::OnNetworkServiceCreated(
+ network::mojom::NetworkService* network_service) {}
+
network::mojom::NetworkContextPtr ContentBrowserClient::CreateNetworkContext(
BrowserContext* context,
bool in_memory,
@@ -628,7 +681,6 @@ network::mojom::NetworkContextPtr ContentBrowserClient::CreateNetworkContext(
context_params->user_agent = GetContentClient()->GetUserAgent();
context_params->accept_language = "en-us,en";
context_params->enable_data_url_support = true;
- context_params->enable_file_url_support = true;
GetNetworkService()->CreateNetworkContext(MakeRequest(&network_context),
std::move(context_params));
return network_context;
@@ -679,22 +731,10 @@ bool ContentBrowserClient::ShouldCreateTaskScheduler() {
return true;
}
-bool ContentBrowserClient::ShouldPermitIndividualAttestationForWebauthnRPID(
- content::BrowserContext* browser_context,
- const std::string& rp_id) {
- return false;
-}
-
-void ContentBrowserClient::ShouldReturnAttestationForWebauthnRPID(
- content::RenderFrameHost* rfh,
- const std::string& rp_id,
- const url::Origin& origin,
- base::OnceCallback<void(bool)> callback) {
- std::move(callback).Run(true);
-}
-
-bool ContentBrowserClient::IsFocused(content::WebContents* web_contents) {
- return true;
+std::unique_ptr<AuthenticatorRequestClientDelegate>
+ContentBrowserClient::GetWebAuthenticationRequestDelegate(
+ RenderFrameHost* render_frame_host) {
+ return std::make_unique<AuthenticatorRequestClientDelegate>();
}
std::unique_ptr<net::ClientCertStore>
@@ -705,8 +745,10 @@ ContentBrowserClient::CreateClientCertStore(ResourceContext* resource_context) {
scoped_refptr<LoginDelegate> ContentBrowserClient::CreateLoginDelegate(
net::AuthChallengeInfo* auth_info,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
+ const GlobalRequestID& request_id,
bool is_request_for_main_frame,
const GURL& url,
+ scoped_refptr<net::HttpResponseHeaders> response_headers,
bool first_auth_attempt,
LoginAuthRequiredCallback auth_required_callback) {
return nullptr;
@@ -729,11 +771,4 @@ ContentBrowserClient::CreateWindowForPictureInPicture(
return nullptr;
}
-std::vector<std::unique_ptr<URLLoaderRequestInterceptor>>
-ContentBrowserClient::WillCreateURLLoaderRequestInterceptors(
- NavigationUIData* navigation_ui_data,
- int frame_tree_node_id) {
- return std::vector<std::unique_ptr<URLLoaderRequestInterceptor>>();
-}
-
} // namespace content
diff --git a/chromium/content/public/browser/content_browser_client.h b/chromium/content/public/browser/content_browser_client.h
index e9c6b810e05..fd5d62fee11 100644
--- a/chromium/content/public/browser/content_browser_client.h
+++ b/chromium/content/public/browser/content_browser_client.h
@@ -14,11 +14,13 @@
#include <vector>
#include "base/callback.h"
+#include "base/containers/flat_set.h"
#include "base/optional.h"
#include "base/task_scheduler/task_scheduler.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/public/browser/certificate_request_result_type.h"
+#include "content/public/browser/global_request_id.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/overlay_window.h"
#include "content/public/browser/resource_request_info.h"
@@ -29,11 +31,15 @@
#include "content/public/common/window_container_type.mojom.h"
#include "device/usb/public/mojom/chooser_service.mojom.h"
#include "device/usb/public/mojom/device_manager.mojom.h"
+#include "media/base/video_codecs.h"
+#include "media/cdm/cdm_proxy.h"
#include "media/media_buildflags.h"
#include "media/mojo/interfaces/remoting.mojom.h"
#include "net/base/mime_util.h"
#include "net/cookies/canonical_cookie.h"
-#include "services/network/public/mojom/network_service.mojom.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "services/network/public/mojom/network_context.mojom.h"
+#include "services/network/public/mojom/websocket.mojom.h"
#include "services/service_manager/embedder/embedded_service_info.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/mojom/service.mojom.h"
@@ -74,13 +80,17 @@ class ImageSkia;
namespace media {
class AudioLogFactory;
class AudioManager;
-class CdmFactory;
+enum class EncryptionMode;
}
namespace mojo {
class ScopedInterfaceEndpointHandle;
}
+namespace network {
+class SharedURLLoaderFactory;
+}
+
namespace service_manager {
class Identity;
class Service;
@@ -93,19 +103,17 @@ class AuthCredentials;
class ClientCertIdentity;
using ClientCertIdentityList = std::vector<std::unique_ptr<ClientCertIdentity>>;
class ClientCertStore;
-class CookieOptions;
class HttpRequestHeaders;
class NetLog;
class SSLCertRequestInfo;
class SSLInfo;
class URLRequest;
class URLRequestContext;
-class URLRequestContextGetter;
} // namespace net
namespace network {
namespace mojom {
-class NetworkContext;
+class NetworkService;
}
struct ResourceRequest;
} // namespace network
@@ -133,6 +141,7 @@ class FileSystemBackend;
namespace content {
enum class PermissionType;
+class AuthenticatorRequestClientDelegate;
class BrowserChildProcessHost;
class BrowserContext;
class BrowserMainParts;
@@ -166,6 +175,7 @@ class WebContentsViewDelegate;
struct MainFunctionParams;
struct OpenURLParams;
struct Referrer;
+struct RendererPreferences;
struct WebPreferences;
CONTENT_EXPORT void OverrideOnBindInterface(
@@ -240,6 +250,10 @@ class CONTENT_EXPORT ContentBrowserClient {
virtual GURL GetEffectiveURL(BrowserContext* browser_context,
const GURL& url);
+ // Returns whether gesture fling events should use the mobile-behavior gesture
+ // curve for scrolling.
+ virtual bool ShouldUseMobileFlingCurve() const;
+
// Returns whether all instances of the specified effective URL should be
// rendered by the same process, rather than using process-per-site-instance.
virtual bool ShouldUseProcessPerSite(BrowserContext* browser_context,
@@ -297,6 +311,13 @@ class CONTENT_EXPORT ContentBrowserClient {
// chrome://) URLs are logged. Returns whether the URL was actually logged.
virtual bool LogWebUIUrl(const GURL& web_ui_url) const;
+ // http://crbug.com/829412
+ // Renderers with WebUI bindings shouldn't make http(s) requests for security
+ // reasons (e.g. to avoid malicious responses being able to run code in
+ // priviliged renderers). Fix these webui's to make requests through C++
+ // code instead.
+ virtual bool IsWebUIAllowedToMakeNetworkRequests(const url::Origin& origin);
+
// Returns whether a specified URL is handled by the embedder's internal
// protocol handlers.
virtual bool IsHandledURL(const GURL& url);
@@ -457,6 +478,14 @@ class CONTENT_EXPORT ContentBrowserClient {
virtual bool IsDataSaverEnabled(BrowserContext* context);
+ // Updates the given prefs for Service Worker and Shared Worker. The prefs
+ // are to be sent to the renderer process when a worker is created. Note that
+ // We don't use this method for Dedicated Workers as they inherit preferences
+ // from their closest ancestor frame.
+ virtual void UpdateRendererPreferencesForWorker(
+ BrowserContext* browser_context,
+ RendererPreferences* out_prefs);
+
// Allow the embedder to return additional headers that should be sent when
// fetching |url| as well as add extra load flags.
virtual void NavigationRequestStarted(
@@ -465,6 +494,14 @@ class CONTENT_EXPORT ContentBrowserClient {
std::unique_ptr<net::HttpRequestHeaders>* extra_headers,
int* extra_load_flags) {}
+ // Allow the embedder to modify headers for a redirect. If non-nullopt,
+ // |*modified_request_headers| are applied to the request headers after
+ // updating them for the redirect.
+ virtual void NavigationRequestRedirected(
+ int frame_tree_node_id,
+ const GURL& url,
+ base::Optional<net::HttpRequestHeaders>* modified_request_headers) {}
+
// Allow the embedder to control if the given cookie can be read.
// This is called on the IO thread.
virtual bool AllowGetCookie(const GURL& url,
@@ -481,8 +518,24 @@ class CONTENT_EXPORT ContentBrowserClient {
const net::CanonicalCookie& cookie,
ResourceContext* context,
int render_process_id,
- int render_frame_id,
- const net::CookieOptions& options);
+ int render_frame_id);
+
+ // Notifies the embedder that an attempt has been made to read the cookies in
+ // |cookie_list|.
+ virtual void OnCookiesRead(int process_id,
+ int routing_id,
+ const GURL& url,
+ const GURL& first_party_url,
+ const net::CookieList& cookie_list,
+ bool blocked_by_policy);
+
+ // Notifies the embedder that an attempt has been made to set |cookie|.
+ virtual void OnCookieChange(int process_id,
+ int routing_id,
+ const GURL& url,
+ const GURL& first_party_url,
+ const net::CanonicalCookie& cookie,
+ bool blocked_by_policy);
// Allow the embedder to control if access to file system by a shared worker
// is allowed.
@@ -542,14 +595,11 @@ class CONTENT_EXPORT ContentBrowserClient {
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
- // by invoking |callback| on the calling thread.
- // * Default implementation provides nullptr URLRequestContextGetter.
- virtual void GetGeolocationRequestContext(
- base::OnceCallback<void(scoped_refptr<net::URLRequestContextGetter>)>
- callback);
+ // Returns a SharedURLLoaderFactory attached to the system network context.
+ // Must be called on the UI thread. The default implementation returns
+ // nullptr.
+ virtual scoped_refptr<network::SharedURLLoaderFactory>
+ GetSystemSharedURLLoaderFactory();
// Allows an embedder to provide a Google API Key to use for network
// geolocation queries.
@@ -557,6 +607,11 @@ class CONTENT_EXPORT ContentBrowserClient {
// * Default implementation returns empty string, meaning send no API key.
virtual std::string GetGeolocationApiKey();
+#if defined(OS_ANDROID)
+ // Allows an embedder to decide whether to use the GmsCoreLocationProvider.
+ virtual bool ShouldUseGmsCoreGeolocationProvider();
+#endif
+
// Allow the embedder to specify a string version of the storage partition
// config with a site.
virtual std::string GetStoragePartitionIdForSite(
@@ -834,15 +889,18 @@ class CONTENT_EXPORT ContentBrowserClient {
const std::string& name,
mojo::ScopedMessagePipeHandle* handle) {}
+ using ProcessNameCallback = base::RepeatingCallback<base::string16()>;
+
struct CONTENT_EXPORT OutOfProcessServiceInfo {
OutOfProcessServiceInfo();
- OutOfProcessServiceInfo(const base::string16& process_name);
- OutOfProcessServiceInfo(const base::string16& process_name,
+ OutOfProcessServiceInfo(const ProcessNameCallback& process_name_callback);
+ OutOfProcessServiceInfo(const ProcessNameCallback& process_name_callback,
const std::string& process_group);
~OutOfProcessServiceInfo();
- // The display name of the service process launched for the service.
- base::string16 process_name;
+ // The callback function to get the display name of the service process
+ // launched for the service.
+ ProcessNameCallback process_name_callback;
// If provided, a string which groups this service into a process shared
// by other services using the same string.
@@ -880,6 +938,10 @@ class CONTENT_EXPORT ContentBrowserClient {
// with the service manager context.
virtual std::vector<ServiceManifestInfo> GetExtraServiceManifests();
+ // Allows the embedder to have a list of services started after the
+ // in-process Service Manager has been initialized.
+ virtual std::vector<service_manager::Identity> GetStartupServices();
+
// Allows to override the visibility state of a RenderFrameHost.
// |visibility_state| should not be null. It will only be set if needed.
virtual void OverridePageVisibilityState(
@@ -939,9 +1001,17 @@ class CONTENT_EXPORT ContentBrowserClient {
// returns a non-null value.
virtual bool OverridesAudioManager();
- // Creates and returns a factory used for creating CDM instances for playing
- // protected content.
- virtual std::unique_ptr<media::CdmFactory> CreateCdmFactory();
+ // Gets supported hardware secure |video_codecs| and |encryption_schemes| for
+ // the purpose of decrypting encrypted media using a Content Decryption Module
+ // (CDM) and a CdmProxy associated with |key_system|. The CDM supports all
+ // protocols in |cdm_proxy_protocols|, but only one CdmProxy protocol will be
+ // supported by the CdmProxy on the system, for which the capabilities will
+ // be returned.
+ virtual void GetHardwareSecureDecryptionCaps(
+ const std::string& key_system,
+ const base::flat_set<media::CdmProxy::Protocol>& cdm_proxy_protocols,
+ base::flat_set<media::VideoCodec>* video_codecs,
+ base::flat_set<media::EncryptionMode>* encryption_schemes);
// Populates |mappings| with all files that need to be mapped before launching
// a child process.
@@ -986,7 +1056,8 @@ class CONTENT_EXPORT ContentBrowserClient {
GetTaskSchedulerInitParams();
// Allows the embedder to register one or more URLLoaderThrottles for a
- // URL request. This is used only when --enable-network-service is in effect.
+ // navigation request.
+ // This is called both when the network service is enabled and disabled.
// This is called on the IO thread.
virtual std::vector<std::unique_ptr<URLLoaderThrottle>>
CreateURLLoaderThrottles(
@@ -1019,20 +1090,39 @@ class CONTENT_EXPORT ContentBrowserClient {
NonNetworkURLLoaderFactoryMap* factories);
// Allows the embedder to intercept URLLoaderFactory interfaces used for
- // navigation or being brokered on behalf of a renderer fetching subresources.
+ // navigation or being brokered on behalf of a renderer fetching subresources,
+ // or for non-navigation requests initiated by the browser on behalf of a
+ // BrowserContext.
+ //
// |*factory_request| is always valid upon entry and MUST be valid upon
// return. The embedder may swap out the value of |*factory_request| for its
- // own, in which case it must return |true| to indicate that its proxying
+ // own, in which case it must return |true| to indicate that it's proxying
// requests for the URLLoaderFactory. Otherwise |*factory_request| is left
// unmodified and this must return |false|.
//
// Always called on the UI thread and only when the Network Service is
// enabled.
+ //
+ // Note that |frame| may be null if this is a browser-initiated,
+ // non-navigation request, e.g. a request made via
+ // |StoragePartition::GetURLLoaderFactoryForBrowserProcess()|.
virtual bool WillCreateURLLoaderFactory(
+ BrowserContext* browser_context,
RenderFrameHost* frame,
bool is_navigation,
network::mojom::URLLoaderFactoryRequest* factory_request);
+ // Allows the embedder to intercept a WebSocket connection. |*request|
+ // is always valid upon entry and MUST be valid upon return. The embedder
+ // may swap out the value of |*request| for its own.
+ //
+ // Always called on the UI thread and only when the Network Service is
+ // enabled.
+ virtual void WillCreateWebSocket(
+ RenderFrameHost* frame,
+ network::mojom::WebSocketRequest* request,
+ network::mojom::AuthenticationHandlerPtr* authentication_handler);
+
// Allows the embedder to returns a list of request interceptors that can
// intercept a navigation request.
//
@@ -1042,6 +1132,13 @@ class CONTENT_EXPORT ContentBrowserClient {
WillCreateURLLoaderRequestInterceptors(NavigationUIData* navigation_ui_data,
int frame_tree_node_id);
+ // Called when the NetworkService, accessible through
+ // content::GetNetworkService(), is created. Implementations should avoid
+ // calling into GetNetworkService() again to avoid re-entrancy if the service
+ // fails to start.
+ virtual void OnNetworkServiceCreated(
+ network::mojom::NetworkService* network_service);
+
// 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
@@ -1123,38 +1220,14 @@ class CONTENT_EXPORT ContentBrowserClient {
// BrowserMainLoop, BrowserMainLoop itself is responsible for that.
virtual bool ShouldCreateTaskScheduler();
- // Returns true if the given Webauthn[1] RP ID[2] is permitted to receive
- // individual attestation certificates. This a) triggers a signal to the
- // security key that returning individual attestation certificates is
- // permitted and b) skips any permission prompt for attestation.
- //
- // [1] https://www.w3.org/TR/webauthn/
- // [2] https://www.w3.org/TR/webauthn/#relying-party-identifier
- virtual bool ShouldPermitIndividualAttestationForWebauthnRPID(
- content::BrowserContext* browser_context,
- const std::string& rp_id);
-
- // Invokes |callback| with |true| if the given Webauthn RP ID (see references
- // above) is permitted to receive attestation certificates from a device.
- // Otherwise invokes |callback| with |false|.
- //
- // Since these certificates may uniquely identify the authenticator, the
- // embedder may choose to show a permissions prompt to the user, and only
- // invoke |callback| afterwards. This may hairpin |callback|.
- virtual void ShouldReturnAttestationForWebauthnRPID(
- content::RenderFrameHost* rfh,
- const std::string& rp_id,
- const url::Origin& origin,
- base::OnceCallback<void(bool)> callback);
-
- // Returns whether |web_contents| is the active tab in the focused window.
- // As an example, webauthn uses this because it doesn't want to allow
- // authenticator operations to be triggered by background tabs.
- //
- // Note that the default implementation of this function, and the
- // implementation in ChromeContentBrowserClient for Android, return |true| so
- // that testing is possible.
- virtual bool IsFocused(content::WebContents* web_contents);
+ // Returns an AuthenticatorRequestClientDelegate subclass instance to provide
+ // embedder-specific configuration for a single Web Authentication API request
+ // being serviced in a given RenderFrame. The instance is guaranteed to be
+ // destroyed before the RenderFrame goes out of scope. The embedder may choose
+ // to return nullptr to indicate that the request cannot be serviced right
+ // now.
+ virtual std::unique_ptr<AuthenticatorRequestClientDelegate>
+ GetWebAuthenticationRequestDelegate(RenderFrameHost* render_frame_host);
// Get platform ClientCertStore. May return nullptr.
virtual std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
@@ -1171,8 +1244,10 @@ class CONTENT_EXPORT ContentBrowserClient {
virtual scoped_refptr<LoginDelegate> CreateLoginDelegate(
net::AuthChallengeInfo* auth_info,
content::ResourceRequestInfo::WebContentsGetter web_contents_getter,
+ const GlobalRequestID& request_id,
bool is_request_for_main_frame,
const GURL& url,
+ scoped_refptr<net::HttpResponseHeaders> response_headers,
bool first_auth_attempt,
LoginAuthRequiredCallback auth_required_callback);
diff --git a/chromium/content/public/browser/devtools_agent_host_client.cc b/chromium/content/public/browser/devtools_agent_host_client.cc
new file mode 100644
index 00000000000..06c611e6737
--- /dev/null
+++ b/chromium/content/public/browser/devtools_agent_host_client.cc
@@ -0,0 +1,15 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/devtools_agent_host_client.h"
+
+namespace content {
+
+bool DevToolsAgentHostClient::MayAttachToRenderer(
+ content::RenderFrameHost* render_frame_host,
+ bool is_webui) {
+ return true;
+}
+
+} // namespace content
diff --git a/chromium/content/public/browser/devtools_agent_host_client.h b/chromium/content/public/browser/devtools_agent_host_client.h
index c8f08114876..53e560ae28e 100644
--- a/chromium/content/public/browser/devtools_agent_host_client.h
+++ b/chromium/content/public/browser/devtools_agent_host_client.h
@@ -12,6 +12,7 @@
namespace content {
class DevToolsAgentHost;
+class RenderFrameHost;
// DevToolsAgentHostClient can attach to a DevToolsAgentHost and start
// debugging it.
@@ -25,6 +26,11 @@ class CONTENT_EXPORT DevToolsAgentHostClient {
// This method is called when attached agent host is closed.
virtual void AgentHostClosed(DevToolsAgentHost* agent_host) = 0;
+
+ // Returns true if the client is allowed to attach to the given renderer.
+ // Note: this method may be called before navigation commits.
+ virtual bool MayAttachToRenderer(content::RenderFrameHost* render_frame_host,
+ bool is_webui);
};
} // namespace content
diff --git a/chromium/content/public/browser/devtools_agent_host_observer.cc b/chromium/content/public/browser/devtools_agent_host_observer.cc
index 3020923243b..0dc6ae58a9c 100644
--- a/chromium/content/public/browser/devtools_agent_host_observer.cc
+++ b/chromium/content/public/browser/devtools_agent_host_observer.cc
@@ -32,4 +32,8 @@ void DevToolsAgentHostObserver::DevToolsAgentHostDestroyed(
DevToolsAgentHost* agent_host) {
}
+void DevToolsAgentHostObserver::DevToolsAgentHostCrashed(
+ DevToolsAgentHost* agent_host,
+ base::TerminationStatus status) {}
+
} // namespace content
diff --git a/chromium/content/public/browser/devtools_agent_host_observer.h b/chromium/content/public/browser/devtools_agent_host_observer.h
index 88d345e8c2c..a971b751160 100644
--- a/chromium/content/public/browser/devtools_agent_host_observer.h
+++ b/chromium/content/public/browser/devtools_agent_host_observer.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_PUBLIC_BROWSER_DEVTOOLS_AGENT_HOST_OBSERVER_H_
#define CONTENT_PUBLIC_BROWSER_DEVTOOLS_AGENT_HOST_OBSERVER_H_
+#include "base/process/kill.h"
#include "content/common/content_export.h"
namespace content {
@@ -33,6 +34,10 @@ class CONTENT_EXPORT DevToolsAgentHostObserver {
// Called when client has detached from DevToolsAgentHost.
virtual void DevToolsAgentHostDetached(DevToolsAgentHost* agent_host);
+ // Called when DevToolsAgentHost crashed.
+ virtual void DevToolsAgentHostCrashed(DevToolsAgentHost* agent_host,
+ base::TerminationStatus status);
+
// Called when DevToolsAgentHost was destroyed.
virtual void DevToolsAgentHostDestroyed(DevToolsAgentHost* agent_host);
};
diff --git a/chromium/content/public/browser/devtools_manager_delegate.cc b/chromium/content/public/browser/devtools_manager_delegate.cc
index 9d659510a10..fb839936bf4 100644
--- a/chromium/content/public/browser/devtools_manager_delegate.cc
+++ b/chromium/content/public/browser/devtools_manager_delegate.cc
@@ -22,6 +22,10 @@ std::string DevToolsManagerDelegate::GetTargetDescription(WebContents* wc) {
return std::string();
}
+bool DevToolsManagerDelegate::AllowInspectingWebContents(WebContents* wc) {
+ return true;
+}
+
DevToolsAgentHost::List DevToolsManagerDelegate::RemoteDebuggingTargets() {
return DevToolsAgentHost::GetOrCreateAll();
}
diff --git a/chromium/content/public/browser/devtools_manager_delegate.h b/chromium/content/public/browser/devtools_manager_delegate.h
index b0f44feed19..d0fea8b66aa 100644
--- a/chromium/content/public/browser/devtools_manager_delegate.h
+++ b/chromium/content/public/browser/devtools_manager_delegate.h
@@ -36,6 +36,9 @@ class CONTENT_EXPORT DevToolsManagerDelegate {
// Returns DevToolsAgentHost title to use for given |web_contents| target.
virtual std::string GetTargetDescription(WebContents* web_contents);
+ // Returns whether embedder allows to inspect given |web_contents|.
+ virtual bool AllowInspectingWebContents(WebContents* web_contents);
+
// Returns all targets embedder would like to report as debuggable
// remotely.
virtual DevToolsAgentHost::List RemoteDebuggingTargets();
diff --git a/chromium/content/public/browser/download_manager.h b/chromium/content/public/browser/download_manager.h
index 0708c4157d0..09476abd2f4 100644
--- a/chromium/content/public/browser/download_manager.h
+++ b/chromium/content/public/browser/download_manager.h
@@ -223,6 +223,11 @@ class CONTENT_EXPORT DownloadManager : public base::SupportsUserData::Data {
// finish asynchronously after this method returns.
virtual void CheckForHistoryFilesRemoval() = 0;
+ // Called when download history query completes. Call
+ // |load_history_downloads_cb| to load all the history downloads.
+ virtual void OnHistoryQueryComplete(
+ base::OnceClosure load_history_downloads_cb) = 0;
+
// Get the download item for |id| if present, no matter what type of download
// it is or state it's in.
// DEPRECATED: Don't add new callers for GetDownload(uint32_t). Instead keep
diff --git a/chromium/content/public/browser/download_utils.h b/chromium/content/public/browser/download_utils.h
new file mode 100644
index 00000000000..af5e7ee4af0
--- /dev/null
+++ b/chromium/content/public/browser/download_utils.h
@@ -0,0 +1,28 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_DOWNLOAD_UTILS_H_
+#define CONTENT_PUBLIC_BROWSER_DOWNLOAD_UTILS_H_
+
+#include "content/common/content_export.h"
+
+#include <string>
+
+class GURL;
+namespace net {
+class HttpResponseHeaders;
+}
+
+namespace content {
+namespace download_utils {
+
+// Returns true if the given response must be downloaded because of the headers.
+CONTENT_EXPORT bool MustDownload(const GURL& url,
+ const net::HttpResponseHeaders* headers,
+ const std::string& mime_type);
+
+} // namespace download_utils
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_DOWNLOAD_UTILS_H_
diff --git a/chromium/content/public/browser/gpu_client.h b/chromium/content/public/browser/gpu_client.h
index 77a7e386c5d..d5d249bf4f6 100644
--- a/chromium/content/public/browser/gpu_client.h
+++ b/chromium/content/public/browser/gpu_client.h
@@ -9,7 +9,6 @@
#include "base/callback_forward.h"
#include "content/common/content_export.h"
-#include "content/public/browser/browser_thread.h"
#include "services/ui/public/interfaces/gpu.mojom.h"
namespace content {
@@ -21,9 +20,10 @@ class CONTENT_EXPORT GpuClient {
using ConnectionErrorHandlerClosure =
base::OnceCallback<void(GpuClient* client)>;
- static std::unique_ptr<GpuClient, BrowserThread::DeleteOnIOThread> Create(
+ static std::unique_ptr<GpuClient, base::OnTaskRunnerDeleter> Create(
ui::mojom::GpuRequest request,
- ConnectionErrorHandlerClosure connection_error_handler);
+ ConnectionErrorHandlerClosure connection_error_handler,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
};
} // namespace content
diff --git a/chromium/content/public/browser/gpu_utils.cc b/chromium/content/public/browser/gpu_utils.cc
index 52db4930d03..78d1c9897aa 100644
--- a/chromium/content/public/browser/gpu_utils.cc
+++ b/chromium/content/public/browser/gpu_utils.cc
@@ -14,11 +14,11 @@
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/service_utils.h"
+#include "gpu/config/gpu_switches.h"
#include "media/media_buildflags.h"
namespace {
-#if defined(OS_WIN)
bool GetUintFromSwitch(const base::CommandLine* command_line,
const base::StringPiece& switch_string,
uint32_t* value) {
@@ -27,7 +27,6 @@ bool GetUintFromSwitch(const base::CommandLine* command_line,
std::string switch_value(command_line->GetSwitchValueASCII(switch_string));
return base::StringToUint(switch_value, value);
}
-#endif // defined(OS_WIN)
void RunTaskOnTaskRunner(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
@@ -81,6 +80,8 @@ const gpu::GpuPreferences GetGpuPreferencesFromCommandLine() {
command_line->HasSwitch(switches::kDisableSoftwareRasterizer);
gpu_preferences.log_gpu_control_list_decisions =
command_line->HasSwitch(switches::kLogGpuControlListDecisions);
+ GetUintFromSwitch(command_line, switches::kMaxActiveWebGLContexts,
+ &gpu_preferences.max_active_webgl_contexts);
gpu_preferences.gpu_startup_dialog =
command_line->HasSwitch(switches::kGpuStartupDialog);
gpu_preferences.disable_gpu_watchdog =
@@ -88,6 +89,15 @@ const gpu::GpuPreferences GetGpuPreferencesFromCommandLine() {
(gpu_preferences.single_process || gpu_preferences.in_process_gpu);
gpu_preferences.gpu_sandbox_start_early =
command_line->HasSwitch(switches::kGpuSandboxStartEarly);
+
+ gpu_preferences.enable_oop_rasterization =
+ command_line->HasSwitch(switches::kEnableOopRasterization);
+ gpu_preferences.disable_oop_rasterization =
+ command_line->HasSwitch(switches::kDisableOopRasterization);
+
+ gpu_preferences.enable_vulkan =
+ command_line->HasSwitch(switches::kEnableVulkan);
+
// Some of these preferences are set or adjusted in
// GpuDataManagerImplPrivate::AppendGpuCommandLine.
return gpu_preferences;
diff --git a/chromium/content/public/browser/gpu_utils.h b/chromium/content/public/browser/gpu_utils.h
index cc12e5b0c46..e4c9ad2c8b0 100644
--- a/chromium/content/public/browser/gpu_utils.h
+++ b/chromium/content/public/browser/gpu_utils.h
@@ -7,7 +7,7 @@
#include "base/callback_forward.h"
#include "content/common/content_export.h"
-#include "gpu/command_buffer/service/gpu_preferences.h"
+#include "gpu/config/gpu_preferences.h"
namespace content {
diff --git a/chromium/content/public/browser/keyboard_event_processing_result.h b/chromium/content/public/browser/keyboard_event_processing_result.h
index ba43542c7ab..4030a527e7c 100644
--- a/chromium/content/public/browser/keyboard_event_processing_result.h
+++ b/chromium/content/public/browser/keyboard_event_processing_result.h
@@ -11,9 +11,6 @@ enum class KeyboardEventProcessingResult {
// The event was handled.
HANDLED,
- // The event was handled, and we want to be notified of the keyup event too.
- HANDLED_WANTS_KEY_UP,
-
#if defined(USE_AURA)
// The event was handled, but don't update the underlying event. A value
// HANDLED results in calling ui::Event::SetHandled(), where as this does not.
diff --git a/chromium/content/public/browser/manifest_icon_selector.h b/chromium/content/public/browser/manifest_icon_selector.h
deleted file mode 100644
index e535ec07f18..00000000000
--- a/chromium/content/public/browser/manifest_icon_selector.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_BROWSER_MANIFEST_ICON_SELECTOR_H_
-#define CONTENT_PUBLIC_BROWSER_MANIFEST_ICON_SELECTOR_H_
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "third_party/blink/public/common/manifest/manifest.h"
-#include "url/gurl.h"
-
-namespace content {
-
-// Selects the square icon with the supported image MIME types and the specified
-// icon purpose that most closely matches the size constraints.
-// This follows very basic heuristics -- improvements are welcome.
-class CONTENT_EXPORT ManifestIconSelector {
- public:
- // Runs the algorithm to find the best matching icon in the icons listed in
- // the Manifest. Size is defined in pixels.
- //
- // Any icon returned will be close as possible to |ideal_icon_size_in_px|
- // with a size not less than |minimum_icon_size_in_px|. Additionally, it must
- // be square, have supported image MIME types, and have icon purpose
- // |purpose|.
- //
- // Returns the icon url if a suitable icon is found. An empty URL otherwise.
- static GURL FindBestMatchingIcon(
- const std::vector<blink::Manifest::Icon>& icons,
- int ideal_icon_size_in_px,
- int minimum_icon_size_in_px,
- blink::Manifest::Icon::IconPurpose purpose);
-
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ManifestIconSelector);
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_BROWSER_MANIFEST_ICON_SELECTOR_H_
diff --git a/chromium/content/public/browser/media_controller.h b/chromium/content/public/browser/media_controller.h
deleted file mode 100644
index 707a109e469..00000000000
--- a/chromium/content/public/browser/media_controller.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_BROWSER_MEDIA_CONTROLLER_H_
-#define CONTENT_PUBLIC_BROWSER_MEDIA_CONTROLLER_H_
-
-#include "base/time/time.h"
-
-namespace content {
-
-// High level interface that allows a controller to issue simple media commands.
-// Modeled after the media_router.mojom.MediaController interface.
-// State changes will be signaled via the MediaStatusObserver interface.
-// TODO(tguilbert): Add MediaStatusObserver interface.
-class MediaController {
- public:
- virtual ~MediaController() = default;
-
- // Starts playing the media if it is paused. Is a no-op if not supported by
- // the media or the media is already playing.
- virtual void Play() = 0;
-
- // Pauses the media if it is playing. Is a no-op if not supported by the media
- // or the media is already paused.
- virtual void Pause() = 0;
-
- // Mutes the media if |mute| is true, and unmutes it if false. Is a no-op if
- // not supported by the media.
- virtual void SetMute(bool mute) = 0;
-
- // Changes the current volume of the media, with 1 being the highest and 0
- // being the lowest/no sound. Does not change the (un)muted state of the
- // media. Is a no-op if not supported by the media.
- virtual void SetVolume(float volume) = 0;
-
- // Sets the current playback position. |time| must be less than or equal to
- // the duration of the media. Is a no-op if the media doesn't support seeking.
- virtual void Seek(base::TimeDelta time) = 0;
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_BROWSER_MEDIA_CONTROLLER_H_
diff --git a/chromium/content/public/browser/navigation_controller.cc b/chromium/content/public/browser/navigation_controller.cc
index f4423936060..31668bd14ef 100644
--- a/chromium/content/public/browser/navigation_controller.cc
+++ b/chromium/content/public/browser/navigation_controller.cc
@@ -20,9 +20,6 @@ NavigationController::LoadURLParams::LoadURLParams(const GURL& url)
post_data(nullptr),
can_load_local_resources(false),
should_replace_current_entry(false),
-#if defined(OS_ANDROID)
- intent_received_timestamp(0),
-#endif
has_user_gesture(false),
should_clear_history_list(false),
started_from_context_menu(false),
diff --git a/chromium/content/public/browser/navigation_controller.h b/chromium/content/public/browser/navigation_controller.h
index 3e4fe938dd9..03d9b48e877 100644
--- a/chromium/content/public/browser/navigation_controller.h
+++ b/chromium/content/public/browser/navigation_controller.h
@@ -94,7 +94,7 @@ class NavigationController {
};
// Creates a navigation entry and translates the virtual url to a real one.
- // This is a general call; prefer LoadURL[FromRenderer]/TransferURL below.
+ // This is a general call; prefer LoadURL[WithParams] below.
// Extra headers are separated by \n.
CONTENT_EXPORT static std::unique_ptr<NavigationEntry> CreateNavigationEntry(
const GURL& url,
@@ -143,11 +143,6 @@ class NavigationController {
// UserAgentOverrideOption definition.
UserAgentOverrideOption override_user_agent;
- // Marks the new navigation as being transferred from one RVH to another.
- // In this case the browser can recycle the old request once the new
- // renderer wants to navigate. Identifies the request ID of the old request.
- GlobalRequestID transferred_global_request_id;
-
// Used in LOAD_TYPE_DATA loads only. Used for specifying a base URL
// for pages loaded via data URLs.
GURL base_url_for_data_url;
@@ -180,13 +175,6 @@ class NavigationController {
// navigated. This is currently only used in tests.
std::string frame_name;
-#if defined(OS_ANDROID)
- // On Android, for a load triggered by an intent, the time Chrome received
- // the original intent that prompted the load (in milliseconds active time
- // since boot).
- int64_t intent_received_timestamp;
-#endif
-
// Indicates that the navigation was triggered by a user gesture.
bool has_user_gesture;
diff --git a/chromium/content/public/browser/navigation_handle.h b/chromium/content/public/browser/navigation_handle.h
index 0ee6b89e56a..2bace920726 100644
--- a/chromium/content/public/browser/navigation_handle.h
+++ b/chromium/content/public/browser/navigation_handle.h
@@ -75,12 +75,19 @@ class CONTENT_EXPORT NavigationHandle {
// of the main frame. This remains constant over the navigation lifetime.
virtual bool IsParentMainFrame() = 0;
- // Whether the navigation was initated by the renderer process. Examples of
+ // Whether the navigation was initiated by the renderer process. Examples of
// renderer-initiated navigations include:
// * <a> link click
// * changing window.location.href
// * redirect via the <meta http-equiv="refresh"> tag
// * using window.history.pushState
+ //
+ // This method returns false for browser-initiated navigations, including:
+ // * any navigation initiated from the omnibox
+ // * navigations via suggestions in browser UI
+ // * navigations via browser UI: Ctrl-R, refresh/forward/back/home buttons
+ // * using window.history.forward() or window.history.back()
+ // * any other "explicit" URL navigations, e.g. bookmarks
virtual bool IsRendererInitiated() = 0;
// Returns the FrameTreeNode ID for the frame in which the navigation is
diff --git a/chromium/content/public/common/network_connection_tracker.cc b/chromium/content/public/browser/network_connection_tracker.cc
index da54535c3d3..1b1612e8c6e 100644
--- a/chromium/content/public/common/network_connection_tracker.cc
+++ b/chromium/content/public/browser/network_connection_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/public/common/network_connection_tracker.h"
+#include "content/public/browser/network_connection_tracker.h"
#include <utility>
@@ -35,30 +35,17 @@ static const int32_t kConnectionTypeInvalid = -1;
} // namespace
-NetworkConnectionTracker::NetworkConnectionTracker()
- : task_runner_(base::ThreadTaskRunnerHandle::Get()),
+NetworkConnectionTracker::NetworkConnectionTracker(
+ base::RepeatingCallback<network::mojom::NetworkService*()> callback)
+ : get_network_service_callback_(callback),
+ 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(
- network::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));
+ binding_(this) {
+ Initialize();
+ DCHECK(binding_.is_bound());
}
NetworkConnectionTracker::~NetworkConnectionTracker() {
@@ -86,7 +73,7 @@ bool NetworkConnectionTracker::GetConnectionType(
}
if (!task_runner_->RunsTasksInCurrentSequence()) {
connection_type_callbacks_.push_back(base::BindOnce(
- &OnGetConnectionType, base::ThreadTaskRunnerHandle::Get(),
+ &OnGetConnectionType, base::SequencedTaskRunnerHandle::Get(),
std::move(callback)));
} else {
connection_type_callbacks_.push_back(std::move(callback));
@@ -125,6 +112,13 @@ void NetworkConnectionTracker::RemoveNetworkConnectionObserver(
network_change_observer_list_->RemoveObserver(observer);
}
+NetworkConnectionTracker::NetworkConnectionTracker()
+ : connection_type_(kConnectionTypeInvalid),
+ network_change_observer_list_(
+ new base::ObserverListThreadSafe<NetworkConnectionObserver>(
+ base::ObserverListPolicy::EXISTING_ONLY)),
+ binding_(this) {}
+
void NetworkConnectionTracker::OnInitialConnectionType(
network::mojom::ConnectionType type) {
base::AutoLock lock(lock_);
@@ -144,4 +138,40 @@ void NetworkConnectionTracker::OnNetworkChanged(
FROM_HERE, &NetworkConnectionObserver::OnConnectionChanged, type);
}
+void NetworkConnectionTracker::Initialize() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ DCHECK(!binding_.is_bound());
+
+ network::mojom::NetworkService* network_service =
+ get_network_service_callback_.Run();
+
+ // 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));
+
+ // base::Unretained is safe as |binding_| is owned by |this|.
+ binding_.set_connection_error_handler(base::BindRepeating(
+ &NetworkConnectionTracker::HandleNetworkServicePipeBroken,
+ base::Unretained(this)));
+}
+
+void NetworkConnectionTracker::HandleNetworkServicePipeBroken() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ binding_.Close();
+ // Reset |connection_type_| to invalid, so future GetConnectionType() can be
+ // delayed after network service has restarted, and that there isn't an
+ // incorrectly cached state.
+ base::subtle::NoBarrier_Store(&connection_type_, kConnectionTypeInvalid);
+ Initialize();
+}
+
} // namespace content
diff --git a/chromium/content/public/common/network_connection_tracker.h b/chromium/content/public/browser/network_connection_tracker.h
index f14010c9775..1eb2c8eb499 100644
--- a/chromium/content/public/common/network_connection_tracker.h
+++ b/chromium/content/public/browser/network_connection_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_PUBLIC_COMMON_NETWORK_CONNECTION_TRACKER_H_
-#define CONTENT_PUBLIC_COMMON_NETWORK_CONNECTION_TRACKER_H_
+#ifndef CONTENT_PUBLIC_BROWSER_NETWORK_CONNECTION_TRACKER_H_
+#define CONTENT_PUBLIC_BROWSER_NETWORK_CONNECTION_TRACKER_H_
#include <list>
#include <memory>
@@ -13,6 +13,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/observer_list_threadsafe.h"
+#include "base/sequence_checker.h"
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/binding.h"
@@ -25,12 +26,12 @@ namespace content {
// This class subscribes to network change events from
// network::mojom::NetworkChangeManager and propogates these notifications to
// its NetworkConnectionObservers registered through
-// AddObserver()/RemoveObserver().
+// AddNetworkConnectionObserver()/RemoveNetworkConnectionObserver().
class CONTENT_EXPORT NetworkConnectionTracker
: public network::mojom::NetworkChangeManagerClient {
public:
- typedef base::OnceCallback<void(network::mojom::ConnectionType)>
- ConnectionTypeCallback;
+ using ConnectionTypeCallback =
+ base::OnceCallback<void(network::mojom::ConnectionType)>;
class CONTENT_EXPORT NetworkConnectionObserver {
public:
@@ -39,30 +40,23 @@ class CONTENT_EXPORT NetworkConnectionTracker
virtual void OnConnectionChanged(network::mojom::ConnectionType type) = 0;
protected:
- NetworkConnectionObserver() {}
virtual ~NetworkConnectionObserver() {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(NetworkConnectionObserver);
};
- NetworkConnectionTracker();
+ // Constructs a NetworkConnectionTracker. |callback| should return the network
+ // service that is in use. NetworkConnectionTracker does not need to be
+ // destroyed before the network service.
+ explicit NetworkConnectionTracker(
+ base::RepeatingCallback<network::mojom::NetworkService*()> callback);
~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(network::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.
+ // will contain the current connection type; Otherwise, returns false and
+ // does not modify |type|, 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);
@@ -79,11 +73,14 @@ class CONTENT_EXPORT NetworkConnectionTracker
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.
+ // on the same thread on which AddNetworkConnectionObserver() was called.
+ // All observers must be unregistered before |this| is destroyed.
void RemoveNetworkConnectionObserver(NetworkConnectionObserver* observer);
protected:
+ // Constructor used in testing to mock out network service.
+ NetworkConnectionTracker();
+
// NetworkChangeManagerClient implementation. Protected for testing.
void OnInitialConnectionType(network::mojom::ConnectionType type) override;
void OnNetworkChanged(network::mojom::ConnectionType type) override;
@@ -91,6 +88,24 @@ class CONTENT_EXPORT NetworkConnectionTracker
private:
FRIEND_TEST_ALL_PREFIXES(NetworkGetConnectionTest,
GetConnectionTypeOnDifferentThread);
+
+ // Starts listening for connection change 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();
+
+ // Serves as a connection error handler, and is invoked when network service
+ // restarts.
+ void HandleNetworkServicePipeBroken();
+
+ // Callback to get the current network service raw mojo pointer. This is to
+ // ensure that |this| can survive crashes and restarts of network service.
+ const base::RepeatingCallback<network::mojom::NetworkService*()>
+ get_network_service_callback_;
+
// The task runner that |this| lives on.
scoped_refptr<base::SequencedTaskRunner> task_runner_;
@@ -109,9 +124,13 @@ class CONTENT_EXPORT NetworkConnectionTracker
mojo::Binding<network::mojom::NetworkChangeManagerClient> binding_;
+ // Only the initialization and re-initialization of |this| are required to
+ // be bound to the same sequence.
+ SEQUENCE_CHECKER(sequence_checker_);
+
DISALLOW_COPY_AND_ASSIGN(NetworkConnectionTracker);
};
} // namespace content
-#endif // CONTENT_PUBLIC_COMMON_NETWORK_CONNECTION_TRACKER_H_
+#endif // CONTENT_PUBLIC_BROWSER_NETWORK_CONNECTION_TRACKER_H_
diff --git a/chromium/content/public/common/network_connection_tracker_unittest.cc b/chromium/content/public/browser/network_connection_tracker_unittest.cc
index 554d0d54484..65689197fb1 100644
--- a/chromium/content/public/common/network_connection_tracker_unittest.cc
+++ b/chromium/content/public/browser/network_connection_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/public/common/network_connection_tracker.h"
+#include "content/public/browser/network_connection_tracker.h"
#include "base/macros.h"
#include "base/run_loop.h"
@@ -127,21 +127,26 @@ class ConnectionTypeGetter {
class NetworkConnectionTrackerTest : public testing::Test {
public:
- NetworkConnectionTrackerTest() {
+ NetworkConnectionTrackerTest() {}
+
+ ~NetworkConnectionTrackerTest() override {}
+
+ void Initialize() {
network::mojom::NetworkServicePtr network_service_ptr;
network::mojom::NetworkServiceRequest network_service_request =
mojo::MakeRequest(&network_service_ptr);
network_service_ =
network::NetworkService::Create(std::move(network_service_request),
/*netlog=*/nullptr);
- tracker_ = std::make_unique<NetworkConnectionTracker>();
- tracker_->Initialize(network_service_.get());
+ tracker_ = std::make_unique<NetworkConnectionTracker>(
+ base::BindRepeating(&NetworkConnectionTrackerTest::network_service,
+ base::Unretained(this)));
observer_ = std::make_unique<TestNetworkConnectionObserver>(tracker_.get());
}
- ~NetworkConnectionTrackerTest() override {}
-
- network::NetworkService* network_service() { return network_service_.get(); }
+ network::mojom::NetworkService* network_service() {
+ return network_service_.get();
+ }
NetworkConnectionTracker* network_connection_tracker() {
return tracker_.get();
@@ -173,6 +178,7 @@ class NetworkConnectionTrackerTest : public testing::Test {
};
TEST_F(NetworkConnectionTrackerTest, ObserverNotified) {
+ Initialize();
EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_UNKNOWN,
network_connection_observer()->connection_type());
@@ -188,6 +194,7 @@ TEST_F(NetworkConnectionTrackerTest, ObserverNotified) {
}
TEST_F(NetworkConnectionTrackerTest, UnregisteredObserverNotNotified) {
+ Initialize();
auto network_connection_observer2 =
std::make_unique<TestNetworkConnectionObserver>(
network_connection_tracker());
@@ -217,18 +224,12 @@ TEST_F(NetworkConnectionTrackerTest, UnregisteredObserverNotNotified) {
TEST_F(NetworkConnectionTrackerTest, GetConnectionType) {
SetConnectionType(net::NetworkChangeNotifier::ConnectionType::CONNECTION_3G);
- // Creates a new NetworkService so it initializes a NetworkChangeManager
+ // Creates a NetworkService now so it initializes a NetworkChangeManager
// with initial connection type as CONNECTION_3G.
- network::mojom::NetworkServicePtr network_service_ptr;
- network::mojom::NetworkServiceRequest network_service_request =
- mojo::MakeRequest(&network_service_ptr);
- std::unique_ptr<network::NetworkService> network_service =
- network::NetworkService::Create(std::move(network_service_request),
- nullptr);
- NetworkConnectionTracker tracker;
- tracker.Initialize(network_service_ptr.get());
-
- ConnectionTypeGetter getter1(&tracker), getter2(&tracker);
+ Initialize();
+
+ ConnectionTypeGetter getter1(network_connection_tracker());
+ ConnectionTypeGetter getter2(network_connection_tracker());
// These two GetConnectionType() will finish asynchonously because network
// service is not yet set up.
EXPECT_FALSE(getter1.GetConnectionType());
@@ -241,19 +242,43 @@ TEST_F(NetworkConnectionTrackerTest, GetConnectionType) {
/*expected_connection_type=*/network::mojom::ConnectionType::
CONNECTION_3G);
- ConnectionTypeGetter getter3(&tracker);
+ ConnectionTypeGetter getter3(network_connection_tracker());
// This GetConnectionType() should finish synchronously.
EXPECT_TRUE(getter3.GetConnectionType());
EXPECT_EQ(network::mojom::ConnectionType::CONNECTION_3G,
getter3.connection_type());
}
+// Tests that GetConnectionType returns false and doesn't modify its |type|
+// parameter when the connection type is unavailable.
+TEST_F(NetworkConnectionTrackerTest, GetConnectionTypeUnavailable) {
+ // Returns a dummy network service that has not been initialized.
+ network::mojom::NetworkServicePtr* network_service_ptr =
+ new network::mojom::NetworkServicePtr;
+
+ network::mojom::NetworkServiceRequest request =
+ mojo::MakeRequest(network_service_ptr);
+ base::RepeatingCallback<network::mojom::NetworkService*()> callback =
+ base::BindRepeating(
+ [](network::mojom::NetworkService* service) { return service; },
+ base::Unretained(network_service_ptr->get()));
+
+ auto tracker = std::make_unique<NetworkConnectionTracker>(callback);
+ auto type = network::mojom::ConnectionType::CONNECTION_3G;
+ bool sync = tracker->GetConnectionType(&type, base::DoNothing());
+
+ EXPECT_FALSE(sync);
+ EXPECT_EQ(type, network::mojom::ConnectionType::CONNECTION_3G);
+ delete network_service_ptr;
+}
+
// Tests GetConnectionType() on a different thread.
class NetworkGetConnectionTest : public NetworkConnectionTrackerTest {
public:
NetworkGetConnectionTest()
: getter_thread_("NetworkGetConnectionTestThread") {
getter_thread_.Start();
+ Initialize();
}
~NetworkGetConnectionTest() override {}
diff --git a/chromium/content/public/browser/notification_database_data.cc b/chromium/content/public/browser/notification_database_data.cc
index b942ed93bd9..a623afec6d6 100644
--- a/chromium/content/public/browser/notification_database_data.cc
+++ b/chromium/content/public/browser/notification_database_data.cc
@@ -2,11 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/time/time.h"
#include "content/public/browser/notification_database_data.h"
namespace content {
-NotificationDatabaseData::NotificationDatabaseData() = default;
+NotificationDatabaseData::NotificationDatabaseData()
+ : creation_time_millis(base::Time::Now()) {}
NotificationDatabaseData::NotificationDatabaseData(
const NotificationDatabaseData& other) = default;
diff --git a/chromium/content/public/browser/notification_database_data.h b/chromium/content/public/browser/notification_database_data.h
index 8d1298f0eb1..0f8744da64f 100644
--- a/chromium/content/public/browser/notification_database_data.h
+++ b/chromium/content/public/browser/notification_database_data.h
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <string>
+#include "base/optional.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
#include "content/public/common/platform_notification_data.h"
@@ -69,14 +70,14 @@ struct CONTENT_EXPORT NotificationDatabaseData {
// Amount of time, in ms, between when the notification is shown and the
// first click.
- base::TimeDelta time_until_first_click_millis;
+ base::Optional<base::TimeDelta> time_until_first_click_millis;
// Amount of time, in ms, between when the notification is shown and the
// last click.
- base::TimeDelta time_until_last_click_millis;
+ base::Optional<base::TimeDelta> time_until_last_click_millis;
// Amount of time, in ms, between when the notification is shown and closed.
- base::TimeDelta time_until_close_millis;
+ base::Optional<base::TimeDelta> time_until_close_millis;
// Why the notification was closed.
ClosedReason closed_reason = ClosedReason::UNKNOWN;
diff --git a/chromium/content/public/browser/notification_event_dispatcher.h b/chromium/content/public/browser/notification_event_dispatcher.h
index 2d0b88d1902..57afa43cb7a 100644
--- a/chromium/content/public/browser/notification_event_dispatcher.h
+++ b/chromium/content/public/browser/notification_event_dispatcher.h
@@ -26,6 +26,7 @@ class CONTENT_EXPORT NotificationEventDispatcher {
public:
static NotificationEventDispatcher* GetInstance();
+ using NotificationClickEventCallback = base::OnceCallback<void(bool)>;
using NotificationDispatchCompleteCallback =
base::OnceCallback<void(PersistentNotificationStatus)>;
@@ -59,7 +60,8 @@ class CONTENT_EXPORT NotificationEventDispatcher {
virtual void DispatchNonPersistentShowEvent(
const std::string& notification_id) = 0;
virtual void DispatchNonPersistentClickEvent(
- const std::string& notification_id) = 0;
+ const std::string& notification_id,
+ NotificationClickEventCallback callback) = 0;
virtual void DispatchNonPersistentCloseEvent(
const std::string& notification_id,
base::OnceClosure completed_closure) = 0;
diff --git a/chromium/content/public/browser/notification_registrar.cc b/chromium/content/public/browser/notification_registrar.cc
index 189008957cb..5fed6a27595 100644
--- a/chromium/content/public/browser/notification_registrar.cc
+++ b/chromium/content/public/browser/notification_registrar.cc
@@ -9,6 +9,7 @@
#include <algorithm>
#include "base/logging.h"
+#include "base/stl_util.h"
#include "content/browser/notification_service_impl.h"
namespace content {
@@ -62,8 +63,8 @@ void NotificationRegistrar::Remove(NotificationObserver* observer,
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Record record = { observer, type, source };
- RecordVector::iterator found = std::find(
- registered_.begin(), registered_.end(), record);
+ RecordVector::iterator found =
+ std::find(registered_.begin(), registered_.end(), record);
DCHECK(found != registered_.end());
registered_.erase(found);
@@ -109,8 +110,7 @@ bool NotificationRegistrar::IsRegistered(NotificationObserver* observer,
const NotificationSource& source) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Record record = { observer, type, source };
- return std::find(registered_.begin(), registered_.end(), record) !=
- registered_.end();
+ return base::ContainsValue(registered_, record);
}
} // namespace content
diff --git a/chromium/content/public/browser/overlay_window.h b/chromium/content/public/browser/overlay_window.h
index 553fc063922..8f04e7e4e63 100644
--- a/chromium/content/public/browser/overlay_window.h
+++ b/chromium/content/public/browser/overlay_window.h
@@ -27,6 +27,12 @@ class PictureInPictureWindowController;
// browser windows.
class OverlayWindow {
public:
+ enum PlaybackState {
+ kPlaying = 0,
+ kPaused,
+ kNoVideo,
+ };
+
OverlayWindow() = default;
virtual ~OverlayWindow() = default;
@@ -45,16 +51,14 @@ class OverlayWindow {
// Retrieves the window's current bounds, including its window.
virtual gfx::Rect GetBounds() const = 0;
virtual void UpdateVideoSize(const gfx::Size& natural_size) = 0;
+ virtual void SetPlaybackState(PlaybackState playback_state) = 0;
- // Retrieve the ui::Layers corresponding to the video and controls.
+ // Retrieves the ui::Layers corresponding to the window and video.
+ virtual ui::Layer* GetWindowBackgroundLayer() = 0;
virtual ui::Layer* GetVideoLayer() = 0;
- virtual ui::Layer* GetControlsBackgroundLayer() = 0;
- virtual ui::Layer* GetCloseControlsLayer() = 0;
- virtual ui::Layer* GetPlayPauseControlsLayer() = 0;
- // Retrieves the bounds of the media controls.
- virtual gfx::Rect GetCloseControlsBounds() = 0;
- virtual gfx::Rect GetPlayPauseControlsBounds() = 0;
+ // Retrieves the bounds of the video.
+ virtual gfx::Rect GetVideoBounds() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(OverlayWindow);
diff --git a/chromium/content/public/browser/permission_controller.h b/chromium/content/public/browser/permission_controller.h
new file mode 100644
index 00000000000..de585e5a8e1
--- /dev/null
+++ b/chromium/content/public/browser/permission_controller.h
@@ -0,0 +1,51 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_H_
+#define CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_H_
+
+#include "base/supports_user_data.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/permission_type.h"
+#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
+
+class GURL;
+
+namespace content {
+class RenderFrameHost;
+
+// This class allows the content layer to manipulate permissions. It's behavior
+// is defined by the embedder via PermissionControllerDelegate implementation.
+class CONTENT_EXPORT PermissionController
+ : public base::SupportsUserData::Data {
+ public:
+ // Constant retured when registering and subscribing if
+ // cancelling/unsubscribing at a later stage would have no effect.
+ static const int kNoPendingOperation = -1;
+
+ ~PermissionController() override{};
+
+ // Returns the permission status of a given requesting_origin/embedding_origin
+ // tuple. This is not taking a RenderFrameHost because the call might happen
+ // outside of a frame context. Prefer GetPermissionStatusForFrame (below)
+ // whenever possible.
+ virtual blink::mojom::PermissionStatus GetPermissionStatus(
+ PermissionType permission,
+ const GURL& requesting_origin,
+ const GURL& embedding_origin) = 0;
+
+ // Returns the permission status for a given frame. Use this over
+ // GetPermissionStatus whenever possible.
+ // TODO(raymes): Currently we still pass the |requesting_origin| as a separate
+ // parameter because we can't yet guarantee that it matches the last committed
+ // origin of the RenderFrameHost. See https://crbug.com/698985.
+ virtual blink::mojom::PermissionStatus GetPermissionStatusForFrame(
+ PermissionType permission,
+ RenderFrameHost* render_frame_host,
+ const GURL& requesting_origin) = 0;
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_H_
diff --git a/chromium/content/public/browser/permission_manager.h b/chromium/content/public/browser/permission_controller_delegate.h
index f96a3ca325a..2a81ed3d815 100644
--- a/chromium/content/public/browser/permission_manager.h
+++ b/chromium/content/public/browser/permission_controller_delegate.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_PERMISSION_MANAGER_H_
-#define CONTENT_PUBLIC_BROWSER_PERMISSION_MANAGER_H_
+#ifndef CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_DELEGATE_H_
+#define CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_DELEGATE_H_
#include "content/common/content_export.h"
#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
@@ -14,16 +14,9 @@ namespace content {
enum class PermissionType;
class RenderFrameHost;
-// This class allows the content layer to manipulate permissions. It has to be
-// implemented by the embedder which ultimately handles the permission
-// management for the content layer.
-class CONTENT_EXPORT PermissionManager {
+class CONTENT_EXPORT PermissionControllerDelegate {
public:
- // Constant retured when registering and subscribing if
- // cancelling/unsubscribing at a later stage would have no effect.
- static const int kNoPendingOperation = -1;
-
- virtual ~PermissionManager() = default;
+ virtual ~PermissionControllerDelegate() = default;
// Requests a permission on behalf of a frame identified by
// render_frame_host.
@@ -103,4 +96,4 @@ class CONTENT_EXPORT PermissionManager {
} // namespace content
-#endif // CONTENT_PUBLIC_BROWSER_PERMISSION_MANAGER_H_
+#endif // CONTENT_PUBLIC_BROWSER_PERMISSION_CONTROLLER_DELEGATE_H_
diff --git a/chromium/content/public/browser/picture_in_picture_window_controller.h b/chromium/content/public/browser/picture_in_picture_window_controller.h
index a6292fa8e29..6df6f227d86 100644
--- a/chromium/content/public/browser/picture_in_picture_window_controller.h
+++ b/chromium/content/public/browser/picture_in_picture_window_controller.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_PUBLIC_BROWSER_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_
#define CONTENT_PUBLIC_BROWSER_PICTURE_IN_PICTURE_WINDOW_CONTROLLER_H_
+#include <string>
#include "content/common/content_export.h"
namespace gfx {
@@ -37,13 +38,23 @@ class PictureInPictureWindowController {
// Returns the size of the window in pixels.
virtual gfx::Size Show() = 0;
- virtual void Close() = 0;
+ // Called to notify the controller that the window was requested to be closed
+ // by the user or the content.
+ virtual void Close(bool should_pause_video) = 0;
+
+ // Called by the window implementation to notify the controller that the
+ // window was requested to be closed and destroyed by the system.
+ virtual void OnWindowDestroyed() = 0;
+
+ virtual void ClickCustomControl(const std::string& control_id) = 0;
virtual void EmbedSurface(const viz::SurfaceId& surface_id,
const gfx::Size& natural_size) = 0;
virtual OverlayWindow* GetWindowForTesting() = 0;
virtual void UpdateLayerBounds() = 0;
virtual bool IsPlayerActive() = 0;
virtual WebContents* GetInitiatorWebContents() = 0;
+ virtual void UpdatePlaybackState(bool is_playing,
+ bool reached_end_of_stream) = 0;
// Commands.
// Returns true if the player is active (i.e. currently playing) after this
diff --git a/chromium/content/public/browser/platform_notification_context.h b/chromium/content/public/browser/platform_notification_context.h
index 71da1d11c7a..973fbeafe24 100644
--- a/chromium/content/public/browser/platform_notification_context.h
+++ b/chromium/content/public/browser/platform_notification_context.h
@@ -38,12 +38,31 @@ class PlatformNotificationContext
using DeleteResultCallback = base::Callback<void(bool /* success */)>;
+ // Reasons for updating a notification, triggering a read.
+ enum class Interaction {
+ // No interaction was taken with the notification.
+ NONE,
+
+ // An action button in the notification was clicked.
+ ACTION_BUTTON_CLICKED,
+
+ // The notification itself was clicked.
+ CLICKED,
+
+ // The notification was closed.
+ CLOSED
+ };
+
// Reads the data associated with |notification_id| belonging to |origin|
// from the database. |callback| will be invoked with the success status
// and a reference to the notification database data when completed.
- virtual void ReadNotificationData(const std::string& notification_id,
- const GURL& origin,
- const ReadResultCallback& callback) = 0;
+ // |interaction| is passed in for UKM logging purposes and does not
+ // otherwise affect the read.
+ virtual void ReadNotificationDataAndRecordInteraction(
+ const std::string& notification_id,
+ const GURL& origin,
+ Interaction interaction,
+ const ReadResultCallback& callback) = 0;
// Reads all data associated with |service_worker_registration_id| belonging
// to |origin| from the database. |callback| will be invoked with the success
@@ -58,6 +77,7 @@ class PlatformNotificationContext
// the notification id when written successfully. The notification ID field
// for |database_data| will be generated, and thus must be empty.
virtual void WriteNotificationData(
+ int64_t persistent_notification_id,
const GURL& origin,
const NotificationDatabaseData& database_data,
const WriteResultCallback& callback) = 0;
diff --git a/chromium/content/public/browser/platform_notification_service.h b/chromium/content/public/browser/platform_notification_service.h
index 53fc4eb4393..228fc30240c 100644
--- a/chromium/content/public/browser/platform_notification_service.h
+++ b/chromium/content/public/browser/platform_notification_service.h
@@ -23,7 +23,6 @@ namespace content {
class BrowserContext;
struct NotificationResources;
struct PlatformNotificationData;
-class ResourceContext;
// The service using which notifications can be presented to the user. There
// should be a unique instance of the PlatformNotificationService depending
@@ -36,23 +35,6 @@ class CONTENT_EXPORT PlatformNotificationService {
base::Callback<void(std::unique_ptr<std::set<std::string>>,
bool /* supports synchronization */)>;
- // Checks if |origin| has permission to display Web Notifications.
- // This method must only be called on the UI thread.
- virtual blink::mojom::PermissionStatus CheckPermissionOnUIThread(
- BrowserContext* browser_context,
- const GURL& origin,
- int render_process_id) = 0;
-
- // Checks if |origin| has permission to display Web Notifications. This method
- // exists to serve the synchronous IPC required by the Notification.permission
- // JavaScript getter, and should not be used for other purposes. See
- // https://crbug.com/446497 for the plan to deprecate this method.
- // This method must only be called on the IO thread.
- virtual blink::mojom::PermissionStatus CheckPermissionOnIOThread(
- ResourceContext* resource_context,
- const GURL& origin,
- int render_process_id) = 0;
-
// Displays the notification described in |notification_data| to the user.
// This method must be called on the UI thread.
virtual void DisplayNotification(
@@ -88,6 +70,11 @@ class CONTENT_EXPORT PlatformNotificationService {
virtual void GetDisplayedNotifications(
BrowserContext* browser_context,
const DisplayedNotificationsCallback& callback) = 0;
+
+ // Reads the value of the next persistent notification ID from the profile and
+ // increments the value, as it is called once per notification write.
+ virtual int64_t ReadNextPersistentNotificationId(
+ BrowserContext* browser_context) = 0;
};
} // namespace content
diff --git a/chromium/content/public/browser/presentation_service_delegate.h b/chromium/content/public/browser/presentation_service_delegate.h
index 4c1b22497e1..03202644b97 100644
--- a/chromium/content/public/browser/presentation_service_delegate.h
+++ b/chromium/content/public/browser/presentation_service_delegate.h
@@ -12,8 +12,8 @@
#include "base/callback.h"
#include "content/common/content_export.h"
-#include "content/public/browser/media_controller.h"
#include "content/public/common/presentation_connection_message.h"
+#include "media/base/media_controller.h"
#include "third_party/blink/public/platform/modules/presentation/presentation.mojom.h"
namespace content {
@@ -174,7 +174,7 @@ class CONTENT_EXPORT ControllerPresentationServiceDelegate
// |render_process_id|, |render_frame_id|: ID of originating frame.
// |presentation_id|: The ID of the presentation for which we want a
// Controller.
- virtual std::unique_ptr<MediaController> GetMediaController(
+ virtual std::unique_ptr<media::MediaController> GetMediaController(
int render_process_id,
int render_frame_id,
const std::string& presentation_id) = 0;
diff --git a/chromium/content/public/browser/push_messaging_service.cc b/chromium/content/public/browser/push_messaging_service.cc
index 72225f7210a..7ade5bc90bf 100644
--- a/chromium/content/public/browser/push_messaging_service.cc
+++ b/chromium/content/public/browser/push_messaging_service.cc
@@ -18,10 +18,11 @@ namespace {
void CallStringCallbackFromIO(
const PushMessagingService::StringCallback& callback,
const std::vector<std::string>& data,
- ServiceWorkerStatusCode service_worker_status) {
+ blink::ServiceWorkerStatusCode service_worker_status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
- bool success = service_worker_status == SERVICE_WORKER_OK;
- bool not_found = service_worker_status == SERVICE_WORKER_ERROR_NOT_FOUND;
+ bool success = service_worker_status == blink::ServiceWorkerStatusCode::kOk;
+ bool not_found =
+ service_worker_status == blink::ServiceWorkerStatusCode::kErrorNotFound;
std::string result;
if (success) {
DCHECK_EQ(1u, data.size());
@@ -32,7 +33,7 @@ void CallStringCallbackFromIO(
}
void CallClosureFromIO(const base::Closure& callback,
- ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
}
diff --git a/chromium/content/public/browser/reload_type.h b/chromium/content/public/browser/reload_type.h
index 77c6e9bd1b8..d6e66c92350 100644
--- a/chromium/content/public/browser/reload_type.h
+++ b/chromium/content/public/browser/reload_type.h
@@ -19,10 +19,10 @@ enum class ReloadType {
BYPASSING_CACHE,
// Reloads the current entry using the original URL used to create it. This
// is used for cases where the user wants to refresh a page using a different
- // user agent after following a redirect.
- ORIGINAL_REQUEST_URL,
- // Reloads the current entry with previews disabled.
- DISABLE_PREVIEWS
+ // user agent after following a redirect. It is also used in the case of an
+ // intervention (i.e., preview) being served on the page and the user
+ // requesting the page without the intervention.
+ ORIGINAL_REQUEST_URL
};
} // namespace content
diff --git a/chromium/content/public/browser/render_frame_host.h b/chromium/content/public/browser/render_frame_host.h
index f5dced5b834..5a8553521db 100644
--- a/chromium/content/public/browser/render_frame_host.h
+++ b/chromium/content/public/browser/render_frame_host.h
@@ -15,6 +15,8 @@
#include "content/public/common/file_chooser_params.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/blink/public/platform/web_sudden_termination_disabler_type.h"
#include "ui/gfx/geometry/rect.h"
@@ -24,6 +26,7 @@
namespace blink {
class AssociatedInterfaceProvider;
+struct WebMediaPlayerAction;
namespace mojom {
enum class FeaturePolicyFeature;
} // namespace mojom
@@ -198,9 +201,8 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
// call are visible on screen. The call completes asynchronously by running
// the supplied |callback| with a value of true upon successful completion and
// false otherwise (when the frame is destroyed, detached, etc..).
- typedef base::Callback<void(bool)> VisualStateCallback;
- virtual void InsertVisualStateCallback(
- const VisualStateCallback& callback) = 0;
+ using VisualStateCallback = base::OnceCallback<void(bool)>;
+ virtual void InsertVisualStateCallback(VisualStateCallback callback) = 0;
// Copies the image at the location in viewport coordinates (not frame
// coordinates) to the clipboard. If there is no image at that location, does
@@ -301,6 +303,22 @@ class CONTENT_EXPORT RenderFrameHost : public IPC::Listener,
// RenderFrameHost.
virtual void ViewSource() = 0;
+ // Starts pausing subresource loading on this frame and returns
+ // PauseSubresourceLoadingHandle that controls the pausing behavior. As long
+ // as this handle is live, pausing will continue until an internal
+ // navigation happens in the frame.
+ virtual blink::mojom::PauseSubresourceLoadingHandlePtr
+ PauseSubresourceLoading() = 0;
+
+ // Run the given action on the media player location at the given point.
+ virtual void ExecuteMediaPlayerActionAtLocation(
+ const gfx::Point& location,
+ const blink::WebMediaPlayerAction& action) = 0;
+
+ // Creates a Network Service-backed factory from appropriate |NetworkContext|.
+ virtual void CreateNetworkServiceDefaultFactory(
+ network::mojom::URLLoaderFactoryRequest default_factory_request) = 0;
+
private:
// This interface should only be implemented inside content.
friend class RenderFrameHostImpl;
diff --git a/chromium/content/public/browser/render_frame_metadata_provider.h b/chromium/content/public/browser/render_frame_metadata_provider.h
index 6ee7068fcdd..3072f9c45ae 100644
--- a/chromium/content/public/browser/render_frame_metadata_provider.h
+++ b/chromium/content/public/browser/render_frame_metadata_provider.h
@@ -29,7 +29,9 @@ class CONTENT_EXPORT RenderFrameMetadataProvider {
public:
virtual ~Observer() {}
- virtual void OnRenderFrameMetadataChanged() = 0;
+ virtual void OnRenderFrameMetadataChangedBeforeActivation(
+ const cc::RenderFrameMetadata& metadata) = 0;
+ virtual void OnRenderFrameMetadataChangedAfterActivation() = 0;
virtual void OnRenderFrameSubmission() = 0;
// Called to indicate that the viz::LocalSurfaceId within the
diff --git a/chromium/content/public/browser/render_process_host.h b/chromium/content/public/browser/render_process_host.h
index df65dddfb96..19d9c106e87 100644
--- a/chromium/content/public/browser/render_process_host.h
+++ b/chromium/content/public/browser/render_process_host.h
@@ -22,6 +22,7 @@
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_sender.h"
#include "media/media_buildflags.h"
+#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h"
#include "ui/gfx/native_widget_types.h"
@@ -223,13 +224,11 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
// Returns true iff the Init() was called and the process hasn't died yet.
//
- // Note that even if HasConnection() returns true, then (for a short duration
- // after calling Init()) the process might not be fully spawned *yet* - e.g.
- // IsReady() might return false and GetProcess() might still return an invalid
- // process with a null handle.
- //
- // TODO(lukasza): Rename to IsInitializedAndNotDead().
- virtual bool HasConnection() const = 0;
+ // Note that even if IsInitializedAndNotDead() returns true, then (for a short
+ // duration after calling Init()) the process might not be fully spawned
+ // *yet*. For example - IsReady() might return false and GetProcess() might
+ // still return an invalid process with a null handle.
+ virtual bool IsInitializedAndNotDead() const = 0;
// Returns the renderer channel.
virtual IPC::ChannelProxy* GetChannel() = 0;
@@ -393,6 +392,16 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
virtual resource_coordinator::ProcessResourceCoordinator*
GetProcessResourceCoordinator() = 0;
+ // Create an URLLoaderFactory for this process.
+ // When NetworkService is enabled, |request| will be bound with a new
+ // URLLoaderFactory created from the storage partition's Network Context. Note
+ // that the URLLoaderFactory returned by this method does NOT support
+ // auto-reconnect after a crash of Network Service.
+ // When NetworkService is not enabled, |request| will be bound with a
+ // URLLoaderFactory which routes requests to ResourceDispatcherHost.
+ virtual void CreateURLLoaderFactory(
+ network::mojom::URLLoaderFactoryRequest request) = 0;
+
// Whether this process is locked out from ever being reused for sites other
// than the ones it currently has.
virtual void SetIsNeverSuitableForReuse() = 0;
@@ -420,6 +429,13 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
// crbug.com/738634.
virtual bool HostHasNotBeenUsed() = 0;
+ // Locks this RenderProcessHost to the 'origin' |lock_url|. This method is
+ // public so that it can be called from SiteInstanceImpl, and used by
+ // MockRenderProcessHost. It isn't meant to be called outside of content.
+ // TODO(creis): Rename LockToOrigin to LockToPrincipal. See
+ // https://crbug.com/846155.
+ virtual void LockToOrigin(const GURL& lock_url) = 0;
+
// Binds |request| to the CacheStorageDispatcherHost instance. The binding is
// sent to the IO thread. This is for internal use only, and is only exposed
// here to support MockRenderProcessHost usage in tests.
diff --git a/chromium/content/public/browser/render_process_host_observer.h b/chromium/content/public/browser/render_process_host_observer.h
index 2cfd0cc25bd..fca52416394 100644
--- a/chromium/content/public/browser/render_process_host_observer.h
+++ b/chromium/content/public/browser/render_process_host_observer.h
@@ -27,13 +27,6 @@ class CONTENT_EXPORT RenderProcessHostObserver {
// 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
- // first step in an orderly shutdown of a render process, do not expect that
- // a new render process will be hosted with this RenderProcessHost.
- virtual void RenderProcessWillExit(RenderProcessHost* host) {}
-
// This method is invoked when the process of the observed RenderProcessHost
// exits (either normally or with a crash). To determine if the process closed
// normally or crashed, examine the |status| parameter.
diff --git a/chromium/content/public/browser/render_view_host.h b/chromium/content/public/browser/render_view_host.h
index b42a63674ce..f376ec12e50 100644
--- a/chromium/content/public/browser/render_view_host.h
+++ b/chromium/content/public/browser/render_view_host.h
@@ -20,7 +20,6 @@ class FilePath;
}
namespace blink {
-struct WebMediaPlayerAction;
struct WebPluginAction;
}
@@ -98,12 +97,6 @@ class CONTENT_EXPORT RenderViewHost : public IPC::Sender {
// Instructs the RenderView to send back updates to the preferred size.
virtual void EnablePreferredSizeMode() = 0;
- // Tells the renderer to perform the given action on the media player
- // located at the given point.
- virtual void ExecuteMediaPlayerActionAtLocation(
- const gfx::Point& location,
- const blink::WebMediaPlayerAction& action) = 0;
-
// Tells the renderer to perform the given action on the plugin located at
// the given point.
virtual void ExecutePluginActionAtLocation(
diff --git a/chromium/content/public/browser/render_widget_host.h b/chromium/content/public/browser/render_widget_host.h
index f547b65c75b..29e577f2c4c 100644
--- a/chromium/content/public/browser/render_widget_host.h
+++ b/chromium/content/public/browser/render_widget_host.h
@@ -7,6 +7,9 @@
#include <stdint.h>
+#include <memory>
+#include <vector>
+
#include "base/callback.h"
#include "content/common/content_export.h"
#include "content/public/browser/native_web_keyboard_event.h"
@@ -195,14 +198,6 @@ class CONTENT_EXPORT RenderWidgetHost : public IPC::Sender {
// Returns true if the renderer is loading, false if not.
virtual bool IsLoading() const = 0;
- // Restart the active hang monitor timeout if the renderer is actively
- // waiting on a response. Clears all existing timeouts and starts with
- // a new one. This can be because the renderer has become
- // active, the tab is being hidden, or the user has chosen to wait some more
- // to give the tab a chance to become active and we don't want to display a
- // warning too soon.
- virtual void RestartHangMonitorTimeoutIfNecessary() = 0;
-
// Returns true if the renderer is considered unresponsive.
virtual bool IsCurrentlyUnresponsive() const = 0;
@@ -264,7 +259,7 @@ class CONTENT_EXPORT RenderWidgetHost : public IPC::Sender {
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::PointF& client_pt,
const gfx::PointF& screen_pt,
@@ -281,11 +276,11 @@ class CONTENT_EXPORT RenderWidgetHost : public IPC::Sender {
// either in a drop or by being cancelled.
virtual void DragSourceEndedAt(const gfx::PointF& client_pt,
const gfx::PointF& screen_pt,
- blink::WebDragOperation operation){};
+ blink::WebDragOperation operation) {}
// Notifies the renderer that we're done with the drag and drop operation.
// This allows the renderer to reset some state.
- virtual void DragSourceSystemDragEnded() {};
+ virtual void DragSourceSystemDragEnded() {}
// Filters drop data before it is passed to RenderWidgetHost.
virtual void FilterDropData(DropData* drop_data) {}
diff --git a/chromium/content/public/browser/render_widget_host_view.h b/chromium/content/public/browser/render_widget_host_view.h
index 0f2bbdcf4b2..c4b21150bbc 100644
--- a/chromium/content/public/browser/render_widget_host_view.h
+++ b/chromium/content/public/browser/render_widget_host_view.h
@@ -16,6 +16,7 @@
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/range/range.h"
namespace gfx {
class Point;
@@ -140,6 +141,12 @@ class CONTENT_EXPORT RenderWidgetHostView {
// Returns the currently selected text.
virtual base::string16 GetSelectedText() = 0;
+ // Returns the currently selected text with the text before and after it.
+ virtual base::string16 GetSurroundingText() = 0;
+
+ // Returns the range of the selection in the page.
+ virtual gfx::Range GetSelectedRange() = 0;
+
// This only returns non-null on platforms that implement touch
// selection editing (TSE), currently Aura and (soon) Android.
// TODO(wjmaclean): update this comment when OOPIF TSE is implemented on
diff --git a/chromium/content/public/browser/resource_context.h b/chromium/content/public/browser/resource_context.h
index 44b829b8b61..2e0006cd5fb 100644
--- a/chromium/content/public/browser/resource_context.h
+++ b/chromium/content/public/browser/resource_context.h
@@ -9,7 +9,6 @@
#include "content/common/content_export.h"
namespace net {
-class HostResolver;
class URLRequestContext;
}
@@ -23,7 +22,6 @@ class CONTENT_EXPORT ResourceContext : public base::SupportsUserData {
public:
ResourceContext();
~ResourceContext() override;
- virtual net::HostResolver* GetHostResolver() = 0;
// DEPRECATED: This is no longer a valid given isolated apps/sites and
// storage partitioning. This getter returns the default context associated
diff --git a/chromium/content/public/browser/resource_hints.h b/chromium/content/public/browser/resource_hints.h
index e5b293eaa3a..b02d5907d30 100644
--- a/chromium/content/public/browser/resource_hints.h
+++ b/chromium/content/public/browser/resource_hints.h
@@ -7,6 +7,7 @@
#include "content/common/content_export.h"
#include "net/base/completion_callback.h"
+#include "net/dns/host_resolver.h"
#include "net/http/http_request_info.h"
#include "url/gurl.h"
@@ -16,6 +17,9 @@ namespace net {
class URLRequestContextGetter;
}
+// TODO(https://crbug.com/565719): Resource hints aren't used nor implemented in
+// content/. Either the preconnect/preresolve code should be moved to content/
+// or this should be moved outside of content/.
namespace content {
// A Preconnect instance maintains state while a TCP/IP connection is made, and
@@ -35,9 +39,11 @@ CONTENT_EXPORT void PreconnectUrl(net::URLRequestContextGetter* getter,
// Issues a DNS request to |url|. Note that these requests are sent to the host
// resolver with priority net::IDLE.
-CONTENT_EXPORT int PreresolveUrl(net::URLRequestContextGetter* getter,
- const GURL& url,
- const net::CompletionCallback& callback);
+CONTENT_EXPORT int PreresolveUrl(
+ net::URLRequestContextGetter* getter,
+ const GURL& url,
+ const net::CompletionCallback& callback,
+ std::unique_ptr<net::HostResolver::Request>* out_req);
} // namespace content
diff --git a/chromium/content/public/browser/resource_request_info.h b/chromium/content/public/browser/resource_request_info.h
index dee1f061b99..c0e13fb0c39 100644
--- a/chromium/content/public/browser/resource_request_info.h
+++ b/chromium/content/public/browser/resource_request_info.h
@@ -29,6 +29,8 @@ class WebContents;
class ResourceRequestInfo {
public:
// Returns the ResourceRequestInfo associated with the given URLRequest.
+ CONTENT_EXPORT static ResourceRequestInfo* ForRequest(
+ net::URLRequest* request);
CONTENT_EXPORT static const ResourceRequestInfo* ForRequest(
const net::URLRequest* request);
@@ -187,8 +189,13 @@ class ResourceRequestInfo {
// If and why this request was canceled by DevTools. TODO(johannes): Remove.
virtual DevToolsStatus GetDevToolsStatus() const = 0;
- // For net::ERR_BLOCKED_BY_CLIENT and net::ERR_BLOCKED_BY_RESPONSE
- // errors, this will return the reason, otherwise base::nullopt.
+ // Used to annotate requests blocked using net::ERR_BLOCKED_BY_CLIENT and
+ // net::ERR_BLOCKED_BY_RESPONSE errors, with a ResourceRequestBlockedReason.
+ virtual void SetResourceRequestBlockedReason(
+ blink::ResourceRequestBlockedReason) = 0;
+
+ // Returns the ResourceRequestBlockedReason for this request, else
+ // base::nullopt.
virtual base::Optional<blink::ResourceRequestBlockedReason>
GetResourceRequestBlockedReason() const = 0;
diff --git a/chromium/content/public/browser/service_worker_context.h b/chromium/content/public/browser/service_worker_context.h
index 9d47e82a744..a8c957a414e 100644
--- a/chromium/content/public/browser/service_worker_context.h
+++ b/chromium/content/public/browser/service_worker_context.h
@@ -63,7 +63,7 @@ class ServiceWorkerContext {
using StartServiceWorkerForNavigationHintCallback = base::OnceCallback<void(
StartServiceWorkerForNavigationHintResult result)>;
- using StartActiveWorkerCallback =
+ using StartWorkerCallback =
base::OnceCallback<void(int process_id, int thread_id)>;
// Registers the header name which should not be passed to the ServiceWorker.
@@ -164,14 +164,14 @@ class ServiceWorkerContext {
// be called on the UI thread.
virtual void ClearAllServiceWorkersForTest(base::OnceClosure callback) = 0;
- // Starts the active worker of the registration whose scope is |pattern|.
+ // Starts the active worker of the registration whose scope is |pattern|. If
+ // there is no active worker, starts the installing worker.
// |info_callback| is passed the worker's render process id and thread id.
//
// Must be called on IO thread.
- virtual void StartActiveWorkerForPattern(
- const GURL& pattern,
- StartActiveWorkerCallback info_callback,
- base::OnceClosure failure_callback) = 0;
+ virtual void StartWorkerForPattern(const GURL& pattern,
+ StartWorkerCallback info_callback,
+ base::OnceClosure failure_callback) = 0;
// Starts the service worker for |document_url|. Called when a navigation to
// that URL is predicted to occur soon. Must be called from the UI thread. The
diff --git a/chromium/content/public/browser/site_isolation_policy.cc b/chromium/content/public/browser/site_isolation_policy.cc
index f6736b39a3b..a3df9c3912a 100644
--- a/chromium/content/public/browser/site_isolation_policy.cc
+++ b/chromium/content/public/browser/site_isolation_policy.cc
@@ -20,6 +20,8 @@
#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/resource_type.h"
+#include "services/network/public/mojom/network_service.mojom.h"
#include "url/gurl.h"
namespace content {
@@ -67,6 +69,37 @@ SiteIsolationPolicy::IsCrossSiteDocumentBlockingEnabled() {
}
// static
+void SiteIsolationPolicy::PopulateURLLoaderFactoryParamsPtrForCORB(
+ network::mojom::URLLoaderFactoryParams* params) {
+ switch (IsCrossSiteDocumentBlockingEnabled()) {
+ case SiteIsolationPolicy::XSDB_ENABLED_UNCONDITIONALLY:
+ params->is_corb_enabled = true;
+ break;
+ case SiteIsolationPolicy::XSDB_ENABLED_IF_ISOLATED: {
+ // TODO(lukasza): Take isolate-origins into account as well.
+ params->is_corb_enabled = UseDedicatedProcessesForAllSites();
+ break;
+ }
+ case SiteIsolationPolicy::XSDB_DISABLED:
+ params->is_corb_enabled = false;
+ break;
+ }
+
+ if (!params->is_corb_enabled)
+ return;
+
+ params->corb_detachable_resource_type = RESOURCE_TYPE_PREFETCH;
+ params->corb_excluded_resource_type = RESOURCE_TYPE_PLUGIN_RESOURCE;
+
+ const char* initiator_scheme_exception =
+ GetContentClient()
+ ->browser()
+ ->GetInitatorSchemeBypassingDocumentBlocking();
+ if (initiator_scheme_exception)
+ params->corb_excluded_initiator_scheme = initiator_scheme_exception;
+}
+
+// static
bool SiteIsolationPolicy::IsTopDocumentIsolationEnabled() {
// --site-per-process trumps --top-document-isolation.
if (UseDedicatedProcessesForAllSites())
diff --git a/chromium/content/public/browser/site_isolation_policy.h b/chromium/content/public/browser/site_isolation_policy.h
index e0edfc6e8ee..53d829e5fa0 100644
--- a/chromium/content/public/browser/site_isolation_policy.h
+++ b/chromium/content/public/browser/site_isolation_policy.h
@@ -13,6 +13,12 @@
#include "content/common/content_export.h"
#include "url/origin.h"
+namespace network {
+namespace mojom {
+class URLLoaderFactoryParams;
+}
+} // namespace network
+
namespace content {
// A centralized place for making policy decisions about out-of-process iframes,
@@ -36,6 +42,11 @@ class CONTENT_EXPORT SiteIsolationPolicy {
static CrossSiteDocumentBlockingEnabledState
IsCrossSiteDocumentBlockingEnabled();
+ // Populates CORB-related (Cross-Origin Read Blocking related) parts of the
+ // URLLoaderFactoryParams depending on the current Site Isolation policy.
+ static void PopulateURLLoaderFactoryParamsPtrForCORB(
+ network::mojom::URLLoaderFactoryParams* params);
+
// Returns true if third-party subframes of a page should be kept in a
// different process from the main frame.
static bool IsTopDocumentIsolationEnabled();
diff --git a/chromium/content/public/browser/speech_recognition_event_listener.h b/chromium/content/public/browser/speech_recognition_event_listener.h
index 3da7413c4b5..db7f7c0d3ce 100644
--- a/chromium/content/public/browser/speech_recognition_event_listener.h
+++ b/chromium/content/public/browser/speech_recognition_event_listener.h
@@ -6,11 +6,15 @@
#define CONTENT_PUBLIC_BROWSER_SPEECH_RECOGNITION_EVENT_LISTENER_H_
#include "content/common/content_export.h"
-#include "content/public/common/speech_recognition_result.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
-namespace content {
+namespace blink {
+namespace mojom {
+class SpeechRecognitionError;
+}
+} // namespace blink
-struct SpeechRecognitionError;
+namespace content {
// The interface to be implemented by consumers interested in receiving
// speech recognition events.
@@ -40,14 +44,16 @@ class CONTENT_EXPORT SpeechRecognitionEventListener {
virtual void OnAudioEnd(int session_id) = 0;
// Invoked when a result is retrieved.
- virtual void OnRecognitionResults(int session_id,
- const SpeechRecognitionResults& results) = 0;
+ virtual void OnRecognitionResults(
+ int session_id,
+ const std::vector<blink::mojom::SpeechRecognitionResultPtr>& results) = 0;
// Invoked if there was an error while capturing or recognizing audio.
// The recognition has already been cancelled when this call is made and
// no more events will be raised.
- virtual void OnRecognitionError(int session_id,
- const SpeechRecognitionError& error) = 0;
+ virtual void OnRecognitionError(
+ int session_id,
+ const blink::mojom::SpeechRecognitionError& error) = 0;
// Informs of a change in the captured audio level, useful if displaying
// a microphone volume indicator while recording.
diff --git a/chromium/content/public/browser/speech_recognition_manager.h b/chromium/content/public/browser/speech_recognition_manager.h
index 10f82b91beb..d6a01f81327 100644
--- a/chromium/content/public/browser/speech_recognition_manager.h
+++ b/chromium/content/public/browser/speech_recognition_manager.h
@@ -8,7 +8,7 @@
#include "base/callback.h"
#include "base/strings/string16.h"
#include "content/common/content_export.h"
-#include "content/public/common/speech_recognition_result.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
namespace content {
diff --git a/chromium/content/public/browser/speech_recognition_manager_delegate.h b/chromium/content/public/browser/speech_recognition_manager_delegate.h
index c8223d12701..9a7c68e71b4 100644
--- a/chromium/content/public/browser/speech_recognition_manager_delegate.h
+++ b/chromium/content/public/browser/speech_recognition_manager_delegate.h
@@ -8,7 +8,6 @@
#include <string>
#include "base/callback_forward.h"
-#include "content/public/common/speech_recognition_error.h"
namespace content {
diff --git a/chromium/content/public/browser/speech_recognition_session_config.h b/chromium/content/public/browser/speech_recognition_session_config.h
index 9b57ba02b31..b42c1cfae8c 100644
--- a/chromium/content/public/browser/speech_recognition_session_config.h
+++ b/chromium/content/public/browser/speech_recognition_session_config.h
@@ -14,8 +14,9 @@
#include "content/common/content_export.h"
#include "content/public/browser/speech_recognition_session_context.h"
#include "content/public/browser/speech_recognition_session_preamble.h"
-#include "content/public/common/speech_recognition_grammar.mojom.h"
#include "net/url_request/url_request_context_getter.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/blink/public/mojom/speech/speech_recognition_grammar.mojom.h"
#include "url/origin.h"
namespace content {
@@ -29,7 +30,7 @@ struct CONTENT_EXPORT SpeechRecognitionSessionConfig {
~SpeechRecognitionSessionConfig();
std::string language;
- std::vector<mojom::SpeechRecognitionGrammar> grammars;
+ std::vector<blink::mojom::SpeechRecognitionGrammar> grammars;
url::Origin origin;
bool filter_profanities;
bool continuous;
@@ -39,7 +40,11 @@ struct CONTENT_EXPORT SpeechRecognitionSessionConfig {
std::string auth_scope;
scoped_refptr<SpeechRecognitionSessionPreamble> preamble;
SpeechRecognitionSessionContext initial_context;
- scoped_refptr<net::URLRequestContextGetter> url_request_context_getter;
+ scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory;
+ // TODO(mmenke): Remove this dependency.
+ scoped_refptr<net::URLRequestContextGetter>
+ deprecated_url_request_context_getter;
+
base::WeakPtr<SpeechRecognitionEventListener> event_listener;
};
diff --git a/chromium/content/public/browser/ssl_host_state_delegate.h b/chromium/content/public/browser/ssl_host_state_delegate.h
index f22ab2114f6..9d8f1c2288b 100644
--- a/chromium/content/public/browser/ssl_host_state_delegate.h
+++ b/chromium/content/public/browser/ssl_host_state_delegate.h
@@ -44,7 +44,7 @@ class SSLHostStateDelegate {
// a specified |error| type.
virtual void AllowCert(const std::string&,
const net::X509Certificate& cert,
- net::CertStatus error) = 0;
+ int error) = 0;
// Clear allow preferences matched by |host_filter|. If the filter is null,
// clear all preferences.
@@ -56,7 +56,7 @@ class SSLHostStateDelegate {
// prior to this query, otherwise false.
virtual CertJudgment QueryPolicy(const std::string& host,
const net::X509Certificate& cert,
- net::CertStatus error,
+ int error,
bool* expired_previous_decision) = 0;
// Records that a host has run insecure content of the given |content_type|.
diff --git a/chromium/content/public/browser/startup_data.h b/chromium/content/public/browser/startup_data.h
new file mode 100644
index 00000000000..89f0c12eee1
--- /dev/null
+++ b/chromium/content/public/browser/startup_data.h
@@ -0,0 +1,18 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_STARTUP_DATA_H_
+#define CONTENT_PUBLIC_BROWSER_STARTUP_DATA_H_
+
+namespace content {
+
+// Data that //content routes through its embedder which should be handed back
+// to //content when the embedder launches it.
+struct StartupData {
+ virtual ~StartupData() = default;
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_STARTUP_DATA_H_
diff --git a/chromium/content/public/browser/storage_partition.h b/chromium/content/public/browser/storage_partition.h
index 28e2c251a11..fe4b7cc8d99 100644
--- a/chromium/content/public/browser/storage_partition.h
+++ b/chromium/content/public/browser/storage_partition.h
@@ -224,6 +224,10 @@ class CONTENT_EXPORT StoragePartition {
// Wait until all deletions tasks are finished. For test use only.
virtual void WaitForDeletionTasksForTesting() = 0;
+ // Used in tests to force the cached SharedURLLoaderFactory to be dropped, as
+ // a way to work-around https://crbug.com/857577.
+ virtual void ResetURLLoaderFactoryForBrowserProcessForTesting() {}
+
protected:
virtual ~StoragePartition() {}
};
diff --git a/chromium/content/public/browser/url_data_source.cc b/chromium/content/public/browser/url_data_source.cc
index 57579e32ab7..8161895bd95 100644
--- a/chromium/content/public/browser/url_data_source.cc
+++ b/chromium/content/public/browser/url_data_source.cc
@@ -34,10 +34,9 @@ bool URLDataSource::ShouldAddContentSecurityPolicy() const {
}
std::string URLDataSource::GetContentSecurityPolicyScriptSrc() const {
- // Specific resources require unsafe-eval in the Content Security Policy.
- // TODO(tsepez,mfoltz): Remove 'unsafe-eval' when tests have been fixed to
- // not use eval()/new Function(). http://crbug.com/525224
- return "script-src chrome://resources 'self' 'unsafe-eval';";
+ // Note: Do not add 'unsafe-eval' here. Instead override CSP for the
+ // specific pages that need it, see context http://crbug.com/525224.
+ return "script-src chrome://resources 'self';";
}
std::string URLDataSource::GetContentSecurityPolicyObjectSrc() const {
diff --git a/chromium/content/public/browser/url_data_source.h b/chromium/content/public/browser/url_data_source.h
index f6b187c558f..d6eab3dae07 100644
--- a/chromium/content/public/browser/url_data_source.h
+++ b/chromium/content/public/browser/url_data_source.h
@@ -103,8 +103,8 @@ class CONTENT_EXPORT URLDataSource {
// may be marginally better than disabling CSP outright.
// Do not override this method without first contacting the chrome security
// team.
- // By default, "script-src chrome://resources 'self' 'unsafe-eval';" is added
- // to CSP. Override to change this.
+ // By default, "script-src chrome://resources 'self';" is added to CSP.
+ // Override to change this.
virtual std::string GetContentSecurityPolicyScriptSrc() const;
// It is OK to override the following methods to a custom CSP directive
diff --git a/chromium/content/public/browser/video_capture_device_launcher.cc b/chromium/content/public/browser/video_capture_device_launcher.cc
new file mode 100644
index 00000000000..176044a145e
--- /dev/null
+++ b/chromium/content/public/browser/video_capture_device_launcher.cc
@@ -0,0 +1,19 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/video_capture_device_launcher.h"
+
+#include "content/browser/renderer_host/media/in_process_video_capture_device_launcher.h"
+
+namespace content {
+
+// static
+std::unique_ptr<VideoCaptureDeviceLauncher>
+VideoCaptureDeviceLauncher::CreateInProcessVideoCaptureDeviceLauncher(
+ scoped_refptr<base::SingleThreadTaskRunner> device_task_runner) {
+ return std::make_unique<InProcessVideoCaptureDeviceLauncher>(
+ device_task_runner, nullptr);
+}
+
+} // namespace content
diff --git a/chromium/content/public/browser/video_capture_device_launcher.h b/chromium/content/public/browser/video_capture_device_launcher.h
index aa6b849818b..d2a3f83e9ab 100644
--- a/chromium/content/public/browser/video_capture_device_launcher.h
+++ b/chromium/content/public/browser/video_capture_device_launcher.h
@@ -35,6 +35,11 @@ class CONTENT_EXPORT VideoCaptureDeviceLauncher {
virtual ~VideoCaptureDeviceLauncher() {}
+ // Creates an InProcessVideoCaptureDeviceLauncher.
+ static std::unique_ptr<VideoCaptureDeviceLauncher>
+ CreateInProcessVideoCaptureDeviceLauncher(
+ scoped_refptr<base::SingleThreadTaskRunner> device_task_runner);
+
// The passed-in |done_cb| must guarantee that the context relevant
// during the asynchronous processing stays alive.
virtual void LaunchDeviceAsync(
diff --git a/chromium/content/public/browser/web_contents.h b/chromium/content/public/browser/web_contents.h
index dee5814a247..0f82f91e437 100644
--- a/chromium/content/public/browser/web_contents.h
+++ b/chromium/content/public/browser/web_contents.h
@@ -17,6 +17,7 @@
#include "base/process/kill.h"
#include "base/strings/string16.h"
#include "base/supports_user_data.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
#include "content/public/browser/invalidate_type.h"
@@ -30,6 +31,7 @@
#include "content/public/browser/web_ui.h"
#include "content/public/common/stop_find_action.h"
#include "third_party/blink/public/common/frame/sandbox_flags.h"
+#include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/accessibility/ax_modes.h"
#include "ui/accessibility/ax_tree_update.h"
@@ -215,6 +217,12 @@ class WebContents : public PageNavigator,
// Sandboxing flags set on the new WebContents.
blink::WebSandboxFlags starting_sandbox_flags;
+
+ // Value used to set the last time the WebContents was made active, this is
+ // the value that'll be returned by GetLastActiveTime(). If this is left
+ // default initialized then the value is not passed on to the WebContents
+ // and GetLastActiveTime() will return the WebContents' creation time.
+ base::TimeTicks last_active_time;
};
// Creates a new WebContents.
@@ -464,7 +472,7 @@ class WebContents : public PageNavigator,
// Indicates whether this tab should be considered crashed. The setter will
// also notify the delegate when the flag is changed.
- virtual bool IsCrashed() const = 0;
+ virtual bool IsCrashed() const = 0;
virtual void SetIsCrashed(base::TerminationStatus status, int error_code) = 0;
virtual base::TerminationStatus GetCrashedStatus() const = 0;
@@ -477,13 +485,14 @@ class WebContents : public PageNavigator,
// change.
virtual void NotifyNavigationStateChanged(InvalidateTypes changed_flags) = 0;
- // Notifies the WebContents that audio started or stopped being audible.
- virtual void OnAudioStateChanged(bool is_audio_playing) = 0;
+ // Notifies the WebContents that audio state has changed. The contents is
+ // aware of all of its potential sources of audio and needs to poll them
+ // directly to determine its aggregate audio state.
+ virtual void OnAudioStateChanged() = 0;
// Get/Set the last time that the WebContents was made active (either when it
// was created or shown with WasShown()).
virtual base::TimeTicks GetLastActiveTime() const = 0;
- virtual void SetLastActiveTime(base::TimeTicks last_active_time) = 0;
// Invoked when the WebContents becomes shown/hidden. A hidden WebContents
// isn't painted on the screen.
@@ -530,8 +539,10 @@ class WebContents : public PageNavigator,
// Stop any pending navigation.
virtual void Stop() = 0;
- // Freeze the current page.
- virtual void FreezePage() = 0;
+ // Freezes or unfreezes the current page. A frozen page runs as few tasks as
+ // possible. This cannot be called when the page is visible. If the page is
+ // made visible after this is called, it is automatically unfrozen.
+ virtual void SetPageFrozen(bool frozen) = 0;
// Creates a new WebContents with the same state as this one. The returned
// heap-allocated pointer is owned by the caller.
@@ -544,6 +555,13 @@ class WebContents : public PageNavigator,
// reloads from the network.
virtual void ReloadLoFiImages() = 0;
+ // Attains PauseSubresourceLoadingHandles for each frame in the web contents.
+ // As long as these handles are not deleted, subresources will continue to be
+ // deferred until an internal navigation happens in the frame. Holding handles
+ // for deleted or re-navigated frames has no effect.
+ virtual std::vector<blink::mojom::PauseSubresourceLoadingHandlePtr>
+ PauseSubresourceLoading() = 0;
+
// Editing commands ----------------------------------------------------------
virtual void Undo() = 0;
@@ -692,9 +710,7 @@ class WebContents : public PageNavigator,
virtual void SystemDragEnded(RenderWidgetHost* source_rwh) = 0;
// The user initiated navigation to this page (as opposed to a navigation that
- // could have been triggered without user interaction). Used to avoid
- // uninitiated user downloads (aka carpet bombing), see DownloadRequestLimiter
- // for details.
+ // could have been triggered without user interaction).
virtual void NavigatedByUser() = 0;
// Indicates if this tab was explicitly closed by the user (control-w, close
@@ -784,13 +800,6 @@ class WebContents : public PageNavigator,
bool bypass_cache,
ImageDownloadCallback callback) = 0;
- // Returns true if the WebContents is responsible for displaying a subframe
- // in a different process from its parent page.
- // TODO(lazyboy): https://crbug.com/542893: this doesn't really belong here.
- // With site isolation, this should be removed since we can then embed iframes
- // in different processes.
- virtual bool IsSubframe() const = 0;
-
// Finds text on a page. |search_text| should not be empty.
virtual void Find(int request_id,
const base::string16& search_text,
@@ -800,9 +809,6 @@ class WebContents : public PageNavigator,
// (and what action to take regarding the selection).
virtual void StopFinding(StopFindAction action) = 0;
- // 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;
diff --git a/chromium/content/public/browser/web_contents_delegate.cc b/chromium/content/public/browser/web_contents_delegate.cc
index b6c6478c858..9d5eb003555 100644
--- a/chromium/content/public/browser/web_contents_delegate.cc
+++ b/chromium/content/public/browser/web_contents_delegate.cc
@@ -34,10 +34,6 @@ bool WebContentsDelegate::ShouldTransferNavigation(
return true;
}
-bool WebContentsDelegate::IsPopupOrPanel(const WebContents* source) const {
- return false;
-}
-
bool WebContentsDelegate::CanOverscrollContent() const { return false; }
bool WebContentsDelegate::ShouldSuppressDialogs(WebContents* source) {
@@ -165,11 +161,11 @@ content::ColorChooser* WebContentsDelegate::OpenColorChooser(
void WebContentsDelegate::RequestMediaAccessPermission(
WebContents* web_contents,
const MediaStreamRequest& request,
- const MediaResponseCallback& callback) {
+ MediaResponseCallback callback) {
LOG(ERROR) << "WebContentsDelegate::RequestMediaAccessPermission: "
<< "Not supported.";
- callback.Run(MediaStreamDevices(), MEDIA_DEVICE_NOT_SUPPORTED,
- std::unique_ptr<MediaStreamUI>());
+ std::move(callback).Run(MediaStreamDevices(), MEDIA_DEVICE_NOT_SUPPORTED,
+ std::unique_ptr<MediaStreamUI>());
}
bool WebContentsDelegate::CheckMediaAccessPermission(
@@ -188,11 +184,6 @@ std::string WebContentsDelegate::GetDefaultMediaDeviceID(
}
#if defined(OS_ANDROID)
-base::android::ScopedJavaLocalRef<jobject>
-WebContentsDelegate::GetContentVideoViewEmbedder() {
- return base::android::ScopedJavaLocalRef<jobject>();
-}
-
bool WebContentsDelegate::ShouldBlockMediaRequest(const GURL& url) {
return false;
}
diff --git a/chromium/content/public/browser/web_contents_delegate.h b/chromium/content/public/browser/web_contents_delegate.h
index 4fc457c9e41..f7e72b32ee7 100644
--- a/chromium/content/public/browser/web_contents_delegate.h
+++ b/chromium/content/public/browser/web_contents_delegate.h
@@ -149,13 +149,10 @@ class CONTENT_EXPORT WebContentsDelegate {
// it needs to do.
virtual void CloseContents(WebContents* source) {}
- // Request the delegate to move this WebContents to the specified position
- // in screen coordinates.
- virtual void MoveContents(WebContents* source, const gfx::Rect& pos) {}
-
- // Called to determine if the WebContents is contained in a popup window
- // or a panel window.
- virtual bool IsPopupOrPanel(const WebContents* source) const;
+ // Request the delegate to resize this WebContents to the specified size in
+ // screen coordinates. The embedder is free to ignore the request.
+ virtual void SetContentsBounds(WebContents* source, const gfx::Rect& bounds) {
+ }
// Notification that the target URL has changed.
virtual void UpdateTargetURL(WebContents* source,
@@ -326,13 +323,18 @@ class CONTENT_EXPORT WebContentsDelegate {
// the WebContents that is hung, and |render_widget_host| is the
// RenderWidgetHost that, while routing events to it, discovered the hang.
//
+ // |hang_monitor_restarter| can be used to restart the timer used to
+ // detect the hang. The timer is typically restarted when the renderer has
+ // become active, the tab got hidden, or the user has chosen to wait some
+ // more.
+ //
// Useful member functions on |render_widget_host|:
// - Getting the hung render process: GetProcess()
// - Querying whether the process is still hung: IsCurrentlyUnresponsive()
- // - Waiting for the process to recover on its own:
- // RestartHangMonitorTimeoutIfNecessary()
- virtual void RendererUnresponsive(WebContents* source,
- RenderWidgetHost* render_widget_host) {}
+ virtual void RendererUnresponsive(
+ WebContents* source,
+ RenderWidgetHost* render_widget_host,
+ base::RepeatingClosure hang_monitor_restarter) {}
// Notification that a process in the WebContents is no longer hung. |source|
// is the WebContents that was hung, and |render_widget_host| is the
@@ -470,10 +472,9 @@ class CONTENT_EXPORT WebContentsDelegate {
// request is denied, a call should be made to |callback| with an empty list
// of devices. |request| has the details of the request (e.g. which of audio
// and/or video devices are requested, and lists of available devices).
- virtual void RequestMediaAccessPermission(
- WebContents* web_contents,
- const MediaStreamRequest& request,
- const MediaResponseCallback& callback);
+ virtual void RequestMediaAccessPermission(WebContents* web_contents,
+ const MediaStreamRequest& request,
+ MediaResponseCallback callback);
// Checks if we have permission to access the microphone or camera. Note that
// this does not query the user. |type| must be MEDIA_DEVICE_AUDIO_CAPTURE
@@ -489,10 +490,6 @@ class CONTENT_EXPORT WebContentsDelegate {
MediaStreamType type);
#if defined(OS_ANDROID)
- // Creates a view embedding the video view.
- virtual base::android::ScopedJavaLocalRef<jobject>
- GetContentVideoViewEmbedder();
-
// Returns true if the given media should be blocked to load.
virtual bool ShouldBlockMediaRequest(const GURL& url);
diff --git a/chromium/content/public/browser/web_contents_observer.cc b/chromium/content/public/browser/web_contents_observer.cc
index ba1f2108c37..8f2128db8f3 100644
--- a/chromium/content/public/browser/web_contents_observer.cc
+++ b/chromium/content/public/browser/web_contents_observer.cc
@@ -24,6 +24,35 @@ WebContentsObserver::~WebContentsObserver() {
web_contents_->RemoveObserver(this);
}
+WebContentsObserver::MediaPlayerId::MediaPlayerId(
+ RenderFrameHost* render_frame_host,
+ int delegate_id)
+ : render_frame_host(render_frame_host), delegate_id(delegate_id) {}
+
+WebContentsObserver::MediaPlayerId
+WebContentsObserver::MediaPlayerId::createMediaPlayerIdForTests() {
+ return WebContentsObserver::MediaPlayerId();
+}
+
+bool WebContentsObserver::MediaPlayerId::operator==(
+ WebContentsObserver::MediaPlayerId const& other) const {
+ return render_frame_host == other.render_frame_host &&
+ delegate_id == other.delegate_id;
+}
+
+bool WebContentsObserver::MediaPlayerId::operator!=(
+ const MediaPlayerId& other) const {
+ return render_frame_host != other.render_frame_host ||
+ delegate_id != other.delegate_id;
+}
+
+bool WebContentsObserver::MediaPlayerId::operator<(
+ const MediaPlayerId& other) const {
+ if (render_frame_host == other.render_frame_host)
+ return delegate_id < other.delegate_id;
+ return render_frame_host < other.render_frame_host;
+}
+
WebContents* WebContentsObserver::web_contents() const {
return web_contents_;
}
diff --git a/chromium/content/public/browser/web_contents_observer.h b/chromium/content/public/browser/web_contents_observer.h
index 9a875c6bb40..35dab314009 100644
--- a/chromium/content/public/browser/web_contents_observer.h
+++ b/chromium/content/public/browser/web_contents_observer.h
@@ -25,6 +25,13 @@
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/window_open_disposition.h"
+#include "ui/gfx/range/range.h"
+
+namespace blink {
+namespace mojom {
+enum class ViewportFit;
+} // namespace mojom
+} // namespace blink
namespace gfx {
class Size;
@@ -321,9 +328,8 @@ class CONTENT_EXPORT WebContentsObserver : public IPC::Listener {
// signalled through this callback includes:
// 1) any mouse down event (blink::WebInputEvent::MouseDown);
// 2) the start of a scroll (blink::WebInputEvent::GestureScrollBegin);
- // 3) any raw key down event (blink::WebInputEvent::RawKeyDown);
- // 4) any touch event (inc. scrolls) (blink::WebInputEvent::TouchStart); and
- // 5) a browser navigation or reload (blink::WebInputEvent::Undefined).
+ // 3) any raw key down event (blink::WebInputEvent::RawKeyDown); and
+ // 4) any touch event (inc. scrolls) (blink::WebInputEvent::TouchStart).
virtual void DidGetUserInteraction(const blink::WebInputEvent::Type type) {}
// This method is invoked when a RenderViewHost of this WebContents was
@@ -353,6 +359,9 @@ class CONTENT_EXPORT WebContentsObserver : public IPC::Listener {
virtual void PepperInstanceCreated() {}
virtual void PepperInstanceDeleted() {}
+ // This method is called when the viewport fit of a WebContents changes.
+ virtual void ViewportFitChanged(blink::mojom::ViewportFit value) {}
+
// Notification that a plugin has crashed.
// |plugin_pid| is the process ID identifying the plugin process. Note that
// this ID is supplied by the renderer process, so should not be trusted.
@@ -404,6 +413,13 @@ class CONTENT_EXPORT WebContentsObserver : public IPC::Listener {
virtual void DidToggleFullscreenModeForTab(bool entered_fullscreen,
bool will_cause_resize) {}
+ // Signals that |rfh| has the current fullscreen element. This is invoked
+ // when:
+ // 1) an element in this frame enters fullscreen or in nested fullscreen, or
+ // 2) after an element in a descendant frame exits fullscreen and makes
+ // this frame own the current fullscreen element again.
+ virtual void DidAcquireFullscreen(RenderFrameHost* rfh) {}
+
// Invoked when an interstitial page is attached or detached.
virtual void DidAttachInterstitialPage() {}
virtual void DidDetachInterstitialPage() {}
@@ -422,25 +438,49 @@ class CONTENT_EXPORT WebContentsObserver : public IPC::Listener {
// from a render frame, but only when the accessibility mode has the
// ui::AXMode::kWebContents flag set.
virtual void AccessibilityEventReceived(
- const std::vector<AXEventNotificationDetails>& details) {}
+ const AXEventNotificationDetails& details) {}
virtual void AccessibilityLocationChangesReceived(
const std::vector<AXLocationChangeNotificationDetails>& details) {}
// Invoked when theme color is changed to |theme_color|.
virtual void DidChangeThemeColor(SkColor theme_color) {}
+ // Invoked when text selection is changed.
+ virtual void DidChangeTextSelection(const base::string16& text,
+ const gfx::Range& range) {}
+
// Invoked when media is playing or paused. |id| is unique per player and per
// RenderFrameHost. There may be multiple players within a RenderFrameHost
// and subsequently within a WebContents. MediaStartedPlaying() will always
// be followed by MediaStoppedPlaying() after player teardown. Observers must
// release all stored copies of |id| when MediaStoppedPlaying() is received.
+ // |has_video| and |has_audio| can both be false in cases where the media
+ // is playing muted and should be considered as inaudible for all intent and
+ // purposes.
struct MediaPlayerInfo {
MediaPlayerInfo(bool has_video, bool has_audio)
: has_video(has_video), has_audio(has_audio) {}
bool has_video;
bool has_audio;
};
- using MediaPlayerId = std::pair<RenderFrameHost*, int>;
+
+ struct CONTENT_EXPORT MediaPlayerId {
+ public:
+ static MediaPlayerId createMediaPlayerIdForTests();
+
+ MediaPlayerId(RenderFrameHost* render_frame_host, int delegate_id);
+
+ bool operator==(const MediaPlayerId& other) const;
+ bool operator!=(const MediaPlayerId& other) const;
+ bool operator<(const MediaPlayerId& other) const;
+
+ RenderFrameHost* render_frame_host = nullptr;
+ int delegate_id = 0;
+
+ private:
+ MediaPlayerId() = default;
+ };
+
virtual void MediaStartedPlaying(const MediaPlayerInfo& video_type,
const MediaPlayerId& id) {}
enum class MediaStoppedReason {
diff --git a/chromium/content/public/browser/web_contents_user_data.h b/chromium/content/public/browser/web_contents_user_data.h
index 99e114b961a..d9a776f53b3 100644
--- a/chromium/content/public/browser/web_contents_user_data.h
+++ b/chromium/content/public/browser/web_contents_user_data.h
@@ -52,26 +52,15 @@ class WebContentsUserData : public base::SupportsUserData::Data {
}
protected:
- static inline void* UserDataKey() {
- return &kLocatorKey;
+ static inline const void* UserDataKey() {
+ static const int kId = 0;
+ return &kId;
}
-
- private:
- // The user data key.
- static int kLocatorKey;
};
-// The macro to define the locator key. This key must be defined in the .cc file
-// of the tab helper otherwise different instances for different template types
-// will be collapsed by the Visual Studio linker.
-//
-// The "= 0" is surprising, but is required to effect a definition rather than
-// a declaration. Without it, this would be merely a declaration of a template
-// specialization. (C++98: 14.7.3.15; C++11: 14.7.3.13)
-//
-#define DEFINE_WEB_CONTENTS_USER_DATA_KEY(TYPE) \
-template<> \
-int content::WebContentsUserData<TYPE>::kLocatorKey = 0
+// Macro previously used to define the UserDataKey().
+// TODO(fdoray): Remove this. https://crbug.com/589840
+#define DEFINE_WEB_CONTENTS_USER_DATA_KEY(TYPE)
} // namespace content
diff --git a/chromium/content/public/browser/web_ui.h b/chromium/content/public/browser/web_ui.h
index 4d320806901..1c46a1a3ef2 100644
--- a/chromium/content/public/browser/web_ui.h
+++ b/chromium/content/public/browser/web_ui.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_PUBLIC_BROWSER_WEB_UI_H_
#define CONTENT_PUBLIC_BROWSER_WEB_UI_H_
+#include <memory>
+#include <string>
#include <vector>
#include "base/callback.h"
@@ -49,7 +51,7 @@ class CONTENT_EXPORT WebUI {
virtual WebContents* GetWebContents() const = 0;
virtual WebUIController* GetController() const = 0;
- virtual void SetController(WebUIController* controller) = 0;
+ virtual void SetController(std::unique_ptr<WebUIController> controller) = 0;
// Returns the device scale factor of the monitor that the renderer is on.
// Whenever possible, WebUI should push resources with this scale factor to
diff --git a/chromium/content/public/browser/web_ui_controller_factory.h b/chromium/content/public/browser/web_ui_controller_factory.h
index ad45ab0920f..7c8127d2f3b 100644
--- a/chromium/content/public/browser/web_ui_controller_factory.h
+++ b/chromium/content/public/browser/web_ui_controller_factory.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_PUBLIC_BROWSER_WEB_UI_CONTROLLER_FACTORY_H_
#define CONTENT_PUBLIC_BROWSER_WEB_UI_CONTROLLER_FACTORY_H_
+#include <memory>
+
#include "content/common/content_export.h"
#include "content/public/browser/web_ui.h"
@@ -28,8 +30,9 @@ class CONTENT_EXPORT WebUIControllerFactory {
// Returns a WebUIController instance for the given URL, or nullptr if the URL
// doesn't correspond to a WebUI.
- virtual WebUIController* CreateWebUIControllerForURL(
- WebUI* web_ui, const GURL& url) const = 0;
+ virtual std::unique_ptr<WebUIController> CreateWebUIControllerForURL(
+ WebUI* web_ui,
+ const GURL& url) const = 0;
// Gets the WebUI type for the given URL. This will return kNoWebUI if the
// corresponding call to CreateWebUIForURL would fail, or something
diff --git a/chromium/content/public/browser/webrtc_event_logger.h b/chromium/content/public/browser/webrtc_event_logger.h
index 84d68719a82..e7f29eae618 100644
--- a/chromium/content/public/browser/webrtc_event_logger.h
+++ b/chromium/content/public/browser/webrtc_event_logger.h
@@ -45,9 +45,8 @@ class CONTENT_EXPORT WebRtcEventLogger {
// This function must not be called for an off-the-records BrowserContext.
// Local-logging is not associated with BrowserContexts, and is allowed even
// if EnableForBrowserContext is not called. That is, even for incognito mode.
- virtual void EnableForBrowserContext(
- const BrowserContext* browser_context,
- base::OnceClosure reply = base::OnceClosure()) = 0;
+ virtual void EnableForBrowserContext(const BrowserContext* browser_context,
+ base::OnceClosure reply) = 0;
// Disables WebRTC event logging for a given BrowserContext. New remote-bound
// WebRTC event logs will no longer be created for this BrowserContext.
@@ -55,9 +54,8 @@ class CONTENT_EXPORT WebRtcEventLogger {
// therefore be careful note to call any of BrowserContext's virtual methods.
// TODO(eladalon): After changing to a Profile-centered interface, change this
// to not even receive a pointer. https://crbug.com/775415
- virtual void DisableForBrowserContext(
- const BrowserContext* browser_context,
- base::OnceClosure reply = base::OnceClosure()) = 0;
+ virtual void DisableForBrowserContext(const BrowserContext* browser_context,
+ base::OnceClosure reply) = 0;
// Call this to let the logger know when a PeerConnection was created.
// |peer_connection_id| should be a non-empty, relatively short (i.e.
@@ -71,8 +69,7 @@ class CONTENT_EXPORT WebRtcEventLogger {
virtual void PeerConnectionAdded(int render_process_id,
int lid,
const std::string& peer_connection_id,
- base::OnceCallback<void(bool)> reply =
- base::OnceCallback<void(bool)>()) = 0;
+ base::OnceCallback<void(bool)> reply) = 0;
// Call this to let the logger know when a PeerConnection was closed.
// If a reply callback is given, it will be posted back to BrowserThread::UI,
@@ -81,8 +78,7 @@ class CONTENT_EXPORT WebRtcEventLogger {
// or if it has since already been removed).
virtual void PeerConnectionRemoved(int render_process_id,
int lid,
- base::OnceCallback<void(bool)> reply =
- base::OnceCallback<void(bool)>()) = 0;
+ base::OnceCallback<void(bool)> reply) = 0;
// Call this to let the logger know when a PeerConnection was stopped.
// Closing of a peer connection is an irreversible action. Its distinction
@@ -90,8 +86,7 @@ class CONTENT_EXPORT WebRtcEventLogger {
// been garbage collected.
virtual void PeerConnectionStopped(int render_process_id,
int lid,
- base::OnceCallback<void(bool)> reply =
- base::OnceCallback<void(bool)>()) = 0;
+ base::OnceCallback<void(bool)> reply) = 0;
// Enable local logging of WebRTC events.
// Local logging is distinguished from remote logging, in that local logs are
@@ -109,15 +104,13 @@ class CONTENT_EXPORT WebRtcEventLogger {
// will get a local log file associated (specifically, we do *not* guarantee
// it would be either the oldest or the newest).
virtual void EnableLocalLogging(const base::FilePath& base_path,
- base::OnceCallback<void(bool)> reply =
- base::OnceCallback<void(bool)>()) = 0;
+ base::OnceCallback<void(bool)> reply) = 0;
// Disable local logging of WebRTC events.
// Any active local logs are stopped. Peer connections added after this call
// will not get a local log associated with them (unless local logging is
// once again enabled).
- virtual void DisableLocalLogging(base::OnceCallback<void(bool)> reply =
- base::OnceCallback<void(bool)>()) = 0;
+ virtual void DisableLocalLogging(base::OnceCallback<void(bool)> reply) = 0;
// Called when a new log fragment is sent from the renderer. This will
// potentially be written to a local WebRTC event log, a remote-bound log
@@ -131,8 +124,7 @@ class CONTENT_EXPORT WebRtcEventLogger {
int render_process_id,
int lid,
const std::string& message,
- base::OnceCallback<void(std::pair<bool, bool>)> reply =
- base::OnceCallback<void(std::pair<bool, bool>)>()) = 0;
+ base::OnceCallback<void(std::pair<bool, bool>)> reply) = 0;
protected:
friend WebRTCInternalsIntegrationBrowserTest; // (PostNullTaskForTesting)
diff --git a/chromium/content/public/child/BUILD.gn b/chromium/content/public/child/BUILD.gn
index 296eca953d4..c7f6f6a1cf3 100644
--- a/chromium/content/public/child/BUILD.gn
+++ b/chromium/content/public/child/BUILD.gn
@@ -29,7 +29,6 @@ jumbo_source_set("child_sources") {
visibility = [ "//content/*" ]
sources = [
- "child_process_sandbox_support_linux.h",
"child_thread.h",
"dwrite_font_proxy_init_win.h",
"image_decoder_utils.h",
diff --git a/chromium/content/public/child/child_process_sandbox_support_linux.h b/chromium/content/public/child/child_process_sandbox_support_linux.h
deleted file mode 100644
index 5f0577c5bab..00000000000
--- a/chromium/content/public/child/child_process_sandbox_support_linux.h
+++ /dev/null
@@ -1,33 +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_CHILD_CHILD_PROCESS_SANDBOX_SUPPORT_LINUX_H_
-#define CONTENT_PUBLIC_CHILD_CHILD_PROCESS_SANDBOX_SUPPORT_LINUX_H_
-
-#include <stddef.h>
-#include <stdint.h>
-#include <string>
-
-#include "content/common/content_export.h"
-#include "ppapi/c/trusted/ppb_browser_font_trusted.h"
-
-namespace content {
-
-// Return a read-only file descriptor to the font which best matches the given
-// properties or -1 on failure.
-// charset: specifies the language(s) that the font must cover. See
-// render_sandbox_host_linux.cc for more information.
-// fallback_family: If not set to PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT, font
-// selection should fall back to generic Windows font names like Arial and
-// Times New Roman.
-CONTENT_EXPORT int MatchFontWithFallback(
- const std::string& face,
- bool bold,
- bool italic,
- int charset,
- PP_BrowserFont_Trusted_Family fallback_family);
-
-}; // namespace content
-
-#endif // CONTENT_PUBLIC_CHILD_CHILD_PROCESS_SANDBOX_SUPPORT_LINUX_H_
diff --git a/chromium/content/public/common/BUILD.gn b/chromium/content/public/common/BUILD.gn
index f134458dd61..f0cad2ddd4c 100644
--- a/chromium/content/public/common/BUILD.gn
+++ b/chromium/content/public/common/BUILD.gn
@@ -103,6 +103,10 @@ source_set("static_features") {
]
public_configs = [ ":static_switches_defines" ]
+
+ if (is_chromeos) {
+ public_deps += [ "//media/capture/video/chromeos/public" ]
+ }
}
jumbo_source_set("common_sources") {
@@ -167,8 +171,6 @@ jumbo_source_set("common_sources") {
"menu_item.h",
"mhtml_generation_params.cc",
"mhtml_generation_params.h",
- "network_connection_tracker.cc",
- "network_connection_tracker.h",
"notification_resources.cc",
"notification_resources.h",
"origin_util.h",
@@ -210,15 +212,11 @@ jumbo_source_set("common_sources") {
"simple_connection_filter.cc",
"simple_connection_filter.h",
"socket_permission_request.h",
- "speech_recognition_error.h",
- "speech_recognition_result.cc",
- "speech_recognition_result.h",
"stop_find_action.h",
"storage_quota_params.h",
"three_d_api_types.h",
"url_constants.cc",
"url_constants.h",
- "url_fetcher.h",
"url_loader_throttle.cc",
"url_loader_throttle.h",
"url_utils.cc",
@@ -248,7 +246,6 @@ jumbo_source_set("common_sources") {
"//content/common",
"//ipc",
"//media/capture:capture_base",
- "//mojo/edk",
"//mojo/public/cpp/bindings",
"//net",
"//services/network:network_service",
@@ -300,6 +297,10 @@ jumbo_source_set("common_sources") {
deps += [ "//services/service_manager/zygote" ]
}
+ if (is_chromeos) {
+ public_deps += [ "//media/capture/video/chromeos/public" ]
+ }
+
# //content/common needs to include public headers.
allow_circular_includes_from = [
":interfaces",
@@ -355,9 +356,6 @@ mojom("interfaces") {
"push_messaging_status.mojom",
"resource_load_info.mojom",
"resource_usage_reporter.mojom",
- "speech_recognition_error.mojom",
- "speech_recognition_grammar.mojom",
- "speech_recognition_result.mojom",
"transferrable_url_loader.mojom",
"webplugininfo.mojom",
"window_container_type.mojom",
diff --git a/chromium/content/public/common/bindings_policy.h b/chromium/content/public/common/bindings_policy.h
index 0792091550a..688adba144c 100644
--- a/chromium/content/public/common/bindings_policy.h
+++ b/chromium/content/public/common/bindings_policy.h
@@ -11,21 +11,28 @@ 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 and to access Mojo system API. The Mojo
+ // data back to the browser process.
+ // These bindings should not be exposed to normal web content.
+ BINDINGS_POLICY_WEB_UI = 1 << 0,
+ // HTML-based UI bindings that allows access to Mojo system API. The Mojo
// system API provides the ability to create Mojo primitives such as message
// and data pipes, as well as connecting to named services exposed by the
- // browser. These bindings should not be exposed to normal web contents.
- BINDINGS_POLICY_WEB_UI = 1 << 0,
+ // browser.
+ // These bindings should not be exposed to normal web content.
+ BINDINGS_POLICY_MOJO_WEB_UI = 1 << 1,
// 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
// allowed unless the app has been started up with the --dom-automation
// switch.)
- BINDINGS_POLICY_DOM_AUTOMATION = 1 << 1,
+ BINDINGS_POLICY_DOM_AUTOMATION = 1 << 2,
// Bindings that allows the JS content to retrieve a variety of internal
// 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_POLICY_STATS_COLLECTION = 1 << 3,
};
+
+constexpr int kWebUIBindingsPolicyMask =
+ BINDINGS_POLICY_WEB_UI | BINDINGS_POLICY_MOJO_WEB_UI;
}
#endif // CONTENT_PUBLIC_COMMON_BINDINGS_POLICY_H_
diff --git a/chromium/content/public/common/cdm_info.h b/chromium/content/public/common/cdm_info.h
index c3c2898a714..2a695f66d04 100644
--- a/chromium/content/public/common/cdm_info.h
+++ b/chromium/content/public/common/cdm_info.h
@@ -12,26 +12,53 @@
#include "base/files/file_path.h"
#include "base/version.h"
#include "content/common/content_export.h"
+#include "media/base/content_decryption_module.h"
// TODO(crbug.com/825041): Move EncryptionMode out of decrypt_config and
// rename it to EncryptionScheme.
#include "media/base/decrypt_config.h"
#include "media/base/video_codecs.h"
+#include "media/cdm/cdm_proxy.h"
namespace content {
+// Capabilites supported by a Content Decryption Module.
+struct CONTENT_EXPORT CdmCapability {
+ CdmCapability();
+ CdmCapability(std::vector<media::VideoCodec> video_codecs,
+ base::flat_set<media::EncryptionMode> encryption_schemes,
+ base::flat_set<media::CdmSessionType> session_types,
+ base::flat_set<media::CdmProxy::Protocol> cdm_proxy_protocols);
+ CdmCapability(const CdmCapability& other);
+ ~CdmCapability();
+
+ // List of video codecs supported by the CDM (e.g. vp8). This is the set of
+ // codecs that can be decrypted and decoded by the CDM. As this is generic,
+ // not all profiles or levels of the specified codecs may actually be
+ // supported.
+ // TODO(crbug.com/796725) Find a way to include profiles and levels.
+ std::vector<media::VideoCodec> video_codecs;
+
+ // List of encryption schemes supported by the CDM (e.g. cenc).
+ base::flat_set<media::EncryptionMode> encryption_schemes;
+
+ // List of session types supported by the CDM.
+ base::flat_set<media::CdmSessionType> session_types;
+
+ // List of CdmProxy protocols supported by the CDM. These protocols should
+ // also be supported by the system to support hardware secure decryption.
+ base::flat_set<media::CdmProxy::Protocol> cdm_proxy_protocols;
+};
+
// Represents a Content Decryption Module implementation and its capabilities.
struct CONTENT_EXPORT CdmInfo {
- CdmInfo(
- const std::string& name,
- const std::string& guid,
- const base::Version& version,
- const base::FilePath& path,
- const std::string& file_system_id,
- const std::vector<media::VideoCodec>& supported_video_codecs,
- bool supports_persistent_license,
- const base::flat_set<media::EncryptionMode>& supported_encryption_schemes,
- const std::string& supported_key_system,
- bool supports_sub_key_systems);
+ CdmInfo(const std::string& name,
+ const std::string& guid,
+ const base::Version& version,
+ const base::FilePath& path,
+ const std::string& file_system_id,
+ CdmCapability capability,
+ const std::string& supported_key_system,
+ bool supports_sub_key_systems);
CdmInfo(const CdmInfo& other);
~CdmInfo();
@@ -53,19 +80,8 @@ struct CONTENT_EXPORT CdmInfo {
// digits(0-9), or "._-".
std::string file_system_id;
- // List of video codecs supported by the CDM (e.g. vp8). This is the set of
- // codecs that can be decrypted and decoded by the CDM. As this is generic,
- // not all profiles or levels of the specified codecs may actually be
- // supported.
- // TODO(crbug.com/796725) Find a way to include profiles and levels.
- std::vector<media::VideoCodec> supported_video_codecs;
-
- // Whether this CDM supports persistent licenses.
- bool supports_persistent_license;
-
- // List of encryption schemes supported by the CDM (e.g. cenc). This is the
- // set of encryption schemes that the CDM supports.
- base::flat_set<media::EncryptionMode> supported_encryption_schemes;
+ // CDM capability, e.g. video codecs, encryption schemes and session types.
+ CdmCapability capability;
// The key system supported by this CDM.
std::string supported_key_system;
diff --git a/chromium/content/public/common/common_param_traits_macros.h b/chromium/content/public/common/common_param_traits_macros.h
index e3c46fdf48c..57f03dc1ed3 100644
--- a/chromium/content/public/common/common_param_traits_macros.h
+++ b/chromium/content/public/common/common_param_traits_macros.h
@@ -26,6 +26,7 @@
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/web/web_frame_serializer_cache_control_policy.h"
#include "third_party/blink/public/web/window_features.mojom.h"
+#include "ui/accessibility/ax_event.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_relative_bounds.h"
#include "ui/accessibility/ax_tree_update.h"
@@ -198,13 +199,13 @@ IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences)
IPC_STRUCT_TRAITS_MEMBER(user_gesture_required_for_presentation)
IPC_STRUCT_TRAITS_MEMBER(text_track_margin_percentage)
IPC_STRUCT_TRAITS_MEMBER(save_previous_document_resources)
-#if defined(OS_ANDROID)
IPC_STRUCT_TRAITS_MEMBER(text_autosizing_enabled)
+ IPC_STRUCT_TRAITS_MEMBER(double_tap_to_zoom_enabled)
+#if defined(OS_ANDROID)
IPC_STRUCT_TRAITS_MEMBER(font_scale_factor)
IPC_STRUCT_TRAITS_MEMBER(device_scale_adjustment)
IPC_STRUCT_TRAITS_MEMBER(force_enable_zoom)
IPC_STRUCT_TRAITS_MEMBER(fullscreen_supported)
- IPC_STRUCT_TRAITS_MEMBER(double_tap_to_zoom_enabled)
IPC_STRUCT_TRAITS_MEMBER(media_playback_gesture_whitelist_scope)
IPC_STRUCT_TRAITS_MEMBER(default_video_poster_url)
IPC_STRUCT_TRAITS_MEMBER(support_deprecated_target_density_dpi)
@@ -240,6 +241,7 @@ IPC_STRUCT_TRAITS_BEGIN(content::WebPreferences)
IPC_STRUCT_TRAITS_MEMBER(autoplay_policy)
IPC_STRUCT_TRAITS_MEMBER(low_priority_iframes_threshold)
IPC_STRUCT_TRAITS_MEMBER(picture_in_picture_enabled)
+ IPC_STRUCT_TRAITS_MEMBER(lazy_frame_loading_distance_thresholds_px)
IPC_STRUCT_TRAITS_END()
IPC_STRUCT_TRAITS_BEGIN(blink::mojom::WindowFeatures)
@@ -281,4 +283,11 @@ IPC_STRUCT_TRAITS_BEGIN(ui::AXRelativeBounds)
IPC_STRUCT_TRAITS_MEMBER(transform)
IPC_STRUCT_TRAITS_END()
+IPC_STRUCT_TRAITS_BEGIN(ui::AXEvent)
+ IPC_STRUCT_TRAITS_MEMBER(event_type)
+ IPC_STRUCT_TRAITS_MEMBER(id)
+ IPC_STRUCT_TRAITS_MEMBER(event_from)
+ IPC_STRUCT_TRAITS_MEMBER(action_request_id)
+IPC_STRUCT_TRAITS_END()
+
#endif // CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_
diff --git a/chromium/content/public/common/content_features.cc b/chromium/content/public/common/content_features.cc
index 10d9366af33..9ac4e9d631b 100644
--- a/chromium/content/public/common/content_features.cc
+++ b/chromium/content/public/common/content_features.cc
@@ -5,6 +5,10 @@
#include "content/public/common/content_features.h"
#include "build/build_config.h"
+#if defined(OS_CHROMEOS)
+#include "media/capture/video/chromeos/public/cros_features.h"
+#endif
+
namespace features {
// All features in alphabetical order.
@@ -21,17 +25,19 @@ const base::Feature kAllowContentInitiatedDataUrlNavigations{
"AllowContentInitiatedDataUrlNavigations",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Accepts Origin-Signed HTTP Exchanges to be signed with certificates
+// that do not have CanSignHttpExchangesDraft extension.
+// TODO(https://crbug.com/862003): Remove when certificates with
+// CanSignHttpExchangesDraft extension are available from trusted CAs.
+const base::Feature kAllowSignedHTTPExchangeCertsWithoutExtension{
+ "AllowSignedHTTPExchangeCertsWithoutExtension",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Enables asm.js to WebAssembly V8 backend.
// http://asmjs.org/spec/latest/
const base::Feature kAsmJsToWebAssembly{"AsmJsToWebAssembly",
base::FEATURE_ENABLED_BY_DEFAULT};
-// 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_ENABLED_BY_DEFAULT};
-
// Creates audio output and input streams using the audio service.
const base::Feature kAudioServiceAudioStreams{
"AudioServiceAudioStreams", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -44,11 +50,20 @@ const base::Feature kAudioServiceLaunchOnStartup{
const base::Feature kAudioServiceOutOfProcess{
"AudioServiceOutOfProcess", base::FEATURE_DISABLED_BY_DEFAULT};
+// Enable incremental marking for Blink's heap managed by the Oilpan garbage
+// collector.
+const base::Feature kBlinkHeapIncrementalMarking{
+ "BlinkHeapIncrementalMarking", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Enable bloated renderer detection.
+const base::Feature kBloatedRendererDetection{
+ "BloatedRendererDetection", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Allows swipe left/right from touchpad change browser navigation. Currently
// only enabled by default on CrOS.
const base::Feature kTouchpadOverscrollHistoryNavigation {
"TouchpadOverscrollHistoryNavigation",
-#if defined(OS_CHROMEOS)
+#if defined(OS_CHROMEOS) || defined(OS_WIN)
base::FEATURE_ENABLED_BY_DEFAULT
#else
base::FEATURE_DISABLED_BY_DEFAULT
@@ -67,13 +82,13 @@ const base::Feature kBrotliEncoding{"brotli-encoding",
// Enables code caching for inline scripts.
const base::Feature kCacheInlineScriptCode{"CacheInlineScriptCode",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
// If Canvas2D Image Chromium is allowed, this feature controls whether it is
// enabled.
const base::Feature kCanvas2DImageChromium {
"Canvas2DImageChromium",
-#if defined(OS_MACOSX) || defined(OS_CHROMEOS)
+#if defined(OS_MACOSX)
base::FEATURE_ENABLED_BY_DEFAULT
#else
base::FEATURE_DISABLED_BY_DEFAULT
@@ -105,6 +120,11 @@ const base::Feature kCrossSiteDocumentBlockingAlways{
const base::Feature kCrossSiteDocumentBlockingIfIsolating{
"CrossSiteDocumentBlockingIfIsolating", base::FEATURE_ENABLED_BY_DEFAULT};
+// Enables specification of a target element in the fragment identifier
+// via a CSS selector.
+const base::Feature kCSSFragmentIdentifiers{"CSSFragmentIdentifiers",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Puts save-data header in the holdback mode. This disables sending of
// save-data header to origins, and to the renderer processes within Chrome.
const base::Feature kDataSaverHoldback{"DataSaverHoldback",
@@ -158,10 +178,6 @@ const base::Feature kHeapCompaction{"HeapCompaction",
const base::Feature kImageCaptureAPI{"ImageCaptureAPI",
base::FEATURE_ENABLED_BY_DEFAULT};
-// Whether to use GeometryMapper to optimize IntersectionObserver.
-const base::Feature kIntersectionObserverGeometryMapper{
- "IntersectionObserverGeometryMapper", base::FEATURE_DISABLED_BY_DEFAULT};
-
// Alternative to switches::kIsolateOrigins, for turning on origin isolation.
// List of origins to isolate has to be specified via
// kIsolateOriginsFieldTrialParamName.
@@ -179,6 +195,8 @@ const base::Feature kLayeredAPI{"LayeredAPI",
const base::Feature kLazyFrameLoading{"LazyFrameLoading",
base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kLazyFrameVisibleLoadTimeMetrics{
+ "LazyFrameVisibleLoadTimeMetrics", base::FEATURE_DISABLED_BY_DEFAULT};
// Enable lazy initialization of the media controls.
const base::Feature kLazyInitializeMediaControls{
@@ -233,6 +251,13 @@ const base::Feature kMojoVideoCapture {
#endif
};
+// A secondary switch used in combination with kMojoVideoCapture.
+// This is intended as a kill switch to allow disabling the service on
+// particular groups of devices even if they forcibly enable kMojoVideoCapture
+// via a command-line argument.
+const base::Feature kMojoVideoCaptureSecondary{
+ "MojoVideoCaptureSecondary", base::FEATURE_ENABLED_BY_DEFAULT};
+
// If the network service is enabled, runs it in process.
const base::Feature kNetworkServiceInProcess{"NetworkServiceInProcess",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -245,14 +270,18 @@ const base::Feature kNotificationContentImage{"NotificationContentImage",
const base::Feature kOffMainThreadWebSocket{"OffMainThreadWebSocket",
base::FEATURE_ENABLED_BY_DEFAULT};
-// Origin Manifest. See crbug.com/751996
-const base::Feature kOriginManifest{"OriginManifest",
- base::FEATURE_DISABLED_BY_DEFAULT};
+// Origin Policy. See https://crbug.com/751996
+const base::Feature kOriginPolicy{"OriginPolicy",
+ base::FEATURE_DISABLED_BY_DEFAULT};
// Origin Trials for controlling access to feature/API experiments.
const base::Feature kOriginTrials{"OriginTrials",
base::FEATURE_ENABLED_BY_DEFAULT};
+// Blink PageLifecycle feature. See https://crbug.com/775194
+const base::Feature kPageLifecycle{"PageLifecycle",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Whether document level event listeners should default 'passive' to true.
const base::Feature kPassiveDocumentEventListeners{
"PassiveDocumentEventListeners", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -346,10 +375,6 @@ const base::Feature kServiceWorkerPaymentApps{
const base::Feature kServiceWorkerScriptFullCodeCache{
"ServiceWorkerScriptFullCodeCache", base::FEATURE_ENABLED_BY_DEFAULT};
-// Establish direct connection from clients to the service worker.
-const base::Feature kServiceWorkerServicification{
- "ServiceWorkerServicification", base::FEATURE_DISABLED_BY_DEFAULT};
-
// http://tc39.github.io/ecmascript_sharedmem/shmem.html
const base::Feature kSharedArrayBuffer{"SharedArrayBuffer",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -363,15 +388,6 @@ const base::Feature kSignedHTTPExchange{"SignedHTTPExchange",
const base::Feature kSignedHTTPExchangeOriginTrial{
"SignedHTTPExchangeOriginTrial", 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.
-const base::Feature kSignInProcessIsolation{"sign-in-process-isolation",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
-// Slimming Paint V1.75. See http://crbug.com/771643.
-const base::Feature kSlimmingPaintV175{"SlimmingPaintV175",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
// Controls whether SpareRenderProcessHostManager tries to always have a warm
// spare renderer process around for the most recently requested BrowserContext.
// This feature is only consulted in site-per-process mode.
@@ -388,11 +404,6 @@ const base::Feature kStopInBackground {
#endif
};
-// 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};
-
// Stop non-timer task queues in background, on Android,
// after allowed grace time. Launch bug: https://crbug.com/822954.
const base::Feature kStopNonTimersInBackground{
@@ -408,10 +419,6 @@ const base::Feature kTimerThrottlingForHiddenFrames{
const base::Feature kTopDocumentIsolation{"top-document-isolation",
base::FEATURE_DISABLED_BY_DEFAULT};
-// Enables touchpad and wheel scroll latching.
-const base::Feature kTouchpadAndWheelScrollLatching{
- "TouchpadAndWheelScrollLatching", 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{
@@ -434,14 +441,18 @@ const base::Feature kUseVideoCaptureApiForDevToolsSnapshots{
const base::Feature kV8ContextSnapshot{"V8ContextSnapshot",
base::FEATURE_ENABLED_BY_DEFAULT};
+// Enables V8's low memory mode for subframes. This is used only
+// in conjunction with the --site-per-process feature.
+const base::Feature kV8LowMemoryModeForSubframes{
+ "V8LowMemoryModeForSubframes", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Enables to use the V8 Orinoco garbage collector.
+const base::Feature kV8Orinoco{"V8Orinoco", base::FEATURE_ENABLED_BY_DEFAULT};
+
// Enables future V8 VM features
const base::Feature kV8VmFuture{"V8VmFuture",
base::FEATURE_DISABLED_BY_DEFAULT};
-// Controls whether editing web input fields is enabled in VR.
-const base::Feature kVrWebInputEditing{"VrWebInputEditing",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
// Enable WebAssembly structured cloning.
// http://webassembly.org/
const base::Feature kWebAssembly{"WebAssembly",
@@ -455,6 +466,11 @@ const base::Feature kWebAssemblyStreaming{"WebAssemblyStreaming",
const base::Feature kWebAssemblyBaseline{"WebAssemblyBaseline",
base::FEATURE_DISABLED_BY_DEFAULT};
+// Enable WebAssembly threads.
+// https://github.com/WebAssembly/threads
+const base::Feature kWebAssemblyThreads{"WebAssemblyThreads",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Enable WebAssembly trap handler.
const base::Feature kWebAssemblyTrapHandler{"WebAssemblyTrapHandler",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -486,11 +502,6 @@ const base::Feature kWebAuth {
const base::Feature kWebAuthBle{"WebAuthenticationBle",
base::FEATURE_DISABLED_BY_DEFAULT};
-// Controls whether CTAP2 authenticators can be used via the WebAuthentication
-// API. https://w3c.github.io/webauthn
-const base::Feature kWebAuthCtap2{"WebAuthenticationCtap2",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
// Controls whether CTAP2 devices can communicate via the WebAuthentication API
// using pairingless BLE protocol.
// https://w3c.github.io/webauthn
@@ -544,11 +555,6 @@ const base::Feature kWebRtcHWVP8Encoding {
#endif
};
-// Enables HW VP8 encoding using Intel Vaapi, if available.
-// TODO(crbug.com/794608): Enable by default when we trust quality.
-const base::Feature kWebRtcVaapiHWVP8Encoding{
- "WebRtcVaapiHWVP8Encoding", base::FEATURE_DISABLED_BY_DEFAULT};
-
// Enables negotiation of experimental multiplex codec in SDP.
const base::Feature kWebRtcMultiplexCodec{"WebRTC-MultiplexCodec",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -604,12 +610,18 @@ const base::Feature kAndroidAutofillAccessibility{
// Enables developers to use the CSS safe-area-* and viewport-fit APIs which
// allow them to support devices with a display cutout.
const base::Feature kDisplayCutoutAPI{"DisplayCutoutAPI",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
// Enables hiding incorrectly-sized frames while in fullscreen.
const base::Feature kHideIncorrectlySizedFullscreenFrames{
"HideIncorrectlySizedFullscreenFrames", base::FEATURE_ENABLED_BY_DEFAULT};
+// Sets moderate binding to background renderers playing media, when enabled.
+// Else the renderer will have strong binding.
+const base::Feature kBackgroundMediaRendererHasModerateBinding{
+ "BackgroundMediaRendererHasModerateBinding",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
// Controls whether the WebNFC API is enabled:
// https://w3c.github.io/web-nfc/
const base::Feature kWebNfc{"WebNFC", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -626,6 +638,14 @@ const char kWebXrRenderPathParamValueGpuFence[] = "GpuFence";
const char kWebXrRenderPathParamValueSharedBuffer[] = "SharedBuffer";
#endif // defined(OS_ANDROID)
+#if !defined(OS_ANDROID)
+// Makes all WebUI that uses Polymer use 2.x version.
+// TODO(dpapad): Remove this once Polymer 2 migration is done,
+// https://crbug.com/738611.
+const base::Feature kWebUIPolymer2{"WebUIPolymer2",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+#endif // !defined(OS_ANDROID)
+
#if defined(OS_MACOSX)
// Enables caching of media devices for the purpose of enumerating them.
const base::Feature kDeviceMonitorMac{"DeviceMonitorMac",
@@ -638,32 +658,52 @@ const base::Feature kIOSurfaceCapturer{"IOSurfaceCapturer",
// The V2 sandbox on MacOS removes the unsandboed warmup phase and sandboxes the
// entire life of the process.
const base::Feature kMacV2Sandbox{"MacV2Sandbox",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
-// Controls whether the CTAP2 implementation should use a built-in platform
-// authenticator, where available.
-const base::Feature kWebAuthTouchId{"WebAuthenticationTouchId",
- base::FEATURE_DISABLED_BY_DEFAULT};
+ base::FEATURE_ENABLED_BY_DEFAULT};
#endif // defined(OS_MACOSX)
-bool IsVideoCaptureServiceEnabledForOutOfProcess() {
-#if defined(OS_ANDROID)
- return false;
-#else
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+// Always set the UI thread's priority to DISPLAY.
+const base::Feature kOverrideUIThreadPriority{
+ "OverrideUIThreadPriority", base::FEATURE_DISABLED_BY_DEFAULT};
+#endif // defined(OS_ANDROID) || defined(OS_CHROMEOS)
+
+enum class VideoCaptureServiceConfiguration {
+ kEnabledForOutOfProcess,
+ kEnabledForBrowserProcess,
+ kDisabled
+};
+
+bool ShouldEnableVideoCaptureService() {
return base::FeatureList::IsEnabled(features::kMojoVideoCapture) &&
- !base::FeatureList::IsEnabled(
- features::kRunVideoCaptureServiceInBrowserProcess);
-#endif
+ base::FeatureList::IsEnabled(features::kMojoVideoCaptureSecondary);
}
-bool IsVideoCaptureServiceEnabledForBrowserProcess() {
+VideoCaptureServiceConfiguration GetVideoCaptureServiceConfiguration() {
+ if (!ShouldEnableVideoCaptureService())
+ return VideoCaptureServiceConfiguration::kDisabled;
+
#if defined(OS_ANDROID)
- return base::FeatureList::IsEnabled(features::kMojoVideoCapture);
+ return VideoCaptureServiceConfiguration::kEnabledForBrowserProcess;
+#elif defined(OS_CHROMEOS)
+ return media::ShouldUseCrosCameraService()
+ ? VideoCaptureServiceConfiguration::kEnabledForBrowserProcess
+ : VideoCaptureServiceConfiguration::kEnabledForOutOfProcess;
#else
- return base::FeatureList::IsEnabled(features::kMojoVideoCapture) &&
- base::FeatureList::IsEnabled(
- features::kRunVideoCaptureServiceInBrowserProcess);
+ return base::FeatureList::IsEnabled(
+ features::kRunVideoCaptureServiceInBrowserProcess)
+ ? VideoCaptureServiceConfiguration::kEnabledForBrowserProcess
+ : VideoCaptureServiceConfiguration::kEnabledForOutOfProcess;
#endif
}
+bool IsVideoCaptureServiceEnabledForOutOfProcess() {
+ return GetVideoCaptureServiceConfiguration() ==
+ VideoCaptureServiceConfiguration::kEnabledForOutOfProcess;
+}
+
+bool IsVideoCaptureServiceEnabledForBrowserProcess() {
+ return GetVideoCaptureServiceConfiguration() ==
+ VideoCaptureServiceConfiguration::kEnabledForBrowserProcess;
+}
+
} // namespace features
diff --git a/chromium/content/public/common/content_features.h b/chromium/content/public/common/content_features.h
index d972131225d..33ff8d509de 100644
--- a/chromium/content/public/common/content_features.h
+++ b/chromium/content/public/common/content_features.h
@@ -19,11 +19,14 @@ namespace features {
CONTENT_EXPORT extern const base::Feature kAllowActivationDelegationAttr;
CONTENT_EXPORT extern const base::Feature
kAllowContentInitiatedDataUrlNavigations;
+CONTENT_EXPORT extern const base::Feature
+ kAllowSignedHTTPExchangeCertsWithoutExtension;
CONTENT_EXPORT extern const base::Feature kAsmJsToWebAssembly;
-CONTENT_EXPORT extern const base::Feature kAsyncWheelEvents;
CONTENT_EXPORT extern const base::Feature kAudioServiceAudioStreams;
CONTENT_EXPORT extern const base::Feature kAudioServiceLaunchOnStartup;
CONTENT_EXPORT extern const base::Feature kAudioServiceOutOfProcess;
+CONTENT_EXPORT extern const base::Feature kBlinkHeapIncrementalMarking;
+CONTENT_EXPORT extern const base::Feature kBloatedRendererDetection;
CONTENT_EXPORT extern const base::Feature kBlockCredentialedSubresources;
CONTENT_EXPORT extern const base::Feature kBrotliEncoding;
CONTENT_EXPORT extern const base::Feature kCacheInlineScriptCode;
@@ -33,6 +36,7 @@ CONTENT_EXPORT extern const base::Feature kCompositeOpaqueScrollers;
CONTENT_EXPORT extern const base::Feature kCompositorTouchAction;
CONTENT_EXPORT extern const base::Feature kCrossSiteDocumentBlockingAlways;
CONTENT_EXPORT extern const base::Feature kCrossSiteDocumentBlockingIfIsolating;
+CONTENT_EXPORT extern const base::Feature kCSSFragmentIdentifiers;
CONTENT_EXPORT extern const base::Feature kDataSaverHoldback;
CONTENT_EXPORT extern const base::Feature kExperimentalProductivityFeatures;
CONTENT_EXPORT extern const base::Feature kExpensiveBackgroundTimerThrottling;
@@ -45,12 +49,12 @@ CONTENT_EXPORT extern const base::Feature kGamepadVibration;
CONTENT_EXPORT extern const base::Feature kGuestViewCrossProcessFrames;
CONTENT_EXPORT extern const base::Feature kHeapCompaction;
CONTENT_EXPORT extern const base::Feature kImageCaptureAPI;
-CONTENT_EXPORT extern const base::Feature kIntersectionObserverGeometryMapper;
CONTENT_EXPORT extern const base::Feature kIsolateOrigins;
CONTENT_EXPORT extern const char kIsolateOriginsFieldTrialParamName[];
CONTENT_EXPORT extern const base::Feature kKeyboardLockAPI;
CONTENT_EXPORT extern const base::Feature kLayeredAPI;
CONTENT_EXPORT extern const base::Feature kLazyFrameLoading;
+CONTENT_EXPORT extern const base::Feature kLazyFrameVisibleLoadTimeMetrics;
CONTENT_EXPORT extern const base::Feature kLazyInitializeMediaControls;
CONTENT_EXPORT extern const base::Feature kLazyParseCSS;
CONTENT_EXPORT extern const base::Feature kLowPriorityIframes;
@@ -60,11 +64,13 @@ CONTENT_EXPORT extern const base::Feature kModuleScriptsDynamicImport;
CONTENT_EXPORT extern const base::Feature kModuleScriptsImportMetaUrl;
CONTENT_EXPORT extern const base::Feature kMojoSessionStorage;
CONTENT_EXPORT extern const base::Feature kMojoVideoCapture;
+CONTENT_EXPORT extern const base::Feature kMojoVideoCaptureSecondary;
CONTENT_EXPORT extern const base::Feature kNetworkServiceInProcess;
CONTENT_EXPORT extern const base::Feature kNotificationContentImage;
CONTENT_EXPORT extern const base::Feature kOffMainThreadWebSocket;
-CONTENT_EXPORT extern const base::Feature kOriginManifest;
+CONTENT_EXPORT extern const base::Feature kOriginPolicy;
CONTENT_EXPORT extern const base::Feature kOriginTrials;
+CONTENT_EXPORT extern const base::Feature kPageLifecycle;
CONTENT_EXPORT extern const base::Feature kPassiveDocumentEventListeners;
CONTENT_EXPORT extern const base::Feature kPassiveEventListenersDueToFling;
CONTENT_EXPORT extern const base::Feature kPdfIsolation;
@@ -85,34 +91,30 @@ CONTENT_EXPORT extern const base::Feature
CONTENT_EXPORT extern const base::Feature kSecMetadata;
CONTENT_EXPORT extern const base::Feature kServiceWorkerPaymentApps;
CONTENT_EXPORT extern const base::Feature kServiceWorkerScriptFullCodeCache;
-CONTENT_EXPORT extern const base::Feature kServiceWorkerServicification;
CONTENT_EXPORT extern const base::Feature kSharedArrayBuffer;
CONTENT_EXPORT extern const base::Feature kSignedHTTPExchange;
CONTENT_EXPORT extern const base::Feature kSignedHTTPExchangeOriginTrial;
-CONTENT_EXPORT extern const base::Feature kSignInProcessIsolation;
-CONTENT_EXPORT extern const base::Feature kSlimmingPaintV175;
CONTENT_EXPORT extern const base::Feature kSpareRendererForSitePerProcess;
CONTENT_EXPORT extern const base::Feature kStopInBackground;
-CONTENT_EXPORT extern const base::Feature kStopLoadingInBackground;
CONTENT_EXPORT extern const base::Feature kStopNonTimersInBackground;
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 kTouchpadOverscrollHistoryNavigation;
CONTENT_EXPORT extern const base::Feature kUseFeaturePolicyForPermissions;
CONTENT_EXPORT extern const base::Feature kUserActivationV2;
CONTENT_EXPORT extern const base::Feature
kUseVideoCaptureApiForDevToolsSnapshots;
CONTENT_EXPORT extern const base::Feature kV8ContextSnapshot;
+CONTENT_EXPORT extern const base::Feature kV8LowMemoryModeForSubframes;
+CONTENT_EXPORT extern const base::Feature kV8Orinoco;
CONTENT_EXPORT extern const base::Feature kV8VmFuture;
-CONTENT_EXPORT extern const base::Feature kVrWebInputEditing;
CONTENT_EXPORT extern const base::Feature kWebAssembly;
CONTENT_EXPORT extern const base::Feature kWebAssemblyStreaming;
CONTENT_EXPORT extern const base::Feature kWebAssemblyBaseline;
+CONTENT_EXPORT extern const base::Feature kWebAssemblyThreads;
CONTENT_EXPORT extern const base::Feature kWebAssemblyTrapHandler;
CONTENT_EXPORT extern const base::Feature kWebAuth;
CONTENT_EXPORT extern const base::Feature kWebAuthBle;
-CONTENT_EXPORT extern const base::Feature kWebAuthCtap2;
CONTENT_EXPORT extern const base::Feature kWebAuthCable;
CONTENT_EXPORT extern const base::Feature kWebContentsOcclusion;
CONTENT_EXPORT extern const base::Feature kWebGLImageChromium;
@@ -123,7 +125,6 @@ CONTENT_EXPORT extern const base::Feature kWebRtcAecNoiseTransparency;
CONTENT_EXPORT extern const base::Feature kWebRtcEcdsaDefault;
CONTENT_EXPORT extern const base::Feature kWebRtcHWH264Encoding;
CONTENT_EXPORT extern const base::Feature kWebRtcHWVP8Encoding;
-CONTENT_EXPORT extern const base::Feature kWebRtcVaapiHWVP8Encoding;
CONTENT_EXPORT extern const base::Feature kWebRtcMultiplexCodec;
CONTENT_EXPORT extern const base::Feature kWebRtcScreenshareSwEncoding;
CONTENT_EXPORT extern const base::Feature kWebRtcUseEchoCanceller3;
@@ -139,6 +140,8 @@ CONTENT_EXPORT extern const base::Feature kWorkStealingInScriptRunner;
#if defined(OS_ANDROID)
CONTENT_EXPORT extern const base::Feature kAndroidAutofillAccessibility;
+CONTENT_EXPORT extern const base::Feature
+ kBackgroundMediaRendererHasModerateBinding;
CONTENT_EXPORT extern const base::Feature kDisplayCutoutAPI;
CONTENT_EXPORT extern const base::Feature kHideIncorrectlySizedFullscreenFrames;
CONTENT_EXPORT extern const base::Feature kWebNfc;
@@ -149,11 +152,18 @@ CONTENT_EXPORT extern const char kWebXrRenderPathParamValueGpuFence[];
CONTENT_EXPORT extern const char kWebXrRenderPathParamValueSharedBuffer[];
#endif // defined(OS_ANDROID)
+#if !defined(OS_ANDROID)
+CONTENT_EXPORT extern const base::Feature kWebUIPolymer2;
+#endif // !defined(OS_ANDROID)
+
+#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
+CONTENT_EXPORT extern const base::Feature kOverrideUIThreadPriority;
+#endif // defined(OS_ANDROID) || defined(OS_CHROMEOS)
+
#if defined(OS_MACOSX)
CONTENT_EXPORT extern const base::Feature kDeviceMonitorMac;
CONTENT_EXPORT extern const base::Feature kIOSurfaceCapturer;
CONTENT_EXPORT extern const base::Feature kMacV2Sandbox;
-CONTENT_EXPORT extern const base::Feature kWebAuthTouchId;
#endif // defined(OS_MACOSX)
// DON'T ADD RANDOM STUFF HERE. Put it in the main section above in
diff --git a/chromium/content/public/common/content_switches.cc b/chromium/content/public/common/content_switches.cc
index aac63339ab2..19c2246a3bd 100644
--- a/chromium/content/public/common/content_switches.cc
+++ b/chromium/content/public/common/content_switches.cc
@@ -79,11 +79,6 @@ const char kDisable3DAPIs[] = "disable-3d-apis";
// Disable gpu-accelerated 2d canvas.
const char kDisableAccelerated2dCanvas[] = "disable-accelerated-2d-canvas";
-// Disable hardware acceleration of mjpeg decode for captured frame, where
-// available.
-const char kDisableAcceleratedMjpegDecode[] =
- "disable-accelerated-mjpeg-decode";
-
// Disables hardware acceleration of video decode, where available.
const char kDisableAcceleratedVideoDecode[] =
"disable-accelerated-video-decode";
@@ -333,10 +328,6 @@ const char kEnableLCDText[] = "enable-lcd-text";
const char kEnablePreferCompositingToLCDText[] =
"enable-prefer-compositing-to-lcd-text";
-// Enable work-in-progress persistent storage for the Background Fetch API.
-const char kEnableBackgroundFetchPersistence[] =
- "enable-background-fetch-persistence";
-
// Enable one or more Blink runtime-enabled features.
// Use names from runtime_enabled_features.json5, separated by commas.
// Applied before kDisableBlinkFeatures, and after other flags that change these
@@ -410,10 +401,6 @@ const char kEnableServiceBinaryLauncher[] = "enable-service-binary-launcher";
// Enables the Skia benchmarking extension
const char kEnableSkiaBenchmarking[] = "enable-skia-benchmarking";
-// Enables slimming paint phase 1.75:
-// https://www.chromium.org/blink/slimming-paint
-const char kEnableSlimmingPaintV175[] = "enable-slimming-paint-v175";
-
// Enables slimming paint phase 2: https://www.chromium.org/blink/slimming-paint
const char kEnableSlimmingPaintV2[] = "enable-slimming-paint-v2";
@@ -442,6 +429,9 @@ const char kEnableTracing[] = "enable-tracing";
// The filename to write the output of the test tracing to.
const char kEnableTracingOutput[] = "enable-tracing-output";
+// Enables unsafe WebGPU support.
+const char kEnableUnsafeWebGPU[] = "enable-unsafe-webgpu";
+
// Enable screen capturing support for MediaStream API.
const char kEnableUserMediaScreenCapturing[] =
"enable-usermedia-screen-capturing";
@@ -464,6 +454,9 @@ const char kEnableVulkan[] = "enable-vulkan";
// https://w3c.github.io/webauthn
const char kEnableWebAuthTestingAPI[] = "enable-web-authentication-testing-api";
+// Enable WebGL2 Compute context.
+const char kEnableWebGL2ComputeContext[] = "enable-webgl2-compute-context";
+
// Enables WebGL extensions not yet approved by the community.
const char kEnableWebGLDraftExtensions[] = "enable-webgl-draft-extensions";
@@ -486,10 +479,22 @@ const char kExplicitlyAllowedPorts[] = "explicitly-allowed-ports";
// shared memory segment as a string.
const char kFieldTrialHandle[] = "field-trial-handle";
+// Define an alias root directory which is replaced with the replacement string
+// in file URLs. The format is "/alias=/replacement", which would turn
+// file:///alias/some/path.html into file:///replacement/some/path.html.
+const char kFileUrlPathAlias[] = "file-url-path-alias";
+
// Always use the Skia GPU backend for drawing layer tiles. Only valid with GPU
// accelerated compositing + impl-side painting. Overrides the
// kEnableGpuRasterization flag.
-const char kForceGpuRasterization[] = "force-gpu-rasterization";
+const char kForceGpuRasterization[] = "force-gpu-rasterization";
+
+// Disables OOP rasterization. Takes precedence over the enable flag.
+const char kDisableOopRasterization[] = "disable-oop-rasterization";
+
+// Turns on out of process raster for the renderer whenever gpu raster
+// would have been used. Enables the chromium_raster_transport extension.
+const char kEnableOopRasterization[] = "enable-oop-rasterization";
// The number of multisample antialiasing samples for GPU rasterization.
// Requires MSAA support on GPU to have an effect. 0 disables MSAA.
@@ -511,6 +516,13 @@ const char kForcePresentationReceiverForTesting[] =
// overrides this if present.
const char kForceRendererAccessibility[] = "force-renderer-accessibility";
+// Sets the timeout seconds of NetworkQuietTimers in
+// FirstMeaningfulPainterDectector. Used by embedders who want to change the
+// timeout time in order to run web contents on various embedded devices and
+// changeable network bandwidths in different regions. For example, it's useful
+// when using FMP signal to dismiss a splash screen.
+const char kFMPNetworkQuietTimeout[] = "fmp-network-quiet-timeout";
+
// For development / testing only. When running content_browsertests,
// saves output of failing accessibility tests to their expectations files in
// content/test/data/accessibility/, overwriting existing file content.
@@ -944,6 +956,10 @@ const char kRendererWaitForJavaDebugger[] = "renderer-wait-for-java-debugger";
const char kEnableOSKOverscroll[] = "enable-osk-overscroll";
#endif
+// Enable the experimental Accessibility Object Model APIs in development.
+const char kEnableAccessibilityObjectModel[] =
+ "enable-accessibility-object-model";
+
// Enable the aggressive flushing of DOM Storage to minimize data loss.
const char kEnableAggressiveDOMStorageFlushing[] =
"enable-aggressive-domstorage-flushing";
@@ -1039,19 +1055,6 @@ const char kIpcDumpDirectory[] = "ipc-dump-directory";
const char kIpcFuzzerTestcase[] = "ipc-fuzzer-testcase";
#endif
-#if defined(OS_MACOSX)
-// Enable the V2 sandbox during the helper executable initialization.
-const char kEnableV2Sandbox[] = "v2-sandbox";
-
-// The command line paramter indicating that the v2 sandbox is enabled. This
-// must be different than the "v2-sandbox" flag to avoid endless re-executing.
-// The flag tells the sandbox initialization code inside Chrome that the sandbox
-// should already be enabled.
-// TODO(kerrnel): Remove this once the V2 sandbox migration is complete, as
-// processes will be assumed to run under the V2 sandbox.
-const char kV2SandboxedEnabled[] = "v2-sandbox-enabled";
-#endif // defined(OS_MACOSX)
-
// Don't dump stuff here, follow the same order as the header.
} // namespace switches
diff --git a/chromium/content/public/common/content_switches.h b/chromium/content/public/common/content_switches.h
index 990f172ac8c..2c795e814b1 100644
--- a/chromium/content/public/common/content_switches.h
+++ b/chromium/content/public/common/content_switches.h
@@ -33,7 +33,6 @@ CONTENT_EXPORT extern const char kDisable2dCanvasImageChromium[];
CONTENT_EXPORT extern const char kDisable3DAPIs[];
CONTENT_EXPORT extern const char kDisableAccelerated2dCanvas[];
CONTENT_EXPORT extern const char kDisableAcceleratedJpegDecoding[];
-CONTENT_EXPORT extern const char kDisableAcceleratedMjpegDecode[];
CONTENT_EXPORT extern const char kDisableAcceleratedVideoDecode[];
CONTENT_EXPORT extern const char kDisableAcceleratedVideoEncode[];
CONTENT_EXPORT extern const char kDisableAudioSupportForDesktopShare[];
@@ -105,12 +104,12 @@ CONTENT_EXPORT extern const char kDisableZeroCopyDxgiVideo[];
CONTENT_EXPORT extern const char kDomAutomationController[];
extern const char kDisable2dCanvasClipAntialiasing[];
CONTENT_EXPORT extern const char kDumpBlinkRuntimeCallStats[];
+CONTENT_EXPORT extern const char kEnableAccessibilityObjectModel[];
CONTENT_EXPORT extern const char kEnableAggressiveDOMStorageFlushing[];
CONTENT_EXPORT extern const char kEnableAutomation[];
CONTENT_EXPORT extern const char kEnablePreferCompositingToLCDText[];
CONTENT_EXPORT extern const char kEnableBlinkFeatures[];
CONTENT_EXPORT extern const char kEnableBlinkGenPropertyTrees[];
-CONTENT_EXPORT extern const char kEnableBackgroundFetchPersistence[];
CONTENT_EXPORT extern const char kEnableDisplayList2dCanvas[];
CONTENT_EXPORT extern const char kEnableExperimentalWebPlatformFeatures[];
CONTENT_EXPORT extern const char kEnableGpuMemoryBufferCompositorResources[];
@@ -128,7 +127,6 @@ CONTENT_EXPORT extern const char kEnablePrintBrowser[];
CONTENT_EXPORT extern const char kEnableRGBA4444Textures[];
CONTENT_EXPORT extern const char kEnableServiceBinaryLauncher[];
extern const char kEnableSkiaBenchmarking[];
-CONTENT_EXPORT extern const char kEnableSlimmingPaintV175[];
CONTENT_EXPORT extern const char kEnableSlimmingPaintV2[];
CONTENT_EXPORT extern const char kEnableSmoothScrolling[];
CONTENT_EXPORT extern const char kEnableSpatialNavigation[];
@@ -137,23 +135,29 @@ CONTENT_EXPORT extern const char kEnableStrictPowerfulFeatureRestrictions[];
CONTENT_EXPORT extern const char kEnableThreadedCompositing[];
CONTENT_EXPORT extern const char kEnableTracing[];
CONTENT_EXPORT extern const char kEnableTracingOutput[];
+CONTENT_EXPORT extern const char kEnableUnsafeWebGPU[];
CONTENT_EXPORT extern const char kEnableUserMediaScreenCapturing[];
CONTENT_EXPORT extern const char kEnableUseZoomForDSF[];
CONTENT_EXPORT extern const char kEnableViewport[];
CONTENT_EXPORT extern const char kEnableVtune[];
CONTENT_EXPORT extern const char kEnableVulkan[];
CONTENT_EXPORT extern const char kEnableWebAuthTestingAPI[];
+CONTENT_EXPORT extern const char kEnableWebGL2ComputeContext[];
CONTENT_EXPORT extern const char kEnableWebGLDraftExtensions[];
CONTENT_EXPORT extern const char kEnableWebGLImageChromium[];
CONTENT_EXPORT extern const char kEnableWebVR[];
CONTENT_EXPORT extern const char kEnableZeroCopy[];
CONTENT_EXPORT extern const char kExplicitlyAllowedPorts[];
CONTENT_EXPORT extern const char kFieldTrialHandle[];
+CONTENT_EXPORT extern const char kFileUrlPathAlias[];
CONTENT_EXPORT extern const char kForceDisplayList2dCanvas[];
CONTENT_EXPORT extern const char kForceGpuRasterization[];
+CONTENT_EXPORT extern const char kDisableOopRasterization[];
+CONTENT_EXPORT extern const char kEnableOopRasterization[];
CONTENT_EXPORT extern const char kForceOverlayFullscreenVideo[];
CONTENT_EXPORT extern const char kForcePresentationReceiverForTesting[];
CONTENT_EXPORT extern const char kForceRendererAccessibility[];
+CONTENT_EXPORT extern const char kFMPNetworkQuietTimeout[];
CONTENT_EXPORT extern const char kGenerateAccessibilityTestExpectations[];
extern const char kGpuLauncher[];
CONTENT_EXPORT extern const char kGpuProcess[];
@@ -296,11 +300,6 @@ extern const char kIpcDumpDirectory[];
extern const char kIpcFuzzerTestcase[];
#endif
-#if defined(OS_MACOSX)
-extern const char kEnableV2Sandbox[];
-extern const char kV2SandboxedEnabled[];
-#endif // defined(OS_MACOSX)
-
// DON'T ADD RANDOM STUFF HERE. Put it in the main section above in
// alphabetical order, or in one of the ifdefs (also in order in each section).
diff --git a/chromium/content/public/common/main_function_params.h b/chromium/content/public/common/main_function_params.h
index a2c6c9e6454..f9b93251e13 100644
--- a/chromium/content/public/common/main_function_params.h
+++ b/chromium/content/public/common/main_function_params.h
@@ -28,6 +28,7 @@ class ScopedNSAutoreleasePool;
namespace content {
class BrowserMainParts;
+struct StartupData;
using CreatedMainPartsClosure = base::Callback<void(BrowserMainParts*)>;
@@ -56,6 +57,10 @@ struct MainFunctionParams {
// Used by InProcessBrowserTest. If non-null this is Run() after
// BrowserMainParts has been created and before PreEarlyInitialization().
CreatedMainPartsClosure* created_main_parts_closure = nullptr;
+
+ // Used by //content, when the embedder yields control back to it, to extract
+ // startup data passed from ContentMainRunner.
+ StartupData* startup_data = nullptr;
};
} // namespace content
diff --git a/chromium/content/public/common/manifest_struct_traits.h b/chromium/content/public/common/manifest_struct_traits.h
deleted file mode 100644
index ee92dc4e34c..00000000000
--- a/chromium/content/public/common/manifest_struct_traits.h
+++ /dev/null
@@ -1,191 +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_MANIFEST_STRUCT_TRAITS_H_
-#define CONTENT_PUBLIC_COMMON_MANIFEST_STRUCT_TRAITS_H_
-
-#include "content/public/common/manifest.h"
-
-#include "mojo/public/cpp/bindings/struct_traits.h"
-#include "third_party/blink/public/platform/modules/manifest/manifest.mojom-shared.h"
-
-namespace mojo {
-namespace internal {
-
-inline base::StringPiece16 TruncateString16(const base::string16& string) {
- return base::StringPiece16(string).substr(
- 0, content::Manifest::kMaxIPCStringLength);
-}
-
-inline base::Optional<base::StringPiece16> TruncateNullableString16(
- const base::NullableString16& string) {
- if (string.is_null())
- return base::nullopt;
-
- return TruncateString16(string.string());
-}
-
-} // namespace internal
-
-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);
- }
-
- static base::Optional<base::StringPiece16> short_name(
- const content::Manifest& m) {
- return internal::TruncateNullableString16(m.short_name);
- }
-
- static base::Optional<base::StringPiece16> gcm_sender_id(
- const content::Manifest& m) {
- return internal::TruncateNullableString16(m.gcm_sender_id);
- }
-
- static const GURL& start_url(const content::Manifest& m) {
- return m.start_url;
- }
-
- static const GURL& scope(const content::Manifest& m) { return m.scope; }
-
- static blink::WebDisplayMode display(const content::Manifest& m) {
- return m.display;
- }
-
- static blink::WebScreenOrientationLockType orientation(
- const content::Manifest& m) {
- return m.orientation;
- }
-
- static bool has_theme_color(const content::Manifest& m) {
- return m.theme_color.has_value();
- }
-
- static uint32_t theme_color(const content::Manifest& m) {
- return m.theme_color.value_or(0);
- }
-
- static bool has_background_color(const content::Manifest& m) {
- return m.background_color.has_value();
- }
-
- static uint32_t background_color(const content::Manifest& m) {
- return m.background_color.value_or(0);
- }
-
- 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;
- }
-
- static const base::Optional<content::Manifest::ShareTarget>& share_target(
- const content::Manifest& m) {
- return m.share_target;
- }
-
- static const std::vector<content::Manifest::RelatedApplication>&
- related_applications(const content::Manifest& m) {
- return m.related_applications;
- }
-
- static bool prefer_related_applications(const content::Manifest& m) {
- return m.prefer_related_applications;
- }
-
- static bool Read(blink::mojom::ManifestDataView data, content::Manifest* out);
-};
-
-template <>
-struct StructTraits<blink::mojom::ManifestIconDataView,
- content::Manifest::Icon> {
- static const GURL& src(const content::Manifest::Icon& m) { return m.src; }
-
- static base::StringPiece16 type(const content::Manifest::Icon& m) {
- return internal::TruncateString16(m.type);
- }
- static const std::vector<gfx::Size>& sizes(const content::Manifest::Icon& m) {
- return m.sizes;
- }
-
- static const std::vector<content::Manifest::Icon::IconPurpose>& purpose(
- const content::Manifest::Icon& m) {
- return m.purpose;
- }
-
- static bool Read(blink::mojom::ManifestIconDataView data,
- content::Manifest::Icon* out);
-};
-
-template <>
-struct StructTraits<blink::mojom::ManifestRelatedApplicationDataView,
- content::Manifest::RelatedApplication> {
- static base::Optional<base::StringPiece16> platform(
- const content::Manifest::RelatedApplication& m) {
- return internal::TruncateNullableString16(m.platform);
- }
-
- static const GURL& url(const content::Manifest::RelatedApplication& m) {
- return m.url;
- }
-
- static base::Optional<base::StringPiece16> id(
- const content::Manifest::RelatedApplication& m) {
- return internal::TruncateNullableString16(m.id);
- }
-
- static bool Read(blink::mojom::ManifestRelatedApplicationDataView data,
- content::Manifest::RelatedApplication* out);
-};
-
-template <>
-struct StructTraits<blink::mojom::ManifestShareTargetDataView,
- content::Manifest::ShareTarget> {
- static const GURL& url_template(const content::Manifest::ShareTarget& m) {
- return m.url_template;
- }
- static bool Read(blink::mojom::ManifestShareTargetDataView data,
- content::Manifest::ShareTarget* out);
-};
-
-template <>
-struct EnumTraits<blink::mojom::ManifestIcon_Purpose,
- content::Manifest::Icon::IconPurpose> {
- static blink::mojom::ManifestIcon_Purpose ToMojom(
- content::Manifest::Icon::IconPurpose purpose) {
- switch (purpose) {
- case content::Manifest::Icon::ANY:
- return blink::mojom::ManifestIcon_Purpose::ANY;
- case content::Manifest::Icon::BADGE:
- return blink::mojom::ManifestIcon_Purpose::BADGE;
- }
- NOTREACHED();
- return blink::mojom::ManifestIcon_Purpose::ANY;
- }
- static bool FromMojom(blink::mojom::ManifestIcon_Purpose input,
- content::Manifest::Icon::IconPurpose* out) {
- switch (input) {
- case blink::mojom::ManifestIcon_Purpose::ANY:
- *out = content::Manifest::Icon::ANY;
- return true;
- case blink::mojom::ManifestIcon_Purpose::BADGE:
- *out = content::Manifest::Icon::BADGE;
- return true;
- }
-
- return false;
- }
-};
-
-} // namespace mojo
-
-#endif // CONTENT_PUBLIC_COMMON_MANIFEST_STRUCT_TRAITS_H_
diff --git a/chromium/content/public/common/media_stream_request.h b/chromium/content/public/common/media_stream_request.h
index 9ea6103ed5c..946502b28db 100644
--- a/chromium/content/public/common/media_stream_request.h
+++ b/chromium/content/public/common/media_stream_request.h
@@ -225,9 +225,9 @@ class MediaStreamUI {
// Callback used return results of media access requests.
using MediaResponseCallback =
- base::Callback<void(const MediaStreamDevices& devices,
- MediaStreamRequestResult result,
- std::unique_ptr<MediaStreamUI> ui)>;
+ base::OnceCallback<void(const MediaStreamDevices& devices,
+ MediaStreamRequestResult result,
+ std::unique_ptr<MediaStreamUI> ui)>;
} // namespace content
#endif // CONTENT_PUBLIC_COMMON_MEDIA_STREAM_REQUEST_H_
diff --git a/chromium/content/public/common/previews_state.h b/chromium/content/public/common/previews_state.h
index 8fce0d16bcd..e5ab4b75df4 100644
--- a/chromium/content/public/common/previews_state.h
+++ b/chromium/content/public/common/previews_state.h
@@ -38,7 +38,11 @@ enum PreviewsTypes {
// the resource. Server transformations may
// still happen if the page is heavy.
NOSCRIPT_ON = 1 << 6, // Request that script be disabled for page load.
- PREVIEWS_STATE_LAST = PREVIEWS_OFF
+ RESOURCE_LOADING_HINTS_ON =
+ 1 << 7, // Request that resource loading hints be used during pageload.
+ OFFLINE_PAGE_ON =
+ 1 << 8, // Request that an offline page be used if one is stored.
+ PREVIEWS_STATE_LAST = OFFLINE_PAGE_ON
};
// Combination of all previews that are guaranteed not to provide partial
@@ -61,6 +65,10 @@ STATIC_ASSERT_PREVIEWS_ENUM(PREVIEWS_NO_TRANSFORM,
blink::WebURLRequest::kPreviewsNoTransform);
STATIC_ASSERT_PREVIEWS_ENUM(PREVIEWS_OFF, blink::WebURLRequest::kPreviewsOff);
STATIC_ASSERT_PREVIEWS_ENUM(NOSCRIPT_ON, blink::WebURLRequest::kNoScriptOn);
+STATIC_ASSERT_PREVIEWS_ENUM(RESOURCE_LOADING_HINTS_ON,
+ blink::WebURLRequest::kResourceLoadingHintsOn);
+STATIC_ASSERT_PREVIEWS_ENUM(OFFLINE_PAGE_ON,
+ blink::WebURLRequest::kOfflinePageOn);
STATIC_ASSERT_PREVIEWS_ENUM(PREVIEWS_STATE_LAST,
blink::WebURLRequest::kPreviewsStateLast);
diff --git a/chromium/content/public/common/renderer_preferences.h b/chromium/content/public/common/renderer_preferences.h
index 688fc6b0207..dd45021de12 100644
--- a/chromium/content/public/common/renderer_preferences.h
+++ b/chromium/content/public/common/renderer_preferences.h
@@ -33,6 +33,9 @@ enum TapMultipleTargetsStrategy {
TAP_MULTIPLE_TARGETS_STRATEGY_MAX = TAP_MULTIPLE_TARGETS_STRATEGY_NONE,
};
+// User preferences needed to be passed to the renderer process.
+// TODO(crbug.com/869748): Move the preferences into
+// third_party/blink/public/mojom as a mojom struct.
struct CONTENT_EXPORT RendererPreferences {
RendererPreferences();
RendererPreferences(const RendererPreferences& other);
@@ -92,9 +95,11 @@ struct CONTENT_EXPORT RendererPreferences {
bool use_custom_colors;
// Set to false to not send referrers.
+ // The default value should be in sync with blink::PrivacyPreferences.
bool enable_referrers;
// Set to true to indicate that the preference to set DNT to 1 is enabled.
+ // The default value should be in sync with blink::PrivacyPreferences.
bool enable_do_not_track;
// Whether to allow the use of Encrypted Media Extensions (EME), except for
diff --git a/chromium/content/public/common/screen_info.h b/chromium/content/public/common/screen_info.h
index d25d136493b..4ed8427b6b2 100644
--- a/chromium/content/public/common/screen_info.h
+++ b/chromium/content/public/common/screen_info.h
@@ -28,15 +28,6 @@ struct CONTENT_EXPORT ScreenInfo {
// The color space of the output display.
gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB();
-#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/speech_recognition_error.h b/chromium/content/public/common/speech_recognition_error.h
deleted file mode 100644
index 34aa16de1c2..00000000000
--- a/chromium/content/public/common/speech_recognition_error.h
+++ /dev/null
@@ -1,77 +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_SPEECH_RECOGNITION_ERROR_H_
-#define CONTENT_PUBLIC_COMMON_SPEECH_RECOGNITION_ERROR_H_
-
-#include "content/common/content_export.h"
-
-namespace content {
-
-// A Java counterpart will be generated for this enum.
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.content_public.common
-// GENERATED_JAVA_PREFIX_TO_STRIP: SPEECH_RECOGNITION_ERROR_
-enum SpeechRecognitionErrorCode {
- // There was no error.
- SPEECH_RECOGNITION_ERROR_NONE,
-
- // No speech heard before timeout.
- SPEECH_RECOGNITION_ERROR_NO_SPEECH,
-
- // The user or a script aborted speech input.
- SPEECH_RECOGNITION_ERROR_ABORTED,
-
- // There was an error with recording audio.
- SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE,
-
- // There was a network error.
- SPEECH_RECOGNITION_ERROR_NETWORK,
-
- // Not allowed for privacy or security reasons.
- SPEECH_RECOGNITION_ERROR_NOT_ALLOWED,
-
- // Speech service is not allowed for privacy or security reasons.
- SPEECH_RECOGNITION_ERROR_SERVICE_NOT_ALLOWED,
-
- // There was an error in the speech recognition grammar.
- SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR,
-
- // The language was not supported.
- SPEECH_RECOGNITION_ERROR_LANGUAGE_NOT_SUPPORTED,
-
- // Speech was heard, but could not be interpreted.
- SPEECH_RECOGNITION_ERROR_NO_MATCH,
-
- SPEECH_RECOGNITION_ERROR_LAST = SPEECH_RECOGNITION_ERROR_NO_MATCH,
-};
-
-// Error details for the SPEECH_RECOGNITION_ERROR_AUDIO error.
-enum SpeechAudioErrorDetails {
- SPEECH_AUDIO_ERROR_DETAILS_NONE = 0,
- SPEECH_AUDIO_ERROR_DETAILS_NO_MIC,
- SPEECH_AUDIO_ERROR_DETAILS_LAST = SPEECH_AUDIO_ERROR_DETAILS_NO_MIC
-};
-
-struct CONTENT_EXPORT SpeechRecognitionError {
- SpeechRecognitionErrorCode code;
- SpeechAudioErrorDetails details;
-
- SpeechRecognitionError()
- : code(SPEECH_RECOGNITION_ERROR_NONE),
- details(SPEECH_AUDIO_ERROR_DETAILS_NONE) {
- }
- explicit SpeechRecognitionError(SpeechRecognitionErrorCode code_value)
- : code(code_value),
- details(SPEECH_AUDIO_ERROR_DETAILS_NONE) {
- }
- SpeechRecognitionError(SpeechRecognitionErrorCode code_value,
- SpeechAudioErrorDetails details_value)
- : code(code_value),
- details(details_value) {
- }
-};
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_COMMON_SPEECH_RECOGNITION_ERROR_H_
diff --git a/chromium/content/public/common/speech_recognition_error.mojom b/chromium/content/public/common/speech_recognition_error.mojom
deleted file mode 100644
index 31f28a46d87..00000000000
--- a/chromium/content/public/common/speech_recognition_error.mojom
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module content.mojom;
-
-// TODO(adithyas): Update users of content::SpeechRecognitionErrorCode to use
-// this instead, then remove content::SpeechRecognitionErrorCode.
-enum SpeechRecognitionErrorCode {
- kNone,
- kNoSpeech,
- kAborted,
- kAudioCapture,
- kNetwork,
- kNotAllowed,
- kServiceNotAllowed,
- kBadGrammar,
- kLanguageNotSupported,
- kNoMatch
-};
-
-// TODO(adithyas): Update users of content::SpeechAudioErrorDetails to use
-// this instead, then remove content::SpeechAudioErrorDetails.
-enum SpeechAudioErrorDetails {
- kNone,
- kNoMic
-};
-
-// TODO(adithyas): Update users of content::SpeechRecognitionError to use
-// this instead, then remove content::SpeechRecognitionError.
-struct SpeechRecognitionError {
- content.mojom.SpeechRecognitionErrorCode code;
- content.mojom.SpeechAudioErrorDetails details;
-};
diff --git a/chromium/content/public/common/speech_recognition_error.typemap b/chromium/content/public/common/speech_recognition_error.typemap
deleted file mode 100644
index 4b99fa73245..00000000000
--- a/chromium/content/public/common/speech_recognition_error.typemap
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2018 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//content/public/common/speech_recognition_error.mojom"
-public_headers = [ "//content/public/common/speech_recognition_error.h" ]
-traits_headers =
- [ "//content/public/common/speech_recognition_error_struct_traits.h" ]
-sources = [
- "//content/public/common/speech_recognition_error_struct_traits.cc",
-]
-deps = []
-type_mappings =
- [ "content.mojom.SpeechRecognitionError=content::SpeechRecognitionError" ]
diff --git a/chromium/content/public/common/speech_recognition_error_struct_traits.cc b/chromium/content/public/common/speech_recognition_error_struct_traits.cc
deleted file mode 100644
index 19720639dd1..00000000000
--- a/chromium/content/public/common/speech_recognition_error_struct_traits.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/public/common/speech_recognition_error_struct_traits.h"
-
-namespace mojo {
-
-bool StructTraits<content::mojom::SpeechRecognitionErrorDataView,
- content::SpeechRecognitionError>::
- Read(content::mojom::SpeechRecognitionErrorDataView data,
- content::SpeechRecognitionError* out) {
- if (!data.ReadCode(&out->code)) {
- return false;
- }
- if (!data.ReadDetails(&out->details)) {
- return false;
- }
- return true;
-}
-
-} // namespace mojo
diff --git a/chromium/content/public/common/speech_recognition_error_struct_traits.h b/chromium/content/public/common/speech_recognition_error_struct_traits.h
deleted file mode 100644
index c863e5a698b..00000000000
--- a/chromium/content/public/common/speech_recognition_error_struct_traits.h
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_COMMON_SPEECH_RECOGNITION_ERROR_STRUCT_TRAITS_H_
-#define CONTENT_PUBLIC_COMMON_SPEECH_RECOGNITION_ERROR_STRUCT_TRAITS_H_
-
-#include "content/public/common/speech_recognition_error.h"
-#include "content/public/common/speech_recognition_error.mojom.h"
-
-namespace mojo {
-
-template <>
-struct EnumTraits<content::mojom::SpeechRecognitionErrorCode,
- content::SpeechRecognitionErrorCode> {
- static content::mojom::SpeechRecognitionErrorCode ToMojom(
- content::SpeechRecognitionErrorCode input) {
- switch (input) {
- case content::SpeechRecognitionErrorCode::SPEECH_RECOGNITION_ERROR_NONE:
- return content::mojom::SpeechRecognitionErrorCode::kNone;
- case content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_NO_SPEECH:
- return content::mojom::SpeechRecognitionErrorCode::kNoSpeech;
- case content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_ABORTED:
- return content::mojom::SpeechRecognitionErrorCode::kAborted;
- case content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE:
- return content::mojom::SpeechRecognitionErrorCode::kAudioCapture;
- case content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_NETWORK:
- return content::mojom::SpeechRecognitionErrorCode::kNetwork;
- case content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_NOT_ALLOWED:
- return content::mojom::SpeechRecognitionErrorCode::kNotAllowed;
- case content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_SERVICE_NOT_ALLOWED:
- return content::mojom::SpeechRecognitionErrorCode::kServiceNotAllowed;
- case content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR:
- return content::mojom::SpeechRecognitionErrorCode::kBadGrammar;
- case content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_LANGUAGE_NOT_SUPPORTED:
- return content::mojom::SpeechRecognitionErrorCode::
- kLanguageNotSupported;
- case content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_NO_MATCH:
- return content::mojom::SpeechRecognitionErrorCode::kNoMatch;
- }
- NOTREACHED();
- return content::mojom::SpeechRecognitionErrorCode::kNoMatch;
- }
-
- static bool FromMojom(content::mojom::SpeechRecognitionErrorCode input,
- content::SpeechRecognitionErrorCode* output) {
- switch (input) {
- case content::mojom::SpeechRecognitionErrorCode::kNone:
- *output =
- content::SpeechRecognitionErrorCode::SPEECH_RECOGNITION_ERROR_NONE;
- return true;
- case content::mojom::SpeechRecognitionErrorCode::kNoSpeech:
- *output = content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_NO_SPEECH;
- return true;
- case content::mojom::SpeechRecognitionErrorCode::kAborted:
- *output = content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_ABORTED;
- return true;
- case content::mojom::SpeechRecognitionErrorCode::kAudioCapture:
- *output = content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE;
- return true;
- case content::mojom::SpeechRecognitionErrorCode::kNetwork:
- *output = content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_NETWORK;
- return true;
- case content::mojom::SpeechRecognitionErrorCode::kNotAllowed:
- *output = content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_NOT_ALLOWED;
- return true;
- case content::mojom::SpeechRecognitionErrorCode::kServiceNotAllowed:
- *output = content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_SERVICE_NOT_ALLOWED;
- return true;
- case content::mojom::SpeechRecognitionErrorCode::kBadGrammar:
- *output = content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR;
- return true;
- case content::mojom::SpeechRecognitionErrorCode::kLanguageNotSupported:
- *output = content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_LANGUAGE_NOT_SUPPORTED;
- return true;
- case content::mojom::SpeechRecognitionErrorCode::kNoMatch:
- *output = content::SpeechRecognitionErrorCode::
- SPEECH_RECOGNITION_ERROR_NO_MATCH;
- return true;
- }
- NOTREACHED();
- return false;
- }
-};
-
-template <>
-struct EnumTraits<content::mojom::SpeechAudioErrorDetails,
- content::SpeechAudioErrorDetails> {
- static content::mojom::SpeechAudioErrorDetails ToMojom(
- content::SpeechAudioErrorDetails input) {
- switch (input) {
- case content::SpeechAudioErrorDetails::SPEECH_AUDIO_ERROR_DETAILS_NONE:
- return content::mojom::SpeechAudioErrorDetails::kNone;
- case content::SpeechAudioErrorDetails::SPEECH_AUDIO_ERROR_DETAILS_NO_MIC:
- return content::mojom::SpeechAudioErrorDetails::kNoMic;
- }
- NOTREACHED();
- return content::mojom::SpeechAudioErrorDetails::kNoMic;
- }
-
- static bool FromMojom(content::mojom::SpeechAudioErrorDetails input,
- content::SpeechAudioErrorDetails* output) {
- switch (input) {
- case content::mojom::SpeechAudioErrorDetails::kNone:
- *output =
- content::SpeechAudioErrorDetails::SPEECH_AUDIO_ERROR_DETAILS_NONE;
- return true;
- case content::mojom::SpeechAudioErrorDetails::kNoMic:
- *output =
- content::SpeechAudioErrorDetails::SPEECH_AUDIO_ERROR_DETAILS_NO_MIC;
- return true;
- }
- NOTREACHED();
- return false;
- }
-};
-
-template <>
-struct StructTraits<content::mojom::SpeechRecognitionErrorDataView,
- content::SpeechRecognitionError> {
- static content::SpeechRecognitionErrorCode code(
- const content::SpeechRecognitionError& r) {
- return r.code;
- }
- static content::SpeechAudioErrorDetails details(
- const content::SpeechRecognitionError& r) {
- return r.details;
- }
- static bool Read(content::mojom::SpeechRecognitionErrorDataView data,
- content::SpeechRecognitionError* out);
-};
-
-} // namespace mojo
-
-#endif // CONTENT_PUBLIC_COMMON_SPEECH_RECOGNITION_ERROR_STRUCT_TRAITS_H_
diff --git a/chromium/content/public/common/speech_recognition_grammar.mojom b/chromium/content/public/common/speech_recognition_grammar.mojom
deleted file mode 100644
index fbb0bb2cbfe..00000000000
--- a/chromium/content/public/common/speech_recognition_grammar.mojom
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module content.mojom;
-
-import "url/mojom/url.mojom";
-
-struct SpeechRecognitionGrammar {
- url.mojom.Url url;
- double weight;
-};
diff --git a/chromium/content/public/common/speech_recognition_result.cc b/chromium/content/public/common/speech_recognition_result.cc
deleted file mode 100644
index 9f4c2ca8a9f..00000000000
--- a/chromium/content/public/common/speech_recognition_result.cc
+++ /dev/null
@@ -1,20 +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/public/common/speech_recognition_result.h"
-
-namespace content {
-
-SpeechRecognitionResult::SpeechRecognitionResult()
- : is_provisional(false) {
-}
-
-SpeechRecognitionResult::SpeechRecognitionResult(
- const SpeechRecognitionResult& other) = default;
-
-SpeechRecognitionResult::~SpeechRecognitionResult() {
-}
-
-} // namespace content
-
diff --git a/chromium/content/public/common/speech_recognition_result.h b/chromium/content/public/common/speech_recognition_result.h
deleted file mode 100644
index 6c3f2ab3dde..00000000000
--- a/chromium/content/public/common/speech_recognition_result.h
+++ /dev/null
@@ -1,44 +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_SPEECH_RECOGNITION_RESULT_H_
-#define CONTENT_PUBLIC_COMMON_SPEECH_RECOGNITION_RESULT_H_
-
-#include <vector>
-
-#include "base/strings/string16.h"
-#include "content/common/content_export.h"
-
-namespace content {
-
-struct SpeechRecognitionHypothesis {
- base::string16 utterance;
- double confidence;
-
- SpeechRecognitionHypothesis() : confidence(0.0) {}
-
- SpeechRecognitionHypothesis(const base::string16& utterance_value,
- double confidence_value)
- : utterance(utterance_value),
- confidence(confidence_value) {
- }
-};
-
-typedef std::vector<SpeechRecognitionHypothesis>
- SpeechRecognitionHypothesisArray;
-
-struct CONTENT_EXPORT SpeechRecognitionResult {
- SpeechRecognitionHypothesisArray hypotheses;
- bool is_provisional;
-
- SpeechRecognitionResult();
- SpeechRecognitionResult(const SpeechRecognitionResult& other);
- ~SpeechRecognitionResult();
-};
-
-typedef std::vector<SpeechRecognitionResult> SpeechRecognitionResults;
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_COMMON_SPEECH_RECOGNITION_RESULT_H_
diff --git a/chromium/content/public/common/speech_recognition_result.mojom b/chromium/content/public/common/speech_recognition_result.mojom
deleted file mode 100644
index 8bc5b6c55c1..00000000000
--- a/chromium/content/public/common/speech_recognition_result.mojom
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module content.mojom;
-
-import "mojo/public/mojom/base/string16.mojom";
-
-// A single hypothesis indicating what the recognition service thinks a
-// particular speech segment means.
-struct SpeechRecognitionHypothesis {
- // Transcript of spoken text.
- mojo_base.mojom.String16 utterance;
-
- // A numeric estimate between 0 and 1 that represents how confident the
- // recognition system is that the recognition is correct.
- double confidence;
-};
-
-// Group of recognition hypotheses for a particular speech segment.
-struct SpeechRecognitionResult {
- // An N-best list of hypotheses.
- array<content.mojom.SpeechRecognitionHypothesis> hypotheses;
-
- // False if this is the final time the speech service will return this
- // particular result. If true, then this represents an interim result that
- // could still be changed.
- bool is_provisional;
-};
diff --git a/chromium/content/public/common/speech_recognition_result.typemap b/chromium/content/public/common/speech_recognition_result.typemap
deleted file mode 100644
index ac03718a8d6..00000000000
--- a/chromium/content/public/common/speech_recognition_result.typemap
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2018 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//content/public/common/speech_recognition_result.mojom"
-public_headers = [ "//content/public/common/speech_recognition_result.h" ]
-traits_headers =
- [ "//content/public/common/speech_recognition_result_struct_traits.h" ]
-sources = [
- "//content/public/common/speech_recognition_result_struct_traits.cc",
-]
-deps = []
-type_mappings = [
- "content.mojom.SpeechRecognitionHypothesis=content::SpeechRecognitionHypothesis",
- "content.mojom.SpeechRecognitionResult=content::SpeechRecognitionResult",
-]
diff --git a/chromium/content/public/common/speech_recognition_result_struct_traits.cc b/chromium/content/public/common/speech_recognition_result_struct_traits.cc
deleted file mode 100644
index 1c1e06d1f08..00000000000
--- a/chromium/content/public/common/speech_recognition_result_struct_traits.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/public/common/speech_recognition_result_struct_traits.h"
-
-namespace mojo {
-
-bool StructTraits<content::mojom::SpeechRecognitionHypothesisDataView,
- content::SpeechRecognitionHypothesis>::
- Read(content::mojom::SpeechRecognitionHypothesisDataView data,
- content::SpeechRecognitionHypothesis* out) {
- if (!data.ReadUtterance(&out->utterance))
- return false;
- out->confidence = data.confidence();
- return true;
-}
-
-bool StructTraits<content::mojom::SpeechRecognitionResultDataView,
- content::SpeechRecognitionResult>::
- Read(content::mojom::SpeechRecognitionResultDataView data,
- content::SpeechRecognitionResult* out) {
- if (!data.ReadHypotheses(&out->hypotheses))
- return false;
- out->is_provisional = data.is_provisional();
- return true;
-}
-
-} // namespace mojo
diff --git a/chromium/content/public/common/speech_recognition_result_struct_traits.h b/chromium/content/public/common/speech_recognition_result_struct_traits.h
deleted file mode 100644
index 53b84eb0da0..00000000000
--- a/chromium/content/public/common/speech_recognition_result_struct_traits.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_PUBLIC_COMMON_SPEECH_RECOGNITION_RESULT_STRUCT_TRAITS_H_
-#define CONTENT_PUBLIC_COMMON_SPEECH_RECOGNITION_RESULT_STRUCT_TRAITS_H_
-
-#include "content/public/common/speech_recognition_result.h"
-#include "content/public/common/speech_recognition_result.mojom.h"
-#include "mojo/public/cpp/base/string16_mojom_traits.h"
-#include "mojo/public/cpp/bindings/struct_traits.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<content::mojom::SpeechRecognitionHypothesisDataView,
- content::SpeechRecognitionHypothesis> {
- static const base::string16& utterance(
- const content::SpeechRecognitionHypothesis& r) {
- return r.utterance;
- }
- static double confidence(const content::SpeechRecognitionHypothesis& r) {
- return r.confidence;
- }
- static bool Read(content::mojom::SpeechRecognitionHypothesisDataView data,
- content::SpeechRecognitionHypothesis* out);
-};
-
-template <>
-struct StructTraits<content::mojom::SpeechRecognitionResultDataView,
- content::SpeechRecognitionResult> {
- static const std::vector<content::SpeechRecognitionHypothesis>& hypotheses(
- const content::SpeechRecognitionResult& r) {
- return r.hypotheses;
- }
-
- static bool is_provisional(const content::SpeechRecognitionResult& r) {
- return r.is_provisional;
- }
-
- static bool Read(content::mojom::SpeechRecognitionResultDataView data,
- content::SpeechRecognitionResult* out);
-};
-
-} // namespace mojo
-
-#endif // CONTENT_PUBLIC_COMMON_SPEECH_RECOGNITION_RESULT_STRUCT_TRAITS_H_
diff --git a/chromium/content/public/common/typemaps.gni b/chromium/content/public/common/typemaps.gni
index ae8d8a0e219..4e0d0c3d3c6 100644
--- a/chromium/content/public/common/typemaps.gni
+++ b/chromium/content/public/common/typemaps.gni
@@ -6,7 +6,5 @@ typemaps = [
"//content/public/common/load_timing_info.typemap",
"//content/public/common/referrer.typemap",
"//content/public/common/resource_type.typemap",
- "//content/public/common/speech_recognition_result.typemap",
- "//content/public/common/speech_recognition_error.typemap",
"//content/public/common/webplugininfo.typemap",
]
diff --git a/chromium/content/public/common/url_fetcher.h b/chromium/content/public/common/url_fetcher.h
deleted file mode 100644
index bc9f1436d82..00000000000
--- a/chromium/content/public/common/url_fetcher.h
+++ /dev/null
@@ -1,31 +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_URL_FETCHER_H_
-#define CONTENT_PUBLIC_COMMON_URL_FETCHER_H_
-
-#include "base/optional.h"
-#include "content/common/content_export.h"
-
-namespace net {
-class URLFetcher;
-} // namespace
-
-namespace url {
-class Origin;
-} // namespace
-
-namespace content {
-
-// Mark URLRequests started by the URLFetcher to stem from the given render
-// frame.
-CONTENT_EXPORT void AssociateURLFetcherWithRenderFrame(
- net::URLFetcher* url_fetcher,
- const base::Optional<url::Origin>& initiator,
- int render_process_id,
- int render_frame_id);
-
-} // namespace content
-
-#endif // CONTENT_PUBLIC_COMMON_URL_FETCHER_H_
diff --git a/chromium/content/public/common/url_loader_throttle.cc b/chromium/content/public/common/url_loader_throttle.cc
index b2743344720..a919a363a9f 100644
--- a/chromium/content/public/common/url_loader_throttle.cc
+++ b/chromium/content/public/common/url_loader_throttle.cc
@@ -34,7 +34,8 @@ void URLLoaderThrottle::WillStartRequest(network::ResourceRequest* request,
void URLLoaderThrottle::WillRedirectRequest(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head,
- bool* defer) {}
+ bool* defer,
+ std::vector<std::string>* to_be_removed_request_headers) {}
void URLLoaderThrottle::WillProcessResponse(
const GURL& response_url,
diff --git a/chromium/content/public/common/url_loader_throttle.h b/chromium/content/public/common/url_loader_throttle.h
index 73a1ae2d0a6..37faba04144 100644
--- a/chromium/content/public/common/url_loader_throttle.h
+++ b/chromium/content/public/common/url_loader_throttle.h
@@ -5,6 +5,9 @@
#ifndef CONTENT_PUBLIC_COMMON_URL_LOADER_THROTTLE_H_
#define CONTENT_PUBLIC_COMMON_URL_LOADER_THROTTLE_H_
+#include <string>
+#include <vector>
+
#include "base/strings/string_piece.h"
#include "content/common/content_export.h"
#include "content/public/common/resource_type.h"
@@ -88,7 +91,8 @@ class CONTENT_EXPORT URLLoaderThrottle {
virtual void WillRedirectRequest(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head,
- bool* defer);
+ bool* defer,
+ std::vector<std::string>* to_be_removed_request_headers);
// Called when the response headers and meta data are available.
// TODO(776312): Migrate this URL to ResourceResponseHead.
diff --git a/chromium/content/public/common/use_zoom_for_dsf_policy.h b/chromium/content/public/common/use_zoom_for_dsf_policy.h
index 9c436f9504f..1c61de5fa66 100644
--- a/chromium/content/public/common/use_zoom_for_dsf_policy.h
+++ b/chromium/content/public/common/use_zoom_for_dsf_policy.h
@@ -9,6 +9,10 @@
// A centralized file for base helper methods and policy decisions about use
// zoom for DSF (i.e., Device Scale Factor).
+//
+// In the renderer, the decision to UseZoomForDSF should come from the
+// CompositorDependencies, not from this global method, so that it can be
+// controlled and injected in tests.
namespace content {
diff --git a/chromium/content/public/common/web_preferences.cc b/chromium/content/public/common/web_preferences.cc
index c5f6d0b03ba..8378aefaf81 100644
--- a/chromium/content/public/common/web_preferences.cc
+++ b/chromium/content/public/common/web_preferences.cc
@@ -187,13 +187,16 @@ WebPreferences::WebPreferences()
user_gesture_required_for_presentation(true),
text_track_margin_percentage(0.0f),
immersive_mode_enabled(false),
-#if defined(OS_ANDROID)
+#if !defined(OS_ANDROID)
+ text_autosizing_enabled(false),
+ double_tap_to_zoom_enabled(false),
+#else
text_autosizing_enabled(true),
+ double_tap_to_zoom_enabled(true),
font_scale_factor(1.0f),
device_scale_adjustment(1.0f),
force_enable_zoom(false),
fullscreen_supported(true),
- double_tap_to_zoom_enabled(true),
support_deprecated_target_density_dpi(false),
use_legacy_background_size_shorthand_behavior(false),
wide_viewport_quirk(false),
@@ -233,7 +236,7 @@ WebPreferences::WebPreferences()
do_not_update_selection_on_mutating_selection_range(false),
autoplay_policy(AutoplayPolicy::kDocumentUserActivationRequired),
low_priority_iframes_threshold(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
- picture_in_picture_enabled(false) {
+ picture_in_picture_enabled(true) {
standard_font_family_map[kCommonScript] =
base::ASCIIToUTF16("Times New Roman");
fixed_font_family_map[kCommonScript] = base::ASCIIToUTF16("Courier New");
diff --git a/chromium/content/public/common/web_preferences.h b/chromium/content/public/common/web_preferences.h
index a1e9fba06a6..78cbf5f3db8 100644
--- a/chromium/content/public/common/web_preferences.h
+++ b/chromium/content/public/common/web_preferences.h
@@ -81,9 +81,9 @@ CONTENT_EXPORT extern const char kCommonScript[];
// A struct for managing blink's settings.
//
// Adding new values to this class probably involves updating
-// blink::WebSettings, content/common/view_messages.h, browser/tab_contents/
-// render_view_host_delegate_helper.cc, browser/profiles/profile.cc,
-// and content/public/common/common_param_traits_macros.h
+// blink::WebSettings, content/common/view_messages.h,
+// browser/profiles/profile.cc, and
+// content/public/common/common_param_traits_macros.h
struct CONTENT_EXPORT WebPreferences {
ScriptFontFamilyMap standard_font_family_map;
ScriptFontFamilyMap fixed_font_family_map;
@@ -224,13 +224,15 @@ struct CONTENT_EXPORT WebPreferences {
bool immersive_mode_enabled;
-#if defined(OS_ANDROID)
bool text_autosizing_enabled;
+
+ bool double_tap_to_zoom_enabled;
+
+#if defined(OS_ANDROID)
float font_scale_factor;
float device_scale_adjustment;
bool force_enable_zoom;
bool fullscreen_supported;
- bool double_tap_to_zoom_enabled;
std::string media_playback_gesture_whitelist_scope;
GURL default_video_poster_url;
bool support_deprecated_target_density_dpi;
@@ -304,6 +306,13 @@ struct CONTENT_EXPORT WebPreferences {
// Whether Picture-in-Picture is enabled.
bool picture_in_picture_enabled;
+ // Specifies how close a lazily loaded iframe should be from the viewport
+ // before it should start being loaded in, depending on the effective
+ // connection type of the current network. Blink will use the default distance
+ // threshold for effective connection types that aren't specified here.
+ std::map<net::EffectiveConnectionType, int>
+ lazy_frame_loading_distance_thresholds_px;
+
// We try to keep the default values the same as the default values in
// chrome, except for the cases where it would require lots of extra work for
// the embedder to use the same default value.
diff --git a/chromium/content/public/renderer/content_renderer_client.cc b/chromium/content/public/renderer/content_renderer_client.cc
index 5134616afa5..5d904190947 100644
--- a/chromium/content/public/renderer/content_renderer_client.cc
+++ b/chromium/content/public/renderer/content_renderer_client.cc
@@ -51,11 +51,11 @@ bool ContentRendererClient::ShouldTrackUseCounter(const GURL& url) {
return true;
}
-void ContentRendererClient::DeferMediaLoad(
- RenderFrame* render_frame,
- bool has_played_media_before,
- const base::Closure& closure) {
- closure.Run();
+bool ContentRendererClient::DeferMediaLoad(RenderFrame* render_frame,
+ bool has_played_media_before,
+ base::OnceClosure closure) {
+ std::move(closure).Run();
+ return false;
}
std::unique_ptr<blink::WebMIDIAccessor>
@@ -94,10 +94,6 @@ bool ContentRendererClient::RunIdleHandlerWhenWidgetsHidden() {
return true;
}
-bool ContentRendererClient::AllowFreezingWhenProcessBackgrounded() {
- return false;
-}
-
bool ContentRendererClient::AllowPopup() {
return false;
}
diff --git a/chromium/content/public/renderer/content_renderer_client.h b/chromium/content/public/renderer/content_renderer_client.h
index 6dd2589d653..a2dc7a811e7 100644
--- a/chromium/content/public/renderer/content_renderer_client.h
+++ b/chromium/content/public/renderer/content_renderer_client.h
@@ -155,9 +155,10 @@ class CONTENT_EXPORT ContentRendererClient {
// can run |closure| immediately if they don't wish to defer media resource
// loading. If |has_played_media_before| is true, the render frame has
// previously started media playback (i.e. played audio and video).
- virtual void DeferMediaLoad(RenderFrame* render_frame,
+ // Returns true if running of |closure| is deferred; false if run immediately.
+ virtual bool DeferMediaLoad(RenderFrame* render_frame,
bool has_played_media_before,
- const base::Closure& closure);
+ base::OnceClosure closure);
// Allows the embedder to override creating a WebMIDIAccessor. If it
// returns NULL the content layer will create the MIDI accessor.
@@ -199,10 +200,6 @@ class CONTENT_EXPORT ContentRendererClient {
// all widgets are hidden.
virtual bool RunIdleHandlerWhenWidgetsHidden();
- // Returns true if the renderer process should allow task suspension
- // after the process has been backgrounded. Defaults to false.
- virtual bool AllowFreezingWhenProcessBackgrounded();
-
// Returns true if a popup window should be allowed.
virtual bool AllowPopup();
diff --git a/chromium/content/public/renderer/key_system_support.cc b/chromium/content/public/renderer/key_system_support.cc
index 9b5ae43b983..b2e2ea4411b 100644
--- a/chromium/content/public/renderer/key_system_support.cc
+++ b/chromium/content/public/renderer/key_system_support.cc
@@ -14,9 +14,7 @@ namespace content {
bool IsKeySystemSupported(
const std::string& key_system,
- std::vector<media::VideoCodec>* supported_video_codecs,
- bool* supports_persistent_license,
- std::vector<media::EncryptionMode>* supported_encryption_schemes) {
+ media::mojom::KeySystemCapabilityPtr* key_system_capability) {
DVLOG(3) << __func__ << " key_system: " << key_system;
bool is_supported = false;
@@ -24,9 +22,8 @@ bool IsKeySystemSupported(
content::RenderThread::Get()->GetConnector()->BindInterface(
mojom::kBrowserServiceName, mojo::MakeRequest(&key_system_support));
- key_system_support->IsKeySystemSupported(
- key_system, &is_supported, supported_video_codecs,
- supports_persistent_license, supported_encryption_schemes);
+ key_system_support->IsKeySystemSupported(key_system, &is_supported,
+ key_system_capability);
return is_supported;
}
diff --git a/chromium/content/public/renderer/key_system_support.h b/chromium/content/public/renderer/key_system_support.h
index 8491ecc1a41..d62111a025f 100644
--- a/chromium/content/public/renderer/key_system_support.h
+++ b/chromium/content/public/renderer/key_system_support.h
@@ -9,20 +9,16 @@
#include <vector>
#include "content/common/content_export.h"
-#include "media/base/decrypt_config.h"
-#include "media/base/video_codecs.h"
+#include "media/mojo/interfaces/key_system_support.mojom.h"
namespace content {
// Determines if |key_system| is supported by calling into the browser.
-// If it is supported, return true and |supported_video_codecs|,
-// |supports_persistent_license| and |supported_encryption_schemes| are updated
+// If it is supported, return true and |key_system_capability| is updated
// to match what |key_system| supports. If not supported, false is returned.
CONTENT_EXPORT bool IsKeySystemSupported(
const std::string& key_system,
- std::vector<media::VideoCodec>* supported_video_codecs,
- bool* supports_persistent_license,
- std::vector<media::EncryptionMode>* supported_encryption_schemes);
+ media::mojom::KeySystemCapabilityPtr* key_system_capability);
} // namespace content
diff --git a/chromium/content/public/renderer/platform_event_observer.h b/chromium/content/public/renderer/platform_event_observer.h
index b62d169a137..ab8008544b5 100644
--- a/chromium/content/public/renderer/platform_event_observer.h
+++ b/chromium/content/public/renderer/platform_event_observer.h
@@ -28,10 +28,6 @@ class PlatformEventObserverBase {
virtual void Start(blink::WebPlatformEventListener* listener) = 0;
virtual void Stop() = 0;
-
- // Helper method that allows an sub-class to write its own test helper.
- // The |data| type MUST be known from the caller.
- virtual void SendFakeDataForTesting(void* data) { }
};
// PlatformEventObserver<> defines the basic skeleton for an object requesting
diff --git a/chromium/content/public/renderer/render_frame.h b/chromium/content/public/renderer/render_frame.h
index b1c8604d292..292a3abb701 100644
--- a/chromium/content/public/renderer/render_frame.h
+++ b/chromium/content/public/renderer/render_frame.h
@@ -231,6 +231,12 @@ class CONTENT_EXPORT RenderFrame : public IPC::Listener,
size_t offset,
const gfx::Range& range) = 0;
+ // Notifies the frame's RenderView that the zoom has changed.
+ virtual void SetZoomLevel(double zoom_level) = 0;
+
+ // Returns the page's zoom level from the frame's RenderView.
+ virtual double GetZoomLevel() const = 0;
+
// Adds |message| to the DevTools console.
virtual void AddMessageToConsole(ConsoleMessageLevel level,
const std::string& message) = 0;
diff --git a/chromium/content/public/renderer/render_frame_observer.h b/chromium/content/public/renderer/render_frame_observer.h
index 74a031ad10c..2f1f46075b2 100644
--- a/chromium/content/public/renderer/render_frame_observer.h
+++ b/chromium/content/public/renderer/render_frame_observer.h
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/strings/string16.h"
#include "content/common/content_export.h"
+#include "content/public/common/resource_type.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
#include "mojo/public/cpp/system/message_pipe.h"
@@ -30,6 +31,11 @@ struct WebURLError;
class WebWorkerFetchContext;
}
+namespace network {
+struct ResourceResponseHead;
+struct URLLoaderCompletionStatus;
+} // namespace network
+
namespace content {
class RendererPpapiHost;
@@ -123,6 +129,25 @@ class CONTENT_EXPORT RenderFrameObserver : public IPC::Listener,
virtual void DidObserveNewCssPropertyUsage(int css_property,
bool is_animated) {}
+ // Notification when the renderer a response started, completed or canceled.
+ // Complete or Cancel is guaranteed to be called for a response that started.
+ // |request_id| uniquely identifies the request within this render frame.
+ virtual void DidStartResponse(
+ int request_id,
+ const network::ResourceResponseHead& response_head,
+ content::ResourceType resource_type) {}
+ virtual void DidCompleteResponse(
+ int request_id,
+ const network::URLLoaderCompletionStatus& status) {}
+ virtual void DidCancelResponse(int request_id) {}
+
+ // Notification when the renderer observes data used during the page load.
+ // This is used for page load metrics. |received_data_length| is the received
+ // network bytes. |resource_id| uniquely identifies the resource within this
+ // render frame.
+ virtual void DidReceiveTransferSizeUpdate(int resource_id,
+ int received_data_length) {}
+
// Called when the focused node has changed to |node|.
virtual void FocusedNodeChanged(const blink::WebNode& node) {}
diff --git a/chromium/content/public/renderer/render_view.h b/chromium/content/public/renderer/render_view.h
index ee8c5779144..21f3b487f13 100644
--- a/chromium/content/public/renderer/render_view.h
+++ b/chromium/content/public/renderer/render_view.h
@@ -70,7 +70,7 @@ 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.
+ // Returns the page's zoom level for the render view.
virtual float GetZoomLevel() const = 0;
// Gets WebKit related preferences associated with this view.
diff --git a/chromium/content/public/renderer/renderer_gamepad_provider.h b/chromium/content/public/renderer/renderer_gamepad_provider.h
index 723ea1d0d27..fe5e69ec08d 100644
--- a/chromium/content/public/renderer/renderer_gamepad_provider.h
+++ b/chromium/content/public/renderer/renderer_gamepad_provider.h
@@ -22,9 +22,7 @@ namespace content {
class RendererGamepadProvider
: public PlatformEventObserver<blink::WebGamepadListener> {
public:
- explicit RendererGamepadProvider(RenderThread* thread)
- : PlatformEventObserver<blink::WebGamepadListener>(thread) { }
-
+ RendererGamepadProvider() {}
~RendererGamepadProvider() override {}
// Provides latest snapshot of gamepads.
diff --git a/chromium/content/public/renderer/renderer_ppapi_host.h b/chromium/content/public/renderer/renderer_ppapi_host.h
index b376692d4fc..5d569710e3a 100644
--- a/chromium/content/public/renderer/renderer_ppapi_host.h
+++ b/chromium/content/public/renderer/renderer_ppapi_host.h
@@ -9,8 +9,10 @@
#include "base/callback_forward.h"
#include "base/files/file.h"
+#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
#include "base/process/process.h"
#include "content/common/content_export.h"
#include "ipc/ipc_platform_file.h"
@@ -119,6 +121,12 @@ class RendererPpapiHost {
// message fails, the returned handle is properly closed by the IPC system.
virtual base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
const base::SharedMemoryHandle& handle) = 0;
+ virtual base::UnsafeSharedMemoryRegion
+ ShareUnsafeSharedMemoryRegionWithRemote(
+ const base::UnsafeSharedMemoryRegion& region) = 0;
+ virtual base::ReadOnlySharedMemoryRegion
+ ShareReadOnlySharedMemoryRegionWithRemote(
+ const base::ReadOnlySharedMemoryRegion& region) = 0;
// Returns true if the plugin is running in process.
virtual bool IsRunningInProcess() const = 0;
diff --git a/chromium/content/public/renderer/request_peer.h b/chromium/content/public/renderer/request_peer.h
index dfd650e57c3..237fef4afca 100644
--- a/chromium/content/public/renderer/request_peer.h
+++ b/chromium/content/public/renderer/request_peer.h
@@ -76,15 +76,6 @@ class CONTENT_EXPORT RequestPeer {
virtual void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) = 0;
- // Called when a chunk of response data is downloaded. This method may be
- // called multiple times or not at all if an error occurs. This method is
- // only called if RequestInfo::download_to_file was set to true, and in
- // that case, OnReceivedData will not be called.
- // The encoded_data_length is the length of the encoded data transferred
- // over the network, which could be different from data length (e.g. for
- // gzipped content).
- virtual void OnDownloadedData(int len, int encoded_data_length) = 0;
-
// Called when a chunk of response data is available. This method may
// be called multiple times or not at all if an error occurs.
virtual void OnReceivedData(std::unique_ptr<ReceivedData> data) = 0;
diff --git a/chromium/content/public/test/android/BUILD.gn b/chromium/content/public/test/android/BUILD.gn
index 08de4404b1c..956c87c17d5 100644
--- a/chromium/content/public/test/android/BUILD.gn
+++ b/chromium/content/public/test/android/BUILD.gn
@@ -23,7 +23,6 @@ android_library("content_java_test_support") {
"//base:base_java",
"//base:base_java_test_support",
"//content/public/android:content_java",
- "//device/geolocation:geolocation_java_test_support",
"//third_party/android_support_test_runner:runner_java",
"//third_party/junit:junit",
"//ui/android:ui_java",
@@ -48,7 +47,6 @@ 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/TestSelectionPopupController.java",
"javatests/src/org/chromium/content/browser/test/util/TestTouchUtils.java",
diff --git a/chromium/content/public/test/test_service.mojom b/chromium/content/public/test/test_service.mojom
index f0f0eedd910..166e45e99a9 100644
--- a/chromium/content/public/test/test_service.mojom
+++ b/chromium/content/public/test/test_service.mojom
@@ -12,6 +12,10 @@ interface TestService {
// a connection error for the utility process.
DoTerminateProcess() => ();
+ // Crashes the current process. Meant to test that crash notifications are
+ // being sent correctly.
+ DoCrashImmediately() => ();
+
// Tries to create a temporary folder. Requires a sandbox to succeed.
CreateFolder() => (bool succeeded);
diff --git a/chromium/content/public/utility/content_utility_client.h b/chromium/content/public/utility/content_utility_client.h
index 56f16390d26..f78fe8dafd5 100644
--- a/chromium/content/public/utility/content_utility_client.h
+++ b/chromium/content/public/utility/content_utility_client.h
@@ -33,6 +33,9 @@ class CONTENT_EXPORT ContentUtilityClient {
virtual void RegisterNetworkBinders(
service_manager::BinderRegistry* registry) {}
+
+ virtual void RegisterAudioBinders(service_manager::BinderRegistry* registry) {
+ }
};
} // namespace content
diff --git a/chromium/content/public/utility/utility_thread.h b/chromium/content/public/utility/utility_thread.h
index f17e367044a..5acc89a518f 100644
--- a/chromium/content/public/utility/utility_thread.h
+++ b/chromium/content/public/utility/utility_thread.h
@@ -29,7 +29,7 @@ class CONTENT_EXPORT UtilityThread : virtual public ChildThread {
// Initializes blink if it hasn't already been initialized.
virtual void EnsureBlinkInitialized() = 0;
-#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
// Initializes blink with web sandbox support.
virtual void EnsureBlinkInitializedWithSandboxSupport() = 0;
#endif
diff --git a/chromium/content/renderer/BUILD.gn b/chromium/content/renderer/BUILD.gn
index 4f9c35e697b..d97b7082177 100644
--- a/chromium/content/renderer/BUILD.gn
+++ b/chromium/content/renderer/BUILD.gn
@@ -45,8 +45,6 @@ target(link_target_type, "renderer") {
"android/renderer_date_time_picker.h",
"android/synchronous_compositor_proxy.cc",
"android/synchronous_compositor_proxy.h",
- "android/synchronous_compositor_proxy_mojo.cc",
- "android/synchronous_compositor_proxy_mojo.h",
"android/synchronous_compositor_registry.h",
"android/synchronous_layer_tree_frame_sink.cc",
"android/synchronous_layer_tree_frame_sink.h",
@@ -69,10 +67,6 @@ target(link_target_type, "renderer") {
"child_frame_compositing_helper.cc",
"child_frame_compositing_helper.h",
"child_frame_compositor.h",
- "child_message_filter.cc",
- "child_message_filter.h",
- "clipboard_utils.cc",
- "clipboard_utils.h",
"content_security_policy_util.cc",
"content_security_policy_util.h",
"context_menu_params_builder.cc",
@@ -81,11 +75,6 @@ target(link_target_type, "renderer") {
"crash_helpers.h",
"cursor_utils.cc",
"cursor_utils.h",
- "device_sensors/device_motion_event_pump.cc",
- "device_sensors/device_motion_event_pump.h",
- "device_sensors/device_orientation_event_pump.cc",
- "device_sensors/device_orientation_event_pump.h",
- "device_sensors/device_sensor_event_pump.h",
"devtools/render_widget_screen_metrics_emulator.cc",
"devtools/render_widget_screen_metrics_emulator.h",
"devtools/render_widget_screen_metrics_emulator_delegate.h",
@@ -136,8 +125,6 @@ target(link_target_type, "renderer") {
"frame_blame_context.h",
"frame_owner_properties.cc",
"frame_owner_properties.h",
- "gamepad_shared_memory_reader.cc",
- "gamepad_shared_memory_reader.h",
"gpu/actions_parser.cc",
"gpu/actions_parser.h",
"gpu/compositor_dependencies.h",
@@ -145,11 +132,11 @@ target(link_target_type, "renderer") {
"gpu/frame_swap_message_queue.h",
"gpu/gpu_benchmarking_extension.cc",
"gpu/gpu_benchmarking_extension.h",
+ "gpu/layer_tree_view.cc",
+ "gpu/layer_tree_view.h",
+ "gpu/layer_tree_view_delegate.h",
"gpu/queue_message_swap_promise.cc",
"gpu/queue_message_swap_promise.h",
- "gpu/render_widget_compositor.cc",
- "gpu/render_widget_compositor.h",
- "gpu/render_widget_compositor_delegate.h",
"gpu/stream_texture_host_android.cc",
"gpu/stream_texture_host_android.h",
"history_entry.cc",
@@ -246,8 +233,12 @@ target(link_target_type, "renderer") {
"loader/web_url_loader_impl.h",
"loader/web_url_request_util.cc",
"loader/web_url_request_util.h",
+ "loader/web_worker_fetch_context_impl.cc",
+ "loader/web_worker_fetch_context_impl.h",
"loader/weburlresponse_extradata_impl.cc",
"loader/weburlresponse_extradata_impl.h",
+ "low_memory_mode_controller.cc",
+ "low_memory_mode_controller.h",
"manifest/manifest_change_notifier.cc",
"manifest/manifest_change_notifier.h",
"manifest/manifest_manager.cc",
@@ -262,25 +253,27 @@ target(link_target_type, "renderer") {
"media/android/media_player_renderer_client_factory.h",
"media/android/renderer_media_player_manager.cc",
"media/android/renderer_media_player_manager.h",
- "media/android/renderer_surface_view_manager.cc",
- "media/android/renderer_surface_view_manager.h",
"media/android/stream_texture_factory.cc",
"media/android/stream_texture_factory.h",
"media/android/stream_texture_wrapper_impl.cc",
"media/android/stream_texture_wrapper_impl.h",
+ "media/audio/audio_device_factory.cc",
+ "media/audio/audio_device_factory.h",
+ "media/audio/audio_input_ipc_factory.cc",
+ "media/audio/audio_input_ipc_factory.h",
+ "media/audio/audio_output_ipc_factory.cc",
+ "media/audio/audio_output_ipc_factory.h",
+ "media/audio/audio_renderer_mixer_manager.cc",
+ "media/audio/audio_renderer_mixer_manager.h",
+ "media/audio/audio_renderer_sink_cache.h",
+ "media/audio/audio_renderer_sink_cache_impl.cc",
+ "media/audio/audio_renderer_sink_cache_impl.h",
+ "media/audio/mojo_audio_input_ipc.cc",
+ "media/audio/mojo_audio_input_ipc.h",
+ "media/audio/mojo_audio_output_ipc.cc",
+ "media/audio/mojo_audio_output_ipc.h",
"media/audio_decoder.cc",
"media/audio_decoder.h",
- "media/audio_device_factory.cc",
- "media/audio_device_factory.h",
- "media/audio_input_ipc_factory.cc",
- "media/audio_input_ipc_factory.h",
- "media/audio_output_ipc_factory.cc",
- "media/audio_output_ipc_factory.h",
- "media/audio_renderer_mixer_manager.cc",
- "media/audio_renderer_mixer_manager.h",
- "media/audio_renderer_sink_cache.h",
- "media/audio_renderer_sink_cache_impl.cc",
- "media/audio_renderer_sink_cache_impl.h",
"media/gpu/gpu_video_accelerator_factories_impl.cc",
"media/gpu/gpu_video_accelerator_factories_impl.h",
"media/media_factory.cc",
@@ -291,10 +284,6 @@ target(link_target_type, "renderer") {
"media/midi/midi_message_filter.h",
"media/midi/renderer_webmidiaccessor_impl.cc",
"media/midi/renderer_webmidiaccessor_impl.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",
"media/render_media_client.h",
"media/render_media_log.cc",
@@ -379,6 +368,8 @@ target(link_target_type, "renderer") {
"media/web_media_element_source_utils.h",
"media/webrtc/audio_codec_factory.cc",
"media/webrtc/audio_codec_factory.h",
+ "media/webrtc/fake_rtc_rtp_transceiver.cc",
+ "media/webrtc/fake_rtc_rtp_transceiver.h",
"media/webrtc/media_stream_remote_video_source.cc",
"media/webrtc/media_stream_remote_video_source.h",
"media/webrtc/media_stream_track_metrics.cc",
@@ -410,6 +401,8 @@ target(link_target_type, "renderer") {
"media/webrtc/rtc_rtp_receiver.h",
"media/webrtc/rtc_rtp_sender.cc",
"media/webrtc/rtc_rtp_sender.h",
+ "media/webrtc/rtc_rtp_transceiver.cc",
+ "media/webrtc/rtc_rtp_transceiver.h",
"media/webrtc/rtc_stats.cc",
"media/webrtc/rtc_stats.h",
"media/webrtc/rtc_video_decoder.cc",
@@ -424,6 +417,8 @@ target(link_target_type, "renderer") {
"media/webrtc/stun_field_trial.h",
"media/webrtc/track_observer.cc",
"media/webrtc/track_observer.h",
+ "media/webrtc/transceiver_state_surfacer.cc",
+ "media/webrtc/transceiver_state_surfacer.h",
"media/webrtc/two_keys_adapter_map.h",
"media/webrtc/webrtc_audio_device_impl.cc",
"media/webrtc/webrtc_audio_device_impl.h",
@@ -433,18 +428,15 @@ target(link_target_type, "renderer") {
"media/webrtc/webrtc_audio_renderer.h",
"media/webrtc/webrtc_audio_sink.cc",
"media/webrtc/webrtc_audio_sink.h",
- "media/webrtc/webrtc_media_stream_adapter.cc",
- "media/webrtc/webrtc_media_stream_adapter.h",
- "media/webrtc/webrtc_media_stream_adapter_map.cc",
- "media/webrtc/webrtc_media_stream_adapter_map.h",
"media/webrtc/webrtc_media_stream_track_adapter.cc",
"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_set_description_observer.cc",
+ "media/webrtc/webrtc_set_description_observer.h",
"media/webrtc/webrtc_uma_histograms.cc",
"media/webrtc/webrtc_uma_histograms.h",
+ "media/webrtc/webrtc_util.h",
"media/webrtc/webrtc_video_capturer_adapter.cc",
"media/webrtc/webrtc_video_capturer_adapter.h",
"media/webrtc/webrtc_video_frame_adapter.cc",
@@ -484,6 +476,8 @@ target(link_target_type, "renderer") {
"mojo/blink_interface_registry_impl.h",
"mouse_lock_dispatcher.cc",
"mouse_lock_dispatcher.h",
+ "navigation_client.cc",
+ "navigation_client.h",
"navigation_state_impl.cc",
"navigation_state_impl.h",
"net_info_helper.cc",
@@ -573,8 +567,6 @@ target(link_target_type, "renderer") {
"service_worker/service_worker_context_client.h",
"service_worker/service_worker_fetch_context_impl.cc",
"service_worker/service_worker_fetch_context_impl.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",
@@ -597,8 +589,6 @@ target(link_target_type, "renderer") {
"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_worker/embedded_shared_worker_stub.cc",
"shared_worker/embedded_shared_worker_stub.h",
"shared_worker/shared_worker_client_impl.cc",
@@ -609,8 +599,6 @@ target(link_target_type, "renderer") {
"shared_worker/shared_worker_repository.h",
"skia_benchmarking_extension.cc",
"skia_benchmarking_extension.h",
- "speech_recognition_dispatcher.cc",
- "speech_recognition_dispatcher.h",
"stats_collection_controller.cc",
"stats_collection_controller.h",
"stats_collection_observer.cc",
@@ -627,22 +615,12 @@ target(link_target_type, "renderer") {
"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",
"web_ui_extension.h",
"web_ui_extension_data.cc",
"web_ui_extension_data.h",
"webgraphicscontext3d_provider_impl.cc",
"webgraphicscontext3d_provider_impl.h",
- "webpublicsuffixlist_impl.cc",
- "webpublicsuffixlist_impl.h",
- "webscrollbarbehavior_impl_aura.cc",
- "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",
]
@@ -671,6 +649,7 @@ target(link_target_type, "renderer") {
"//base:i18n",
"//cc",
"//cc/animation",
+ "//cc/mojo_embedder",
"//cc/paint",
"//components/discardable_memory/client",
"//components/metrics",
@@ -740,7 +719,6 @@ target(link_target_type, "renderer") {
"//third_party/opus",
"//third_party/webrtc/api:libjingle_logging_api",
"//third_party/webrtc/api:libjingle_peerconnection_api",
- "//third_party/webrtc/api:optional",
"//third_party/webrtc/api:rtc_stats_api",
"//third_party/webrtc/api/audio:aec3_factory",
"//third_party/webrtc/api/audio_codecs:audio_codecs_api",
@@ -809,13 +787,6 @@ target(link_target_type, "renderer") {
]
}
- if (is_mac) {
- sources -= [
- "webscrollbarbehavior_impl_aura.cc",
- "webscrollbarbehavior_impl_aura.h",
- ]
- }
-
if (is_android) {
# Add back the Linux file which Android shares.
set_sources_assignment_filter([])
@@ -839,7 +810,10 @@ target(link_target_type, "renderer") {
}
if (is_linux) {
- deps += [ "//services/service_manager/zygote" ]
+ deps += [
+ "//components/services/font/public/cpp",
+ "//services/service_manager/zygote",
+ ]
}
if (is_fuchsia) {
diff --git a/chromium/content/renderer/OWNERS b/chromium/content/renderer/OWNERS
index 9b1fac28656..d646d43c6cc 100644
--- a/chromium/content/renderer/OWNERS
+++ b/chromium/content/renderer/OWNERS
@@ -14,3 +14,4 @@ per-file render_view_impl.*=fsamuel@chromium.org
per-file render_widget.*=fsamuel@chromium.org
per-file child_frame_compositor.*=fsamuel@chromium.org
per-file child_frame_compositing_helper.*=fsamuel@chromium.org
+per-file render_frame_metadata*=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 1e9b5afec74..3b504e29872 100644
--- a/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc
+++ b/chromium/content/renderer/accessibility/blink_ax_enum_conversion.cc
@@ -113,6 +113,10 @@ ax::mojom::Role AXRoleFromBlink(blink::WebAXRole role) {
return ax::mojom::Role::kComboBoxMenuButton;
case blink::kWebAXRoleComplementary:
return ax::mojom::Role::kComplementary;
+ case blink::kWebAXRoleContentDeletion:
+ return ax::mojom::Role::kContentDeletion;
+ case blink::kWebAXRoleContentInsertion:
+ return ax::mojom::Role::kContentInsertion;
case blink::kWebAXRoleContentInfo:
return ax::mojom::Role::kContentInfo;
case blink::kWebAXRoleDate:
@@ -420,6 +424,8 @@ ax::mojom::Event AXEventFromBlink(blink::WebAXEvent event) {
return ax::mojom::Event::kClicked;
case blink::kWebAXEventDocumentSelectionChanged:
return ax::mojom::Event::kDocumentSelectionChanged;
+ case blink::kWebAXEventDocumentTitleChanged:
+ return ax::mojom::Event::kDocumentTitleChanged;
case blink::kWebAXEventExpandedChanged:
return ax::mojom::Event::kExpandedChanged;
case blink::kWebAXEventFocus:
diff --git a/chromium/content/renderer/accessibility/blink_ax_tree_source.cc b/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
index 2e67e084f9c..f43d7214fd2 100644
--- a/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/chromium/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -39,6 +39,7 @@
#include "third_party/blink/public/web/web_view.h"
#include "ui/accessibility/ax_enum_util.h"
#include "ui/accessibility/ax_role_properties.h"
+#include "ui/gfx/geometry/vector2d_f.h"
using base::ASCIIToUTF16;
using base::UTF16ToUTF8;
@@ -395,6 +396,13 @@ void BlinkAXTreeSource::GetChildren(
if (!is_iframe && !IsParentUnignoredOf(parent, child))
continue;
+ // Skip table headers and columns, they're only needed on Mac
+ // and soon we'll get rid of this code entirely.
+ if (child.Role() == blink::kWebAXRoleColumn ||
+ child.Role() == blink::kWebAXRoleLayoutTableColumn ||
+ child.Role() == blink::kWebAXRoleTableHeaderContainer)
+ continue;
+
out_children->push_back(child);
}
}
@@ -442,8 +450,24 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
src.GetRelativeBounds(offset_container, bounds_in_container,
container_transform, &clips_children);
dst->location = bounds_in_container;
+#if !defined(OS_ANDROID) && !defined(OS_MACOSX)
+ if (src.Equals(root())) {
+ WebView* web_view = render_frame_->GetRenderView()->GetWebView();
+ std::unique_ptr<gfx::Transform> container_transform_gfx =
+ std::make_unique<gfx::Transform>(container_transform);
+ container_transform_gfx->Scale(web_view->PageScaleFactor(),
+ web_view->PageScaleFactor());
+ container_transform_gfx->Translate(
+ gfx::Vector2dF(-web_view->VisualViewportOffset().x,
+ -web_view->VisualViewportOffset().y));
+ if (!container_transform_gfx->IsIdentity())
+ dst->transform = std::move(container_transform_gfx);
+ } else if (!container_transform.isIdentity())
+ dst->transform = base::WrapUnique(new gfx::Transform(container_transform));
+#else
if (!container_transform.isIdentity())
dst->transform = base::WrapUnique(new gfx::Transform(container_transform));
+#endif // !defined(OS_ANDROID) && !defined(OS_MACOSX)
if (!offset_container.IsDetached())
dst->offset_container_id = offset_container.AxID();
if (clips_children)
@@ -457,7 +481,8 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
blink::WebString web_name = src.GetName(nameFrom, nameObjects);
if ((!web_name.IsEmpty() && !web_name.IsNull()) ||
nameFrom == blink::kWebAXNameFromAttributeExplicitlyEmpty) {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kName, web_name.Utf8());
+ TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kName,
+ web_name.Utf8());
dst->SetNameFrom(AXNameFromFromBlink(nameFrom));
AddIntListAttributeFromWebObjects(
ax::mojom::IntListAttribute::kLabelledbyIds, nameObjects, dst);
@@ -468,8 +493,8 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
blink::WebString web_description =
src.Description(nameFrom, descriptionFrom, descriptionObjects);
if (!web_description.IsEmpty()) {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kDescription,
- web_description.Utf8());
+ TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kDescription,
+ web_description.Utf8());
dst->AddIntAttribute(
ax::mojom::IntAttribute::kDescriptionFrom,
static_cast<int32_t>(AXDescriptionFromFromBlink(descriptionFrom)));
@@ -478,11 +503,11 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
}
if (src.ValueDescription().length()) {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kValue,
- src.ValueDescription().Utf8());
+ TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kValue,
+ src.ValueDescription().Utf8());
} else {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kValue,
- src.StringValue().Utf8());
+ TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kValue,
+ src.StringValue().Utf8());
}
switch (src.Restriction()) {
@@ -499,8 +524,8 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
}
if (!src.Url().IsEmpty())
- dst->AddStringAttribute(ax::mojom::StringAttribute::kUrl,
- src.Url().GetString().Utf8());
+ TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kUrl,
+ src.Url().GetString().Utf8());
// The following set of attributes are only accessed when the accessibility
// mode is set to screen reader mode, otherwise only the more basic
@@ -508,8 +533,9 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
if (accessibility_mode_.has_mode(ui::AXMode::kScreenReader)) {
blink::WebString web_placeholder = src.Placeholder(nameFrom);
if (!web_placeholder.IsEmpty())
- dst->AddStringAttribute(ax::mojom::StringAttribute::kPlaceholder,
- web_placeholder.Utf8());
+ TruncateAndAddStringAttribute(dst,
+ ax::mojom::StringAttribute::kPlaceholder,
+ web_placeholder.Utf8());
if (dst->role == ax::mojom::Role::kColorWell)
dst->AddIntAttribute(ax::mojom::IntAttribute::kColorValue,
@@ -541,8 +567,9 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
WebAXObject parent = ParentObjectUnignored(src);
if (src.FontFamily().length()) {
if (parent.IsNull() || parent.FontFamily() != src.FontFamily())
- dst->AddStringAttribute(ax::mojom::StringAttribute::kFontFamily,
- src.FontFamily().Utf8());
+ TruncateAndAddStringAttribute(dst,
+ ax::mojom::StringAttribute::kFontFamily,
+ src.FontFamily().Utf8());
}
// Font size is in pixels.
@@ -566,8 +593,9 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
}
if (src.InvalidState() == blink::kWebAXInvalidStateOther &&
src.AriaInvalidValue().length()) {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kAriaInvalidValue,
- src.AriaInvalidValue().Utf8());
+ TruncateAndAddStringAttribute(
+ dst, ax::mojom::StringAttribute::kAriaInvalidValue,
+ src.AriaInvalidValue().Utf8());
}
if (src.CheckedState()) {
@@ -618,13 +646,14 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
}
if (src.AccessKey().length()) {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kAccessKey,
- src.AccessKey().Utf8());
+ TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kAccessKey,
+ src.AccessKey().Utf8());
}
if (src.AriaAutoComplete().length()) {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kAutoComplete,
- src.AriaAutoComplete().Utf8());
+ TruncateAndAddStringAttribute(dst,
+ ax::mojom::StringAttribute::kAutoComplete,
+ src.AriaAutoComplete().Utf8());
}
if (src.Action() != blink::WebAXDefaultActionVerb::kNone) {
@@ -632,20 +661,21 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
}
if (src.HasComputedStyle()) {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kDisplay,
- src.ComputedStyleDisplay().Utf8());
+ TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kDisplay,
+ src.ComputedStyleDisplay().Utf8());
}
if (src.Language().length()) {
if (parent.IsNull() || parent.Language() != src.Language())
- dst->AddStringAttribute(ax::mojom::StringAttribute::kLanguage,
- src.Language().Utf8());
+ TruncateAndAddStringAttribute(
+ dst, ax::mojom::StringAttribute::kLanguage, src.Language().Utf8());
}
if (src.KeyboardShortcut().length() &&
!dst->HasStringAttribute(ax::mojom::StringAttribute::kKeyShortcuts)) {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kKeyShortcuts,
- src.KeyboardShortcut().Utf8());
+ TruncateAndAddStringAttribute(dst,
+ ax::mojom::StringAttribute::kKeyShortcuts,
+ src.KeyboardShortcut().Utf8());
}
if (!src.NextOnLine().IsDetached()) {
@@ -715,11 +745,13 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
dst->AddBoolAttribute(ax::mojom::BoolAttribute::kLiveAtomic,
src.LiveRegionAtomic());
if (!src.LiveRegionStatus().IsEmpty()) {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kLiveStatus,
- src.LiveRegionStatus().Utf8());
+ TruncateAndAddStringAttribute(dst,
+ ax::mojom::StringAttribute::kLiveStatus,
+ src.LiveRegionStatus().Utf8());
}
- dst->AddStringAttribute(ax::mojom::StringAttribute::kLiveRelevant,
- src.LiveRegionRelevant().Utf8());
+ TruncateAndAddStringAttribute(dst,
+ ax::mojom::StringAttribute::kLiveRelevant,
+ src.LiveRegionRelevant().Utf8());
// If we are not at the root of an atomic live region.
if (src.ContainerLiveRegionAtomic() &&
!src.LiveRegionRoot().IsDetached() && !src.LiveRegionAtomic()) {
@@ -730,10 +762,11 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
src.ContainerLiveRegionAtomic());
dst->AddBoolAttribute(ax::mojom::BoolAttribute::kContainerLiveBusy,
src.ContainerLiveRegionBusy());
- dst->AddStringAttribute(ax::mojom::StringAttribute::kContainerLiveStatus,
- src.ContainerLiveRegionStatus().Utf8());
- dst->AddStringAttribute(
- ax::mojom::StringAttribute::kContainerLiveRelevant,
+ TruncateAndAddStringAttribute(
+ dst, ax::mojom::StringAttribute::kContainerLiveStatus,
+ src.ContainerLiveRegionStatus().Utf8());
+ TruncateAndAddStringAttribute(
+ dst, ax::mojom::StringAttribute::kContainerLiveRelevant,
src.ContainerLiveRegionRelevant().Utf8());
}
@@ -774,12 +807,10 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
}
if (dst->role == ax::mojom::Role::kRootWebArea)
- dst->AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag,
- "#document");
+ TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kHtmlTag,
+ "#document");
- const bool is_table_like_role = dst->role == ax::mojom::Role::kTable ||
- dst->role == ax::mojom::Role::kGrid ||
- dst->role == ax::mojom::Role::kTreeGrid;
+ const bool is_table_like_role = ui::IsTableLikeRole(dst->role);
if (is_table_like_role) {
int column_count = src.ColumnCount();
int row_count = src.RowCount();
@@ -788,10 +819,6 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
column_count);
dst->AddIntAttribute(ax::mojom::IntAttribute::kTableRowCount,
row_count);
- WebAXObject header = src.HeaderContainerObject();
- if (!header.IsDetached())
- dst->AddIntAttribute(ax::mojom::IntAttribute::kTableHeaderId,
- header.AxID());
}
int aria_colcount = src.AriaColumnCount();
@@ -814,15 +841,6 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
header.AxID());
}
- if (dst->role == ax::mojom::Role::kColumn) {
- dst->AddIntAttribute(ax::mojom::IntAttribute::kTableColumnIndex,
- src.ColumnIndex());
- WebAXObject header = src.ColumnHeader();
- if (!header.IsDetached())
- dst->AddIntAttribute(ax::mojom::IntAttribute::kTableColumnHeaderId,
- header.AxID());
- }
-
if (dst->role == ax::mojom::Role::kCell ||
dst->role == ax::mojom::Role::kRowHeader ||
dst->role == ax::mojom::Role::kColumnHeader ||
@@ -873,8 +891,9 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
// TODO(ctguil): The tagName in WebKit is lower cased but
// HTMLElement::nodeName calls localNameUpper. Consider adding
// a WebElement method that returns the original lower cased tagName.
- dst->AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag,
- base::ToLowerASCII(element.TagName().Utf8()));
+ TruncateAndAddStringAttribute(
+ dst, ax::mojom::StringAttribute::kHtmlTag,
+ base::ToLowerASCII(element.TagName().Utf8()));
for (unsigned i = 0; i < element.AttributeCount(); ++i) {
std::string name =
base::ToLowerASCII(element.AttributeLocalName(i).Utf8());
@@ -886,8 +905,9 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
// and remove ifdef.
#if defined(OS_WIN)
if (dst->role == ax::mojom::Role::kMath && element.InnerHTML().length()) {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kInnerHtml,
- element.InnerHTML().Utf8());
+ TruncateAndAddStringAttribute(dst,
+ ax::mojom::StringAttribute::kInnerHtml,
+ element.InnerHTML().Utf8());
}
#endif
}
@@ -907,12 +927,13 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
// ARIA role.
if (element.HasAttribute("role")) {
- dst->AddStringAttribute(ax::mojom::StringAttribute::kRole,
- element.GetAttribute("role").Utf8());
+ TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kRole,
+ element.GetAttribute("role").Utf8());
} else {
std::string role = GetEquivalentAriaRoleString(dst->role);
if (!role.empty())
- dst->AddStringAttribute(ax::mojom::StringAttribute::kRole, role);
+ TruncateAndAddStringAttribute(dst, ax::mojom::StringAttribute::kRole,
+ role);
}
// Browser plugin (used in a <webview>).
@@ -967,6 +988,9 @@ void BlinkAXTreeSource::SerializeNode(WebAXObject src,
}
if (dst->id == image_data_node_id_) {
+ // In general, string attributes should be truncated using
+ // TruncateAndAddStringAttribute, but ImageDataUrl contains a data url
+ // representing an image, so add it directly using AddStringAttribute.
dst->AddStringAttribute(ax::mojom::StringAttribute::kImageDataUrl,
src.ImageDataUrl(max_image_data_size_).Utf8());
}
@@ -991,4 +1015,18 @@ WebAXObject BlinkAXTreeSource::ComputeRoot() const {
return WebAXObject();
}
+void BlinkAXTreeSource::TruncateAndAddStringAttribute(
+ AXContentNodeData* dst,
+ ax::mojom::StringAttribute attribute,
+ const std::string& value) const {
+ if (value.size() > BlinkAXTreeSource::kMaxStringAttributeLength) {
+ std::string truncated;
+ base::TruncateUTF8ToByteSize(
+ value, BlinkAXTreeSource::kMaxStringAttributeLength, &truncated);
+ dst->AddStringAttribute(attribute, truncated);
+ } else {
+ dst->AddStringAttribute(attribute, value);
+ }
+}
+
} // namespace content
diff --git a/chromium/content/renderer/accessibility/blink_ax_tree_source.h b/chromium/content/renderer/accessibility/blink_ax_tree_source.h
index 4447c4eb800..2adf7bf8cbe 100644
--- a/chromium/content/renderer/accessibility/blink_ax_tree_source.h
+++ b/chromium/content/renderer/accessibility/blink_ax_tree_source.h
@@ -110,6 +110,11 @@ class BlinkAXTreeSource
blink::WebAXObject ComputeRoot() const;
+ uint32_t kMaxStringAttributeLength = 10000;
+ void TruncateAndAddStringAttribute(AXContentNodeData* dst,
+ ax::mojom::StringAttribute attribute,
+ const std::string& value) const;
+
RenderFrameImpl* render_frame_;
ui::AXMode accessibility_mode_;
diff --git a/chromium/content/renderer/accessibility/render_accessibility_impl.cc b/chromium/content/renderer/accessibility/render_accessibility_impl.cc
index 79fd36cffc5..05fbd8de672 100644
--- a/chromium/content/renderer/accessibility/render_accessibility_impl.cc
+++ b/chromium/content/renderer/accessibility/render_accessibility_impl.cc
@@ -29,7 +29,9 @@
#include "third_party/blink/public/web/web_user_gesture_indicator.h"
#include "third_party/blink/public/web/web_view.h"
#include "ui/accessibility/ax_enum_util.h"
+#include "ui/accessibility/ax_event.h"
#include "ui/accessibility/ax_node.h"
+#include "ui/accessibility/ax_role_properties.h"
using blink::WebAXObject;
using blink::WebDocument;
@@ -183,7 +185,7 @@ bool RenderAccessibilityImpl::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(RenderAccessibilityImpl, message)
IPC_MESSAGE_HANDLER(AccessibilityMsg_PerformAction, OnPerformAction)
- IPC_MESSAGE_HANDLER(AccessibilityMsg_Events_ACK, OnEventsAck)
+ IPC_MESSAGE_HANDLER(AccessibilityMsg_EventBundle_ACK, OnEventsAck)
IPC_MESSAGE_HANDLER(AccessibilityMsg_HitTest, OnHitTest)
IPC_MESSAGE_HANDLER(AccessibilityMsg_Reset, OnReset)
IPC_MESSAGE_HANDLER(AccessibilityMsg_FatalError, OnFatalError)
@@ -272,7 +274,7 @@ void RenderAccessibilityImpl::HandleAXEvent(const blink::WebAXObject& obj,
// Force the newly focused node to be re-serialized so we include its
// inline text boxes.
if (event == ax::mojom::Event::kFocus)
- serializer_.DeleteClientSubtree(obj);
+ serializer_.InvalidateSubtree(obj);
#endif
// If some cell IDs have been added or removed, we need to update the whole
@@ -281,7 +283,7 @@ void RenderAccessibilityImpl::HandleAXEvent(const blink::WebAXObject& obj,
event == ax::mojom::Event::kChildrenChanged) {
WebAXObject table_like_object = obj.ParentObject();
if (!table_like_object.IsDetached()) {
- serializer_.DeleteClientSubtree(table_like_object);
+ serializer_.InvalidateSubtree(table_like_object);
HandleAXEvent(table_like_object, ax::mojom::Event::kChildrenChanged);
}
}
@@ -292,13 +294,13 @@ void RenderAccessibilityImpl::HandleAXEvent(const blink::WebAXObject& obj,
event == ax::mojom::Event::kChildrenChanged) {
WebAXObject popup_like_object = obj.ParentObject();
if (!popup_like_object.IsDetached()) {
- serializer_.DeleteClientSubtree(popup_like_object);
+ serializer_.InvalidateSubtree(popup_like_object);
HandleAXEvent(popup_like_object, ax::mojom::Event::kChildrenChanged);
}
}
// Add the accessibility object to our cache and ensure it's valid.
- AccessibilityHostMsg_EventParams acc_event;
+ ui::AXEvent acc_event;
acc_event.id = obj.AxID();
acc_event.event_type = event;
@@ -410,18 +412,23 @@ void RenderAccessibilityImpl::SendPendingAccessibilityEvents() {
// Make a copy of the events, because it's possible that
// actions inside this loop will cause more events to be
// queued up.
- std::vector<AccessibilityHostMsg_EventParams> src_events = pending_events_;
+ std::vector<ui::AXEvent> src_events = pending_events_;
pending_events_.clear();
- // Generate an event message from each Blink event.
- std::vector<AccessibilityHostMsg_EventParams> event_msgs;
+ // The serialized event bundle to send to the browser.
+ AccessibilityHostMsg_EventBundleParams bundle;
+
+ // Keep track of nodes in the tree that need to be updated.
+ std::vector<DirtyObject> dirty_objects;
// If there's a layout complete message, we need to send location changes.
bool had_layout_complete_messages = false;
+ ScopedFreezeBlinkAXTreeSource freeze(&tree_source_);
+
// Loop over each event and generate an updated event message.
for (size_t i = 0; i < src_events.size(); ++i) {
- AccessibilityHostMsg_EventParams& event = src_events[i];
+ ui::AXEvent& event = src_events[i];
if (event.event_type == ax::mojom::Event::kLayoutComplete)
had_layout_complete_messages = true;
@@ -435,40 +442,64 @@ void RenderAccessibilityImpl::SendPendingAccessibilityEvents() {
while (!obj.IsDetached() && obj.AccessibilityIsIgnored())
obj = obj.ParentObject();
- ScopedFreezeBlinkAXTreeSource freeze(&tree_source_);
-
// Make sure it's a descendant of our root node - exceptions include the
// scroll area that's the parent of the main document (we ignore it), and
// possibly nodes attached to a different document.
if (!tree_source_.IsInTree(obj))
continue;
- AccessibilityHostMsg_EventParams event_msg;
- event_msg.event_type = event.event_type;
- event_msg.id = event.id;
- event_msg.event_from = event.event_from;
- event_msg.action_request_id = event.action_request_id;
+ bundle.events.push_back(event);
+
+ // Whenever there's a change within a table, invalidate the
+ // whole table so that row and cell indexes are recomputed.
+ ax::mojom::Role role = AXRoleFromBlink(obj.Role());
+ if (ui::IsTableLikeRole(role) || role == ax::mojom::Role::kRow ||
+ ui::IsCellOrTableHeaderRole(role)) {
+ auto table = obj;
+ while (!table.IsDetached() &&
+ !ui::IsTableLikeRole(AXRoleFromBlink(table.Role())))
+ table = table.ParentObject();
+ if (!table.IsDetached())
+ serializer_.InvalidateSubtree(table);
+ }
+
+ VLOG(1) << "Accessibility event: " << ui::ToString(event.event_type)
+ << " on node id " << event.id;
+
+ DirtyObject dirty_object;
+ dirty_object.obj = obj;
+ dirty_object.event_from = event.event_from;
+ dirty_objects.push_back(dirty_object);
+ }
+
+ // Now serialize all dirty objects. Keep track of IDs serialized
+ // so we don't have to serialize the same node twice.
+ std::set<int32_t> already_serialized_ids;
+ for (size_t i = 0; i < dirty_objects.size(); i++) {
+ auto obj = dirty_objects[i].obj;
+ if (already_serialized_ids.find(obj.AxID()) != already_serialized_ids.end())
+ continue;
+ AXContentTreeUpdate update;
+ update.event_from = dirty_objects[i].event_from;
// If there's a plugin, force the tree data to be generated in every
// message so the plugin can merge its own tree data changes.
if (plugin_tree_source_)
- event_msg.update.has_tree_data = true;
+ update.has_tree_data = true;
- if (!serializer_.SerializeChanges(obj, &event_msg.update)) {
+ if (!serializer_.SerializeChanges(obj, &update)) {
VLOG(1) << "Failed to serialize one accessibility event.";
continue;
}
if (plugin_tree_source_)
- AddPluginTreeToUpdate(&event_msg.update);
-
- event_msgs.push_back(event_msg);
+ AddPluginTreeToUpdate(&update);
// For each node in the update, set the location in our map from
// ids to locations.
- for (size_t j = 0; j < event_msg.update.nodes.size(); ++j) {
- ui::AXNodeData& src = event_msg.update.nodes[j];
- ui::AXRelativeBounds& dst = locations_[event_msg.update.nodes[j].id];
+ for (size_t j = 0; j < update.nodes.size(); ++j) {
+ ui::AXNodeData& src = update.nodes[j];
+ ui::AXRelativeBounds& dst = locations_[update.nodes[j].id];
dst.offset_container_id = src.offset_container_id;
dst.bounds = src.location;
dst.transform.reset(nullptr);
@@ -476,13 +507,16 @@ void RenderAccessibilityImpl::SendPendingAccessibilityEvents() {
dst.transform.reset(new gfx::Transform(*src.transform));
}
- VLOG(1) << "Accessibility event: " << ui::ToString(event.event_type)
- << " on node id " << event_msg.id
- << "\n" << event_msg.update.ToString();
+ for (size_t j = 0; j < update.nodes.size(); ++j)
+ already_serialized_ids.insert(update.nodes[j].id);
+
+ bundle.updates.push_back(update);
+
+ VLOG(1) << "Accessibility tree update:\n" << update.ToString();
}
- Send(new AccessibilityHostMsg_Events(routing_id(), event_msgs, reset_token_,
- ack_token_));
+ Send(new AccessibilityHostMsg_EventBundle(routing_id(), bundle, reset_token_,
+ ack_token_));
reset_token_ = 0;
if (had_layout_complete_messages)
@@ -495,7 +529,6 @@ void RenderAccessibilityImpl::SendLocationChanges() {
std::vector<AccessibilityHostMsg_LocationChangeParams> messages;
// Update layout on the root of the tree.
- ScopedFreezeBlinkAXTreeSource freeze(&tree_source_);
WebAXObject root = tree_source_.GetRoot();
if (!root.UpdateLayoutAndCheckValidity())
return;
@@ -616,7 +649,7 @@ void RenderAccessibilityImpl::OnPerformAction(
target.SetSequentialFocusNavigationStartingPoint();
break;
case ax::mojom::Action::kSetValue:
- target.SetValue(blink::WebString::FromUTF16(data.value));
+ target.SetValue(blink::WebString::FromUTF8(data.value));
HandleAXEvent(target, ax::mojom::Event::kValueChanged);
break;
case ax::mojom::Action::kShowContextMenu:
@@ -700,7 +733,7 @@ void RenderAccessibilityImpl::OnLoadInlineTextBoxes(
// This object may not be a leaf node. Force the whole subtree to be
// re-serialized.
- serializer_.DeleteClientSubtree(obj);
+ serializer_.InvalidateSubtree(obj);
// Explicitly send a tree change update event now.
HandleAXEvent(obj, ax::mojom::Event::kTreeChanged);
@@ -719,7 +752,7 @@ void RenderAccessibilityImpl::OnGetImageData(
if (document.IsNull())
return;
- serializer_.DeleteClientSubtree(obj);
+ serializer_.InvalidateSubtree(obj);
HandleAXEvent(obj, ax::mojom::Event::kImageFrameUpdated);
}
diff --git a/chromium/content/renderer/accessibility/render_accessibility_impl.h b/chromium/content/renderer/accessibility/render_accessibility_impl.h
index 3d3563a7ffc..f2c5d3fb805 100644
--- a/chromium/content/renderer/accessibility/render_accessibility_impl.h
+++ b/chromium/content/renderer/accessibility/render_accessibility_impl.h
@@ -20,8 +20,6 @@
#include "ui/accessibility/ax_tree_serializer.h"
#include "ui/gfx/geometry/rect_f.h"
-struct AccessibilityHostMsg_EventParams;
-
namespace blink {
class WebDocument;
class WebNode;
@@ -29,6 +27,7 @@ class WebNode;
namespace ui {
struct AXActionData;
+struct AXEvent;
}
namespace content {
@@ -115,6 +114,11 @@ class CONTENT_EXPORT RenderAccessibilityImpl
void SendLocationChanges();
private:
+ struct DirtyObject {
+ blink::WebAXObject obj;
+ ax::mojom::EventFrom event_from;
+ };
+
// RenderFrameObserver implementation.
void OnDestruct() override;
@@ -137,7 +141,7 @@ class CONTENT_EXPORT RenderAccessibilityImpl
// Events from Blink are collected until they are ready to be
// sent to the browser.
- std::vector<AccessibilityHostMsg_EventParams> pending_events_;
+ std::vector<ui::AXEvent> pending_events_;
// The adapter that exposes Blink's accessibility tree to AXTreeSerializer.
BlinkAXTreeSource tree_source_;
diff --git a/chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc b/chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
index 07978a44eec..e812e74632f 100644
--- a/chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
+++ b/chromium/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
@@ -67,28 +67,26 @@ class RenderAccessibilityImplTest : public RenderViewTest {
void SetMode(ui::AXMode mode) { frame()->OnSetAccessibilityMode(mode); }
- void GetAllAccEvents(
- std::vector<AccessibilityHostMsg_EventParams>* param_list) {
+ void GetLastAccessibilityEventBundle(
+ AccessibilityHostMsg_EventBundleParams* event_bundle) {
const IPC::Message* message =
- sink_->GetUniqueMessageMatching(AccessibilityHostMsg_Events::ID);
+ sink_->GetUniqueMessageMatching(AccessibilityHostMsg_EventBundle::ID);
ASSERT_TRUE(message);
- std::tuple<std::vector<AccessibilityHostMsg_EventParams>, int, int> param;
- AccessibilityHostMsg_Events::Read(message, &param);
- *param_list = std::get<0>(param);
+ std::tuple<AccessibilityHostMsg_EventBundleParams, int, int> param;
+ AccessibilityHostMsg_EventBundle::Read(message, &param);
+ *event_bundle = std::get<0>(param);
}
- void GetLastAccEvent(
- AccessibilityHostMsg_EventParams* params) {
- std::vector<AccessibilityHostMsg_EventParams> param_list;
- GetAllAccEvents(&param_list);
- ASSERT_GE(param_list.size(), 1U);
- *params = param_list[0];
+ AXContentTreeUpdate GetLastAccUpdate() {
+ AccessibilityHostMsg_EventBundleParams event_bundle;
+ GetLastAccessibilityEventBundle(&event_bundle);
+ CHECK_GE(event_bundle.updates.size(), 1U);
+ return event_bundle.updates[event_bundle.updates.size() - 1];
}
int CountAccessibilityNodesSentToBrowser() {
- AccessibilityHostMsg_EventParams event;
- GetLastAccEvent(&event);
- return event.update.nodes.size();
+ AXContentTreeUpdate update = GetLastAccUpdate();
+ return update.nodes.size();
}
protected:
@@ -130,9 +128,8 @@ TEST_F(RenderAccessibilityImplTest, SendFullAccessibilityTreeOnReload) {
EXPECT_EQ(1, CountAccessibilityNodesSentToBrowser());
{
// Make sure it's the root object that was updated.
- AccessibilityHostMsg_EventParams event;
- GetLastAccEvent(&event);
- EXPECT_EQ(root_obj.AxID(), event.update.nodes[0].id);
+ AXContentTreeUpdate update = GetLastAccUpdate();
+ EXPECT_EQ(root_obj.AxID(), update.nodes[0].id);
}
// If we reload the page and send a event, we should send
@@ -197,15 +194,14 @@ TEST_F(RenderAccessibilityImplTest, HideAccessibilityObject) {
accessibility->HandleAXEvent(node_a, ax::mojom::Event::kChildrenChanged);
accessibility->SendPendingAccessibilityEvents();
- AccessibilityHostMsg_EventParams event;
- GetLastAccEvent(&event);
- ASSERT_EQ(2U, event.update.nodes.size());
+ AXContentTreeUpdate update = GetLastAccUpdate();
+ ASSERT_EQ(2U, update.nodes.size());
// RenderAccessibilityImpl notices that 'C' is being reparented,
// so it clears the subtree rooted at 'A', then updates 'A' and then 'C'.
- EXPECT_EQ(node_a.AxID(), event.update.node_id_to_clear);
- EXPECT_EQ(node_a.AxID(), event.update.nodes[0].id);
- EXPECT_EQ(node_c.AxID(), event.update.nodes[1].id);
+ EXPECT_EQ(node_a.AxID(), update.node_id_to_clear);
+ EXPECT_EQ(node_a.AxID(), update.nodes[0].id);
+ EXPECT_EQ(node_c.AxID(), update.nodes[1].id);
EXPECT_EQ(2, CountAccessibilityNodesSentToBrowser());
}
@@ -245,14 +241,13 @@ TEST_F(RenderAccessibilityImplTest, ShowAccessibilityObject) {
accessibility->HandleAXEvent(node_a, ax::mojom::Event::kChildrenChanged);
accessibility->SendPendingAccessibilityEvents();
- AccessibilityHostMsg_EventParams event;
- GetLastAccEvent(&event);
-
- ASSERT_EQ(3U, event.update.nodes.size());
- EXPECT_EQ(node_a.AxID(), event.update.node_id_to_clear);
- EXPECT_EQ(node_a.AxID(), event.update.nodes[0].id);
- EXPECT_EQ(node_b.AxID(), event.update.nodes[1].id);
- EXPECT_EQ(node_c.AxID(), event.update.nodes[2].id);
+ AXContentTreeUpdate update = GetLastAccUpdate();
+
+ ASSERT_EQ(3U, update.nodes.size());
+ EXPECT_EQ(node_a.AxID(), update.node_id_to_clear);
+ EXPECT_EQ(node_a.AxID(), update.nodes[0].id);
+ EXPECT_EQ(node_b.AxID(), update.nodes[1].id);
+ EXPECT_EQ(node_c.AxID(), update.nodes[2].id);
EXPECT_EQ(3, CountAccessibilityNodesSentToBrowser());
}
diff --git a/chromium/content/renderer/android/synchronous_compositor_proxy.cc b/chromium/content/renderer/android/synchronous_compositor_proxy.cc
index 441d8e860b7..0ad58b0748e 100644
--- a/chromium/content/renderer/android/synchronous_compositor_proxy.cc
+++ b/chromium/content/renderer/android/synchronous_compositor_proxy.cc
@@ -23,6 +23,7 @@ namespace content {
SynchronousCompositorProxy::SynchronousCompositorProxy(
ui::SynchronousInputHandlerProxy* input_handler_proxy)
: input_handler_proxy_(input_handler_proxy),
+ binding_(this),
use_in_process_zero_copy_software_draw_(
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kSingleProcess)),
@@ -31,6 +32,7 @@ SynchronousCompositorProxy::SynchronousCompositorProxy(
max_page_scale_factor_(0.f),
need_animate_scroll_(false),
need_invalidate_count_(0u),
+ invalidate_needs_draw_(false),
did_activate_pending_tree_count_(0u) {
DCHECK(input_handler_proxy_);
}
@@ -66,7 +68,7 @@ void SynchronousCompositorProxy::SetNeedsSynchronousAnimateInput() {
SendSetNeedsBeginFramesIfNeeded();
} else {
need_animate_scroll_ = true;
- Invalidate();
+ Invalidate(true);
}
}
@@ -94,8 +96,9 @@ void SynchronousCompositorProxy::UpdateRootLayerState(
}
}
-void SynchronousCompositorProxy::Invalidate() {
+void SynchronousCompositorProxy::Invalidate(bool needs_draw) {
++need_invalidate_count_;
+ invalidate_needs_draw_ |= needs_draw;
SendAsyncRendererStateIfNeeded();
}
@@ -114,6 +117,7 @@ void SynchronousCompositorProxy::PopulateCommonParams(
params->min_page_scale_factor = min_page_scale_factor_;
params->max_page_scale_factor = max_page_scale_factor_;
params->need_invalidate_count = need_invalidate_count_;
+ params->invalidate_needs_draw = invalidate_needs_draw_;
params->did_activate_pending_tree_count = did_activate_pending_tree_count_;
if (!compute_scroll_called_via_ipc_)
params->need_animate_scroll = need_animate_scroll_;
@@ -130,6 +134,7 @@ void SynchronousCompositorProxy::DemandDrawHwAsync(
void SynchronousCompositorProxy::DemandDrawHw(
const SyncCompositorDemandDrawHwParams& params,
DemandDrawHwCallback callback) {
+ invalidate_needs_draw_ = false;
hardware_draw_reply_ = std::move(callback);
if (layer_tree_frame_sink_) {
@@ -149,6 +154,10 @@ void SynchronousCompositorProxy::DemandDrawHw(
}
}
+void SynchronousCompositorProxy::WillSkipDraw() {
+ layer_tree_frame_sink_->WillSkipDraw();
+}
+
struct SynchronousCompositorProxy::SharedMemoryWithSize {
base::SharedMemory shm;
const size_t buffer_size;
@@ -172,6 +181,7 @@ void SynchronousCompositorProxy::ZeroSharedMemory() {
void SynchronousCompositorProxy::DemandDrawSw(
const SyncCompositorDemandDrawSwParams& params,
DemandDrawSwCallback callback) {
+ invalidate_needs_draw_ = false;
software_draw_reply_ = std::move(callback);
if (layer_tree_frame_sink_) {
SkCanvas* sk_canvas_for_draw = SynchronousCompositorGetSkCanvas();
@@ -336,4 +346,55 @@ uint32_t SynchronousCompositorProxy::NextMetadataVersion() {
return ++metadata_version_;
}
+void SynchronousCompositorProxy::SendDemandDrawHwAsyncReply(
+ const content::SyncCompositorCommonRendererParams&,
+ uint32_t layer_tree_frame_sink_id,
+ uint32_t metadata_version,
+ base::Optional<viz::CompositorFrame> frame) {
+ control_host_->ReturnFrame(layer_tree_frame_sink_id, metadata_version,
+ std::move(frame));
+}
+
+void SynchronousCompositorProxy::SendBeginFrameResponse(
+ const content::SyncCompositorCommonRendererParams& param) {
+ control_host_->BeginFrameResponse(param);
+}
+
+void SynchronousCompositorProxy::SendAsyncRendererStateIfNeeded() {
+ if (hardware_draw_reply_ || software_draw_reply_ || zoom_by_reply_ || !host_)
+ return;
+
+ SyncCompositorCommonRendererParams params;
+ PopulateCommonParams(&params);
+ host_->UpdateState(params);
+}
+
+void SynchronousCompositorProxy::SendSetNeedsBeginFrames(
+ bool needs_begin_frames) {
+ needs_begin_frame_ = needs_begin_frames;
+ if (host_)
+ host_->SetNeedsBeginFrames(needs_begin_frames);
+}
+
+void SynchronousCompositorProxy::LayerTreeFrameSinkCreated() {
+ DCHECK(layer_tree_frame_sink_);
+ if (host_)
+ host_->LayerTreeFrameSinkCreated();
+}
+
+void SynchronousCompositorProxy::BindChannel(
+ mojom::SynchronousCompositorControlHostPtr control_host,
+ mojom::SynchronousCompositorHostAssociatedPtrInfo host,
+ mojom::SynchronousCompositorAssociatedRequest compositor_request) {
+ control_host_ = std::move(control_host);
+ host_.Bind(std::move(host));
+ binding_.Bind(std::move(compositor_request));
+
+ if (layer_tree_frame_sink_)
+ LayerTreeFrameSinkCreated();
+
+ if (needs_begin_frame_)
+ host_->SetNeedsBeginFrames(true);
+}
+
} // namespace content
diff --git a/chromium/content/renderer/android/synchronous_compositor_proxy.h b/chromium/content/renderer/android/synchronous_compositor_proxy.h
index e3ed37f29cc..8319840a6d4 100644
--- a/chromium/content/renderer/android/synchronous_compositor_proxy.h
+++ b/chromium/content/renderer/android/synchronous_compositor_proxy.h
@@ -40,6 +40,10 @@ class SynchronousCompositorProxy : public ui::SynchronousInputHandler,
~SynchronousCompositorProxy() override;
void Init();
+ void BindChannel(
+ mojom::SynchronousCompositorControlHostPtr control_host,
+ mojom::SynchronousCompositorHostAssociatedPtrInfo host,
+ mojom::SynchronousCompositorAssociatedRequest compositor_request);
// ui::SynchronousInputHandler overrides.
void SetNeedsSynchronousAnimateInput() final;
@@ -52,7 +56,7 @@ class SynchronousCompositorProxy : public ui::SynchronousInputHandler,
// SynchronousLayerTreeFrameSinkClient overrides.
void DidActivatePendingTree() final;
- void Invalidate() final;
+ void Invalidate(bool needs_draw) final;
void SubmitCompositorFrame(uint32_t layer_tree_frame_sink_id,
viz::CompositorFrame frame) final;
void SetNeedsBeginFrames(bool needs_begin_frames) final;
@@ -74,6 +78,7 @@ class SynchronousCompositorProxy : public ui::SynchronousInputHandler,
SetSharedMemoryCallback callback) final;
void DemandDrawSw(const SyncCompositorDemandDrawSwParams& params,
DemandDrawSwCallback callback) final;
+ void WillSkipDraw() final;
void ZeroSharedMemory() final;
void ZoomBy(float zoom_delta, const gfx::Point& anchor, ZoomByCallback) final;
void SetMemoryPolicy(uint32_t bytes_limit) final;
@@ -85,16 +90,16 @@ class SynchronousCompositorProxy : public ui::SynchronousInputHandler,
void SetBeginFrameSourcePaused(bool paused) final;
protected:
- virtual void SendSetNeedsBeginFrames(bool needs_begin_frames) = 0;
- virtual void SendAsyncRendererStateIfNeeded() = 0;
- virtual void LayerTreeFrameSinkCreated() = 0;
- virtual void SendBeginFrameResponse(
- const content::SyncCompositorCommonRendererParams&) = 0;
- virtual void SendDemandDrawHwAsyncReply(
+ void SendSetNeedsBeginFrames(bool needs_begin_frames);
+ void SendAsyncRendererStateIfNeeded();
+ void LayerTreeFrameSinkCreated();
+ void SendBeginFrameResponse(
+ const content::SyncCompositorCommonRendererParams&);
+ void SendDemandDrawHwAsyncReply(
const content::SyncCompositorCommonRendererParams&,
uint32_t layer_tree_frame_sink_id,
uint32_t metadata_version,
- base::Optional<viz::CompositorFrame>) = 0;
+ base::Optional<viz::CompositorFrame>);
DemandDrawHwCallback hardware_draw_reply_;
DemandDrawSwCallback software_draw_reply_;
@@ -109,10 +114,14 @@ class SynchronousCompositorProxy : public ui::SynchronousInputHandler,
struct SharedMemoryWithSize;
ui::SynchronousInputHandlerProxy* const input_handler_proxy_;
+ mojom::SynchronousCompositorControlHostPtr control_host_;
+ mojom::SynchronousCompositorHostAssociatedPtr host_;
+ mojo::AssociatedBinding<mojom::SynchronousCompositor> binding_;
const bool use_in_process_zero_copy_software_draw_;
bool compute_scroll_called_via_ipc_ = false;
bool browser_needs_begin_frame_state_ = false;
+ bool needs_begin_frame_ = false;
bool needs_begin_frame_for_frame_sink_ = false;
bool needs_begin_frame_for_animate_input_ = false;
@@ -129,6 +138,7 @@ class SynchronousCompositorProxy : public ui::SynchronousInputHandler,
float max_page_scale_factor_;
bool need_animate_scroll_;
uint32_t need_invalidate_count_;
+ bool invalidate_needs_draw_;
uint32_t did_activate_pending_tree_count_;
uint32_t metadata_version_ = 0u;
diff --git a/chromium/content/renderer/android/synchronous_compositor_proxy_mojo.cc b/chromium/content/renderer/android/synchronous_compositor_proxy_mojo.cc
deleted file mode 100644
index 3c3019de1c0..00000000000
--- a/chromium/content/renderer/android/synchronous_compositor_proxy_mojo.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/android/synchronous_compositor_proxy_mojo.h"
-
-namespace content {
-
-SynchronousCompositorProxyMojo::SynchronousCompositorProxyMojo(
- ui::SynchronousInputHandlerProxy* input_handler_proxy)
- : SynchronousCompositorProxy(input_handler_proxy), binding_(this) {}
-
-SynchronousCompositorProxyMojo::~SynchronousCompositorProxyMojo() {}
-
-void SynchronousCompositorProxyMojo::SendDemandDrawHwAsyncReply(
- const content::SyncCompositorCommonRendererParams&,
- uint32_t layer_tree_frame_sink_id,
- uint32_t metadata_version,
- base::Optional<viz::CompositorFrame> frame) {
- control_host_->ReturnFrame(layer_tree_frame_sink_id, metadata_version,
- std::move(frame));
-}
-
-void SynchronousCompositorProxyMojo::SendBeginFrameResponse(
- const content::SyncCompositorCommonRendererParams& param) {
- control_host_->BeginFrameResponse(param);
-}
-
-void SynchronousCompositorProxyMojo::SendAsyncRendererStateIfNeeded() {
- if (hardware_draw_reply_ || software_draw_reply_ || zoom_by_reply_ || !host_)
- return;
-
- SyncCompositorCommonRendererParams params;
- PopulateCommonParams(&params);
- host_->UpdateState(params);
-}
-
-void SynchronousCompositorProxyMojo::SendSetNeedsBeginFrames(
- bool needs_begin_frames) {
- needs_begin_frame_ = needs_begin_frames;
- if (host_)
- host_->SetNeedsBeginFrames(needs_begin_frames);
-}
-
-void SynchronousCompositorProxyMojo::LayerTreeFrameSinkCreated() {
- DCHECK(layer_tree_frame_sink_);
- if (host_)
- host_->LayerTreeFrameSinkCreated();
-}
-
-void SynchronousCompositorProxyMojo::BindChannel(
- mojom::SynchronousCompositorControlHostPtr control_host,
- mojom::SynchronousCompositorHostAssociatedPtrInfo host,
- mojom::SynchronousCompositorAssociatedRequest compositor_request) {
- control_host_ = std::move(control_host);
- host_.Bind(std::move(host));
- binding_.Bind(std::move(compositor_request));
-
- if (layer_tree_frame_sink_)
- LayerTreeFrameSinkCreated();
-
- if (needs_begin_frame_)
- host_->SetNeedsBeginFrames(true);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/android/synchronous_compositor_proxy_mojo.h b/chromium/content/renderer/android/synchronous_compositor_proxy_mojo.h
deleted file mode 100644
index 236b938db92..00000000000
--- a/chromium/content/renderer/android/synchronous_compositor_proxy_mojo.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_PROXY_MOJO_H_
-#define CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_PROXY_MOJO_H_
-
-#include "content/renderer/android/synchronous_compositor_proxy.h"
-
-namespace content {
-
-// This class implements the SynchronousCompositorProxy with
-// IPC messaging backed by mojo.
-class SynchronousCompositorProxyMojo : public SynchronousCompositorProxy {
- public:
- SynchronousCompositorProxyMojo(
- ui::SynchronousInputHandlerProxy* input_handler_proxy);
- ~SynchronousCompositorProxyMojo() override;
-
- void BindChannel(
- mojom::SynchronousCompositorControlHostPtr control_host,
- mojom::SynchronousCompositorHostAssociatedPtrInfo host,
- mojom::SynchronousCompositorAssociatedRequest compositor_request);
-
- protected:
- void SendSetNeedsBeginFrames(bool needs_begin_frames) final;
- void SendAsyncRendererStateIfNeeded() final;
- void LayerTreeFrameSinkCreated() final;
- void SendBeginFrameResponse(
- const content::SyncCompositorCommonRendererParams&) final;
- void SendDemandDrawHwAsyncReply(
- const content::SyncCompositorCommonRendererParams&,
- uint32_t layer_tree_frame_sink_id,
- uint32_t metadata_version,
- base::Optional<viz::CompositorFrame>) final;
-
- private:
- mojom::SynchronousCompositorControlHostPtr control_host_;
- mojom::SynchronousCompositorHostAssociatedPtr host_;
- mojo::AssociatedBinding<mojom::SynchronousCompositor> binding_;
- bool needs_begin_frame_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(SynchronousCompositorProxyMojo);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_ANDROID_SYNCHRONOUS_COMPOSITOR_PROXY_MOJO_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 2b66ba1ad54..24c569eea65 100644
--- a/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.cc
+++ b/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.cc
@@ -86,6 +86,12 @@ class SynchronousLayerTreeFrameSink::SoftwareOutputSurface
void BindFramebuffer() override {}
void SetDrawRectangle(const gfx::Rect& rect) override {}
void SwapBuffers(viz::OutputSurfaceFrame frame) override {}
+#if BUILDFLAG(ENABLE_VULKAN)
+ gpu::VulkanSurface* GetVulkanSurface() override {
+ NOTIMPLEMENTED();
+ return nullptr;
+ }
+#endif
void Reshape(const gfx::Size& size,
float scale_factor,
const gfx::ColorSpace& color_space,
@@ -154,7 +160,10 @@ bool SynchronousLayerTreeFrameSink::BindToClient(
if (!cc::LayerTreeFrameSink::BindToClient(sink_client))
return false;
- frame_sink_manager_ = std::make_unique<viz::FrameSinkManagerImpl>();
+ // The SharedBitmapManager is null since software compositing is not supported
+ // or used on Android.
+ frame_sink_manager_ = std::make_unique<viz::FrameSinkManagerImpl>(
+ /*shared_bitmap_manager=*/nullptr);
client_->SetBeginFrameSource(synthetic_begin_frame_source_
? synthetic_begin_frame_source_.get()
@@ -361,10 +370,10 @@ void SynchronousLayerTreeFrameSink::FallbackTickFired() {
frame_swap_message_queue_->NotifyFramesAreDiscarded(false);
}
-void SynchronousLayerTreeFrameSink::Invalidate() {
+void SynchronousLayerTreeFrameSink::Invalidate(bool needs_draw) {
DCHECK(CalledOnValidThread());
if (sync_client_)
- sync_client_->Invalidate();
+ sync_client_->Invalidate(needs_draw);
if (!fallback_tick_pending_) {
fallback_tick_.Reset(
@@ -413,6 +422,12 @@ void SynchronousLayerTreeFrameSink::DemandDrawSw(SkCanvas* canvas) {
InvokeComposite(transform, viewport);
}
+void SynchronousLayerTreeFrameSink::WillSkipDraw() {
+ CancelFallbackTick();
+ client_->OnDraw(gfx::Transform(), gfx::Rect(), in_software_draw_,
+ true /*skip_draw*/);
+}
+
void SynchronousLayerTreeFrameSink::InvokeComposite(
const gfx::Transform& transform,
const gfx::Rect& viewport) {
@@ -425,7 +440,8 @@ void SynchronousLayerTreeFrameSink::InvokeComposite(
// SetExternalTilePriorityConstraints), surely this could be more clear?
gfx::Transform adjusted_transform = transform;
adjusted_transform.matrix().postTranslate(-viewport.x(), -viewport.y(), 0);
- client_->OnDraw(adjusted_transform, viewport, in_software_draw_);
+ client_->OnDraw(adjusted_transform, viewport, in_software_draw_,
+ false /*skip_draw*/);
if (did_submit_frame_) {
// This must happen after unwinding the stack and leaving the compositor.
@@ -500,12 +516,7 @@ void SynchronousLayerTreeFrameSink::DidReceiveCompositorFrameAck(
void SynchronousLayerTreeFrameSink::DidPresentCompositorFrame(
uint32_t presentation_token,
- base::TimeTicks time,
- base::TimeDelta refresh,
- uint32_t flags) {}
-
-void SynchronousLayerTreeFrameSink::DidDiscardCompositorFrame(
- uint32_t presentation_token) {}
+ const gfx::PresentationFeedback& feedback) {}
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 380c3109a16..5177e340848 100644
--- a/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.h
+++ b/chromium/content/renderer/android/synchronous_layer_tree_frame_sink.h
@@ -50,7 +50,7 @@ class SynchronousCompositorRegistry;
class SynchronousLayerTreeFrameSinkClient {
public:
virtual void DidActivatePendingTree() = 0;
- virtual void Invalidate() = 0;
+ virtual void Invalidate(bool needs_draw) = 0;
virtual void SubmitCompositorFrame(uint32_t layer_tree_frame_sink_id,
viz::CompositorFrame frame) = 0;
virtual void SetNeedsBeginFrames(bool needs_begin_frames) = 0;
@@ -96,22 +96,21 @@ class SynchronousLayerTreeFrameSink
void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer,
const viz::SharedBitmapId& id) override;
void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override;
- void Invalidate() override;
+ void Invalidate(bool needs_draw) override;
// Partial SynchronousCompositor API implementation.
void DemandDrawHw(const gfx::Size& viewport_size,
const gfx::Rect& viewport_rect_for_tile_priority,
const gfx::Transform& transform_for_tile_priority);
void DemandDrawSw(SkCanvas* canvas);
+ void WillSkipDraw();
// 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 DidPresentCompositorFrame(
+ uint32_t presentation_token,
+ const gfx::PresentationFeedback& feedback) override;
void OnBeginFrame(const viz::BeginFrameArgs& args) override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
@@ -172,6 +171,7 @@ class SynchronousLayerTreeFrameSink
void DisplayDidDrawAndSwap() override {}
void DisplayDidReceiveCALayerParams(
const gfx::CALayerParams& ca_layer_params) override {}
+ void DisplayDidCompleteSwapWithSize(const gfx::Size& pixel_size) override {}
void DidSwapAfterSnapshotRequestReceived(
const std::vector<ui::LatencyInfo>& latency_info) override {}
};
diff --git a/chromium/content/renderer/appcache/web_application_cache_host_impl.cc b/chromium/content/renderer/appcache/web_application_cache_host_impl.cc
index ef2969aaa1c..8e1f7d18566 100644
--- a/chromium/content/renderer/appcache/web_application_cache_host_impl.cc
+++ b/chromium/content/renderer/appcache/web_application_cache_host_impl.cc
@@ -5,21 +5,19 @@
#include "content/renderer/appcache/web_application_cache_host_impl.h"
#include <stddef.h>
+#include <vector>
#include "base/compiler_specific.h"
#include "base/containers/id_map.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
-#include "content/public/common/browser_side_navigation_policy.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
-#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/platform/web_url_response.h"
using blink::WebApplicationCacheHost;
using blink::WebApplicationCacheHostClient;
using blink::WebString;
-using blink::WebURLRequest;
using blink::WebURL;
using blink::WebURLResponse;
using blink::WebVector;
@@ -70,7 +68,6 @@ WebApplicationCacheHostImpl::WebApplicationCacheHostImpl(
DCHECK(client && backend);
// PlzNavigate: The browser passes the ID to be used.
if (appcache_host_id != kAppCacheNoHostId) {
- DCHECK(IsBrowserSideNavigationEnabled());
all_hosts()->AddWithID(this, appcache_host_id);
host_id_ = appcache_host_id;
} else {
diff --git a/chromium/content/renderer/blob_storage/OWNERS b/chromium/content/renderer/blob_storage/OWNERS
index 471c08e8a01..d04a7d57277 100644
--- a/chromium/content/renderer/blob_storage/OWNERS
+++ b/chromium/content/renderer/blob_storage/OWNERS
@@ -1 +1,4 @@
dmurph@chromium.org
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>FileAPI
diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.cc b/chromium/content/renderer/browser_plugin/browser_plugin.cc
index d64895137a7..4d8251069ae 100644
--- a/chromium/content/renderer/browser_plugin/browser_plugin.cc
+++ b/chromium/content/renderer/browser_plugin/browser_plugin.cc
@@ -136,16 +136,16 @@ bool BrowserPlugin::OnMessageReceived(const IPC::Message& message) {
#endif
IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents,
OnShouldAcceptTouchEvents)
- IPC_MESSAGE_HANDLER(BrowserPluginMsg_SetChildFrameSurface,
- OnSetChildFrameSurface)
+ IPC_MESSAGE_HANDLER(BrowserPluginMsg_FirstSurfaceActivation,
+ OnFirstSurfaceActivation)
IPC_END_MESSAGE_MAP()
return handled;
}
-void BrowserPlugin::OnSetChildFrameSurface(
+void BrowserPlugin::OnFirstSurfaceActivation(
int browser_plugin_instance_id,
const viz::SurfaceInfo& surface_info) {
- if (!attached() || base::FeatureList::IsEnabled(features::kMash))
+ if (!attached() || !features::IsAshInBrowserProcess())
return;
if (!enable_surface_synchronization_) {
@@ -264,6 +264,10 @@ void BrowserPlugin::SynchronizeVisualProperties() {
sent_visual_properties_->screen_space_rect.size() !=
pending_visual_properties_.screen_space_rect.size();
+ bool zoom_changed =
+ !sent_visual_properties_ || sent_visual_properties_->zoom_level !=
+ pending_visual_properties_.zoom_level;
+
// Note that the following flag is true if the capture sequence number
// actually changed. That is, it is false if we did not have
// |sent_visual_properties_|, which is different from the other local flags
@@ -274,7 +278,7 @@ void BrowserPlugin::SynchronizeVisualProperties() {
pending_visual_properties_.capture_sequence_number;
bool synchronized_props_changed =
- !sent_visual_properties_ || size_changed ||
+ !sent_visual_properties_ || size_changed || zoom_changed ||
sent_visual_properties_->screen_info !=
pending_visual_properties_.screen_info ||
capture_sequence_number_changed;
@@ -316,7 +320,7 @@ void BrowserPlugin::SynchronizeVisualProperties() {
sent_visual_properties_ = pending_visual_properties_;
#if defined(USE_AURA)
- if (features::IsMashEnabled() && mus_embedded_frame_) {
+ if (!features::IsAshInBrowserProcess() && mus_embedded_frame_) {
mus_embedded_frame_->SetWindowBounds(GetLocalSurfaceId(),
FrameRectInPixels());
}
@@ -390,22 +394,19 @@ void BrowserPlugin::OnSetCursor(int browser_plugin_instance_id,
void BrowserPlugin::OnSetMouseLock(int browser_plugin_instance_id,
bool enable) {
- auto* render_frame =
- RenderFrameImpl::FromRoutingID(render_frame_routing_id());
- auto* render_view = static_cast<RenderViewImpl*>(
- render_frame ? render_frame->GetRenderView() : nullptr);
+ RenderWidget* render_widget = GetMainWidget();
if (enable) {
- if (mouse_locked_ || !render_view)
+ if (mouse_locked_ || !render_widget)
return;
- render_view->mouse_lock_dispatcher()->LockMouse(this);
+ render_widget->mouse_lock_dispatcher()->LockMouse(this);
} else {
if (!mouse_locked_) {
OnLockMouseACK(false);
return;
}
- if (!render_view)
+ if (!render_widget)
return;
- render_view->mouse_lock_dispatcher()->UnlockMouse(this);
+ render_widget->mouse_lock_dispatcher()->UnlockMouse(this);
}
}
@@ -413,7 +414,7 @@ void BrowserPlugin::OnSetMouseLock(int browser_plugin_instance_id,
void BrowserPlugin::OnSetMusEmbedToken(
int instance_id,
const base::UnguessableToken& embed_token) {
- DCHECK(base::FeatureList::IsEnabled(features::kMash));
+ DCHECK(!features::IsAshInBrowserProcess());
if (!attached_) {
pending_embed_token_ = embed_token;
} else {
@@ -444,6 +445,20 @@ float BrowserPlugin::GetDeviceScaleFactor() const {
return pending_visual_properties_.screen_info.device_scale_factor;
}
+RenderWidget* BrowserPlugin::GetMainWidget() const {
+ RenderFrameImpl* frame =
+ RenderFrameImpl::FromRoutingID(render_frame_routing_id());
+ if (frame) {
+ RenderViewImpl* render_view =
+ static_cast<RenderViewImpl*>(frame->GetRenderView());
+ if (render_view) {
+ return render_view->GetWidget();
+ }
+ }
+
+ return nullptr;
+}
+
void BrowserPlugin::UpdateInternalInstanceId() {
// This is a way to notify observers of our attributes that this plugin is
// available in render tree.
@@ -475,6 +490,11 @@ void BrowserPlugin::ScreenInfoChanged(const ScreenInfo& screen_info) {
SynchronizeVisualProperties();
}
+void BrowserPlugin::OnZoomLevelChanged(double zoom_level) {
+ pending_visual_properties_.zoom_level = zoom_level;
+ SynchronizeVisualProperties();
+}
+
void BrowserPlugin::UpdateCaptureSequenceNumber(
uint32_t capture_sequence_number) {
pending_visual_properties_.capture_sequence_number = capture_sequence_number;
@@ -483,12 +503,9 @@ void BrowserPlugin::UpdateCaptureSequenceNumber(
bool BrowserPlugin::ShouldGuestBeFocused() const {
bool embedder_focused = false;
- auto* render_frame =
- RenderFrameImpl::FromRoutingID(render_frame_routing_id());
- auto* render_view = static_cast<RenderViewImpl*>(
- render_frame ? render_frame->GetRenderView() : nullptr);
- if (render_view)
- embedder_focused = render_view->has_focus();
+ RenderWidget* render_widget = GetMainWidget();
+ if (render_widget)
+ embedder_focused = render_widget->has_focus();
return plugin_focused_ && embedder_focused;
}
@@ -539,12 +556,9 @@ void BrowserPlugin::Destroy() {
container_ = nullptr;
// Will be a no-op if the mouse is not currently locked.
- auto* render_frame =
- RenderFrameImpl::FromRoutingID(render_frame_routing_id());
- auto* render_view = static_cast<RenderViewImpl*>(
- render_frame ? render_frame->GetRenderView() : nullptr);
- if (render_view)
- render_view->mouse_lock_dispatcher()->OnLockTargetDestroyed(this);
+ RenderWidget* render_widget = GetMainWidget();
+ if (render_widget)
+ render_widget->mouse_lock_dispatcher()->OnLockTargetDestroyed(this);
task_runner_->DeleteSoon(FROM_HERE, this);
}
@@ -847,7 +861,7 @@ void BrowserPlugin::OnMusEmbeddedFrameSurfaceChanged(
void BrowserPlugin::OnMusEmbeddedFrameSinkIdAllocated(
const viz::FrameSinkId& frame_sink_id) {
// RendererWindowTreeClient should only call this when mus is hosting viz.
- DCHECK(base::FeatureList::IsEnabled(features::kMash));
+ DCHECK(!features::IsAshInBrowserProcess());
OnGuestReady(browser_plugin_instance_id_, frame_sink_id);
}
#endif
diff --git a/chromium/content/renderer/browser_plugin/browser_plugin.h b/chromium/content/renderer/browser_plugin/browser_plugin.h
index 8ab2c1b82ba..b3091678c58 100644
--- a/chromium/content/renderer/browser_plugin/browser_plugin.h
+++ b/chromium/content/renderer/browser_plugin/browser_plugin.h
@@ -81,6 +81,8 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
void ScreenInfoChanged(const ScreenInfo& screen_info);
+ void OnZoomLevelChanged(double zoom_level);
+
void UpdateCaptureSequenceNumber(uint32_t capture_sequence_number);
// Indicates whether the guest should be focused.
@@ -112,7 +114,7 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
bool SupportsInputMethod() const override;
bool CanProcessDrag() const override;
void UpdateAllLifecyclePhases() override {}
- void Paint(blink::WebCanvas* canvas, const blink::WebRect& rect) override {}
+ void Paint(cc::PaintCanvas* canvas, const blink::WebRect& rect) override {}
void UpdateGeometry(const blink::WebRect& window_rect,
const blink::WebRect& clip_rect,
const blink::WebRect& unobscured_rect,
@@ -176,6 +178,7 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
}
gfx::Rect FrameRectInPixels() const;
float GetDeviceScaleFactor() const;
+ RenderWidget* GetMainWidget() const;
const ScreenInfo& screen_info() const {
return pending_visual_properties_.screen_info;
@@ -201,8 +204,8 @@ class CONTENT_EXPORT BrowserPlugin : public blink::WebPlugin,
const gfx::Size& min_size,
const gfx::Size& max_size);
void OnDisableAutoResize(int browser_plugin_instance_id);
- void OnSetChildFrameSurface(int instance_id,
- const viz::SurfaceInfo& surface_info);
+ void OnFirstSurfaceActivation(int instance_id,
+ const viz::SurfaceInfo& surface_info);
void OnSetContentsOpaque(int instance_id, bool opaque);
void OnSetCursor(int instance_id, const WebCursor& cursor);
void OnSetMouseLock(int instance_id, bool enable);
diff --git a/chromium/content/renderer/child_frame_compositing_helper.cc b/chromium/content/renderer/child_frame_compositing_helper.cc
index 8ef6f5b20b7..ba7454e3faa 100644
--- a/chromium/content/renderer/child_frame_compositing_helper.cc
+++ b/chromium/content/renderer/child_frame_compositing_helper.cc
@@ -101,9 +101,6 @@ void ChildFrameCompositingHelper::SetPrimarySurfaceId(
void ChildFrameCompositingHelper::SetFallbackSurfaceId(
const viz::SurfaceId& surface_id,
const gfx::Size& frame_size_in_dip) {
- if (fallback_surface_id_ == surface_id)
- return;
-
fallback_surface_id_ = surface_id;
if (!surface_layer_) {
diff --git a/chromium/content/renderer/child_message_filter.cc b/chromium/content/renderer/child_message_filter.cc
deleted file mode 100644
index c212d4835fa..00000000000
--- a/chromium/content/renderer/child_message_filter.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/child_message_filter.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/location.h"
-#include "base/macros.h"
-#include "base/task_runner.h"
-#include "content/child/child_thread_impl.h"
-#include "content/child/thread_safe_sender.h"
-#include "ipc/message_filter.h"
-
-namespace content {
-
-class ChildMessageFilter::Internal : public IPC::MessageFilter {
- public:
- explicit Internal(ChildMessageFilter* filter) : filter_(filter) {}
-
- bool OnMessageReceived(const IPC::Message& msg) override {
- scoped_refptr<base::TaskRunner> runner =
- filter_->OverrideTaskRunnerForMessage(msg);
- if (runner.get() && !runner->RunsTasksInCurrentSequence()) {
- if (!runner->PostTask(
- FROM_HERE,
- base::BindOnce(
- base::IgnoreResult(&ChildMessageFilter::OnMessageReceived),
- filter_, msg)))
- filter_->OnStaleMessageReceived(msg);
- return true;
- }
-
- return filter_->OnMessageReceived(msg);
- }
-
- private:
- ~Internal() override {}
- scoped_refptr<ChildMessageFilter> filter_;
-
- DISALLOW_COPY_AND_ASSIGN(Internal);
-};
-
-bool ChildMessageFilter::Send(IPC::Message* message) {
- return thread_safe_sender_->Send(message);
-}
-
-base::TaskRunner* ChildMessageFilter::OverrideTaskRunnerForMessage(
- const IPC::Message& msg) {
- return nullptr;
-}
-
-ChildMessageFilter::ChildMessageFilter()
- : internal_(nullptr),
- thread_safe_sender_(ChildThreadImpl::current()->thread_safe_sender()) {}
-
-ChildMessageFilter::~ChildMessageFilter() {}
-
-IPC::MessageFilter* ChildMessageFilter::GetFilter() {
- if (!internal_)
- internal_ = new Internal(this);
- return internal_;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/child_message_filter.h b/chromium/content/renderer/child_message_filter.h
deleted file mode 100644
index d02cf3a09d3..00000000000
--- a/chromium/content/renderer/child_message_filter.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_CHILD_MESSAGE_FILTER_H_
-#define CONTENT_RENDERER_CHILD_MESSAGE_FILTER_H_
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "ipc/ipc_sender.h"
-
-namespace base {
-class TaskRunner;
-}
-
-namespace IPC {
-class MessageFilter;
-}
-
-namespace content {
-
-class ThreadSafeSender;
-
-// A base class for implementing IPC MessageFilter's that run on a different
-// thread or TaskRunner than the main thread.
-class ChildMessageFilter
- : public base::RefCountedThreadSafe<ChildMessageFilter>,
- public IPC::Sender {
- public:
- // IPC::Sender implementation. Can be called on any threads.
- bool Send(IPC::Message* message) override;
-
- // If implementers want to run OnMessageReceived on a different task
- // runner it should override this and return the TaskRunner for the message.
- // Returning NULL runs OnMessageReceived() on the current IPC thread.
- virtual base::TaskRunner* OverrideTaskRunnerForMessage(
- const IPC::Message& msg) = 0;
-
- // If OverrideTaskRunnerForMessage is overriden and returns non-null
- // this will be called on the returned TaskRunner.
- virtual bool OnMessageReceived(const IPC::Message& msg) = 0;
-
- // This method is called when WorkerTaskRunner::PostTask() returned false
- // for the target thread. Note that there's still a little chance that
- // PostTask() returns true but OnMessageReceived() is never called on the
- // target thread. By default this does nothing.
- virtual void OnStaleMessageReceived(const IPC::Message& msg) {}
-
- protected:
- ChildMessageFilter();
- ~ChildMessageFilter() override;
-
- private:
- class Internal;
- friend class ChildThreadImpl;
- friend class RenderThreadImpl;
- friend class WorkerThread;
-
- friend class base::RefCountedThreadSafe<ChildMessageFilter>;
-
- IPC::MessageFilter* GetFilter();
-
- // This implements IPC::MessageFilter to hide the actual filter methods from
- // child classes.
- Internal* internal_;
-
- scoped_refptr<ThreadSafeSender> thread_safe_sender_;
-
- DISALLOW_COPY_AND_ASSIGN(ChildMessageFilter);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_CHILD_MESSAGE_FILTER_H_
diff --git a/chromium/content/renderer/clipboard_utils.cc b/chromium/content/renderer/clipboard_utils.cc
deleted file mode 100644
index 8324300097b..00000000000
--- a/chromium/content/renderer/clipboard_utils.cc
+++ /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.
-
-#include "content/renderer/clipboard_utils.h"
-
-#include "base/strings/utf_string_conversions.h"
-#include "net/base/escape.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_url.h"
-
-namespace content {
-
-std::string URLToImageMarkup(const blink::WebURL& url,
- const blink::WebString& title) {
- std::string markup("<img src=\"");
- markup.append(net::EscapeForHTML(url.GetString().Utf8()));
- markup.append("\"");
- if (!title.IsEmpty()) {
- markup.append(" alt=\"");
- markup.append(net::EscapeForHTML(title.Utf8()));
- markup.append("\"");
- }
- markup.append("/>");
- return markup;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/clipboard_utils.h b/chromium/content/renderer/clipboard_utils.h
deleted file mode 100644
index 069488c81fb..00000000000
--- a/chromium/content/renderer/clipboard_utils.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_CLIPBOARD_UTILS_H_
-#define CONTENT_RENDERER_CLIPBOARD_UTILS_H_
-
-#include <string>
-
-#include "content/common/content_export.h"
-
-namespace blink {
-class WebString;
-class WebURL;
-}
-
-namespace content {
-
-CONTENT_EXPORT std::string URLToImageMarkup(const blink::WebURL& url,
- const blink::WebString& title);
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_CLIPBOARD_UTILS_H_
diff --git a/chromium/content/renderer/cursor_utils.cc b/chromium/content/renderer/cursor_utils.cc
index ccdb7bceddf..523fd5361cd 100644
--- a/chromium/content/renderer/cursor_utils.cc
+++ b/chromium/content/renderer/cursor_utils.cc
@@ -30,7 +30,7 @@ void InitializeCursorFromWebCursorInfo(WebCursor* cursor,
cursor_info.type = web_cursor_info.type;
cursor_info.image_scale_factor = web_cursor_info.image_scale_factor;
cursor_info.hotspot = web_cursor_info.hot_spot;
- cursor_info.custom_image = web_cursor_info.custom_image.GetSkBitmap();
+ cursor_info.custom_image = web_cursor_info.custom_image;
cursor->InitFromCursorInfo(cursor_info);
}
diff --git a/chromium/content/renderer/device_sensors/OWNERS b/chromium/content/renderer/device_sensors/OWNERS
deleted file mode 100644
index 7b1e4f284f7..00000000000
--- a/chromium/content/renderer/device_sensors/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-timvolodine@chromium.org
-
-# COMPONENT: Blink>Sensor>DeviceOrientation
-# TEAM: device-dev@chromium.org
diff --git a/chromium/content/renderer/device_sensors/device_motion_event_pump.cc b/chromium/content/renderer/device_sensors/device_motion_event_pump.cc
deleted file mode 100644
index e19341cd04f..00000000000
--- a/chromium/content/renderer/device_sensors/device_motion_event_pump.cc
+++ /dev/null
@@ -1,162 +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/device_sensors/device_motion_event_pump.h"
-
-#include <cmath>
-
-#include "base/logging.h"
-#include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/renderer/render_thread_impl.h"
-#include "services/device/public/cpp/generic_sensor/motion_data.h"
-#include "services/device/public/mojom/sensor.mojom.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
-#include "ui/gfx/geometry/angle_conversions.h"
-
-namespace content {
-
-template class DeviceSensorEventPump<blink::WebDeviceMotionListener>;
-
-DeviceMotionEventPump::DeviceMotionEventPump(RenderThread* thread)
- : DeviceSensorEventPump<blink::WebDeviceMotionListener>(thread),
- accelerometer_(this, device::mojom::SensorType::ACCELEROMETER),
- linear_acceleration_sensor_(
- this,
- device::mojom::SensorType::LINEAR_ACCELERATION),
- gyroscope_(this, device::mojom::SensorType::GYROSCOPE) {}
-
-DeviceMotionEventPump::~DeviceMotionEventPump() {}
-
-void DeviceMotionEventPump::SendStartMessage() {
- // When running layout tests, those observers should not listen to the
- // actual hardware changes. In order to make that happen, don't connect
- // the other end of the mojo pipe to anything.
- //
- // TODO(sammc): Remove this when JS layout test support for shared buffers
- // is ready and the layout tests are converted to use that for mocking.
- // https://crbug.com/774183
- if (!RenderThreadImpl::current() ||
- RenderThreadImpl::current()->layout_test_mode()) {
- return;
- }
-
- SendStartMessageImpl();
-}
-
-void DeviceMotionEventPump::SendStopMessage() {
- // SendStopMessage() gets called both when the page visibility changes and if
- // all device motion event listeners are unregistered. Since removing the
- // event listener is more rare than the page visibility changing,
- // Sensor::Suspend() is used to optimize this case for not doing extra work.
-
- accelerometer_.Stop();
- linear_acceleration_sensor_.Stop();
- gyroscope_.Stop();
-}
-
-void DeviceMotionEventPump::SendFakeDataForTesting(void* fake_data) {
- if (!listener())
- return;
-
- device::MotionData data = *static_cast<device::MotionData*>(fake_data);
- listener()->DidChangeDeviceMotion(data);
-}
-
-void DeviceMotionEventPump::FireEvent() {
- device::MotionData data;
- // The device orientation spec states that interval should be in milliseconds.
- // https://w3c.github.io/deviceorientation/spec-source-orientation.html#devicemotion
- data.interval = kDefaultPumpDelayMicroseconds / 1000;
-
- DCHECK(listener());
-
- GetDataFromSharedMemory(&data);
-
- if (ShouldFireEvent(data))
- listener()->DidChangeDeviceMotion(data);
-}
-
-void DeviceMotionEventPump::SendStartMessageImpl() {
- if (!sensor_provider_) {
- RenderFrame* const render_frame = GetRenderFrame();
- if (!render_frame)
- return;
-
- render_frame->GetRemoteInterfaces()->GetInterface(
- mojo::MakeRequest(&sensor_provider_));
- sensor_provider_.set_connection_error_handler(
- base::BindOnce(&DeviceSensorEventPump::HandleSensorProviderError,
- base::Unretained(this)));
- }
-
- accelerometer_.Start(sensor_provider_.get());
- linear_acceleration_sensor_.Start(sensor_provider_.get());
- gyroscope_.Start(sensor_provider_.get());
-}
-
-bool DeviceMotionEventPump::SensorsReadyOrErrored() const {
- return accelerometer_.ReadyOrErrored() &&
- linear_acceleration_sensor_.ReadyOrErrored() &&
- gyroscope_.ReadyOrErrored();
-}
-
-void DeviceMotionEventPump::GetDataFromSharedMemory(device::MotionData* data) {
- // "Active" here means that sensor has been initialized and is either ready
- // or not available.
- bool accelerometer_active = true;
- bool linear_acceleration_sensor_active = true;
- bool gyroscope_active = true;
-
- if (accelerometer_.SensorReadingCouldBeRead() &&
- (accelerometer_active = accelerometer_.reading.timestamp() != 0.0)) {
- data->acceleration_including_gravity_x = accelerometer_.reading.accel.x;
- data->acceleration_including_gravity_y = accelerometer_.reading.accel.y;
- data->acceleration_including_gravity_z = accelerometer_.reading.accel.z;
- data->has_acceleration_including_gravity_x =
- !std::isnan(accelerometer_.reading.accel.x.value());
- data->has_acceleration_including_gravity_y =
- !std::isnan(accelerometer_.reading.accel.y.value());
- data->has_acceleration_including_gravity_z =
- !std::isnan(accelerometer_.reading.accel.z.value());
- }
-
- if (linear_acceleration_sensor_.SensorReadingCouldBeRead() &&
- (linear_acceleration_sensor_active =
- linear_acceleration_sensor_.reading.timestamp() != 0.0)) {
- data->acceleration_x = linear_acceleration_sensor_.reading.accel.x;
- data->acceleration_y = linear_acceleration_sensor_.reading.accel.y;
- data->acceleration_z = linear_acceleration_sensor_.reading.accel.z;
- data->has_acceleration_x =
- !std::isnan(linear_acceleration_sensor_.reading.accel.x.value());
- data->has_acceleration_y =
- !std::isnan(linear_acceleration_sensor_.reading.accel.y.value());
- data->has_acceleration_z =
- !std::isnan(linear_acceleration_sensor_.reading.accel.z.value());
- }
-
- if (gyroscope_.SensorReadingCouldBeRead() &&
- (gyroscope_active = gyroscope_.reading.timestamp() != 0.0)) {
- data->rotation_rate_alpha = gfx::RadToDeg(gyroscope_.reading.gyro.x);
- data->rotation_rate_beta = gfx::RadToDeg(gyroscope_.reading.gyro.y);
- data->rotation_rate_gamma = gfx::RadToDeg(gyroscope_.reading.gyro.z);
- data->has_rotation_rate_alpha =
- !std::isnan(gyroscope_.reading.gyro.x.value());
- data->has_rotation_rate_beta =
- !std::isnan(gyroscope_.reading.gyro.y.value());
- data->has_rotation_rate_gamma =
- !std::isnan(gyroscope_.reading.gyro.z.value());
- }
-
- data->all_available_sensors_are_active = accelerometer_active &&
- linear_acceleration_sensor_active &&
- gyroscope_active;
-} // namespace content
-
-bool DeviceMotionEventPump::ShouldFireEvent(
- const device::MotionData& data) const {
- return data.all_available_sensors_are_active;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/device_sensors/device_motion_event_pump.h b/chromium/content/renderer/device_sensors/device_motion_event_pump.h
deleted file mode 100644
index e7bb8e6026e..00000000000
--- a/chromium/content/renderer/device_sensors/device_motion_event_pump.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_MOTION_EVENT_PUMP_H_
-#define CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_MOTION_EVENT_PUMP_H_
-
-#include "base/macros.h"
-#include "content/renderer/device_sensors/device_sensor_event_pump.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h"
-
-namespace device {
-class MotionData;
-}
-
-namespace content {
-
-class RenderThread;
-
-class CONTENT_EXPORT DeviceMotionEventPump
- : public DeviceSensorEventPump<blink::WebDeviceMotionListener> {
- public:
- explicit DeviceMotionEventPump(RenderThread* thread);
- ~DeviceMotionEventPump() override;
-
- // PlatformEventObserver:
- void SendStartMessage() override;
- void SendStopMessage() override;
- void SendFakeDataForTesting(void* fake_data) override;
-
- protected:
- // DeviceSensorEventPump:
- void FireEvent() override;
-
- void SendStartMessageImpl();
-
- SensorEntry accelerometer_;
- SensorEntry linear_acceleration_sensor_;
- SensorEntry gyroscope_;
-
- private:
- friend class DeviceMotionEventPumpTest;
-
- // DeviceSensorEventPump:
- bool SensorsReadyOrErrored() const override;
-
- void GetDataFromSharedMemory(device::MotionData* data);
-
- bool ShouldFireEvent(const device::MotionData& data) const;
-
- DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPump);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_MOTION_EVENT_PUMP_H_
diff --git a/chromium/content/renderer/device_sensors/device_motion_event_pump_unittest.cc b/chromium/content/renderer/device_sensors/device_motion_event_pump_unittest.cc
deleted file mode 100644
index 2d35111465a..00000000000
--- a/chromium/content/renderer/device_sensors/device_motion_event_pump_unittest.cc
+++ /dev/null
@@ -1,433 +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/device_sensors/device_motion_event_pump.h"
-
-#include <string.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "content/public/test/test_utils.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
-#include "services/device/public/cpp/generic_sensor/motion_data.h"
-#include "services/device/public/cpp/test/fake_sensor_and_provider.h"
-#include "services/device/public/mojom/sensor.mojom.h"
-#include "services/device/public/mojom/sensor_provider.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h"
-#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "ui/gfx/geometry/angle_conversions.h"
-
-namespace content {
-
-using device::FakeSensorProvider;
-
-class MockDeviceMotionListener : public blink::WebDeviceMotionListener {
- public:
- MockDeviceMotionListener()
- : did_change_device_motion_(false), number_of_events_(0) {
- memset(&data_, 0, sizeof(data_));
- }
- ~MockDeviceMotionListener() override {}
-
- void DidChangeDeviceMotion(const device::MotionData& data) override {
- memcpy(&data_, &data, sizeof(data));
- did_change_device_motion_ = true;
- ++number_of_events_;
- }
-
- bool did_change_device_motion() const {
- return did_change_device_motion_;
- }
-
- int number_of_events() const { return number_of_events_; }
-
- const device::MotionData& data() const { return data_; }
-
- private:
- bool did_change_device_motion_;
- int number_of_events_;
- device::MotionData data_;
-
- DISALLOW_COPY_AND_ASSIGN(MockDeviceMotionListener);
-};
-
-class DeviceMotionEventPumpForTesting : public DeviceMotionEventPump {
- public:
- DeviceMotionEventPumpForTesting() : DeviceMotionEventPump(nullptr) {}
- ~DeviceMotionEventPumpForTesting() override {}
-
- // DeviceMotionEventPump:
- void SendStartMessage() override {
- DeviceMotionEventPump::SendStartMessageImpl();
- }
-
- int pump_delay_microseconds() const { return kDefaultPumpDelayMicroseconds; }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpForTesting);
-};
-
-class DeviceMotionEventPumpTest : public testing::Test {
- public:
- DeviceMotionEventPumpTest() = default;
-
- protected:
- void SetUp() override {
- motion_pump_.reset(new DeviceMotionEventPumpForTesting());
- device::mojom::SensorProviderPtr sensor_provider_ptr;
- sensor_provider_.Bind(mojo::MakeRequest(&sensor_provider_ptr));
- motion_pump_->SetSensorProviderForTesting(std::move(sensor_provider_ptr));
-
- listener_.reset(new MockDeviceMotionListener);
-
- ExpectAllThreeSensorsStateToBe(
- DeviceMotionEventPump::SensorState::NOT_INITIALIZED);
- EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED,
- motion_pump()->GetPumpStateForTesting());
- }
-
- void FireEvent() { motion_pump_->FireEvent(); }
-
- void ExpectAccelerometerStateToBe(
- DeviceMotionEventPump::SensorState expected_sensor_state) {
- EXPECT_EQ(expected_sensor_state, motion_pump_->accelerometer_.sensor_state);
- }
-
- void ExpectLinearAccelerationSensorStateToBe(
- DeviceMotionEventPump::SensorState expected_sensor_state) {
- EXPECT_EQ(expected_sensor_state,
- motion_pump_->linear_acceleration_sensor_.sensor_state);
- }
-
- void ExpectGyroscopeStateToBe(
- DeviceMotionEventPump::SensorState expected_sensor_state) {
- EXPECT_EQ(expected_sensor_state, motion_pump_->gyroscope_.sensor_state);
- }
-
- void ExpectAllThreeSensorsStateToBe(
- DeviceMotionEventPump::SensorState expected_sensor_state) {
- ExpectAccelerometerStateToBe(expected_sensor_state);
- ExpectLinearAccelerationSensorStateToBe(expected_sensor_state);
- ExpectGyroscopeStateToBe(expected_sensor_state);
- }
-
- DeviceMotionEventPumpForTesting* motion_pump() { return motion_pump_.get(); }
-
- MockDeviceMotionListener* listener() { return listener_.get(); }
-
- FakeSensorProvider* sensor_provider() { return &sensor_provider_; }
-
- private:
- base::MessageLoop loop_;
- std::unique_ptr<DeviceMotionEventPumpForTesting> motion_pump_;
- std::unique_ptr<MockDeviceMotionListener> listener_;
- FakeSensorProvider sensor_provider_;
-
- DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpTest);
-};
-
-TEST_F(DeviceMotionEventPumpTest, MultipleStartAndStopWithWait) {
- motion_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
- EXPECT_EQ(DeviceMotionEventPump::PumpState::RUNNING,
- motion_pump()->GetPumpStateForTesting());
-
- motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
- EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED,
- motion_pump()->GetPumpStateForTesting());
-
- motion_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
- EXPECT_EQ(DeviceMotionEventPump::PumpState::RUNNING,
- motion_pump()->GetPumpStateForTesting());
-
- motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
- EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED,
- motion_pump()->GetPumpStateForTesting());
-}
-
-TEST_F(DeviceMotionEventPumpTest, CallStop) {
- motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(
- DeviceMotionEventPump::SensorState::NOT_INITIALIZED);
-}
-
-TEST_F(DeviceMotionEventPumpTest, CallStartAndStop) {
- motion_pump()->Start(listener());
- motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceMotionEventPumpTest, CallStartMultipleTimes) {
- motion_pump()->Start(listener());
- motion_pump()->Start(listener());
- motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceMotionEventPumpTest, CallStopMultipleTimes) {
- motion_pump()->Start(listener());
- motion_pump()->Stop();
- motion_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
-}
-
-// Test multiple DeviceSensorEventPump::Start() calls only bind sensor once.
-TEST_F(DeviceMotionEventPumpTest, SensorOnlyBindOnce) {
- motion_pump()->Start(listener());
- motion_pump()->Stop();
- motion_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
-
- motion_pump()->Stop();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) {
- motion_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateAccelerometerData(1, 2, 3);
- sensor_provider()->UpdateLinearAccelerationSensorData(4, 5, 6);
- sensor_provider()->UpdateGyroscopeData(7, 8, 9);
-
- FireEvent();
-
- device::MotionData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_motion());
-
- EXPECT_TRUE(received_data.has_acceleration_including_gravity_x);
- EXPECT_EQ(1, received_data.acceleration_including_gravity_x);
- EXPECT_TRUE(received_data.has_acceleration_including_gravity_y);
- EXPECT_EQ(2, received_data.acceleration_including_gravity_y);
- EXPECT_TRUE(received_data.has_acceleration_including_gravity_z);
- EXPECT_EQ(3, received_data.acceleration_including_gravity_z);
-
- EXPECT_TRUE(received_data.has_acceleration_x);
- EXPECT_EQ(4, received_data.acceleration_x);
- EXPECT_TRUE(received_data.has_acceleration_y);
- EXPECT_EQ(5, received_data.acceleration_y);
- EXPECT_TRUE(received_data.has_acceleration_z);
- EXPECT_EQ(6, received_data.acceleration_z);
-
- EXPECT_TRUE(received_data.has_rotation_rate_alpha);
- EXPECT_EQ(gfx::RadToDeg(7.0), received_data.rotation_rate_alpha);
- EXPECT_TRUE(received_data.has_rotation_rate_beta);
- EXPECT_EQ(gfx::RadToDeg(8.0), received_data.rotation_rate_beta);
- EXPECT_TRUE(received_data.has_rotation_rate_gamma);
- EXPECT_EQ(gfx::RadToDeg(9.0), received_data.rotation_rate_gamma);
-
- motion_pump()->Stop();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) {
- sensor_provider()->set_linear_acceleration_sensor_is_available(false);
-
- motion_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAccelerometerStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
- ExpectLinearAccelerationSensorStateToBe(
- DeviceMotionEventPump::SensorState::NOT_INITIALIZED);
- ExpectGyroscopeStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateAccelerometerData(1, 2, 3);
- sensor_provider()->UpdateGyroscopeData(7, 8, 9);
-
- FireEvent();
-
- device::MotionData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_motion());
-
- EXPECT_TRUE(received_data.has_acceleration_including_gravity_x);
- EXPECT_EQ(1, received_data.acceleration_including_gravity_x);
- EXPECT_TRUE(received_data.has_acceleration_including_gravity_y);
- EXPECT_EQ(2, received_data.acceleration_including_gravity_y);
- EXPECT_TRUE(received_data.has_acceleration_including_gravity_z);
- EXPECT_EQ(3, received_data.acceleration_including_gravity_z);
-
- EXPECT_FALSE(received_data.has_acceleration_x);
- EXPECT_FALSE(received_data.has_acceleration_y);
- EXPECT_FALSE(received_data.has_acceleration_z);
-
- EXPECT_TRUE(received_data.has_rotation_rate_alpha);
- EXPECT_EQ(gfx::RadToDeg(7.0), received_data.rotation_rate_alpha);
- EXPECT_TRUE(received_data.has_rotation_rate_beta);
- EXPECT_EQ(gfx::RadToDeg(8.0), received_data.rotation_rate_beta);
- EXPECT_TRUE(received_data.has_rotation_rate_gamma);
- EXPECT_EQ(gfx::RadToDeg(9.0), received_data.rotation_rate_gamma);
-
- motion_pump()->Stop();
-
- ExpectAccelerometerStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
- ExpectLinearAccelerationSensorStateToBe(
- DeviceMotionEventPump::SensorState::NOT_INITIALIZED);
- ExpectGyroscopeStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceMotionEventPumpTest, SomeSensorDataFieldsNotAvailable) {
- motion_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateAccelerometerData(NAN, 2, 3);
- sensor_provider()->UpdateLinearAccelerationSensorData(4, NAN, 6);
- sensor_provider()->UpdateGyroscopeData(7, 8, NAN);
-
- FireEvent();
-
- device::MotionData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_motion());
-
- EXPECT_FALSE(received_data.has_acceleration_including_gravity_x);
- EXPECT_TRUE(received_data.has_acceleration_including_gravity_y);
- EXPECT_EQ(2, received_data.acceleration_including_gravity_y);
- EXPECT_TRUE(received_data.has_acceleration_including_gravity_z);
- EXPECT_EQ(3, received_data.acceleration_including_gravity_z);
-
- EXPECT_TRUE(received_data.has_acceleration_x);
- EXPECT_EQ(4, received_data.acceleration_x);
- EXPECT_FALSE(received_data.has_acceleration_y);
- EXPECT_TRUE(received_data.has_acceleration_z);
- EXPECT_EQ(6, received_data.acceleration_z);
-
- EXPECT_TRUE(received_data.has_rotation_rate_alpha);
- EXPECT_EQ(gfx::RadToDeg(7.0), received_data.rotation_rate_alpha);
- EXPECT_TRUE(received_data.has_rotation_rate_beta);
- EXPECT_EQ(gfx::RadToDeg(8.0), received_data.rotation_rate_beta);
- EXPECT_FALSE(received_data.has_rotation_rate_gamma);
-
- motion_pump()->Stop();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceMotionEventPumpTest, FireAllNullEvent) {
- // No active sensors.
- sensor_provider()->set_accelerometer_is_available(false);
- sensor_provider()->set_linear_acceleration_sensor_is_available(false);
- sensor_provider()->set_gyroscope_is_available(false);
-
- motion_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(
- DeviceMotionEventPump::SensorState::NOT_INITIALIZED);
-
- FireEvent();
-
- device::MotionData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_motion());
-
- EXPECT_FALSE(received_data.has_acceleration_x);
- EXPECT_FALSE(received_data.has_acceleration_y);
- EXPECT_FALSE(received_data.has_acceleration_z);
-
- EXPECT_FALSE(received_data.has_acceleration_including_gravity_x);
- EXPECT_FALSE(received_data.has_acceleration_including_gravity_y);
- EXPECT_FALSE(received_data.has_acceleration_including_gravity_z);
-
- EXPECT_FALSE(received_data.has_rotation_rate_alpha);
- EXPECT_FALSE(received_data.has_rotation_rate_beta);
- EXPECT_FALSE(received_data.has_rotation_rate_gamma);
-
- motion_pump()->Stop();
-
- ExpectAllThreeSensorsStateToBe(
- DeviceMotionEventPump::SensorState::NOT_INITIALIZED);
-}
-
-TEST_F(DeviceMotionEventPumpTest,
- NotFireEventWhenSensorReadingTimeStampIsZero) {
- motion_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
-
- FireEvent();
- EXPECT_FALSE(listener()->did_change_device_motion());
-
- sensor_provider()->UpdateAccelerometerData(1, 2, 3);
- FireEvent();
- EXPECT_FALSE(listener()->did_change_device_motion());
-
- sensor_provider()->UpdateLinearAccelerationSensorData(4, 5, 6);
- FireEvent();
- EXPECT_FALSE(listener()->did_change_device_motion());
-
- sensor_provider()->UpdateGyroscopeData(7, 8, 9);
- FireEvent();
- // Event is fired only after all the available sensors have data.
- EXPECT_TRUE(listener()->did_change_device_motion());
-
- motion_pump()->Stop();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
-}
-
-// Confirm that the frequency of pumping events is not greater than 60Hz.
-// A rate above 60Hz would allow for the detection of keystrokes.
-// (crbug.com/421691)
-TEST_F(DeviceMotionEventPumpTest, PumpThrottlesEventRate) {
- // Confirm that the delay for pumping events is 60 Hz.
- EXPECT_GE(60, base::Time::kMicrosecondsPerSecond /
- motion_pump()->pump_delay_microseconds());
-
- motion_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateAccelerometerData(1, 2, 3);
- sensor_provider()->UpdateLinearAccelerationSensorData(4, 5, 6);
- sensor_provider()->UpdateGyroscopeData(7, 8, 9);
-
- blink::scheduler::GetSingleThreadTaskRunnerForTesting()->PostDelayedTask(
- FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated(),
- base::TimeDelta::FromMilliseconds(100));
- base::RunLoop().Run();
- motion_pump()->Stop();
-
- ExpectAllThreeSensorsStateToBe(DeviceMotionEventPump::SensorState::SUSPENDED);
-
- // Check that the blink::WebDeviceMotionListener does not receive excess
- // events.
- EXPECT_TRUE(listener()->did_change_device_motion());
- EXPECT_GE(6, listener()->number_of_events());
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/device_sensors/device_orientation_event_pump.cc b/chromium/content/renderer/device_sensors/device_orientation_event_pump.cc
deleted file mode 100644
index f2c7d89f96b..00000000000
--- a/chromium/content/renderer/device_sensors/device_orientation_event_pump.cc
+++ /dev/null
@@ -1,235 +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/device_sensors/device_orientation_event_pump.h"
-
-#include <cmath>
-
-#include "base/logging.h"
-#include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/renderer/render_thread_impl.h"
-#include "services/device/public/mojom/sensor.mojom.h"
-#include "services/service_manager/public/cpp/interface_provider.h"
-
-namespace {
-
-bool IsAngleDifferentThreshold(bool has_angle1,
- double angle1,
- bool has_angle2,
- double angle2) {
- if (has_angle1 != has_angle2)
- return true;
-
- return (has_angle1 &&
- std::fabs(angle1 - angle2) >=
- content::DeviceOrientationEventPump::kOrientationThreshold);
-}
-
-bool IsSignificantlyDifferent(const device::OrientationData& data1,
- const device::OrientationData& data2) {
- return IsAngleDifferentThreshold(data1.has_alpha, data1.alpha,
- data2.has_alpha, data2.alpha) ||
- IsAngleDifferentThreshold(data1.has_beta, data1.beta, data2.has_beta,
- data2.beta) ||
- IsAngleDifferentThreshold(data1.has_gamma, data1.gamma,
- data2.has_gamma, data2.gamma);
-}
-
-} // namespace
-
-namespace content {
-
-template class DeviceSensorEventPump<blink::WebDeviceOrientationListener>;
-
-const double DeviceOrientationEventPump::kOrientationThreshold = 0.1;
-
-DeviceOrientationEventPump::DeviceOrientationEventPump(RenderThread* thread,
- bool absolute)
- : DeviceSensorEventPump<blink::WebDeviceOrientationListener>(thread),
- relative_orientation_sensor_(
- this,
- device::mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES),
- absolute_orientation_sensor_(
- this,
- device::mojom::SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES),
- absolute_(absolute),
- fall_back_to_absolute_orientation_sensor_(!absolute) {}
-
-DeviceOrientationEventPump::~DeviceOrientationEventPump() {}
-
-void DeviceOrientationEventPump::SendStartMessage() {
- // When running layout tests, those observers should not listen to the
- // actual hardware changes. In order to make that happen, don't connect
- // the other end of the mojo pipe to anything.
- //
- // TODO(sammc): Remove this when JS layout test support for shared buffers
- // is ready and the layout tests are converted to use that for mocking.
- // https://crbug.com/774183
- if (!RenderThreadImpl::current() ||
- RenderThreadImpl::current()->layout_test_mode()) {
- return;
- }
-
- SendStartMessageImpl();
-}
-
-void DeviceOrientationEventPump::SendStopMessage() {
- // SendStopMessage() gets called both when the page visibility changes and if
- // all device orientation event listeners are unregistered. Since removing
- // the event listener is more rare than the page visibility changing,
- // Sensor::Suspend() is used to optimize this case for not doing extra work.
-
- relative_orientation_sensor_.Stop();
- // This is needed in case we fallback to using the absolute orientation
- // sensor. In this case, the relative orientation sensor is marked as
- // SensorState::SHOULD_SUSPEND, and if the relative orientation sensor
- // is not available, the absolute orientation sensor should also be marked as
- // SensorState::SHOULD_SUSPEND, but only after the
- // absolute_orientation_sensor_.Start() is called for initializing
- // the absolute orientation sensor in
- // DeviceOrientationEventPump::DidStartIfPossible().
- if (relative_orientation_sensor_.sensor_state ==
- SensorState::SHOULD_SUSPEND &&
- fall_back_to_absolute_orientation_sensor_) {
- should_suspend_absolute_orientation_sensor_ = true;
- }
-
- absolute_orientation_sensor_.Stop();
-}
-
-void DeviceOrientationEventPump::SendFakeDataForTesting(void* fake_data) {
- if (!listener())
- return;
-
- device::OrientationData data =
- *static_cast<device::OrientationData*>(fake_data);
- listener()->DidChangeDeviceOrientation(data);
-}
-
-void DeviceOrientationEventPump::FireEvent() {
- device::OrientationData data;
-
- DCHECK(listener());
-
- GetDataFromSharedMemory(&data);
-
- if (ShouldFireEvent(data)) {
- data_ = data;
- listener()->DidChangeDeviceOrientation(data);
- }
-}
-
-void DeviceOrientationEventPump::DidStartIfPossible() {
- if (!absolute_ && !relative_orientation_sensor_.sensor &&
- fall_back_to_absolute_orientation_sensor_ && sensor_provider_) {
- // When relative orientation sensor is not available fall back to using
- // the absolute orientation sensor but only on the first failure.
- fall_back_to_absolute_orientation_sensor_ = false;
- absolute_orientation_sensor_.Start(sensor_provider_.get());
- if (should_suspend_absolute_orientation_sensor_) {
- // The absolute orientation sensor needs to be marked as
- // SensorState::SUSPENDED when it is successfully initialized.
- absolute_orientation_sensor_.sensor_state = SensorState::SHOULD_SUSPEND;
- should_suspend_absolute_orientation_sensor_ = false;
- }
- return;
- }
- DeviceSensorEventPump::DidStartIfPossible();
-}
-
-void DeviceOrientationEventPump::SendStartMessageImpl() {
- if (!sensor_provider_) {
- RenderFrame* const render_frame = GetRenderFrame();
- if (!render_frame)
- return;
-
- render_frame->GetRemoteInterfaces()->GetInterface(
- mojo::MakeRequest(&sensor_provider_));
- sensor_provider_.set_connection_error_handler(
- base::BindOnce(&DeviceSensorEventPump::HandleSensorProviderError,
- base::Unretained(this)));
- }
-
- if (absolute_) {
- absolute_orientation_sensor_.Start(sensor_provider_.get());
- } else {
- fall_back_to_absolute_orientation_sensor_ = true;
- should_suspend_absolute_orientation_sensor_ = false;
- relative_orientation_sensor_.Start(sensor_provider_.get());
- }
-}
-
-bool DeviceOrientationEventPump::SensorsReadyOrErrored() const {
- if (!relative_orientation_sensor_.ReadyOrErrored() ||
- !absolute_orientation_sensor_.ReadyOrErrored()) {
- return false;
- }
-
- // At most one sensor can be successfully initialized.
- DCHECK(!relative_orientation_sensor_.sensor ||
- !absolute_orientation_sensor_.sensor);
-
- return true;
-}
-
-void DeviceOrientationEventPump::GetDataFromSharedMemory(
- device::OrientationData* data) {
- data->all_available_sensors_are_active = true;
-
- if (!absolute_ && relative_orientation_sensor_.SensorReadingCouldBeRead()) {
- // For DeviceOrientation Event, this provides relative orientation data.
- data->all_available_sensors_are_active =
- relative_orientation_sensor_.reading.timestamp() != 0.0;
- if (!data->all_available_sensors_are_active)
- return;
- data->alpha = relative_orientation_sensor_.reading.orientation_euler.z;
- data->beta = relative_orientation_sensor_.reading.orientation_euler.x;
- data->gamma = relative_orientation_sensor_.reading.orientation_euler.y;
- data->has_alpha = !std::isnan(
- relative_orientation_sensor_.reading.orientation_euler.z.value());
- data->has_beta = !std::isnan(
- relative_orientation_sensor_.reading.orientation_euler.x.value());
- data->has_gamma = !std::isnan(
- relative_orientation_sensor_.reading.orientation_euler.y.value());
- data->absolute = false;
- } else if (absolute_orientation_sensor_.SensorReadingCouldBeRead()) {
- // For DeviceOrientationAbsolute Event, this provides absolute orientation
- // data.
- //
- // For DeviceOrientation Event, this provides absolute orientation data if
- // relative orientation data is not available.
- data->all_available_sensors_are_active =
- absolute_orientation_sensor_.reading.timestamp() != 0.0;
- if (!data->all_available_sensors_are_active)
- return;
- data->alpha = absolute_orientation_sensor_.reading.orientation_euler.z;
- data->beta = absolute_orientation_sensor_.reading.orientation_euler.x;
- data->gamma = absolute_orientation_sensor_.reading.orientation_euler.y;
- data->has_alpha = !std::isnan(
- absolute_orientation_sensor_.reading.orientation_euler.z.value());
- data->has_beta = !std::isnan(
- absolute_orientation_sensor_.reading.orientation_euler.x.value());
- data->has_gamma = !std::isnan(
- absolute_orientation_sensor_.reading.orientation_euler.y.value());
- data->absolute = true;
- } else {
- data->absolute = absolute_;
- }
-}
-
-bool DeviceOrientationEventPump::ShouldFireEvent(
- const device::OrientationData& data) const {
- if (!data.all_available_sensors_are_active)
- return false;
-
- if (!data.has_alpha && !data.has_beta && !data.has_gamma) {
- // no data can be provided, this is an all-null event.
- return true;
- }
-
- return IsSignificantlyDifferent(data_, data);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/device_sensors/device_orientation_event_pump.h b/chromium/content/renderer/device_sensors/device_orientation_event_pump.h
deleted file mode 100644
index 6ec081eb5e4..00000000000
--- a/chromium/content/renderer/device_sensors/device_orientation_event_pump.h
+++ /dev/null
@@ -1,63 +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_DEVICE_SENSORS_DEVICE_ORIENTATION_EVENT_PUMP_H_
-#define CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_ORIENTATION_EVENT_PUMP_H_
-
-#include "base/macros.h"
-#include "content/renderer/device_sensors/device_sensor_event_pump.h"
-#include "services/device/public/cpp/generic_sensor/orientation_data.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h"
-
-namespace content {
-
-class RenderThread;
-
-class CONTENT_EXPORT DeviceOrientationEventPump
- : public DeviceSensorEventPump<blink::WebDeviceOrientationListener> {
- public:
- // Angle threshold beyond which two orientation events are considered
- // sufficiently different.
- static const double kOrientationThreshold;
-
- DeviceOrientationEventPump(RenderThread* thread, bool absolute);
- ~DeviceOrientationEventPump() override;
-
- // PlatformEventObserver:
- void SendStartMessage() override;
- void SendStopMessage() override;
- void SendFakeDataForTesting(void* fake_data) override;
-
- protected:
- // DeviceSensorEventPump:
- void FireEvent() override;
- void DidStartIfPossible() override;
-
- void SendStartMessageImpl();
-
- SensorEntry relative_orientation_sensor_;
- SensorEntry absolute_orientation_sensor_;
-
- private:
- friend class DeviceOrientationEventPumpTest;
- friend class DeviceAbsoluteOrientationEventPumpTest;
-
- // DeviceSensorEventPump:
- bool SensorsReadyOrErrored() const override;
-
- void GetDataFromSharedMemory(device::OrientationData* data);
-
- bool ShouldFireEvent(const device::OrientationData& data) const;
-
- bool absolute_;
- bool fall_back_to_absolute_orientation_sensor_;
- bool should_suspend_absolute_orientation_sensor_ = false;
- device::OrientationData data_;
-
- DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPump);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_ORIENTATION_EVENT_PUMP_H_
diff --git a/chromium/content/renderer/device_sensors/device_orientation_event_pump_unittest.cc b/chromium/content/renderer/device_sensors/device_orientation_event_pump_unittest.cc
deleted file mode 100644
index a445b6af3a3..00000000000
--- a/chromium/content/renderer/device_sensors/device_orientation_event_pump_unittest.cc
+++ /dev/null
@@ -1,1018 +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/device_sensors/device_orientation_event_pump.h"
-
-#include <string.h>
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "content/public/test/test_utils.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
-#include "services/device/public/cpp/generic_sensor/orientation_data.h"
-#include "services/device/public/cpp/test/fake_sensor_and_provider.h"
-#include "services/device/public/mojom/sensor.mojom.h"
-#include "services/device/public/mojom/sensor_provider.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h"
-#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-
-namespace {
-
-constexpr double kEpsilon = 1e-8;
-
-} // namespace
-
-namespace content {
-
-using device::FakeSensorProvider;
-
-class MockDeviceOrientationListener
- : public blink::WebDeviceOrientationListener {
- public:
- MockDeviceOrientationListener() : did_change_device_orientation_(false) {
- memset(&data_, 0, sizeof(data_));
- }
- ~MockDeviceOrientationListener() override {}
-
- void DidChangeDeviceOrientation(
- const device::OrientationData& data) override {
- memcpy(&data_, &data, sizeof(data));
- did_change_device_orientation_ = true;
- }
-
- bool did_change_device_orientation() const {
- return did_change_device_orientation_;
- }
- void set_did_change_device_orientation(bool value) {
- did_change_device_orientation_ = value;
- }
- const device::OrientationData& data() const { return data_; }
-
- private:
- bool did_change_device_orientation_;
- device::OrientationData data_;
-
- DISALLOW_COPY_AND_ASSIGN(MockDeviceOrientationListener);
-};
-
-class DeviceOrientationEventPumpForTesting : public DeviceOrientationEventPump {
- public:
- DeviceOrientationEventPumpForTesting(bool absolute)
- : DeviceOrientationEventPump(nullptr, absolute) {}
- ~DeviceOrientationEventPumpForTesting() override {}
-
- // DeviceOrientationEventPump:
- void SendStartMessage() override {
- DeviceOrientationEventPump::SendStartMessageImpl();
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPumpForTesting);
-};
-
-class DeviceOrientationEventPumpTest : public testing::Test {
- public:
- DeviceOrientationEventPumpTest() = default;
-
- protected:
- void SetUp() override {
- orientation_pump_.reset(
- new DeviceOrientationEventPumpForTesting(false /* absolute */));
- device::mojom::SensorProviderPtr sensor_provider_ptr;
- sensor_provider_.Bind(mojo::MakeRequest(&sensor_provider_ptr));
- orientation_pump_->SetSensorProviderForTesting(
- std::move(sensor_provider_ptr));
-
- listener_.reset(new MockDeviceOrientationListener);
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- orientation_pump()->GetPumpStateForTesting());
- }
-
- void FireEvent() { orientation_pump_->FireEvent(); }
-
- void ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState expected_sensor_state) {
- EXPECT_EQ(expected_sensor_state,
- orientation_pump_->relative_orientation_sensor_.sensor_state);
- }
-
- void ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState expected_sensor_state) {
- EXPECT_EQ(expected_sensor_state,
- orientation_pump_->absolute_orientation_sensor_.sensor_state);
- }
-
- DeviceOrientationEventPump* orientation_pump() {
- return orientation_pump_.get();
- }
-
- MockDeviceOrientationListener* listener() { return listener_.get(); }
-
- FakeSensorProvider* sensor_provider() { return &sensor_provider_; }
-
- private:
- base::MessageLoop loop_;
- std::unique_ptr<DeviceOrientationEventPumpForTesting> orientation_pump_;
- std::unique_ptr<MockDeviceOrientationListener> listener_;
- FakeSensorProvider sensor_provider_;
-
- DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPumpTest);
-};
-
-TEST_F(DeviceOrientationEventPumpTest, MultipleStartAndStopWithWait) {
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- orientation_pump()->GetPumpStateForTesting());
-
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- orientation_pump()->GetPumpStateForTesting());
-
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- orientation_pump()->GetPumpStateForTesting());
-
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- orientation_pump()->GetPumpStateForTesting());
-}
-
-TEST_F(DeviceOrientationEventPumpTest,
- MultipleStartAndStopWithWaitWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- orientation_pump()->GetPumpStateForTesting());
-
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- orientation_pump()->GetPumpStateForTesting());
-
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- orientation_pump()->GetPumpStateForTesting());
-
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- orientation_pump()->GetPumpStateForTesting());
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStop) {
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStopWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStartAndStop) {
- orientation_pump()->Start(listener());
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStartAndStopWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- orientation_pump()->Start(listener());
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStartMultipleTimes) {
- orientation_pump()->Start(listener());
- orientation_pump()->Start(listener());
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest,
- CallStartMultipleTimesWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- orientation_pump()->Start(listener());
- orientation_pump()->Start(listener());
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, CallStopMultipleTimes) {
- orientation_pump()->Start(listener());
- orientation_pump()->Stop();
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest,
- CallStopMultipleTimesWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- orientation_pump()->Start(listener());
- orientation_pump()->Stop();
- orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-// Test a sequence of Start(), Stop(), Start() calls only bind sensor once.
-TEST_F(DeviceOrientationEventPumpTest, SensorOnlyBindOnce) {
- orientation_pump()->Start(listener());
- orientation_pump()->Stop();
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-// Test when using fallback from relative orientation to absolute orientation,
-// a sequence of Start(), Stop(), Start() calls only bind sensor once.
-TEST_F(DeviceOrientationEventPumpTest, SensorOnlyBindOnceWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- orientation_pump()->Start(listener());
- orientation_pump()->Stop();
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, SensorIsActive) {
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateRelativeOrientationSensorData(
- 1 /* alpha */, 2 /* beta */, 3 /* gamma */);
-
- FireEvent();
-
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- // DeviceOrientation Event provides relative orientation data when it is
- // available.
- EXPECT_DOUBLE_EQ(1, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(2, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(3, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
-
- orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, SensorIsActiveWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateAbsoluteOrientationSensorData(
- 4 /* alpha */, 5 /* beta */, 6 /* gamma */);
-
- FireEvent();
-
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- // DeviceOrientation Event provides absolute orientation data when relative
- // orientation data is not available but absolute orientation data is
- // available.
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- // Since no relative orientation data is available, DeviceOrientationEvent
- // fallback to provide absolute orientation data.
- EXPECT_TRUE(received_data.absolute);
-
- orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, SomeSensorDataFieldsNotAvailable) {
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateRelativeOrientationSensorData(
- NAN /* alpha */, 2 /* beta */, 3 /* gamma */);
-
- FireEvent();
-
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- EXPECT_FALSE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(2, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(3, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
-
- orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest,
- SomeSensorDataFieldsNotAvailableWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateAbsoluteOrientationSensorData(
- 4 /* alpha */, NAN /* beta */, 6 /* gamma */);
-
- FireEvent();
-
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- // DeviceOrientation Event provides absolute orientation data when relative
- // orientation data is not available but absolute orientation data is
- // available.
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_FALSE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- // Since no relative orientation data is available, DeviceOrientationEvent
- // fallback to provide absolute orientation data.
- EXPECT_TRUE(received_data.absolute);
-
- orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) {
- // No active sensors.
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
- sensor_provider()->set_absolute_orientation_sensor_is_available(false);
-
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
-
- FireEvent();
-
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- EXPECT_FALSE(received_data.has_alpha);
- EXPECT_FALSE(received_data.has_beta);
- EXPECT_FALSE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
-
- orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest,
- NotFireEventWhenSensorReadingTimeStampIsZero) {
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- FireEvent();
-
- EXPECT_FALSE(listener()->did_change_device_orientation());
-
- orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest,
- NotFireEventWhenSensorReadingTimeStampIsZeroWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- FireEvent();
-
- EXPECT_FALSE(listener()->did_change_device_orientation());
-
- orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest, UpdateRespectsOrientationThreshold) {
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateRelativeOrientationSensorData(
- 1 /* alpha */, 2 /* beta */, 3 /* gamma */);
-
- FireEvent();
-
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- // DeviceOrientation Event provides relative orientation data when it is
- // available.
- EXPECT_DOUBLE_EQ(1, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(2, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(3, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
-
- listener()->set_did_change_device_orientation(false);
-
- sensor_provider()->UpdateRelativeOrientationSensorData(
- 1 + DeviceOrientationEventPump::kOrientationThreshold / 2.0 /* alpha */,
- 2 /* beta */, 3 /* gamma */);
-
- FireEvent();
-
- received_data = listener()->data();
- EXPECT_FALSE(listener()->did_change_device_orientation());
-
- EXPECT_DOUBLE_EQ(1, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(2, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(3, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
-
- listener()->set_did_change_device_orientation(false);
-
- sensor_provider()->UpdateRelativeOrientationSensorData(
- 1 + DeviceOrientationEventPump::kOrientationThreshold /* alpha */,
- 2 /* beta */, 3 /* gamma */);
-
- FireEvent();
-
- received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- EXPECT_DOUBLE_EQ(1 + DeviceOrientationEventPump::kOrientationThreshold,
- received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(2, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(3, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_FALSE(received_data.absolute);
-
- orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceOrientationEventPumpTest,
- UpdateRespectsOrientationThresholdWithSensorFallback) {
- sensor_provider()->set_relative_orientation_sensor_is_available(false);
-
- orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateAbsoluteOrientationSensorData(
- 4 /* alpha */, 5 /* beta */, 6 /* gamma */);
-
- FireEvent();
-
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- // DeviceOrientation Event provides absolute orientation data when relative
- // orientation data is not available but absolute orientation data is
- // available.
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- // Since no relative orientation data is available, DeviceOrientationEvent
- // fallback to provide absolute orientation data.
- EXPECT_TRUE(received_data.absolute);
-
- listener()->set_did_change_device_orientation(false);
-
- sensor_provider()->UpdateAbsoluteOrientationSensorData(
- 4 /* alpha */,
- 5 + DeviceOrientationEventPump::kOrientationThreshold / 2.0 /* beta */,
- 6 /* gamma */);
-
- FireEvent();
-
- received_data = listener()->data();
- EXPECT_FALSE(listener()->did_change_device_orientation());
-
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
-
- listener()->set_did_change_device_orientation(false);
-
- sensor_provider()->UpdateAbsoluteOrientationSensorData(
- 4 /* alpha */,
- 5 + DeviceOrientationEventPump::kOrientationThreshold +
- kEpsilon /* beta */,
- 6 /* gamma */);
-
- FireEvent();
-
- received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(
- 5 + DeviceOrientationEventPump::kOrientationThreshold + kEpsilon,
- received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
-
- orientation_pump()->Stop();
-
- ExpectRelativeOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-class DeviceAbsoluteOrientationEventPumpTest : public testing::Test {
- public:
- DeviceAbsoluteOrientationEventPumpTest() = default;
-
- protected:
- void SetUp() override {
- absolute_orientation_pump_.reset(
- new DeviceOrientationEventPumpForTesting(true /* absolute */));
- device::mojom::SensorProviderPtr sensor_provider_ptr;
- sensor_provider_.Bind(mojo::MakeRequest(&sensor_provider_ptr));
- absolute_orientation_pump_->SetSensorProviderForTesting(
- std::move(sensor_provider_ptr));
-
- listener_.reset(new MockDeviceOrientationListener);
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- absolute_orientation_pump()->GetPumpStateForTesting());
- }
-
- void FireEvent() { absolute_orientation_pump_->FireEvent(); }
-
- void ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState expected_sensor_state) {
- EXPECT_EQ(
- expected_sensor_state,
- absolute_orientation_pump_->absolute_orientation_sensor_.sensor_state);
- }
-
- DeviceOrientationEventPump* absolute_orientation_pump() {
- return absolute_orientation_pump_.get();
- }
-
- MockDeviceOrientationListener* listener() { return listener_.get(); }
-
- FakeSensorProvider* sensor_provider() { return &sensor_provider_; }
-
- private:
- base::MessageLoop loop_;
- std::unique_ptr<DeviceOrientationEventPumpForTesting>
- absolute_orientation_pump_;
- std::unique_ptr<MockDeviceOrientationListener> listener_;
- FakeSensorProvider sensor_provider_;
-
- DISALLOW_COPY_AND_ASSIGN(DeviceAbsoluteOrientationEventPumpTest);
-};
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, MultipleStartAndStopWithWait) {
- absolute_orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- absolute_orientation_pump()->GetPumpStateForTesting());
-
- absolute_orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- absolute_orientation_pump()->GetPumpStateForTesting());
-
- absolute_orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING,
- absolute_orientation_pump()->GetPumpStateForTesting());
-
- absolute_orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
- EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED,
- absolute_orientation_pump()->GetPumpStateForTesting());
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStop) {
- absolute_orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStartAndStop) {
- absolute_orientation_pump()->Start(listener());
- absolute_orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStartMultipleTimes) {
- absolute_orientation_pump()->Start(listener());
- absolute_orientation_pump()->Start(listener());
- absolute_orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStopMultipleTimes) {
- absolute_orientation_pump()->Start(listener());
- absolute_orientation_pump()->Stop();
- absolute_orientation_pump()->Stop();
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-// Test multiple DeviceSensorEventPump::Start() calls only bind sensor once.
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorOnlyBindOnce) {
- absolute_orientation_pump()->Start(listener());
- absolute_orientation_pump()->Stop();
- absolute_orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- absolute_orientation_pump()->Stop();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorIsActive) {
- absolute_orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateAbsoluteOrientationSensorData(
- 4 /* alpha */, 5 /* beta */, 6 /* gamma */);
-
- FireEvent();
-
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
-
- absolute_orientation_pump()->Stop();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest,
- SomeSensorDataFieldsNotAvailable) {
- absolute_orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateAbsoluteOrientationSensorData(
- 4 /* alpha */, NAN /* beta */, 6 /* gamma */);
-
- FireEvent();
-
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_FALSE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
-
- absolute_orientation_pump()->Stop();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest, FireAllNullEvent) {
- // No active sensor.
- sensor_provider()->set_absolute_orientation_sensor_is_available(false);
-
- absolute_orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
-
- FireEvent();
-
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- EXPECT_FALSE(received_data.has_alpha);
- EXPECT_FALSE(received_data.has_beta);
- EXPECT_FALSE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
-
- absolute_orientation_pump()->Stop();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::NOT_INITIALIZED);
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest,
- NotFireEventWhenSensorReadingTimeStampIsZero) {
- absolute_orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- FireEvent();
-
- EXPECT_FALSE(listener()->did_change_device_orientation());
-
- absolute_orientation_pump()->Stop();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-TEST_F(DeviceAbsoluteOrientationEventPumpTest,
- UpdateRespectsOrientationThreshold) {
- absolute_orientation_pump()->Start(listener());
- base::RunLoop().RunUntilIdle();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::ACTIVE);
-
- sensor_provider()->UpdateAbsoluteOrientationSensorData(
- 4 /* alpha */, 5 /* beta */, 6 /* gamma */);
-
- FireEvent();
-
- device::OrientationData received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
-
- listener()->set_did_change_device_orientation(false);
-
- sensor_provider()->UpdateAbsoluteOrientationSensorData(
- 4 /* alpha */,
- 5 + DeviceOrientationEventPump::kOrientationThreshold / 2.0 /* beta */,
- 6 /* gamma */);
-
- FireEvent();
-
- received_data = listener()->data();
- EXPECT_FALSE(listener()->did_change_device_orientation());
-
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(5, received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
-
- listener()->set_did_change_device_orientation(false);
-
- sensor_provider()->UpdateAbsoluteOrientationSensorData(
- 4 /* alpha */,
- 5 + DeviceOrientationEventPump::kOrientationThreshold +
- kEpsilon /* beta */,
- 6 /* gamma */);
-
- FireEvent();
-
- received_data = listener()->data();
- EXPECT_TRUE(listener()->did_change_device_orientation());
-
- EXPECT_DOUBLE_EQ(4, received_data.alpha);
- EXPECT_TRUE(received_data.has_alpha);
- EXPECT_DOUBLE_EQ(
- 5 + DeviceOrientationEventPump::kOrientationThreshold + kEpsilon,
- received_data.beta);
- EXPECT_TRUE(received_data.has_beta);
- EXPECT_DOUBLE_EQ(6, received_data.gamma);
- EXPECT_TRUE(received_data.has_gamma);
- EXPECT_TRUE(received_data.absolute);
-
- absolute_orientation_pump()->Stop();
-
- ExpectAbsoluteOrientationSensorStateToBe(
- DeviceOrientationEventPump::SensorState::SUSPENDED);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/device_sensors/device_sensor_event_pump.h b/chromium/content/renderer/device_sensors/device_sensor_event_pump.h
deleted file mode 100644
index 98d846bc08e..00000000000
--- a/chromium/content/renderer/device_sensors/device_sensor_event_pump.h
+++ /dev/null
@@ -1,329 +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_DEVICE_SENSORS_DEVICE_SENSOR_EVENT_PUMP_H_
-#define CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_SENSOR_EVENT_PUMP_H_
-
-#include <algorithm>
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/macros.h"
-#include "base/time/time.h"
-#include "base/timer/timer.h"
-#include "content/public/common/service_names.mojom.h"
-#include "content/public/renderer/platform_event_observer.h"
-#include "content/public/renderer/render_frame.h"
-#include "content/public/renderer/render_thread.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
-#include "services/device/public/cpp/generic_sensor/sensor_reading.h"
-#include "services/device/public/cpp/generic_sensor/sensor_reading_shared_buffer_reader.h"
-#include "services/device/public/cpp/generic_sensor/sensor_traits.h"
-#include "services/device/public/mojom/constants.mojom.h"
-#include "services/device/public/mojom/sensor_provider.mojom.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h"
-#include "third_party/blink/public/web/web_local_frame.h"
-
-namespace content {
-
-template <typename ListenerType>
-class CONTENT_EXPORT DeviceSensorEventPump
- : public PlatformEventObserver<ListenerType> {
- public:
- // Default rate for firing events.
- static constexpr int kDefaultPumpFrequencyHz = 60;
- static constexpr int kDefaultPumpDelayMicroseconds =
- base::Time::kMicrosecondsPerSecond / kDefaultPumpFrequencyHz;
-
- // The pump is a tri-state automaton with allowed transitions as follows:
- // STOPPED -> PENDING_START
- // PENDING_START -> RUNNING
- // PENDING_START -> STOPPED
- // RUNNING -> STOPPED
- enum class PumpState { STOPPED, RUNNING, PENDING_START };
-
- // The sensor state is an automaton with allowed transitions as follows:
- // NOT_INITIALIZED -> INITIALIZING
- // INITIALIZING -> ACTIVE
- // INITIALIZING -> SHOULD_SUSPEND
- // ACTIVE -> SUSPENDED
- // SHOULD_SUSPEND -> INITIALIZING
- // SHOULD_SUSPEND -> SUSPENDED
- // SUSPENDED -> ACTIVE
- // { INITIALIZING, ACTIVE, SHOULD_SUSPEND, SUSPENDED } -> NOT_INITIALIZED
- enum class SensorState {
- NOT_INITIALIZED,
- INITIALIZING,
- ACTIVE,
- SHOULD_SUSPEND,
- SUSPENDED
- };
-
- // PlatformEventObserver:
- void Start(blink::WebPlatformEventListener* listener) override {
- DVLOG(2) << "requested start";
-
- if (state_ != PumpState::STOPPED)
- return;
-
- DCHECK(!timer_.IsRunning());
-
- state_ = PumpState::PENDING_START;
- PlatformEventObserver<ListenerType>::Start(listener);
- }
-
- // PlatformEventObserver:
- void Stop() override {
- DVLOG(2) << "requested stop";
-
- if (state_ == PumpState::STOPPED)
- return;
-
- DCHECK((state_ == PumpState::PENDING_START && !timer_.IsRunning()) ||
- (state_ == PumpState::RUNNING && timer_.IsRunning()));
-
- if (timer_.IsRunning())
- timer_.Stop();
-
- PlatformEventObserver<ListenerType>::Stop();
- state_ = PumpState::STOPPED;
- }
-
- void HandleSensorProviderError() { sensor_provider_.reset(); }
-
- void SetSensorProviderForTesting(
- device::mojom::SensorProviderPtr sensor_provider) {
- sensor_provider_ = std::move(sensor_provider);
- }
-
- PumpState GetPumpStateForTesting() { return state_; }
-
- protected:
- explicit DeviceSensorEventPump(RenderThread* thread)
- : PlatformEventObserver<ListenerType>(thread),
- state_(PumpState::STOPPED) {}
-
- ~DeviceSensorEventPump() override {
- PlatformEventObserver<ListenerType>::StopIfObserving();
- }
-
- virtual void FireEvent() = 0;
-
- struct SensorEntry : public device::mojom::SensorClient {
- SensorEntry(DeviceSensorEventPump* pump,
- device::mojom::SensorType sensor_type)
- : event_pump(pump),
- sensor_state(SensorState::NOT_INITIALIZED),
- type(sensor_type),
- client_binding(this) {}
-
- ~SensorEntry() override {}
-
- // device::mojom::SensorClient:
- void RaiseError() override { HandleSensorError(); }
-
- // device::mojom::SensorClient:
- void SensorReadingChanged() override {
- // Since DeviceSensorEventPump::FireEvent is called in a fixed
- // frequency, the |shared_buffer| is read frequently, and
- // Sensor::ConfigureReadingChangeNotifications() is set to false,
- // so this method is not called and doesn't need to be implemented.
- NOTREACHED();
- }
-
- // Mojo callback for SensorProvider::GetSensor().
- void OnSensorCreated(device::mojom::SensorCreationResult result,
- device::mojom::SensorInitParamsPtr params) {
- // |sensor_state| can be SensorState::SHOULD_SUSPEND if Stop() is called
- // before OnSensorCreated() is called.
- DCHECK(sensor_state == SensorState::INITIALIZING ||
- sensor_state == SensorState::SHOULD_SUSPEND);
-
- if (!params) {
- HandleSensorError();
- event_pump->DidStartIfPossible();
- return;
- }
- DCHECK_EQ(device::mojom::SensorCreationResult::SUCCESS, result);
-
- constexpr size_t kReadBufferSize =
- sizeof(device::SensorReadingSharedBuffer);
-
- DCHECK_EQ(0u, params->buffer_offset % kReadBufferSize);
-
- mode = params->mode;
- default_config = params->default_configuration;
-
- sensor.Bind(std::move(params->sensor));
- client_binding.Bind(std::move(params->client_request));
-
- shared_buffer_handle = std::move(params->memory);
- DCHECK(!shared_buffer);
- shared_buffer = shared_buffer_handle->MapAtOffset(kReadBufferSize,
- params->buffer_offset);
- if (!shared_buffer) {
- HandleSensorError();
- event_pump->DidStartIfPossible();
- return;
- }
-
- const device::SensorReadingSharedBuffer* buffer =
- static_cast<const device::SensorReadingSharedBuffer*>(
- shared_buffer.get());
- shared_buffer_reader.reset(
- new device::SensorReadingSharedBufferReader(buffer));
-
- default_config.set_frequency(
- std::min(static_cast<double>(kDefaultPumpFrequencyHz),
- params->maximum_frequency));
-
- sensor.set_connection_error_handler(base::BindOnce(
- &SensorEntry::HandleSensorError, base::Unretained(this)));
- sensor->ConfigureReadingChangeNotifications(false /* disabled */);
- sensor->AddConfiguration(
- default_config, base::BindOnce(&SensorEntry::OnSensorAddConfiguration,
- base::Unretained(this)));
- }
-
- // Mojo callback for Sensor::AddConfiguration().
- void OnSensorAddConfiguration(bool success) {
- if (!success)
- HandleSensorError();
-
- if (sensor_state == SensorState::INITIALIZING) {
- sensor_state = SensorState::ACTIVE;
- event_pump->DidStartIfPossible();
- } else if (sensor_state == SensorState::SHOULD_SUSPEND) {
- sensor->Suspend();
- sensor_state = SensorState::SUSPENDED;
- }
- }
-
- void HandleSensorError() {
- sensor.reset();
- sensor_state = SensorState::NOT_INITIALIZED;
- shared_buffer_handle.reset();
- shared_buffer.reset();
- client_binding.Close();
- }
-
- bool SensorReadingCouldBeRead() {
- if (!sensor)
- return false;
-
- DCHECK(shared_buffer);
-
- if (!shared_buffer_handle->is_valid() ||
- !shared_buffer_reader->GetReading(&reading)) {
- HandleSensorError();
- return false;
- }
-
- return true;
- }
-
- bool ReadyOrErrored() const {
- // When some sensors are not available, the pump still needs to fire
- // events which set the unavailable sensor data fields to null.
- return sensor_state == SensorState::ACTIVE ||
- sensor_state == SensorState::NOT_INITIALIZED;
- }
-
- void Start(device::mojom::SensorProvider* sensor_provider) {
- if (sensor_state == SensorState::NOT_INITIALIZED) {
- sensor_state = SensorState::INITIALIZING;
- sensor_provider->GetSensor(type,
- base::BindOnce(&SensorEntry::OnSensorCreated,
- base::Unretained(this)));
- } else if (sensor_state == SensorState::SUSPENDED) {
- sensor->Resume();
- sensor_state = SensorState::ACTIVE;
- event_pump->DidStartIfPossible();
- } else if (sensor_state == SensorState::SHOULD_SUSPEND) {
- // This can happen when calling Start(), Stop(), Start() in a sequence:
- // After the first Start() call, the sensor state is
- // SensorState::INITIALIZING. Then after the Stop() call, the sensor
- // state is SensorState::SHOULD_SUSPEND, and the next Start() call needs
- // to set the sensor state to be SensorState::INITIALIZING again.
- sensor_state = SensorState::INITIALIZING;
- } else {
- NOTREACHED();
- }
- }
-
- void Stop() {
- if (sensor) {
- sensor->Suspend();
- sensor_state = SensorState::SUSPENDED;
- } else if (sensor_state == SensorState::INITIALIZING) {
- // When the sensor needs to be suspended, and it is still in the
- // SensorState::INITIALIZING state, the sensor creation is not affected
- // (the SensorEntry::OnSensorCreated() callback will run as usual), but
- // the sensor is marked as SensorState::SHOULD_SUSPEND, and when the
- // sensor is created successfully, it will be suspended and its state
- // will be marked as SensorState::SUSPENDED in the
- // SensorEntry::OnSensorAddConfiguration().
- sensor_state = SensorState::SHOULD_SUSPEND;
- }
- }
-
- DeviceSensorEventPump* event_pump;
- device::mojom::SensorPtr sensor;
- SensorState sensor_state;
- device::mojom::SensorType type;
- device::mojom::ReportingMode mode;
- device::PlatformSensorConfiguration default_config;
- mojo::ScopedSharedBufferHandle shared_buffer_handle;
- mojo::ScopedSharedBufferMapping shared_buffer;
- std::unique_ptr<device::SensorReadingSharedBufferReader>
- shared_buffer_reader;
- device::SensorReading reading;
- mojo::Binding<device::mojom::SensorClient> client_binding;
- };
-
- friend struct SensorEntry;
-
- virtual void DidStartIfPossible() {
- DVLOG(2) << "did start sensor event pump";
-
- if (state_ != PumpState::PENDING_START)
- return;
-
- if (!SensorsReadyOrErrored())
- return;
-
- DCHECK(!timer_.IsRunning());
-
- timer_.Start(
- FROM_HERE,
- base::TimeDelta::FromMicroseconds(kDefaultPumpDelayMicroseconds), this,
- &DeviceSensorEventPump::FireEvent);
- state_ = PumpState::RUNNING;
- }
-
- static RenderFrame* GetRenderFrame() {
- blink::WebLocalFrame* const web_frame =
- blink::WebLocalFrame::FrameForCurrentContext();
-
- return RenderFrame::FromWebFrame(web_frame);
- }
-
- device::mojom::SensorProviderPtr sensor_provider_;
-
- private:
- virtual bool SensorsReadyOrErrored() const = 0;
-
- PumpState state_;
- base::RepeatingTimer timer_;
-
- DISALLOW_COPY_AND_ASSIGN(DeviceSensorEventPump);
-};
-} // namespace content
-
-#endif // CONTENT_RENDERER_DEVICE_SENSORS_DEVICE_SENSOR_EVENT_PUMP_H_
diff --git a/chromium/content/renderer/dom_serializer_browsertest.cc b/chromium/content/renderer/dom_serializer_browsertest.cc
index fc8ff6e4ebd..2b188608b53 100644
--- a/chromium/content/renderer/dom_serializer_browsertest.cc
+++ b/chromium/content/renderer/dom_serializer_browsertest.cc
@@ -138,7 +138,11 @@ class MAYBE_DomSerializerTests : public ContentBrowserTest,
// Do not use WebFrame.LoadHTMLString because it assumes that input
// html contents use UTF-8 encoding.
WebData data(contents.data(), contents.length());
- GetMainFrame()->LoadData(data, "text/html", encoding_info, base_url);
+ GetMainFrame()->CommitDataNavigation(
+ data, "text/html", encoding_info, base_url, WebURL(),
+ false /* replace */, blink::WebFrameLoadType::kStandard,
+ blink::WebHistoryItem(), false /* is_client_redirect */,
+ nullptr /* navigation_data */, blink::WebNavigationTimings());
}
base::MessageLoopCurrent::ScopedNestableTaskAllower allow;
waiter.Wait();
diff --git a/chromium/content/renderer/dom_storage/dom_storage_cached_area.cc b/chromium/content/renderer/dom_storage/dom_storage_cached_area.cc
index f21e958f7d7..402c27727ff 100644
--- a/chromium/content/renderer/dom_storage/dom_storage_cached_area.cc
+++ b/chromium/content/renderer/dom_storage/dom_storage_cached_area.cc
@@ -11,7 +11,7 @@
#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/blink/public/platform/scheduler/web_main_thread_scheduler.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
namespace content {
@@ -19,7 +19,7 @@ DOMStorageCachedArea::DOMStorageCachedArea(
const std::string& namespace_id,
const GURL& origin,
DOMStorageProxy* proxy,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler)
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler)
: ignore_all_mutations_(false),
namespace_id_(namespace_id),
origin_(origin),
@@ -34,10 +34,12 @@ unsigned DOMStorageCachedArea::GetLength(int connection_id) {
return map_->Length();
}
-base::NullableString16 DOMStorageCachedArea::GetKey(int connection_id,
- unsigned index) {
+base::NullableString16 DOMStorageCachedArea::GetKey(
+ int connection_id,
+ unsigned index,
+ bool* did_decrease_iterator) {
PrimeIfNeeded(connection_id);
- return map_->Key(index);
+ return map_->Key(index, did_decrease_iterator);
}
base::NullableString16 DOMStorageCachedArea::GetItem(
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 a7ebb1dd0c2..dacf2da744f 100644
--- a/chromium/content/renderer/dom_storage/dom_storage_cached_area.h
+++ b/chromium/content/renderer/dom_storage/dom_storage_cached_area.h
@@ -19,7 +19,7 @@
namespace blink {
namespace scheduler {
-class WebMainThreadScheduler;
+class WebThreadScheduler;
}
} // namespace blink
@@ -41,13 +41,16 @@ class CONTENT_EXPORT DOMStorageCachedArea
const std::string& namespace_id,
const GURL& origin,
DOMStorageProxy* proxy,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler);
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler);
const std::string& namespace_id() const { return namespace_id_; }
const GURL& origin() const { return origin_; }
unsigned GetLength(int connection_id);
- base::NullableString16 GetKey(int connection_id, unsigned index);
+ // See DOMStorageMap for the meaning of |did_decrease_iterator|.
+ base::NullableString16 GetKey(int connection_id,
+ unsigned index,
+ bool* did_decrease_iterator = nullptr);
base::NullableString16 GetItem(int connection_id, const base::string16& key);
bool SetItem(int connection_id,
const base::string16& key,
@@ -104,7 +107,7 @@ class CONTENT_EXPORT DOMStorageCachedArea
scoped_refptr<DOMStorageProxy> proxy_;
// Not owned.
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler_;
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler_;
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 1c0afc9434d..f4d390d0a07 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
@@ -160,8 +160,7 @@ class DOMStorageCachedAreaTest : public testing::Test {
protected:
base::MessageLoop message_loop_; // Needed to construct a RendererScheduler.
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler>
- main_thread_scheduler_;
+ std::unique_ptr<blink::scheduler::WebThreadScheduler> main_thread_scheduler_;
scoped_refptr<MockProxy> mock_proxy_;
};
diff --git a/chromium/content/renderer/dom_storage/local_storage_area.cc b/chromium/content/renderer/dom_storage/local_storage_area.cc
index af5fe91bcc8..9aae8851998 100644
--- a/chromium/content/renderer/dom_storage/local_storage_area.cc
+++ b/chromium/content/renderer/dom_storage/local_storage_area.cc
@@ -28,8 +28,9 @@ unsigned LocalStorageArea::length() {
return cached_area_->GetLength();
}
-WebString LocalStorageArea::Key(unsigned index) {
- return WebString::FromUTF16(cached_area_->GetKey(index));
+WebString LocalStorageArea::Key(unsigned index, bool* did_decrease_iterator) {
+ return WebString::FromUTF16(
+ cached_area_->GetKey(index, did_decrease_iterator));
}
WebString LocalStorageArea::GetItem(const WebString& key) {
diff --git a/chromium/content/renderer/dom_storage/local_storage_area.h b/chromium/content/renderer/dom_storage/local_storage_area.h
index 55967276a12..01ed6f22673 100644
--- a/chromium/content/renderer/dom_storage/local_storage_area.h
+++ b/chromium/content/renderer/dom_storage/local_storage_area.h
@@ -22,7 +22,7 @@ class LocalStorageArea : public blink::WebStorageArea {
// blink::WebStorageArea:
unsigned length() override;
- blink::WebString Key(unsigned index) override;
+ blink::WebString Key(unsigned index, bool* did_decrease_iterator) override;
blink::WebString GetItem(const blink::WebString& key) override;
void SetItem(const blink::WebString& key,
const blink::WebString& value,
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 a56c6def416..ffa21c9200d 100644
--- a/chromium/content/renderer/dom_storage/local_storage_cached_area.cc
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_area.cc
@@ -15,12 +15,13 @@
#include "base/time/time.h"
#include "components/services/leveldb/public/cpp/util.h"
#include "content/common/dom_storage/dom_storage_map.h"
-#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/dom_storage/session_web_storage_namespace_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
+#include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom.h"
#include "third_party/blink/public/platform/web_url.h"
#include "third_party/blink/public/web/web_storage_event_dispatcher.h"
@@ -32,11 +33,11 @@ namespace {
// are serialized on disk.
enum class StorageFormat : uint8_t { UTF16 = 0, Latin1 = 1 };
-class GetAllCallback : public mojom::LevelDBWrapperGetAllCallback {
+class GetAllCallback : public blink::mojom::StorageAreaGetAllCallback {
public:
- static mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo CreateAndBind(
+ static blink::mojom::StorageAreaGetAllCallbackAssociatedPtrInfo CreateAndBind(
base::OnceCallback<void(bool)> callback) {
- mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo ptr_info;
+ blink::mojom::StorageAreaGetAllCallbackAssociatedPtrInfo ptr_info;
auto request = mojo::MakeRequest(&ptr_info);
mojo::MakeStrongAssociatedBinding(
base::WrapUnique(new GetAllCallback(std::move(callback))),
@@ -74,9 +75,9 @@ void UnpackSource(const std::string& source,
LocalStorageCachedArea::LocalStorageCachedArea(
const std::string& namespace_id,
const url::Origin& origin,
- mojom::SessionStorageNamespace* session_namespace,
+ blink::mojom::SessionStorageNamespace* session_namespace,
LocalStorageCachedAreas* cached_areas,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler)
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler)
: namespace_id_(namespace_id),
origin_(origin),
binding_(this),
@@ -84,33 +85,33 @@ LocalStorageCachedArea::LocalStorageCachedArea(
main_thread_scheduler_(main_thread_scheduler),
weak_factory_(this) {
DCHECK(!namespace_id_.empty());
-
- mojom::LevelDBWrapperAssociatedPtrInfo wrapper_ptr_info;
+ blink::mojom::StorageAreaAssociatedPtrInfo wrapper_ptr_info;
session_namespace->OpenArea(origin_, mojo::MakeRequest(&wrapper_ptr_info));
leveldb_.Bind(std::move(wrapper_ptr_info),
main_thread_scheduler->IPCTaskRunner());
- mojom::LevelDBObserverAssociatedPtrInfo ptr_info;
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo ptr_info;
binding_.Bind(mojo::MakeRequest(&ptr_info),
main_thread_scheduler->IPCTaskRunner());
+ leveldb_->AddObserver(std::move(ptr_info));
}
LocalStorageCachedArea::LocalStorageCachedArea(
const url::Origin& origin,
- mojom::StoragePartitionService* storage_partition_service,
+ blink::mojom::StoragePartitionService* storage_partition_service,
LocalStorageCachedAreas* cached_areas,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler)
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler)
: origin_(origin),
binding_(this),
cached_areas_(cached_areas),
main_thread_scheduler_(main_thread_scheduler),
weak_factory_(this) {
DCHECK(namespace_id_.empty());
- mojom::LevelDBWrapperPtrInfo wrapper_ptr_info;
+ blink::mojom::StorageAreaPtrInfo wrapper_ptr_info;
storage_partition_service->OpenLocalStorage(
origin_, mojo::MakeRequest(&wrapper_ptr_info));
leveldb_.Bind(std::move(wrapper_ptr_info),
main_thread_scheduler->IPCTaskRunner());
- mojom::LevelDBObserverAssociatedPtrInfo ptr_info;
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo ptr_info;
binding_.Bind(mojo::MakeRequest(&ptr_info),
main_thread_scheduler->IPCTaskRunner());
leveldb_->AddObserver(std::move(ptr_info));
@@ -123,9 +124,11 @@ unsigned LocalStorageCachedArea::GetLength() {
return map_->Length();
}
-base::NullableString16 LocalStorageCachedArea::GetKey(unsigned index) {
+base::NullableString16 LocalStorageCachedArea::GetKey(
+ unsigned index,
+ bool* did_decrease_iterator) {
EnsureLoaded();
- return map_->Key(index);
+ return map_->Key(index, did_decrease_iterator);
}
base::NullableString16 LocalStorageCachedArea::GetItem(
@@ -433,7 +436,6 @@ void LocalStorageCachedArea::KeyDeleted(const std::vector<uint8_t>& key,
}
void LocalStorageCachedArea::AllDeleted(const std::string& source) {
- DCHECK(!IsSessionStorage());
GURL page_url;
std::string storage_area_id;
UnpackSource(source, &page_url, &storage_area_id);
@@ -457,9 +459,18 @@ void LocalStorageCachedArea::AllDeleted(const std::string& source) {
}
}
- blink::WebStorageEventDispatcher::DispatchLocalStorageEvent(
- blink::WebString(), blink::WebString(), blink::WebString(),
- origin_.GetURL(), page_url, originating_area);
+ if (IsSessionStorage()) {
+ SessionWebStorageNamespaceImpl session_namespace_for_event_dispatch(
+ namespace_id_, nullptr);
+ blink::WebStorageEventDispatcher::DispatchSessionStorageEvent(
+ blink::WebString(), blink::WebString(), blink::WebString(),
+ origin_.GetURL(), page_url, session_namespace_for_event_dispatch,
+ originating_area);
+ } else {
+ blink::WebStorageEventDispatcher::DispatchLocalStorageEvent(
+ blink::WebString(), blink::WebString(), blink::WebString(),
+ origin_.GetURL(), page_url, originating_area);
+ }
}
void LocalStorageCachedArea::ShouldSendOldValueOnMutations(bool value) {
@@ -513,12 +524,12 @@ void LocalStorageCachedArea::EnsureLoaded() {
base::TimeTicks before = base::TimeTicks::Now();
ignore_all_mutations_ = true;
- leveldb::mojom::DatabaseError status = leveldb::mojom::DatabaseError::OK;
- std::vector<content::mojom::KeyValuePtr> data;
+ bool success = false;
+ std::vector<blink::mojom::KeyValuePtr> data;
leveldb_->GetAll(GetAllCallback::CreateAndBind(
base::BindOnce(&LocalStorageCachedArea::OnGetAllComplete,
weak_factory_.GetWeakPtr())),
- &status, &data);
+ &success, &data);
DOMStorageValuesMap values;
bool is_session_storage = IsSessionStorage();
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 a4b8b03b4a8..9780e7ad402 100644
--- a/chromium/content/renderer/dom_storage/local_storage_cached_area.h
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_area.h
@@ -12,16 +12,21 @@
#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 "content/common/possibly_associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_area.mojom.h"
#include "third_party/blink/public/platform/web_scoped_virtual_time_pauser.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace blink {
+namespace mojom {
+class SessionStorageNamespace;
+class StoragePartitionService;
+} // namespace mojom
+
namespace scheduler {
-class WebMainThreadScheduler;
+class WebThreadScheduler;
}
} // namespace blink
@@ -29,11 +34,6 @@ namespace content {
class LocalStorageArea;
class LocalStorageCachedAreas;
-namespace mojom {
-class StoragePartitionService;
-class SessionStorageNamespace;
-}
-
// An in-process implementation of LocalStorage using a LevelDB Mojo service.
// Maintains a complete cache of the origin's Map of key/value pairs for fast
// access. The cache is primed on first access and changes are written to the
@@ -44,24 +44,26 @@ class SessionStorageNamespace;
// objects.
// TODO(dmurph): Rename to remove LocalStorage.
class CONTENT_EXPORT LocalStorageCachedArea
- : public mojom::LevelDBObserver,
+ : public blink::mojom::StorageAreaObserver,
public base::RefCounted<LocalStorageCachedArea> {
public:
LocalStorageCachedArea(
const std::string& namespace_id,
const url::Origin& origin,
- mojom::SessionStorageNamespace* session_namespace,
+ blink::mojom::SessionStorageNamespace* session_namespace,
LocalStorageCachedAreas* cached_areas,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler);
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler);
LocalStorageCachedArea(
const url::Origin& origin,
- mojom::StoragePartitionService* storage_partition_service,
+ blink::mojom::StoragePartitionService* storage_partition_service,
LocalStorageCachedAreas* cached_areas,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler);
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler);
// These correspond to blink::WebStorageArea.
unsigned GetLength();
- base::NullableString16 GetKey(unsigned index);
+ // See DOMStorageMap for the meaning of |did_decrease_iterator|.
+ base::NullableString16 GetKey(unsigned index,
+ bool* did_decrease_iterator = nullptr);
base::NullableString16 GetItem(const base::string16& key);
bool SetItem(const base::string16& key,
const base::string16& value,
@@ -146,13 +148,13 @@ class CONTENT_EXPORT LocalStorageCachedArea
bool ignore_all_mutations_ = false;
// See ShouldSendOldValueOnMutations().
bool should_send_old_value_on_mutations_ = true;
- content::PossiblyAssociatedInterfacePtr<mojom::LevelDBWrapper> leveldb_;
- mojo::AssociatedBinding<mojom::LevelDBObserver> binding_;
+ content::PossiblyAssociatedInterfacePtr<blink::mojom::StorageArea> leveldb_;
+ mojo::AssociatedBinding<blink::mojom::StorageAreaObserver> binding_;
LocalStorageCachedAreas* cached_areas_;
std::map<std::string, LocalStorageArea*> areas_;
// Not owned.
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler_;
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler_;
base::WeakPtrFactory<LocalStorageCachedArea> weak_factory_;
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 341cbc23f33..2134e99cc92 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
@@ -10,7 +10,6 @@
#include "base/bind.h"
#include "base/strings/utf_string_conversions.h"
-#include "content/common/leveldb_wrapper.mojom.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/renderer/dom_storage/local_storage_cached_areas.h"
#include "content/renderer/dom_storage/mock_leveldb_wrapper.h"
@@ -77,7 +76,7 @@ class LocalStorageCachedAreaTest : public testing::Test {
protected:
TestBrowserThreadBundle test_browser_thread_bundle_;
MockLevelDBWrapper mock_leveldb_wrapper_;
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler> renderer_scheduler_;
+ std::unique_ptr<blink::scheduler::WebThreadScheduler> renderer_scheduler_;
LocalStorageCachedAreas cached_areas_;
};
@@ -190,7 +189,7 @@ TEST_F(LocalStorageCachedAreaTest, Setters) {
TEST_F(LocalStorageCachedAreaTest, MutationsAreIgnoredUntilLoadCompletion) {
scoped_refptr<LocalStorageCachedArea> cached_area =
cached_areas_.GetCachedArea(kOrigin);
- mojom::LevelDBObserver* observer = cached_area.get();
+ blink::mojom::StorageAreaObserver* observer = cached_area.get();
EXPECT_TRUE(cached_area->GetItem(kKey).is_null());
EXPECT_TRUE(IsCacheLoaded(cached_area.get()));
@@ -243,7 +242,7 @@ TEST_F(LocalStorageCachedAreaTest, MutationsAreIgnoredUntilClearCompletion) {
TEST_F(LocalStorageCachedAreaTest, KeyMutationsAreIgnoredUntilCompletion) {
scoped_refptr<LocalStorageCachedArea> cached_area =
cached_areas_.GetCachedArea(kOrigin);
- mojom::LevelDBObserver* observer = cached_area.get();
+ blink::mojom::StorageAreaObserver* observer = cached_area.get();
// SetItem
EXPECT_TRUE(cached_area->SetItem(kKey, kValue, kPageUrl, kStorageAreaId));
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 1f2133c87d6..7c2327ac3df 100644
--- a/chromium/content/renderer/dom_storage/local_storage_cached_areas.cc
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_areas.cc
@@ -11,29 +11,36 @@
#include "content/public/common/content_features.h"
#include "content/renderer/dom_storage/local_storage_cached_area.h"
#include "content/renderer/render_thread_impl.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom.h"
namespace content {
namespace {
const size_t kTotalCacheLimitInBytesLowEnd = 1 * 1024 * 1024;
const size_t kTotalCacheLimitInBytes = 5 * 1024 * 1024;
+const constexpr int64_t kDOMStorageObjectPrefix = 0x0001020304050607;
+const constexpr int64_t kDOMStorageObjectPostfix = 0x08090a0b0c0d0e0f;
+
// An empty namespace is the local storage namespace.
constexpr const char kLocalStorageNamespaceId[] = "";
} // namespace
LocalStorageCachedAreas::LocalStorageCachedAreas(
- mojom::StoragePartitionService* storage_partition_service,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler)
+ blink::mojom::StoragePartitionService* storage_partition_service,
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler)
: storage_partition_service_(storage_partition_service),
total_cache_limit_(base::SysInfo::IsLowEndDevice()
? kTotalCacheLimitInBytesLowEnd
: kTotalCacheLimitInBytes),
main_thread_scheduler_(main_thread_scheduler) {}
-LocalStorageCachedAreas::~LocalStorageCachedAreas() {}
+LocalStorageCachedAreas::~LocalStorageCachedAreas() {
+ CHECK(sequence_checker_.CalledOnValidSequence());
+}
scoped_refptr<LocalStorageCachedArea> LocalStorageCachedAreas::GetCachedArea(
const url::Origin& origin) {
+ CHECK(sequence_checker_.CalledOnValidSequence());
return GetCachedArea(kLocalStorageNamespaceId, origin,
main_thread_scheduler_);
}
@@ -42,6 +49,7 @@ scoped_refptr<LocalStorageCachedArea>
LocalStorageCachedAreas::GetSessionStorageArea(const std::string& namespace_id,
const url::Origin& origin) {
DCHECK_NE(kLocalStorageNamespaceId, namespace_id);
+ CHECK(sequence_checker_.CalledOnValidSequence());
return GetCachedArea(namespace_id, origin, main_thread_scheduler_);
}
@@ -51,6 +59,7 @@ void LocalStorageCachedAreas::CloneNamespace(
DCHECK(base::FeatureList::IsEnabled(features::kMojoSessionStorage));
DCHECK_EQ(kSessionStorageNamespaceIdLength, source_namespace.size());
DCHECK_EQ(kSessionStorageNamespaceIdLength, destination_namespace.size());
+ CHECK(sequence_checker_.CalledOnValidSequence());
auto namespace_it = cached_namespaces_.find(source_namespace);
if (namespace_it == cached_namespaces_.end()) {
@@ -67,6 +76,7 @@ void LocalStorageCachedAreas::CloneNamespace(
}
size_t LocalStorageCachedAreas::TotalCacheSize() const {
+ CHECK(sequence_checker_.CalledOnValidSequence());
size_t total = 0;
for (const auto& it : cached_namespaces_)
total += it.second.TotalCacheSize();
@@ -74,6 +84,7 @@ size_t LocalStorageCachedAreas::TotalCacheSize() const {
}
void LocalStorageCachedAreas::ClearAreasIfNeeded() {
+ CHECK(sequence_checker_.CalledOnValidSequence());
if (TotalCacheSize() < total_cache_limit_)
return;
@@ -84,7 +95,8 @@ void LocalStorageCachedAreas::ClearAreasIfNeeded() {
scoped_refptr<LocalStorageCachedArea> LocalStorageCachedAreas::GetCachedArea(
const std::string& namespace_id,
const url::Origin& origin,
- blink::scheduler::WebMainThreadScheduler* scheduler) {
+ blink::scheduler::WebThreadScheduler* scheduler) {
+ CHECK(sequence_checker_.CalledOnValidSequence());
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class CacheMetrics {
@@ -102,6 +114,7 @@ scoped_refptr<LocalStorageCachedArea> LocalStorageCachedAreas::GetCachedArea(
metric = CacheMetrics::kMiss;
} else {
dom_namespace = &namespace_it->second;
+ dom_namespace->CheckPrefixes();
auto cache_it = dom_namespace->cached_areas.find(origin);
if (cache_it == dom_namespace->cached_areas.end()) {
metric = CacheMetrics::kMiss;
@@ -124,6 +137,7 @@ scoped_refptr<LocalStorageCachedArea> LocalStorageCachedAreas::GetCachedArea(
if (!dom_namespace) {
dom_namespace = &cached_namespaces_[namespace_id];
}
+ dom_namespace->CheckPrefixes();
if (namespace_id == kLocalStorageNamespaceId) {
result = base::MakeRefCounted<LocalStorageCachedArea>(
origin, storage_partition_service_, this, scheduler);
@@ -143,12 +157,21 @@ scoped_refptr<LocalStorageCachedArea> LocalStorageCachedAreas::GetCachedArea(
return result;
}
-LocalStorageCachedAreas::DOMStorageNamespace::DOMStorageNamespace() {}
-LocalStorageCachedAreas::DOMStorageNamespace::~DOMStorageNamespace() {}
+LocalStorageCachedAreas::DOMStorageNamespace::DOMStorageNamespace()
+ : prefix(kDOMStorageObjectPrefix), postfix(kDOMStorageObjectPostfix) {}
+LocalStorageCachedAreas::DOMStorageNamespace::~DOMStorageNamespace() {
+ CheckPrefixes();
+}
LocalStorageCachedAreas::DOMStorageNamespace::DOMStorageNamespace(
LocalStorageCachedAreas::DOMStorageNamespace&& other) = default;
+void LocalStorageCachedAreas::DOMStorageNamespace::CheckPrefixes() const {
+ CHECK_EQ(kDOMStorageObjectPrefix, prefix) << "Memory corruption?";
+ CHECK_EQ(kDOMStorageObjectPostfix, postfix) << "Memory corruption?";
+}
+
size_t LocalStorageCachedAreas::DOMStorageNamespace::TotalCacheSize() const {
+ CheckPrefixes();
size_t total = 0;
for (const auto& it : cached_areas)
total += it.second.get()->memory_used();
@@ -156,6 +179,7 @@ size_t LocalStorageCachedAreas::DOMStorageNamespace::TotalCacheSize() const {
}
bool LocalStorageCachedAreas::DOMStorageNamespace::CleanUpUnusedAreas() {
+ CheckPrefixes();
base::EraseIf(cached_areas,
[](auto& pair) { return pair.second->HasOneRef(); });
return cached_areas.empty();
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 53ad4de71ce..390b7eddf4c 100644
--- a/chromium/content/renderer/dom_storage/local_storage_cached_areas.h
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_areas.h
@@ -5,29 +5,31 @@
#ifndef CONTENT_RENDERER_DOM_STORAGE_LOCAL_STORAGE_CACHED_AREAS_H_
#define CONTENT_RENDERER_DOM_STORAGE_LOCAL_STORAGE_CACHED_AREAS_H_
+#include <array>
#include <map>
#include <string>
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "base/sequence_checker.h"
#include "content/common/content_export.h"
-#include "content/common/storage_partition_service.mojom.h"
+#include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom.h"
#include "url/origin.h"
namespace blink {
+namespace mojom {
+class StoragePartitionService;
+}
+
namespace scheduler {
-class WebMainThreadScheduler;
+class WebThreadScheduler;
}
} // namespace blink
namespace content {
class LocalStorageCachedArea;
-namespace mojom {
-class StoragePartitionService;
-}
-
// Keeps a map of all the LocalStorageCachedArea objects in a renderer. This is
// 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
@@ -36,8 +38,8 @@ class StoragePartitionService;
class CONTENT_EXPORT LocalStorageCachedAreas {
public:
LocalStorageCachedAreas(
- mojom::StoragePartitionService* storage_partition_service,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler);
+ blink::mojom::StoragePartitionService* storage_partition_service,
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler);
~LocalStorageCachedAreas();
// Returns, creating if necessary, a cached storage area for the given origin.
@@ -53,7 +55,10 @@ class CONTENT_EXPORT LocalStorageCachedAreas {
size_t TotalCacheSize() const;
- void set_cache_limit_for_testing(size_t limit) { total_cache_limit_ = limit; }
+ void set_cache_limit_for_testing(size_t limit) {
+ CHECK(sequence_checker_.CalledOnValidSequence());
+ total_cache_limit_ = limit;
+ }
private:
void ClearAreasIfNeeded();
@@ -61,9 +66,13 @@ class CONTENT_EXPORT LocalStorageCachedAreas {
scoped_refptr<LocalStorageCachedArea> GetCachedArea(
const std::string& namespace_id,
const url::Origin& origin,
- blink::scheduler::WebMainThreadScheduler* scheduler);
+ blink::scheduler::WebThreadScheduler* scheduler);
- mojom::StoragePartitionService* const storage_partition_service_;
+ // TODO(dmurph): Remove release check when crashing has stopped.
+ // http://crbug.com/857464
+ base::SequenceCheckerImpl sequence_checker_;
+
+ blink::mojom::StoragePartitionService* const storage_partition_service_;
struct DOMStorageNamespace {
public:
@@ -72,13 +81,19 @@ class CONTENT_EXPORT LocalStorageCachedAreas {
DOMStorageNamespace(DOMStorageNamespace&& other);
DOMStorageNamespace& operator=(DOMStorageNamespace&&) = default;
+ void CheckPrefixes() const;
+
size_t TotalCacheSize() const;
// Returns true if this namespace is totally unused and can be deleted.
bool CleanUpUnusedAreas();
- mojom::SessionStorageNamespacePtr session_storage_namespace;
+ // TODO(dmurph): Remove the prefix & postfix after memory corruption is
+ // solved.
+ int64_t prefix;
+ blink::mojom::SessionStorageNamespacePtr session_storage_namespace;
base::flat_map<url::Origin, scoped_refptr<LocalStorageCachedArea>>
cached_areas;
+ int64_t postfix;
DISALLOW_COPY_AND_ASSIGN(DOMStorageNamespace);
};
@@ -87,7 +102,7 @@ class CONTENT_EXPORT LocalStorageCachedAreas {
size_t total_cache_limit_;
// Not owned.
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler_;
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler_;
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
index 15704b82293..70d5b0d97be 100644
--- a/chromium/content/renderer/dom_storage/local_storage_cached_areas_unittest.cc
+++ b/chromium/content/renderer/dom_storage/local_storage_cached_areas_unittest.cc
@@ -11,12 +11,25 @@
#include "content/public/common/content_features.h"
#include "content/renderer/dom_storage/local_storage_cached_area.h"
#include "content/renderer/dom_storage/mock_leveldb_wrapper.h"
+#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/fake_renderer_scheduler.h"
namespace content {
-TEST(LocalStorageCachedAreasTest, CacheLimit) {
- base::test::ScopedTaskEnvironment scoped_task_environment;
+class LocalStorageCachedAreasTest : public testing::Test {
+ // testing::Test:
+ void TearDown() override {
+ // Some of these tests close message pipes which serve as master interfaces
+ // to other associated interfaces; this in turn schedules tasks to invoke
+ // the associated interfaces' error handlers, and local storage code relies
+ // on those handlers running in order to avoid memory leaks at shutdown.
+ scoped_task_environment_.RunUntilIdle();
+ }
+
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+};
+
+TEST_F(LocalStorageCachedAreasTest, CacheLimit) {
const url::Origin kOrigin = url::Origin::Create(GURL("http://dom_storage1/"));
const url::Origin kOrigin2 =
url::Origin::Create(GURL("http://dom_storage2/"));
@@ -59,8 +72,7 @@ TEST(LocalStorageCachedAreasTest, CacheLimit) {
EXPECT_EQ(cached_area2->memory_used(), cached_areas.TotalCacheSize());
}
-TEST(LocalStorageCachedAreasTest, CloneBeforeGetArea) {
- base::test::ScopedTaskEnvironment scoped_task_environment;
+TEST_F(LocalStorageCachedAreasTest, CloneBeforeGetArea) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kMojoSessionStorage);
const std::string kNamespace1 = base::GenerateGUID();
diff --git a/chromium/content/renderer/dom_storage/local_storage_namespace.cc b/chromium/content/renderer/dom_storage/local_storage_namespace.cc
index d493cc4a3f1..8ec1992b762 100644
--- a/chromium/content/renderer/dom_storage/local_storage_namespace.cc
+++ b/chromium/content/renderer/dom_storage/local_storage_namespace.cc
@@ -24,6 +24,10 @@ LocalStorageNamespace::LocalStorageNamespace(
LocalStorageNamespace::~LocalStorageNamespace() {
}
+blink::WebString LocalStorageNamespace::GetNamespaceId() const {
+ return blink::WebString();
+}
+
WebStorageArea* LocalStorageNamespace::CreateStorageArea(
const blink::WebSecurityOrigin& origin) {
return new LocalStorageArea(
diff --git a/chromium/content/renderer/dom_storage/local_storage_namespace.h b/chromium/content/renderer/dom_storage/local_storage_namespace.h
index 65fc4f17956..b0ce38458fe 100644
--- a/chromium/content/renderer/dom_storage/local_storage_namespace.h
+++ b/chromium/content/renderer/dom_storage/local_storage_namespace.h
@@ -22,6 +22,9 @@ class LocalStorageNamespace : public blink::WebStorageNamespace {
// blink::WebStorageNamespace:
blink::WebStorageArea* CreateStorageArea(
const blink::WebSecurityOrigin& origin) override;
+
+ blink::WebString GetNamespaceId() const override;
+
bool IsSameNamespace(const WebStorageNamespace&) const override;
private:
diff --git a/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.cc b/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.cc
index 4dcdf113160..3cc34427cc4 100644
--- a/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.cc
+++ b/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.cc
@@ -11,14 +11,14 @@
namespace content {
class MockLevelDBWrapper::MockSessionStorageNamespace
- : public mojom::SessionStorageNamespace {
+ : public blink::mojom::SessionStorageNamespace {
public:
MockSessionStorageNamespace(std::string namespace_id,
MockLevelDBWrapper* wrapper)
: namespace_id_(std::move(namespace_id)), wrapper_(wrapper) {}
void OpenArea(const url::Origin& origin,
- mojom::LevelDBWrapperAssociatedRequest database) override {
+ blink::mojom::StorageAreaAssociatedRequest database) override {
bindings_.AddBinding(wrapper_, std::move(database));
}
@@ -31,7 +31,7 @@ class MockLevelDBWrapper::MockSessionStorageNamespace
private:
std::string namespace_id_;
MockLevelDBWrapper* wrapper_;
- mojo::AssociatedBindingSet<mojom::LevelDBWrapper> bindings_;
+ mojo::AssociatedBindingSet<blink::mojom::StorageArea> bindings_;
};
MockLevelDBWrapper::MockLevelDBWrapper() {}
@@ -39,20 +39,20 @@ MockLevelDBWrapper::~MockLevelDBWrapper() {}
void MockLevelDBWrapper::OpenLocalStorage(
const url::Origin& origin,
- mojom::LevelDBWrapperRequest database) {
+ blink::mojom::StorageAreaRequest database) {
bindings_.AddBinding(this, std::move(database));
}
void MockLevelDBWrapper::OpenSessionStorage(
const std::string& namespace_id,
- mojom::SessionStorageNamespaceRequest request) {
+ blink::mojom::SessionStorageNamespaceRequest request) {
namespace_bindings_.AddBinding(
std::make_unique<MockSessionStorageNamespace>(namespace_id, this),
std::move(request));
}
void MockLevelDBWrapper::AddObserver(
- mojom::LevelDBObserverAssociatedPtrInfo observer) {}
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo observer) {}
void MockLevelDBWrapper::Put(
const std::vector<uint8_t>& key,
@@ -89,22 +89,23 @@ void MockLevelDBWrapper::Get(const std::vector<uint8_t>& key,
GetCallback callback) {}
void MockLevelDBWrapper::GetAll(
- mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo complete_callback,
+ blink::mojom::StorageAreaGetAllCallbackAssociatedPtrInfo complete_callback,
GetAllCallback callback) {
- mojom::LevelDBWrapperGetAllCallbackAssociatedPtr complete_ptr;
+ blink::mojom::StorageAreaGetAllCallbackAssociatedPtr complete_ptr;
complete_ptr.Bind(std::move(complete_callback));
- pending_callbacks_.push_back(base::BindOnce(
- &mojom::LevelDBWrapperGetAllCallback::Complete, std::move(complete_ptr)));
+ pending_callbacks_.push_back(
+ base::BindOnce(&blink::mojom::StorageAreaGetAllCallback::Complete,
+ std::move(complete_ptr)));
observed_get_all_ = true;
- std::vector<mojom::KeyValuePtr> all;
+ std::vector<blink::mojom::KeyValuePtr> all;
for (const auto& it : get_all_return_values_) {
- mojom::KeyValuePtr kv = mojom::KeyValue::New();
+ auto kv = blink::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(true, 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
index 8c96fda2e03..d459ddbad73 100644
--- a/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.h
+++ b/chromium/content/renderer/dom_storage/mock_leveldb_wrapper.h
@@ -5,18 +5,18 @@
#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 "mojo/public/cpp/bindings/strong_binding_set.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_area.mojom.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom.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 {
+class MockLevelDBWrapper : public blink::mojom::StoragePartitionService,
+ public blink::mojom::StorageArea {
public:
using ResultCallback = base::OnceCallback<void(bool)>;
@@ -25,13 +25,14 @@ class MockLevelDBWrapper : public mojom::StoragePartitionService,
// StoragePartitionService implementation:
void OpenLocalStorage(const url::Origin& origin,
- mojom::LevelDBWrapperRequest database) override;
+ blink::mojom::StorageAreaRequest database) override;
void OpenSessionStorage(
const std::string& namespace_id,
- mojom::SessionStorageNamespaceRequest request) override;
+ blink::mojom::SessionStorageNamespaceRequest request) override;
- // LevelDBWrapper implementation:
- void AddObserver(mojom::LevelDBObserverAssociatedPtrInfo observer) override;
+ // StorageArea implementation:
+ void AddObserver(
+ blink::mojom::StorageAreaObserverAssociatedPtrInfo observer) override;
void Put(const std::vector<uint8_t>& key,
const std::vector<uint8_t>& value,
@@ -49,9 +50,9 @@ class MockLevelDBWrapper : public mojom::StoragePartitionService,
void Get(const std::vector<uint8_t>& key, GetCallback callback) override;
- void GetAll(
- mojom::LevelDBWrapperGetAllCallbackAssociatedPtrInfo complete_callback,
- GetAllCallback callback) override;
+ void GetAll(blink::mojom::StorageAreaGetAllCallbackAssociatedPtrInfo
+ complete_callback,
+ GetAllCallback callback) override;
// Methods and members for use by test fixtures.
bool HasBindings() { return !bindings_.empty(); }
@@ -117,8 +118,9 @@ class MockLevelDBWrapper : public mojom::StoragePartitionService,
std::map<std::vector<uint8_t>, std::vector<uint8_t>> get_all_return_values_;
- mojo::BindingSet<mojom::LevelDBWrapper> bindings_;
- mojo::StrongBindingSet<mojom::SessionStorageNamespace> namespace_bindings_;
+ mojo::BindingSet<blink::mojom::StorageArea> bindings_;
+ mojo::StrongBindingSet<blink::mojom::SessionStorageNamespace>
+ namespace_bindings_;
};
} // namespace content
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
index 8745849d9b3..b2d9c70b632 100644
--- a/chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.cc
+++ b/chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.cc
@@ -31,11 +31,13 @@ WebStorageArea* SessionWebStorageNamespaceImpl::CreateStorageArea(
origin));
}
+blink::WebString SessionWebStorageNamespaceImpl::GetNamespaceId() const {
+ return blink::WebString::FromASCII(namespace_id_);
+}
+
bool SessionWebStorageNamespaceImpl::IsSameNamespace(
const WebStorageNamespace& other) const {
- const SessionWebStorageNamespaceImpl* other_impl =
- static_cast<const SessionWebStorageNamespaceImpl*>(&other);
- return namespace_id_ == other_impl->namespace_id_;
+ return GetNamespaceId() == other.GetNamespaceId();
}
} // 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
index d69b8f3e490..52830aa2cc7 100644
--- a/chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.h
+++ b/chromium/content/renderer/dom_storage/session_web_storage_namespace_impl.h
@@ -23,6 +23,7 @@ class SessionWebStorageNamespaceImpl : public blink::WebStorageNamespace {
// blink::WebStorageNamespace:
blink::WebStorageArea* CreateStorageArea(
const blink::WebSecurityOrigin& origin) override;
+ blink::WebString GetNamespaceId() const override;
bool IsSameNamespace(const WebStorageNamespace&) const override;
private:
diff --git a/chromium/content/renderer/dom_storage/webstoragearea_impl.cc b/chromium/content/renderer/dom_storage/webstoragearea_impl.cc
index e47617f860d..f3041216603 100644
--- a/chromium/content/renderer/dom_storage/webstoragearea_impl.cc
+++ b/chromium/content/renderer/dom_storage/webstoragearea_impl.cc
@@ -50,8 +50,9 @@ unsigned WebStorageAreaImpl::length() {
return cached_area_->GetLength(connection_id_);
}
-WebString WebStorageAreaImpl::Key(unsigned index) {
- return WebString::FromUTF16(cached_area_->GetKey(connection_id_, index));
+WebString WebStorageAreaImpl::Key(unsigned index, bool* did_decrease_iterator) {
+ return WebString::FromUTF16(
+ cached_area_->GetKey(connection_id_, index, did_decrease_iterator));
}
WebString WebStorageAreaImpl::GetItem(const WebString& key) {
diff --git a/chromium/content/renderer/dom_storage/webstoragearea_impl.h b/chromium/content/renderer/dom_storage/webstoragearea_impl.h
index ca47ab4e485..e7c6bcdcd9d 100644
--- a/chromium/content/renderer/dom_storage/webstoragearea_impl.h
+++ b/chromium/content/renderer/dom_storage/webstoragearea_impl.h
@@ -27,7 +27,7 @@ class WebStorageAreaImpl : public blink::WebStorageArea {
// See WebStorageArea.h for documentation on these functions.
unsigned length() override;
- blink::WebString Key(unsigned index) override;
+ blink::WebString Key(unsigned index, bool* did_decrease_iterator) override;
blink::WebString GetItem(const blink::WebString& key) override;
void SetItem(const blink::WebString& key,
const blink::WebString& value,
diff --git a/chromium/content/renderer/dom_storage/webstoragenamespace_impl.cc b/chromium/content/renderer/dom_storage/webstoragenamespace_impl.cc
index 377d7961a16..cc8d7998d51 100644
--- a/chromium/content/renderer/dom_storage/webstoragenamespace_impl.cc
+++ b/chromium/content/renderer/dom_storage/webstoragenamespace_impl.cc
@@ -39,11 +39,13 @@ WebStorageNamespace* WebStorageNamespaceImpl::copy() {
return nullptr;
}
+blink::WebString WebStorageNamespaceImpl::GetNamespaceId() const {
+ return blink::WebString::FromASCII(namespace_id_);
+}
+
bool WebStorageNamespaceImpl::IsSameNamespace(
const WebStorageNamespace& other) const {
- const WebStorageNamespaceImpl* other_impl =
- static_cast<const WebStorageNamespaceImpl*>(&other);
- return namespace_id_ == other_impl->namespace_id_;
+ return GetNamespaceId() == other.GetNamespaceId();
}
} // namespace content
diff --git a/chromium/content/renderer/dom_storage/webstoragenamespace_impl.h b/chromium/content/renderer/dom_storage/webstoragenamespace_impl.h
index b4b522b798c..15008e3bae2 100644
--- a/chromium/content/renderer/dom_storage/webstoragenamespace_impl.h
+++ b/chromium/content/renderer/dom_storage/webstoragenamespace_impl.h
@@ -21,6 +21,7 @@ class WebStorageNamespaceImpl : public blink::WebStorageNamespace {
blink::WebStorageArea* CreateStorageArea(
const blink::WebSecurityOrigin& origin) override;
virtual blink::WebStorageNamespace* copy();
+ blink::WebString GetNamespaceId() const override;
bool IsSameNamespace(const WebStorageNamespace&) const override;
private:
diff --git a/chromium/content/renderer/fetchers/resource_fetcher_impl.cc b/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
index 56aca6e806d..98c8c10ed36 100644
--- a/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
+++ b/chromium/content/renderer/fetchers/resource_fetcher_impl.cc
@@ -175,8 +175,7 @@ class ResourceFetcherImpl::ClientImpl : public network::mojom::URLLoaderClient {
// network::mojom::URLLoaderClient overrides:
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override {
+ const network::ResourceResponseHead& response_head) override {
DCHECK_EQ(Status::kStarted, status_);
// Existing callers need URL and HTTP status code. URL is already set in
// Start().
@@ -187,10 +186,9 @@ class ResourceFetcherImpl::ClientImpl : public network::mojom::URLLoaderClient {
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head) override {
DCHECK_EQ(Status::kStarted, status_);
- loader_->FollowRedirect(base::nullopt);
+ loader_->FollowRedirect(base::nullopt, base::nullopt);
response_.SetURL(redirect_info.new_url);
}
- 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 {}
diff --git a/chromium/content/renderer/gamepad_shared_memory_reader.cc b/chromium/content/renderer/gamepad_shared_memory_reader.cc
deleted file mode 100644
index fe68df67ae3..00000000000
--- a/chromium/content/renderer/gamepad_shared_memory_reader.cc
+++ /dev/null
@@ -1,138 +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/gamepad_shared_memory_reader.h"
-
-#include "base/metrics/histogram_macros.h"
-#include "base/trace_event/trace_event.h"
-#include "content/public/common/service_names.mojom.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/renderer/renderer_blink_platform_impl.h"
-#include "ipc/ipc_sync_message_filter.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "third_party/blink/public/platform/web_gamepad_listener.h"
-#include "third_party/blink/public/platform/web_platform_event_listener.h"
-
-namespace content {
-
-GamepadSharedMemoryReader::GamepadSharedMemoryReader(RenderThread* thread)
- : RendererGamepadProvider(thread),
- gamepad_hardware_buffer_(nullptr),
- ever_interacted_with_(false),
- binding_(this) {
- if (thread) {
- thread->GetConnector()->BindInterface(mojom::kBrowserServiceName,
- mojo::MakeRequest(&gamepad_monitor_));
- device::mojom::GamepadObserverPtr observer;
- binding_.Bind(mojo::MakeRequest(&observer));
- gamepad_monitor_->SetObserver(std::move(observer));
- }
-}
-
-void GamepadSharedMemoryReader::SendStartMessage() {
- if (gamepad_monitor_) {
- gamepad_monitor_->GamepadStartPolling(&renderer_shared_buffer_handle_);
- }
-}
-
-void GamepadSharedMemoryReader::SendStopMessage() {
- if (gamepad_monitor_) {
- gamepad_monitor_->GamepadStopPolling();
- }
-}
-
-void GamepadSharedMemoryReader::Start(
- blink::WebPlatformEventListener* listener) {
- PlatformEventObserver::Start(listener);
-
- // If we don't get a valid handle from the browser, don't try to Map (we're
- // probably out of memory or file handles).
- bool valid_handle = renderer_shared_buffer_handle_.is_valid();
- UMA_HISTOGRAM_BOOLEAN("Gamepad.ValidSharedMemoryHandle", valid_handle);
- if (!valid_handle)
- return;
-
- renderer_shared_buffer_mapping_ =
- renderer_shared_buffer_handle_->Map(sizeof(GamepadHardwareBuffer));
- CHECK(renderer_shared_buffer_mapping_);
- void* memory = renderer_shared_buffer_mapping_.get();
- CHECK(memory);
- gamepad_hardware_buffer_ =
- static_cast<GamepadHardwareBuffer*>(memory);
-}
-
-void GamepadSharedMemoryReader::SampleGamepads(device::Gamepads& gamepads) {
- // Blink should have started observing at that point.
- CHECK(is_observing());
-
- // ==========
- // DANGER
- // ==========
- //
- // This logic is duplicated in Pepper as well. If you change it, that also
- // needs to be in sync. See ppapi/proxy/gamepad_resource.cc.
- device::Gamepads read_into;
- TRACE_EVENT0("GAMEPAD", "SampleGamepads");
-
- if (!renderer_shared_buffer_handle_.is_valid())
- return;
-
- // Only try to read this many times before failing to avoid waiting here
- // very long in case of contention with the writer. TODO(scottmg) Tune this
- // number (as low as 1?) if histogram shows distribution as mostly
- // 0-and-maximum.
- const int kMaximumContentionCount = 10;
- int contention_count = -1;
- base::subtle::Atomic32 version;
- do {
- version = gamepad_hardware_buffer_->seqlock.ReadBegin();
- memcpy(&read_into, &gamepad_hardware_buffer_->data, sizeof(read_into));
- ++contention_count;
- if (contention_count == kMaximumContentionCount)
- break;
- } while (gamepad_hardware_buffer_->seqlock.ReadRetry(version));
- UMA_HISTOGRAM_COUNTS("Gamepad.ReadContentionCount", contention_count);
-
- if (contention_count >= kMaximumContentionCount) {
- // We failed to successfully read, presumably because the hardware
- // thread was taking unusually long. Don't copy the data to the output
- // buffer, and simply leave what was there before.
- return;
- }
-
- // New data was read successfully, copy it into the output buffer.
- memcpy(&gamepads, &read_into, sizeof(gamepads));
-
- if (!ever_interacted_with_) {
- // Clear the connected flag if the user hasn't interacted with any of the
- // gamepads to prevent fingerprinting. The actual data is not cleared.
- // WebKit will only copy out data into the JS buffers for connected
- // gamepads so this is sufficient.
- for (unsigned i = 0; i < device::Gamepads::kItemsLengthCap; i++)
- gamepads.items[i].connected = false;
- }
-}
-
-GamepadSharedMemoryReader::~GamepadSharedMemoryReader() {
- StopIfObserving();
-}
-
-void GamepadSharedMemoryReader::GamepadConnected(
- int index,
- const device::Gamepad& gamepad) {
- // The browser already checks if the user actually interacted with a device.
- ever_interacted_with_ = true;
-
- if (listener())
- listener()->DidConnectGamepad(index, gamepad);
-}
-
-void GamepadSharedMemoryReader::GamepadDisconnected(
- int index,
- const device::Gamepad& gamepad) {
- if (listener())
- listener()->DidDisconnectGamepad(index, gamepad);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/gamepad_shared_memory_reader.h b/chromium/content/renderer/gamepad_shared_memory_reader.h
deleted file mode 100644
index 384c38d878f..00000000000
--- a/chromium/content/renderer/gamepad_shared_memory_reader.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_GAMEPAD_SHARED_MEMORY_READER_H_
-#define CONTENT_RENDERER_GAMEPAD_SHARED_MEMORY_READER_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "content/public/renderer/renderer_gamepad_provider.h"
-#include "device/base/synchronization/shared_memory_seqlock_buffer.h"
-#include "device/gamepad/public/cpp/gamepads.h"
-#include "device/gamepad/public/mojom/gamepad.mojom.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/system/buffer.h"
-
-namespace content {
-
-typedef device::SharedMemorySeqLockBuffer<device::Gamepads>
- GamepadHardwareBuffer;
-
-class GamepadSharedMemoryReader : public RendererGamepadProvider,
- public device::mojom::GamepadObserver {
- public:
- explicit GamepadSharedMemoryReader(RenderThread* thread);
- ~GamepadSharedMemoryReader() override;
-
- // RendererGamepadProvider implementation.
- void SampleGamepads(device::Gamepads& gamepads) override;
- void Start(blink::WebPlatformEventListener* listener) override;
-
- protected:
- // PlatformEventObserver protected methods.
- void SendStartMessage() override;
- void SendStopMessage() override;
-
- private:
- // device::mojom::GamepadObserver methods.
- void GamepadConnected(int index, const device::Gamepad& gamepad) override;
- void GamepadDisconnected(int index, const device::Gamepad& gamepad) override;
-
- mojo::ScopedSharedBufferHandle renderer_shared_buffer_handle_;
- mojo::ScopedSharedBufferMapping renderer_shared_buffer_mapping_;
- GamepadHardwareBuffer* gamepad_hardware_buffer_;
-
- bool ever_interacted_with_;
-
- mojo::Binding<device::mojom::GamepadObserver> binding_;
- device::mojom::GamepadMonitorPtr gamepad_monitor_;
-
- DISALLOW_COPY_AND_ASSIGN(GamepadSharedMemoryReader);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_GAMEPAD_SHARED_MEMORY_READER_H_
diff --git a/chromium/content/renderer/gpu/compositor_dependencies.h b/chromium/content/renderer/gpu/compositor_dependencies.h
index 4fc1825ead3..74da8435707 100644
--- a/chromium/content/renderer/gpu/compositor_dependencies.h
+++ b/chromium/content/renderer/gpu/compositor_dependencies.h
@@ -22,7 +22,7 @@ class UkmRecorderFactory;
namespace blink {
namespace scheduler {
-class WebMainThreadScheduler;
+class WebThreadScheduler;
}
}
@@ -37,20 +37,23 @@ class CompositorDependencies {
virtual bool IsPartialRasterEnabled() = 0;
virtual bool IsGpuMemoryBufferCompositorResourcesEnabled() = 0;
virtual bool IsElasticOverscrollEnabled() = 0;
+ virtual bool IsUseZoomForDSFEnabled() = 0;
virtual scoped_refptr<base::SingleThreadTaskRunner>
GetCompositorMainThreadTaskRunner() = 0;
// Returns null if the compositor is in single-threaded mode (ie. there is no
// compositor thread).
virtual scoped_refptr<base::SingleThreadTaskRunner>
GetCompositorImplThreadTaskRunner() = 0;
- virtual blink::scheduler::WebMainThreadScheduler*
- GetWebMainThreadScheduler() = 0;
+ virtual blink::scheduler::WebThreadScheduler* GetWebMainThreadScheduler() = 0;
virtual cc::TaskGraphRunner* GetTaskGraphRunner() = 0;
- virtual bool IsThreadedAnimationEnabled() = 0;
virtual bool IsScrollAnimatorEnabled() = 0;
virtual std::unique_ptr<cc::UkmRecorderFactory>
CreateUkmRecorderFactory() = 0;
+#ifdef OS_ANDROID
+ virtual bool UsingSynchronousCompositing() = 0;
+#endif
+
virtual ~CompositorDependencies() {}
};
diff --git a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
index cedd8d4ca36..0b2b903d230 100644
--- a/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
+++ b/chromium/content/renderer/gpu/gpu_benchmarking_extension.cc
@@ -33,7 +33,7 @@
#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/gpu/layer_tree_view.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_view_impl.h"
#include "content/renderer/skia_benchmarking_extension.h"
@@ -61,12 +61,16 @@
#include "v8/include/v8.h"
#if defined(OS_WIN) && !defined(NDEBUG)
+// XpsObjectModel.h indirectly includes <wincrypt.h> which is
+// incompatible with Chromium's OpenSSL. By including wincrypt_shim.h
+// first, problems are avoided.
+#include "crypto/wincrypt_shim.h"
+
#include <XpsObjectModel.h>
#include <objbase.h>
#include <wrl/client.h>
#endif
-using blink::WebCanvas;
using blink::WebLocalFrame;
using blink::WebImageCache;
using blink::WebPrivatePtr;
@@ -183,11 +187,7 @@ class CallbackAndContext : public base::RefCounted<CallbackAndContext> {
class GpuBenchmarkingContext {
public:
- GpuBenchmarkingContext()
- : web_frame_(nullptr),
- web_view_(nullptr),
- render_view_impl_(nullptr),
- compositor_(nullptr) {}
+ GpuBenchmarkingContext() = default;
bool Init(bool init_compositor) {
web_frame_ = WebLocalFrame::FrameForCurrentContext();
@@ -210,8 +210,8 @@ class GpuBenchmarkingContext {
if (!init_compositor)
return true;
- compositor_ = render_view_impl_->GetWidget()->compositor();
- if (!compositor_) {
+ layer_tree_view_ = render_view_impl_->GetWidget()->layer_tree_view();
+ if (!layer_tree_view_) {
web_frame_ = nullptr;
web_view_ = nullptr;
render_view_impl_ = nullptr;
@@ -233,16 +233,16 @@ class GpuBenchmarkingContext {
DCHECK(render_view_impl_ != nullptr);
return render_view_impl_;
}
- RenderWidgetCompositor* compositor() const {
- DCHECK(compositor_ != nullptr);
- return compositor_;
+ LayerTreeView* layer_tree_view() const {
+ DCHECK(layer_tree_view_ != nullptr);
+ return layer_tree_view_;
}
private:
- WebLocalFrame* web_frame_;
- WebView* web_view_;
- RenderViewImpl* render_view_impl_;
- RenderWidgetCompositor* compositor_;
+ WebLocalFrame* web_frame_ = nullptr;
+ WebView* web_view_ = nullptr;
+ RenderViewImpl* render_view_impl_ = nullptr;
+ LayerTreeView* layer_tree_view_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(GpuBenchmarkingContext);
};
@@ -550,7 +550,8 @@ gin::ObjectTemplateBuilder GpuBenchmarking::GetObjectTemplateBuilder(
.SetMethod("getGpuDriverBugWorkarounds",
&GpuBenchmarking::GetGpuDriverBugWorkarounds)
.SetMethod("startProfiling", &GpuBenchmarking::StartProfiling)
- .SetMethod("stopProfiling", &GpuBenchmarking::StopProfiling);
+ .SetMethod("stopProfiling", &GpuBenchmarking::StopProfiling)
+ .SetMethod("freeze", &GpuBenchmarking::Freeze);
}
void GpuBenchmarking::SetNeedsDisplayOnAllLayers() {
@@ -558,7 +559,7 @@ void GpuBenchmarking::SetNeedsDisplayOnAllLayers() {
if (!context.Init(true))
return;
- context.compositor()->SetNeedsDisplayOnAllLayers();
+ context.layer_tree_view()->SetNeedsDisplayOnAllLayers();
}
void GpuBenchmarking::SetRasterizeOnlyVisibleContent() {
@@ -566,7 +567,7 @@ void GpuBenchmarking::SetRasterizeOnlyVisibleContent() {
if (!context.Init(true))
return;
- context.compositor()->SetRasterizeOnlyVisibleContent();
+ context.layer_tree_view()->SetRasterizeOnlyVisibleContent();
}
namespace {
@@ -596,7 +597,7 @@ void GpuBenchmarking::PrintToSkPicture(v8::Isolate* isolate,
if (!context.Init(true))
return;
- const cc::Layer* root_layer = context.compositor()->GetRootLayer();
+ const cc::Layer* root_layer = context.layer_tree_view()->GetRootLayer();
if (!root_layer)
return;
@@ -874,8 +875,9 @@ void GpuBenchmarking::SetBrowserControlsShown(bool show) {
if (!context.Init(false))
return;
context.web_view()->UpdateBrowserControlsState(
- blink::kWebBrowserControlsBoth,
- show ? blink::kWebBrowserControlsShown : blink::kWebBrowserControlsHidden,
+ cc::BrowserControlsState::kBoth,
+ show ? cc::BrowserControlsState::kShown
+ : cc::BrowserControlsState::kHidden,
false);
}
@@ -885,7 +887,7 @@ float GpuBenchmarking::VisualViewportY() {
return 0.0;
float y = context.web_view()->VisualViewportOffset().y;
blink::WebRect rect(0, y, 0, 0);
- context.render_view_impl()->ConvertViewportToWindow(&rect);
+ context.render_view_impl()->WidgetClient()->ConvertViewportToWindow(&rect);
return rect.y;
}
@@ -895,7 +897,7 @@ float GpuBenchmarking::VisualViewportX() {
return 0.0;
float x = context.web_view()->VisualViewportOffset().x;
blink::WebRect rect(x, 0, 0, 0);
- context.render_view_impl()->ConvertViewportToWindow(&rect);
+ context.render_view_impl()->WidgetClient()->ConvertViewportToWindow(&rect);
return rect.x;
}
@@ -905,7 +907,7 @@ float GpuBenchmarking::VisualViewportHeight() {
return 0.0;
float height = context.web_view()->VisualViewportSize().height;
blink::WebRect rect(0, 0, 0, height);
- context.render_view_impl()->ConvertViewportToWindow(&rect);
+ context.render_view_impl()->WidgetClient()->ConvertViewportToWindow(&rect);
return rect.height;
}
@@ -915,7 +917,7 @@ float GpuBenchmarking::VisualViewportWidth() {
return 0.0;
float width = context.web_view()->VisualViewportSize().width;
blink::WebRect rect(0, 0, width, 0);
- context.render_view_impl()->ConvertViewportToWindow(&rect);
+ context.render_view_impl()->WidgetClient()->ConvertViewportToWindow(&rect);
return rect.width;
}
@@ -1040,10 +1042,10 @@ int GpuBenchmarking::RunMicroBenchmark(gin::Arguments* args) {
std::unique_ptr<base::Value> value =
V8ValueConverter::Create()->FromV8Value(arguments, v8_context);
- return context.compositor()->ScheduleMicroBenchmark(
+ return context.layer_tree_view()->ScheduleMicroBenchmark(
name, std::move(value),
- base::Bind(&OnMicroBenchmarkCompleted,
- base::RetainedRef(callback_and_context)));
+ base::BindOnce(&OnMicroBenchmarkCompleted,
+ base::RetainedRef(callback_and_context)));
}
bool GpuBenchmarking::SendMessageToMicroBenchmark(
@@ -1058,8 +1060,8 @@ bool GpuBenchmarking::SendMessageToMicroBenchmark(
std::unique_ptr<base::Value> value =
V8ValueConverter::Create()->FromV8Value(message, v8_context);
- return context.compositor()->SendMessageToMicroBenchmark(id,
- std::move(value));
+ return context.layer_tree_view()->SendMessageToMicroBenchmark(
+ id, std::move(value));
}
bool GpuBenchmarking::HasGpuChannel() {
@@ -1113,4 +1115,15 @@ void GpuBenchmarking::StopProfiling() {
base::debug::StopProfiling();
}
+void GpuBenchmarking::Freeze() {
+ GpuBenchmarkingContext context;
+ if (!context.Init(true))
+ return;
+ // TODO(fmeawad): Instead of forcing a visibility change, only allow
+ // freezing a page if it was already hidden.
+ context.web_view()->SetVisibilityState(
+ blink::mojom::PageVisibilityState::kHidden, false);
+ context.web_view()->SetPageFrozen(true);
+}
+
} // namespace content
diff --git a/chromium/content/renderer/gpu/gpu_benchmarking_extension.h b/chromium/content/renderer/gpu/gpu_benchmarking_extension.h
index 15b285cf7de..f423142cda6 100644
--- a/chromium/content/renderer/gpu/gpu_benchmarking_extension.h
+++ b/chromium/content/renderer/gpu/gpu_benchmarking_extension.h
@@ -91,6 +91,9 @@ class GpuBenchmarking : public gin::Wrappable<GpuBenchmarking> {
void StartProfiling(gin::Arguments* args);
void StopProfiling();
+ // Freezes a page, used to transition the page to the FROZEN lifecycle state.
+ void Freeze();
+
RenderFrameImpl* render_frame_;
mojom::InputInjectorPtr input_injector_;
DISALLOW_COPY_AND_ASSIGN(GpuBenchmarking);
diff --git a/chromium/content/renderer/gpu/layer_tree_view.cc b/chromium/content/renderer/gpu/layer_tree_view.cc
new file mode 100644
index 00000000000..511f04a5cac
--- /dev/null
+++ b/chromium/content/renderer/gpu/layer_tree_view.cc
@@ -0,0 +1,742 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/gpu/layer_tree_view.h"
+
+#include <stddef.h>
+#include <string>
+#include <utility>
+
+#include "base/auto_reset.h"
+#include "base/callback.h"
+#include "base/location.h"
+#include "base/single_thread_task_runner.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_scheduler.h"
+#include "base/task_scheduler/task_traits.h"
+#include "base/time/time.h"
+#include "base/values.h"
+#include "cc/animation/animation_host.h"
+#include "cc/animation/animation_timeline.h"
+#include "cc/base/region.h"
+#include "cc/benchmarks/micro_benchmark.h"
+#include "cc/debug/layer_tree_debug_state.h"
+#include "cc/input/layer_selection_bound.h"
+#include "cc/layers/layer.h"
+#include "cc/trees/latency_info_swap_promise.h"
+#include "cc/trees/latency_info_swap_promise_monitor.h"
+#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/layer_tree_mutator.h"
+#include "cc/trees/render_frame_metadata_observer.h"
+#include "cc/trees/swap_promise.h"
+#include "cc/trees/ukm_manager.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/quads/compositor_frame_metadata.h"
+#include "components/viz/common/resources/single_release_callback.h"
+#include "content/renderer/gpu/layer_tree_view_delegate.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
+#include "third_party/blink/public/platform/web_runtime_features.h"
+#include "third_party/blink/public/platform/web_size.h"
+#include "third_party/blink/public/web/blink.h"
+#include "ui/gfx/presentation_feedback.h"
+
+namespace base {
+class Value;
+}
+
+namespace cc {
+class Layer;
+}
+
+namespace content {
+namespace {
+
+using ReportTimeCallback = blink::WebLayerTreeView::ReportTimeCallback;
+
+class ReportTimeSwapPromise : public cc::SwapPromise {
+ public:
+ ReportTimeSwapPromise(ReportTimeCallback callback,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ base::WeakPtr<LayerTreeView> layer_tree_view);
+ ~ReportTimeSwapPromise() override;
+
+ void DidActivate() override {}
+ void WillSwap(viz::CompositorFrameMetadata* metadata) override;
+ void DidSwap() override;
+ void DidNotSwap(DidNotSwapReason reason) override;
+ int64_t TraceId() const override;
+
+ private:
+ ReportTimeCallback callback_;
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ base::WeakPtr<LayerTreeView> layer_tree_view_;
+
+ DISALLOW_COPY_AND_ASSIGN(ReportTimeSwapPromise);
+};
+
+ReportTimeSwapPromise::ReportTimeSwapPromise(
+ ReportTimeCallback callback,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ base::WeakPtr<LayerTreeView> layer_tree_view)
+ : callback_(std::move(callback)),
+ task_runner_(std::move(task_runner)),
+ layer_tree_view_(std::move(layer_tree_view)) {}
+
+ReportTimeSwapPromise::~ReportTimeSwapPromise() {}
+
+void ReportTimeSwapPromise::WillSwap(viz::CompositorFrameMetadata* metadata) {
+ DCHECK_GT(metadata->frame_token, 0u);
+ metadata->request_presentation_feedback = true;
+ auto* task_runner = task_runner_.get();
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &LayerTreeView::AddPresentationCallback, layer_tree_view_,
+ metadata->frame_token,
+ base::BindOnce(std::move(callback_),
+ blink::WebLayerTreeView::SwapResult::kDidSwap)));
+}
+
+void ReportTimeSwapPromise::DidSwap() {
+ // If swap did happen, then the paint-time will be reported when the
+ // presentation feedback is received.
+}
+
+void ReportTimeSwapPromise::DidNotSwap(
+ cc::SwapPromise::DidNotSwapReason reason) {
+ blink::WebLayerTreeView::SwapResult result;
+ switch (reason) {
+ case cc::SwapPromise::DidNotSwapReason::SWAP_FAILS:
+ result = blink::WebLayerTreeView::SwapResult::kDidNotSwapSwapFails;
+ break;
+ case cc::SwapPromise::DidNotSwapReason::COMMIT_FAILS:
+ result = blink::WebLayerTreeView::SwapResult::kDidNotSwapCommitFails;
+ break;
+ case cc::SwapPromise::DidNotSwapReason::COMMIT_NO_UPDATE:
+ result = blink::WebLayerTreeView::SwapResult::kDidNotSwapCommitNoUpdate;
+ break;
+ case cc::SwapPromise::DidNotSwapReason::ACTIVATION_FAILS:
+ result = blink::WebLayerTreeView::SwapResult::kDidNotSwapActivationFails;
+ break;
+ }
+ task_runner_->PostTask(FROM_HERE, base::BindOnce(std::move(callback_), result,
+ base::TimeTicks::Now()));
+}
+
+int64_t ReportTimeSwapPromise::TraceId() const {
+ return 0;
+}
+
+} // namespace
+
+LayerTreeView::LayerTreeView(
+ LayerTreeViewDelegate* delegate,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_thread,
+ cc::TaskGraphRunner* task_graph_runner,
+ blink::scheduler::WebThreadScheduler* scheduler)
+ : delegate_(delegate),
+ main_thread_(std::move(main_thread)),
+ compositor_thread_(std::move(compositor_thread)),
+ task_graph_runner_(task_graph_runner),
+ web_main_thread_scheduler_(scheduler),
+ animation_host_(cc::AnimationHost::CreateMainInstance()),
+ weak_factory_(this) {}
+
+LayerTreeView::~LayerTreeView() = default;
+
+void LayerTreeView::Initialize(
+ const cc::LayerTreeSettings& settings,
+ std::unique_ptr<cc::UkmRecorderFactory> ukm_recorder_factory) {
+ const bool is_threaded = !!compositor_thread_;
+
+ cc::LayerTreeHost::InitParams params;
+ params.client = this;
+ params.settings = &settings;
+ params.task_graph_runner = task_graph_runner_;
+ params.main_task_runner = main_thread_;
+ params.mutator_host = animation_host_.get();
+ params.ukm_recorder_factory = std::move(ukm_recorder_factory);
+ 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
+ // IO thread.
+ params.image_worker_task_runner = base::CreateSequencedTaskRunnerWithTraits(
+ {base::WithBaseSyncPrimitives(), base::TaskPriority::USER_VISIBLE,
+ base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN});
+ }
+ if (!is_threaded) {
+ // Single-threaded layout tests, and unit tests.
+ layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded(this, &params);
+ } else {
+ layer_tree_host_ =
+ cc::LayerTreeHost::CreateThreaded(compositor_thread_, &params);
+ }
+}
+
+void LayerTreeView::SetNeverVisible() {
+ DCHECK(!layer_tree_host_->IsVisible());
+ never_visible_ = true;
+}
+
+const base::WeakPtr<cc::InputHandler>& LayerTreeView::GetInputHandler() {
+ return layer_tree_host_->GetInputHandler();
+}
+
+void LayerTreeView::SetNeedsDisplayOnAllLayers() {
+ layer_tree_host_->SetNeedsDisplayOnAllLayers();
+}
+
+void LayerTreeView::SetRasterizeOnlyVisibleContent() {
+ cc::LayerTreeDebugState current = layer_tree_host_->GetDebugState();
+ current.rasterize_only_visible_content = true;
+ layer_tree_host_->SetDebugState(current);
+}
+
+void LayerTreeView::SetNeedsRedrawRect(gfx::Rect damage_rect) {
+ layer_tree_host_->SetNeedsRedrawRect(damage_rect);
+}
+
+bool LayerTreeView::IsSurfaceSynchronizationEnabled() const {
+ return layer_tree_host_->GetSettings().enable_surface_synchronization;
+}
+
+void LayerTreeView::SetNeedsForcedRedraw() {
+ layer_tree_host_->SetNeedsCommitWithForcedRedraw();
+}
+
+std::unique_ptr<cc::SwapPromiseMonitor>
+LayerTreeView::CreateLatencyInfoSwapPromiseMonitor(ui::LatencyInfo* latency) {
+ return std::make_unique<cc::LatencyInfoSwapPromiseMonitor>(
+ latency, layer_tree_host_->GetSwapPromiseManager(), nullptr);
+}
+
+void LayerTreeView::QueueSwapPromise(
+ std::unique_ptr<cc::SwapPromise> swap_promise) {
+ layer_tree_host_->QueueSwapPromise(std::move(swap_promise));
+}
+
+int LayerTreeView::GetSourceFrameNumber() const {
+ return layer_tree_host_->SourceFrameNumber();
+}
+
+void LayerTreeView::NotifyInputThrottledUntilCommit() {
+ layer_tree_host_->NotifyInputThrottledUntilCommit();
+}
+
+const cc::Layer* LayerTreeView::GetRootLayer() const {
+ return layer_tree_host_->root_layer();
+}
+
+int LayerTreeView::ScheduleMicroBenchmark(
+ const std::string& name,
+ std::unique_ptr<base::Value> value,
+ base::OnceCallback<void(std::unique_ptr<base::Value>)> callback) {
+ return layer_tree_host_->ScheduleMicroBenchmark(name, std::move(value),
+ std::move(callback));
+}
+
+bool LayerTreeView::SendMessageToMicroBenchmark(
+ int id,
+ std::unique_ptr<base::Value> value) {
+ return layer_tree_host_->SendMessageToMicroBenchmark(id, std::move(value));
+}
+
+void LayerTreeView::SetViewportSizeAndScale(
+ const gfx::Size& device_viewport_size,
+ float device_scale_factor,
+ const viz::LocalSurfaceId& local_surface_id) {
+ layer_tree_host_->SetViewportSizeAndScale(
+ device_viewport_size, device_scale_factor, local_surface_id);
+}
+
+void LayerTreeView::RequestNewLocalSurfaceId() {
+ layer_tree_host_->RequestNewLocalSurfaceId();
+}
+
+void LayerTreeView::SetViewportVisibleRect(const gfx::Rect& visible_rect) {
+ layer_tree_host_->SetViewportVisibleRect(visible_rect);
+}
+
+viz::FrameSinkId LayerTreeView::GetFrameSinkId() {
+ return frame_sink_id_;
+}
+
+void LayerTreeView::SetRootLayer(scoped_refptr<cc::Layer> layer) {
+ layer_tree_host_->SetRootLayer(std::move(layer));
+}
+
+void LayerTreeView::ClearRootLayer() {
+ layer_tree_host_->SetRootLayer(nullptr);
+}
+
+cc::AnimationHost* LayerTreeView::CompositorAnimationHost() {
+ return animation_host_.get();
+}
+
+gfx::Size LayerTreeView::GetViewportSize() const {
+ return layer_tree_host_->device_viewport_size();
+}
+
+void LayerTreeView::SetBackgroundColor(SkColor color) {
+ layer_tree_host_->set_background_color(color);
+}
+
+void LayerTreeView::SetVisible(bool visible) {
+ if (never_visible_)
+ return;
+
+ layer_tree_host_->SetVisible(visible);
+
+ if (visible && layer_tree_frame_sink_request_failed_while_invisible_)
+ DidFailToInitializeLayerTreeFrameSink();
+}
+
+void LayerTreeView::SetPageScaleFactorAndLimits(float page_scale_factor,
+ float minimum,
+ float maximum) {
+ layer_tree_host_->SetPageScaleFactorAndLimits(page_scale_factor, minimum,
+ maximum);
+}
+
+void LayerTreeView::StartPageScaleAnimation(const gfx::Vector2d& target_offset,
+ bool use_anchor,
+ float new_page_scale,
+ double duration_sec) {
+ base::TimeDelta duration = base::TimeDelta::FromMicroseconds(
+ duration_sec * base::Time::kMicrosecondsPerSecond);
+ layer_tree_host_->StartPageScaleAnimation(target_offset, use_anchor,
+ new_page_scale, duration);
+}
+
+bool LayerTreeView::HasPendingPageScaleAnimation() const {
+ return layer_tree_host_->HasPendingPageScaleAnimation();
+}
+
+void LayerTreeView::HeuristicsForGpuRasterizationUpdated(
+ bool matches_heuristics) {
+ layer_tree_host_->SetHasGpuRasterizationTrigger(matches_heuristics);
+}
+
+void LayerTreeView::SetNeedsBeginFrame() {
+ layer_tree_host_->SetNeedsAnimate();
+}
+
+void LayerTreeView::RegisterViewportLayers(const ViewportLayers& layers) {
+ cc::LayerTreeHost::ViewportLayers viewport_layers;
+ viewport_layers.overscroll_elasticity = layers.overscroll_elasticity;
+ viewport_layers.page_scale = layers.page_scale;
+ viewport_layers.inner_viewport_container = layers.inner_viewport_container;
+ viewport_layers.outer_viewport_container = layers.outer_viewport_container;
+ viewport_layers.inner_viewport_scroll = layers.inner_viewport_scroll;
+ viewport_layers.outer_viewport_scroll = layers.outer_viewport_scroll;
+ layer_tree_host_->RegisterViewportLayers(viewport_layers);
+}
+
+void LayerTreeView::ClearViewportLayers() {
+ layer_tree_host_->RegisterViewportLayers(cc::LayerTreeHost::ViewportLayers());
+}
+
+void LayerTreeView::RegisterSelection(const cc::LayerSelection& selection) {
+ layer_tree_host_->RegisterSelection(selection);
+}
+
+void LayerTreeView::ClearSelection() {
+ layer_tree_host_->RegisterSelection(cc::LayerSelection());
+}
+
+void LayerTreeView::SetMutatorClient(
+ std::unique_ptr<cc::LayerTreeMutator> client) {
+ TRACE_EVENT0("cc", "LayerTreeView::setMutatorClient");
+ layer_tree_host_->SetLayerTreeMutator(std::move(client));
+}
+
+void LayerTreeView::ForceRecalculateRasterScales() {
+ layer_tree_host_->SetNeedsRecalculateRasterScales();
+}
+
+void LayerTreeView::SetEventListenerProperties(
+ cc::EventListenerClass event_class,
+ cc::EventListenerProperties properties) {
+ layer_tree_host_->SetEventListenerProperties(event_class, properties);
+}
+
+cc::EventListenerProperties LayerTreeView::EventListenerProperties(
+ cc::EventListenerClass event_class) const {
+ return layer_tree_host_->event_listener_properties(event_class);
+}
+
+void LayerTreeView::SetHaveScrollEventHandlers(bool has_handlers) {
+ layer_tree_host_->SetHaveScrollEventHandlers(has_handlers);
+}
+
+bool LayerTreeView::HaveScrollEventHandlers() const {
+ return layer_tree_host_->have_scroll_event_handlers();
+}
+
+bool LayerTreeView::CompositeIsSynchronous() const {
+ if (!compositor_thread_) {
+ DCHECK(!layer_tree_host_->GetSettings().single_thread_proxy_scheduler);
+ return true;
+ }
+ return false;
+}
+
+void LayerTreeView::LayoutAndPaintAsync(base::OnceClosure callback) {
+ DCHECK(layout_and_paint_async_callback_.is_null());
+ layout_and_paint_async_callback_ = std::move(callback);
+
+ if (CompositeIsSynchronous()) {
+ // The LayoutAndPaintAsyncCallback is invoked in WillCommit, which is
+ // dispatched after layout and paint for all compositing modes.
+ const bool raster = false;
+ layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&LayerTreeView::SynchronouslyComposite,
+ weak_factory_.GetWeakPtr(), raster, nullptr));
+ } else {
+ layer_tree_host_->SetNeedsCommit();
+ }
+}
+
+void LayerTreeView::SetLayerTreeFrameSink(
+ std::unique_ptr<cc::LayerTreeFrameSink> layer_tree_frame_sink) {
+ if (!layer_tree_frame_sink) {
+ DidFailToInitializeLayerTreeFrameSink();
+ return;
+ }
+ layer_tree_host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
+}
+
+void LayerTreeView::InvokeLayoutAndPaintCallback() {
+ if (!layout_and_paint_async_callback_.is_null())
+ std::move(layout_and_paint_async_callback_).Run();
+}
+
+void LayerTreeView::CompositeAndReadbackAsync(
+ base::OnceCallback<void(const SkBitmap&)> callback) {
+ DCHECK(layout_and_paint_async_callback_.is_null());
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner =
+ layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner();
+ std::unique_ptr<viz::CopyOutputRequest> request =
+ std::make_unique<viz::CopyOutputRequest>(
+ viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
+ base::BindOnce(
+ [](base::OnceCallback<void(const SkBitmap&)> callback,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ std::unique_ptr<viz::CopyOutputResult> result) {
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), result->AsSkBitmap()));
+ },
+ std::move(callback), std::move(main_thread_task_runner)));
+ auto swap_promise =
+ delegate_->RequestCopyOfOutputForLayoutTest(std::move(request));
+
+ // Force a commit to happen. The temporary copy output request will
+ // be installed after layout which will happen as a part of the commit, for
+ // widgets that delay the creation of their output surface.
+ if (CompositeIsSynchronous()) {
+ // Since the composite is required for a pixel dump, we need to raster.
+ // Note that we defer queuing the SwapPromise until the requested Composite
+ // with rasterization is done.
+ const bool raster = true;
+ layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&LayerTreeView::SynchronouslyComposite,
+ weak_factory_.GetWeakPtr(), raster,
+ std::move(swap_promise)));
+ } else {
+ // Force a redraw to ensure that the copy swap promise isn't cancelled due
+ // to no damage.
+ SetNeedsForcedRedraw();
+ layer_tree_host_->QueueSwapPromise(std::move(swap_promise));
+ layer_tree_host_->SetNeedsCommit();
+ }
+}
+
+void LayerTreeView::SynchronouslyCompositeNoRasterForTesting() {
+ SynchronouslyComposite(false /* raster */, nullptr /* swap_promise */);
+}
+
+void LayerTreeView::CompositeWithRasterForTesting() {
+ SynchronouslyComposite(true /* raster */, nullptr /* swap_promise */);
+}
+
+void LayerTreeView::SynchronouslyComposite(
+ bool raster,
+ std::unique_ptr<cc::SwapPromise> swap_promise) {
+ DCHECK(CompositeIsSynchronous());
+ if (!layer_tree_host_->IsVisible())
+ return;
+
+ if (in_synchronous_compositor_update_) {
+ // LayoutTests can use a nested message loop to pump frames while inside a
+ // frame, but the compositor does not support this. In this case, we only
+ // run blink's lifecycle updates.
+ delegate_->BeginMainFrame(base::TimeTicks::Now());
+ delegate_->UpdateVisualState(
+ cc::LayerTreeHostClient::VisualStateUpdate::kAll);
+ return;
+ }
+
+ if (swap_promise) {
+ // Force a redraw to ensure that the copy swap promise isn't cancelled due
+ // to no damage.
+ SetNeedsForcedRedraw();
+ layer_tree_host_->QueueSwapPromise(std::move(swap_promise));
+ }
+
+ DCHECK(!in_synchronous_compositor_update_);
+ base::AutoReset<bool> inside_composite(&in_synchronous_compositor_update_,
+ true);
+ layer_tree_host_->Composite(base::TimeTicks::Now(), raster);
+}
+
+void LayerTreeView::SetDeferCommits(bool defer_commits) {
+ layer_tree_host_->SetDeferCommits(defer_commits);
+}
+
+int LayerTreeView::LayerTreeId() const {
+ return layer_tree_host_->GetId();
+}
+
+void LayerTreeView::SetShowFPSCounter(bool show) {
+ cc::LayerTreeDebugState debug_state = layer_tree_host_->GetDebugState();
+ debug_state.show_fps_counter = show;
+ layer_tree_host_->SetDebugState(debug_state);
+}
+
+void LayerTreeView::SetShowPaintRects(bool show) {
+ cc::LayerTreeDebugState debug_state = layer_tree_host_->GetDebugState();
+ debug_state.show_paint_rects = show;
+ layer_tree_host_->SetDebugState(debug_state);
+}
+
+void LayerTreeView::SetShowDebugBorders(bool show) {
+ cc::LayerTreeDebugState debug_state = layer_tree_host_->GetDebugState();
+ if (show)
+ debug_state.show_debug_borders.set();
+ else
+ debug_state.show_debug_borders.reset();
+ layer_tree_host_->SetDebugState(debug_state);
+}
+
+void LayerTreeView::SetShowScrollBottleneckRects(bool show) {
+ cc::LayerTreeDebugState debug_state = layer_tree_host_->GetDebugState();
+ debug_state.show_touch_event_handler_rects = show;
+ debug_state.show_wheel_event_handler_rects = show;
+ debug_state.show_non_fast_scrollable_rects = show;
+ layer_tree_host_->SetDebugState(debug_state);
+}
+
+void LayerTreeView::UpdateBrowserControlsState(
+ cc::BrowserControlsState constraints,
+ cc::BrowserControlsState current,
+ bool animate) {
+ layer_tree_host_->UpdateBrowserControlsState(constraints, current, animate);
+}
+
+void LayerTreeView::SetBrowserControlsHeight(float top_height,
+ float bottom_height,
+ bool shrink) {
+ layer_tree_host_->SetBrowserControlsHeight(top_height, bottom_height, shrink);
+}
+
+void LayerTreeView::SetBrowserControlsShownRatio(float ratio) {
+ layer_tree_host_->SetBrowserControlsShownRatio(ratio);
+}
+
+void LayerTreeView::RequestDecode(const cc::PaintImage& image,
+ 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
+ // fact that this would make layout tests slow and cause flakiness. However,
+ // in this case we actually need a commit to transfer the decode requests to
+ // the impl side. So, force a commit to happen.
+ if (CompositeIsSynchronous()) {
+ const bool raster = true;
+ layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&LayerTreeView::SynchronouslyComposite,
+ weak_factory_.GetWeakPtr(), raster, nullptr));
+ }
+}
+
+void LayerTreeView::SetOverscrollBehavior(
+ const cc::OverscrollBehavior& behavior) {
+ layer_tree_host_->SetOverscrollBehavior(behavior);
+}
+
+void LayerTreeView::WillBeginMainFrame() {
+ delegate_->WillBeginCompositorFrame();
+}
+
+void LayerTreeView::DidBeginMainFrame() {}
+
+void LayerTreeView::BeginMainFrame(const viz::BeginFrameArgs& args) {
+ web_main_thread_scheduler_->WillBeginFrame(args);
+ delegate_->BeginMainFrame(args.frame_time);
+}
+
+void LayerTreeView::BeginMainFrameNotExpectedSoon() {
+ web_main_thread_scheduler_->BeginFrameNotExpectedSoon();
+}
+
+void LayerTreeView::BeginMainFrameNotExpectedUntil(base::TimeTicks time) {
+ web_main_thread_scheduler_->BeginMainFrameNotExpectedUntil(time);
+}
+
+void LayerTreeView::UpdateLayerTreeHost(VisualStateUpdate requested_update) {
+ delegate_->UpdateVisualState(requested_update);
+}
+
+void LayerTreeView::ApplyViewportDeltas(
+ const gfx::Vector2dF& inner_delta,
+ const gfx::Vector2dF& outer_delta,
+ const gfx::Vector2dF& elastic_overscroll_delta,
+ float page_scale,
+ float top_controls_delta) {
+ delegate_->ApplyViewportDeltas(inner_delta, outer_delta,
+ elastic_overscroll_delta, page_scale,
+ top_controls_delta);
+}
+
+void LayerTreeView::RecordWheelAndTouchScrollingCount(
+ bool has_scrolled_by_wheel,
+ bool has_scrolled_by_touch) {
+ delegate_->RecordWheelAndTouchScrollingCount(has_scrolled_by_wheel,
+ has_scrolled_by_touch);
+}
+
+void LayerTreeView::RequestNewLayerTreeFrameSink() {
+ // If the host is closing, then no more compositing is possible. This
+ // prevents shutdown races between handling the close message and
+ // the CreateLayerTreeFrameSink task.
+ if (delegate_->IsClosing())
+ return;
+ delegate_->RequestNewLayerTreeFrameSink(base::BindOnce(
+ &LayerTreeView::SetLayerTreeFrameSink, weak_factory_.GetWeakPtr()));
+}
+
+void LayerTreeView::DidInitializeLayerTreeFrameSink() {}
+
+void LayerTreeView::DidFailToInitializeLayerTreeFrameSink() {
+ if (!layer_tree_host_->IsVisible()) {
+ layer_tree_frame_sink_request_failed_while_invisible_ = true;
+ return;
+ }
+ layer_tree_frame_sink_request_failed_while_invisible_ = false;
+ layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&LayerTreeView::RequestNewLayerTreeFrameSink,
+ weak_factory_.GetWeakPtr()));
+}
+
+void LayerTreeView::WillCommit() {
+ InvokeLayoutAndPaintCallback();
+}
+
+void LayerTreeView::DidCommit() {
+ delegate_->DidCommitCompositorFrame();
+ web_main_thread_scheduler_->DidCommitFrameToCompositor();
+}
+
+void LayerTreeView::DidCommitAndDrawFrame() {
+ delegate_->DidCommitAndDrawCompositorFrame();
+}
+
+void LayerTreeView::DidReceiveCompositorFrameAck() {
+ delegate_->DidReceiveCompositorFrameAck();
+}
+
+void LayerTreeView::DidCompletePageScaleAnimation() {
+ delegate_->DidCompletePageScaleAnimation();
+}
+
+void LayerTreeView::DidPresentCompositorFrame(
+ uint32_t frame_token,
+ const gfx::PresentationFeedback& feedback) {
+ DCHECK(layer_tree_host_->GetTaskRunnerProvider()
+ ->MainThreadTaskRunner()
+ ->RunsTasksInCurrentSequence());
+ while (!presentation_callbacks_.empty()) {
+ const auto& front = presentation_callbacks_.begin();
+ if (viz::FrameTokenGT(front->first, frame_token))
+ break;
+ for (auto& callback : front->second)
+ std::move(callback).Run(feedback.timestamp);
+ presentation_callbacks_.erase(front);
+ }
+}
+
+void LayerTreeView::RequestScheduleAnimation() {
+ delegate_->RequestScheduleAnimation();
+}
+
+void LayerTreeView::DidSubmitCompositorFrame() {}
+
+void LayerTreeView::DidLoseLayerTreeFrameSink() {}
+
+void LayerTreeView::SetFrameSinkId(const viz::FrameSinkId& frame_sink_id) {
+ frame_sink_id_ = frame_sink_id;
+}
+
+void LayerTreeView::SetRasterColorSpace(const gfx::ColorSpace& color_space) {
+ layer_tree_host_->SetRasterColorSpace(color_space);
+}
+
+void LayerTreeView::ClearCachesOnNextCommit() {
+ layer_tree_host_->ClearCachesOnNextCommit();
+}
+
+void LayerTreeView::SetContentSourceId(uint32_t id) {
+ layer_tree_host_->SetContentSourceId(id);
+}
+
+void LayerTreeView::NotifySwapTime(ReportTimeCallback callback) {
+ QueueSwapPromise(std::make_unique<ReportTimeSwapPromise>(
+ std::move(callback),
+ layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner(),
+ weak_factory_.GetWeakPtr()));
+}
+
+void LayerTreeView::RequestBeginMainFrameNotExpected(bool new_state) {
+ layer_tree_host_->RequestBeginMainFrameNotExpected(new_state);
+}
+
+const cc::LayerTreeSettings& LayerTreeView::GetLayerTreeSettings() const {
+ return layer_tree_host_->GetSettings();
+}
+
+void LayerTreeView::SetRenderFrameObserver(
+ std::unique_ptr<cc::RenderFrameMetadataObserver> observer) {
+ layer_tree_host_->SetRenderFrameObserver(std::move(observer));
+}
+
+void LayerTreeView::AddPresentationCallback(
+ uint32_t frame_token,
+ base::OnceCallback<void(base::TimeTicks)> callback) {
+ if (!presentation_callbacks_.empty()) {
+ auto& previous = presentation_callbacks_.back();
+ uint32_t previous_frame_token = previous.first;
+ if (previous_frame_token == frame_token) {
+ previous.second.push_back(std::move(callback));
+ DCHECK_LE(previous.second.size(), 250u);
+ return;
+ }
+ DCHECK(viz::FrameTokenGT(frame_token, previous_frame_token));
+ }
+ std::vector<base::OnceCallback<void(base::TimeTicks)>> callbacks;
+ callbacks.push_back(std::move(callback));
+ presentation_callbacks_.push_back({frame_token, std::move(callbacks)});
+ DCHECK_LE(presentation_callbacks_.size(), 25u);
+}
+
+void LayerTreeView::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/layer_tree_view.h
index 933ed484cec..09dbf800511 100644
--- a/chromium/content/renderer/gpu/render_widget_compositor.h
+++ b/chromium/content/renderer/gpu/layer_tree_view.h
@@ -2,46 +2,49 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_H_
-#define CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_H_
+#ifndef CONTENT_RENDERER_GPU_LAYER_TREE_VIEW_H_
+#define CONTENT_RENDERER_GPU_LAYER_TREE_VIEW_H_
#include <stdint.h>
#include "base/callback.h"
+#include "base/containers/circular_deque.h"
#include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/values.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"
-#include "cc/trees/managed_memory_policy.h"
#include "cc/trees/swap_promise.h"
#include "cc/trees/swap_promise_monitor.h"
#include "content/common/content_export.h"
-#include "content/common/render_frame_metadata.mojom.h"
-#include "content/renderer/gpu/compositor_dependencies.h"
-#include "services/metrics/public/cpp/ukm_recorder.h"
#include "third_party/blink/public/platform/web_layer_tree_view.h"
#include "ui/gfx/geometry/rect.h"
-namespace base {
-class CommandLine;
+class GURL;
+
+namespace blink {
+namespace scheduler {
+class WebThreadScheduler;
}
+} // namespace blink
namespace cc {
-
class AnimationHost;
class InputHandler;
class Layer;
class LayerTreeFrameSink;
class LayerTreeHost;
-class MutatorHost;
-}
+class LayerTreeSettings;
+class RenderFrameMetadataObserver;
+class TaskGraphRunner;
+class UkmRecorderFactory;
+} // namespace cc
namespace gfx {
class ColorSpace;
+class Size;
}
namespace ui {
@@ -49,41 +52,28 @@ class LatencyInfo;
}
namespace content {
-class RenderWidgetCompositorDelegate;
-struct ScreenInfo;
+class LayerTreeViewDelegate;
-class CONTENT_EXPORT RenderWidgetCompositor
+class CONTENT_EXPORT LayerTreeView
: public blink::WebLayerTreeView,
public cc::LayerTreeHostClient,
public cc::LayerTreeHostSingleThreadClient {
public:
- // Attempt to construct and initialize a compositor instance for the widget
- // with the given settings. Returns NULL if initialization fails.
- static std::unique_ptr<RenderWidgetCompositor> Create(
- RenderWidgetCompositorDelegate* delegate,
- CompositorDependencies* compositor_deps);
-
- ~RenderWidgetCompositor() override;
-
- static cc::LayerTreeSettings GenerateLayerTreeSettings(
- const base::CommandLine& cmd,
- CompositorDependencies* compositor_deps,
- bool is_for_subframe,
- const ScreenInfo& screen_info,
- bool is_threaded);
- static std::unique_ptr<cc::LayerTreeHost> CreateLayerTreeHost(
- cc::LayerTreeHostClient* client,
- cc::LayerTreeHostSingleThreadClient* single_thread_client,
- cc::MutatorHost* mutator_host,
- CompositorDependencies* deps,
- const ScreenInfo& screen_info);
-
- void Initialize(std::unique_ptr<cc::LayerTreeHost> layer_tree_host,
- std::unique_ptr<cc::AnimationHost> animation_host);
-
- static cc::ManagedMemoryPolicy GetGpuMemoryPolicy(
- const cc::ManagedMemoryPolicy& policy,
- const ScreenInfo& screen_info);
+ // The |main_thread| is the task runner that the compositor will use for the
+ // main thread (where it is constructed). The |compositor_thread| is the task
+ // runner for the compositor thread, but is null if the compositor will run in
+ // single-threaded mode (in tests only).
+ LayerTreeView(LayerTreeViewDelegate* delegate,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_thread,
+ cc::TaskGraphRunner* task_graph_runner,
+ blink::scheduler::WebThreadScheduler* scheduler);
+ ~LayerTreeView() override;
+
+ // The |ukm_recorder_factory| may be null to disable recording (in tests
+ // only).
+ void Initialize(const cc::LayerTreeSettings& settings,
+ std::unique_ptr<cc::UkmRecorderFactory> ukm_recorder_factory);
void SetNeverVisible();
const base::WeakPtr<cc::InputHandler>& GetInputHandler();
@@ -112,59 +102,54 @@ class CONTENT_EXPORT RenderWidgetCompositor
int ScheduleMicroBenchmark(
const std::string& name,
std::unique_ptr<base::Value> value,
- const base::Callback<void(std::unique_ptr<base::Value>)>& callback);
+ base::OnceCallback<void(std::unique_ptr<base::Value>)> callback);
bool SendMessageToMicroBenchmark(int id, std::unique_ptr<base::Value> value);
void SetFrameSinkId(const viz::FrameSinkId& frame_sink_id);
void SetRasterColorSpace(const gfx::ColorSpace& color_space);
- void SetIsForOopif(bool is_for_oopif);
+ void ClearCachesOnNextCommit();
void SetContentSourceId(uint32_t source_id);
void SetViewportSizeAndScale(const gfx::Size& device_viewport_size,
float device_scale_factor,
const viz::LocalSurfaceId& local_surface_id);
void RequestNewLocalSurfaceId();
- bool HasNewLocalSurfaceIdRequest() const;
void SetViewportVisibleRect(const gfx::Rect& visible_rect);
void SetURLForUkm(const GURL& url);
- // WebLayerTreeView implementation.
+ // blink::WebLayerTreeView implementation.
viz::FrameSinkId GetFrameSinkId() override;
void SetRootLayer(scoped_refptr<cc::Layer> layer) override;
void ClearRootLayer() override;
cc::AnimationHost* CompositorAnimationHost() override;
- blink::WebSize GetViewportSize() const override;
- virtual blink::WebFloatPoint adjustEventPointForPinchZoom(
- const blink::WebFloatPoint& point) const;
+ gfx::Size GetViewportSize() const override;
void SetBackgroundColor(SkColor color) override;
void SetVisible(bool visible) override;
void SetPageScaleFactorAndLimits(float page_scale_factor,
float minimum,
float maximum) override;
- void StartPageScaleAnimation(const blink::WebPoint& destination,
+ void StartPageScaleAnimation(const gfx::Vector2d& target_offset,
bool use_anchor,
float new_page_scale,
double duration_sec) override;
bool HasPendingPageScaleAnimation() const override;
void HeuristicsForGpuRasterizationUpdated(bool matches_heuristics) override;
void SetNeedsBeginFrame() override;
- void DidStopFlinging() override;
void LayoutAndPaintAsync(base::OnceClosure callback) override;
void CompositeAndReadbackAsync(
base::OnceCallback<void(const SkBitmap&)> callback) override;
void SynchronouslyCompositeNoRasterForTesting() override;
void CompositeWithRasterForTesting() override;
void SetDeferCommits(bool defer_commits) override;
- void RegisterViewportLayers(
- const blink::WebLayerTreeView::ViewportLayers& viewport_layers) override;
+ void RegisterViewportLayers(const ViewportLayers& viewport_layers) override;
void ClearViewportLayers() override;
- void RegisterSelection(const blink::WebSelection& selection) override;
+ void RegisterSelection(const cc::LayerSelection& selection) override;
void ClearSelection() override;
void SetMutatorClient(std::unique_ptr<cc::LayerTreeMutator>) override;
void ForceRecalculateRasterScales() override;
void SetEventListenerProperties(
- blink::WebEventListenerClass eventClass,
- blink::WebEventListenerProperties properties) override;
- blink::WebEventListenerProperties EventListenerProperties(
- blink::WebEventListenerClass eventClass) const override;
+ cc::EventListenerClass eventClass,
+ cc::EventListenerProperties properties) override;
+ cc::EventListenerProperties EventListenerProperties(
+ cc::EventListenerClass eventClass) const override;
void SetHaveScrollEventHandlers(bool) override;
bool HaveScrollEventHandlers() const override;
int LayerTreeId() const override;
@@ -174,8 +159,8 @@ class CONTENT_EXPORT RenderWidgetCompositor
void SetShowScrollBottleneckRects(bool show) override;
void NotifySwapTime(ReportTimeCallback callback) override;
- void UpdateBrowserControlsState(blink::WebBrowserControlsState constraints,
- blink::WebBrowserControlsState current,
+ void UpdateBrowserControlsState(cc::BrowserControlsState constraints,
+ cc::BrowserControlsState current,
bool animate) override;
void SetBrowserControlsHeight(float top_height,
float bottom_height,
@@ -208,7 +193,9 @@ class CONTENT_EXPORT RenderWidgetCompositor
void DidCommitAndDrawFrame() override;
void DidReceiveCompositorFrameAck() override;
void DidCompletePageScaleAnimation() override;
- bool IsForSubframe() override;
+ void DidPresentCompositorFrame(
+ uint32_t frame_token,
+ const gfx::PresentationFeedback& feedback) override;
// cc::LayerTreeHostSingleThreadClient implementation.
void RequestScheduleAnimation() override;
@@ -216,24 +203,22 @@ class CONTENT_EXPORT RenderWidgetCompositor
void DidLoseLayerTreeFrameSink() override;
void RequestBeginMainFrameNotExpected(bool new_state) override;
- const cc::LayerTreeSettings& GetLayerTreeSettings() const {
- return layer_tree_host_->GetSettings();
- }
+ const cc::LayerTreeSettings& GetLayerTreeSettings() const;
- // Creates a cc::RenderFrameMetadataObserver, which is sent to the compositor
+ // Sets the RenderFrameMetadataObserver, which is sent to the compositor
// thread for binding.
- void CreateRenderFrameObserver(
- mojom::RenderFrameMetadataObserverRequest request,
- mojom::RenderFrameMetadataObserverClientPtrInfo client_info);
+ void SetRenderFrameObserver(
+ std::unique_ptr<cc::RenderFrameMetadataObserver> observer);
- protected:
- friend class RenderViewImplScaleFactorTest;
-
- RenderWidgetCompositor(RenderWidgetCompositorDelegate* delegate,
- CompositorDependencies* compositor_deps);
+ void AddPresentationCallback(
+ uint32_t frame_token,
+ base::OnceCallback<void(base::TimeTicks)> callback);
cc::LayerTreeHost* layer_tree_host() { return layer_tree_host_.get(); }
+ protected:
+ friend class RenderViewImplScaleFactorTest;
+
private:
void SetLayerTreeFrameSink(
std::unique_ptr<cc::LayerTreeFrameSink> layer_tree_frame_sink);
@@ -242,13 +227,14 @@ class CONTENT_EXPORT RenderWidgetCompositor
void SynchronouslyComposite(bool raster,
std::unique_ptr<cc::SwapPromise> swap_promise);
- RenderWidgetCompositorDelegate* const delegate_;
- CompositorDependencies* const compositor_deps_;
- const bool threaded_;
- std::unique_ptr<cc::AnimationHost> animation_host_;
+ LayerTreeViewDelegate* const delegate_;
+ const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
+ const scoped_refptr<base::SingleThreadTaskRunner> compositor_thread_;
+ cc::TaskGraphRunner* const task_graph_runner_;
+ blink::scheduler::WebThreadScheduler* const web_main_thread_scheduler_;
+ const std::unique_ptr<cc::AnimationHost> animation_host_;
std::unique_ptr<cc::LayerTreeHost> layer_tree_host_;
- bool never_visible_;
- bool is_for_oopif_;
+ bool never_visible_ = false;
bool layer_tree_frame_sink_request_failed_while_invisible_ = false;
@@ -256,12 +242,16 @@ class CONTENT_EXPORT RenderWidgetCompositor
base::OnceClosure layout_and_paint_async_callback_;
viz::FrameSinkId frame_sink_id_;
+ base::circular_deque<
+ std::pair<uint32_t,
+ std::vector<base::OnceCallback<void(base::TimeTicks)>>>>
+ presentation_callbacks_;
- base::WeakPtrFactory<RenderWidgetCompositor> weak_factory_;
+ base::WeakPtrFactory<LayerTreeView> weak_factory_;
- DISALLOW_COPY_AND_ASSIGN(RenderWidgetCompositor);
+ DISALLOW_COPY_AND_ASSIGN(LayerTreeView);
};
} // namespace content
-#endif // CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_H_
+#endif // CONTENT_RENDERER_GPU_LAYER_TREE_VIEW_H_
diff --git a/chromium/content/renderer/gpu/render_widget_compositor_delegate.h b/chromium/content/renderer/gpu/layer_tree_view_delegate.h
index 24e9453d6dc..51ab69aed61 100644
--- a/chromium/content/renderer/gpu/render_widget_compositor_delegate.h
+++ b/chromium/content/renderer/gpu/layer_tree_view_delegate.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_DELEGATE_H_
-#define CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_DELEGATE_H_
+#ifndef CONTENT_RENDERER_GPU_LAYER_TREE_VIEW_DELEGATE_H_
+#define CONTENT_RENDERER_GPU_LAYER_TREE_VIEW_DELEGATE_H_
#include <memory>
#include <vector>
@@ -11,12 +11,11 @@
#include "base/callback.h"
#include "base/time/time.h"
#include "cc/trees/layer_tree_host_client.h"
-#include "content/common/content_export.h"
namespace cc {
class LayerTreeFrameSink;
class SwapPromise;
-}
+} // namespace cc
namespace gfx {
class Vector2dF;
@@ -28,13 +27,13 @@ class CopyOutputRequest;
namespace content {
-using LayerTreeFrameSinkCallback =
- base::Callback<void(std::unique_ptr<cc::LayerTreeFrameSink>)>;
-
-// Consumers of RenderWidgetCompositor implement this delegate in order to
+// Consumers of LayerTreeView implement this delegate in order to
// transport compositing information across processes.
-class CONTENT_EXPORT RenderWidgetCompositorDelegate {
+class LayerTreeViewDelegate {
public:
+ using LayerTreeFrameSinkCallback =
+ base::OnceCallback<void(std::unique_ptr<cc::LayerTreeFrameSink>)>;
+
// Report viewport related properties during a commit from the compositor
// thread.
virtual void ApplyViewportDeltas(
@@ -55,7 +54,7 @@ class CONTENT_EXPORT RenderWidgetCompositorDelegate {
// Requests a LayerTreeFrameSink to submit CompositorFrames to.
virtual void RequestNewLayerTreeFrameSink(
- const LayerTreeFrameSinkCallback& callback) = 0;
+ LayerTreeFrameSinkCallback callback) = 0;
// Notifies that the draw commands for a committed frame have been issued.
virtual void DidCommitAndDrawCompositorFrame() = 0;
@@ -70,7 +69,7 @@ class CONTENT_EXPORT RenderWidgetCompositorDelegate {
// will be displayed.
virtual void DidReceiveCompositorFrameAck() = 0;
- // Indicates whether the RenderWidgetCompositor is about to close.
+ // Indicates whether the LayerTreeView is about to close.
virtual bool IsClosing() const = 0;
// Requests that the client schedule a composite now, and calculate
@@ -93,9 +92,9 @@ class CONTENT_EXPORT RenderWidgetCompositorDelegate {
std::unique_ptr<viz::CopyOutputRequest> request) = 0;
protected:
- virtual ~RenderWidgetCompositorDelegate() {}
+ virtual ~LayerTreeViewDelegate() {}
};
} // namespace content
-#endif // CONTENT_RENDERER_GPU_RENDER_WIDGET_COMPOSITOR_DELEGATE_H_
+#endif // CONTENT_RENDERER_GPU_LAYER_TREE_VIEW_DELEGATE_H_
diff --git a/chromium/content/renderer/gpu/layer_tree_view_unittest.cc b/chromium/content/renderer/gpu/layer_tree_view_unittest.cc
new file mode 100644
index 00000000000..abc55297718
--- /dev/null
+++ b/chromium/content/renderer/gpu/layer_tree_view_unittest.cc
@@ -0,0 +1,376 @@
+// 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/gpu/layer_tree_view.h"
+
+#include <utility>
+
+#include "base/location.h"
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "build/build_config.h"
+#include "cc/test/fake_layer_tree_frame_sink.h"
+#include "cc/test/test_task_graph_runner.h"
+#include "cc/test/test_ukm_recorder_factory.h"
+#include "cc/trees/layer_tree_host.h"
+#include "components/viz/common/frame_sinks/copy_output_request.h"
+#include "components/viz/test/test_context_provider.h"
+#include "content/test/stub_layer_tree_view_delegate.h"
+#include "gpu/GLES2/gl2extchromium.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/scheduler/test/fake_renderer_scheduler.h"
+#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+
+using testing::AllOf;
+using testing::Field;
+
+namespace content {
+namespace {
+
+enum FailureMode {
+ NO_FAILURE,
+ BIND_CONTEXT_FAILURE,
+ GPU_CHANNEL_FAILURE,
+};
+
+class FakeLayerTreeViewDelegate : public StubLayerTreeViewDelegate {
+ public:
+ FakeLayerTreeViewDelegate() = default;
+
+ void RequestNewLayerTreeFrameSink(
+ LayerTreeFrameSinkCallback callback) override {
+ // 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_) {
+ std::move(callback).Run(nullptr);
+ return;
+ }
+
+ auto context_provider = viz::TestContextProvider::Create();
+ if (num_failures_since_last_success_ < num_failures_before_success_) {
+ context_provider->UnboundTestContextGL()->LoseContextCHROMIUM(
+ GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
+ }
+ std::move(callback).Run(
+ cc::FakeLayerTreeFrameSink::Create3d(std::move(context_provider)));
+ }
+
+ 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_failures_since_last_success_ = 0;
+ num_successes_ = 0;
+ }
+
+ void add_success() {
+ ++num_successes_;
+ num_requests_since_last_success_ = 0;
+ num_failures_since_last_success_ = 0;
+ }
+ int num_successes() const { return num_successes_; }
+
+ void add_request() {
+ ++num_requests_since_last_success_;
+ ++num_requests_;
+ }
+ int num_requests() const { return num_requests_; }
+
+ 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;
+ }
+ int num_failures_before_success() const {
+ return num_failures_before_success_;
+ }
+
+ 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_failures_since_last_success_ = 0;
+ int num_successes_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeLayerTreeViewDelegate);
+};
+
+// Verify that failing to create an output surface will cause the compositor
+// 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.
+class LayerTreeViewWithFrameSinkTracking : public LayerTreeView {
+ public:
+ LayerTreeViewWithFrameSinkTracking(
+ FakeLayerTreeViewDelegate* delegate,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_thread,
+ cc::TaskGraphRunner* task_graph_runner,
+ blink::scheduler::WebThreadScheduler* scheduler)
+ : LayerTreeView(delegate,
+ std::move(main_thread),
+ std::move(compositor_thread),
+ task_graph_runner,
+ scheduler),
+ delegate_(delegate) {}
+
+ // Force a new output surface to be created.
+ void SynchronousComposite() {
+ layer_tree_host()->SetVisible(false);
+ layer_tree_host()->ReleaseLayerTreeFrameSink();
+ layer_tree_host()->SetVisible(true);
+
+ base::TimeTicks some_time;
+ layer_tree_host()->Composite(some_time, true /* raster */);
+ }
+
+ void RequestNewLayerTreeFrameSink() override {
+ delegate_->add_request();
+ LayerTreeView::RequestNewLayerTreeFrameSink();
+ }
+
+ void DidInitializeLayerTreeFrameSink() override {
+ LayerTreeView::DidInitializeLayerTreeFrameSink();
+ delegate_->add_success();
+ 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
+ // reentrantly as a part of RequestNewLayerTreeFrameSink.
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &LayerTreeViewWithFrameSinkTracking::SynchronousComposite,
+ base::Unretained(this)));
+ }
+ }
+
+ void DidFailToInitializeLayerTreeFrameSink() override {
+ LayerTreeView::DidFailToInitializeLayerTreeFrameSink();
+ delegate_->add_failure();
+ if (delegate_->num_requests() == expected_requests_) {
+ EXPECT_EQ(delegate_->num_successes(), expected_successes_);
+ EndTest();
+ return;
+ }
+ }
+
+ 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_ = expected_successes;
+ break;
+ case BIND_CONTEXT_FAILURE:
+ case GPU_CHANNEL_FAILURE:
+ expected_requests_ = num_tries * std::max(1, expected_successes);
+ break;
+ }
+ }
+
+ void EndTest() { run_loop_->Quit(); }
+
+ private:
+ FakeLayerTreeViewDelegate* delegate_;
+ base::RunLoop* run_loop_ = nullptr;
+ int expected_successes_ = 0;
+ int expected_requests_ = 0;
+ FailureMode failure_mode_ = NO_FAILURE;
+
+ DISALLOW_COPY_AND_ASSIGN(LayerTreeViewWithFrameSinkTracking);
+};
+
+class LayerTreeViewWithFrameSinkTrackingTest : public testing::Test {
+ public:
+ LayerTreeViewWithFrameSinkTrackingTest()
+ : layer_tree_view_(
+ &layer_tree_view_delegate_,
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
+ /*compositor_thread=*/nullptr,
+ &test_task_graph_runner_,
+ &fake_renderer_scheduler_) {
+ cc::LayerTreeSettings settings;
+ settings.single_thread_proxy_scheduler = false;
+ layer_tree_view_.Initialize(settings,
+ std::make_unique<cc::TestUkmRecorderFactory>());
+ }
+
+ void RunTest(int expected_successes, FailureMode failure_mode) {
+ layer_tree_view_delegate_.Reset();
+ // 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:
+ layer_tree_view_delegate_.set_num_failures_before_success(0);
+ layer_tree_view_delegate_.set_num_requests_before_success(0);
+ break;
+ case BIND_CONTEXT_FAILURE:
+ layer_tree_view_delegate_.set_num_failures_before_success(
+ tries_before_success);
+ layer_tree_view_delegate_.set_num_requests_before_success(0);
+ break;
+ case GPU_CHANNEL_FAILURE:
+ layer_tree_view_delegate_.set_num_failures_before_success(0);
+ layer_tree_view_delegate_.set_num_requests_before_success(
+ tries_before_success);
+ break;
+ }
+ base::RunLoop run_loop;
+ layer_tree_view_.SetUp(expected_successes, kTries, failure_mode, &run_loop);
+ layer_tree_view_.SetVisible(true);
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &LayerTreeViewWithFrameSinkTracking::SynchronousComposite,
+ base::Unretained(&layer_tree_view_)));
+ run_loop.Run();
+ }
+
+ protected:
+ base::MessageLoop ye_olde_message_loope_;
+ cc::TestTaskGraphRunner test_task_graph_runner_;
+ blink::scheduler::FakeRendererScheduler fake_renderer_scheduler_;
+ FakeLayerTreeViewDelegate layer_tree_view_delegate_;
+ LayerTreeViewWithFrameSinkTracking layer_tree_view_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LayerTreeViewWithFrameSinkTrackingTest);
+};
+
+TEST_F(LayerTreeViewWithFrameSinkTrackingTest, SucceedOnce) {
+ RunTest(1, NO_FAILURE);
+}
+
+TEST_F(LayerTreeViewWithFrameSinkTrackingTest, SucceedOnce_AfterNullChannel) {
+ RunTest(1, GPU_CHANNEL_FAILURE);
+}
+
+TEST_F(LayerTreeViewWithFrameSinkTrackingTest, SucceedOnce_AfterLostContext) {
+ RunTest(1, BIND_CONTEXT_FAILURE);
+}
+
+TEST_F(LayerTreeViewWithFrameSinkTrackingTest, SucceedTwice) {
+ RunTest(2, NO_FAILURE);
+}
+
+TEST_F(LayerTreeViewWithFrameSinkTrackingTest, SucceedTwice_AfterNullChannel) {
+ RunTest(2, GPU_CHANNEL_FAILURE);
+}
+
+TEST_F(LayerTreeViewWithFrameSinkTrackingTest, SucceedTwice_AfterLostContext) {
+ RunTest(2, BIND_CONTEXT_FAILURE);
+}
+
+TEST_F(LayerTreeViewWithFrameSinkTrackingTest, FailWithNullChannel) {
+ RunTest(0, GPU_CHANNEL_FAILURE);
+}
+
+TEST_F(LayerTreeViewWithFrameSinkTrackingTest, FailWithLostContext) {
+ RunTest(0, BIND_CONTEXT_FAILURE);
+}
+
+class VisibilityTestLayerTreeView : public LayerTreeView {
+ public:
+ VisibilityTestLayerTreeView(
+ StubLayerTreeViewDelegate* delegate,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread,
+ scoped_refptr<base::SingleThreadTaskRunner> compositor_thread,
+ cc::TaskGraphRunner* task_graph_runner,
+ blink::scheduler::WebThreadScheduler* scheduler)
+ : LayerTreeView(delegate,
+ std::move(main_thread),
+ std::move(compositor_thread),
+ task_graph_runner,
+ scheduler) {}
+
+ void RequestNewLayerTreeFrameSink() override {
+ LayerTreeView::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(LayerTreeViewTest, VisibilityTest) {
+ // Test that LayerTreeView does not retry FrameSink request while
+ // invisible.
+
+ base::MessageLoop message_loop;
+
+ cc::TestTaskGraphRunner test_task_graph_runner;
+ blink::scheduler::FakeRendererScheduler fake_renderer_scheduler;
+ // Synchronously callback with null FrameSink.
+ StubLayerTreeViewDelegate layer_tree_view_delegate;
+ VisibilityTestLayerTreeView layer_tree_view(
+ &layer_tree_view_delegate,
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
+ /*compositor_thread=*/nullptr, &test_task_graph_runner,
+ &fake_renderer_scheduler);
+
+ layer_tree_view.Initialize(cc::LayerTreeSettings(),
+ std::make_unique<cc::TestUkmRecorderFactory>());
+
+ {
+ // Make one request and stop immediately while invisible.
+ base::RunLoop run_loop;
+ layer_tree_view.set_run_loop(&run_loop);
+ layer_tree_view.SetVisible(false);
+ layer_tree_view.RequestNewLayerTreeFrameSink();
+ run_loop.Run();
+ layer_tree_view.set_run_loop(nullptr);
+ EXPECT_EQ(1, layer_tree_view.num_requests_sent());
+ }
+
+ {
+ // Make sure there are no more requests.
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+ EXPECT_EQ(1, layer_tree_view.num_requests_sent());
+ }
+
+ {
+ // Becoming visible retries request.
+ base::RunLoop run_loop;
+ layer_tree_view.set_run_loop(&run_loop);
+ layer_tree_view.SetVisible(true);
+ run_loop.Run();
+ layer_tree_view.set_run_loop(nullptr);
+ EXPECT_EQ(2, layer_tree_view.num_requests_sent());
+ }
+}
+
+} // namespace
+} // namespace content
diff --git a/chromium/content/renderer/gpu/queue_message_swap_promise.cc b/chromium/content/renderer/gpu/queue_message_swap_promise.cc
index 199ddfa4402..b9a07865124 100644
--- a/chromium/content/renderer/gpu/queue_message_swap_promise.cc
+++ b/chromium/content/renderer/gpu/queue_message_swap_promise.cc
@@ -7,7 +7,6 @@
#include <memory>
#include "base/command_line.h"
-#include "cc/trees/frame_token_allocator.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_thread.h"
@@ -47,9 +46,7 @@ void QueueMessageSwapPromise::DidActivate() {
// The OutputSurface will take care of the Drain+Send.
}
-void QueueMessageSwapPromise::WillSwap(
- viz::CompositorFrameMetadata* metadata,
- cc::FrameTokenAllocator* frame_token_allocator) {
+void QueueMessageSwapPromise::WillSwap(viz::CompositorFrameMetadata* metadata) {
#if DCHECK_IS_ON()
DCHECK(!completed_);
#endif
@@ -64,7 +61,7 @@ void QueueMessageSwapPromise::WillSwap(
std::vector<IPC::Message> messages_to_send;
FrameSwapMessageQueue::TransferMessages(&messages, &messages_to_send);
if (!messages_to_send.empty()) {
- metadata->frame_token = frame_token_allocator->GetOrAllocateFrameToken();
+ metadata->send_frame_token_to_embedder = true;
message_sender_->Send(new ViewHostMsg_FrameSwapMessages(
message_queue_->routing_id(), metadata->frame_token,
messages_to_send));
@@ -76,8 +73,7 @@ void QueueMessageSwapPromise::WillSwap(
void QueueMessageSwapPromise::DidSwap() {}
-cc::SwapPromise::DidNotSwapAction QueueMessageSwapPromise::DidNotSwap(
- DidNotSwapReason reason) {
+void QueueMessageSwapPromise::DidNotSwap(DidNotSwapReason reason) {
#if DCHECK_IS_ON()
DCHECK(!completed_);
#endif
@@ -89,7 +85,6 @@ cc::SwapPromise::DidNotSwapAction QueueMessageSwapPromise::DidNotSwap(
message_sender_->Send(msg.release());
}
PromiseCompleted();
- return DidNotSwapAction::BREAK_PROMISE;
}
void QueueMessageSwapPromise::PromiseCompleted() {
diff --git a/chromium/content/renderer/gpu/queue_message_swap_promise.h b/chromium/content/renderer/gpu/queue_message_swap_promise.h
index 392ac6da142..e56df3986fe 100644
--- a/chromium/content/renderer/gpu/queue_message_swap_promise.h
+++ b/chromium/content/renderer/gpu/queue_message_swap_promise.h
@@ -27,10 +27,9 @@ class QueueMessageSwapPromise : public cc::SwapPromise {
~QueueMessageSwapPromise() override;
void DidActivate() override;
- void WillSwap(viz::CompositorFrameMetadata* metadata,
- cc::FrameTokenAllocator* frame_token_allocator) override;
+ void WillSwap(viz::CompositorFrameMetadata* metadata) override;
void DidSwap() override;
- DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override;
+ void DidNotSwap(DidNotSwapReason reason) override;
int64_t TraceId() const override;
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 828148017c4..098d92e1e00 100644
--- a/chromium/content/renderer/gpu/queue_message_swap_promise_unittest.cc
+++ b/chromium/content/renderer/gpu/queue_message_swap_promise_unittest.cc
@@ -12,11 +12,11 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/test/scoped_task_environment.h"
-#include "cc/trees/frame_token_allocator.h"
#include "cc/trees/swap_promise.h"
+#include "content/common/render_frame_metadata.mojom.h"
#include "content/common/view_messages.h"
#include "content/renderer/gpu/frame_swap_message_queue.h"
-#include "content/renderer/gpu/render_widget_compositor.h"
+#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/render_widget.h"
#include "content/test/mock_render_process.h"
#include "ipc/ipc_message.h"
@@ -146,7 +146,7 @@ class QueueMessageSwapPromiseTest : public testing::Test {
for (const auto& promise : promises_) {
if (promise.get()) {
promise->DidActivate();
- promise->WillSwap(&dummy_metadata_, &dummy_frame_token_allocator_);
+ promise->WillSwap(&dummy_metadata_);
promise->DidSwap();
}
}
@@ -162,7 +162,6 @@ class QueueMessageSwapPromiseTest : public testing::Test {
std::vector<IPC::Message> messages_;
std::vector<std::unique_ptr<cc::SwapPromise>> promises_;
viz::CompositorFrameMetadata dummy_metadata_;
- cc::FrameTokenAllocator dummy_frame_token_allocator_;
cc::RenderFrameMetadata dummy_render_frame_metadata_;
private:
@@ -180,7 +179,7 @@ TEST_F(QueueMessageSwapPromiseTest, NextSwapPolicySchedulesMessageForNextSwap) {
ASSERT_TRUE(promises_[0].get());
promises_[0]->DidActivate();
- promises_[0]->WillSwap(&dummy_metadata_, &dummy_frame_token_allocator_);
+ promises_[0]->WillSwap(&dummy_metadata_);
promises_[0]->DidSwap();
EXPECT_TRUE(DirectSendMessages().empty());
@@ -285,7 +284,7 @@ TEST_F(QueueMessageSwapPromiseTest, VisualStateSwapPromiseDidActivate) {
QueueMessages(data, arraysize(data));
promises_[0]->DidActivate();
- promises_[0]->WillSwap(&dummy_metadata_, &dummy_frame_token_allocator_);
+ promises_[0]->WillSwap(&dummy_metadata_);
promises_[0]->DidSwap();
ASSERT_FALSE(promises_[1].get());
std::vector<std::unique_ptr<IPC::Message>> messages;
diff --git a/chromium/content/renderer/gpu/render_widget_compositor.cc b/chromium/content/renderer/gpu/render_widget_compositor.cc
deleted file mode 100644
index e4faef4229e..00000000000
--- a/chromium/content/renderer/gpu/render_widget_compositor.cc
+++ /dev/null
@@ -1,1304 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/gpu/render_widget_compositor.h"
-
-#include <stddef.h>
-
-#include <cmath>
-#include <limits>
-#include <string>
-#include <utility>
-
-#include "base/auto_reset.h"
-#include "base/base_switches.h"
-#include "base/callback.h"
-#include "base/command_line.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/synchronization/lock.h"
-#include "base/sys_info.h"
-#include "base/task_scheduler/post_task.h"
-#include "base/task_scheduler/task_scheduler.h"
-#include "base/task_scheduler/task_traits.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/time/time.h"
-#include "base/values.h"
-#include "build/build_config.h"
-#include "cc/animation/animation_host.h"
-#include "cc/animation/animation_timeline.h"
-#include "cc/base/region.h"
-#include "cc/base/switches.h"
-#include "cc/benchmarks/micro_benchmark.h"
-#include "cc/debug/layer_tree_debug_state.h"
-#include "cc/input/layer_selection_bound.h"
-#include "cc/layers/layer.h"
-#include "cc/trees/latency_info_swap_promise.h"
-#include "cc/trees/latency_info_swap_promise_monitor.h"
-#include "cc/trees/layer_tree_host.h"
-#include "cc/trees/layer_tree_mutator.h"
-#include "cc/trees/render_frame_metadata_observer.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/common/render_frame_metadata.mojom.h"
-#include "content/public/common/content_client.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/common/screen_info.h"
-#include "content/public/common/use_zoom_for_dsf_policy.h"
-#include "content/public/renderer/content_renderer_client.h"
-#include "content/renderer/gpu/render_widget_compositor_delegate.h"
-#include "content/renderer/render_frame_metadata_observer_impl.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/command_buffer/service/gpu_switches.h"
-#include "media/base/media_switches.h"
-#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
-#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
-#include "third_party/blink/public/platform/web_runtime_features.h"
-#include "third_party/blink/public/platform/web_size.h"
-#include "third_party/blink/public/web/blink.h"
-#include "third_party/blink/public/web/web_selection.h"
-#include "third_party/skia/include/core/SkImage.h"
-#include "ui/base/ui_base_switches.h"
-#include "ui/gfx/switches.h"
-#include "ui/gl/gl_switches.h"
-#include "ui/native_theme/native_theme_features.h"
-#include "ui/native_theme/overlay_scrollbar_constants_aura.h"
-
-namespace base {
-class Value;
-}
-
-namespace cc {
-class Layer;
-}
-
-namespace content {
-namespace {
-
-const base::Feature kUnpremultiplyAndDitherLowBitDepthTiles = {
- "UnpremultiplyAndDitherLowBitDepthTiles", base::FEATURE_ENABLED_BY_DEFAULT};
-
-using ReportTimeCallback = blink::WebLayerTreeView::ReportTimeCallback;
-
-class ReportTimeSwapPromise : public cc::SwapPromise {
- public:
- ReportTimeSwapPromise(
- ReportTimeCallback callback,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
- ~ReportTimeSwapPromise() override;
-
- void DidActivate() override {}
- void WillSwap(viz::CompositorFrameMetadata* metadata,
- cc::FrameTokenAllocator* frame_token_allocator) override {}
- void DidSwap() override;
- DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override;
-
- int64_t TraceId() const override;
-
- private:
- ReportTimeCallback callback_;
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(ReportTimeSwapPromise);
-};
-
-ReportTimeSwapPromise::ReportTimeSwapPromise(
- ReportTimeCallback callback,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : callback_(std::move(callback)), task_runner_(std::move(task_runner)) {}
-
-ReportTimeSwapPromise::~ReportTimeSwapPromise() {}
-
-void ReportTimeSwapPromise::DidSwap() {
- task_runner_->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback_),
- blink::WebLayerTreeView::SwapResult::kDidSwap,
- base::TimeTicks::Now()));
-}
-
-cc::SwapPromise::DidNotSwapAction ReportTimeSwapPromise::DidNotSwap(
- cc::SwapPromise::DidNotSwapReason reason) {
- blink::WebLayerTreeView::SwapResult result;
- switch (reason) {
- case cc::SwapPromise::DidNotSwapReason::SWAP_FAILS:
- result = blink::WebLayerTreeView::SwapResult::kDidNotSwapSwapFails;
- break;
- case cc::SwapPromise::DidNotSwapReason::COMMIT_FAILS:
- result = blink::WebLayerTreeView::SwapResult::kDidNotSwapCommitFails;
- break;
- case cc::SwapPromise::DidNotSwapReason::COMMIT_NO_UPDATE:
- result = blink::WebLayerTreeView::SwapResult::kDidNotSwapCommitNoUpdate;
- break;
- case cc::SwapPromise::DidNotSwapReason::ACTIVATION_FAILS:
- result = blink::WebLayerTreeView::SwapResult::kDidNotSwapActivationFails;
- break;
- }
- task_runner_->PostTask(FROM_HERE, base::BindOnce(std::move(callback_), result,
- base::TimeTicks::Now()));
- return cc::SwapPromise::DidNotSwapAction::BREAK_PROMISE;
-}
-
-int64_t ReportTimeSwapPromise::TraceId() const {
- return 0;
-}
-
-bool GetSwitchValueAsInt(const base::CommandLine& command_line,
- const std::string& switch_string,
- int min_value,
- int max_value,
- int* result) {
- std::string string_value = command_line.GetSwitchValueASCII(switch_string);
- int int_value;
- if (base::StringToInt(string_value, &int_value) && int_value >= min_value &&
- int_value <= max_value) {
- *result = int_value;
- return true;
- } else {
- LOG(WARNING) << "Failed to parse switch " << switch_string << ": "
- << string_value;
- return false;
- }
-}
-
-gfx::SelectionBound::Type ConvertFromWebSelectionBoundType(
- blink::WebSelectionBound::Type type) {
- if (type == blink::WebSelectionBound::Type::kSelectionLeft)
- return gfx::SelectionBound::Type::LEFT;
- if (type == blink::WebSelectionBound::Type::kSelectionRight)
- return gfx::SelectionBound::Type::RIGHT;
- // if WebSelection is not a range (caret or none),
- // The type of gfx::SelectionBound should be CENTER.
- DCHECK_EQ(type, blink::WebSelectionBound::Type::kCaret);
- return gfx::SelectionBound::Type::CENTER;
-}
-
-cc::LayerSelectionBound ConvertFromWebSelectionBound(
- const blink::WebSelectionBound& bound) {
- cc::LayerSelectionBound cc_bound;
- DCHECK(bound.layer_id);
-
- cc_bound.type = ConvertFromWebSelectionBoundType(bound.type);
- cc_bound.layer_id = bound.layer_id;
- cc_bound.edge_top = gfx::Point(bound.edge_top_in_layer);
- cc_bound.edge_bottom = gfx::Point(bound.edge_bottom_in_layer);
- cc_bound.hidden = bound.hidden;
- return cc_bound;
-}
-
-cc::LayerSelection ConvertFromWebSelection(
- const blink::WebSelection& web_selection) {
- if (web_selection.IsNone())
- return cc::LayerSelection();
- cc::LayerSelection cc_selection;
- cc_selection.start = ConvertFromWebSelectionBound(web_selection.Start());
- cc_selection.end = ConvertFromWebSelectionBound(web_selection.end());
- return cc_selection;
-}
-
-gfx::Size CalculateDefaultTileSize(const ScreenInfo& screen_info) {
- int default_tile_size = 256;
-#if defined(OS_ANDROID)
- const gfx::Size screen_size = gfx::ScaleToFlooredSize(
- screen_info.rect.size(), screen_info.device_scale_factor);
- int display_width = screen_size.width();
- int display_height = screen_size.height();
- int numTiles = (display_width * display_height) / (256 * 256);
- if (numTiles > 16)
- default_tile_size = 384;
- if (numTiles >= 40)
- default_tile_size = 512;
-
- // Adjust for some resolutions that barely straddle an extra
- // tile when in portrait mode. This helps worst case scroll/raster
- // by not needing a full extra tile for each row.
- constexpr int tolerance = 10; // To avoid rounding errors.
- int portrait_width = std::min(display_width, display_height);
- if (default_tile_size == 256 && std::abs(portrait_width - 768) < tolerance)
- default_tile_size += 32;
- if (default_tile_size == 384 && std::abs(portrait_width - 1200) < tolerance)
- default_tile_size += 32;
-#elif defined(OS_CHROMEOS) || defined(OS_MACOSX)
- // Use 512 for high DPI (dsf=2.0f) devices.
- if (screen_info.device_scale_factor >= 2.0f)
- default_tile_size = 512;
-#endif
-
- return gfx::Size(default_tile_size, default_tile_size);
-}
-
-// Check cc::BrowserControlsState, and blink::WebBrowserControlsState
-// are kept in sync.
-static_assert(int(blink::kWebBrowserControlsBoth) == int(cc::BOTH),
- "mismatching enums: BOTH");
-static_assert(int(blink::kWebBrowserControlsHidden) == int(cc::HIDDEN),
- "mismatching enums: HIDDEN");
-static_assert(int(blink::kWebBrowserControlsShown) == int(cc::SHOWN),
- "mismatching enums: SHOWN");
-
-static cc::BrowserControlsState ConvertBrowserControlsState(
- blink::WebBrowserControlsState state) {
- return static_cast<cc::BrowserControlsState>(state);
-}
-
-} // namespace
-
-// static
-std::unique_ptr<RenderWidgetCompositor> RenderWidgetCompositor::Create(
- RenderWidgetCompositorDelegate* delegate,
- CompositorDependencies* compositor_deps) {
- std::unique_ptr<RenderWidgetCompositor> compositor(
- new RenderWidgetCompositor(delegate, compositor_deps));
- return compositor;
-}
-
-RenderWidgetCompositor::RenderWidgetCompositor(
- RenderWidgetCompositorDelegate* delegate,
- CompositorDependencies* compositor_deps)
- : delegate_(delegate),
- compositor_deps_(compositor_deps),
- threaded_(!!compositor_deps_->GetCompositorImplThreadTaskRunner()),
- never_visible_(false),
- is_for_oopif_(false),
- weak_factory_(this) {}
-
-void RenderWidgetCompositor::Initialize(
- std::unique_ptr<cc::LayerTreeHost> layer_tree_host,
- std::unique_ptr<cc::AnimationHost> animation_host) {
- DCHECK(layer_tree_host);
- DCHECK(animation_host);
- animation_host_ = std::move(animation_host);
- layer_tree_host_ = std::move(layer_tree_host);
-}
-
-RenderWidgetCompositor::~RenderWidgetCompositor() = default;
-
-// static
-std::unique_ptr<cc::LayerTreeHost> RenderWidgetCompositor::CreateLayerTreeHost(
- LayerTreeHostClient* client,
- cc::LayerTreeHostSingleThreadClient* single_thread_client,
- cc::MutatorHost* mutator_host,
- CompositorDependencies* deps,
- const ScreenInfo& screen_info) {
- base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
- const bool is_threaded = !!deps->GetCompositorImplThreadTaskRunner();
- cc::LayerTreeSettings settings = GenerateLayerTreeSettings(
- *cmd, deps, client->IsForSubframe(), screen_info, is_threaded);
-
- std::unique_ptr<cc::LayerTreeHost> layer_tree_host;
-
- cc::LayerTreeHost::InitParams params;
- params.client = client;
- params.settings = &settings;
- 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
- // IO thread.
- params.image_worker_task_runner = base::CreateSequencedTaskRunnerWithTraits(
- {base::WithBaseSyncPrimitives(), base::TaskPriority::USER_VISIBLE,
- base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN});
- }
- if (!is_threaded) {
- // Single-threaded layout tests.
- layer_tree_host =
- cc::LayerTreeHost::CreateSingleThreaded(single_thread_client, &params);
- } else {
- layer_tree_host = cc::LayerTreeHost::CreateThreaded(
- deps->GetCompositorImplThreadTaskRunner(), &params);
- }
-
- return layer_tree_host;
-}
-
-// static
-cc::LayerTreeSettings RenderWidgetCompositor::GenerateLayerTreeSettings(
- const base::CommandLine& cmd,
- CompositorDependencies* compositor_deps,
- bool is_for_subframe,
- const ScreenInfo& screen_info,
- bool is_threaded) {
- cc::LayerTreeSettings settings;
-
- settings.resource_settings.use_r16_texture =
- base::FeatureList::IsEnabled(media::kUseR16Texture);
-
- settings.commit_to_active_tree = !is_threaded;
- settings.is_layer_tree_for_subframe = is_for_subframe;
-
- // For web contents, layer transforms should scale up the contents of layers
- // to keep content always crisp when possible.
- settings.layer_transforms_should_scale_layer_contents = true;
-
- settings.main_frame_before_activation_enabled =
- cmd.HasSwitch(cc::switches::kEnableMainFrameBeforeActivation);
-
- // Checkerimaging is not supported for synchronous single-threaded mode, which
- // is what the renderer uses if its not threaded.
- settings.enable_checker_imaging =
- !cmd.HasSwitch(cc::switches::kDisableCheckerImaging) && is_threaded;
-
-#if defined(OS_ANDROID)
- // We can use a more aggressive limit on Android since decodes tend to take
- // longer on these devices.
- settings.min_image_bytes_to_checker = 512 * 1024; // 512kB
-
- // Re-rasterization of checker-imaged content with software raster can be too
- // costly on Android.
- settings.only_checker_images_with_gpu_raster = true;
-#endif
-
- // TODO(danakj): This should not be a setting O_O; it should change when the
- // device scale factor on LayerTreeHost changes.
- settings.default_tile_size = CalculateDefaultTileSize(screen_info);
- if (cmd.HasSwitch(switches::kDefaultTileWidth)) {
- int tile_width = 0;
- GetSwitchValueAsInt(cmd, switches::kDefaultTileWidth, 1,
- std::numeric_limits<int>::max(), &tile_width);
- settings.default_tile_size.set_width(tile_width);
- }
- if (cmd.HasSwitch(switches::kDefaultTileHeight)) {
- int tile_height = 0;
- GetSwitchValueAsInt(cmd, switches::kDefaultTileHeight, 1,
- std::numeric_limits<int>::max(), &tile_height);
- settings.default_tile_size.set_height(tile_height);
- }
-
- int max_untiled_layer_width = settings.max_untiled_layer_size.width();
- if (cmd.HasSwitch(switches::kMaxUntiledLayerWidth)) {
- GetSwitchValueAsInt(cmd, switches::kMaxUntiledLayerWidth, 1,
- std::numeric_limits<int>::max(),
- &max_untiled_layer_width);
- }
- int max_untiled_layer_height = settings.max_untiled_layer_size.height();
- if (cmd.HasSwitch(switches::kMaxUntiledLayerHeight)) {
- GetSwitchValueAsInt(cmd, switches::kMaxUntiledLayerHeight, 1,
- std::numeric_limits<int>::max(),
- &max_untiled_layer_height);
- }
-
- settings.max_untiled_layer_size =
- gfx::Size(max_untiled_layer_width, max_untiled_layer_height);
-
- settings.gpu_rasterization_msaa_sample_count =
- compositor_deps->GetGpuRasterizationMSAASampleCount();
- settings.gpu_rasterization_forced =
- compositor_deps->IsGpuRasterizationForced();
-
- settings.can_use_lcd_text = compositor_deps->IsLcdTextEnabled();
- settings.use_zero_copy = compositor_deps->IsZeroCopyEnabled();
- settings.use_partial_raster = compositor_deps->IsPartialRasterEnabled();
- settings.enable_elastic_overscroll =
- compositor_deps->IsElasticOverscrollEnabled();
- settings.resource_settings.use_gpu_memory_buffer_resources =
- compositor_deps->IsGpuMemoryBufferCompositorResourcesEnabled();
- settings.enable_oop_rasterization =
- cmd.HasSwitch(switches::kEnableOOPRasterization);
-
- // Build LayerTreeSettings from command line args.
- LayerTreeSettingsFactory::SetBrowserControlsSettings(settings, cmd);
-
- settings.use_layer_lists = cmd.HasSwitch(cc::switches::kEnableLayerLists);
-
- // The means the renderer compositor has 2 possible modes:
- // - Threaded compositing with a scheduler.
- // - Single threaded compositing without a scheduler (for layout tests only).
- // Using the scheduler in layout tests introduces additional composite steps
- // that create flakiness.
- settings.single_thread_proxy_scheduler = false;
-
- // These flags should be mirrored by UI versions in ui/compositor/.
- if (cmd.HasSwitch(cc::switches::kShowCompositedLayerBorders))
- settings.initial_debug_state.show_debug_borders.set();
- settings.initial_debug_state.show_layer_animation_bounds_rects =
- cmd.HasSwitch(cc::switches::kShowLayerAnimationBounds);
- settings.initial_debug_state.show_paint_rects =
- cmd.HasSwitch(switches::kShowPaintRects);
- settings.initial_debug_state.show_property_changed_rects =
- cmd.HasSwitch(cc::switches::kShowPropertyChangedRects);
- settings.initial_debug_state.show_surface_damage_rects =
- cmd.HasSwitch(cc::switches::kShowSurfaceDamageRects);
- settings.initial_debug_state.show_screen_space_rects =
- cmd.HasSwitch(cc::switches::kShowScreenSpaceRects);
-
- settings.initial_debug_state.SetRecordRenderingStats(
- cmd.HasSwitch(cc::switches::kEnableGpuBenchmarking));
- settings.enable_surface_synchronization =
- features::IsSurfaceSynchronizationEnabled();
- settings.build_hit_test_data = features::IsVizHitTestingSurfaceLayerEnabled();
-
- if (cmd.HasSwitch(cc::switches::kSlowDownRasterScaleFactor)) {
- const int kMinSlowDownScaleFactor = 0;
- const int kMaxSlowDownScaleFactor = INT_MAX;
- GetSwitchValueAsInt(
- cmd, cc::switches::kSlowDownRasterScaleFactor, kMinSlowDownScaleFactor,
- kMaxSlowDownScaleFactor,
- &settings.initial_debug_state.slow_down_raster_scale_factor);
- }
-
- // This is default overlay scrollbar settings for Android and DevTools mobile
- // emulator. Aura Overlay Scrollbar will override below.
- settings.scrollbar_animator = cc::LayerTreeSettings::ANDROID_OVERLAY;
- settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
- settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(300);
- settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(300);
-
-
-#if defined(OS_ANDROID)
- bool using_synchronous_compositor =
- GetContentClient()->UsingSynchronousCompositing();
- bool using_low_memory_policy = base::SysInfo::IsLowEndDevice();
-
- settings.use_stream_video_draw_quad = true;
- settings.using_synchronous_renderer_compositor = using_synchronous_compositor;
- if (using_synchronous_compositor) {
- // Android WebView uses system scrollbars, so make ours invisible.
- // http://crbug.com/677348: This can't be done using hide_scrollbars
- // setting because supporting -webkit custom scrollbars is still desired
- // on sublayers.
- settings.scrollbar_animator = cc::LayerTreeSettings::NO_ANIMATOR;
- settings.solid_color_scrollbar_color = SK_ColorTRANSPARENT;
-
- settings.enable_early_damage_check =
- cmd.HasSwitch(cc::switches::kCheckDamageEarly);
- }
- // Android WebView handles root layer flings itself.
- settings.ignore_root_layer_flings = using_synchronous_compositor;
- // Memory policy on Android WebView does not depend on whether device is
- // low end, so always use default policy.
- if (using_low_memory_policy && !using_synchronous_compositor) {
- // On low-end we want to be very carefull about killing other
- // apps. So initially we use 50% more memory to avoid flickering
- // or raster-on-demand.
- settings.max_memory_for_prepaint_percentage = 67;
- } else {
- // On other devices we have increased memory excessively to avoid
- // raster-on-demand already, so now we reserve 50% _only_ to avoid
- // raster-on-demand, and use 50% of the memory otherwise.
- settings.max_memory_for_prepaint_percentage = 50;
- }
-
- // TODO(danakj): Only do this on low end devices.
- settings.create_low_res_tiling = true;
-
-#else // defined(OS_ANDROID)
- bool using_synchronous_compositor = false; // Only for Android WebView.
- // On desktop, we never use the low memory policy unless we are simulating
- // low-end mode via a switch.
- bool using_low_memory_policy =
- cmd.HasSwitch(switches::kEnableLowEndDeviceMode);
-
- if (ui::IsOverlayScrollbarEnabled()) {
- settings.scrollbar_animator = cc::LayerTreeSettings::AURA_OVERLAY;
- settings.scrollbar_fade_delay = ui::kOverlayScrollbarFadeDelay;
- settings.scrollbar_fade_duration = ui::kOverlayScrollbarFadeDuration;
- settings.scrollbar_thinning_duration =
- ui::kOverlayScrollbarThinningDuration;
- settings.scrollbar_flash_after_any_scroll_update =
- ui::OverlayScrollbarFlashAfterAnyScrollUpdate();
- settings.scrollbar_flash_when_mouse_enter =
- ui::OverlayScrollbarFlashWhenMouseEnter();
- }
-
- // On desktop, if there's over 4GB of memory on the machine, increase the
- // working set size to 256MB for both gpu and software.
- const int kImageDecodeMemoryThresholdMB = 4 * 1024;
- if (base::SysInfo::AmountOfPhysicalMemoryMB() >=
- kImageDecodeMemoryThresholdMB) {
- settings.decoded_image_working_set_budget_bytes = 256 * 1024 * 1024;
- } else {
- // This is the default, but recorded here as well.
- settings.decoded_image_working_set_budget_bytes = 128 * 1024 * 1024;
- }
-#endif // defined(OS_ANDROID)
-
- if (using_low_memory_policy) {
- // RGBA_4444 textures are only enabled:
- // - If the user hasn't explicitly disabled them
- // - If system ram is <= 512MB (1GB devices are sometimes low-end).
- // - If we are not running in a WebView, where 4444 isn't supported.
- if (!cmd.HasSwitch(switches::kDisableRGBA4444Textures) &&
- base::SysInfo::AmountOfPhysicalMemoryMB() <= 512 &&
- !using_synchronous_compositor) {
- settings.use_rgba_4444 = viz::RGBA_4444;
-
- // If we are going to unpremultiply and dither these tiles, we need to
- // allocate an additional RGBA_8888 intermediate for each tile
- // rasterization when rastering to RGBA_4444 to allow for dithering.
- // Setting a reasonable sized max tile size allows this intermediate to
- // be consistently reused.
- if (base::FeatureList::IsEnabled(
- kUnpremultiplyAndDitherLowBitDepthTiles)) {
- settings.max_gpu_raster_tile_size = gfx::Size(512, 256);
- settings.unpremultiply_and_dither_low_bit_depth_tiles = true;
- }
- }
- }
-
- if (cmd.HasSwitch(switches::kEnableLowResTiling))
- settings.create_low_res_tiling = true;
- if (cmd.HasSwitch(switches::kDisableLowResTiling))
- settings.create_low_res_tiling = false;
-
- if (cmd.HasSwitch(switches::kEnableRGBA4444Textures) &&
- !cmd.HasSwitch(switches::kDisableRGBA4444Textures)) {
- settings.use_rgba_4444 = true;
- }
-
- settings.max_staging_buffer_usage_in_bytes = 32 * 1024 * 1024; // 32MB
- // Use 1/4th of staging buffers on low-end devices.
- if (base::SysInfo::IsLowEndDevice())
- settings.max_staging_buffer_usage_in_bytes /= 4;
-
- cc::ManagedMemoryPolicy defaults = settings.memory_policy;
- settings.memory_policy = GetGpuMemoryPolicy(defaults, screen_info);
-
- settings.disallow_non_exact_resource_reuse =
- cmd.HasSwitch(switches::kDisallowNonExactResourceReuse);
-#if defined(OS_ANDROID)
- // TODO(crbug.com/746931): This feature appears to be causing visual
- // corruption on certain android devices. Will investigate and re-enable.
- settings.disallow_non_exact_resource_reuse = true;
-#endif
-
- if (cmd.HasSwitch(switches::kRunAllCompositorStagesBeforeDraw)) {
- settings.wait_for_all_pipeline_stages_before_draw = true;
- settings.enable_latency_recovery = false;
- }
-
- settings.enable_image_animation_resync =
- !cmd.HasSwitch(switches::kDisableImageAnimationResync);
-
- settings.always_request_presentation_time =
- cmd.HasSwitch(cc::switches::kAlwaysRequestPresentationTime);
-
- settings.use_painted_device_scale_factor = IsUseZoomForDSFEnabled();
- return settings;
-}
-
-// static
-cc::ManagedMemoryPolicy RenderWidgetCompositor::GetGpuMemoryPolicy(
- const cc::ManagedMemoryPolicy& default_policy,
- const ScreenInfo& screen_info) {
- cc::ManagedMemoryPolicy actual = default_policy;
- actual.bytes_limit_when_visible = 0;
-
- // If the value was overridden on the command line, use the specified value.
- static bool client_hard_limit_bytes_overridden =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kForceGpuMemAvailableMb);
- if (client_hard_limit_bytes_overridden) {
- if (base::StringToSizeT(
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kForceGpuMemAvailableMb),
- &actual.bytes_limit_when_visible))
- actual.bytes_limit_when_visible *= 1024 * 1024;
- return actual;
- }
-
-#if defined(OS_ANDROID)
- // We can't query available GPU memory from the system on Android.
- // Physical memory is also mis-reported sometimes (eg. Nexus 10 reports
- // 1262MB when it actually has 2GB, while Razr M has 1GB but only reports
- // 128MB java heap size). First we estimate physical memory using both.
- size_t dalvik_mb = base::SysInfo::DalvikHeapSizeMB();
- size_t physical_mb = base::SysInfo::AmountOfPhysicalMemoryMB();
- size_t physical_memory_mb = 0;
- if (base::SysInfo::IsLowEndDevice()) {
- // TODO(crbug.com/742534): The code below appears to no longer work.
- // |dalvik_mb| no longer follows the expected heuristic pattern, causing us
- // to over-estimate memory on low-end devices. This entire section probably
- // needs to be re-written, but for now we can address the low-end Android
- // issues by ignoring |dalvik_mb|.
- physical_memory_mb = physical_mb;
- } else if (dalvik_mb >= 256) {
- physical_memory_mb = dalvik_mb * 4;
- } else {
- physical_memory_mb = std::max(dalvik_mb * 4, (physical_mb * 4) / 3);
- }
-
- // Now we take a default of 1/8th of memory on high-memory devices,
- // and gradually scale that back for low-memory devices (to be nicer
- // to other apps so they don't get killed). Examples:
- // Nexus 4/10(2GB) 256MB (normally 128MB)
- // Droid Razr M(1GB) 114MB (normally 57MB)
- // Galaxy Nexus(1GB) 100MB (normally 50MB)
- // Xoom(1GB) 100MB (normally 50MB)
- // Nexus S(low-end) 8MB (normally 8MB)
- // Note that the compositor now uses only some of this memory for
- // pre-painting and uses the rest only for 'emergencies'.
- if (actual.bytes_limit_when_visible == 0) {
- // NOTE: Non-low-end devices use only 50% of these limits,
- // except during 'emergencies' where 100% can be used.
- if (physical_memory_mb >= 1536)
- actual.bytes_limit_when_visible = physical_memory_mb / 8; // >192MB
- else if (physical_memory_mb >= 1152)
- actual.bytes_limit_when_visible = physical_memory_mb / 8; // >144MB
- else if (physical_memory_mb >= 768)
- actual.bytes_limit_when_visible = physical_memory_mb / 10; // >76MB
- else if (physical_memory_mb >= 513)
- actual.bytes_limit_when_visible = physical_memory_mb / 12; // <64MB
- else
- // Devices with this little RAM have very little headroom so we hardcode
- // the limit rather than relying on the heuristics above. (They also use
- // 4444 textures so we can use a lower limit.)
- actual.bytes_limit_when_visible = 8;
-
- actual.bytes_limit_when_visible =
- actual.bytes_limit_when_visible * 1024 * 1024;
- // Clamp the observed value to a specific range on Android.
- actual.bytes_limit_when_visible = std::max(
- actual.bytes_limit_when_visible, static_cast<size_t>(8 * 1024 * 1024));
- actual.bytes_limit_when_visible =
- std::min(actual.bytes_limit_when_visible,
- static_cast<size_t>(256 * 1024 * 1024));
- }
- actual.priority_cutoff_when_visible =
- gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING;
-#else
- // Ignore what the system said and give all clients the same maximum
- // allocation on desktop platforms.
- actual.bytes_limit_when_visible = 512 * 1024 * 1024;
- actual.priority_cutoff_when_visible =
- gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
-
- // For large monitors (4k), double the tile memory to avoid frequent out of
- // memory problems. 4k could mean a screen width of anywhere from 3840 to 4096
- // (see https://en.wikipedia.org/wiki/4K_resolution). We use 3500 as a proxy
- // for "large enough".
- static const int kLargeDisplayThreshold = 3500;
- int display_width =
- std::round(screen_info.rect.width() * screen_info.device_scale_factor);
- if (display_width >= kLargeDisplayThreshold)
- actual.bytes_limit_when_visible *= 2;
-#endif
- return actual;
-}
-
-void RenderWidgetCompositor::SetNeverVisible() {
- DCHECK(!layer_tree_host_->IsVisible());
- never_visible_ = true;
-}
-
-const base::WeakPtr<cc::InputHandler>&
-RenderWidgetCompositor::GetInputHandler() {
- return layer_tree_host_->GetInputHandler();
-}
-
-void RenderWidgetCompositor::SetNeedsDisplayOnAllLayers() {
- layer_tree_host_->SetNeedsDisplayOnAllLayers();
-}
-
-void RenderWidgetCompositor::SetRasterizeOnlyVisibleContent() {
- cc::LayerTreeDebugState current = layer_tree_host_->GetDebugState();
- current.rasterize_only_visible_content = true;
- layer_tree_host_->SetDebugState(current);
-}
-
-void RenderWidgetCompositor::SetNeedsRedrawRect(gfx::Rect damage_rect) {
- layer_tree_host_->SetNeedsRedrawRect(damage_rect);
-}
-
-bool RenderWidgetCompositor::IsSurfaceSynchronizationEnabled() const {
- return layer_tree_host_->GetSettings().enable_surface_synchronization;
-}
-
-void RenderWidgetCompositor::SetNeedsForcedRedraw() {
- layer_tree_host_->SetNeedsCommitWithForcedRedraw();
-}
-
-std::unique_ptr<cc::SwapPromiseMonitor>
-RenderWidgetCompositor::CreateLatencyInfoSwapPromiseMonitor(
- ui::LatencyInfo* latency) {
- return std::make_unique<cc::LatencyInfoSwapPromiseMonitor>(
- latency, layer_tree_host_->GetSwapPromiseManager(), nullptr);
-}
-
-void RenderWidgetCompositor::QueueSwapPromise(
- std::unique_ptr<cc::SwapPromise> swap_promise) {
- layer_tree_host_->QueueSwapPromise(std::move(swap_promise));
-}
-
-int RenderWidgetCompositor::GetSourceFrameNumber() const {
- return layer_tree_host_->SourceFrameNumber();
-}
-
-void RenderWidgetCompositor::NotifyInputThrottledUntilCommit() {
- layer_tree_host_->NotifyInputThrottledUntilCommit();
-}
-
-const cc::Layer* RenderWidgetCompositor::GetRootLayer() const {
- return layer_tree_host_->root_layer();
-}
-
-int RenderWidgetCompositor::ScheduleMicroBenchmark(
- const std::string& name,
- std::unique_ptr<base::Value> value,
- const base::Callback<void(std::unique_ptr<base::Value>)>& callback) {
- return layer_tree_host_->ScheduleMicroBenchmark(name, std::move(value),
- callback);
-}
-
-bool RenderWidgetCompositor::SendMessageToMicroBenchmark(
- int id,
- std::unique_ptr<base::Value> value) {
- return layer_tree_host_->SendMessageToMicroBenchmark(id, std::move(value));
-}
-
-void RenderWidgetCompositor::SetViewportSizeAndScale(
- const gfx::Size& device_viewport_size,
- float device_scale_factor,
- const viz::LocalSurfaceId& local_surface_id) {
- layer_tree_host_->SetViewportSizeAndScale(
- device_viewport_size, device_scale_factor, local_surface_id);
-}
-
-void RenderWidgetCompositor::RequestNewLocalSurfaceId() {
- layer_tree_host_->RequestNewLocalSurfaceId();
-}
-
-bool RenderWidgetCompositor::HasNewLocalSurfaceIdRequest() const {
- return layer_tree_host_->new_local_surface_id_request_for_testing();
-}
-
-void RenderWidgetCompositor::SetViewportVisibleRect(
- const gfx::Rect& visible_rect) {
- layer_tree_host_->SetViewportVisibleRect(visible_rect);
-}
-
-viz::FrameSinkId RenderWidgetCompositor::GetFrameSinkId() {
- return frame_sink_id_;
-}
-
-void RenderWidgetCompositor::SetRootLayer(scoped_refptr<cc::Layer> layer) {
- layer_tree_host_->SetRootLayer(std::move(layer));
-}
-
-void RenderWidgetCompositor::ClearRootLayer() {
- layer_tree_host_->SetRootLayer(nullptr);
-}
-
-cc::AnimationHost* RenderWidgetCompositor::CompositorAnimationHost() {
- return animation_host_.get();
-}
-
-blink::WebSize RenderWidgetCompositor::GetViewportSize() const {
- return layer_tree_host_->device_viewport_size();
-}
-
-blink::WebFloatPoint RenderWidgetCompositor::adjustEventPointForPinchZoom(
- const blink::WebFloatPoint& point) const {
- return point;
-}
-
-void RenderWidgetCompositor::SetBackgroundColor(SkColor color) {
- layer_tree_host_->set_background_color(color);
-}
-
-void RenderWidgetCompositor::SetVisible(bool visible) {
- if (never_visible_)
- return;
-
- layer_tree_host_->SetVisible(visible);
-
- if (visible && layer_tree_frame_sink_request_failed_while_invisible_)
- DidFailToInitializeLayerTreeFrameSink();
-}
-
-void RenderWidgetCompositor::SetPageScaleFactorAndLimits(
- float page_scale_factor,
- float minimum,
- float maximum) {
- layer_tree_host_->SetPageScaleFactorAndLimits(page_scale_factor, minimum,
- maximum);
-}
-
-void RenderWidgetCompositor::StartPageScaleAnimation(
- const blink::WebPoint& destination,
- bool use_anchor,
- float new_page_scale,
- double duration_sec) {
- base::TimeDelta duration = base::TimeDelta::FromMicroseconds(
- duration_sec * base::Time::kMicrosecondsPerSecond);
- layer_tree_host_->StartPageScaleAnimation(
- gfx::Vector2d(destination.x, destination.y), use_anchor, new_page_scale,
- duration);
-}
-
-bool RenderWidgetCompositor::HasPendingPageScaleAnimation() const {
- return layer_tree_host_->HasPendingPageScaleAnimation();
-}
-
-void RenderWidgetCompositor::HeuristicsForGpuRasterizationUpdated(
- bool matches_heuristics) {
- layer_tree_host_->SetHasGpuRasterizationTrigger(matches_heuristics);
-}
-
-void RenderWidgetCompositor::SetNeedsBeginFrame() {
- layer_tree_host_->SetNeedsAnimate();
-}
-
-void RenderWidgetCompositor::DidStopFlinging() {
- layer_tree_host_->DidStopFlinging();
-}
-
-void RenderWidgetCompositor::RegisterViewportLayers(
- const blink::WebLayerTreeView::ViewportLayers& layers) {
- cc::LayerTreeHost::ViewportLayers viewport_layers;
- // TODO(bokan): This check can probably be removed now, but it looks
- // like overscroll elasticity may still be nullptr until VisualViewport
- // registers its layers.
- if (layers.overscroll_elasticity) {
- viewport_layers.overscroll_elasticity = layers.overscroll_elasticity;
- }
- viewport_layers.page_scale = layers.page_scale;
- if (layers.inner_viewport_container) {
- viewport_layers.inner_viewport_container = layers.inner_viewport_container;
- }
- if (layers.outer_viewport_container) {
- viewport_layers.outer_viewport_container = layers.outer_viewport_container;
- }
- viewport_layers.inner_viewport_scroll = layers.inner_viewport_scroll;
- // TODO(bokan): This check can probably be removed now, but it looks
- // like overscroll elasticity may still be nullptr until VisualViewport
- // registers its layers.
- if (layers.outer_viewport_scroll) {
- viewport_layers.outer_viewport_scroll = layers.outer_viewport_scroll;
- }
- layer_tree_host_->RegisterViewportLayers(viewport_layers);
-}
-
-void RenderWidgetCompositor::ClearViewportLayers() {
- layer_tree_host_->RegisterViewportLayers(cc::LayerTreeHost::ViewportLayers());
-}
-
-void RenderWidgetCompositor::RegisterSelection(
- const blink::WebSelection& selection) {
- layer_tree_host_->RegisterSelection(ConvertFromWebSelection(selection));
-}
-
-void RenderWidgetCompositor::ClearSelection() {
- cc::LayerSelection empty_selection;
- layer_tree_host_->RegisterSelection(empty_selection);
-}
-
-void RenderWidgetCompositor::SetMutatorClient(
- std::unique_ptr<cc::LayerTreeMutator> client) {
- TRACE_EVENT0("cc", "RenderWidgetCompositor::setMutatorClient");
- layer_tree_host_->SetLayerTreeMutator(std::move(client));
-}
-
-void RenderWidgetCompositor::ForceRecalculateRasterScales() {
- layer_tree_host_->SetNeedsRecalculateRasterScales();
-}
-
-static_assert(static_cast<cc::EventListenerClass>(
- blink::WebEventListenerClass::kTouchStartOrMove) ==
- cc::EventListenerClass::kTouchStartOrMove,
- "EventListenerClass and WebEventListenerClass enums must match");
-static_assert(static_cast<cc::EventListenerClass>(
- blink::WebEventListenerClass::kMouseWheel) ==
- cc::EventListenerClass::kMouseWheel,
- "EventListenerClass and WebEventListenerClass enums must match");
-
-static_assert(static_cast<cc::EventListenerProperties>(
- blink::WebEventListenerProperties::kNothing) ==
- cc::EventListenerProperties::kNone,
- "EventListener and WebEventListener enums must match");
-static_assert(static_cast<cc::EventListenerProperties>(
- blink::WebEventListenerProperties::kPassive) ==
- cc::EventListenerProperties::kPassive,
- "EventListener and WebEventListener enums must match");
-static_assert(static_cast<cc::EventListenerProperties>(
- blink::WebEventListenerProperties::kBlocking) ==
- cc::EventListenerProperties::kBlocking,
- "EventListener and WebEventListener enums must match");
-static_assert(static_cast<cc::EventListenerProperties>(
- blink::WebEventListenerProperties::kBlockingAndPassive) ==
- cc::EventListenerProperties::kBlockingAndPassive,
- "EventListener and WebEventListener enums must match");
-
-void RenderWidgetCompositor::SetEventListenerProperties(
- blink::WebEventListenerClass eventClass,
- blink::WebEventListenerProperties properties) {
- layer_tree_host_->SetEventListenerProperties(
- static_cast<cc::EventListenerClass>(eventClass),
- static_cast<cc::EventListenerProperties>(properties));
-}
-
-blink::WebEventListenerProperties
-RenderWidgetCompositor::EventListenerProperties(
- blink::WebEventListenerClass event_class) const {
- return static_cast<blink::WebEventListenerProperties>(
- layer_tree_host_->event_listener_properties(
- static_cast<cc::EventListenerClass>(event_class)));
-}
-
-void RenderWidgetCompositor::SetHaveScrollEventHandlers(bool has_handlers) {
- layer_tree_host_->SetHaveScrollEventHandlers(has_handlers);
-}
-
-bool RenderWidgetCompositor::HaveScrollEventHandlers() const {
- return layer_tree_host_->have_scroll_event_handlers();
-}
-
-bool RenderWidgetCompositor::CompositeIsSynchronous() const {
- if (!threaded_) {
- DCHECK(!layer_tree_host_->GetSettings().single_thread_proxy_scheduler);
- return true;
- }
- return false;
-}
-
-void RenderWidgetCompositor::LayoutAndPaintAsync(base::OnceClosure callback) {
- DCHECK(layout_and_paint_async_callback_.is_null());
- layout_and_paint_async_callback_ = std::move(callback);
-
- if (CompositeIsSynchronous()) {
- // The LayoutAndPaintAsyncCallback is invoked in WillCommit, which is
- // dispatched after layout and paint for all compositing modes.
- const bool raster = false;
- layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&RenderWidgetCompositor::SynchronouslyComposite,
- weak_factory_.GetWeakPtr(), raster, nullptr));
- } else {
- layer_tree_host_->SetNeedsCommit();
- }
-}
-
-void RenderWidgetCompositor::SetLayerTreeFrameSink(
- std::unique_ptr<cc::LayerTreeFrameSink> layer_tree_frame_sink) {
- if (!layer_tree_frame_sink) {
- DidFailToInitializeLayerTreeFrameSink();
- return;
- }
- layer_tree_host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
-}
-
-void RenderWidgetCompositor::InvokeLayoutAndPaintCallback() {
- if (!layout_and_paint_async_callback_.is_null())
- std::move(layout_and_paint_async_callback_).Run();
-}
-
-void RenderWidgetCompositor::CompositeAndReadbackAsync(
- base::OnceCallback<void(const SkBitmap&)> callback) {
- DCHECK(layout_and_paint_async_callback_.is_null());
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner =
- layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner();
- std::unique_ptr<viz::CopyOutputRequest> request =
- std::make_unique<viz::CopyOutputRequest>(
- viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
- base::BindOnce(
- [](base::OnceCallback<void(const SkBitmap&)> callback,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- std::unique_ptr<viz::CopyOutputResult> result) {
- task_runner->PostTask(
- FROM_HERE,
- base::BindOnce(std::move(callback), result->AsSkBitmap()));
- },
- std::move(callback), std::move(main_thread_task_runner)));
- auto swap_promise =
- delegate_->RequestCopyOfOutputForLayoutTest(std::move(request));
-
- // Force a commit to happen. The temporary copy output request will
- // be installed after layout which will happen as a part of the commit, for
- // widgets that delay the creation of their output surface.
- if (CompositeIsSynchronous()) {
- // Since the composite is required for a pixel dump, we need to raster.
- // Note that we defer queuing the SwapPromise until the requested Composite
- // with rasterization is done.
- const bool raster = true;
- layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&RenderWidgetCompositor::SynchronouslyComposite,
- weak_factory_.GetWeakPtr(), raster,
- std::move(swap_promise)));
- } else {
- // Force a redraw to ensure that the copy swap promise isn't cancelled due
- // to no damage.
- SetNeedsForcedRedraw();
- layer_tree_host_->QueueSwapPromise(std::move(swap_promise));
- layer_tree_host_->SetNeedsCommit();
- }
-}
-
-void RenderWidgetCompositor::SynchronouslyCompositeNoRasterForTesting() {
- SynchronouslyComposite(false /* raster */, nullptr /* swap_promise */);
-}
-
-void RenderWidgetCompositor::CompositeWithRasterForTesting() {
- SynchronouslyComposite(true /* raster */, nullptr /* swap_promise */);
-}
-
-void RenderWidgetCompositor::SynchronouslyComposite(
- bool raster,
- std::unique_ptr<cc::SwapPromise> swap_promise) {
- DCHECK(CompositeIsSynchronous());
- if (!layer_tree_host_->IsVisible())
- return;
-
- if (in_synchronous_compositor_update_) {
- // LayoutTests can use a nested message loop to pump frames while inside a
- // frame, but the compositor does not support this. In this case, we only
- // run blink's lifecycle updates.
- delegate_->BeginMainFrame(base::TimeTicks::Now());
- delegate_->UpdateVisualState(
- cc::LayerTreeHostClient::VisualStateUpdate::kAll);
- return;
- }
-
- if (swap_promise) {
- // Force a redraw to ensure that the copy swap promise isn't cancelled due
- // to no damage.
- SetNeedsForcedRedraw();
- layer_tree_host_->QueueSwapPromise(std::move(swap_promise));
- }
-
- DCHECK(!in_synchronous_compositor_update_);
- base::AutoReset<bool> inside_composite(&in_synchronous_compositor_update_,
- true);
- layer_tree_host_->Composite(base::TimeTicks::Now(), raster);
-}
-
-void RenderWidgetCompositor::SetDeferCommits(bool defer_commits) {
- layer_tree_host_->SetDeferCommits(defer_commits);
-}
-
-int RenderWidgetCompositor::LayerTreeId() const {
- return layer_tree_host_->GetId();
-}
-
-void RenderWidgetCompositor::SetShowFPSCounter(bool show) {
- cc::LayerTreeDebugState debug_state = layer_tree_host_->GetDebugState();
- debug_state.show_fps_counter = show;
- layer_tree_host_->SetDebugState(debug_state);
-}
-
-void RenderWidgetCompositor::SetShowPaintRects(bool show) {
- cc::LayerTreeDebugState debug_state = layer_tree_host_->GetDebugState();
- debug_state.show_paint_rects = show;
- layer_tree_host_->SetDebugState(debug_state);
-}
-
-void RenderWidgetCompositor::SetShowDebugBorders(bool show) {
- cc::LayerTreeDebugState debug_state = layer_tree_host_->GetDebugState();
- if (show)
- debug_state.show_debug_borders.set();
- else
- debug_state.show_debug_borders.reset();
- layer_tree_host_->SetDebugState(debug_state);
-}
-
-void RenderWidgetCompositor::SetShowScrollBottleneckRects(bool show) {
- cc::LayerTreeDebugState debug_state = layer_tree_host_->GetDebugState();
- debug_state.show_touch_event_handler_rects = show;
- debug_state.show_wheel_event_handler_rects = show;
- debug_state.show_non_fast_scrollable_rects = show;
- layer_tree_host_->SetDebugState(debug_state);
-}
-
-void RenderWidgetCompositor::UpdateBrowserControlsState(
- blink::WebBrowserControlsState constraints,
- blink::WebBrowserControlsState current,
- bool animate) {
- layer_tree_host_->UpdateBrowserControlsState(
- ConvertBrowserControlsState(constraints),
- ConvertBrowserControlsState(current), animate);
-}
-
-void RenderWidgetCompositor::SetBrowserControlsHeight(float top_height,
- float bottom_height,
- bool shrink) {
- layer_tree_host_->SetBrowserControlsHeight(top_height, bottom_height, shrink);
-}
-
-void RenderWidgetCompositor::SetBrowserControlsShownRatio(float ratio) {
- layer_tree_host_->SetBrowserControlsShownRatio(ratio);
-}
-
-void RenderWidgetCompositor::RequestDecode(
- const cc::PaintImage& image,
- 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
- // fact that this would make layout tests slow and cause flakiness. However,
- // in this case we actually need a commit to transfer the decode requests to
- // the impl side. So, force a commit to happen.
- if (CompositeIsSynchronous()) {
- const bool raster = true;
- layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&RenderWidgetCompositor::SynchronouslyComposite,
- weak_factory_.GetWeakPtr(), raster, nullptr));
- }
-}
-
-void RenderWidgetCompositor::SetOverscrollBehavior(
- const cc::OverscrollBehavior& behavior) {
- layer_tree_host_->SetOverscrollBehavior(behavior);
-}
-
-void RenderWidgetCompositor::WillBeginMainFrame() {
- delegate_->WillBeginCompositorFrame();
-}
-
-void RenderWidgetCompositor::DidBeginMainFrame() {}
-
-void RenderWidgetCompositor::BeginMainFrame(const viz::BeginFrameArgs& args) {
- compositor_deps_->GetWebMainThreadScheduler()->WillBeginFrame(args);
- delegate_->BeginMainFrame(args.frame_time);
-}
-
-void RenderWidgetCompositor::BeginMainFrameNotExpectedSoon() {
- compositor_deps_->GetWebMainThreadScheduler()->BeginFrameNotExpectedSoon();
-}
-
-void RenderWidgetCompositor::BeginMainFrameNotExpectedUntil(
- base::TimeTicks time) {
- compositor_deps_->GetWebMainThreadScheduler()->BeginMainFrameNotExpectedUntil(
- time);
-}
-
-void RenderWidgetCompositor::UpdateLayerTreeHost(
- VisualStateUpdate requested_update) {
- delegate_->UpdateVisualState(requested_update);
-}
-
-void RenderWidgetCompositor::ApplyViewportDeltas(
- const gfx::Vector2dF& inner_delta,
- const gfx::Vector2dF& outer_delta,
- const gfx::Vector2dF& elastic_overscroll_delta,
- float page_scale,
- float top_controls_delta) {
- delegate_->ApplyViewportDeltas(inner_delta, outer_delta,
- elastic_overscroll_delta, page_scale,
- top_controls_delta);
-}
-
-void RenderWidgetCompositor::RecordWheelAndTouchScrollingCount(
- bool has_scrolled_by_wheel,
- bool has_scrolled_by_touch) {
- delegate_->RecordWheelAndTouchScrollingCount(has_scrolled_by_wheel,
- has_scrolled_by_touch);
-}
-
-void RenderWidgetCompositor::RequestNewLayerTreeFrameSink() {
- // If the host is closing, then no more compositing is possible. This
- // prevents shutdown races between handling the close message and
- // the CreateLayerTreeFrameSink task.
- if (delegate_->IsClosing())
- return;
- delegate_->RequestNewLayerTreeFrameSink(
- base::Bind(&RenderWidgetCompositor::SetLayerTreeFrameSink,
- weak_factory_.GetWeakPtr()));
-}
-
-void RenderWidgetCompositor::DidInitializeLayerTreeFrameSink() {
-}
-
-void RenderWidgetCompositor::DidFailToInitializeLayerTreeFrameSink() {
- if (!layer_tree_host_->IsVisible()) {
- layer_tree_frame_sink_request_failed_while_invisible_ = true;
- return;
- }
- layer_tree_frame_sink_request_failed_while_invisible_ = false;
- layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
- FROM_HERE,
- base::BindOnce(&RenderWidgetCompositor::RequestNewLayerTreeFrameSink,
- weak_factory_.GetWeakPtr()));
-}
-
-void RenderWidgetCompositor::WillCommit() {
- InvokeLayoutAndPaintCallback();
-}
-
-void RenderWidgetCompositor::DidCommit() {
- delegate_->DidCommitCompositorFrame();
- compositor_deps_->GetWebMainThreadScheduler()->DidCommitFrameToCompositor();
-}
-
-void RenderWidgetCompositor::DidCommitAndDrawFrame() {
- delegate_->DidCommitAndDrawCompositorFrame();
-}
-
-void RenderWidgetCompositor::DidReceiveCompositorFrameAck() {
- delegate_->DidReceiveCompositorFrameAck();
-}
-
-void RenderWidgetCompositor::DidCompletePageScaleAnimation() {
- delegate_->DidCompletePageScaleAnimation();
-}
-
-bool RenderWidgetCompositor::IsForSubframe() {
- return is_for_oopif_;
-}
-
-void RenderWidgetCompositor::RequestScheduleAnimation() {
- delegate_->RequestScheduleAnimation();
-}
-
-void RenderWidgetCompositor::DidSubmitCompositorFrame() {}
-
-void RenderWidgetCompositor::DidLoseLayerTreeFrameSink() {}
-
-void RenderWidgetCompositor::SetFrameSinkId(
- const viz::FrameSinkId& frame_sink_id) {
- frame_sink_id_ = frame_sink_id;
-}
-
-void RenderWidgetCompositor::SetRasterColorSpace(
- const gfx::ColorSpace& color_space) {
- layer_tree_host_->SetRasterColorSpace(color_space);
-}
-
-void RenderWidgetCompositor::SetIsForOopif(bool is_for_oopif) {
- is_for_oopif_ = is_for_oopif;
-}
-
-void RenderWidgetCompositor::SetContentSourceId(uint32_t id) {
- layer_tree_host_->SetContentSourceId(id);
-}
-
-void RenderWidgetCompositor::NotifySwapTime(ReportTimeCallback callback) {
- QueueSwapPromise(std::make_unique<ReportTimeSwapPromise>(
- std::move(callback),
- layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()));
-}
-
-void RenderWidgetCompositor::RequestBeginMainFrameNotExpected(bool new_state) {
- layer_tree_host_->RequestBeginMainFrameNotExpected(new_state);
-}
-
-void RenderWidgetCompositor::CreateRenderFrameObserver(
- mojom::RenderFrameMetadataObserverRequest request,
- mojom::RenderFrameMetadataObserverClientPtrInfo client_info) {
- auto render_frame_metadata_observer =
- std::make_unique<RenderFrameMetadataObserverImpl>(std::move(request),
- std::move(client_info));
- layer_tree_host_->SetRenderFrameObserver(
- std::move(render_frame_metadata_observer));
-}
-
-void RenderWidgetCompositor::SetURLForUkm(const GURL& url) {
- layer_tree_host_->SetURLForUkm(url);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/gpu/render_widget_compositor_unittest.cc b/chromium/content/renderer/gpu/render_widget_compositor_unittest.cc
deleted file mode 100644
index b0cd76d9bb5..00000000000
--- a/chromium/content/renderer/gpu/render_widget_compositor_unittest.cc
+++ /dev/null
@@ -1,425 +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/gpu/render_widget_compositor.h"
-
-#include <utility>
-
-#include "base/location.h"
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "build/build_config.h"
-#include "cc/animation/animation_host.h"
-#include "cc/test/fake_layer_tree_frame_sink.h"
-#include "cc/trees/layer_tree_host.h"
-#include "components/viz/common/frame_sinks/copy_output_request.h"
-#include "components/viz/test/test_context_provider.h"
-#include "content/public/common/screen_info.h"
-#include "content/public/test/mock_render_thread.h"
-#include "content/renderer/render_widget.h"
-#include "content/test/fake_compositor_dependencies.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-
-using testing::AllOf;
-using testing::Field;
-
-namespace content {
-namespace {
-
-enum FailureMode {
- NO_FAILURE,
- BIND_CONTEXT_FAILURE,
- GPU_CHANNEL_FAILURE,
-};
-
-class StubRenderWidgetCompositorDelegate
- : public RenderWidgetCompositorDelegate {
- public:
- // RenderWidgetCompositorDelegate implementation.
- void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
- const gfx::Vector2dF& outer_delta,
- const gfx::Vector2dF& elastic_overscroll_delta,
- float page_scale,
- float top_controls_delta) override {}
- void RecordWheelAndTouchScrollingCount(bool has_scrolled_by_wheel,
- bool has_scrolled_by_touch) override {}
- void BeginMainFrame(base::TimeTicks frame_time) override {}
- void RequestNewLayerTreeFrameSink(
- const LayerTreeFrameSinkCallback& callback) override {
- callback.Run(nullptr);
- }
- void DidCommitAndDrawCompositorFrame() override {}
- void DidCommitCompositorFrame() override {}
- void DidCompletePageScaleAnimation() override {}
- void DidReceiveCompositorFrameAck() override {}
- bool IsClosing() const override { return false; }
- void RequestScheduleAnimation() override {}
- void UpdateVisualState(VisualStateUpdate requested_update) override {}
- void WillBeginCompositorFrame() override {}
- std::unique_ptr<cc::SwapPromise> RequestCopyOfOutputForLayoutTest(
- std::unique_ptr<viz::CopyOutputRequest> request) override {
- return nullptr;
- }
-};
-
-class FakeRenderWidgetCompositorDelegate
- : public StubRenderWidgetCompositorDelegate {
- public:
- FakeRenderWidgetCompositorDelegate() = default;
-
- void RequestNewLayerTreeFrameSink(
- const LayerTreeFrameSinkCallback& callback) override {
- // 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 = viz::TestContextProvider::Create();
- if (num_failures_since_last_success_ < num_failures_before_success_) {
- context_provider->UnboundTestContext3d()->loseContextCHROMIUM(
- GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
- }
- callback.Run(
- cc::FakeLayerTreeFrameSink::Create3d(std::move(context_provider)));
- }
-
- 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_failures_since_last_success_ = 0;
- num_successes_ = 0;
- }
-
- void add_success() {
- ++num_successes_;
- num_requests_since_last_success_ = 0;
- num_failures_since_last_success_ = 0;
- }
- int num_successes() const { return num_successes_; }
-
- void add_request() {
- ++num_requests_since_last_success_;
- ++num_requests_;
- }
- int num_requests() const { return num_requests_; }
-
- 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;
- }
- int num_failures_before_success() const {
- return num_failures_before_success_;
- }
-
- 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_failures_since_last_success_ = 0;
- int num_successes_ = 0;
-
- 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.
-// 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.
-class RenderWidgetLayerTreeFrameSink : public RenderWidgetCompositor {
- public:
- RenderWidgetLayerTreeFrameSink(FakeRenderWidgetCompositorDelegate* delegate,
- CompositorDependencies* compositor_deps)
- : RenderWidgetCompositor(delegate, compositor_deps),
- delegate_(delegate) {}
-
- using RenderWidgetCompositor::Initialize;
-
- // Force a new output surface to be created.
- void SynchronousComposite() {
- layer_tree_host()->SetVisible(false);
- layer_tree_host()->ReleaseLayerTreeFrameSink();
- layer_tree_host()->SetVisible(true);
-
- base::TimeTicks some_time;
- layer_tree_host()->Composite(some_time, true /* raster */);
- }
-
- void RequestNewLayerTreeFrameSink() override {
- delegate_->add_request();
- RenderWidgetCompositor::RequestNewLayerTreeFrameSink();
- }
-
- void DidInitializeLayerTreeFrameSink() override {
- RenderWidgetCompositor::DidInitializeLayerTreeFrameSink();
- delegate_->add_success();
- 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
- // reentrantly as a part of RequestNewLayerTreeFrameSink.
- blink::scheduler::GetSingleThreadTaskRunnerForTesting()->PostTask(
- FROM_HERE,
- base::BindOnce(&RenderWidgetLayerTreeFrameSink::SynchronousComposite,
- base::Unretained(this)));
- }
- }
-
- void DidFailToInitializeLayerTreeFrameSink() override {
- 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,
- 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_ = expected_successes;
- break;
- case BIND_CONTEXT_FAILURE:
- case GPU_CHANNEL_FAILURE:
- expected_requests_ = num_tries * std::max(1, expected_successes);
- break;
- }
- }
-
- 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;
-
- DISALLOW_COPY_AND_ASSIGN(RenderWidgetLayerTreeFrameSink);
-};
-
-class RenderWidgetLayerTreeFrameSinkTest : public testing::Test {
- public:
- RenderWidgetLayerTreeFrameSinkTest()
- : render_widget_compositor_(&compositor_delegate_, &compositor_deps_) {
- auto animation_host = cc::AnimationHost::CreateMainInstance();
-
- ScreenInfo dummy_screen_info;
- auto layer_tree_host = RenderWidgetCompositor::CreateLayerTreeHost(
- &render_widget_compositor_, &render_widget_compositor_,
- animation_host.get(), &compositor_deps_, dummy_screen_info);
- render_widget_compositor_.Initialize(std::move(layer_tree_host),
- std::move(animation_host));
- }
-
- void RunTest(int expected_successes, FailureMode failure_mode) {
- compositor_delegate_.Reset();
- // 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);
- blink::scheduler::GetSingleThreadTaskRunnerForTesting()->PostTask(
- FROM_HERE,
- base::BindOnce(&RenderWidgetLayerTreeFrameSink::SynchronousComposite,
- base::Unretained(&render_widget_compositor_)));
- run_loop.Run();
- }
-
- protected:
- base::MessageLoop ye_olde_message_loope_;
- MockRenderThread render_thread_;
- FakeCompositorDependencies compositor_deps_;
- FakeRenderWidgetCompositorDelegate compositor_delegate_;
- RenderWidgetLayerTreeFrameSink render_widget_compositor_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(RenderWidgetLayerTreeFrameSinkTest);
-};
-
-TEST_F(RenderWidgetLayerTreeFrameSinkTest, SucceedOnce) {
- 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(2, NO_FAILURE);
-}
-
-TEST_F(RenderWidgetLayerTreeFrameSinkTest, SucceedTwice_AfterNullChannel) {
- RunTest(2, 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, FailWithLostContext) {
- RunTest(0, BIND_CONTEXT_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;
- auto layer_tree_host = RenderWidgetCompositor::CreateLayerTreeHost(
- &render_widget_compositor, &render_widget_compositor,
- animation_host.get(), &compositor_deps, 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());
- }
-}
-
-// Verify desktop memory limit calculations.
-#if !defined(OS_ANDROID)
-TEST(RenderWidgetCompositorTest, IgnoreGivenMemoryPolicy) {
- auto policy = RenderWidgetCompositor::GetGpuMemoryPolicy(
- cc::ManagedMemoryPolicy(256), ScreenInfo());
- EXPECT_EQ(512u * 1024u * 1024u, policy.bytes_limit_when_visible);
- EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
- policy.priority_cutoff_when_visible);
-}
-
-TEST(RenderWidgetCompositorTest, LargeScreensUseMoreMemory) {
- ScreenInfo screen_info;
-
- screen_info.rect = gfx::Rect(4096, 2160);
- screen_info.device_scale_factor = 1.f;
- auto policy = RenderWidgetCompositor::GetGpuMemoryPolicy(
- cc::ManagedMemoryPolicy(256), screen_info);
- EXPECT_EQ(2u * 512u * 1024u * 1024u, policy.bytes_limit_when_visible);
- EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
- policy.priority_cutoff_when_visible);
-
- screen_info.rect = gfx::Rect(2048, 1080);
- screen_info.device_scale_factor = 2.f;
- policy = RenderWidgetCompositor::GetGpuMemoryPolicy(
- cc::ManagedMemoryPolicy(256), screen_info);
- EXPECT_EQ(2u * 512u * 1024u * 1024u, policy.bytes_limit_when_visible);
- EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
- policy.priority_cutoff_when_visible);
-}
-#endif // !defined(OS_ANDROID)
-
-} // namespace
-} // namespace content
diff --git a/chromium/content/renderer/image_capture/image_capture_frame_grabber.cc b/chromium/content/renderer/image_capture/image_capture_frame_grabber.cc
index c5e6515bb19..58c58f005e2 100644
--- a/chromium/content/renderer/image_capture/image_capture_frame_grabber.cc
+++ b/chromium/content/renderer/image_capture/image_capture_frame_grabber.cc
@@ -79,7 +79,7 @@ void ImageCaptureFrameGrabber::SingleShotFrameHandler::OnVideoFrameOnIOThread(
return;
}
- const uint32 destination_pixel_format =
+ const uint32_t destination_pixel_format =
(kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR
: libyuv::FOURCC_ARGB;
@@ -89,7 +89,7 @@ void ImageCaptureFrameGrabber::SingleShotFrameHandler::OnVideoFrameOnIOThread(
frame->stride(media::VideoFrame::kUPlane),
frame->visible_data(media::VideoFrame::kVPlane),
frame->stride(media::VideoFrame::kVPlane),
- static_cast<uint8*>(pixmap.writable_addr()),
+ static_cast<uint8_t*>(pixmap.writable_addr()),
pixmap.width() * 4, pixmap.width(), pixmap.height(),
destination_pixel_format);
@@ -98,7 +98,7 @@ void ImageCaptureFrameGrabber::SingleShotFrameHandler::OnVideoFrameOnIOThread(
// This function copies any plane into the alpha channel of an ARGB image.
libyuv::ARGBCopyYToAlpha(frame->visible_data(media::VideoFrame::kAPlane),
frame->stride(media::VideoFrame::kAPlane),
- static_cast<uint8*>(pixmap.writable_addr()),
+ static_cast<uint8_t*>(pixmap.writable_addr()),
pixmap.width() * 4, pixmap.width(),
pixmap.height());
}
@@ -115,7 +115,7 @@ ImageCaptureFrameGrabber::~ImageCaptureFrameGrabber() {
void ImageCaptureFrameGrabber::GrabFrame(
blink::WebMediaStreamTrack* track,
- WebImageCaptureGrabFrameCallbacks* callbacks) {
+ std::unique_ptr<blink::WebImageCaptureGrabFrameCallbacks> callbacks) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!!callbacks);
@@ -128,8 +128,8 @@ void ImageCaptureFrameGrabber::GrabFrame(
return;
}
- ScopedWebCallbacks<WebImageCaptureGrabFrameCallbacks> scoped_callbacks =
- make_scoped_web_callbacks(callbacks, base::Bind(&OnError));
+ auto scoped_callbacks = blink::MakeScopedWebCallbacks(
+ std::move(callbacks), base::BindOnce(&OnError));
// A SingleShotFrameHandler is bound and given to the Track to guarantee that
// only one VideoFrame is converted and delivered to OnSkImage(), otherwise
@@ -149,7 +149,8 @@ void ImageCaptureFrameGrabber::GrabFrame(
}
void ImageCaptureFrameGrabber::OnSkImage(
- ScopedWebCallbacks<blink::WebImageCaptureGrabFrameCallbacks> callbacks,
+ blink::ScopedWebCallbacks<blink::WebImageCaptureGrabFrameCallbacks>
+ callbacks,
sk_sp<SkImage> image) {
DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/chromium/content/renderer/image_capture/image_capture_frame_grabber.h b/chromium/content/renderer/image_capture/image_capture_frame_grabber.h
index 99356ce9a24..547cc74f507 100644
--- a/chromium/content/renderer/image_capture/image_capture_frame_grabber.h
+++ b/chromium/content/renderer/image_capture/image_capture_frame_grabber.h
@@ -5,13 +5,15 @@
#ifndef CONTENT_RENDERER_IMAGE_CAPTURE_IMAGE_CAPTURE_FRAME_GRABBER_H_
#define CONTENT_RENDERER_IMAGE_CAPTURE_IMAGE_CAPTURE_FRAME_GRABBER_H_
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
-#include "content/child/scoped_web_callbacks.h"
#include "content/common/content_export.h"
#include "content/public/renderer/media_stream_video_sink.h"
+#include "third_party/blink/public/platform/scoped_web_callbacks.h"
#include "third_party/blink/public/platform/web_image_capture_frame_grabber.h"
namespace blink {
@@ -36,15 +38,16 @@ class CONTENT_EXPORT ImageCaptureFrameGrabber final
// blink::WebImageCaptureFrameGrabber implementation.
void GrabFrame(blink::WebMediaStreamTrack* track,
- blink::WebImageCaptureGrabFrameCallbacks* callbacks) override;
+ std::unique_ptr<blink::WebImageCaptureGrabFrameCallbacks>
+ callbacks) override;
private:
// Internal class to receive, convert and forward one frame.
class SingleShotFrameHandler;
- void OnSkImage(
- ScopedWebCallbacks<blink::WebImageCaptureGrabFrameCallbacks> callbacks,
- sk_sp<SkImage> image);
+ void OnSkImage(blink::ScopedWebCallbacks<
+ blink::WebImageCaptureGrabFrameCallbacks> callbacks,
+ sk_sp<SkImage> image);
// Flag to indicate that there is a frame grabbing in progress.
bool frame_grab_in_progress_;
diff --git a/chromium/content/renderer/indexed_db/OWNERS b/chromium/content/renderer/indexed_db/OWNERS
index bbe466e537d..a740487227f 100644
--- a/chromium/content/renderer/indexed_db/OWNERS
+++ b/chromium/content/renderer/indexed_db/OWNERS
@@ -1 +1,4 @@
file://content/browser/indexed_db/OWNERS
+
+# TEAM: storage-dev@chromium.org
+# COMPONENT: Blink>Storage>IndexedDB
diff --git a/chromium/content/renderer/input/frame_input_handler_impl.cc b/chromium/content/renderer/input/frame_input_handler_impl.cc
index d4293d0a857..206f5181794 100644
--- a/chromium/content/renderer/input/frame_input_handler_impl.cc
+++ b/chromium/content/renderer/input/frame_input_handler_impl.cc
@@ -10,7 +10,7 @@
#include "base/debug/stack_trace.h"
#include "base/logging.h"
#include "content/common/input/ime_text_span_conversions.h"
-#include "content/renderer/gpu/render_widget_compositor.h"
+#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/ime_event_guard.h"
#include "content/renderer/input/widget_input_handler_manager.h"
#include "content/renderer/render_thread_impl.h"
@@ -280,11 +280,11 @@ void FrameInputHandlerImpl::SelectRange(const gfx::Point& base,
if (!render_frame_)
return;
- RenderViewImpl* render_view = render_frame_->render_view();
+ RenderWidget* window_widget = render_frame_->render_view()->GetWidget();
HandlingState handling_state(render_frame_, UpdateState::kIsSelectingRange);
render_frame_->GetWebFrame()->SelectRange(
- render_view->ConvertWindowPointToViewport(base),
- render_view->ConvertWindowPointToViewport(extent));
+ window_widget->ConvertWindowPointToViewport(base),
+ window_widget->ConvertWindowPointToViewport(extent));
}
void FrameInputHandlerImpl::AdjustSelectionByCharacterOffset(
@@ -334,7 +334,8 @@ void FrameInputHandlerImpl::MoveRangeSelectionExtent(const gfx::Point& extent) {
return;
HandlingState handling_state(render_frame_, UpdateState::kIsSelectingRange);
render_frame_->GetWebFrame()->MoveRangeSelectionExtent(
- render_frame_->render_view()->ConvertWindowPointToViewport(extent));
+ render_frame_->render_view()->GetWidget()->ConvertWindowPointToViewport(
+ extent));
}
void FrameInputHandlerImpl::ScrollFocusedEditableNodeIntoRect(
@@ -362,9 +363,9 @@ void FrameInputHandlerImpl::MoveCaret(const gfx::Point& point) {
if (!render_frame_)
return;
- RenderViewImpl* render_view = render_frame_->render_view();
render_frame_->GetWebFrame()->MoveCaretSelection(
- render_view->ConvertWindowPointToViewport(point));
+ render_frame_->render_view()->GetWidget()->ConvertWindowPointToViewport(
+ point));
}
void FrameInputHandlerImpl::GetWidgetInputHandler(
diff --git a/chromium/content/renderer/input/input_event_prediction.cc b/chromium/content/renderer/input/input_event_prediction.cc
index 89636c9736d..5b0579d3606 100644
--- a/chromium/content/renderer/input/input_event_prediction.cc
+++ b/chromium/content/renderer/input/input_event_prediction.cc
@@ -5,8 +5,12 @@
#include "content/renderer/input/input_event_prediction.h"
#include "base/feature_list.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/field_trial_params.h"
#include "content/public/common/content_features.h"
#include "ui/events/blink/prediction/empty_predictor.h"
+#include "ui/events/blink/prediction/kalman_predictor.h"
+#include "ui/events/blink/prediction/least_squares_predictor.h"
using blink::WebInputEvent;
using blink::WebMouseEvent;
@@ -18,14 +22,23 @@ namespace content {
namespace {
-std::unique_ptr<ui::InputPredictor> SetUpPredictor() {
- return std::make_unique<ui::EmptyPredictor>();
-}
+constexpr char kPredictor[] = "predictor";
+constexpr char kInputEventPredictorTypeLsq[] = "lsq";
+constexpr char kInputEventPredictorTypeKalman[] = "kalman";
} // namespace
InputEventPrediction::InputEventPrediction() {
- mouse_predictor_ = SetUpPredictor();
+ std::string predictor_type = GetFieldTrialParamValueByFeature(
+ features::kResamplingInputEvents, kPredictor);
+ if (predictor_type == kInputEventPredictorTypeLsq)
+ selected_predictor_type_ = PredictorType::kLsq;
+ else if (predictor_type == kInputEventPredictorTypeKalman)
+ selected_predictor_type_ = PredictorType::kKalman;
+ else
+ selected_predictor_type_ = PredictorType::kEmpty;
+
+ mouse_predictor_ = CreatePredictor();
}
InputEventPrediction::~InputEventPrediction() {}
@@ -54,6 +67,18 @@ void InputEventPrediction::HandleEvents(
}
}
+std::unique_ptr<ui::InputPredictor> InputEventPrediction::CreatePredictor()
+ const {
+ switch (selected_predictor_type_) {
+ case PredictorType::kEmpty:
+ return std::make_unique<ui::EmptyPredictor>();
+ case PredictorType::kLsq:
+ return std::make_unique<ui::LeastSquaresPredictor>();
+ case PredictorType::kKalman:
+ return std::make_unique<ui::KalmanPredictor>();
+ }
+}
+
void InputEventPrediction::UpdatePrediction(const WebInputEvent& event) {
if (WebInputEvent::IsTouchEventType(event.GetType())) {
DCHECK(event.GetType() == WebInputEvent::kTouchMove);
@@ -110,8 +135,7 @@ void InputEventPrediction::ResetPredictor(const WebInputEvent& event) {
void InputEventPrediction::UpdateSinglePointer(
const WebPointerProperties& event,
base::TimeTicks event_time) {
- ui::InputPredictor::InputData data = {event.PositionInWidget().x,
- event.PositionInWidget().y, event_time};
+ ui::InputPredictor::InputData data = {event.PositionInWidget(), event_time};
if (event.pointer_type == WebPointerProperties::PointerType::kMouse)
mouse_predictor_->Update(data);
else {
@@ -119,7 +143,10 @@ void InputEventPrediction::UpdateSinglePointer(
if (predictor != pointer_id_predictor_map_.end()) {
predictor->second->Update(data);
} else {
- pointer_id_predictor_map_.insert({event.id, SetUpPredictor()});
+ // Workaround for GLIBC C++ < 7.3 that fails to insert with braces
+ // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82522
+ auto pair = std::make_pair(event.id, CreatePredictor());
+ pointer_id_predictor_map_.insert(std::move(pair));
pointer_id_predictor_map_[event.id]->Update(data);
}
}
@@ -131,7 +158,7 @@ bool InputEventPrediction::ResampleSinglePointer(base::TimeTicks frame_time,
if (event->pointer_type == WebPointerProperties::PointerType::kMouse) {
if (mouse_predictor_->HasPrediction() &&
mouse_predictor_->GeneratePrediction(frame_time, &predict_result)) {
- event->SetPositionInWidget(predict_result.pos_x, predict_result.pos_y);
+ event->SetPositionInWidget(predict_result.pos);
return true;
}
} else {
@@ -142,7 +169,7 @@ bool InputEventPrediction::ResampleSinglePointer(base::TimeTicks frame_time,
if (predictor != pointer_id_predictor_map_.end() &&
predictor->second->HasPrediction() &&
predictor->second->GeneratePrediction(frame_time, &predict_result)) {
- event->SetPositionInWidget(predict_result.pos_x, predict_result.pos_y);
+ event->SetPositionInWidget(predict_result.pos);
return true;
}
}
diff --git a/chromium/content/renderer/input/input_event_prediction.h b/chromium/content/renderer/input/input_event_prediction.h
index 59a473e977d..3bcc9ae3a58 100644
--- a/chromium/content/renderer/input/input_event_prediction.h
+++ b/chromium/content/renderer/input/input_event_prediction.h
@@ -28,7 +28,14 @@ class CONTENT_EXPORT InputEventPrediction {
base::TimeTicks frame_time,
blink::WebInputEvent* event);
+ // Initialize predictor for different pointer.
+ std::unique_ptr<ui::InputPredictor> CreatePredictor() const;
+
private:
+ friend class InputEventPredictionTest;
+
+ enum class PredictorType { kEmpty, kLsq, kKalman };
+
// The following three function is for handling multiple TouchPoints in a
// WebTouchEvent. They should be more neat when WebTouchEvent is elimated.
// Cast events from WebInputEvent to WebPointerProperties. Call
@@ -52,12 +59,14 @@ class CONTENT_EXPORT InputEventPrediction {
// predictor, for other pointer type, remove it from mapping.
void ResetSinglePredictor(const WebPointerProperties& event);
- friend class InputEventPredictionTest;
-
std::unordered_map<ui::PointerId, std::unique_ptr<ui::InputPredictor>>
pointer_id_predictor_map_;
std::unique_ptr<ui::InputPredictor> mouse_predictor_;
+ // Store the field trial parameter used for choosing different types of
+ // predictor.
+ PredictorType selected_predictor_type_;
+
DISALLOW_COPY_AND_ASSIGN(InputEventPrediction);
};
diff --git a/chromium/content/renderer/input/input_event_prediction_unittest.cc b/chromium/content/renderer/input/input_event_prediction_unittest.cc
index a0d5a498031..04ef06741ce 100644
--- a/chromium/content/renderer/input/input_event_prediction_unittest.cc
+++ b/chromium/content/renderer/input/input_event_prediction_unittest.cc
@@ -69,8 +69,8 @@ TEST_F(InputEventPredictionTest, MouseEvent) {
HandleEvents(mouse_move);
EXPECT_EQ(GetPredictorMapSize(), 0);
EXPECT_TRUE(GetPrediction(mouse_move, &last_point));
- EXPECT_EQ(last_point.pos_x, 10);
- EXPECT_EQ(last_point.pos_y, 10);
+ EXPECT_EQ(last_point.pos.x(), 10);
+ EXPECT_EQ(last_point.pos.y(), 10);
WebMouseEvent mouse_down = SyntheticWebMouseEventBuilder::Build(
WebInputEvent::kMouseDown, 10, 10, 0);
@@ -93,8 +93,8 @@ TEST_F(InputEventPredictionTest, SingleTouchPoint) {
HandleEvents(touch_event);
EXPECT_EQ(GetPredictorMapSize(), 1);
EXPECT_TRUE(GetPrediction(touch_event.touches[0], &last_point));
- EXPECT_EQ(last_point.pos_x, 11);
- EXPECT_EQ(last_point.pos_y, 12);
+ EXPECT_EQ(last_point.pos.x(), 11);
+ EXPECT_EQ(last_point.pos.y(), 12);
touch_event.ReleasePoint(0);
HandleEvents(touch_event);
@@ -111,8 +111,8 @@ TEST_F(InputEventPredictionTest, MouseEventTypePen) {
HandleEvents(pen_move);
EXPECT_EQ(GetPredictorMapSize(), 1);
EXPECT_TRUE(GetPrediction(pen_move, &last_point));
- EXPECT_EQ(last_point.pos_x, 10);
- EXPECT_EQ(last_point.pos_y, 10);
+ EXPECT_EQ(last_point.pos.x(), 10);
+ EXPECT_EQ(last_point.pos.y(), 10);
WebMouseEvent pen_leave = SyntheticWebMouseEventBuilder::Build(
WebInputEvent::kMouseLeave, 10, 10, 0,
@@ -145,12 +145,12 @@ TEST_F(InputEventPredictionTest, MultipleTouchPoint) {
ui::InputPredictor::InputData last_point;
EXPECT_TRUE(GetPrediction(touch_event.touches[0], &last_point));
- EXPECT_EQ(last_point.pos_x, 11);
- EXPECT_EQ(last_point.pos_y, 12);
+ EXPECT_EQ(last_point.pos.x(), 11);
+ EXPECT_EQ(last_point.pos.y(), 12);
EXPECT_TRUE(GetPrediction(touch_event.touches[1], &last_point));
- EXPECT_EQ(last_point.pos_x, 25);
- EXPECT_EQ(last_point.pos_y, 25);
+ EXPECT_EQ(last_point.pos.x(), 25);
+ EXPECT_EQ(last_point.pos.y(), 25);
touch_event.ReleasePoint(0);
HandleEvents(touch_event);
@@ -210,4 +210,4 @@ TEST_F(InputEventPredictionTest, TouchScrollStartedRemoveAllTouchPoints) {
EXPECT_EQ(GetPredictorMapSize(), 0);
}
-} // namespace content \ No newline at end of file
+} // namespace content
diff --git a/chromium/content/renderer/input/main_thread_event_queue.cc b/chromium/content/renderer/input/main_thread_event_queue.cc
index 7db4e91d2e5..3503cbbd5d2 100644
--- a/chromium/content/renderer/input/main_thread_event_queue.cc
+++ b/chromium/content/renderer/input/main_thread_event_queue.cc
@@ -209,7 +209,7 @@ MainThreadEventQueue::SharedState::~SharedState() {}
MainThreadEventQueue::MainThreadEventQueue(
MainThreadEventQueueClient* client,
const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler,
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler,
bool allow_raf_aligned_input)
: client_(client),
last_touch_start_forced_nonblocking_due_to_fling_(false),
@@ -526,6 +526,8 @@ void MainThreadEventQueue::SetNeedsMainFrame() {
}
if (client_)
client_->SetNeedsMainFrame();
+ if (main_thread_scheduler_)
+ main_thread_scheduler_->OnMainFrameRequestedForInput();
return;
}
diff --git a/chromium/content/renderer/input/main_thread_event_queue.h b/chromium/content/renderer/input/main_thread_event_queue.h
index cf767c67a3d..f1a690f58d5 100644
--- a/chromium/content/renderer/input/main_thread_event_queue.h
+++ b/chromium/content/renderer/input/main_thread_event_queue.h
@@ -16,7 +16,7 @@
#include "content/renderer/input/input_event_prediction.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/blink/public/platform/scheduler/web_main_thread_scheduler.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_input_event.h"
#include "ui/events/blink/did_overscroll_params.h"
#include "ui/events/blink/web_input_event_traits.h"
@@ -85,7 +85,7 @@ class CONTENT_EXPORT MainThreadEventQueue
MainThreadEventQueue(
MainThreadEventQueueClient* client,
const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler,
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler,
bool allow_raf_aligned_input);
// Called once the compositor has handled |event| and indicated that it is
@@ -162,7 +162,7 @@ class CONTENT_EXPORT MainThreadEventQueue
SharedState shared_state_;
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler_;
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler_;
base::OneShotTimer raf_fallback_timer_;
bool use_raf_fallback_timer_;
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 7702e79d9a7..ce7c9a17b21 100644
--- a/chromium/content/renderer/input/main_thread_event_queue_task.h
+++ b/chromium/content/renderer/input/main_thread_event_queue_task.h
@@ -6,7 +6,7 @@
#define CONTENT_RENDERER_INPUT_MAIN_THREAD_EVENT_QUEUE_TASK_H_
#include "content/public/common/input_event_ack_state.h"
-#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_input_event.h"
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 ca425a44022..e4636407871 100644
--- a/chromium/content/renderer/input/render_widget_input_handler.cc
+++ b/chromium/content/renderer/input/render_widget_input_handler.cc
@@ -17,15 +17,14 @@
#include "content/common/input/input_event_ack.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/input_event_ack_state.h"
-#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "content/public/renderer/render_frame.h"
-#include "content/renderer/gpu/render_widget_compositor.h"
+#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/ime_event_guard.h"
#include "content/renderer/input/render_widget_input_handler_delegate.h"
#include "content/renderer/render_frame_proxy.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_widget.h"
-#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_float_point.h"
#include "third_party/blink/public/platform/web_float_size.h"
#include "third_party/blink/public/platform/web_gesture_event.h"
@@ -194,7 +193,7 @@ RenderWidgetInputHandler::~RenderWidgetInputHandler() {}
viz::FrameSinkId RenderWidgetInputHandler::GetFrameSinkIdAtPoint(
const gfx::Point& point) {
gfx::PointF point_in_pixel(point);
- if (IsUseZoomForDSFEnabled()) {
+ if (widget_->compositor_deps()->IsUseZoomForDSFEnabled()) {
point_in_pixel = gfx::ConvertPointToPixel(
widget_->GetOriginalScreenInfo().device_scale_factor, point_in_pixel);
}
@@ -305,10 +304,10 @@ void RenderWidgetInputHandler::HandleInputEvent(
ui::LatencyInfo swap_latency_info(latency_info);
swap_latency_info.AddLatencyNumber(
- ui::LatencyComponentType::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0);
- if (widget_->compositor()) {
+ ui::LatencyComponentType::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT);
+ if (widget_->layer_tree_view()) {
latency_info_swap_promise_monitor =
- widget_->compositor()->CreateLatencyInfoSwapPromiseMonitor(
+ widget_->layer_tree_view()->CreateLatencyInfoSwapPromiseMonitor(
&swap_latency_info);
}
diff --git a/chromium/content/renderer/input/widget_input_handler_impl.cc b/chromium/content/renderer/input/widget_input_handler_impl.cc
index dd01e03a9f1..09384eed9c0 100644
--- a/chromium/content/renderer/input/widget_input_handler_impl.cc
+++ b/chromium/content/renderer/input/widget_input_handler_impl.cc
@@ -10,13 +10,13 @@
#include "base/logging.h"
#include "content/common/input/ime_text_span_conversions.h"
#include "content/common/input_messages.h"
-#include "content/renderer/gpu/render_widget_compositor.h"
+#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/ime_event_guard.h"
#include "content/renderer/input/widget_input_handler_manager.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_widget.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
#include "third_party/blink/public/platform/web_keyboard_event.h"
#include "third_party/blink/public/web/web_local_frame.h"
diff --git a/chromium/content/renderer/input/widget_input_handler_manager.cc b/chromium/content/renderer/input/widget_input_handler_manager.cc
index fa74edacbc2..d76df765d91 100644
--- a/chromium/content/renderer/input/widget_input_handler_manager.cc
+++ b/chromium/content/renderer/input/widget_input_handler_manager.cc
@@ -9,13 +9,13 @@
#include "base/bind.h"
#include "base/logging.h"
#include "content/common/input_messages.h"
-#include "content/renderer/gpu/render_widget_compositor.h"
+#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/ime_event_guard.h"
#include "content/renderer/input/widget_input_handler_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/render_widget.h"
#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_coalesced_input_event.h"
#include "third_party/blink/public/platform/web_keyboard_event.h"
#include "third_party/blink/public/web/web_local_frame.h"
@@ -23,7 +23,7 @@
#if defined(OS_ANDROID)
#include "content/public/common/content_client.h"
-#include "content/renderer/android/synchronous_compositor_proxy_mojo.h"
+#include "content/renderer/android/synchronous_compositor_proxy.h"
#include "content/renderer/android/synchronous_compositor_registry.h"
#endif
@@ -80,14 +80,14 @@ class SynchronousCompositorProxyRegistry
void CreateProxy(ui::SynchronousInputHandlerProxy* handler) {
DCHECK(compositor_task_runner_->BelongsToCurrentThread());
- proxy_ = std::make_unique<SynchronousCompositorProxyMojo>(handler);
+ proxy_ = std::make_unique<SynchronousCompositorProxy>(handler);
proxy_->Init();
if (sink_)
proxy_->SetLayerTreeFrameSink(sink_);
}
- SynchronousCompositorProxyMojo* proxy() { return proxy_.get(); }
+ SynchronousCompositorProxy* proxy() { return proxy_.get(); }
void RegisterLayerTreeFrameSink(
int routing_id,
@@ -114,7 +114,7 @@ class SynchronousCompositorProxyRegistry
private:
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
- std::unique_ptr<SynchronousCompositorProxyMojo> proxy_;
+ std::unique_ptr<SynchronousCompositorProxy> proxy_;
SynchronousLayerTreeFrameSink* sink_ = nullptr;
};
@@ -123,7 +123,7 @@ class SynchronousCompositorProxyRegistry
scoped_refptr<WidgetInputHandlerManager> WidgetInputHandlerManager::Create(
base::WeakPtr<RenderWidget> render_widget,
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler) {
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler) {
scoped_refptr<WidgetInputHandlerManager> manager =
new WidgetInputHandlerManager(std::move(render_widget),
std::move(compositor_task_runner),
@@ -135,7 +135,7 @@ scoped_refptr<WidgetInputHandlerManager> WidgetInputHandlerManager::Create(
WidgetInputHandlerManager::WidgetInputHandlerManager(
base::WeakPtr<RenderWidget> render_widget,
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler)
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler)
: render_widget_(render_widget),
main_thread_scheduler_(main_thread_scheduler),
input_event_queue_(render_widget->GetInputEventQueue()),
@@ -161,7 +161,7 @@ void WidgetInputHandlerManager::Init() {
FROM_HERE,
base::BindOnce(
&WidgetInputHandlerManager::InitOnCompositorThread, this,
- render_widget_->compositor()->GetInputHandler(),
+ render_widget_->layer_tree_view()->GetInputHandler(),
render_widget_->compositor_deps()->IsScrollAnimatorEnabled(),
sync_compositing));
}
@@ -225,15 +225,6 @@ void WidgetInputHandlerManager::DispatchNonBlockingEventToMainThread(
INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING, HandledEventCallback());
}
-std::unique_ptr<blink::WebGestureCurve>
-WidgetInputHandlerManager::CreateFlingAnimationCurve(
- blink::WebGestureDevice device_source,
- const blink::WebFloatPoint& velocity,
- const blink::WebSize& cumulative_scroll) {
- return blink::Platform::Current()->CreateFlingAnimationCurve(
- device_source, velocity, cumulative_scroll);
-}
-
void WidgetInputHandlerManager::DidOverscroll(
const gfx::Vector2dF& accumulated_overscroll,
const gfx::Vector2dF& latest_overscroll_delta,
@@ -252,13 +243,6 @@ void WidgetInputHandlerManager::DidOverscroll(
host->DidOverscroll(params);
}
-void WidgetInputHandlerManager::DidStopFlinging() {
- mojom::WidgetInputHandlerHost* host = GetWidgetInputHandlerHost();
- if (!host)
- return;
- host->DidStopFlinging();
-}
-
void WidgetInputHandlerManager::DidAnimateForInput() {
main_thread_scheduler_->DidAnimateForInputOnCompositorThread();
}
@@ -389,10 +373,8 @@ void WidgetInputHandlerManager::InitOnCompositorThread(
const base::WeakPtr<cc::InputHandler>& input_handler,
bool smooth_scroll_enabled,
bool sync_compositing) {
- input_handler_proxy_ = std::make_unique<ui::InputHandlerProxy>(
- input_handler.get(), this,
- base::FeatureList::IsEnabled(features::kTouchpadAndWheelScrollLatching),
- base::FeatureList::IsEnabled(features::kAsyncWheelEvents));
+ input_handler_proxy_ =
+ std::make_unique<ui::InputHandlerProxy>(input_handler.get(), this);
input_handler_proxy_->set_smooth_scroll_enabled(smooth_scroll_enabled);
#if defined(OS_ANDROID)
@@ -457,12 +439,12 @@ void WidgetInputHandlerManager::DidHandleInputEventAndOverscroll(
InputEventAckState ack_state = InputEventDispositionToAck(event_disposition);
if (ack_state == INPUT_EVENT_ACK_STATE_CONSUMED) {
main_thread_scheduler_->DidHandleInputEventOnCompositorThread(
- *input_event, blink::scheduler::WebMainThreadScheduler::
- InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
+ *input_event, blink::scheduler::WebThreadScheduler::InputEventState::
+ EVENT_CONSUMED_BY_COMPOSITOR);
} else if (MainThreadEventQueue::IsForwardedAndSchedulerKnown(ack_state)) {
main_thread_scheduler_->DidHandleInputEventOnCompositorThread(
- *input_event, blink::scheduler::WebMainThreadScheduler::
- InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
+ *input_event, blink::scheduler::WebThreadScheduler::InputEventState::
+ EVENT_FORWARDED_TO_MAIN_THREAD);
}
if (ack_state == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING ||
diff --git a/chromium/content/renderer/input/widget_input_handler_manager.h b/chromium/content/renderer/input/widget_input_handler_manager.h
index abda6108d65..06821186013 100644
--- a/chromium/content/renderer/input/widget_input_handler_manager.h
+++ b/chromium/content/renderer/input/widget_input_handler_manager.h
@@ -17,7 +17,7 @@
namespace blink {
namespace scheduler {
-class WebMainThreadScheduler;
+class WebThreadScheduler;
}; // namespace scheduler
}; // namespace blink
@@ -36,7 +36,7 @@ class CONTENT_EXPORT WidgetInputHandlerManager
static scoped_refptr<WidgetInputHandlerManager> Create(
base::WeakPtr<RenderWidget> render_widget,
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler);
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler);
void AddAssociatedInterface(
mojom::WidgetInputHandlerAssociatedRequest interface_request,
mojom::WidgetInputHandlerHostPtr host);
@@ -49,10 +49,6 @@ class CONTENT_EXPORT WidgetInputHandlerManager
void DispatchNonBlockingEventToMainThread(
ui::WebScopedInputEvent event,
const ui::LatencyInfo& latency_info) override;
- std::unique_ptr<blink::WebGestureCurve> CreateFlingAnimationCurve(
- blink::WebGestureDevice device_source,
- const blink::WebFloatPoint& velocity,
- const blink::WebSize& cumulative_scroll) override;
void DidOverscroll(
const gfx::Vector2dF& accumulated_overscroll,
@@ -60,7 +56,6 @@ class CONTENT_EXPORT WidgetInputHandlerManager
const gfx::Vector2dF& current_fling_velocity,
const gfx::PointF& causal_event_viewport_point,
const cc::OverscrollBehavior& overscroll_behavior) override;
- void DidStopFlinging() override;
void DidAnimateForInput() override;
void DidStartScrollingViewport() override;
void GenerateScrollBeginAndSendToMainThread(
@@ -98,7 +93,7 @@ class CONTENT_EXPORT WidgetInputHandlerManager
WidgetInputHandlerManager(
base::WeakPtr<RenderWidget> render_widget,
scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner,
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler);
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler);
void Init();
void InitOnCompositorThread(
const base::WeakPtr<cc::InputHandler>& input_handler,
@@ -129,7 +124,7 @@ class CONTENT_EXPORT WidgetInputHandlerManager
// Only valid to be called on the main thread.
base::WeakPtr<RenderWidget> render_widget_;
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler_;
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler_;
// InputHandlerProxy is only interacted with on the compositor
// thread.
diff --git a/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc b/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc
index 32ddb9deabd..9dd95c396a7 100644
--- a/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc
+++ b/chromium/content/renderer/loader/child_url_loader_factory_bundle.cc
@@ -24,12 +24,14 @@ class URLLoaderRelay : public network::mojom::URLLoaderClient,
client_sink_(std::move(client_sink)) {}
// network::mojom::URLLoader implementation:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override {
DCHECK(!modified_request_headers.has_value())
<< "Redirect with modified headers was not supported yet. "
"crbug.com/845683";
- loader_sink_->FollowRedirect(base::nullopt);
+ loader_sink_->FollowRedirect(base::nullopt, base::nullopt);
}
void ProceedWithResponse() override { loader_sink_->ProceedWithResponse(); }
@@ -48,10 +50,8 @@ class URLLoaderRelay : public network::mojom::URLLoaderClient,
}
// network::mojom::URLLoaderClient implementation:
- void OnReceiveResponse(
- const network::ResourceResponseHead& head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override {
- client_sink_->OnReceiveResponse(head, std::move(downloaded_file));
+ void OnReceiveResponse(const network::ResourceResponseHead& head) override {
+ client_sink_->OnReceiveResponse(head);
}
void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
@@ -59,10 +59,6 @@ class URLLoaderRelay : public network::mojom::URLLoaderClient,
client_sink_->OnReceiveRedirect(redirect_info, head);
}
- void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override {
- client_sink_->OnDataDownloaded(data_length, encoded_length);
- }
-
void OnUploadProgress(int64_t current_position,
int64_t total_size,
OnUploadProgressCallback callback) override {
@@ -133,18 +129,14 @@ ChildURLLoaderFactoryBundle::ChildURLLoaderFactoryBundle(
}
ChildURLLoaderFactoryBundle::ChildURLLoaderFactoryBundle(
- PossiblyAssociatedFactoryGetterCallback direct_network_factory_getter,
- FactoryGetterCallback default_blob_factory_getter)
- : direct_network_factory_getter_(std::move(direct_network_factory_getter)),
- default_blob_factory_getter_(std::move(default_blob_factory_getter)) {}
+ PossiblyAssociatedFactoryGetterCallback direct_network_factory_getter)
+ : direct_network_factory_getter_(std::move(direct_network_factory_getter)) {
+}
ChildURLLoaderFactoryBundle::~ChildURLLoaderFactoryBundle() = default;
network::mojom::URLLoaderFactory* ChildURLLoaderFactoryBundle::GetFactoryForURL(
const GURL& url) {
- if (url.SchemeIsBlob())
- InitDefaultBlobFactoryIfNecessary();
-
auto it = factories_.find(url.scheme());
if (it != factories_.end())
return it->second.get();
@@ -171,7 +163,7 @@ void ChildURLLoaderFactoryBundle::CreateLoaderAndStart(
std::move(override_iter->second);
subresource_overrides_.erase(override_iter);
- client->OnReceiveResponse(transferrable_loader->head, nullptr);
+ client->OnReceiveResponse(transferrable_loader->head);
mojo::MakeStrongBinding(
std::make_unique<URLLoaderRelay>(
network::mojom::URLLoaderPtr(
@@ -221,20 +213,6 @@ bool ChildURLLoaderFactoryBundle::IsHostChildURLLoaderFactoryBundle() const {
return false;
}
-void ChildURLLoaderFactoryBundle::InitDefaultBlobFactoryIfNecessary() {
- if (default_blob_factory_getter_.is_null())
- return;
-
- if (factories_.find(url::kBlobScheme) == factories_.end()) {
- network::mojom::URLLoaderFactoryPtr blob_factory =
- std::move(default_blob_factory_getter_).Run();
- if (blob_factory)
- factories_.emplace(url::kBlobScheme, std::move(blob_factory));
- } else {
- default_blob_factory_getter_.Reset();
- }
-}
-
void ChildURLLoaderFactoryBundle::InitDirectNetworkFactoryIfNecessary() {
if (direct_network_factory_getter_.is_null())
return;
@@ -248,7 +226,6 @@ void ChildURLLoaderFactoryBundle::InitDirectNetworkFactoryIfNecessary() {
std::unique_ptr<network::SharedURLLoaderFactoryInfo>
ChildURLLoaderFactoryBundle::CloneInternal(bool include_default) {
- InitDefaultBlobFactoryIfNecessary();
InitDirectNetworkFactoryIfNecessary();
network::mojom::URLLoaderFactoryPtrInfo default_factory_info;
@@ -278,7 +255,6 @@ ChildURLLoaderFactoryBundle::CloneInternal(bool include_default) {
std::unique_ptr<ChildURLLoaderFactoryBundleInfo>
ChildURLLoaderFactoryBundle::PassInterface() {
- InitDefaultBlobFactoryIfNecessary();
InitDirectNetworkFactoryIfNecessary();
network::mojom::URLLoaderFactoryPtrInfo default_factory_info;
diff --git a/chromium/content/renderer/loader/child_url_loader_factory_bundle.h b/chromium/content/renderer/loader/child_url_loader_factory_bundle.h
index cb613cbc247..bcf816a026c 100644
--- a/chromium/content/renderer/loader/child_url_loader_factory_bundle.h
+++ b/chromium/content/renderer/loader/child_url_loader_factory_bundle.h
@@ -47,8 +47,8 @@ class CONTENT_EXPORT ChildURLLoaderFactoryBundleInfo
// This class extends URLLoaderFactoryBundle to support a direct network loader
// factory, which bypasses custom overrides such as appcache or service worker.
-// Besides, it also supports using callbacks to lazily initialize the blob and
-// the direct network loader factories.
+// Besides, it also supports using callbacks to lazily initialize the direct
+// network loader factory.
class CONTENT_EXPORT ChildURLLoaderFactoryBundle
: public URLLoaderFactoryBundle {
public:
@@ -66,8 +66,7 @@ class CONTENT_EXPORT ChildURLLoaderFactoryBundle
std::unique_ptr<ChildURLLoaderFactoryBundleInfo> info);
ChildURLLoaderFactoryBundle(
- PossiblyAssociatedFactoryGetterCallback direct_network_factory_getter,
- FactoryGetterCallback default_blob_factory_getter);
+ PossiblyAssociatedFactoryGetterCallback direct_network_factory_getter);
// URLLoaderFactoryBundle overrides.
network::mojom::URLLoaderFactory* GetFactoryForURL(const GURL& url) override;
@@ -100,7 +99,6 @@ class CONTENT_EXPORT ChildURLLoaderFactoryBundle
~ChildURLLoaderFactoryBundle() override;
private:
- void InitDefaultBlobFactoryIfNecessary();
void InitDirectNetworkFactoryIfNecessary();
std::unique_ptr<network::SharedURLLoaderFactoryInfo> CloneInternal(
bool include_default);
@@ -109,8 +107,6 @@ class CONTENT_EXPORT ChildURLLoaderFactoryBundle
PossiblyAssociatedURLLoaderFactoryPtr direct_network_factory_;
std::map<GURL, mojom::TransferrableURLLoaderPtr> subresource_overrides_;
-
- FactoryGetterCallback default_blob_factory_getter_;
};
} // namespace content
diff --git a/chromium/content/renderer/loader/resource_dispatcher.cc b/chromium/content/renderer/loader/resource_dispatcher.cc
index f3f906a3c5a..3d5bd290d7b 100644
--- a/chromium/content/renderer/loader/resource_dispatcher.cc
+++ b/chromium/content/renderer/loader/resource_dispatcher.cc
@@ -19,9 +19,11 @@
#include "base/strings/string_util.h"
#include "base/synchronization/waitable_event.h"
#include "base/task_scheduler/post_task.h"
+#include "base/time/time.h"
#include "build/build_config.h"
#include "content/common/inter_process_time_ticks_converter.h"
#include "content/common/navigation_params.h"
+#include "content/common/net/record_load_histograms.h"
#include "content/common/throttling_url_loader.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/resource_load_info.mojom.h"
@@ -38,7 +40,6 @@
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
-#include "net/cert/cert_status_flags.h"
#include "net/http/http_response_headers.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_request.h"
@@ -95,10 +96,36 @@ void NotifySubresourceStarted(
render_frame->GetFrameHost()->SubresourceResponseStarted(url, cert_status);
}
+void NotifyResourceLoadStarted(
+ scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner,
+ int render_frame_id,
+ int request_id,
+ const network::ResourceResponseHead& response_head,
+ content::ResourceType resource_type) {
+ if (!thread_task_runner)
+ return;
+
+ if (!thread_task_runner->BelongsToCurrentThread()) {
+ thread_task_runner->PostTask(
+ FROM_HERE, base::BindOnce(NotifyResourceLoadStarted, thread_task_runner,
+ render_frame_id, request_id, response_head,
+ resource_type));
+ return;
+ }
+
+ RenderFrameImpl* render_frame =
+ RenderFrameImpl::FromRoutingID(render_frame_id);
+ if (!render_frame)
+ return;
+
+ render_frame->DidStartResponse(request_id, response_head, resource_type);
+}
+
void NotifyResourceLoadComplete(
scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner,
int render_frame_id,
- mojom::ResourceLoadInfoPtr resource_load_info) {
+ mojom::ResourceLoadInfoPtr resource_load_info,
+ const network::URLLoaderCompletionStatus& status) {
if (!thread_task_runner)
return;
@@ -106,7 +133,7 @@ void NotifyResourceLoadComplete(
thread_task_runner->PostTask(
FROM_HERE,
base::BindOnce(NotifyResourceLoadComplete, thread_task_runner,
- render_frame_id, std::move(resource_load_info)));
+ render_frame_id, std::move(resource_load_info), status));
return;
}
@@ -115,10 +142,57 @@ void NotifyResourceLoadComplete(
if (!render_frame)
return;
+ render_frame->DidCompleteResponse(resource_load_info->request_id, status);
render_frame->GetFrameHost()->ResourceLoadComplete(
std::move(resource_load_info));
}
+void NotifyResourceLoadCancel(
+ scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner,
+ int render_frame_id,
+ int request_id) {
+ if (!thread_task_runner)
+ return;
+
+ if (!thread_task_runner->BelongsToCurrentThread()) {
+ thread_task_runner->PostTask(
+ FROM_HERE, base::BindOnce(NotifyResourceLoadCancel, thread_task_runner,
+ render_frame_id, request_id));
+ return;
+ }
+
+ RenderFrameImpl* render_frame =
+ RenderFrameImpl::FromRoutingID(render_frame_id);
+ if (!render_frame)
+ return;
+
+ render_frame->DidCancelResponse(request_id);
+}
+
+void NotifyResourceTransferSizeUpdate(
+ scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner,
+ int render_frame_id,
+ int request_id,
+ int transfer_size_diff) {
+ if (!thread_task_runner)
+ return;
+
+ if (!thread_task_runner->BelongsToCurrentThread()) {
+ thread_task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(NotifyResourceTransferSizeUpdate, thread_task_runner,
+ render_frame_id, request_id, transfer_size_diff));
+ return;
+ }
+
+ RenderFrameImpl* render_frame =
+ RenderFrameImpl::FromRoutingID(render_frame_id);
+ if (!render_frame)
+ return;
+
+ render_frame->DidReceiveTransferSizeUpdate(request_id, transfer_size_diff);
+}
+
// Returns true if the headers indicate that this resource should always be
// revalidated or not cached.
bool AlwaysAccessNetwork(
@@ -231,6 +305,15 @@ void ResourceDispatcher::OnReceivedResponse(
}
request_info->peer->OnReceivedResponse(renderer_response_info);
+
+ // Make a deep copy of ResourceResponseHead before passing it cross-thread.
+ auto resource_response = base::MakeRefCounted<network::ResourceResponse>();
+ resource_response->head = response_head;
+ auto deep_copied_response = resource_response->DeepCopy();
+ NotifyResourceLoadStarted(RenderThreadImpl::DeprecatedGetMainTaskRunner(),
+ request_info->render_frame_id, request_id,
+ deep_copied_response->head,
+ request_info->resource_type);
}
void ResourceDispatcher::OnReceivedCachedMetadata(
@@ -256,16 +339,6 @@ void ResourceDispatcher::OnStartLoadingResponseBody(
request_info->peer->OnStartLoadingResponseBody(std::move(body));
}
-void ResourceDispatcher::OnDownloadedData(int request_id,
- int data_len,
- int encoded_data_length) {
- PendingRequestInfo* request_info = GetPendingRequestInfo(request_id);
- if (!request_info)
- return;
-
- request_info->peer->OnDownloadedData(data_len, encoded_data_length);
-}
-
void ResourceDispatcher::OnReceivedRedirect(
int request_id,
const net::RedirectInfo& redirect_info,
@@ -317,7 +390,7 @@ void ResourceDispatcher::FollowPendingRedirect(
request_info->has_pending_redirect = false;
// net::URLRequest clears its request_start on redirect, so should we.
request_info->local_request_start = base::TimeTicks::Now();
- request_info->url_loader->FollowRedirect();
+ request_info->url_loader->FollowRedirect(base::nullopt);
}
}
@@ -331,6 +404,7 @@ void ResourceDispatcher::OnRequestComplete(
return;
request_info->buffer.reset();
request_info->buffer_size = 0;
+ request_info->net_error = status.error_code;
auto resource_load_info = mojom::ResourceLoadInfo::New();
resource_load_info->url = request_info->response_url;
@@ -356,7 +430,7 @@ void ResourceDispatcher::OnRequestComplete(
NotifyResourceLoadComplete(RenderThreadImpl::DeprecatedGetMainTaskRunner(),
request_info->render_frame_id,
- std::move(resource_load_info));
+ std::move(resource_load_info), status);
RequestPeer* peer = request_info->peer.get();
@@ -399,17 +473,6 @@ void ResourceDispatcher::OnRequestComplete(
peer->OnCompletedRequest(renderer_status);
}
-network::mojom::DownloadedTempFilePtr
-ResourceDispatcher::TakeDownloadedTempFile(int request_id) {
- PendingRequestMap::iterator it = pending_requests_.find(request_id);
- if (it == pending_requests_.end())
- return nullptr;
- PendingRequestInfo* request_info = it->second.get();
- if (!request_info->url_loader_client)
- return nullptr;
- return request_info->url_loader_client->TakeDownloadedTempFile();
-}
-
bool ResourceDispatcher::RemovePendingRequest(
int request_id,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
@@ -417,6 +480,15 @@ bool ResourceDispatcher::RemovePendingRequest(
if (it == pending_requests_.end())
return false;
+ if (it->second->net_error == net::ERR_IO_PENDING) {
+ it->second->net_error = net::ERR_ABORTED;
+ NotifyResourceLoadCancel(RenderThreadImpl::DeprecatedGetMainTaskRunner(),
+ it->second->render_frame_id, request_id);
+ }
+
+ RecordLoadHistograms(it->second->response_url, it->second->resource_type,
+ it->second->net_error);
+
// Cancel loading.
it->second->url_loader = nullptr;
// Clear URLLoaderClient to stop receiving further Mojo IPC from the browser
@@ -485,6 +557,10 @@ void ResourceDispatcher::OnTransferSizeUpdated(int request_id,
// TODO(yhirano): Consider using int64_t in
// RequestPeer::OnTransferSizeUpdated.
request_info->peer->OnTransferSizeUpdated(transfer_size_diff);
+
+ NotifyResourceTransferSizeUpdate(
+ RenderThreadImpl::DeprecatedGetMainTaskRunner(),
+ request_info->render_frame_id, request_id, transfer_size_diff);
}
ResourceDispatcher::PendingRequestInfo::PendingRequestInfo(
@@ -494,7 +570,6 @@ ResourceDispatcher::PendingRequestInfo::PendingRequestInfo(
const GURL& request_url,
const std::string& method,
const GURL& referrer,
- bool download_to_file,
std::unique_ptr<NavigationResponseOverrideParameters>
navigation_response_override_params)
: peer(std::move(peer)),
@@ -504,7 +579,6 @@ ResourceDispatcher::PendingRequestInfo::PendingRequestInfo(
response_url(request_url),
response_method(method),
response_referrer(referrer),
- download_to_file(download_to_file),
local_request_start(base::TimeTicks::Now()),
buffer_size(0),
navigation_response_override(
@@ -520,7 +594,7 @@ void ResourceDispatcher::StartSync(
SyncLoadResponse* response,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
- double timeout,
+ base::TimeDelta timeout,
blink::mojom::BlobRegistryPtrInfo download_to_blob_registry,
std::unique_ptr<RequestPeer> peer) {
CheckSchemeForReferrerPolicy(*request);
@@ -599,8 +673,7 @@ int ResourceDispatcher::StartAsync(
pending_requests_[request_id] = std::make_unique<PendingRequestInfo>(
std::move(peer), static_cast<ResourceType>(request->resource_type),
request->render_frame_id, request->url, request->method,
- request->referrer, request->download_to_file,
- std::move(response_override_params));
+ request->referrer, std::move(response_override_params));
if (override_url_loader) {
pending_requests_[request_id]->url_loader_client =
@@ -709,8 +782,7 @@ void ResourceDispatcher::ContinueForNavigation(int request_id) {
return;
}
- client_ptr->OnReceiveResponse(response_override->response,
- network::mojom::DownloadedTempFilePtr());
+ client_ptr->OnReceiveResponse(response_override->response);
// Abort if the request is cancelled.
if (!GetPendingRequestInfo(request_id))
diff --git a/chromium/content/renderer/loader/resource_dispatcher.h b/chromium/content/renderer/loader/resource_dispatcher.h
index 609aaef3f2a..3040fbd1189 100644
--- a/chromium/content/renderer/loader/resource_dispatcher.h
+++ b/chromium/content/renderer/loader/resource_dispatcher.h
@@ -28,6 +28,7 @@
#include "content/public/common/url_loader_throttle.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "net/base/host_port_pair.h"
+#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -89,7 +90,8 @@ class CONTENT_EXPORT ResourceDispatcher {
//
// |routing_id| is used to associated the bridge with a frame's network
// context.
- // |timeout| (in seconds) is used to abort the sync request on timeouts.
+ // |timeout| is used to abort the sync request on timeouts. TimeDelta::Max()
+ // is interpreted as no-timeout.
// If |download_to_blob_registry| is not null, it is used to redirect the
// download to a blob, using StartAsync's |pass_response_pipe_to_peer| flag.
virtual void StartSync(
@@ -99,7 +101,7 @@ class CONTENT_EXPORT ResourceDispatcher {
SyncLoadResponse* response,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
- double timeout,
+ base::TimeDelta timeout,
blink::mojom::BlobRegistryPtrInfo download_to_blob_registry,
std::unique_ptr<RequestPeer> peer);
@@ -131,8 +133,6 @@ class CONTENT_EXPORT ResourceDispatcher {
response_override_params,
base::OnceClosure* continue_navigation_function);
- network::mojom::DownloadedTempFilePtr TakeDownloadedTempFile(int request_id);
-
// Removes a request from the |pending_requests_| list, returning true if the
// request was found and removed.
bool RemovePendingRequest(
@@ -185,7 +185,6 @@ class CONTENT_EXPORT ResourceDispatcher {
const GURL& request_url,
const std::string& method,
const GURL& referrer,
- bool download_to_file,
std::unique_ptr<NavigationResponseOverrideParameters>
response_override_params);
@@ -202,7 +201,6 @@ class CONTENT_EXPORT ResourceDispatcher {
GURL response_url;
std::string response_method;
GURL response_referrer;
- bool download_to_file;
bool has_pending_redirect = false;
base::TimeTicks local_request_start;
base::TimeTicks local_response_start;
@@ -217,6 +215,10 @@ class CONTENT_EXPORT ResourceDispatcher {
navigation_response_override;
bool should_follow_redirect = true;
bool always_access_network = false;
+ // Network error code the request completed with, or net::ERR_IO_PENDING if
+ // it's not completed. Used both to distinguish completion from
+ // cancellation, and to log histograms.
+ int net_error = net::ERR_IO_PENDING;
std::vector<content::mojom::RedirectInfoPtr> redirect_info_chain;
@@ -245,7 +247,6 @@ class CONTENT_EXPORT ResourceDispatcher {
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
void OnStartLoadingResponseBody(int request_id,
mojo::ScopedDataPipeConsumerHandle body);
- void OnDownloadedData(int request_id, int data_len, int encoded_data_length);
void OnRequestComplete(int request_id,
const network::URLLoaderCompletionStatus& status);
diff --git a/chromium/content/renderer/loader/resource_dispatcher_unittest.cc b/chromium/content/renderer/loader/resource_dispatcher_unittest.cc
index 9d89c8b0198..186292fb0ba 100644
--- a/chromium/content/renderer/loader/resource_dispatcher_unittest.cc
+++ b/chromium/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -85,7 +85,7 @@ class ResourceDispatcherTest : public testing::Test,
head.headers = new net::HttpResponseHeaders(raw_headers);
head.mime_type = kTestPageMimeType;
head.charset = kTestPageCharset;
- client->OnReceiveResponse(head, {});
+ client->OnReceiveResponse(head);
}
std::unique_ptr<network::ResourceRequest> CreateResourceRequest() {
@@ -184,8 +184,6 @@ class TestResourceDispatcherDelegate : public ResourceDispatcherDelegate {
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override {}
- void OnDownloadedData(int len, int encoded_data_length) override {}
-
void OnReceivedData(std::unique_ptr<ReceivedData> data) override {
data_.append(data->payload(), data->length());
}
@@ -325,7 +323,7 @@ class TimeConversionTest : public ResourceDispatcherTest {
ASSERT_EQ(1u, loader_and_clients_.size());
auto client = std::move(loader_and_clients_[0].second);
loader_and_clients_.clear();
- client->OnReceiveResponse(response_head, {});
+ client->OnReceiveResponse(response_head);
}
const network::ResourceResponseInfo& response_info() const {
@@ -396,7 +394,7 @@ class CompletionTimeConversionTest : public ResourceDispatcherTest {
// copied.
response_head.load_timing.request_start_time =
base::Time() + base::TimeDelta::FromSeconds(99);
- client->OnReceiveResponse(response_head, {});
+ client->OnReceiveResponse(response_head);
network::URLLoaderCompletionStatus status;
status.completion_time = completion_time;
diff --git a/chromium/content/renderer/loader/sync_load_context.cc b/chromium/content/renderer/loader/sync_load_context.cc
index 17da79d30b5..b9362684d8e 100644
--- a/chromium/content/renderer/loader/sync_load_context.cc
+++ b/chromium/content/renderer/loader/sync_load_context.cc
@@ -7,7 +7,9 @@
#include <string>
#include "base/logging.h"
+#include "base/optional.h"
#include "base/synchronization/waitable_event.h"
+#include "base/time/time.h"
#include "content/public/common/url_loader_throttle.h"
#include "content/renderer/loader/navigation_response_override_parameters.h"
#include "content/renderer/loader/sync_load_response.h"
@@ -24,32 +26,42 @@ class SyncLoadContext::SignalHelper final {
SignalHelper(SyncLoadContext* context,
base::WaitableEvent* redirect_or_response_event,
base::WaitableEvent* abort_event,
- double timeout)
+ base::TimeDelta timeout)
: context_(context),
redirect_or_response_event_(redirect_or_response_event),
abort_event_(abort_event) {
- Start(base::TimeDelta::FromSecondsD(timeout));
+ // base::TimeDelta::Max() means no timeout.
+ if (timeout != base::TimeDelta::Max()) {
+ // Instantiate a base::OneShotTimer instance.
+ timeout_timer_.emplace();
+ }
+ Start(timeout);
}
void SignalRedirectOrResponseComplete() {
abort_watcher_.StopWatching();
- timeout_timer_.AbandonAndStop();
+ if (timeout_timer_)
+ timeout_timer_->AbandonAndStop();
redirect_or_response_event_->Signal();
}
bool RestartAfterRedirect() {
if (abort_event_ && abort_event_->IsSignaled())
return false;
- base::TimeDelta timeout_remainder =
- timeout_timer_.desired_run_time() - base::TimeTicks::Now();
- if (timeout_remainder <= base::TimeDelta())
- return false;
+
+ base::TimeDelta timeout_remainder = base::TimeDelta::Max();
+ if (timeout_timer_) {
+ timeout_remainder =
+ timeout_timer_->desired_run_time() - base::TimeTicks::Now();
+ if (timeout_remainder <= base::TimeDelta())
+ return false;
+ }
Start(timeout_remainder);
return true;
}
private:
- void Start(const base::TimeDelta& timeout) {
+ void Start(base::TimeDelta timeout) {
DCHECK(!redirect_or_response_event_->IsSignaled());
if (abort_event_) {
abort_watcher_.StartWatching(
@@ -57,9 +69,10 @@ class SyncLoadContext::SignalHelper final {
base::BindOnce(&SyncLoadContext::OnAbort, base::Unretained(context_)),
context_->task_runner_);
}
- if (timeout > base::TimeDelta()) {
- timeout_timer_.Start(FROM_HERE, timeout, context_,
- &SyncLoadContext::OnTimeout);
+ if (timeout_timer_) {
+ DCHECK_NE(base::TimeDelta::Max(), timeout);
+ timeout_timer_->Start(FROM_HERE, timeout, context_,
+ &SyncLoadContext::OnTimeout);
}
}
@@ -67,7 +80,7 @@ class SyncLoadContext::SignalHelper final {
base::WaitableEvent* redirect_or_response_event_;
base::WaitableEvent* abort_event_;
base::WaitableEventWatcher abort_watcher_;
- base::OneShotTimer timeout_timer_;
+ base::Optional<base::OneShotTimer> timeout_timer_;
};
// static
@@ -82,7 +95,7 @@ void SyncLoadContext::StartAsyncWithWaitableEvent(
SyncLoadResponse* response,
base::WaitableEvent* redirect_or_response_event,
base::WaitableEvent* abort_event,
- double timeout,
+ base::TimeDelta timeout,
blink::mojom::BlobRegistryPtrInfo download_to_blob_registry) {
bool download_to_blob = download_to_blob_registry.is_valid();
auto* context = new SyncLoadContext(
@@ -104,7 +117,7 @@ SyncLoadContext::SyncLoadContext(
SyncLoadResponse* response,
base::WaitableEvent* redirect_or_response_event,
base::WaitableEvent* abort_event,
- double timeout,
+ base::TimeDelta timeout,
blink::mojom::BlobRegistryPtrInfo download_to_blob_registry,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: response_(response),
@@ -113,8 +126,7 @@ SyncLoadContext::SyncLoadContext(
signals_(std::make_unique<SignalHelper>(this,
redirect_or_response_event,
abort_event,
- timeout)),
- fetch_request_mode_(request->fetch_request_mode) {
+ timeout)) {
url_loader_factory_ =
network::SharedURLLoaderFactory::Create(std::move(url_loader_factory));
@@ -134,23 +146,6 @@ bool SyncLoadContext::OnReceivedRedirect(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseInfo& info) {
DCHECK(!Completed());
- // Synchronous loads in blink aren't associated with a ResourceClient, and
- // CORS checks are performed by ResourceClient subclasses, so there's
- // currently no way to perform CORS checks for redirects.
- // Err on the side of extreme caution and block any cross origin redirect
- // that might have CORS implications.
- if (fetch_request_mode_ != network::mojom::FetchRequestMode::kNoCORS &&
- redirect_info.new_url.GetOrigin() != response_->url.GetOrigin()) {
- LOG(ERROR) << "Cross origin redirect denied";
- response_->error_code = net::ERR_ABORTED;
-
- CompleteRequest(false /* remove_pending_request */);
-
- // Returning false here will cause the request to be cancelled and this
- // object deleted.
- return false;
- }
-
response_->url = redirect_info.new_url;
response_->info = info;
response_->redirect_info = redirect_info;
@@ -200,11 +195,6 @@ void SyncLoadContext::OnStartLoadingResponseBody(
base::Unretained(this)));
}
-void SyncLoadContext::OnDownloadedData(int len, int encoded_data_length) {
- downloaded_file_length_ =
- (downloaded_file_length_ ? *downloaded_file_length_ : 0) + len;
-}
-
void SyncLoadContext::OnReceivedData(std::unique_ptr<ReceivedData> data) {
DCHECK(!Completed());
response_->data.append(data->payload(), data->length());
@@ -217,17 +207,9 @@ void SyncLoadContext::OnCompletedRequest(
DCHECK(!Completed());
response_->error_code = status.error_code;
response_->extended_error_code = status.extended_error_code;
- if (status.cors_error_status)
- response_->cors_error = status.cors_error_status->cors_error;
+ response_->cors_error = status.cors_error_status;
response_->info.encoded_data_length = status.encoded_data_length;
response_->info.encoded_body_length = status.encoded_body_length;
- response_->downloaded_file_length = downloaded_file_length_;
- // Need to pass |downloaded_tmp_file| to the caller thread. Otherwise the blob
- // creation in ResourceResponse::SetDownloadedFilePath() fails.
- response_->downloaded_tmp_file =
- resource_dispatcher_->TakeDownloadedTempFile(request_id_);
- DCHECK_EQ(!response_->downloaded_file_length,
- !response_->downloaded_tmp_file);
if (blob_response_started_ && !blob_finished_) {
request_completed_ = true;
return;
diff --git a/chromium/content/renderer/loader/sync_load_context.h b/chromium/content/renderer/loader/sync_load_context.h
index 23a7e7e8094..576233f5054 100644
--- a/chromium/content/renderer/loader/sync_load_context.h
+++ b/chromium/content/renderer/loader/sync_load_context.h
@@ -50,7 +50,7 @@ class SyncLoadContext : public RequestPeer {
SyncLoadResponse* response,
base::WaitableEvent* completed_event,
base::WaitableEvent* abort_event,
- double timeout,
+ base::TimeDelta timeout,
blink::mojom::BlobRegistryPtrInfo download_to_blob_registry);
~SyncLoadContext() override;
@@ -65,7 +65,7 @@ class SyncLoadContext : public RequestPeer {
SyncLoadResponse* response,
base::WaitableEvent* completed_event,
base::WaitableEvent* abort_event,
- double timeout,
+ base::TimeDelta timeout,
blink::mojom::BlobRegistryPtrInfo download_to_blob_registry,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
// RequestPeer implementation:
@@ -75,7 +75,6 @@ class SyncLoadContext : public RequestPeer {
void OnReceivedResponse(const network::ResourceResponseInfo& info) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
- 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(
@@ -108,13 +107,9 @@ class SyncLoadContext : public RequestPeer {
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- base::Optional<int64_t> downloaded_file_length_;
-
class SignalHelper;
std::unique_ptr<SignalHelper> signals_;
- const network::mojom::FetchRequestMode fetch_request_mode_;
-
DISALLOW_COPY_AND_ASSIGN(SyncLoadContext);
};
diff --git a/chromium/content/renderer/loader/sync_load_response.h b/chromium/content/renderer/loader/sync_load_response.h
index ea252ca5f31..df5a86cf879 100644
--- a/chromium/content/renderer/loader/sync_load_response.h
+++ b/chromium/content/renderer/loader/sync_load_response.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_RENDERER_CHILD_SYNC_LOAD_RESPONSE_H_
-#define CONTENT_RENDERER_CHILD_SYNC_LOAD_RESPONSE_H_
+#ifndef CONTENT_RENDERER_LOADER_SYNC_LOAD_RESPONSE_H_
+#define CONTENT_RENDERER_LOADER_SYNC_LOAD_RESPONSE_H_
#include <string>
#include "base/optional.h"
#include "content/common/content_export.h"
+#include "services/network/public/cpp/cors/cors_error_status.h"
#include "services/network/public/cpp/resource_response_info.h"
-#include "services/network/public/mojom/cors.mojom.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "third_party/blink/public/mojom/blob/serialized_blob.mojom.h"
#include "url/gurl.h"
@@ -40,7 +40,7 @@ struct CONTENT_EXPORT SyncLoadResponse {
int extended_error_code = 0;
// Optional CORS error details.
- base::Optional<network::mojom::CORSError> cors_error;
+ base::Optional<network::CORSErrorStatus> cors_error;
// The final URL of the response. This may differ from the request URL in
// the case of a server redirect.
@@ -50,11 +50,9 @@ struct CONTENT_EXPORT SyncLoadResponse {
std::string data;
// Used for blob response type XMLHttpRequest.
- base::Optional<int64_t> downloaded_file_length;
- network::mojom::DownloadedTempFilePtr downloaded_tmp_file;
blink::mojom::SerializedBlobPtr downloaded_blob;
};
} // namespace content
-#endif // CONTENT_RENDERER_CHILD_SYNC_LOAD_RESPONSE_H_
+#endif // CONTENT_RENDERER_LOADER_SYNC_LOAD_RESPONSE_H_
diff --git a/chromium/content/renderer/loader/test_request_peer.cc b/chromium/content/renderer/loader/test_request_peer.cc
index 1d92c02c630..95f90b53f9b 100644
--- a/chromium/content/renderer/loader/test_request_peer.cc
+++ b/chromium/content/renderer/loader/test_request_peer.cc
@@ -55,14 +55,6 @@ void TestRequestPeer::OnStartLoadingResponseBody(
EXPECT_FALSE(context_->complete);
}
-void TestRequestPeer::OnDownloadedData(int len, int encoded_data_length) {
- EXPECT_TRUE(context_->received_response);
- EXPECT_FALSE(context_->cancelled);
- EXPECT_FALSE(context_->complete);
- context_->total_downloaded_data_length += len;
- context_->total_encoded_data_length += encoded_data_length;
-}
-
void TestRequestPeer::OnReceivedData(std::unique_ptr<ReceivedData> data) {
if (context_->cancelled)
return;
diff --git a/chromium/content/renderer/loader/test_request_peer.h b/chromium/content/renderer/loader/test_request_peer.h
index 3c40627b410..f77658b574c 100644
--- a/chromium/content/renderer/loader/test_request_peer.h
+++ b/chromium/content/renderer/loader/test_request_peer.h
@@ -41,7 +41,6 @@ class TestRequestPeer : public RequestPeer {
void OnReceivedResponse(const network::ResourceResponseInfo& info) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
- 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 OnReceivedCachedMetadata(const char* data, int len) override;
@@ -73,9 +72,6 @@ class TestRequestPeer : public RequestPeer {
int total_encoded_data_length = 0;
bool defer_on_transfer_size_updated = false;
- // Total length when downloading to a file.
- int total_downloaded_data_length = 0;
-
bool complete = false;
bool cancelled = false;
int request_id = -1;
diff --git a/chromium/content/renderer/loader/url_loader_client_impl.cc b/chromium/content/renderer/loader/url_loader_client_impl.cc
index 9b237d2ae52..0deb4423338 100644
--- a/chromium/content/renderer/loader/url_loader_client_impl.cc
+++ b/chromium/content/renderer/loader/url_loader_client_impl.cc
@@ -65,23 +65,6 @@ class URLLoaderClientImpl::DeferredOnReceiveRedirect final
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
};
-class URLLoaderClientImpl::DeferredOnDataDownloaded final
- : public DeferredMessage {
- public:
- DeferredOnDataDownloaded(int64_t data_length, int64_t encoded_data_length)
- : data_length_(data_length), encoded_data_length_(encoded_data_length) {}
-
- void HandleMessage(ResourceDispatcher* dispatcher, int request_id) override {
- dispatcher->OnDownloadedData(request_id, data_length_,
- encoded_data_length_);
- }
- bool IsCompletionMessage() const override { return false; }
-
- private:
- const int64_t data_length_;
- const int64_t encoded_data_length_;
-};
-
class URLLoaderClientImpl::DeferredOnUploadProgress final
: public DeferredMessage {
public:
@@ -233,10 +216,8 @@ void URLLoaderClientImpl::Bind(
}
void URLLoaderClientImpl::OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) {
+ const network::ResourceResponseHead& response_head) {
has_received_response_ = true;
- downloaded_file_ = std::move(downloaded_file);
if (NeedsStoringMessage()) {
StoreAndDispatch(
std::make_unique<DeferredOnReceiveResponse>(response_head));
@@ -259,17 +240,6 @@ void URLLoaderClientImpl::OnReceiveRedirect(
}
}
-void URLLoaderClientImpl::OnDataDownloaded(int64_t data_len,
- int64_t encoded_data_len) {
- if (NeedsStoringMessage()) {
- StoreAndDispatch(
- std::make_unique<DeferredOnDataDownloaded>(data_len, encoded_data_len));
- } else {
- resource_dispatcher_->OnDownloadedData(request_id_, data_len,
- encoded_data_len);
- }
-}
-
void URLLoaderClientImpl::OnUploadProgress(
int64_t current_position,
int64_t total_size,
@@ -338,11 +308,6 @@ void URLLoaderClientImpl::OnComplete(
body_consumer_->OnComplete(status);
}
-network::mojom::DownloadedTempFilePtr
-URLLoaderClientImpl::TakeDownloadedTempFile() {
- return std::move(downloaded_file_);
-}
-
bool URLLoaderClientImpl::NeedsStoringMessage() const {
return is_deferred_ || deferred_messages_.size() > 0;
}
diff --git a/chromium/content/renderer/loader/url_loader_client_impl.h b/chromium/content/renderer/loader/url_loader_client_impl.h
index 66c1a455214..6ede15c50e6 100644
--- a/chromium/content/renderer/loader/url_loader_client_impl.h
+++ b/chromium/content/renderer/loader/url_loader_client_impl.h
@@ -68,12 +68,10 @@ class CONTENT_EXPORT URLLoaderClientImpl final
// network::mojom::URLLoaderClient implementation
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override;
+ const network::ResourceResponseHead& response_head) override;
void OnReceiveRedirect(
const net::RedirectInfo& redirect_info,
const network::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;
@@ -83,14 +81,10 @@ class CONTENT_EXPORT URLLoaderClientImpl final
mojo::ScopedDataPipeConsumerHandle body) override;
void OnComplete(const network::URLLoaderCompletionStatus& status) override;
- // Takes |downloaded_file_|.
- network::mojom::DownloadedTempFilePtr TakeDownloadedTempFile();
-
private:
class DeferredMessage;
class DeferredOnReceiveResponse;
class DeferredOnReceiveRedirect;
- class DeferredOnDataDownloaded;
class DeferredOnUploadProgress;
class DeferredOnReceiveCachedMetadata;
class DeferredOnComplete;
@@ -100,7 +94,6 @@ class CONTENT_EXPORT URLLoaderClientImpl final
void OnConnectionClosed();
scoped_refptr<URLResponseBodyConsumer> body_consumer_;
- network::mojom::DownloadedTempFilePtr downloaded_file_;
std::vector<std::unique_ptr<DeferredMessage>> deferred_messages_;
const int request_id_;
bool has_received_response_ = false;
diff --git a/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc b/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc
index 4278bd904a9..71bdf233be9 100644
--- a/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc
+++ b/chromium/content/renderer/loader/url_loader_client_impl_unittest.cc
@@ -79,7 +79,7 @@ class URLLoaderClientImplTest : public ::testing::Test,
TEST_F(URLLoaderClientImplTest, OnReceiveResponse) {
network::ResourceResponseHead response_head;
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
EXPECT_FALSE(request_peer_context_.received_response);
base::RunLoop().RunUntilIdle();
@@ -89,7 +89,7 @@ TEST_F(URLLoaderClientImplTest, OnReceiveResponse) {
TEST_F(URLLoaderClientImplTest, ResponseBody) {
network::ResourceResponseHead response_head;
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
EXPECT_FALSE(request_peer_context_.received_response);
base::RunLoop().RunUntilIdle();
@@ -119,28 +119,12 @@ TEST_F(URLLoaderClientImplTest, OnReceiveRedirect) {
EXPECT_EQ(1, request_peer_context_.seen_redirects);
}
-TEST_F(URLLoaderClientImplTest, OnDataDownloaded) {
- network::ResourceResponseHead response_head;
-
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
- url_loader_client_->OnDataDownloaded(8, 13);
- url_loader_client_->OnDataDownloaded(2, 1);
-
- EXPECT_FALSE(request_peer_context_.received_response);
- EXPECT_EQ(0, request_peer_context_.total_downloaded_data_length);
- EXPECT_EQ(0, request_peer_context_.total_encoded_data_length);
- base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(request_peer_context_.received_response);
- EXPECT_EQ(10, request_peer_context_.total_downloaded_data_length);
- EXPECT_EQ(14, request_peer_context_.total_encoded_data_length);
-}
-
TEST_F(URLLoaderClientImplTest, OnReceiveCachedMetadata) {
network::ResourceResponseHead response_head;
std::vector<uint8_t> metadata;
metadata.push_back('a');
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
url_loader_client_->OnReceiveCachedMetadata(metadata);
EXPECT_FALSE(request_peer_context_.received_response);
@@ -154,7 +138,7 @@ TEST_F(URLLoaderClientImplTest, OnReceiveCachedMetadata) {
TEST_F(URLLoaderClientImplTest, OnTransferSizeUpdated) {
network::ResourceResponseHead response_head;
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
url_loader_client_->OnTransferSizeUpdated(4);
url_loader_client_->OnTransferSizeUpdated(4);
@@ -169,7 +153,7 @@ TEST_F(URLLoaderClientImplTest, OnCompleteWithoutResponseBody) {
network::ResourceResponseHead response_head;
network::URLLoaderCompletionStatus status;
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
url_loader_client_->OnComplete(status);
EXPECT_FALSE(request_peer_context_.received_response);
@@ -183,7 +167,7 @@ TEST_F(URLLoaderClientImplTest, OnCompleteWithResponseBody) {
network::ResourceResponseHead response_head;
network::URLLoaderCompletionStatus status;
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
mojo::DataPipe data_pipe(DataPipeOptions());
url_loader_client_->OnStartLoadingResponseBody(
std::move(data_pipe.consumer_handle));
@@ -217,7 +201,7 @@ TEST_F(URLLoaderClientImplTest, OnCompleteShouldBeTheLastMessage) {
network::ResourceResponseHead response_head;
network::URLLoaderCompletionStatus status;
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
mojo::DataPipe data_pipe(DataPipeOptions());
url_loader_client_->OnStartLoadingResponseBody(
std::move(data_pipe.consumer_handle));
@@ -249,7 +233,7 @@ TEST_F(URLLoaderClientImplTest, CancelOnReceiveResponse) {
network::ResourceResponseHead response_head;
network::URLLoaderCompletionStatus status;
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
mojo::DataPipe data_pipe(DataPipeOptions());
url_loader_client_->OnStartLoadingResponseBody(
std::move(data_pipe.consumer_handle));
@@ -278,7 +262,7 @@ TEST_F(URLLoaderClientImplTest, CancelOnReceiveData) {
ASSERT_EQ(MOJO_RESULT_OK, result);
EXPECT_EQ(5u, size);
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
url_loader_client_->OnStartLoadingResponseBody(
std::move(data_pipe.consumer_handle));
url_loader_client_->OnComplete(status);
@@ -299,7 +283,7 @@ TEST_F(URLLoaderClientImplTest, Defer) {
network::ResourceResponseHead response_head;
network::URLLoaderCompletionStatus status;
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
url_loader_client_->OnComplete(status);
EXPECT_FALSE(request_peer_context_.received_response);
@@ -324,7 +308,7 @@ TEST_F(URLLoaderClientImplTest, DeferWithResponseBody) {
network::ResourceResponseHead response_head;
network::URLLoaderCompletionStatus status;
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
mojo::DataPipe data_pipe(DataPipeOptions());
uint32_t size = 5;
MojoResult result = data_pipe.producer_handle->WriteData(
@@ -365,7 +349,7 @@ TEST_F(URLLoaderClientImplTest, DeferWithTransferSizeUpdated) {
network::ResourceResponseHead response_head;
network::URLLoaderCompletionStatus status;
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
mojo::DataPipe data_pipe(DataPipeOptions());
uint32_t size = 5;
MojoResult result = data_pipe.producer_handle->WriteData(
@@ -413,7 +397,7 @@ TEST_F(URLLoaderClientImplTest, SetDeferredDuringFlushingDeferredMessage) {
network::URLLoaderCompletionStatus status;
url_loader_client_->OnReceiveRedirect(redirect_info, response_head);
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
mojo::DataPipe data_pipe(DataPipeOptions());
uint32_t size = 5;
MojoResult result = data_pipe.producer_handle->WriteData(
@@ -474,7 +458,7 @@ TEST_F(URLLoaderClientImplTest,
network::ResourceResponseHead response_head;
network::URLLoaderCompletionStatus status;
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
url_loader_client_->OnTransferSizeUpdated(4);
url_loader_client_->OnComplete(status);
@@ -523,7 +507,7 @@ TEST_F(URLLoaderClientImplTest, CancelOnReceiveDataWhileFlushing) {
ASSERT_EQ(MOJO_RESULT_OK, result);
EXPECT_EQ(5u, size);
- url_loader_client_->OnReceiveResponse(response_head, nullptr);
+ url_loader_client_->OnReceiveResponse(response_head);
url_loader_client_->OnStartLoadingResponseBody(
std::move(data_pipe.consumer_handle));
url_loader_client_->OnComplete(status);
diff --git a/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc b/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc
index 3038533caa2..fb32f809835 100644
--- a/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc
+++ b/chromium/content/renderer/loader/url_response_body_consumer_unittest.cc
@@ -55,10 +55,6 @@ class TestRequestPeer : public RequestPeer {
ADD_FAILURE() << "OnStartLoadingResponseBody should not be called.";
}
- void OnDownloadedData(int len, int encoded_data_length) override {
- ADD_FAILURE() << "OnDownloadedData should not be called.";
- }
-
void OnReceivedData(std::unique_ptr<ReceivedData> data) override {
EXPECT_FALSE(context_->complete);
context_->data.append(data->payload(), data->length());
diff --git a/chromium/content/renderer/loader/web_url_loader_impl.cc b/chromium/content/renderer/loader/web_url_loader_impl.cc
index c1ece37554f..b031f857bb1 100644
--- a/chromium/content/renderer/loader/web_url_loader_impl.cc
+++ b/chromium/content/renderer/loader/web_url_loader_impl.cc
@@ -89,6 +89,7 @@ using blink::WebURLLoader;
using blink::WebURLLoaderClient;
using blink::WebURLRequest;
using blink::WebURLResponse;
+using blink::scheduler::WebResourceLoadingTaskRunnerHandle;
namespace content {
@@ -367,21 +368,28 @@ WebURLLoaderFactoryImpl::CreateTestOnlyFactory() {
std::unique_ptr<blink::WebURLLoader> WebURLLoaderFactoryImpl::CreateURLLoader(
const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ std::unique_ptr<WebResourceLoadingTaskRunnerHandle> task_runner_handle) {
if (!loader_factory_) {
// In some tests like RenderViewTests loader_factory_ is not available.
// These tests can still use data URLs to bypass the ResourceDispatcher.
- if (!task_runner)
- task_runner = base::ThreadTaskRunnerHandle::Get();
+ if (!task_runner_handle) {
+ // TODO(altimin): base::ThreadTaskRunnerHandle::Get is deprecated in
+ // the renderer. Fix this for frame and non-frame clients.
+ task_runner_handle =
+ WebResourceLoadingTaskRunnerHandle::CreateUnprioritized(
+ base::ThreadTaskRunnerHandle::Get());
+ }
+
return std::make_unique<WebURLLoaderImpl>(resource_dispatcher_.get(),
- std::move(task_runner),
+ std::move(task_runner_handle),
nullptr /* factory */);
}
- DCHECK(task_runner);
+ DCHECK(task_runner_handle);
DCHECK(resource_dispatcher_);
- return std::make_unique<WebURLLoaderImpl>(
- resource_dispatcher_.get(), std::move(task_runner), loader_factory_);
+ return std::make_unique<WebURLLoaderImpl>(resource_dispatcher_.get(),
+ std::move(task_runner_handle),
+ loader_factory_);
}
// This inner class exists since the WebURLLoader may be deleted while inside a
@@ -391,11 +399,12 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context> {
public:
using ReceivedData = RequestPeer::ReceivedData;
- Context(WebURLLoaderImpl* loader,
- ResourceDispatcher* resource_dispatcher,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- scoped_refptr<network::SharedURLLoaderFactory> factory,
- mojom::KeepAliveHandlePtr keep_alive_handle);
+ Context(
+ WebURLLoaderImpl* loader,
+ ResourceDispatcher* resource_dispatcher,
+ std::unique_ptr<WebResourceLoadingTaskRunnerHandle> task_runner_handle,
+ scoped_refptr<network::SharedURLLoaderFactory> factory,
+ mojom::KeepAliveHandlePtr keep_alive_handle);
ResourceDispatcher* resource_dispatcher() { return resource_dispatcher_; }
int request_id() const { return request_id_; }
@@ -417,7 +426,6 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context> {
const network::ResourceResponseInfo& info);
void OnReceivedResponse(const network::ResourceResponseInfo& info);
void OnStartLoadingResponseBody(mojo::ScopedDataPipeConsumerHandle body);
- void OnDownloadedData(int len, int encoded_data_length);
void OnReceivedData(std::unique_ptr<ReceivedData> data);
void OnTransferSizeUpdated(int transfer_size_diff);
void OnReceivedCachedMetadata(const char* data, int len);
@@ -450,6 +458,7 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context> {
WebURLLoaderClient* client_;
ResourceDispatcher* resource_dispatcher_;
+ std::unique_ptr<WebResourceLoadingTaskRunnerHandle> task_runner_handle_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
std::unique_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_;
std::unique_ptr<SharedMemoryDataConsumerHandle::Writer> body_stream_writer_;
@@ -477,7 +486,6 @@ class WebURLLoaderImpl::RequestPeerImpl : public RequestPeer {
void OnReceivedResponse(const network::ResourceResponseInfo& info) override;
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override;
- 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 OnReceivedCachedMetadata(const char* data, int len) override;
@@ -504,7 +512,6 @@ class WebURLLoaderImpl::SinkPeer : public RequestPeer {
void OnReceivedResponse(const network::ResourceResponseInfo& info) override {}
void OnStartLoadingResponseBody(
mojo::ScopedDataPipeConsumerHandle body) override {}
- 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 OnReceivedCachedMetadata(const char* data, int len) override {}
@@ -524,7 +531,7 @@ class WebURLLoaderImpl::SinkPeer : public RequestPeer {
WebURLLoaderImpl::Context::Context(
WebURLLoaderImpl* loader,
ResourceDispatcher* resource_dispatcher,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ std::unique_ptr<WebResourceLoadingTaskRunnerHandle> task_runner_handle,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
mojom::KeepAliveHandlePtr keep_alive_handle_ptr)
: loader_(loader),
@@ -532,7 +539,8 @@ WebURLLoaderImpl::Context::Context(
report_raw_headers_(false),
client_(nullptr),
resource_dispatcher_(resource_dispatcher),
- task_runner_(std::move(task_runner)),
+ task_runner_handle_(std::move(task_runner_handle)),
+ task_runner_(task_runner_handle_->GetTaskRunner()),
keep_alive_handle_(
keep_alive_handle_ptr
? std::make_unique<KeepAliveHandleWithChildProcessReference>(
@@ -583,10 +591,11 @@ void WebURLLoaderImpl::Context::SetDefersLoading(bool value) {
void WebURLLoaderImpl::Context::DidChangePriority(
WebURLRequest::Priority new_priority, int intra_priority_value) {
if (request_id_ != -1) {
- resource_dispatcher_->DidChangePriority(
- request_id_,
- ConvertWebKitPriorityToNetPriority(new_priority),
- intra_priority_value);
+ net::RequestPriority net_priority =
+ ConvertWebKitPriorityToNetPriority(new_priority);
+ resource_dispatcher_->DidChangePriority(request_id_, net_priority,
+ intra_priority_value);
+ task_runner_handle_->DidChangeRequestPriority(net_priority);
}
}
@@ -644,6 +653,7 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
resource_request->method = method;
resource_request->url = url_;
resource_request->site_for_cookies = request.SiteForCookies();
+ resource_request->upgrade_if_insecure = request.UpgradeIfInsecure();
resource_request->request_initiator =
request.RequestorOrigin().IsNull()
? base::Optional<url::Origin>()
@@ -698,7 +708,6 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
resource_request->fetch_frame_type = request.GetFrameType();
resource_request->request_body =
GetRequestBodyForWebURLRequest(request).get();
- resource_request->download_to_file = request.DownloadToFile();
resource_request->keepalive = request.GetKeepalive();
resource_request->has_user_gesture = request.HasUserGesture();
resource_request->enable_load_timing = true;
@@ -712,6 +721,7 @@ void WebURLLoaderImpl::Context::Start(const WebURLRequest& request,
resource_request->report_raw_headers = request.ReportRawHeaders();
resource_request->previews_state =
static_cast<int>(request.GetPreviewsState());
+ resource_request->throttling_profile_id = request.GetDevToolsToken();
// The network request has already been made by the browser. The renderer
// should bind the URLLoaderClientEndpoints stored in |response_override| to
@@ -882,12 +892,6 @@ void WebURLLoaderImpl::Context::OnStartLoadingResponseBody(
client_->DidStartLoadingResponseBody(std::move(body));
}
-void WebURLLoaderImpl::Context::OnDownloadedData(int len,
- int encoded_data_length) {
- if (client_)
- client_->DidDownloadData(len, encoded_data_length);
-}
-
void WebURLLoaderImpl::Context::OnReceivedData(
std::unique_ptr<ReceivedData> data) {
const char* payload = data->payload();
@@ -964,7 +968,7 @@ void WebURLLoaderImpl::Context::OnCompletedRequest(
} else {
client_->DidFinishLoading(status.completion_time, total_transfer_size,
encoded_body_size, status.decoded_body_length,
- status.blocked_cross_site_document);
+ status.should_report_corb_blocking);
}
}
}
@@ -1003,8 +1007,8 @@ bool WebURLLoaderImpl::Context::CanHandleDataURLRequestLocally(
return false;
// The fast paths for data URL, Start() and HandleDataURL(), don't support
- // the downloadToFile option.
- if (request.DownloadToFile() || request.PassResponsePipeToClient())
+ // the PassResponsePipeToClient option.
+ if (request.PassResponsePipeToClient())
return false;
// Data url requests from object tags may need to be intercepted as streams
@@ -1099,12 +1103,6 @@ void WebURLLoaderImpl::RequestPeerImpl::OnStartLoadingResponseBody(
context_->OnStartLoadingResponseBody(std::move(body));
}
-void WebURLLoaderImpl::RequestPeerImpl::OnDownloadedData(
- int len,
- int encoded_data_length) {
- context_->OnDownloadedData(len, encoded_data_length);
-}
-
void WebURLLoaderImpl::RequestPeerImpl::OnReceivedData(
std::unique_ptr<ReceivedData> data) {
if (discard_body_)
@@ -1134,21 +1132,21 @@ void WebURLLoaderImpl::RequestPeerImpl::OnCompletedRequest(
WebURLLoaderImpl::WebURLLoaderImpl(
ResourceDispatcher* resource_dispatcher,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ std::unique_ptr<WebResourceLoadingTaskRunnerHandle> task_runner_handle,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
: WebURLLoaderImpl(resource_dispatcher,
- std::move(task_runner),
+ std::move(task_runner_handle),
std::move(url_loader_factory),
nullptr) {}
WebURLLoaderImpl::WebURLLoaderImpl(
ResourceDispatcher* resource_dispatcher,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ std::unique_ptr<WebResourceLoadingTaskRunnerHandle> task_runner_handle,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
mojom::KeepAliveHandlePtr keep_alive_handle)
: context_(new Context(this,
resource_dispatcher,
- std::move(task_runner),
+ std::move(task_runner_handle),
std::move(url_loader_factory),
std::move(keep_alive_handle))) {}
@@ -1181,8 +1179,6 @@ void WebURLLoaderImpl::PopulateURLResponse(
response->SetRemotePort(info.socket_address.port());
response->SetConnectionID(info.load_timing.socket_log_id);
response->SetConnectionReused(info.load_timing.socket_reused);
- response->SetDownloadFilePath(
- blink::FilePathToWebString(info.download_file_path));
response->SetWasFetchedViaSPDY(info.was_fetched_via_spdy);
response->SetWasFetchedViaServiceWorker(info.was_fetched_via_service_worker);
response->SetWasFallbackRequiredByServiceWorker(
@@ -1207,6 +1203,7 @@ void WebURLLoaderImpl::PopulateURLResponse(
response->SetAlpnNegotiatedProtocol(
WebString::FromUTF8(info.alpn_negotiated_protocol));
response->SetConnectionInfo(info.connection_info);
+ response->SetAsyncRevalidationRequested(info.async_revalidation_requested);
SetSecurityStyleAndDetails(url, info, response, report_security_info);
@@ -1297,7 +1294,6 @@ void WebURLLoaderImpl::LoadSynchronously(
WebData& data,
int64_t& encoded_data_length,
int64_t& encoded_body_length,
- base::Optional<int64_t>& downloaded_file_length,
blink::WebBlobInfo& downloaded_blob) {
TRACE_EVENT0("loading", "WebURLLoaderImpl::loadSynchronously");
SyncLoadResponse sync_load_response;
@@ -1313,10 +1309,8 @@ void WebURLLoaderImpl::LoadSynchronously(
const int error_code = sync_load_response.error_code;
if (error_code != net::OK) {
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);
+ error = WebURLError(*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.
@@ -1335,7 +1329,6 @@ void WebURLLoaderImpl::LoadSynchronously(
request.ReportRawHeaders());
encoded_data_length = sync_load_response.info.encoded_data_length;
encoded_body_length = sync_load_response.info.encoded_body_length;
- downloaded_file_length = sync_load_response.downloaded_file_length;
if (sync_load_response.downloaded_blob) {
downloaded_blob = blink::WebBlobInfo(
WebString::FromLatin1(sync_load_response.downloaded_blob->uuid),
diff --git a/chromium/content/renderer/loader/web_url_loader_impl.h b/chromium/content/renderer/loader/web_url_loader_impl.h
index ced62e5a71b..890893884c1 100644
--- a/chromium/content/renderer/loader/web_url_loader_impl.h
+++ b/chromium/content/renderer/loader/web_url_loader_impl.h
@@ -5,6 +5,8 @@
#ifndef CONTENT_RENDERER_LOADER_WEB_URL_LOADER_IMPL_H_
#define CONTENT_RENDERER_LOADER_WEB_URL_LOADER_IMPL_H_
+#include <memory>
+
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
@@ -12,13 +14,10 @@
#include "mojo/public/cpp/system/data_pipe.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "third_party/blink/public/platform/scheduler/web_resource_loading_task_runner_handle.h"
#include "third_party/blink/public/platform/web_url_loader.h"
#include "third_party/blink/public/platform/web_url_loader_factory.h"
-namespace base {
-class SingleThreadTaskRunner;
-}
-
namespace network {
struct ResourceResponseInfo;
}
@@ -41,7 +40,8 @@ class CONTENT_EXPORT WebURLLoaderFactoryImpl
std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
+ std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle>
+ task_runner_handle) override;
private:
base::WeakPtr<ResourceDispatcher> resource_dispatcher_;
@@ -53,13 +53,15 @@ class CONTENT_EXPORT WebURLLoaderImpl : public blink::WebURLLoader {
public:
WebURLLoaderImpl(
ResourceDispatcher* resource_dispatcher,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle>
+ task_runner_handle,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
// When non-null |keep_alive_handle| is specified, this loader prolongs
// this render process's lifetime.
WebURLLoaderImpl(
ResourceDispatcher* resource_dispatcher,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle>
+ task_runner_handle,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
mojom::KeepAliveHandlePtr keep_alive_handle);
~WebURLLoaderImpl() override;
@@ -76,7 +78,6 @@ class CONTENT_EXPORT WebURLLoaderImpl : public blink::WebURLLoader {
blink::WebData& data,
int64_t& encoded_data_length,
int64_t& encoded_body_length,
- base::Optional<int64_t>& downloaded_file_length,
blink::WebBlobInfo& downloaded_blob) override;
void LoadAsynchronously(const blink::WebURLRequest& request,
blink::WebURLLoaderClient* client) override;
diff --git a/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc b/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc
index e3fd5112703..9a92c2bcb8f 100644
--- a/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc
+++ b/chromium/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -39,6 +39,7 @@
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url_error.h"
#include "third_party/blink/public/platform/web_url_loader_client.h"
@@ -77,7 +78,7 @@ class TestResourceDispatcher : public ResourceDispatcher {
SyncLoadResponse* response,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles,
- double timeout,
+ base::TimeDelta timeout,
blink::mojom::BlobRegistryPtrInfo download_to_blob_registry,
std::unique_ptr<RequestPeer> peer) override {
*response = std::move(sync_load_response_);
@@ -175,7 +176,9 @@ class TestWebURLLoaderClient : public blink::WebURLLoaderClient {
TestWebURLLoaderClient(ResourceDispatcher* dispatcher)
: loader_(new WebURLLoaderImpl(
dispatcher,
- blink::scheduler::GetSingleThreadTaskRunnerForTesting(),
+ blink::scheduler::WebResourceLoadingTaskRunnerHandle::
+ CreateUnprioritized(
+ blink::scheduler::GetSingleThreadTaskRunnerForTesting()),
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
&fake_url_loader_factory_))),
delete_on_receive_redirect_(false),
@@ -224,10 +227,6 @@ class TestWebURLLoaderClient : public blink::WebURLLoaderClient {
loader_.reset();
}
- void DidDownloadData(int dataLength, int encodedDataLength) override {
- EXPECT_TRUE(loader_);
- }
-
void DidReceiveData(const char* data, int dataLength) override {
EXPECT_TRUE(loader_);
// The response should have started, but must not have finished, or failed.
@@ -245,7 +244,7 @@ class TestWebURLLoaderClient : public blink::WebURLLoaderClient {
int64_t totalEncodedDataLength,
int64_t totalEncodedBodyLength,
int64_t totalDecodedBodyLength,
- bool blocked_cross_site_document) override {
+ bool should_report_corb_blocking) override {
EXPECT_TRUE(loader_);
EXPECT_TRUE(did_receive_response_);
EXPECT_FALSE(did_finish_);
@@ -796,15 +795,13 @@ TEST_F(WebURLLoaderImplTest, SyncLengths) {
blink::WebData data;
int64_t encoded_data_length = 0;
int64_t encoded_body_length = 0;
- base::Optional<int64_t> downloaded_file_length;
blink::WebBlobInfo downloaded_blob;
- client()->loader()->LoadSynchronously(
- request, nullptr, response, error, data, encoded_data_length,
- encoded_body_length, downloaded_file_length, downloaded_blob);
+ client()->loader()->LoadSynchronously(request, nullptr, response, error, data,
+ encoded_data_length,
+ encoded_body_length, downloaded_blob);
EXPECT_EQ(kEncodedBodyLength, encoded_body_length);
EXPECT_EQ(kEncodedDataLength, encoded_data_length);
- EXPECT_FALSE(downloaded_file_length);
EXPECT_TRUE(downloaded_blob.Uuid().IsNull());
}
diff --git a/chromium/content/renderer/loader/web_url_request_util.cc b/chromium/content/renderer/loader/web_url_request_util.cc
index 9dacb1aad64..bceb21b9362 100644
--- a/chromium/content/renderer/loader/web_url_request_util.cc
+++ b/chromium/content/renderer/loader/web_url_request_util.cc
@@ -30,6 +30,7 @@
#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_data.h"
+#include "third_party/blink/public/platform/web_http_body.h"
#include "third_party/blink/public/platform/web_http_header_visitor.h"
#include "third_party/blink/public/platform/web_mixed_content.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -291,6 +292,8 @@ int GetLoadFlagsForWebURLRequest(const WebURLRequest& request) {
if (extra_data->is_for_no_state_prefetch())
load_flags |= net::LOAD_PREFETCH;
}
+ if (request.SupportsAsyncRevalidation())
+ load_flags |= net::LOAD_SUPPORT_ASYNC_REVALIDATION;
return load_flags;
}
@@ -389,12 +392,7 @@ scoped_refptr<network::ResourceRequestBody> GetRequestBodyForWebHTTPBody(
while (httpBody.ElementAt(i++, element)) {
switch (element.type) {
case WebHTTPBody::Element::kTypeData:
- element.data.ForEachSegment([&request_body](const char* segment,
- size_t segment_size,
- size_t segment_offset) {
- request_body->AppendBytes(segment, static_cast<int>(segment_size));
- return true;
- });
+ request_body->AppendBytes(element.data.Copy().ReleaseVector());
break;
case WebHTTPBody::Element::kTypeFile:
if (element.file_length == -1) {
diff --git a/chromium/content/renderer/service_worker/worker_fetch_context_impl.cc b/chromium/content/renderer/loader/web_worker_fetch_context_impl.cc
index bc16217cbdc..d548ae54b5d 100644
--- a/chromium/content/renderer/service_worker/worker_fetch_context_impl.cc
+++ b/chromium/content/renderer/loader/web_worker_fetch_context_impl.cc
@@ -2,16 +2,20 @@
// 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/worker_fetch_context_impl.h"
+#include "content/renderer/loader/web_worker_fetch_context_impl.h"
+
+#include <utility>
#include "base/feature_list.h"
#include "base/single_thread_task_runner.h"
+#include "base/task_scheduler/post_task.h"
#include "content/child/child_thread_impl.h"
#include "content/child/thread_safe_sender.h"
+#include "content/common/content_constants_internal.h"
#include "content/common/frame_messages.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
-#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/common/content_features.h"
+#include "content/public/common/origin_util.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/renderer/url_loader_throttle_provider.h"
#include "content/public/renderer/websocket_handshake_throttle_provider.h"
@@ -25,31 +29,35 @@
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
#include "services/service_manager/public/cpp/connector.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
+#include "third_party/blink/public/platform/web_security_origin.h"
namespace content {
-WorkerFetchContextImpl::RewriteURLFunction g_rewrite_url = nullptr;
+WebWorkerFetchContextImpl::RewriteURLFunction g_rewrite_url = nullptr;
namespace {
// Runs on IO thread.
-void CreateSubresourceLoaderFactory(
+void CreateSubresourceLoaderFactoryForWorker(
mojom::ServiceWorkerContainerHostPtrInfo container_host_info,
const std::string& client_id,
std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory,
- network::mojom::URLLoaderFactoryRequest request) {
+ network::mojom::URLLoaderFactoryRequest request,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
ServiceWorkerSubresourceLoaderFactory::Create(
base::MakeRefCounted<ControllerServiceWorkerConnector>(
- std::move(container_host_info), client_id),
+ std::move(container_host_info), nullptr /* controller_ptr */,
+ client_id),
network::SharedURLLoaderFactory::Create(std::move(fallback_factory)),
- std::move(request));
+ std::move(request), std::move(task_runner));
}
} // namespace
// static
-void WorkerFetchContextImpl::InstallRewriteURLFunction(
+void WebWorkerFetchContextImpl::InstallRewriteURLFunction(
RewriteURLFunction rewrite_url) {
CHECK(!g_rewrite_url);
g_rewrite_url = rewrite_url;
@@ -60,7 +68,7 @@ void WorkerFetchContextImpl::InstallRewriteURLFunction(
// worker fetch context is controlled by a service worker, it creates a loader
// that uses |service_worker_loader_factory_| for requests that should be
// intercepted by the service worker.
-class WorkerFetchContextImpl::Factory : public blink::WebURLLoaderFactory {
+class WebWorkerFetchContextImpl::Factory : public blink::WebURLLoaderFactory {
public:
Factory(base::WeakPtr<ResourceDispatcher> resource_dispatcher,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory)
@@ -71,17 +79,29 @@ class WorkerFetchContextImpl::Factory : public blink::WebURLLoaderFactory {
std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
- DCHECK(task_runner);
+ std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle>
+ task_runner_handle) override {
+ DCHECK(task_runner_handle);
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_);
+ if (CanCreateServiceWorkerURLLoader(request)) {
+ // 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_handle),
+ service_worker_loader_factory_);
+ }
+
+ return std::make_unique<WebURLLoaderImpl>(resource_dispatcher_.get(),
+ std::move(task_runner_handle),
+ loader_factory_);
}
void SetServiceWorkerURLLoaderFactory(
network::mojom::URLLoaderFactoryPtr service_worker_loader_factory) {
+ if (!service_worker_loader_factory) {
+ service_worker_loader_factory_ = nullptr;
+ return;
+ }
service_worker_loader_factory_ =
base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
std::move(service_worker_loader_factory));
@@ -90,9 +110,7 @@ class WorkerFetchContextImpl::Factory : public blink::WebURLLoaderFactory {
base::WeakPtr<Factory> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); }
private:
- std::unique_ptr<blink::WebURLLoader> CreateServiceWorkerURLLoader(
- const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
+ bool CanCreateServiceWorkerURLLoader(const blink::WebURLRequest& request) {
// TODO(horo): Unify this code path with
// ServiceWorkerNetworkProvider::CreateURLLoader that is used for document
// cases.
@@ -100,21 +118,24 @@ class WorkerFetchContextImpl::Factory : public blink::WebURLLoaderFactory {
// We need the service worker loader factory populated in order to create
// our own URLLoader for subresource loading via a service worker.
if (!service_worker_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;
+ return false;
+
+ // If the URL is not http(s) or otherwise whitelisted, do not intercept the
+ // request. Schemes like 'blob' and 'file' are not eligible to be
+ // intercepted by service workers.
+ // TODO(falken): Let ServiceWorkerSubresourceLoaderFactory handle the
+ // request and move this check there (i.e., for such URLs, it should use
+ // its fallback factory).
+ if (!GURL(request.Url()).SchemeIsHTTPOrHTTPS() &&
+ !OriginCanAccessServiceWorkers(request.Url())) {
+ return false;
+ }
// If GetSkipServiceWorker() returns true, no need to intercept the request.
if (request.GetSkipServiceWorker())
- return nullptr;
+ return false;
- // 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_loader_factory_);
+ return true;
}
base::WeakPtr<ResourceDispatcher> resource_dispatcher_;
@@ -124,8 +145,11 @@ class WorkerFetchContextImpl::Factory : public blink::WebURLLoaderFactory {
DISALLOW_COPY_AND_ASSIGN(Factory);
};
-WorkerFetchContextImpl::WorkerFetchContextImpl(
+WebWorkerFetchContextImpl::WebWorkerFetchContextImpl(
+ RendererPreferences renderer_preferences,
mojom::ServiceWorkerWorkerClientRequest service_worker_client_request,
+ mojom::ServiceWorkerWorkerClientRegistryPtrInfo
+ service_worker_worker_client_registry_info,
mojom::ServiceWorkerContainerHostPtrInfo service_worker_container_host_info,
std::unique_ptr<network::SharedURLLoaderFactoryInfo> loader_factory_info,
std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory_info,
@@ -133,54 +157,69 @@ WorkerFetchContextImpl::WorkerFetchContextImpl(
std::unique_ptr<WebSocketHandshakeThrottleProvider>
websocket_handshake_throttle_provider,
ThreadSafeSender* thread_safe_sender,
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
+ std::unique_ptr<service_manager::Connector> service_manager_connection)
: binding_(this),
service_worker_client_request_(std::move(service_worker_client_request)),
+ service_worker_worker_client_registry_info_(
+ std::move(service_worker_worker_client_registry_info)),
service_worker_container_host_info_(
std::move(service_worker_container_host_info)),
loader_factory_info_(std::move(loader_factory_info)),
fallback_factory_info_(std::move(fallback_factory_info)),
thread_safe_sender_(thread_safe_sender),
+ renderer_preferences_(std::move(renderer_preferences)),
throttle_provider_(std::move(throttle_provider)),
websocket_handshake_throttle_provider_(
std::move(websocket_handshake_throttle_provider)),
- io_task_runner_(std::move(io_task_runner)) {
- if (ServiceWorkerUtils::IsServicificationEnabled()) {
- ChildThreadImpl::current()->GetConnector()->BindInterface(
- mojom::kBrowserServiceName,
- mojo::MakeRequest(&blob_registry_ptr_info_));
- }
-}
+ service_manager_connection_(std::move(service_manager_connection)) {}
-WorkerFetchContextImpl::~WorkerFetchContextImpl() {}
+WebWorkerFetchContextImpl::~WebWorkerFetchContextImpl() {}
-void WorkerFetchContextImpl::SetTerminateSyncLoadEvent(
+void WebWorkerFetchContextImpl::SetTerminateSyncLoadEvent(
base::WaitableEvent* terminate_sync_load_event) {
DCHECK(!terminate_sync_load_event_);
terminate_sync_load_event_ = terminate_sync_load_event;
}
std::unique_ptr<blink::WebWorkerFetchContext>
-WorkerFetchContextImpl::CloneForNestedWorker() {
- // TODO(japhet?): This doens't plumb service worker state to nested workers,
- // because dedicated workers in service worker-controlled documents are
- // currently not spec compliant and we don't want to propagate the wrong
- // behavior. See https://crbug.com/731604
- auto new_context = std::make_unique<WorkerFetchContextImpl>(
- mojom::ServiceWorkerWorkerClientRequest(),
- mojom::ServiceWorkerContainerHostPtrInfo(), loader_factory_->Clone(),
+WebWorkerFetchContextImpl::CloneForNestedWorker() {
+ mojom::ServiceWorkerWorkerClientRequest service_worker_client_request;
+ mojom::ServiceWorkerWorkerClientPtr service_worker_client_ptr;
+ service_worker_client_request = mojo::MakeRequest(&service_worker_client_ptr);
+ service_worker_worker_client_registry_->RegisterWorkerClient(
+ std::move(service_worker_client_ptr));
+
+ mojom::ServiceWorkerWorkerClientRegistryPtrInfo
+ service_worker_worker_client_registry_ptr_info;
+ service_worker_worker_client_registry_->CloneWorkerClientRegistry(
+ mojo::MakeRequest(&service_worker_worker_client_registry_ptr_info));
+
+ mojom::ServiceWorkerContainerHostPtrInfo host_ptr_info;
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ service_worker_container_host_->CloneForWorker(
+ mojo::MakeRequest(&host_ptr_info));
+ }
+
+ auto new_context = std::make_unique<WebWorkerFetchContextImpl>(
+ renderer_preferences_, std::move(service_worker_client_request),
+ std::move(service_worker_worker_client_registry_ptr_info),
+ std::move(host_ptr_info), loader_factory_->Clone(),
fallback_factory_->Clone(),
throttle_provider_ ? throttle_provider_->Clone() : nullptr,
websocket_handshake_throttle_provider_
? websocket_handshake_throttle_provider_->Clone()
: nullptr,
- thread_safe_sender_.get(), io_task_runner_);
+ thread_safe_sender_.get(), service_manager_connection_->Clone());
+ new_context->service_worker_provider_id_ = service_worker_provider_id_;
+ new_context->is_controlled_by_service_worker_ =
+ is_controlled_by_service_worker_;
new_context->is_on_sub_frame_ = is_on_sub_frame_;
+ new_context->ancestor_frame_id_ = ancestor_frame_id_;
new_context->appcache_host_id_ = appcache_host_id_;
return new_context;
}
-void WorkerFetchContextImpl::InitializeOnWorkerThread() {
+void WebWorkerFetchContextImpl::InitializeOnWorkerThread() {
DCHECK(!resource_dispatcher_);
DCHECK(!binding_.is_bound());
resource_dispatcher_ = std::make_unique<ResourceDispatcher>();
@@ -194,12 +233,16 @@ void WorkerFetchContextImpl::InitializeOnWorkerThread() {
if (service_worker_client_request_.is_pending())
binding_.Bind(std::move(service_worker_client_request_));
- if (ServiceWorkerUtils::IsServicificationEnabled()) {
+ service_worker_worker_client_registry_.Bind(
+ std::move(service_worker_worker_client_registry_info_));
+
+ if (blink::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_));
+ service_manager_connection_->BindInterface(
+ mojom::kBrowserServiceName, mojo::MakeRequest(&blob_registry_ptr));
blob_registry_ = base::MakeRefCounted<
base::RefCountedData<blink::mojom::BlobRegistryPtr>>(
std::move(blob_registry_ptr));
@@ -207,21 +250,21 @@ void WorkerFetchContextImpl::InitializeOnWorkerThread() {
}
std::unique_ptr<blink::WebURLLoaderFactory>
-WorkerFetchContextImpl::CreateURLLoaderFactory() {
+WebWorkerFetchContextImpl::CreateURLLoaderFactory() {
DCHECK(loader_factory_);
DCHECK(!web_loader_factory_);
auto factory = std::make_unique<Factory>(resource_dispatcher_->GetWeakPtr(),
loader_factory_);
web_loader_factory_ = factory->GetWeakPtr();
- if (ServiceWorkerUtils::IsServicificationEnabled())
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
ResetServiceWorkerURLLoaderFactory();
return factory;
}
std::unique_ptr<blink::WebURLLoaderFactory>
-WorkerFetchContextImpl::WrapURLLoaderFactory(
+WebWorkerFetchContextImpl::WrapURLLoaderFactory(
mojo::ScopedMessagePipeHandle url_loader_factory_handle) {
return std::make_unique<WebURLLoaderFactoryImpl>(
resource_dispatcher_->GetWeakPtr(),
@@ -231,19 +274,25 @@ WorkerFetchContextImpl::WrapURLLoaderFactory(
network::mojom::URLLoaderFactory::Version_)));
}
-void WorkerFetchContextImpl::WillSendRequest(blink::WebURLRequest& request) {
+void WebWorkerFetchContextImpl::WillSendRequest(blink::WebURLRequest& request) {
+ if (renderer_preferences_.enable_do_not_track) {
+ request.SetHTTPHeaderField(blink::WebString::FromUTF8(kDoNotTrackHeader),
+ "1");
+ }
+
auto extra_data = std::make_unique<RequestExtraData>();
extra_data->set_service_worker_provider_id(service_worker_provider_id_);
- extra_data->set_render_frame_id(parent_frame_id_);
+ extra_data->set_render_frame_id(ancestor_frame_id_);
extra_data->set_initiated_in_secure_context(is_secure_context_);
if (throttle_provider_) {
extra_data->set_url_loader_throttles(throttle_provider_->CreateThrottles(
- parent_frame_id_, request, WebURLRequestToResourceType(request)));
+ ancestor_frame_id_, request, WebURLRequestToResourceType(request)));
}
request.SetExtraData(std::move(extra_data));
request.SetAppCacheHostID(appcache_host_id_);
- if (!IsControlledByServiceWorker()) {
+ if (IsControlledByServiceWorker() ==
+ blink::mojom::ControllerServiceWorkerMode::kNoController) {
// TODO(falken): Is still this needed? It used to set kForeign for foreign
// fetch.
request.SetSkipServiceWorker(true);
@@ -251,116 +300,123 @@ void WorkerFetchContextImpl::WillSendRequest(blink::WebURLRequest& request) {
if (g_rewrite_url)
request.SetURL(g_rewrite_url(request.Url().GetString().Utf8(), false));
+
+ if (!renderer_preferences_.enable_referrers) {
+ request.SetHTTPReferrer(blink::WebString(),
+ blink::kWebReferrerPolicyDefault);
+ }
}
-bool WorkerFetchContextImpl::IsControlledByServiceWorker() const {
- return is_controlled_by_service_worker_ ||
- (controller_version_id_ !=
- blink::mojom::kInvalidServiceWorkerVersionId);
+blink::mojom::ControllerServiceWorkerMode
+WebWorkerFetchContextImpl::IsControlledByServiceWorker() const {
+ return is_controlled_by_service_worker_;
}
-void WorkerFetchContextImpl::SetIsOnSubframe(bool is_on_sub_frame) {
+void WebWorkerFetchContextImpl::SetIsOnSubframe(bool is_on_sub_frame) {
is_on_sub_frame_ = is_on_sub_frame;
}
-bool WorkerFetchContextImpl::IsOnSubframe() const {
+bool WebWorkerFetchContextImpl::IsOnSubframe() const {
return is_on_sub_frame_;
}
-blink::WebURL WorkerFetchContextImpl::SiteForCookies() const {
+blink::WebURL WebWorkerFetchContextImpl::SiteForCookies() const {
return site_for_cookies_;
}
-void WorkerFetchContextImpl::DidRunContentWithCertificateErrors() {
- Send(new FrameHostMsg_DidRunContentWithCertificateErrors(parent_frame_id_));
+void WebWorkerFetchContextImpl::DidRunContentWithCertificateErrors() {
+ Send(new FrameHostMsg_DidRunContentWithCertificateErrors(ancestor_frame_id_));
}
-void WorkerFetchContextImpl::DidDisplayContentWithCertificateErrors() {
+void WebWorkerFetchContextImpl::DidDisplayContentWithCertificateErrors() {
Send(new FrameHostMsg_DidDisplayContentWithCertificateErrors(
- parent_frame_id_));
+ ancestor_frame_id_));
}
-void WorkerFetchContextImpl::DidRunInsecureContent(
+void WebWorkerFetchContextImpl::DidRunInsecureContent(
const blink::WebSecurityOrigin& origin,
const blink::WebURL& url) {
Send(new FrameHostMsg_DidRunInsecureContent(
- parent_frame_id_, GURL(origin.ToString().Utf8()), url));
+ ancestor_frame_id_, GURL(origin.ToString().Utf8()), url));
}
-void WorkerFetchContextImpl::SetSubresourceFilterBuilder(
+void WebWorkerFetchContextImpl::SetSubresourceFilterBuilder(
std::unique_ptr<blink::WebDocumentSubresourceFilter::Builder>
subresource_filter_builder) {
subresource_filter_builder_ = std::move(subresource_filter_builder);
}
std::unique_ptr<blink::WebDocumentSubresourceFilter>
-WorkerFetchContextImpl::TakeSubresourceFilter() {
+WebWorkerFetchContextImpl::TakeSubresourceFilter() {
if (!subresource_filter_builder_)
return nullptr;
return std::move(subresource_filter_builder_)->Build();
}
std::unique_ptr<blink::WebSocketHandshakeThrottle>
-WorkerFetchContextImpl::CreateWebSocketHandshakeThrottle() {
+WebWorkerFetchContextImpl::CreateWebSocketHandshakeThrottle() {
if (!websocket_handshake_throttle_provider_)
return nullptr;
return websocket_handshake_throttle_provider_->CreateThrottle(
- parent_frame_id_);
+ ancestor_frame_id_);
}
-void WorkerFetchContextImpl::set_service_worker_provider_id(int id) {
+void WebWorkerFetchContextImpl::set_service_worker_provider_id(int id) {
service_worker_provider_id_ = id;
}
-void WorkerFetchContextImpl::set_is_controlled_by_service_worker(bool flag) {
- is_controlled_by_service_worker_ = flag;
+void WebWorkerFetchContextImpl::set_is_controlled_by_service_worker(
+ blink::mojom::ControllerServiceWorkerMode mode) {
+ is_controlled_by_service_worker_ = mode;
}
-void WorkerFetchContextImpl::set_parent_frame_id(int id) {
- parent_frame_id_ = id;
+void WebWorkerFetchContextImpl::set_ancestor_frame_id(int id) {
+ ancestor_frame_id_ = id;
}
-void WorkerFetchContextImpl::set_site_for_cookies(
+void WebWorkerFetchContextImpl::set_site_for_cookies(
const blink::WebURL& site_for_cookies) {
site_for_cookies_ = site_for_cookies;
}
-void WorkerFetchContextImpl::set_is_secure_context(bool flag) {
+void WebWorkerFetchContextImpl::set_is_secure_context(bool flag) {
is_secure_context_ = flag;
}
-void WorkerFetchContextImpl::set_origin_url(const GURL& origin_url) {
+void WebWorkerFetchContextImpl::set_origin_url(const GURL& origin_url) {
origin_url_ = origin_url;
}
-void WorkerFetchContextImpl::set_client_id(const std::string& client_id) {
+void WebWorkerFetchContextImpl::set_client_id(const std::string& client_id) {
client_id_ = client_id;
}
-void WorkerFetchContextImpl::SetApplicationCacheHostID(int id) {
+void WebWorkerFetchContextImpl::SetApplicationCacheHostID(int id) {
appcache_host_id_ = id;
}
-int WorkerFetchContextImpl::ApplicationCacheHostID() const {
+int WebWorkerFetchContextImpl::ApplicationCacheHostID() const {
return appcache_host_id_;
}
-void WorkerFetchContextImpl::SetControllerServiceWorker(
- int64_t controller_version_id) {
- controller_version_id_ = controller_version_id;
- if (ServiceWorkerUtils::IsServicificationEnabled())
+void WebWorkerFetchContextImpl::OnControllerChanged(
+ blink::mojom::ControllerServiceWorkerMode mode) {
+ set_is_controlled_by_service_worker(mode);
+
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
ResetServiceWorkerURLLoaderFactory();
}
-bool WorkerFetchContextImpl::Send(IPC::Message* message) {
+bool WebWorkerFetchContextImpl::Send(IPC::Message* message) {
return thread_safe_sender_->Send(message);
}
-void WorkerFetchContextImpl::ResetServiceWorkerURLLoaderFactory() {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+void WebWorkerFetchContextImpl::ResetServiceWorkerURLLoaderFactory() {
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
if (!web_loader_factory_)
return;
- if (!IsControlledByServiceWorker()) {
+ if (IsControlledByServiceWorker() !=
+ blink::mojom::ControllerServiceWorkerMode::kControlled) {
web_loader_factory_->SetServiceWorkerURLLoaderFactory(nullptr);
return;
}
@@ -370,12 +426,15 @@ void WorkerFetchContextImpl::ResetServiceWorkerURLLoaderFactory() {
service_worker_container_host_->CloneForWorker(
mojo::MakeRequest(&host_ptr_info));
// To avoid potential dead-lock while synchronous loading, create the
- // SubresourceLoaderFactory on the IO thread.
- io_task_runner_->PostTask(
+ // SubresourceLoaderFactory on a background thread.
+ auto task_runner = base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
+ task_runner->PostTask(
FROM_HERE,
- base::BindOnce(&CreateSubresourceLoaderFactory, std::move(host_ptr_info),
- client_id_, fallback_factory_->Clone(),
- mojo::MakeRequest(&service_worker_url_loader_factory)));
+ base::BindOnce(
+ &CreateSubresourceLoaderFactoryForWorker, std::move(host_ptr_info),
+ client_id_, fallback_factory_->Clone(),
+ mojo::MakeRequest(&service_worker_url_loader_factory), task_runner));
web_loader_factory_->SetServiceWorkerURLLoaderFactory(
std::move(service_worker_url_loader_factory));
}
diff --git a/chromium/content/renderer/service_worker/worker_fetch_context_impl.h b/chromium/content/renderer/loader/web_worker_fetch_context_impl.h
index 82217aa61f7..519e3bc570d 100644
--- a/chromium/content/renderer/service_worker/worker_fetch_context_impl.h
+++ b/chromium/content/renderer/loader/web_worker_fetch_context_impl.h
@@ -2,16 +2,21 @@
// 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_WORKER_FETCH_CONTEXT_IMPL_H_
-#define CONTENT_RENDERER_SERVICE_WORKER_WORKER_FETCH_CONTEXT_IMPL_H_
+#ifndef CONTENT_RENDERER_LOADER_WEB_WORKER_FETCH_CONTEXT_IMPL_H_
+#define CONTENT_RENDERER_LOADER_WEB_WORKER_FETCH_CONTEXT_IMPL_H_
+
+#include <memory>
+#include <string>
#include "base/synchronization/waitable_event.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/common/service_worker/service_worker_types.h"
+#include "content/public/common/renderer_preferences.h"
#include "ipc/ipc_message.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/platform/web_application_cache_host.h"
@@ -29,15 +34,19 @@ class ThreadSafeSender;
class URLLoaderThrottleProvider;
class WebSocketHandshakeThrottleProvider;
-// This class is used while fetching resource requests on workers (dedicated
+// This class is used for fetching resource requests from workers (dedicated
// worker and shared worker). This class is created on the main thread and
// passed to the worker thread. This class is not used for service workers. For
// service workers, ServiceWorkerFetchContextImpl class is used instead.
-class CONTENT_EXPORT WorkerFetchContextImpl
+class CONTENT_EXPORT WebWorkerFetchContextImpl
: public blink::WebWorkerFetchContext,
public mojom::ServiceWorkerWorkerClient {
public:
- // |loader_factory_info| is used for regular loading by the worker.
+ // |service_worker_client_request| is bound to |this| to receive
+ // OnControllerChanged() notifications.
+ // |service_worker_worker_client_registry_info| is a host pointer to register
+ // a new ServiceWorkerWorkerClient, which is needed when creating a nested
+ // worker. |loader_factory_info| is used for regular loading by the worker.
//
// S13nServiceWorker:
// If the worker is controlled by a service worker, this class makes another
@@ -51,8 +60,11 @@ class CONTENT_EXPORT WorkerFetchContextImpl
// |fallback_factory_info| might not be simply the direct network factory,
// because it might additionally support non-NetworkService schemes (e.g.,
// chrome-extension://).
- WorkerFetchContextImpl(
+ WebWorkerFetchContextImpl(
+ RendererPreferences renderer_preferences,
mojom::ServiceWorkerWorkerClientRequest service_worker_client_request,
+ mojom::ServiceWorkerWorkerClientRegistryPtrInfo
+ service_worker_worker_client_registry_info,
mojom::ServiceWorkerContainerHostPtrInfo
service_worker_container_host_info,
std::unique_ptr<network::SharedURLLoaderFactoryInfo> loader_factory_info,
@@ -62,8 +74,8 @@ class CONTENT_EXPORT WorkerFetchContextImpl
std::unique_ptr<WebSocketHandshakeThrottleProvider>
websocket_handshake_throttle_provider,
ThreadSafeSender* thread_safe_sender,
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
- ~WorkerFetchContextImpl() override;
+ std::unique_ptr<service_manager::Connector> service_manager_connection);
+ ~WebWorkerFetchContextImpl() override;
// blink::WebWorkerFetchContext implementation:
std::unique_ptr<blink::WebWorkerFetchContext> CloneForNestedWorker() override;
@@ -73,7 +85,8 @@ class CONTENT_EXPORT WorkerFetchContextImpl
std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory(
mojo::ScopedMessagePipeHandle url_loader_factory_handle) override;
void WillSendRequest(blink::WebURLRequest&) override;
- bool IsControlledByServiceWorker() const override;
+ blink::mojom::ControllerServiceWorkerMode IsControlledByServiceWorker()
+ const override;
void SetIsOnSubframe(bool) override;
bool IsOnSubframe() const override;
blink::WebURL SiteForCookies() const override;
@@ -91,13 +104,16 @@ class CONTENT_EXPORT WorkerFetchContextImpl
CreateWebSocketHandshakeThrottle() override;
// mojom::ServiceWorkerWorkerClient implementation:
- void SetControllerServiceWorker(int64_t controller_version_id) override;
+ void OnControllerChanged(blink::mojom::ControllerServiceWorkerMode) override;
- // Sets the fetch context status copied from the frame; the parent frame for a
- // dedicated worker, the main frame of the shadow page for a shared worker.
+ // Sets the fetch context status copied from a frame. For dedicated workers,
+ // it's copied from the ancestor frame (directly for non-nested workers, or
+ // indirectly via its parent worker for nested workers). For shared workers,
+ // it's copied from the shadow page.
void set_service_worker_provider_id(int id);
- void set_is_controlled_by_service_worker(bool flag);
- void set_parent_frame_id(int id);
+ void set_is_controlled_by_service_worker(
+ blink::mojom::ControllerServiceWorkerMode mode);
+ void set_ancestor_frame_id(int id);
void set_site_for_cookies(const blink::WebURL& site_for_cookies);
// Sets whether the worker context is a secure context.
// https://w3c.github.io/webappsec-secure-contexts/
@@ -121,20 +137,26 @@ class CONTENT_EXPORT WorkerFetchContextImpl
void ResetServiceWorkerURLLoaderFactory();
mojo::Binding<mojom::ServiceWorkerWorkerClient> binding_;
+ mojom::ServiceWorkerWorkerClientRegistryPtr
+ service_worker_worker_client_registry_;
// Bound to |this| on the worker thread.
mojom::ServiceWorkerWorkerClientRequest service_worker_client_request_;
+ // Consumed on the worker thread to create
+ // |service_worker_worker_client_registry_|.
+ mojom::ServiceWorkerWorkerClientRegistryPtrInfo
+ service_worker_worker_client_registry_info_;
// 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 |loader_factory_|.
std::unique_ptr<network::SharedURLLoaderFactoryInfo> loader_factory_info_;
// Consumed on the worker thread to create |fallback_factory_|.
std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory_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;
+ blink::mojom::ControllerServiceWorkerMode is_controlled_by_service_worker_ =
+ blink::mojom::ControllerServiceWorkerMode::kNoController;
+
// S13nServiceWorker:
// Initialized on the worker thread when InitializeOnWorkerThread() is called.
mojom::ServiceWorkerContainerHostPtr service_worker_container_host_;
@@ -165,20 +187,23 @@ class CONTENT_EXPORT WorkerFetchContextImpl
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_ = blink::mojom::kInvalidServiceWorkerVersionId;
-
scoped_refptr<ThreadSafeSender> thread_safe_sender_;
std::unique_ptr<blink::WebDocumentSubresourceFilter::Builder>
subresource_filter_builder_;
+ // For dedicated workers, this is the ancestor frame (the parent frame for
+ // non-nested workers, the closest ancestor for nested workers). For shared
+ // workers, this is the shadow page.
bool is_on_sub_frame_ = false;
- int parent_frame_id_ = MSG_ROUTING_NONE;
+ int ancestor_frame_id_ = MSG_ROUTING_NONE;
GURL site_for_cookies_;
bool is_secure_context_ = false;
GURL origin_url_;
int appcache_host_id_ = blink::WebApplicationCacheHost::kAppCacheNoHostId;
+ // TODO(crbug.com/862854): Propagate preference changes from the browser
+ // process.
+ RendererPreferences renderer_preferences_;
+
// This is owned by ThreadedMessagingProxyBase on the main thread.
base::WaitableEvent* terminate_sync_load_event_ = nullptr;
@@ -190,9 +215,9 @@ class CONTENT_EXPORT WorkerFetchContextImpl
std::unique_ptr<WebSocketHandshakeThrottleProvider>
websocket_handshake_throttle_provider_;
- scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+ std::unique_ptr<service_manager::Connector> service_manager_connection_;
};
} // namespace content
-#endif // CONTENT_RENDERER_SERVICE_WORKER_WORKER_FETCH_CONTEXT_IMPL_H_
+#endif // CONTENT_RENDERER_LOADER_WEB_WORKER_FETCH_CONTEXT_IMPL_H_
diff --git a/chromium/content/renderer/low_memory_mode_controller.cc b/chromium/content/renderer/low_memory_mode_controller.cc
new file mode 100644
index 00000000000..a3e6fc43fb5
--- /dev/null
+++ b/chromium/content/renderer/low_memory_mode_controller.cc
@@ -0,0 +1,61 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/low_memory_mode_controller.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "third_party/blink/public/web/blink.h"
+#include "v8/include/v8.h"
+
+namespace content {
+
+LowMemoryModeController::LowMemoryModeController() = default;
+
+LowMemoryModeController::~LowMemoryModeController() = default;
+
+void LowMemoryModeController::OnFrameCreated(bool is_main_frame) {
+ if (is_main_frame) {
+ // If the process is gaining its first main frame, disable memory
+ // savings mode.
+ if (++main_frame_count_ == 1) {
+ Disable();
+ }
+ } else if (main_frame_count_ == 0) {
+ // The process is getting a new frame and none is main, enable
+ // memory savings mode (if not already on).
+ Enable();
+ }
+}
+
+void LowMemoryModeController::OnFrameDestroyed(bool is_main_frame) {
+ // If the process is losing its last main frame, enable memory
+ // savings mode.
+ if (is_main_frame && --main_frame_count_ == 0) {
+ Enable();
+ }
+}
+
+void LowMemoryModeController::Enable() {
+ if (is_enabled_)
+ return;
+
+ blink::MainThreadIsolate()->EnableMemorySavingsMode();
+ RecordHistogram(true);
+ is_enabled_ = true;
+}
+
+void LowMemoryModeController::Disable() {
+ if (!is_enabled_)
+ return;
+
+ blink::MainThreadIsolate()->DisableMemorySavingsMode();
+ RecordHistogram(false);
+ is_enabled_ = false;
+}
+
+void LowMemoryModeController::RecordHistogram(bool enabled) {
+ UMA_HISTOGRAM_BOOLEAN("SiteIsolation.LowMemoryMode.Transition", enabled);
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/low_memory_mode_controller.h b/chromium/content/renderer/low_memory_mode_controller.h
new file mode 100644
index 00000000000..2038a68600c
--- /dev/null
+++ b/chromium/content/renderer/low_memory_mode_controller.h
@@ -0,0 +1,58 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_LOW_MEMORY_MODE_CONTROLLER_H_
+#define CONTENT_RENDERER_LOW_MEMORY_MODE_CONTROLLER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+// The LowMemoryModeController manages for a renderer process the blink
+// main thread isolate's memory savings mode state. This is only enabled
+// if the V8LowMemoryModeForNonMainFrames feature and --site-per-process
+// are enabled.
+//
+// When a process only contains subframes, the memory saving mode is
+// enabled. If a main frame is later created, then the mode is disabled
+// for the duration of the main frame's existence.
+//
+// The default state after initialization is to not enable low memory mode.
+class CONTENT_EXPORT LowMemoryModeController {
+ public:
+ LowMemoryModeController();
+ ~LowMemoryModeController();
+
+ // Notifies the controller that a frame has either been created or
+ // destroyed. A transition to the memory saving mode may occur as a result.
+ void OnFrameCreated(bool is_main_frame);
+ void OnFrameDestroyed(bool is_main_frame);
+
+ bool is_enabled() const { return is_enabled_; }
+
+ private:
+ // Puts the main thread isolate into memory savings mode if it is not
+ // currently enabled.
+ void Enable();
+
+ // Takes the main thread isolate out of memory savings mode if it is
+ // currently enabled.
+ void Disable();
+
+ // Records an UMA histogram marking an Enabled->Disabled state transition,
+ // or vice versa.
+ void RecordHistogram(bool enabled);
+
+ int main_frame_count_ = 0;
+ bool is_enabled_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(LowMemoryModeController);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_LOW_MEMORY_MODE_CONTROLLER_H_
diff --git a/chromium/content/renderer/low_memory_mode_controller_unittest.cc b/chromium/content/renderer/low_memory_mode_controller_unittest.cc
new file mode 100644
index 00000000000..00f0fa81f45
--- /dev/null
+++ b/chromium/content/renderer/low_memory_mode_controller_unittest.cc
@@ -0,0 +1,86 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/low_memory_mode_controller.h"
+
+#include "base/test/metrics/histogram_tester.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+class LowMemoryModeControllerTest : public testing::Test {
+ public:
+ LowMemoryModeController* controller() { return &controller_; }
+
+ void ExpectTransitionCount(int enabled_count, int disabled_count) {
+ static constexpr char kHistogram[] =
+ "SiteIsolation.LowMemoryMode.Transition";
+ histogram_tester_.ExpectBucketCount(kHistogram, true, enabled_count);
+ histogram_tester_.ExpectBucketCount(kHistogram, false, disabled_count);
+ histogram_tester_.ExpectTotalCount(kHistogram,
+ enabled_count + disabled_count);
+ }
+
+ private:
+ base::HistogramTester histogram_tester_;
+ LowMemoryModeController controller_;
+};
+
+TEST_F(LowMemoryModeControllerTest, CreateMainFrames) {
+ EXPECT_FALSE(controller()->is_enabled());
+
+ controller()->OnFrameCreated(true);
+ EXPECT_FALSE(controller()->is_enabled());
+
+ controller()->OnFrameCreated(true);
+ EXPECT_FALSE(controller()->is_enabled());
+
+ controller()->OnFrameDestroyed(true);
+ EXPECT_FALSE(controller()->is_enabled());
+
+ controller()->OnFrameDestroyed(true);
+ EXPECT_TRUE(controller()->is_enabled());
+
+ ExpectTransitionCount(1, 0);
+}
+
+TEST_F(LowMemoryModeControllerTest, MainFrameAddSubframe) {
+ EXPECT_FALSE(controller()->is_enabled());
+
+ controller()->OnFrameCreated(true);
+ EXPECT_FALSE(controller()->is_enabled());
+
+ controller()->OnFrameCreated(false);
+ EXPECT_FALSE(controller()->is_enabled());
+
+ controller()->OnFrameDestroyed(true);
+ EXPECT_TRUE(controller()->is_enabled());
+
+ controller()->OnFrameDestroyed(false);
+ EXPECT_TRUE(controller()->is_enabled());
+
+ ExpectTransitionCount(1, 0);
+}
+
+TEST_F(LowMemoryModeControllerTest, SubFrameAddMainFrame) {
+ EXPECT_FALSE(controller()->is_enabled());
+
+ controller()->OnFrameCreated(false);
+ EXPECT_TRUE(controller()->is_enabled());
+
+ controller()->OnFrameCreated(true);
+ EXPECT_FALSE(controller()->is_enabled());
+
+ controller()->OnFrameDestroyed(true);
+ EXPECT_TRUE(controller()->is_enabled());
+
+ controller()->OnFrameDestroyed(false);
+ EXPECT_TRUE(controller()->is_enabled());
+
+ ExpectTransitionCount(2, 1);
+}
+
+} // namespace
+} // namespace content
diff --git a/chromium/content/renderer/manifest/manifest_parser.cc b/chromium/content/renderer/manifest/manifest_parser.cc
index 21f715cbf0d..22fba6ba3bd 100644
--- a/chromium/content/renderer/manifest/manifest_parser.cc
+++ b/chromium/content/renderer/manifest/manifest_parser.cc
@@ -277,13 +277,13 @@ std::vector<gfx::Size> ManifestParser::ParseIconSizes(
return sizes;
}
-std::vector<blink::Manifest::Icon::IconPurpose>
+std::vector<blink::Manifest::ImageResource::Purpose>
ManifestParser::ParseIconPurpose(const base::DictionaryValue& icon) {
base::NullableString16 purpose_str = ParseString(icon, "purpose", NoTrim);
- std::vector<blink::Manifest::Icon::IconPurpose> purposes;
+ std::vector<blink::Manifest::ImageResource::Purpose> purposes;
if (purpose_str.is_null()) {
- purposes.push_back(blink::Manifest::Icon::IconPurpose::ANY);
+ purposes.push_back(blink::Manifest::ImageResource::Purpose::ANY);
return purposes;
}
@@ -292,9 +292,9 @@ ManifestParser::ParseIconPurpose(const base::DictionaryValue& icon) {
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
for (const base::string16& keyword : keywords) {
if (base::LowerCaseEqualsASCII(keyword, "any")) {
- purposes.push_back(blink::Manifest::Icon::IconPurpose::ANY);
+ purposes.push_back(blink::Manifest::ImageResource::Purpose::ANY);
} else if (base::LowerCaseEqualsASCII(keyword, "badge")) {
- purposes.push_back(blink::Manifest::Icon::IconPurpose::BADGE);
+ purposes.push_back(blink::Manifest::ImageResource::Purpose::BADGE);
} else {
AddErrorInfo(
"found icon with invalid purpose. "
@@ -303,15 +303,15 @@ ManifestParser::ParseIconPurpose(const base::DictionaryValue& icon) {
}
if (purposes.empty()) {
- purposes.push_back(blink::Manifest::Icon::IconPurpose::ANY);
+ purposes.push_back(blink::Manifest::ImageResource::Purpose::ANY);
}
return purposes;
}
-std::vector<blink::Manifest::Icon> ManifestParser::ParseIcons(
+std::vector<blink::Manifest::ImageResource> ManifestParser::ParseIcons(
const base::DictionaryValue& dictionary) {
- std::vector<blink::Manifest::Icon> icons;
+ std::vector<blink::Manifest::ImageResource> icons;
if (!dictionary.HasKey("icons"))
return icons;
@@ -326,7 +326,7 @@ std::vector<blink::Manifest::Icon> ManifestParser::ParseIcons(
if (!icons_list->GetDictionary(i, &icon_dictionary))
continue;
- blink::Manifest::Icon icon;
+ blink::Manifest::ImageResource icon;
icon.src = ParseIconSrc(*icon_dictionary);
// An icon MUST have a valid src. If it does not, it MUST be ignored.
if (!icon.src.is_valid())
diff --git a/chromium/content/renderer/manifest/manifest_parser.h b/chromium/content/renderer/manifest/manifest_parser.h
index a456754390f..69551b8c3f3 100644
--- a/chromium/content/renderer/manifest/manifest_parser.h
+++ b/chromium/content/renderer/manifest/manifest_parser.h
@@ -146,14 +146,14 @@ class CONTENT_EXPORT ManifestParser {
// Returns a vector of Manifest::Icon::IconPurpose with the successfully
// parsed icon purposes, and a vector with Manifest::Icon::IconPurpose::Any if
// the parsing failed.
- std::vector<blink::Manifest::Icon::IconPurpose> ParseIconPurpose(
+ std::vector<blink::Manifest::ImageResource::Purpose> ParseIconPurpose(
const base::DictionaryValue& icon);
// Parses the 'icons' field of a Manifest, as defined in:
// https://w3c.github.io/manifest/#dfn-steps-for-processing-an-array-of-images
// Returns a vector of Manifest::Icon with the successfully parsed icons, if
// any. An empty vector if the field was not present or empty.
- std::vector<blink::Manifest::Icon> ParseIcons(
+ std::vector<blink::Manifest::ImageResource> ParseIcons(
const base::DictionaryValue& dictionary);
// Parses the 'url_template' field of a Share Target, as defined in:
diff --git a/chromium/content/renderer/manifest/manifest_parser_unittest.cc b/chromium/content/renderer/manifest/manifest_parser_unittest.cc
index 016020e6f17..a47995053f4 100644
--- a/chromium/content/renderer/manifest/manifest_parser_unittest.cc
+++ b/chromium/content/renderer/manifest/manifest_parser_unittest.cc
@@ -931,7 +931,7 @@ TEST_F(ManifestParserTest, IconPurposeParseRules) {
ParseManifest("{ \"icons\": [ {\"src\": \"\" } ] }");
EXPECT_EQ(manifest.icons[0].purpose.size(), 1u);
EXPECT_EQ(manifest.icons[0].purpose[0],
- blink::Manifest::Icon::IconPurpose::ANY);
+ blink::Manifest::ImageResource::Purpose::ANY);
EXPECT_EQ(0u, GetErrorCount());
}
@@ -943,7 +943,7 @@ TEST_F(ManifestParserTest, IconPurposeParseRules) {
"\"purpose\": 42 } ] }");
EXPECT_EQ(manifest.icons[0].purpose.size(), 1u);
EXPECT_EQ(manifest.icons[0].purpose[0],
- blink::Manifest::Icon::IconPurpose::ANY);
+ blink::Manifest::ImageResource::Purpose::ANY);
ASSERT_EQ(1u, GetErrorCount());
EXPECT_EQ(kPurposeParseStringError, errors()[0]);
}
@@ -956,7 +956,7 @@ TEST_F(ManifestParserTest, IconPurposeParseRules) {
"\"purpose\": {} } ] }");
EXPECT_EQ(manifest.icons[0].purpose.size(), 1u);
EXPECT_EQ(manifest.icons[0].purpose[0],
- blink::Manifest::Icon::IconPurpose::ANY);
+ blink::Manifest::ImageResource::Purpose::ANY);
ASSERT_EQ(1u, GetErrorCount());
EXPECT_EQ(kPurposeParseStringError, errors()[0]);
}
@@ -968,9 +968,9 @@ TEST_F(ManifestParserTest, IconPurposeParseRules) {
"\"purpose\": \"Any Badge\" } ] }");
ASSERT_EQ(manifest.icons[0].purpose.size(), 2u);
EXPECT_EQ(manifest.icons[0].purpose[0],
- blink::Manifest::Icon::IconPurpose::ANY);
+ blink::Manifest::ImageResource::Purpose::ANY);
EXPECT_EQ(manifest.icons[0].purpose[1],
- blink::Manifest::Icon::IconPurpose::BADGE);
+ blink::Manifest::ImageResource::Purpose::BADGE);
EXPECT_EQ(0u, GetErrorCount());
}
@@ -981,9 +981,9 @@ TEST_F(ManifestParserTest, IconPurposeParseRules) {
"\"purpose\": \" Any Badge \" } ] }");
ASSERT_EQ(manifest.icons[0].purpose.size(), 2u);
EXPECT_EQ(manifest.icons[0].purpose[0],
- blink::Manifest::Icon::IconPurpose::ANY);
+ blink::Manifest::ImageResource::Purpose::ANY);
EXPECT_EQ(manifest.icons[0].purpose[1],
- blink::Manifest::Icon::IconPurpose::BADGE);
+ blink::Manifest::ImageResource::Purpose::BADGE);
EXPECT_EQ(0u, GetErrorCount());
}
@@ -994,9 +994,9 @@ TEST_F(ManifestParserTest, IconPurposeParseRules) {
"\"purpose\": \"badge badge\" } ] }");
ASSERT_EQ(manifest.icons[0].purpose.size(), 2u);
EXPECT_EQ(manifest.icons[0].purpose[0],
- blink::Manifest::Icon::IconPurpose::BADGE);
+ blink::Manifest::ImageResource::Purpose::BADGE);
EXPECT_EQ(manifest.icons[0].purpose[1],
- blink::Manifest::Icon::IconPurpose::BADGE);
+ blink::Manifest::ImageResource::Purpose::BADGE);
EXPECT_EQ(0u, GetErrorCount());
}
@@ -1007,7 +1007,7 @@ TEST_F(ManifestParserTest, IconPurposeParseRules) {
"\"purpose\": \"badge notification\" } ] }");
ASSERT_EQ(manifest.icons[0].purpose.size(), 1u);
EXPECT_EQ(manifest.icons[0].purpose[0],
- blink::Manifest::Icon::IconPurpose::BADGE);
+ blink::Manifest::ImageResource::Purpose::BADGE);
ASSERT_EQ(1u, GetErrorCount());
EXPECT_EQ(kPurposeInvalidValueError, errors()[0]);
}
@@ -1019,7 +1019,7 @@ TEST_F(ManifestParserTest, IconPurposeParseRules) {
"\"purpose\": \"notification\" } ] }");
ASSERT_EQ(manifest.icons[0].purpose.size(), 1u);
EXPECT_EQ(manifest.icons[0].purpose[0],
- blink::Manifest::Icon::IconPurpose::ANY);
+ blink::Manifest::ImageResource::Purpose::ANY);
ASSERT_EQ(1u, GetErrorCount());
EXPECT_EQ(kPurposeInvalidValueError, errors()[0]);
}
diff --git a/chromium/content/renderer/media/android/renderer_media_player_manager.cc b/chromium/content/renderer/media/android/renderer_media_player_manager.cc
index 72ae5491082..70fd8ec9954 100644
--- a/chromium/content/renderer/media/android/renderer_media_player_manager.cc
+++ b/chromium/content/renderer/media/android/renderer_media_player_manager.cc
@@ -248,10 +248,6 @@ void RendererMediaPlayerManager::OnRemoteRouteAvailabilityChanged(
player->OnRemoteRouteAvailabilityChanged(availability);
}
-void RendererMediaPlayerManager::EnterFullscreen(int player_id) {
- Send(new MediaPlayerHostMsg_EnterFullscreen(routing_id(), player_id));
-}
-
int RendererMediaPlayerManager::RegisterMediaPlayer(
media::RendererMediaPlayerInterface* player) {
media_players_[next_media_player_id_] = player;
diff --git a/chromium/content/renderer/media/android/renderer_media_player_manager.h b/chromium/content/renderer/media/android/renderer_media_player_manager.h
index d8b2a58d6f0..08c4116168e 100644
--- a/chromium/content/renderer/media/android/renderer_media_player_manager.h
+++ b/chromium/content/renderer/media/android/renderer_media_player_manager.h
@@ -78,9 +78,6 @@ class RendererMediaPlayerManager :
// Requests stopping remote playback
void RequestRemotePlaybackStop(int player_id) override;
- // Requests the player to enter fullscreen.
- void EnterFullscreen(int player_id);
-
// Registers and unregisters a WebMediaPlayerAndroid object.
int RegisterMediaPlayer(media::RendererMediaPlayerInterface* player) override;
void UnregisterMediaPlayer(int player_id) override;
diff --git a/chromium/content/renderer/media/android/renderer_surface_view_manager.cc b/chromium/content/renderer/media/android/renderer_surface_view_manager.cc
deleted file mode 100644
index 0402460b7e6..00000000000
--- a/chromium/content/renderer/media/android/renderer_surface_view_manager.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/media/android/renderer_surface_view_manager.h"
-
-#include "content/common/media/surface_view_manager_messages_android.h"
-#include "ipc/ipc_message_macros.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace content {
-
-RendererSurfaceViewManager::RendererSurfaceViewManager(
- RenderFrame* render_frame)
- : RenderFrameObserver(render_frame) {}
-
-RendererSurfaceViewManager::~RendererSurfaceViewManager() {}
-
-bool RendererSurfaceViewManager::OnMessageReceived(const IPC::Message& msg) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(RendererSurfaceViewManager, msg)
- IPC_MESSAGE_HANDLER(SurfaceViewManagerMsg_FullscreenSurfaceCreated,
- OnFullscreenSurfaceCreated)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void RendererSurfaceViewManager::CreateFullscreenSurface(
- const gfx::Size& video_natural_size,
- const media::SurfaceCreatedCB& surface_created_cb) {
- DCHECK(!surface_created_cb.is_null());
- pending_surface_created_cb_ = surface_created_cb;
- Send(new SurfaceViewManagerHostMsg_CreateFullscreenSurface(
- routing_id(), video_natural_size));
-}
-
-void RendererSurfaceViewManager::NaturalSizeChanged(const gfx::Size& size) {
- DVLOG(3) << __func__ << ": size: " << size.ToString();
- Send(new SurfaceViewManagerHostMsg_NaturalSizeChanged(routing_id(), size));
-}
-
-void RendererSurfaceViewManager::OnFullscreenSurfaceCreated(int surface_id) {
- DVLOG(3) << __func__ << ": surface_id: " << surface_id;
- if (!pending_surface_created_cb_.is_null()) {
- pending_surface_created_cb_.Run(surface_id);
- pending_surface_created_cb_.Reset();
- }
-}
-
-void RendererSurfaceViewManager::OnDestruct() {
- delete this;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/android/renderer_surface_view_manager.h b/chromium/content/renderer/media/android/renderer_surface_view_manager.h
deleted file mode 100644
index f2918f37877..00000000000
--- a/chromium/content/renderer/media/android/renderer_surface_view_manager.h
+++ /dev/null
@@ -1,49 +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_MEDIA_ANDROID_RENDERER_SURFACE_VIEW_MANAGER_H_
-#define CONTENT_RENDERER_MEDIA_ANDROID_RENDERER_SURFACE_VIEW_MANAGER_H_
-
-#include "base/callback.h"
-#include "content/common/content_export.h"
-#include "content/public/renderer/render_frame_observer.h"
-#include "media/base/surface_manager.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace content {
-
-// RendererSurfaceViewManager creates delegates requests for video SurfaceViews
-// to BrowserSurfaceViewManager. The returned surface ids may be invalidated
-// at any time (e.g., when the app is backgrounded), so clients should handle
-// this gracefully. It should be created and used on a single thread only.
-class CONTENT_EXPORT RendererSurfaceViewManager : public media::SurfaceManager,
- public RenderFrameObserver {
- public:
- explicit RendererSurfaceViewManager(RenderFrame* render_frame);
- ~RendererSurfaceViewManager() override;
-
- // RenderFrameObserver override.
- bool OnMessageReceived(const IPC::Message& msg) override;
-
- // SurfaceManager overrides.
- void CreateFullscreenSurface(
- const gfx::Size& video_natural_size,
- const media::SurfaceCreatedCB& surface_created_cb) override;
- void NaturalSizeChanged(const gfx::Size& size) override;
-
- private:
- // RenderFrameObserver implementation.
- void OnDestruct() override;
-
- void OnFullscreenSurfaceCreated(int surface_id);
-
- // Set when a surface request is in progress.
- media::SurfaceCreatedCB pending_surface_created_cb_;
-
- DISALLOW_COPY_AND_ASSIGN(RendererSurfaceViewManager);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_ANDROID_RENDERER_SURFACE_VIEW_MANAGER_H_
diff --git a/chromium/content/renderer/media/android/stream_texture_factory.cc b/chromium/content/renderer/media/android/stream_texture_factory.cc
index 5e982601dab..86b022e7e59 100644
--- a/chromium/content/renderer/media/android/stream_texture_factory.cc
+++ b/chromium/content/renderer/media/android/stream_texture_factory.cc
@@ -119,7 +119,6 @@ unsigned StreamTextureFactory::CreateStreamTexture(
*texture_id = 0;
*texture_mailbox = gpu::Mailbox();
} else {
- gl->GenMailboxCHROMIUM(texture_mailbox->name);
gl->ProduceTextureDirectCHROMIUM(*texture_id, texture_mailbox->name);
}
return route_id;
diff --git a/chromium/content/renderer/media/audio_device_factory.cc b/chromium/content/renderer/media/audio/audio_device_factory.cc
index 52a260eb6fe..d20dbe3a5b0 100644
--- a/chromium/content/renderer/media/audio_device_factory.cc
+++ b/chromium/content/renderer/media/audio/audio_device_factory.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/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include <algorithm>
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/threading/platform_thread.h"
#include "build/build_config.h"
#include "content/common/content_constants_internal.h"
#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
-#include "content/renderer/media/audio_input_ipc_factory.h"
-#include "content/renderer/media/audio_output_ipc_factory.h"
-#include "content/renderer/media/audio_renderer_mixer_manager.h"
-#include "content/renderer/media/mojo_audio_input_ipc.h"
+#include "content/renderer/media/audio/audio_input_ipc_factory.h"
+#include "content/renderer/media/audio/audio_output_ipc_factory.h"
+#include "content/renderer/media/audio/audio_renderer_mixer_manager.h"
+#include "content/renderer/media/audio/mojo_audio_input_ipc.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "media/audio/audio_input_device.h"
@@ -168,7 +169,8 @@ AudioDeviceFactory::NewAudioCapturerSource(int render_frame_id,
return base::MakeRefCounted<media::AudioInputDevice>(
AudioInputIPCFactory::get()->CreateAudioInputIPC(render_frame_id,
- session_id));
+ session_id),
+ base::ThreadPriority::REALTIME_AUDIO);
}
// static
diff --git a/chromium/content/renderer/media/audio_device_factory.h b/chromium/content/renderer/media/audio/audio_device_factory.h
index 6184e7a0eca..d4f3704a70e 100644
--- a/chromium/content/renderer/media/audio_device_factory.h
+++ b/chromium/content/renderer/media/audio/audio_device_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_RENDERER_MEDIA_AUDIO_DEVICE_FACTORY_H_
-#define CONTENT_RENDERER_MEDIA_AUDIO_DEVICE_FACTORY_H_
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_DEVICE_FACTORY_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_DEVICE_FACTORY_H_
#include <string>
@@ -142,4 +142,4 @@ class CONTENT_EXPORT AudioDeviceFactory {
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_AUDIO_DEVICE_FACTORY_H_
+#endif // CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_DEVICE_FACTORY_H_
diff --git a/chromium/content/renderer/media/audio_input_ipc_factory.cc b/chromium/content/renderer/media/audio/audio_input_ipc_factory.cc
index 7cafd730916..f301aace7c4 100644
--- a/chromium/content/renderer/media/audio_input_ipc_factory.cc
+++ b/chromium/content/renderer/media/audio/audio_input_ipc_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/renderer/media/audio_input_ipc_factory.h"
+#include "content/renderer/media/audio/audio_input_ipc_factory.h"
#include <utility>
@@ -10,7 +10,7 @@
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "content/common/media/renderer_audio_input_stream_factory.mojom.h"
-#include "content/renderer/media/mojo_audio_input_ipc.h"
+#include "content/renderer/media/audio/mojo_audio_input_ipc.h"
#include "content/renderer/render_frame_impl.h"
#include "services/service_manager/public/cpp/interface_provider.h"
diff --git a/chromium/content/renderer/media/audio_input_ipc_factory.h b/chromium/content/renderer/media/audio/audio_input_ipc_factory.h
index 7921cb74635..ea3956945f3 100644
--- a/chromium/content/renderer/media/audio_input_ipc_factory.h
+++ b/chromium/content/renderer/media/audio/audio_input_ipc_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_RENDERER_MEDIA_AUDIO_INPUT_IPC_FACTORY_H_
-#define CONTENT_RENDERER_MEDIA_AUDIO_INPUT_IPC_FACTORY_H_
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_INPUT_IPC_FACTORY_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_INPUT_IPC_FACTORY_H_
#include <memory>
@@ -57,4 +57,4 @@ class CONTENT_EXPORT AudioInputIPCFactory {
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_AUDIO_INPUT_IPC_FACTORY_H_
+#endif // CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_INPUT_IPC_FACTORY_H_
diff --git a/chromium/content/renderer/media/audio_output_ipc_factory.cc b/chromium/content/renderer/media/audio/audio_output_ipc_factory.cc
index 829d85a8e6c..4bcab6233fd 100644
--- a/chromium/content/renderer/media/audio_output_ipc_factory.cc
+++ b/chromium/content/renderer/media/audio/audio_output_ipc_factory.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/audio_output_ipc_factory.h"
+#include "content/renderer/media/audio/audio_output_ipc_factory.h"
#include <utility>
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
-#include "content/renderer/media/mojo_audio_output_ipc.h"
+#include "content/renderer/media/audio/mojo_audio_output_ipc.h"
#include "services/service_manager/public/cpp/interface_provider.h"
namespace content {
diff --git a/chromium/content/renderer/media/audio_output_ipc_factory.h b/chromium/content/renderer/media/audio/audio_output_ipc_factory.h
index 6cb588204f5..0f87cfdd9b0 100644
--- a/chromium/content/renderer/media/audio_output_ipc_factory.h
+++ b/chromium/content/renderer/media/audio/audio_output_ipc_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_RENDERER_MEDIA_AUDIO_OUTPUT_IPC_FACTORY_H_
-#define CONTENT_RENDERER_MEDIA_AUDIO_OUTPUT_IPC_FACTORY_H_
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_OUTPUT_IPC_FACTORY_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_OUTPUT_IPC_FACTORY_H_
#include <memory>
@@ -89,4 +89,4 @@ class CONTENT_EXPORT AudioOutputIPCFactory {
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_AUDIO_OUTPUT_IPC_FACTORY_H_
+#endif // CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_OUTPUT_IPC_FACTORY_H_
diff --git a/chromium/content/renderer/media/audio_output_ipc_factory_unittest.cc b/chromium/content/renderer/media/audio/audio_output_ipc_factory_unittest.cc
index 6f675a57444..cefb2a3c533 100644
--- a/chromium/content/renderer/media/audio_output_ipc_factory_unittest.cc
+++ b/chromium/content/renderer/media/audio/audio_output_ipc_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/renderer/media/audio_output_ipc_factory.h"
+#include "content/renderer/media/audio/audio_output_ipc_factory.h"
#include <string>
#include <utility>
@@ -72,7 +72,7 @@ class FakeAudioOutputIPCDelegate : public media::AudioOutputIPCDelegate {
void OnDeviceAuthorized(media::OutputDeviceStatus device_status,
const media::AudioParameters& output_params,
const std::string& matched_device_id) override {}
- void OnStreamCreated(base::SharedMemoryHandle handle,
+ void OnStreamCreated(base::UnsafeSharedMemoryRegion region,
base::SyncSocket::Handle socket_handle,
bool playing_automatically) override {}
void OnIPCClosed() override {}
diff --git a/chromium/content/renderer/media/audio_renderer_mixer_manager.cc b/chromium/content/renderer/media/audio/audio_renderer_mixer_manager.cc
index 942553572ad..b457f7ce47c 100644
--- a/chromium/content/renderer/media/audio_renderer_mixer_manager.cc
+++ b/chromium/content/renderer/media/audio/audio_renderer_mixer_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/renderer/media/audio_renderer_mixer_manager.h"
+#include "content/renderer/media/audio/audio_renderer_mixer_manager.h"
#include <algorithm>
#include <string>
@@ -14,7 +14,7 @@
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
-#include "content/renderer/media/audio_renderer_sink_cache.h"
+#include "content/renderer/media/audio/audio_renderer_sink_cache.h"
#include "media/audio/audio_device_description.h"
#include "media/base/audio_renderer_mixer.h"
#include "media/base/audio_renderer_mixer_input.h"
@@ -90,6 +90,9 @@ media::AudioParameters GetMixerOutputParams(
if (input_params.channel_layout() == media::CHANNEL_LAYOUT_DISCRETE)
params.set_channels_for_discrete(input_params.channels());
+ // Specify the effects info the passed to the browser side.
+ params.set_effects(input_params.effects());
+
// Specify the latency info to be passed to the browser side.
params.set_latency_tag(latency);
return params;
@@ -168,9 +171,6 @@ media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
media::AudioLatency::LatencyType latency,
const std::string& device_id,
media::OutputDeviceStatus* device_status) {
- // Effects are not passed through to output creation, so ensure none are set.
- DCHECK_EQ(input_params.effects(), media::AudioParameters::NO_EFFECTS);
-
const MixerKey key(source_render_frame_id, input_params, latency, device_id);
base::AutoLock auto_lock(mixers_lock_);
diff --git a/chromium/content/renderer/media/audio_renderer_mixer_manager.h b/chromium/content/renderer/media/audio/audio_renderer_mixer_manager.h
index f7821b05759..be586bcd703 100644
--- a/chromium/content/renderer/media/audio_renderer_mixer_manager.h
+++ b/chromium/content/renderer/media/audio/audio_renderer_mixer_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_RENDERER_MEDIA_AUDIO_RENDERER_MIXER_MANAGER_H_
-#define CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_MIXER_MANAGER_H_
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_RENDERER_MIXER_MANAGER_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_RENDERER_MIXER_MANAGER_H_
#include <bitset>
#include <map>
@@ -111,11 +111,13 @@ class CONTENT_EXPORT AudioRendererMixerManager
// adding support for it.
DCHECK_NE(media::AudioLatency::LATENCY_EXACT_MS, a.latency);
- // Ignore effects(), format(), and frames_per_buffer(), these parameters
- // do not affect mixer reuse. All AudioRendererMixer units disable FIFO,
- // so frames_per_buffer() can be safely ignored.
+ // Ignore format(), and frames_per_buffer(), these parameters do not
+ // affect mixer reuse. All AudioRendererMixer units disable FIFO, so
+ // frames_per_buffer() can be safely ignored.
if (a.params.channel_layout() != b.params.channel_layout())
return a.params.channel_layout() < b.params.channel_layout();
+ if (a.params.effects() != b.params.effects())
+ return a.params.effects() < b.params.effects();
if (media::AudioDeviceDescription::IsDefaultDevice(a.device_id) &&
media::AudioDeviceDescription::IsDefaultDevice(b.device_id)) {
@@ -157,4 +159,4 @@ class CONTENT_EXPORT AudioRendererMixerManager
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_MIXER_MANAGER_H_
+#endif // CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_RENDERER_MIXER_MANAGER_H_
diff --git a/chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc b/chromium/content/renderer/media/audio/audio_renderer_mixer_manager_unittest.cc
index bba7a3e8224..03e1a7d415f 100644
--- a/chromium/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
+++ b/chromium/content/renderer/media/audio/audio_renderer_mixer_manager_unittest.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/renderer/media/audio_renderer_mixer_manager.h"
+#include "content/renderer/media/audio/audio_renderer_mixer_manager.h"
#include <memory>
#include "base/bind.h"
-#include "build/build_config.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "content/renderer/media/audio_renderer_sink_cache.h"
+#include "build/build_config.h"
+#include "content/renderer/media/audio/audio_renderer_sink_cache.h"
#include "media/audio/audio_device_description.h"
#include "media/base/audio_parameters.h"
#include "media/base/audio_renderer_mixer.h"
@@ -536,6 +536,72 @@ TEST_F(AudioRendererMixerManagerTest, LatencyMixing) {
EXPECT_EQ(0, mixer_count());
}
+// Verify GetMixer() correctly deduplicate mixers basing on the effects
+// requirements.
+TEST_F(AudioRendererMixerManagerTest, EffectsMixing) {
+ EXPECT_CALL(*mock_sink_.get(), Start()).Times(3);
+ EXPECT_CALL(*mock_sink_.get(), Stop()).Times(3);
+ EXPECT_CALL(*this, ReleaseSinkPtr(mock_sink_.get())).Times(3);
+
+ EXPECT_EQ(0, mixer_count());
+
+ media::AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
+ kChannelLayout, kSampleRate, kBufferSize);
+ params.set_effects(1);
+ media::AudioRendererMixer* mixer1 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, nullptr);
+ ASSERT_TRUE(mixer1);
+ EXPECT_EQ(1, mixer_count());
+
+ media::AudioRendererMixer* mixer2 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, nullptr);
+ ASSERT_TRUE(mixer2);
+ EXPECT_EQ(mixer1, mixer2); // Same effects => same mixer.
+ EXPECT_EQ(1, mixer_count());
+
+ params.set_effects(2);
+ media::AudioRendererMixer* mixer3 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, nullptr);
+ ASSERT_TRUE(mixer3);
+ EXPECT_NE(mixer1, mixer3);
+ EXPECT_EQ(2, mixer_count()); // Another effects => another mixer.
+
+ media::AudioRendererMixer* mixer4 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, nullptr);
+ EXPECT_EQ(mixer3, mixer4);
+ EXPECT_EQ(2, mixer_count()); // Same effects => same mixer.
+
+ params.set_effects(3);
+ media::AudioRendererMixer* mixer5 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, nullptr);
+ ASSERT_TRUE(mixer5);
+ EXPECT_EQ(3, mixer_count()); // Another effects => another mixer.
+
+ media::AudioRendererMixer* mixer6 =
+ GetMixer(kRenderFrameId, params, AudioLatency::LATENCY_PLAYBACK,
+ kDefaultDeviceId, nullptr);
+ EXPECT_EQ(mixer5, mixer6);
+ EXPECT_EQ(3, mixer_count()); // Same effects => same mixer.
+
+ ReturnMixer(mixer1);
+ EXPECT_EQ(3, mixer_count());
+ ReturnMixer(mixer2);
+ EXPECT_EQ(2, mixer_count());
+ ReturnMixer(mixer3);
+ EXPECT_EQ(2, mixer_count());
+ ReturnMixer(mixer4);
+ EXPECT_EQ(1, mixer_count());
+ ReturnMixer(mixer5);
+ EXPECT_EQ(1, mixer_count());
+ ReturnMixer(mixer6);
+ EXPECT_EQ(0, mixer_count());
+}
+
// Verify output bufer size of the mixer is correctly adjusted for Playback
// latency.
TEST_F(AudioRendererMixerManagerTest, MixerParamsLatencyPlayback) {
diff --git a/chromium/content/renderer/media/audio_renderer_sink_cache.h b/chromium/content/renderer/media/audio/audio_renderer_sink_cache.h
index 4a06a3fc0c6..598e023d0c8 100644
--- a/chromium/content/renderer/media/audio_renderer_sink_cache.h
+++ b/chromium/content/renderer/media/audio/audio_renderer_sink_cache.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_H_
-#define CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_H_
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_RENDERER_SINK_CACHE_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_RENDERER_SINK_CACHE_H_
#include <memory>
#include <string>
@@ -60,4 +60,4 @@ class CONTENT_EXPORT AudioRendererSinkCache {
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_H_
+#endif // CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_RENDERER_SINK_CACHE_H_
diff --git a/chromium/content/renderer/media/audio_renderer_sink_cache_impl.cc b/chromium/content/renderer/media/audio/audio_renderer_sink_cache_impl.cc
index 3dc8bebc611..a28bcf9eed6 100644
--- a/chromium/content/renderer/media/audio_renderer_sink_cache_impl.cc
+++ b/chromium/content/renderer/media/audio/audio_renderer_sink_cache_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/renderer/media/audio_renderer_sink_cache_impl.h"
+#include "content/renderer/media/audio/audio_renderer_sink_cache_impl.h"
#include <algorithm>
#include <memory>
@@ -17,7 +17,7 @@
#include "base/trace_event/trace_event.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_frame_observer.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "media/audio/audio_device_description.h"
#include "media/base/audio_renderer_sink.h"
diff --git a/chromium/content/renderer/media/audio_renderer_sink_cache_impl.h b/chromium/content/renderer/media/audio/audio_renderer_sink_cache_impl.h
index 93dd9adb2e3..0b6e872f4b9 100644
--- a/chromium/content/renderer/media/audio_renderer_sink_cache_impl.h
+++ b/chromium/content/renderer/media/audio/audio_renderer_sink_cache_impl.h
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_IMPL_H_
-#define CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_IMPL_H_
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_RENDERER_SINK_CACHE_IMPL_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_RENDERER_SINK_CACHE_IMPL_H_
-#include "content/renderer/media/audio_renderer_sink_cache.h"
+#include "content/renderer/media/audio/audio_renderer_sink_cache.h"
#include <string>
#include <vector>
@@ -118,4 +118,4 @@ class CONTENT_EXPORT AudioRendererSinkCacheImpl
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_AUDIO_RENDERER_SINK_CACHE_IMPL_H_
+#endif // CONTENT_RENDERER_MEDIA_AUDIO_AUDIO_RENDERER_SINK_CACHE_IMPL_H_
diff --git a/chromium/content/renderer/media/audio_renderer_sink_cache_unittest.cc b/chromium/content/renderer/media/audio/audio_renderer_sink_cache_unittest.cc
index bd510528654..3c3172e277d 100644
--- a/chromium/content/renderer/media/audio_renderer_sink_cache_unittest.cc
+++ b/chromium/content/renderer/media/audio/audio_renderer_sink_cache_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/renderer/media/audio_renderer_sink_cache_impl.h"
+#include "content/renderer/media/audio/audio_renderer_sink_cache_impl.h"
#include <utility>
diff --git a/chromium/content/renderer/media/mock_audio_device_factory.cc b/chromium/content/renderer/media/audio/mock_audio_device_factory.cc
index d4517c7250c..69c1589a53b 100644
--- a/chromium/content/renderer/media/mock_audio_device_factory.cc
+++ b/chromium/content/renderer/media/audio/mock_audio_device_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/renderer/media/mock_audio_device_factory.h"
+#include "content/renderer/media/audio/mock_audio_device_factory.h"
namespace content {
diff --git a/chromium/content/renderer/media/mock_audio_device_factory.h b/chromium/content/renderer/media/audio/mock_audio_device_factory.h
index 33be7bf046c..0958cc23b47 100644
--- a/chromium/content/renderer/media/mock_audio_device_factory.h
+++ b/chromium/content/renderer/media/audio/mock_audio_device_factory.h
@@ -2,12 +2,12 @@
// 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_AUDIO_DEVICE_FACTORY_H_
-#define CONTENT_RENDERER_MEDIA_MOCK_AUDIO_DEVICE_FACTORY_H_
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_MOCK_AUDIO_DEVICE_FACTORY_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_MOCK_AUDIO_DEVICE_FACTORY_H_
#include <string>
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "media/base/audio_capturer_source.h"
#include "media/base/audio_renderer_sink.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -78,4 +78,4 @@ class MockAudioDeviceFactory : public AudioDeviceFactory {
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_MOCK_AUDIO_DEVICE_FACTORY_H_
+#endif // CONTENT_RENDERER_MEDIA_AUDIO_MOCK_AUDIO_DEVICE_FACTORY_H_
diff --git a/chromium/content/renderer/media/mojo_audio_input_ipc.cc b/chromium/content/renderer/media/audio/mojo_audio_input_ipc.cc
index 44b2e55fb11..490b3cd0a6b 100644
--- a/chromium/content/renderer/media/mojo_audio_input_ipc.cc
+++ b/chromium/content/renderer/media/audio/mojo_audio_input_ipc.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/media/mojo_audio_input_ipc.h"
+#include "content/renderer/media/audio/mojo_audio_input_ipc.h"
#include <utility>
@@ -81,7 +81,7 @@ void MojoAudioInputIPC::CloseStream() {
void MojoAudioInputIPC::StreamCreated(
media::mojom::AudioInputStreamPtr stream,
media::mojom::AudioInputStreamClientRequest stream_client_request,
- media::mojom::AudioDataPipePtr data_pipe,
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
bool initially_muted,
const base::Optional<base::UnguessableToken>& stream_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -104,14 +104,12 @@ void MojoAudioInputIPC::StreamCreated(
mojo::UnwrapPlatformFile(std::move(data_pipe->socket), &socket_handle);
DCHECK_EQ(result, MOJO_RESULT_OK);
- base::SharedMemoryHandle memory_handle;
- mojo::UnwrappedSharedMemoryHandleProtection protection;
- result = mojo::UnwrapSharedMemoryHandle(std::move(data_pipe->shared_memory),
- &memory_handle, nullptr, &protection);
- DCHECK_EQ(result, MOJO_RESULT_OK);
- DCHECK_EQ(protection, mojo::UnwrappedSharedMemoryHandleProtection::kReadOnly);
+ base::ReadOnlySharedMemoryRegion& shared_memory_region =
+ data_pipe->shared_memory;
+ DCHECK(shared_memory_region.IsValid());
- delegate_->OnStreamCreated(memory_handle, socket_handle, initially_muted);
+ delegate_->OnStreamCreated(std::move(shared_memory_region), socket_handle,
+ initially_muted);
}
void MojoAudioInputIPC::OnError() {
diff --git a/chromium/content/renderer/media/mojo_audio_input_ipc.h b/chromium/content/renderer/media/audio/mojo_audio_input_ipc.h
index 9161a53c62f..b47c1d0fcea 100644
--- a/chromium/content/renderer/media/mojo_audio_input_ipc.h
+++ b/chromium/content/renderer/media/audio/mojo_audio_input_ipc.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_MEDIA_MOJO_AUDIO_INPUT_IPC_H_
-#define CONTENT_RENDERER_MEDIA_MOJO_AUDIO_INPUT_IPC_H_
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_MOJO_AUDIO_INPUT_IPC_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_MOJO_AUDIO_INPUT_IPC_H_
#include <string>
@@ -59,7 +59,7 @@ class CONTENT_EXPORT MojoAudioInputIPC
void StreamCreated(
media::mojom::AudioInputStreamPtr stream,
media::mojom::AudioInputStreamClientRequest stream_client_request,
- media::mojom::AudioDataPipePtr data_pipe,
+ media::mojom::ReadOnlyAudioDataPipePtr data_pipe,
bool initially_muted,
const base::Optional<base::UnguessableToken>& stream_id) override;
void OnError() override;
@@ -86,4 +86,4 @@ class CONTENT_EXPORT MojoAudioInputIPC
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_MOJO_AUDIO_INPUT_IPC_H_
+#endif // CONTENT_RENDERER_MEDIA_AUDIO_MOJO_AUDIO_INPUT_IPC_H_
diff --git a/chromium/content/renderer/media/mojo_audio_input_ipc_unittest.cc b/chromium/content/renderer/media/audio/mojo_audio_input_ipc_unittest.cc
index 540cb3125cd..f9f33fe2e11 100644
--- a/chromium/content/renderer/media/mojo_audio_input_ipc_unittest.cc
+++ b/chromium/content/renderer/media/audio/mojo_audio_input_ipc_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/renderer/media/mojo_audio_input_ipc.h"
+#include "content/renderer/media/audio/mojo_audio_input_ipc.h"
#include <algorithm>
#include <memory>
@@ -52,11 +52,9 @@ class MockDelegate : public media::AudioInputIPCDelegate {
MockDelegate() {}
~MockDelegate() override {}
- void OnStreamCreated(base::SharedMemoryHandle mem_handle,
+ void OnStreamCreated(base::ReadOnlySharedMemoryRegion mem_handle,
base::SyncSocket::Handle socket_handle,
bool initially_muted) override {
- base::SharedMemory sh_mem(
- mem_handle, /*read_only*/ true); // Releases the shared memory handle.
base::SyncSocket socket(socket_handle); // Releases the socket descriptor.
GotOnStreamCreated(initially_muted);
}
@@ -88,8 +86,7 @@ class FakeStreamCreator {
factory_client_->StreamCreated(
std::move(stream_ptr), mojo::MakeRequest(&stream_client_),
{base::in_place,
- mojo::SharedBufferHandle::Create(kMemoryLength)
- ->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY),
+ base::ReadOnlySharedMemoryRegion::Create(kMemoryLength).region,
mojo::WrapPlatformFile(foreign_socket.Release())},
initially_muted_, base::UnguessableToken::Create());
}
diff --git a/chromium/content/renderer/media/mojo_audio_output_ipc.cc b/chromium/content/renderer/media/audio/mojo_audio_output_ipc.cc
index 35ead19d6b9..1782dd20420 100644
--- a/chromium/content/renderer/media/mojo_audio_output_ipc.cc
+++ b/chromium/content/renderer/media/audio/mojo_audio_output_ipc.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/media/mojo_audio_output_ipc.h"
+#include "content/renderer/media/audio/mojo_audio_output_ipc.h"
#include <utility>
@@ -214,8 +214,9 @@ void MojoAudioOutputIPC::ReceivedDeviceAuthorization(
delegate_->OnDeviceAuthorized(status, params, device_id);
}
-void MojoAudioOutputIPC::Created(media::mojom::AudioOutputStreamPtr stream,
- media::mojom::AudioDataPipePtr data_pipe) {
+void MojoAudioOutputIPC::Created(
+ media::mojom::AudioOutputStreamPtr stream,
+ media::mojom::ReadWriteAudioDataPipePtr data_pipe) {
DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
DCHECK(delegate_);
@@ -228,17 +229,11 @@ void MojoAudioOutputIPC::Created(media::mojom::AudioOutputStreamPtr stream,
mojo::UnwrapPlatformFile(std::move(data_pipe->socket), &socket_handle);
DCHECK_EQ(result, MOJO_RESULT_OK);
- base::SharedMemoryHandle memory_handle;
- mojo::UnwrappedSharedMemoryHandleProtection protection;
- size_t memory_length = 0;
- result = mojo::UnwrapSharedMemoryHandle(std::move(data_pipe->shared_memory),
- &memory_handle, &memory_length,
- &protection);
- DCHECK_EQ(result, MOJO_RESULT_OK);
- DCHECK_EQ(protection,
- mojo::UnwrappedSharedMemoryHandleProtection::kReadWrite);
+ base::UnsafeSharedMemoryRegion& shared_memory_region =
+ data_pipe->shared_memory;
+ DCHECK(shared_memory_region.IsValid());
- delegate_->OnStreamCreated(memory_handle, socket_handle,
+ delegate_->OnStreamCreated(std::move(shared_memory_region), socket_handle,
expected_state_ == kPlaying);
if (volume_)
diff --git a/chromium/content/renderer/media/mojo_audio_output_ipc.h b/chromium/content/renderer/media/audio/mojo_audio_output_ipc.h
index bd78a490a92..00084e5928e 100644
--- a/chromium/content/renderer/media/mojo_audio_output_ipc.h
+++ b/chromium/content/renderer/media/audio/mojo_audio_output_ipc.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CONTENT_RENDERER_MEDIA_MOJO_AUDIO_OUTPUT_IPC_H_
-#define CONTENT_RENDERER_MEDIA_MOJO_AUDIO_OUTPUT_IPC_H_
+#ifndef CONTENT_RENDERER_MEDIA_AUDIO_MOJO_AUDIO_OUTPUT_IPC_H_
+#define CONTENT_RENDERER_MEDIA_AUDIO_MOJO_AUDIO_OUTPUT_IPC_H_
#include <string>
@@ -52,7 +52,7 @@ class CONTENT_EXPORT MojoAudioOutputIPC
// media::mojom::AudioOutputStreamProviderClient implementation.
void Created(media::mojom::AudioOutputStreamPtr stream,
- media::mojom::AudioDataPipePtr data_pipe) override;
+ media::mojom::ReadWriteAudioDataPipePtr data_pipe) override;
private:
static constexpr double kDefaultVolume = 1.0;
@@ -104,4 +104,4 @@ class CONTENT_EXPORT MojoAudioOutputIPC
} // namespace content
-#endif // CONTENT_RENDERER_MEDIA_MOJO_AUDIO_OUTPUT_IPC_H_
+#endif // CONTENT_RENDERER_MEDIA_AUDIO_MOJO_AUDIO_OUTPUT_IPC_H_
diff --git a/chromium/content/renderer/media/mojo_audio_output_ipc_unittest.cc b/chromium/content/renderer/media/audio/mojo_audio_output_ipc_unittest.cc
index 58be5468279..100687c928c 100644
--- a/chromium/content/renderer/media/mojo_audio_output_ipc_unittest.cc
+++ b/chromium/content/renderer/media/audio/mojo_audio_output_ipc_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/renderer/media/mojo_audio_output_ipc.h"
+#include "content/renderer/media/audio/mojo_audio_output_ipc.h"
#include <algorithm>
#include <memory>
@@ -70,7 +70,7 @@ class TestStreamProvider : public media::mojom::AudioOutputStreamProvider {
base::CancelableSyncSocket::CreatePair(&socket_, &foreign_socket));
provider_client_->Created(
std::move(stream_ptr),
- {base::in_place, mojo::SharedBufferHandle::Create(kMemoryLength),
+ {base::in_place, base::UnsafeSharedMemoryRegion::Create(kMemoryLength),
mojo::WrapPlatformFile(foreign_socket.Release())});
}
@@ -180,11 +180,9 @@ class MockDelegate : public media::AudioOutputIPCDelegate {
MockDelegate() {}
~MockDelegate() override {}
- void OnStreamCreated(base::SharedMemoryHandle mem_handle,
+ void OnStreamCreated(base::UnsafeSharedMemoryRegion mem_handle,
base::SyncSocket::Handle socket_handle,
bool playing_automatically) 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();
}
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 8336e384eec..6022a765b1b 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
@@ -223,7 +223,6 @@ bool GpuVideoAcceleratorFactoriesImpl::CreateTextures(
gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
}
- gles2->GenMailboxCHROMIUM(texture_mailboxes->at(i).name);
gles2->ProduceTextureDirectCHROMIUM(texture_id,
texture_mailboxes->at(i).name);
}
@@ -312,9 +311,8 @@ GpuVideoAcceleratorFactoriesImpl::VideoFrameOutputFormat(size_t bit_depth) {
if (rendering_color_space_.IsHDR())
return media::GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED;
-#if defined(OS_MACOSX) || defined(OS_LINUX)
- // TODO(mcasas): enable other platforms https://crbug.com/776093
- // https://crbug.com/803451.
+#if !defined(OS_WIN)
+ // TODO(mcasas): enable Win https://crbug.com/803451.
// TODO(mcasas): remove the |bit_depth| check when libyuv supports more than
// just x010ToAR30 conversions, https://crbug.com/libyuv/751.
if (bit_depth == 10) {
diff --git a/chromium/content/renderer/media/media_factory.cc b/chromium/content/renderer/media/media_factory.cc
index 5e2119c7f4c..fe25c6b87ab 100644
--- a/chromium/content/renderer/media/media_factory.cc
+++ b/chromium/content/renderer/media/media_factory.cc
@@ -15,7 +15,7 @@
#include "build/buildflag.h"
#include "content/public/common/content_client.h"
#include "content/public/renderer/content_renderer_client.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "content/renderer/media/render_media_log.h"
#include "content/renderer/media/renderer_webmediaplayer_delegate.h"
#include "content/renderer/media/stream/media_stream_renderer_factory_impl.h"
@@ -28,7 +28,6 @@
#include "media/base/decoder_factory.h"
#include "media/base/media_switches.h"
#include "media/base/renderer_factory_selector.h"
-#include "media/base/surface_manager.h"
#include "media/blink/remote_playback_client_wrapper_impl.h"
#include "media/blink/resource_fetch_context.h"
#include "media/blink/webencryptedmediaclient_impl.h"
@@ -46,12 +45,12 @@
#include "third_party/blink/public/platform/web_video_frame_submitter.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/public/web/web_local_frame.h"
+#include "ui/base/ui_base_features.h"
#include "url/origin.h"
#if defined(OS_ANDROID)
#include "content/renderer/media/android/media_player_renderer_client_factory.h"
#include "content/renderer/media/android/renderer_media_player_manager.h"
-#include "content/renderer/media/android/renderer_surface_view_manager.h"
#include "content/renderer/media/android/stream_texture_wrapper_impl.h"
#include "media/base/android/media_codec_util.h"
#include "media/base/media.h"
@@ -139,6 +138,21 @@ void PostMediaContextProviderToCallback(
namespace content {
+// static
+bool MediaFactory::VideoSurfaceLayerEnabled() {
+ // LayoutTests do not support SurfaceLayer by default at the moment.
+ // See https://crbug.com/838128
+ content::RenderThreadImpl* render_thread =
+ content::RenderThreadImpl::current();
+ if (render_thread && render_thread->layout_test_mode() &&
+ !render_thread->LayoutTestModeUsesDisplayCompositorPixelDump()) {
+ return false;
+ }
+
+ return base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideo) &&
+ features::IsAshInBrowserProcess();
+}
+
MediaFactory::MediaFactory(
RenderFrameImpl* render_frame,
media::RequestRoutingTokenCallback request_routing_token_cb)
@@ -223,8 +237,6 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
bool use_media_player_renderer = false;
#if defined(OS_ANDROID)
use_media_player_renderer = UseMediaPlayerRenderer(url);
- if (!use_media_player_renderer && !media_surface_manager_)
- media_surface_manager_ = new RendererSurfaceViewManager(render_frame_);
embedded_media_experience_enabled =
webkit_preferences.embedded_media_experience_enabled;
#endif // defined(OS_ANDROID)
@@ -278,8 +290,7 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
scoped_refptr<base::SingleThreadTaskRunner>
video_frame_compositor_task_runner;
std::unique_ptr<blink::WebVideoFrameSubmitter> submitter;
- bool use_surface_layer_for_video =
- base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideo);
+ bool use_surface_layer_for_video = VideoSurfaceLayerEnabled();
if (use_surface_layer_for_video) {
// TODO(lethalantidote): Use a separate task_runner. https://crbug/753605.
video_frame_compositor_task_runner =
@@ -298,25 +309,36 @@ blink::WebMediaPlayer* MediaFactory::CreateMediaPlayer(
}
DCHECK(layer_tree_view);
+ scoped_refptr<base::SingleThreadTaskRunner> media_task_runner =
+ render_thread->GetMediaThreadTaskRunner();
+
+ if (!media_task_runner) {
+ // If the media thread failed to start, we will receive a null task runner.
+ // Fail the creation by returning null, and let callers handle the error.
+ // See https://crbug.com/775393.
+ return nullptr;
+ }
+
std::unique_ptr<media::WebMediaPlayerParams> params(
new media::WebMediaPlayerParams(
std::move(media_log),
- base::Bind(&ContentRendererClient::DeferMediaLoad,
- base::Unretained(GetContentClient()->renderer()),
- static_cast<RenderFrame*>(render_frame_),
- GetWebMediaPlayerDelegate()->has_played_media()),
- audio_renderer_sink, render_thread->GetMediaThreadTaskRunner(),
+ base::BindRepeating(&ContentRendererClient::DeferMediaLoad,
+ base::Unretained(GetContentClient()->renderer()),
+ static_cast<RenderFrame*>(render_frame_),
+ GetWebMediaPlayerDelegate()->has_played_media()),
+ audio_renderer_sink, media_task_runner,
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_,
- media_observer, max_keyframe_distance_to_disable_background_video,
+ initial_cdm, request_routing_token_cb_, media_observer,
+ max_keyframe_distance_to_disable_background_video,
max_keyframe_distance_to_disable_background_video_mse,
enable_instant_source_buffer_gc, embedded_media_experience_enabled,
std::move(metrics_provider),
- base::Bind(&blink::WebSurfaceLayerBridge::Create, layer_tree_view),
+ base::BindOnce(&blink::WebSurfaceLayerBridge::Create,
+ layer_tree_view),
RenderThreadImpl::current()->SharedMainThreadContextProvider(),
use_surface_layer_for_video));
diff --git a/chromium/content/renderer/media/media_factory.h b/chromium/content/renderer/media/media_factory.h
index 1d5aeece741..7c4ea973a11 100644
--- a/chromium/content/renderer/media/media_factory.h
+++ b/chromium/content/renderer/media/media_factory.h
@@ -45,7 +45,6 @@ class MediaLog;
class MediaObserver;
class RemotePlaybackClientWrapper;
class RendererWebMediaPlayerDelegate;
-class SurfaceManager;
class WebEncryptedMediaClientImpl;
#if defined(OS_ANDROID)
class RendererMediaPlayerManager;
@@ -72,6 +71,9 @@ class RendererMediaPlayerManager;
// Assist to RenderFrameImpl in creating various media clients.
class MediaFactory {
public:
+ // Helper function returning whether VideoSurfaceLayer should be enabled.
+ static bool VideoSurfaceLayerEnabled();
+
// Create a MediaFactory to assist the |render_frame| with media tasks.
// |request_routing_token_cb| bound to |render_frame| IPC functions for
// obtaining overlay tokens.
@@ -172,10 +174,6 @@ class MediaFactory {
RendererMediaPlayerManager* media_player_manager_ = nullptr;
#endif
- // Handles requests for SurfaceViews for MediaPlayers.
- // Lifetime is tied to the RenderFrame via the RenderFrameObserver interface.
- media::SurfaceManager* media_surface_manager_ = nullptr;
-
// Manages play, pause notifications for WebMediaPlayer implementations; its
// lifetime is tied to the RenderFrame via the RenderFrameObserver interface.
media::RendererWebMediaPlayerDelegate* media_player_delegate_ = nullptr;
diff --git a/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc b/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc
index 9f8eb121f4c..ce350d3026f 100644
--- a/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc
+++ b/chromium/content/renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc
@@ -71,8 +71,8 @@ TEST_F(PepperToVideoTrackAdapterTest, PutFrame) {
// Verify the video track has been added.
const blink::WebMediaStream test_stream = registry_->test_stream();
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- test_stream.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ test_stream.VideoTracks();
ASSERT_EQ(1u, video_tracks.size());
// Verify the native video track has been added.
diff --git a/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.cc b/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.cc
index 6787c2ea278..a87b792ff77 100644
--- a/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.cc
+++ b/chromium/content/renderer/media/pepper/video_track_to_pepper_adapter.cc
@@ -106,8 +106,8 @@ blink::WebMediaStreamTrack VideoTrackToPepperAdapter::GetFirstVideoTrack(
}
// Get the first video track from the stream.
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- stream.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ stream.VideoTracks();
if (video_tracks.IsEmpty()) {
LOG(ERROR) << "GetFirstVideoSource - no video tracks. url: " << url;
return blink::WebMediaStreamTrack();
diff --git a/chromium/content/renderer/media/renderer_webaudiodevice_impl.cc b/chromium/content/renderer/media/renderer_webaudiodevice_impl.cc
index 8c6ca64ef59..1c57ddf3713 100644
--- a/chromium/content/renderer/media/renderer_webaudiodevice_impl.cc
+++ b/chromium/content/renderer/media/renderer_webaudiodevice_impl.cc
@@ -13,7 +13,7 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "base/time/time.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "media/base/audio_timestamp_helper.h"
diff --git a/chromium/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc b/chromium/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc
index 5b338c5e67b..337fff50fc4 100644
--- a/chromium/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc
+++ b/chromium/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc
@@ -8,7 +8,7 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "media/base/audio_capturer_source.h"
#include "media/base/limits.h"
#include "media/base/mock_audio_renderer_sink.h"
diff --git a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
index 31ba7ced7ae..f644a25e76f 100644
--- a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
+++ b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.cc
@@ -276,6 +276,8 @@ bool RendererWebMediaPlayerDelegate::OnMessageReceived(
OnMediaDelegateBecamePersistentVideo)
IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_EndPictureInPictureMode,
OnPictureInPictureModeEnded)
+ IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_ClickPictureInPictureControl,
+ OnPictureInPictureControlClicked)
IPC_MESSAGE_HANDLER(MediaPlayerDelegateMsg_OnPictureInPictureModeEnded_ACK,
OnPictureInPictureModeEndedAck)
IPC_MESSAGE_HANDLER(
@@ -394,6 +396,14 @@ void RendererWebMediaPlayerDelegate::OnPictureInPictureModeEnded(
observer->OnPictureInPictureModeEnded();
}
+void RendererWebMediaPlayerDelegate::OnPictureInPictureControlClicked(
+ int player_id,
+ const std::string& control_id) {
+ Observer* observer = id_map_.Lookup(player_id);
+ if (observer)
+ observer->OnPictureInPictureControlClicked(control_id);
+}
+
void RendererWebMediaPlayerDelegate::OnPictureInPictureModeEndedAck(
int player_id,
int request_id) {
diff --git a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
index 171141ef960..5897004debb 100644
--- a/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
+++ b/chromium/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -107,6 +107,8 @@ class CONTENT_EXPORT RendererWebMediaPlayerDelegate
void OnMediaDelegateVolumeMultiplierUpdate(int player_id, double multiplier);
void OnMediaDelegateBecamePersistentVideo(int player_id, bool value);
void OnPictureInPictureModeEnded(int player_id);
+ void OnPictureInPictureControlClicked(int player_id,
+ const std::string& control_id);
void OnPictureInPictureModeEndedAck(int player_id, int request_id);
void OnPictureInPictureModeStartedAck(int player_id,
int request_id,
diff --git a/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc b/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
index 26d8e6ab43b..8c2cf76c616 100644
--- a/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
+++ b/chromium/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
@@ -9,7 +9,7 @@
#include "base/location.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/common/media/media_player_delegate_messages.h"
@@ -49,6 +49,7 @@ class MockWebMediaPlayerDelegateObserver
MOCK_METHOD1(OnVolumeMultiplierUpdate, void(double));
MOCK_METHOD1(OnBecamePersistentVideo, void(bool));
MOCK_METHOD0(OnPictureInPictureModeEnded, void());
+ MOCK_METHOD1(OnPictureInPictureControlClicked, void(const std::string&));
};
class RendererWebMediaPlayerDelegateTest : public content::RenderViewTest {
diff --git a/chromium/content/renderer/media/stream/local_media_stream_audio_source.cc b/chromium/content/renderer/media/stream/local_media_stream_audio_source.cc
index 25d43bf45c8..a51cc04af8f 100644
--- a/chromium/content/renderer/media/stream/local_media_stream_audio_source.cc
+++ b/chromium/content/renderer/media/stream/local_media_stream_audio_source.cc
@@ -4,7 +4,7 @@
#include "content/renderer/media/stream/local_media_stream_audio_source.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "content/renderer/media/webrtc_logging.h"
#include "content/renderer/render_frame_impl.h"
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_processor.cc b/chromium/content/renderer/media/stream/media_stream_audio_processor.cc
index 9b76c672c26..d71f25992ac 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_processor.cc
+++ b/chromium/content/renderer/media/stream/media_stream_audio_processor.cc
@@ -36,6 +36,8 @@
namespace content {
+using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
+
namespace {
using webrtc::AudioProcessing;
@@ -104,19 +106,6 @@ bool UseAecRefinedAdaptiveFilter() {
switches::kAecRefinedAdaptiveFilter);
}
-webrtc::Point WebrtcPointFromMediaPoint(const media::Point& point) {
- return webrtc::Point(point.x(), point.y(), point.z());
-}
-
-std::vector<webrtc::Point> WebrtcPointsFromMediaPoints(
- const std::vector<media::Point>& points) {
- std::vector<webrtc::Point> webrtc_points;
- webrtc_points.reserve(webrtc_points.size());
- for (const auto& point : points)
- webrtc_points.push_back(WebrtcPointFromMediaPoint(point));
- return webrtc_points;
-}
-
} // namespace
// Wraps AudioBus to provide access to the array of channel pointers, since this
@@ -425,8 +414,9 @@ void MediaStreamAudioProcessor::OnAecDumpFile(
// webrtc::AudioProcessing instance is destroyed.
StartEchoCancellationDump(audio_processing_.get(), std::move(file),
worker_queue_.get());
- } else
+ } else {
file.Close();
+ }
}
void MediaStreamAudioProcessor::OnDisableAecDump() {
@@ -454,7 +444,7 @@ bool MediaStreamAudioProcessor::WouldModifyAudio(
return true;
#if !defined(OS_IOS)
- if (properties.enable_sw_echo_cancellation ||
+ if (properties.EchoCancellationIsWebRtcProvided() ||
properties.goog_auto_gain_control) {
return true;
}
@@ -469,7 +459,7 @@ bool MediaStreamAudioProcessor::WouldModifyAudio(
if (properties.goog_noise_suppression ||
properties.goog_experimental_noise_suppression ||
- properties.goog_beamforming || properties.goog_highpass_filter) {
+ properties.goog_highpass_filter) {
return true;
}
@@ -568,11 +558,11 @@ void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
// Return immediately if none of the goog constraints requiring
// webrtc::AudioProcessing are enabled.
- if (!properties.enable_sw_echo_cancellation && !goog_experimental_aec &&
- !properties.goog_noise_suppression && !properties.goog_highpass_filter &&
- !goog_typing_detection && !properties.goog_auto_gain_control &&
- !properties.goog_experimental_noise_suppression &&
- !properties.goog_beamforming) {
+ if (!properties.EchoCancellationIsWebRtcProvided() &&
+ !goog_experimental_aec && !properties.goog_noise_suppression &&
+ !properties.goog_highpass_filter && !goog_typing_detection &&
+ !properties.goog_auto_gain_control &&
+ !properties.goog_experimental_noise_suppression) {
// Sanity-check: WouldModifyAudio() should return true iff
// |audio_mirroring_| is true.
DCHECK_EQ(audio_mirroring_, WouldModifyAudio(properties));
@@ -595,12 +585,6 @@ void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
config.Set<webrtc::RefinedAdaptiveFilter>(
new webrtc::RefinedAdaptiveFilter(true));
}
- if (properties.goog_beamforming) {
- // Only enable beamforming if we have at least two mics.
- config.Set<webrtc::Beamforming>(new webrtc::Beamforming(
- properties.goog_array_geometry.size() > 1,
- WebrtcPointsFromMediaPoints(properties.goog_array_geometry)));
- }
// If the experimental AGC is enabled, check for overridden config params.
if (properties.goog_experimental_auto_gain_control) {
@@ -609,21 +593,10 @@ void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
new webrtc::ExperimentalAgc(true, startup_min_volume.value_or(0)));
}
- // Check if experimental echo canceller should be used.
- if (properties.enable_sw_echo_cancellation) {
- base::Optional<bool> override_aec3;
- // 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.
- if (aec_dump_message_filter_)
- override_aec3 = aec_dump_message_filter_->GetOverrideAec3();
- using_aec3_ = override_aec3.value_or(
- base::FeatureList::IsEnabled(features::kWebRtcUseEchoCanceller3));
- }
-
// Create and configure the webrtc::AudioProcessing.
webrtc::AudioProcessingBuilder ap_builder;
- if (using_aec3_) {
+ if (properties.echo_cancellation_type ==
+ EchoCancellationType::kEchoCancellationAec3) {
webrtc::EchoCanceller3Config aec3_config;
aec3_config.ep_strength.bounded_erl =
base::FeatureList::IsEnabled(features::kWebRtcAecBoundedErlSetup);
@@ -645,25 +618,20 @@ void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
playout_data_source_->AddPlayoutSink(this);
}
- if (properties.enable_sw_echo_cancellation) {
+ if (properties.EchoCancellationIsWebRtcProvided()) {
EnableEchoCancellation(audio_processing_.get());
// Prepare for logging echo information. Do not log any echo information
// when AEC3 is active, as the echo information then will not be properly
// updated.
- if (!using_aec3_)
+ if (properties.echo_cancellation_type !=
+ EchoCancellationType::kEchoCancellationAec3) {
echo_information_ = std::make_unique<EchoInformation>();
+ }
}
- if (properties.goog_noise_suppression) {
- // The beamforming postfilter is effective at suppressing stationary noise,
- // so reduce the single-channel NS aggressiveness when enabled.
- const NoiseSuppression::Level ns_level =
- config.Get<webrtc::Beamforming>().enabled ? NoiseSuppression::kLow
- : NoiseSuppression::kHigh;
-
- EnableNoiseSuppression(audio_processing_.get(), ns_level);
- }
+ if (properties.goog_noise_suppression)
+ EnableNoiseSuppression(audio_processing_.get(), NoiseSuppression::kHigh);
apm_config.high_pass_filter.enabled = properties.goog_highpass_filter;
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_processor.h b/chromium/content/renderer/media/stream/media_stream_audio_processor.h
index c7b1d1c1287..c5237570077 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_processor.h
+++ b/chromium/content/renderer/media/stream/media_stream_audio_processor.h
@@ -120,10 +120,6 @@ class CONTENT_EXPORT MediaStreamAudioProcessor
protected:
~MediaStreamAudioProcessor() override;
- // True if AEC3 is used, false if it's not or no AEC is used at all. Used for
- // verification in tests.
- bool using_aec3_ = false;
-
private:
friend class MediaStreamAudioProcessorTest;
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_processor_options.cc b/chromium/content/renderer/media/stream/media_stream_audio_processor_options.cc
index 4c471a4ea36..7a5a6274a5c 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_processor_options.cc
+++ b/chromium/content/renderer/media/stream/media_stream_audio_processor_options.cc
@@ -67,25 +67,29 @@ AudioProcessingProperties::AudioProcessingProperties(
const AudioProcessingProperties& other) = default;
AudioProcessingProperties& AudioProcessingProperties::operator=(
const AudioProcessingProperties& other) = default;
-AudioProcessingProperties::AudioProcessingProperties(
- AudioProcessingProperties&& other) = default;
-AudioProcessingProperties& AudioProcessingProperties::operator=(
- AudioProcessingProperties&& other) = default;
-AudioProcessingProperties::~AudioProcessingProperties() = default;
void AudioProcessingProperties::DisableDefaultProperties() {
- enable_sw_echo_cancellation = false;
- disable_hw_echo_cancellation = false;
+ echo_cancellation_type = EchoCancellationType::kEchoCancellationDisabled;
goog_auto_gain_control = false;
goog_experimental_echo_cancellation = false;
goog_typing_noise_detection = false;
goog_noise_suppression = false;
goog_experimental_noise_suppression = false;
- goog_beamforming = false;
goog_highpass_filter = false;
goog_experimental_auto_gain_control = false;
}
+bool AudioProcessingProperties::EchoCancellationEnabled() const {
+ return echo_cancellation_type !=
+ EchoCancellationType::kEchoCancellationDisabled;
+}
+
+bool AudioProcessingProperties::EchoCancellationIsWebRtcProvided() const {
+ return echo_cancellation_type ==
+ EchoCancellationType::kEchoCancellationAec2 ||
+ echo_cancellation_type == EchoCancellationType::kEchoCancellationAec3;
+}
+
EchoInformation::EchoInformation()
: delay_stats_time_ms_(0),
echo_frames_received_(false),
@@ -271,8 +275,7 @@ void EnableAutomaticGainControl(AudioProcessing* audio_processing) {
void GetAudioProcessingStats(
AudioProcessing* audio_processing,
webrtc::AudioProcessorInterface::AudioProcessorStats* stats) {
- // TODO(ivoc): Change the APM stats to use rtc::Optional instead of default
- // values.
+ // TODO(ivoc): Change the APM stats to use optional instead of default values.
auto apm_stats = audio_processing->GetStatistics();
stats->echo_return_loss = apm_stats.echo_return_loss.instant();
stats->echo_return_loss_enhancement =
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_processor_options.h b/chromium/content/renderer/media/stream/media_stream_audio_processor_options.h
index 235fd87a925..75dd60a9879 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_processor_options.h
+++ b/chromium/content/renderer/media/stream/media_stream_audio_processor_options.h
@@ -33,21 +33,35 @@ using webrtc::AudioProcessing;
// Simple struct with audio-processing properties.
struct CONTENT_EXPORT AudioProcessingProperties {
+ enum class EchoCancellationType {
+ // Echo cancellation disabled.
+ kEchoCancellationDisabled,
+ // The WebRTC-provided AEC2 echo canceller.
+ kEchoCancellationAec2,
+ // The WebRTC-provided AEC3 echo canceller.
+ kEchoCancellationAec3,
+ // System echo canceller, for example an OS-provided or hardware echo
+ // canceller.
+ kEchoCancellationSystem
+ };
+
// Creates an AudioProcessingProperties object with fields initialized to
// their default values.
AudioProcessingProperties();
AudioProcessingProperties(const AudioProcessingProperties& other);
AudioProcessingProperties& operator=(const AudioProcessingProperties& other);
- AudioProcessingProperties(AudioProcessingProperties&& other);
- AudioProcessingProperties& operator=(AudioProcessingProperties&& other);
- ~AudioProcessingProperties();
// Disables properties that are enabled by default.
void DisableDefaultProperties();
- bool enable_sw_echo_cancellation = true;
- bool disable_hw_echo_cancellation = true;
- bool enable_experimental_hw_echo_cancellation = false;
+ // Returns whether echo cancellation is enabled.
+ bool EchoCancellationEnabled() const;
+
+ // Returns whether WebRTC-provided echo cancellation is enabled.
+ bool EchoCancellationIsWebRtcProvided() const;
+
+ EchoCancellationType echo_cancellation_type =
+ EchoCancellationType::kEchoCancellationAec2;
bool disable_hw_noise_suppression = false;
bool goog_audio_mirroring = false;
bool goog_auto_gain_control = true;
@@ -60,10 +74,8 @@ struct CONTENT_EXPORT AudioProcessingProperties {
bool goog_typing_noise_detection = true;
bool goog_noise_suppression = true;
bool goog_experimental_noise_suppression = true;
- bool goog_beamforming = true;
bool goog_highpass_filter = true;
bool goog_experimental_auto_gain_control = true;
- std::vector<media::Point> goog_array_geometry;
};
// A helper class to log echo information in general and Echo Cancellation
diff --git a/chromium/content/renderer/media/stream/media_stream_audio_processor_unittest.cc b/chromium/content/renderer/media/stream/media_stream_audio_processor_unittest.cc
index 16e71069bdb..19dff280a73 100644
--- a/chromium/content/renderer/media/stream/media_stream_audio_processor_unittest.cc
+++ b/chromium/content/renderer/media/stream/media_stream_audio_processor_unittest.cc
@@ -40,14 +40,6 @@ using ::testing::Return;
using media::AudioParameters;
-namespace webrtc {
-
-bool operator==(const webrtc::Point& lhs, const webrtc::Point& rhs) {
- return lhs.x() == rhs.x() && lhs.y() == rhs.y() && lhs.z() == rhs.z();
-}
-
-} // namespace webrtc
-
namespace content {
namespace {
@@ -80,35 +72,6 @@ void ReadDataFromSpeechFile(char* data, int length) {
} // namespace
-class AecDumpMessageFilterForTest : public AecDumpMessageFilter {
- public:
- // This class is only used for setting |override_aec3_|, so we simply inject
- // the current task runner.
- AecDumpMessageFilterForTest()
- : AecDumpMessageFilter(base::MessageLoopCurrent::Get()->task_runner(),
- base::MessageLoopCurrent::Get()->task_runner()) {}
-
- void set_override_aec3(base::Optional<bool> override_aec3) {
- override_aec3_ = override_aec3;
- }
-
- protected:
- ~AecDumpMessageFilterForTest() override {}
-};
-
-class MediaStreamAudioProcessorUnderTest : public MediaStreamAudioProcessor {
- public:
- MediaStreamAudioProcessorUnderTest(
- const AudioProcessingProperties& properties,
- WebRtcPlayoutDataSource* playout_data_source)
- : MediaStreamAudioProcessor(properties, playout_data_source) {}
-
- bool using_aec3() { return using_aec3_; }
-
- protected:
- ~MediaStreamAudioProcessorUnderTest() override {}
-};
-
class MediaStreamAudioProcessorTest : public ::testing::Test {
public:
MediaStreamAudioProcessorTest()
@@ -247,8 +210,8 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_WithAudioProcessing) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
- scoped_refptr<MediaStreamAudioProcessorUnderTest> audio_processor(
- new rtc::RefCountedObject<MediaStreamAudioProcessorUnderTest>(
+ scoped_refptr<MediaStreamAudioProcessor> audio_processor(
+ new rtc::RefCountedObject<MediaStreamAudioProcessor>(
properties, webrtc_audio_device.get()));
EXPECT_TRUE(audio_processor->has_audio_processing());
audio_processor->OnCaptureFormatChanged(params_);
@@ -270,8 +233,8 @@ TEST_F(MediaStreamAudioProcessorTest, TurnOffDefaultConstraints) {
properties.DisableDefaultProperties();
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
- scoped_refptr<MediaStreamAudioProcessorUnderTest> audio_processor(
- new rtc::RefCountedObject<MediaStreamAudioProcessorUnderTest>(
+ scoped_refptr<MediaStreamAudioProcessor> audio_processor(
+ new rtc::RefCountedObject<MediaStreamAudioProcessor>(
properties, webrtc_audio_device.get()));
EXPECT_FALSE(audio_processor->has_audio_processing());
audio_processor->OnCaptureFormatChanged(params_);
@@ -296,8 +259,8 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestAllSampleRates) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
- scoped_refptr<MediaStreamAudioProcessorUnderTest> audio_processor(
- new rtc::RefCountedObject<MediaStreamAudioProcessorUnderTest>(
+ scoped_refptr<MediaStreamAudioProcessor> audio_processor(
+ new rtc::RefCountedObject<MediaStreamAudioProcessor>(
properties, webrtc_audio_device.get()));
EXPECT_TRUE(audio_processor->has_audio_processing());
@@ -334,8 +297,8 @@ TEST_F(MediaStreamAudioProcessorTest, GetAecDumpMessageFilter) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
- scoped_refptr<MediaStreamAudioProcessorUnderTest> audio_processor(
- new rtc::RefCountedObject<MediaStreamAudioProcessorUnderTest>(
+ scoped_refptr<MediaStreamAudioProcessor> audio_processor(
+ new rtc::RefCountedObject<MediaStreamAudioProcessor>(
properties, webrtc_audio_device.get()));
EXPECT_TRUE(audio_processor->aec_dump_message_filter_.get());
@@ -356,8 +319,8 @@ TEST_F(MediaStreamAudioProcessorTest, StartStopAecDump) {
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_directory.GetPath(),
&temp_file_path));
{
- scoped_refptr<MediaStreamAudioProcessorUnderTest> audio_processor(
- new rtc::RefCountedObject<MediaStreamAudioProcessorUnderTest>(
+ scoped_refptr<MediaStreamAudioProcessor> audio_processor(
+ new rtc::RefCountedObject<MediaStreamAudioProcessor>(
properties, webrtc_audio_device.get()));
// Start and stop recording.
@@ -386,8 +349,8 @@ TEST_F(MediaStreamAudioProcessorTest, TestStereoAudio) {
// Turn off the audio processing and turn on the stereo channels mirroring.
properties.DisableDefaultProperties();
properties.goog_audio_mirroring = true;
- scoped_refptr<MediaStreamAudioProcessorUnderTest> audio_processor(
- new rtc::RefCountedObject<MediaStreamAudioProcessorUnderTest>(
+ scoped_refptr<MediaStreamAudioProcessor> audio_processor(
+ new rtc::RefCountedObject<MediaStreamAudioProcessor>(
properties, webrtc_audio_device.get()));
EXPECT_FALSE(audio_processor->has_audio_processing());
const media::AudioParameters source_params(
@@ -447,8 +410,8 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestWithKeyboardMicChannel) {
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
AudioProcessingProperties properties;
- scoped_refptr<MediaStreamAudioProcessorUnderTest> audio_processor(
- new rtc::RefCountedObject<MediaStreamAudioProcessorUnderTest>(
+ scoped_refptr<MediaStreamAudioProcessor> audio_processor(
+ new rtc::RefCountedObject<MediaStreamAudioProcessor>(
properties, webrtc_audio_device.get()));
EXPECT_TRUE(audio_processor->has_audio_processing());
@@ -467,47 +430,4 @@ TEST_F(MediaStreamAudioProcessorTest, MAYBE_TestWithKeyboardMicChannel) {
audio_processor->Stop();
}
-// Test that setting AEC3 override has the desired effect on the APM
-// configuration.
-TEST_F(MediaStreamAudioProcessorTest, TestAec3Switch) {
- scoped_refptr<AecDumpMessageFilterForTest> admf =
- new AecDumpMessageFilterForTest();
- admf->set_override_aec3(true);
-
- scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
- new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
- AudioProcessingProperties properties;
- scoped_refptr<MediaStreamAudioProcessorUnderTest> audio_processor(
- new rtc::RefCountedObject<MediaStreamAudioProcessorUnderTest>(
- properties, webrtc_audio_device.get()));
-
- EXPECT_TRUE(audio_processor->using_aec3());
-
- // Stop |audio_processor| so that it removes itself from
- // |webrtc_audio_device| and clears its pointer to it.
- audio_processor->Stop();
-}
-
-// Same test as above, but when AEC is disabled in the constraints. The expected
-// outcome is that AEC3 should be disabled in all cases.
-TEST_F(MediaStreamAudioProcessorTest, TestAec3Switch_AecOff) {
- scoped_refptr<AecDumpMessageFilterForTest> admf =
- new AecDumpMessageFilterForTest();
- admf->set_override_aec3(true);
-
- scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
- new rtc::RefCountedObject<WebRtcAudioDeviceImpl>());
- AudioProcessingProperties properties;
- properties.enable_sw_echo_cancellation = false;
- scoped_refptr<MediaStreamAudioProcessorUnderTest> audio_processor(
- new rtc::RefCountedObject<MediaStreamAudioProcessorUnderTest>(
- properties, webrtc_audio_device.get()));
-
- EXPECT_FALSE(audio_processor->using_aec3());
-
- // Stop |audio_processor| so that it removes itself from
- // |webrtc_audio_device| and clears its pointer to it.
- audio_processor->Stop();
-}
-
} // namespace content
diff --git a/chromium/content/renderer/media/stream/media_stream_center.cc b/chromium/content/renderer/media/stream/media_stream_center.cc
index f2972e9353a..a5e056ff5ef 100644
--- a/chromium/content/renderer/media/stream/media_stream_center.cc
+++ b/chromium/content/renderer/media/stream/media_stream_center.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include <string>
+#include <vector>
#include "base/command_line.h"
#include "base/logging.h"
@@ -17,11 +18,12 @@
#include "content/renderer/media/stream/media_stream_source.h"
#include "content/renderer/media/stream/media_stream_video_source.h"
#include "content/renderer/media/stream/media_stream_video_track.h"
+#include "content/renderer/media/stream/processed_local_audio_source.h"
#include "content/renderer/media/stream/webaudio_media_stream_source.h"
#include "content/renderer/media/webrtc_local_audio_source_provider.h"
+#include "media/base/sample_format.h"
#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_center_client.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_vector.h"
@@ -99,11 +101,9 @@ void CloneNativeVideoMediaStreamTrack(
} // namespace
-MediaStreamCenter::MediaStreamCenter(
- blink::WebMediaStreamCenterClient* client,
- PeerConnectionDependencyFactory* factory) {}
+MediaStreamCenter::MediaStreamCenter() = default;
-MediaStreamCenter::~MediaStreamCenter() {}
+MediaStreamCenter::~MediaStreamCenter() = default;
void MediaStreamCenter::DidCreateMediaStreamTrack(
const blink::WebMediaStreamTrack& track) {
@@ -191,4 +191,28 @@ void MediaStreamCenter::DidStopMediaStreamSource(
source->StopSource();
}
+void MediaStreamCenter::GetSourceSettings(
+ const blink::WebMediaStreamSource& web_source,
+ blink::WebMediaStreamTrack::Settings& settings) {
+ MediaStreamAudioSource* const source =
+ MediaStreamAudioSource::From(web_source);
+ if (!source)
+ return;
+
+ media::AudioParameters audio_parameters = source->GetAudioParameters();
+ settings.sample_rate = audio_parameters.sample_rate();
+ // kSampleFormatS16 is the format used for all audio input streams.
+ settings.sample_size =
+ media::SampleFormatToBitsPerChannel(media::kSampleFormatS16);
+ settings.channel_count = audio_parameters.channels();
+ settings.latency = audio_parameters.GetBufferDuration().InSecondsF();
+
+ ProcessedLocalAudioSource* const processed_source =
+ ProcessedLocalAudioSource::From(source);
+ settings.volume = processed_source
+ ? static_cast<double>(processed_source->Volume()) /
+ processed_source->MaxVolume()
+ : 1.0;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/stream/media_stream_center.h b/chromium/content/renderer/media/stream/media_stream_center.h
index c057c16e9f5..a548a8db632 100644
--- a/chromium/content/renderer/media/stream/media_stream_center.h
+++ b/chromium/content/renderer/media/stream/media_stream_center.h
@@ -5,9 +5,6 @@
#ifndef CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CENTER_H_
#define CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CENTER_H_
-#include <map>
-
-#include "base/compiler_specific.h"
#include "base/macros.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/platform/web_media_stream.h"
@@ -16,18 +13,13 @@
namespace blink {
class WebAudioSourceProvider;
-class WebMediaStreamCenterClient;
}
namespace content {
-class PeerConnectionDependencyFactory;
class CONTENT_EXPORT MediaStreamCenter : public blink::WebMediaStreamCenter {
public:
- // TODO(miu): Remove these constructor args. They are no longer used.
- // http://crbug.com/577874
- MediaStreamCenter(blink::WebMediaStreamCenterClient* client,
- PeerConnectionDependencyFactory* factory);
+ MediaStreamCenter();
~MediaStreamCenter() override;
private:
@@ -52,6 +44,10 @@ class CONTENT_EXPORT MediaStreamCenter : public blink::WebMediaStreamCenter {
void DidStopMediaStreamSource(
const blink::WebMediaStreamSource& web_source) override;
+ void GetSourceSettings(
+ const blink::WebMediaStreamSource& web_source,
+ blink::WebMediaStreamTrack::Settings& settings) override;
+
DISALLOW_COPY_AND_ASSIGN(MediaStreamCenter);
};
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util.cc
index 52a4824eae8..d4111ac35b1 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util.cc
@@ -235,16 +235,6 @@ bool GetConstraintValueAsString(
return false;
}
-rtc::Optional<bool> ConstraintToOptional(
- const blink::WebMediaConstraints& constraints,
- const blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*picker) {
- bool value;
- if (GetConstraintValueAsBoolean(constraints, picker, &value)) {
- return rtc::Optional<bool>(value);
- }
- return rtc::Optional<bool>();
-}
-
std::string GetMediaStreamSource(
const blink::WebMediaConstraints& constraints) {
std::string source;
@@ -266,12 +256,13 @@ bool IsDeviceCapture(const blink::WebMediaConstraints& constraints) {
VideoTrackAdapterSettings SelectVideoTrackAdapterSettings(
const blink::WebMediaTrackConstraintSet& basic_constraint_set,
- const ResolutionSet& resolution_set,
- const NumericRangeSet<double>& frame_rate_set,
+ const media_constraints::ResolutionSet& resolution_set,
+ const media_constraints::NumericRangeSet<double>& frame_rate_set,
const media::VideoCaptureFormat& source_format) {
- ResolutionSet::Point resolution = resolution_set.SelectClosestPointToIdeal(
- basic_constraint_set, source_format.frame_size.height(),
- source_format.frame_size.width());
+ media_constraints::ResolutionSet::Point resolution =
+ resolution_set.SelectClosestPointToIdeal(
+ basic_constraint_set, source_format.frame_size.height(),
+ source_format.frame_size.width());
int track_max_height = static_cast<int>(std::round(resolution.height()));
int track_max_width = static_cast<int>(std::round(resolution.width()));
double track_min_aspect_ratio =
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util.h b/chromium/content/renderer/media/stream/media_stream_constraints_util.h
index 0e40d0790ab..fd2267d2086 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util.h
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util.h
@@ -16,13 +16,14 @@
#include "third_party/blink/public/platform/modules/mediastream/media_devices.mojom.h"
#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/webrtc/api/optional.h"
namespace content {
+namespace media_constraints {
class ResolutionSet;
template <typename T>
class NumericRangeSet;
+} // namespace media_constraints
// This class represents the output the SelectSettings algorithm for video
// constraints (see https://w3c.github.io/mediacapture-main/#dfn-selectsettings)
@@ -287,10 +288,6 @@ bool CONTENT_EXPORT GetConstraintValueAsString(
const blink::StringConstraint blink::WebMediaTrackConstraintSet::*picker,
std::string* value);
-rtc::Optional<bool> ConstraintToOptional(
- const blink::WebMediaConstraints& constraints,
- const blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*picker);
-
template <typename ConstraintType>
bool ConstraintHasMax(const ConstraintType& constraint) {
return constraint.HasMax() || constraint.HasExact();
@@ -355,8 +352,8 @@ bool IsDeviceCapture(const blink::WebMediaConstraints& constraints);
// |frame_rate_set| are empty.
VideoTrackAdapterSettings CONTENT_EXPORT SelectVideoTrackAdapterSettings(
const blink::WebMediaTrackConstraintSet& basic_constraint_set,
- const ResolutionSet& resolution_set,
- const NumericRangeSet<double>& frame_rate_set,
+ const media_constraints::ResolutionSet& resolution_set,
+ const media_constraints::NumericRangeSet<double>& frame_rate_set,
const media::VideoCaptureFormat& source_format);
// Generic distance function between two values for numeric constraints. Based
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.cc
index 2b48e570ee7..faf854cacbb 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.cc
@@ -11,6 +11,7 @@
#include "base/strings/string_number_conversions.h"
#include "content/common/media/media_stream_controls.h"
+#include "content/public/common/content_features.h"
#include "content/renderer/media/stream/media_stream_audio_source.h"
#include "content/renderer/media/stream/media_stream_constraints_util_sets.h"
#include "content/renderer/media/stream/media_stream_video_source.h"
@@ -22,8 +23,13 @@
namespace content {
+using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
+
namespace {
+template <class T>
+using DiscreteSet = media_constraints::DiscreteSet<T>;
+
enum BoolConstraint {
// Constraints not related to audio processing.
HOTWORD_ENABLED,
@@ -41,7 +47,6 @@ enum BoolConstraint {
GOOG_TYPING_NOISE_DETECTION,
GOOG_NOISE_SUPPRESSION,
GOOG_EXPERIMENTAL_NOISE_SUPPRESSION,
- GOOG_BEAMFORMING,
GOOG_HIGHPASS_FILTER,
GOOG_EXPERIMENTAL_AUTO_GAIN_CONTROL,
NUM_BOOL_CONSTRAINTS
@@ -67,37 +72,10 @@ const AudioPropertyConstraintPair kAudioPropertyConstraintMap[] = {
GOOG_NOISE_SUPPRESSION},
{&AudioProcessingProperties::goog_experimental_noise_suppression,
GOOG_EXPERIMENTAL_NOISE_SUPPRESSION},
- {&AudioProcessingProperties::goog_beamforming, GOOG_BEAMFORMING},
{&AudioProcessingProperties::goog_highpass_filter, GOOG_HIGHPASS_FILTER},
{&AudioProcessingProperties::goog_experimental_auto_gain_control,
GOOG_EXPERIMENTAL_AUTO_GAIN_CONTROL}};
-// TODO(guidou): Remove this function. http://crbug.com/796955
-std::string MediaPointToString(const media::Point& point) {
- std::string point_string;
- point_string.append(base::NumberToString(point.x()));
- point_string.append(" ");
- point_string.append(base::NumberToString(point.y()));
- point_string.append(" ");
- point_string.append(base::NumberToString(point.z()));
-
- return point_string;
-}
-
-// TODO(guidou): Remove this function. http://crbug.com/796955
-std::string MediaPointsToString(const std::vector<media::Point>& points) {
- std::string points_string;
- if (!points.empty()) {
- for (size_t i = 0; i < points.size() - 1; ++i) {
- points_string.append(MediaPointToString(points[i]));
- points_string.append(" ");
- }
- points_string.append(MediaPointToString(points.back()));
- }
-
- return points_string;
-}
-
// Selects the best value from the nonempty |set|, subject to |constraint|. The
// first selection criteria is equality to |constraint.Ideal()|, followed by
// equality to |default_value|. There is always a single best value.
@@ -153,27 +131,6 @@ std::string SelectString(const DiscreteSet<std::string>& set,
return set.FirstElement();
}
-// Selects the best value from the nonempty |set|, subject to |constraint|. The
-// only decision criteria is inclusion in |constraint.Ideal()|. If there is no
-// single best value in |set|, returns nullopt.
-base::Optional<std::string> SelectOptionalString(
- const DiscreteSet<std::string>& set,
- const blink::StringConstraint& constraint) {
- DCHECK(!set.IsEmpty());
- if (constraint.HasIdeal()) {
- for (const auto& ideal_candidate : constraint.Ideal()) {
- std::string candidate = ideal_candidate.Utf8();
- if (set.Contains(candidate))
- return candidate;
- }
- }
-
- if (set.is_universal())
- return base::Optional<std::string>();
-
- return set.FirstElement();
-}
-
bool SelectUseEchoCancellation(base::Optional<bool> echo_cancellation,
base::Optional<bool> goog_echo_cancellation,
bool is_device_capture) {
@@ -195,12 +152,16 @@ std::vector<std::string> GetEchoCancellationTypesFromParameters(
if (audio_parameters.effects() &
(media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER |
media::AudioParameters::ECHO_CANCELLER)) {
- // If the hardware supports echo cancellation, return both echo cancellers.
+ // If the system/hardware supports echo cancellation, return all echo
+ // cancellers.
return {blink::kEchoCancellationTypeBrowser,
+ blink::kEchoCancellationTypeAec3,
blink::kEchoCancellationTypeSystem};
}
- // The browser echo canceller is always available.
- return {blink::kEchoCancellationTypeBrowser};
+
+ // The browser and AEC3 echo cancellers are always available.
+ return {blink::kEchoCancellationTypeBrowser,
+ blink::kEchoCancellationTypeAec3};
}
// This class represents all the candidates settings for a single audio device.
@@ -215,6 +176,9 @@ class SingleDeviceCandidateSet {
if (!capability.DeviceID().empty())
device_id_set_ = DiscreteSet<std::string>({capability.DeviceID()});
+ if (!capability.GroupID().empty())
+ group_id_set_ = DiscreteSet<std::string>({capability.GroupID()});
+
MediaStreamAudioSource* source = capability.source();
// Set up echo cancellation types. Depending on if we have a source or not
@@ -235,38 +199,46 @@ class SingleDeviceCandidateSet {
// Properties related with audio processing.
AudioProcessingProperties properties;
- if (ProcessedLocalAudioSource* processed_source =
- ProcessedLocalAudioSource::From(source)) {
+ ProcessedLocalAudioSource* processed_source =
+ ProcessedLocalAudioSource::From(source);
+ if (processed_source)
properties = processed_source->audio_processing_properties();
- } else {
+ else
properties.DisableDefaultProperties();
- }
-
- const bool experimental_hardware_cancellation_available =
- properties.enable_experimental_hw_echo_cancellation &&
- (parameters_.effects() &
- media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER);
- const bool hardware_echo_cancellation_available =
+ const bool system_echo_cancellation_available =
+ (properties.echo_cancellation_type ==
+ EchoCancellationType::kEchoCancellationSystem ||
+ !processed_source) &&
parameters_.effects() & media::AudioParameters::ECHO_CANCELLER;
- const bool hardware_echo_cancellation_enabled =
- !properties.disable_hw_echo_cancellation &&
- (hardware_echo_cancellation_available ||
- experimental_hardware_cancellation_available);
+ const bool experimental_system_cancellation_available =
+ properties.echo_cancellation_type ==
+ EchoCancellationType::kEchoCancellationSystem &&
+ parameters_.effects() &
+ media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER;
+
+ const bool system_echo_cancellation_enabled =
+ system_echo_cancellation_available ||
+ experimental_system_cancellation_available;
const bool echo_cancellation_enabled =
- properties.enable_sw_echo_cancellation ||
- hardware_echo_cancellation_enabled;
+ properties.EchoCancellationIsWebRtcProvided() ||
+ system_echo_cancellation_enabled;
bool_sets_[ECHO_CANCELLATION] =
DiscreteSet<bool>({echo_cancellation_enabled});
bool_sets_[GOOG_ECHO_CANCELLATION] = bool_sets_[ECHO_CANCELLATION];
- if (properties.enable_sw_echo_cancellation) {
+ if (properties.echo_cancellation_type ==
+ EchoCancellationType::kEchoCancellationAec2) {
echo_cancellation_type_set_ =
DiscreteSet<std::string>({blink::kEchoCancellationTypeBrowser});
- } else if (hardware_echo_cancellation_enabled) {
+ } else if (properties.echo_cancellation_type ==
+ EchoCancellationType::kEchoCancellationAec3) {
+ echo_cancellation_type_set_ =
+ DiscreteSet<std::string>({blink::kEchoCancellationTypeAec3});
+ } else if (system_echo_cancellation_enabled) {
echo_cancellation_type_set_ =
DiscreteSet<std::string>({blink::kEchoCancellationTypeSystem});
}
@@ -285,15 +257,6 @@ class SingleDeviceCandidateSet {
DCHECK(!bool_set.IsEmpty());
}
#endif
-
- // This fails with input strings that are equivalent to
- // |properties.goog_array_geometry|, but not exactly equal to the string
- // returned by MediaPointsToString().
- // TODO(guidou): Change |goog_array_geometry_set_| to be a set of vectors of
- // points instead of a set of strings. http://crbug.com/796955
- std::string mic_positions =
- MediaPointsToString(properties.goog_array_geometry);
- goog_array_geometry_set_ = DiscreteSet<std::string>({mic_positions});
}
// Accessors
@@ -307,22 +270,23 @@ class SingleDeviceCandidateSet {
void ApplyConstraintSet(
const blink::WebMediaTrackConstraintSet& constraint_set) {
device_id_set_ = device_id_set_.Intersection(
- StringSetFromConstraint(constraint_set.device_id));
+ media_constraints::StringSetFromConstraint(constraint_set.device_id));
if (device_id_set_.IsEmpty()) {
failed_constraint_name_ = constraint_set.device_id.GetName();
return;
}
- goog_array_geometry_set_ = goog_array_geometry_set_.Intersection(
- StringSetFromConstraint(constraint_set.goog_array_geometry));
- if (goog_array_geometry_set_.IsEmpty()) {
- failed_constraint_name_ = constraint_set.goog_array_geometry.GetName();
+ group_id_set_ = group_id_set_.Intersection(
+ media_constraints::StringSetFromConstraint(constraint_set.group_id));
+ if (group_id_set_.IsEmpty()) {
+ failed_constraint_name_ = constraint_set.group_id.GetName();
return;
}
for (size_t i = 0; i < NUM_BOOL_CONSTRAINTS; ++i) {
- bool_sets_[i] = bool_sets_[i].Intersection(
- BoolSetFromConstraint(constraint_set.*kBlinkBoolConstraintFields[i]));
+ bool_sets_[i] =
+ bool_sets_[i].Intersection(media_constraints::BoolSetFromConstraint(
+ constraint_set.*kBlinkBoolConstraintFields[i]));
if (bool_sets_[i].IsEmpty()) {
failed_constraint_name_ =
(constraint_set.*kBlinkBoolConstraintFields[i]).GetName();
@@ -342,7 +306,8 @@ class SingleDeviceCandidateSet {
}
echo_cancellation_type_set_ = echo_cancellation_type_set_.Intersection(
- StringSetFromConstraint(constraint_set.echo_cancellation_type));
+ media_constraints::StringSetFromConstraint(
+ constraint_set.echo_cancellation_type));
if (echo_cancellation_type_set_.IsEmpty()) {
failed_constraint_name_ = constraint_set.echo_cancellation_type.GetName();
return;
@@ -373,6 +338,16 @@ class SingleDeviceCandidateSet {
}
}
+ if (constraint_set.group_id.HasIdeal()) {
+ for (const blink::WebString& ideal_value :
+ constraint_set.group_id.Ideal()) {
+ if (group_id_set_.Contains(ideal_value.Utf8())) {
+ fitness += 1.0;
+ break;
+ }
+ }
+ }
+
for (size_t i = 0; i < NUM_BOOL_CONSTRAINTS; ++i) {
if ((constraint_set.*kBlinkBoolConstraintFields[i]).HasIdeal() &&
bool_sets_[i].Contains(
@@ -381,16 +356,6 @@ class SingleDeviceCandidateSet {
}
}
- if (constraint_set.goog_array_geometry.HasIdeal()) {
- for (const blink::WebString& ideal_value :
- constraint_set.goog_array_geometry.Ideal()) {
- if (goog_array_geometry_set_.Contains(ideal_value.Utf8())) {
- fitness += 1.0;
- break;
- }
- }
- }
-
// If echo cancellation constraint is not set to true, the type shall be
// ignored.
if ((constraint_set.*kBlinkBoolConstraintFields[ECHO_CANCELLATION])
@@ -441,10 +406,9 @@ class SingleDeviceCandidateSet {
}
private:
- void SelectEchoCancellationFlags(
+ EchoCancellationType SelectEchoCancellationType(
const blink::StringConstraint& echo_cancellation_type,
- const media::AudioParameters& audio_parameters,
- AudioProcessingProperties* properties_out) const {
+ const media::AudioParameters& audio_parameters) const {
// Try to use an ideal candidate, if supplied.
base::Optional<std::string> selected_type;
if (echo_cancellation_type.HasIdeal()) {
@@ -466,26 +430,38 @@ class SingleDeviceCandidateSet {
}
}
- // Set properties based the type selected.
+ // Return type based the selected type.
if (selected_type == blink::kEchoCancellationTypeBrowser) {
- properties_out->enable_sw_echo_cancellation = true;
- properties_out->disable_hw_echo_cancellation = true;
- properties_out->enable_experimental_hw_echo_cancellation = false;
+ return EchoCancellationType::kEchoCancellationAec2;
+ } else if (selected_type == blink::kEchoCancellationTypeAec3) {
+ return EchoCancellationType::kEchoCancellationAec3;
} else if (selected_type == blink::kEchoCancellationTypeSystem) {
- properties_out->enable_sw_echo_cancellation = false;
- properties_out->disable_hw_echo_cancellation = false;
- properties_out->enable_experimental_hw_echo_cancellation = true;
- } else {
- // If no type has been selected, choose 'system' if the device has the
- // ECHO_CANCELLER flag set. Choose 'browser' otherwise. Never
- // automatically enable an experimental hardware echo canceller.
- const bool has_hw_echo_canceller =
- audio_parameters.IsValid() &&
- (audio_parameters.effects() & media::AudioParameters::ECHO_CANCELLER);
- properties_out->enable_sw_echo_cancellation = !has_hw_echo_canceller;
- properties_out->disable_hw_echo_cancellation = !has_hw_echo_canceller;
- properties_out->enable_experimental_hw_echo_cancellation = false;
+ return EchoCancellationType::kEchoCancellationSystem;
+ }
+
+ // If no type has been selected, choose system if the device has the
+ // ECHO_CANCELLER flag set. Never automatically enable an experimental
+ // system echo canceller.
+ if (audio_parameters.IsValid() &&
+ audio_parameters.effects() & media::AudioParameters::ECHO_CANCELLER) {
+ return EchoCancellationType::kEchoCancellationSystem;
}
+
+ // Finally, choose the browser provided AEC2 or AEC3 based on an optional
+ // override setting for AEC3 or feature.
+ // 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.
+ base::Optional<bool> override_aec3;
+ scoped_refptr<AecDumpMessageFilter> aec_dump_message_filter =
+ AecDumpMessageFilter::Get();
+ if (aec_dump_message_filter)
+ override_aec3 = aec_dump_message_filter->GetOverrideAec3();
+ const bool use_aec3 = override_aec3.value_or(
+ base::FeatureList::IsEnabled(features::kWebRtcUseEchoCanceller3));
+
+ return use_aec3 ? EchoCancellationType::kEchoCancellationAec3
+ : EchoCancellationType::kEchoCancellationAec2;
}
// Returns the audio-processing properties supported by this
@@ -513,17 +489,17 @@ class SingleDeviceCandidateSet {
AudioProcessingProperties properties;
if (use_echo_cancellation) {
- SelectEchoCancellationFlags(basic_constraint_set.echo_cancellation_type,
- parameters_, &properties);
+ properties.echo_cancellation_type = SelectEchoCancellationType(
+ basic_constraint_set.echo_cancellation_type, parameters_);
} else {
- properties.enable_sw_echo_cancellation = false;
- properties.disable_hw_echo_cancellation = true;
- properties.enable_experimental_hw_echo_cancellation = false;
+ properties.echo_cancellation_type =
+ EchoCancellationType::kEchoCancellationDisabled;
}
properties.disable_hw_noise_suppression =
should_disable_hardware_noise_suppression &&
- !properties.disable_hw_echo_cancellation;
+ properties.echo_cancellation_type ==
+ EchoCancellationType::kEchoCancellationSystem;
properties.goog_audio_mirroring =
SelectBool(bool_sets_[GOOG_AUDIO_MIRRORING],
@@ -538,18 +514,6 @@ class SingleDeviceCandidateSet {
default_audio_processing_value && properties.*entry.audio_property);
}
- base::Optional<std::string> array_geometry = SelectOptionalString(
- goog_array_geometry_set_, basic_constraint_set.goog_array_geometry);
- std::vector<media::Point> parsed_positions;
- if (array_geometry)
- parsed_positions = media::ParsePointsFromString(*array_geometry);
- bool are_valid_parsed_positions =
- !parsed_positions.empty() ||
- (array_geometry && array_geometry->empty());
- properties.goog_array_geometry = are_valid_parsed_positions
- ? std::move(parsed_positions)
- : parameters_.mic_positions();
-
return properties;
}
@@ -569,15 +533,14 @@ class SingleDeviceCandidateSet {
&blink::WebMediaTrackConstraintSet::goog_noise_suppression,
&blink::WebMediaTrackConstraintSet::
goog_experimental_noise_suppression,
- &blink::WebMediaTrackConstraintSet::goog_beamforming,
&blink::WebMediaTrackConstraintSet::goog_highpass_filter,
&blink::WebMediaTrackConstraintSet::
goog_experimental_auto_gain_control};
const char* failed_constraint_name_ = nullptr;
DiscreteSet<std::string> device_id_set_;
+ DiscreteSet<std::string> group_id_set_;
std::array<DiscreteSet<bool>, NUM_BOOL_CONSTRAINTS> bool_sets_;
- DiscreteSet<std::string> goog_array_geometry_set_;
DiscreteSet<std::string> echo_cancellation_type_set_;
media::AudioParameters parameters_;
};
@@ -587,16 +550,15 @@ constexpr blink::BooleanConstraint blink::WebMediaTrackConstraintSet::* const
// This class represents a set of possible candidate settings.
// The SelectSettings algorithm starts with a set containing all possible
-// candidates based on hardware capabilities and/or allowed values for supported
-// properties. The set is then reduced progressively as the basic and advanced
-// constraint sets are applied.
-// In the end, if the set of candidates is empty, SelectSettings fails.
-// If not, the ideal values (if any) or tie breaker rules are used to select
-// the final settings based on the candidates that survived the application
-// of the constraint sets.
-// This class is implemented as a collection of more specific sets for the
-// various supported properties. If any of the specific sets is empty, the
-// whole AudioCaptureCandidates set is considered empty as well.
+// candidates based on system/hardware capabilities and/or allowed values for
+// supported properties. The set is then reduced progressively as the basic and
+// advanced constraint sets are applied. In the end, if the set of candidates is
+// empty, SelectSettings fails. If not, the ideal values (if any) or tie breaker
+// rules are used to select the final settings based on the candidates that
+// survived the application of the constraint sets. This class is implemented as
+// a collection of more specific sets for the various supported properties. If
+// any of the specific sets is empty, the whole AudioCaptureCandidates set is
+// considered empty as well.
class AudioCaptureCandidates {
public:
AudioCaptureCandidates(
@@ -689,15 +651,26 @@ AudioDeviceCaptureCapability::AudioDeviceCaptureCapability(
AudioDeviceCaptureCapability::AudioDeviceCaptureCapability(
std::string device_id,
+ std::string group_id,
const media::AudioParameters& parameters)
- : device_id_(std::move(device_id)), parameters_(parameters) {
+ : device_id_(std::move(device_id)),
+ group_id_(std::move(group_id)),
+ parameters_(parameters) {
DCHECK(!device_id_.empty());
}
+AudioDeviceCaptureCapability::AudioDeviceCaptureCapability(
+ const AudioDeviceCaptureCapability& other) = default;
+
const std::string& AudioDeviceCaptureCapability::DeviceID() const {
return source_ ? source_->device().id : device_id_;
}
+const std::string& AudioDeviceCaptureCapability::GroupID() const {
+ return source_ && source_->device().group_id ? *source_->device().group_id
+ : group_id_;
+}
+
const media::AudioParameters& AudioDeviceCaptureCapability::Parameters() const {
return source_ ? source_->device().input : parameters_;
}
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.h b/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.h
index 6eb84383ff8..c1006f6c6d9 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.h
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_audio.h
@@ -41,10 +41,12 @@ class CONTENT_EXPORT AudioDeviceCaptureCapability {
AudioDeviceCaptureCapability();
// This creates an AudioDeviceCaptureCapability where the device ID is limited
- // to |device_id| and other settings are limited by the given |parameters|.
- // |device_id| must not be empty. Intended to be used by getUserMedia() with
- // device capture for devices that are not currently in use.
+ // to |device_id|, the group ID is limited to |group_id| and other settings
+ // are limited by the given |parameters|. |device_id| must not be empty.
+ // Intended to be used by getUserMedia() with device capture for devices that
+ // are not currently in use.
AudioDeviceCaptureCapability(std::string device_id,
+ std::string group_id,
const media::AudioParameters& parameters);
// This creates an AudioDeviceCaptureCapability where the device ID and other
@@ -53,6 +55,8 @@ class CONTENT_EXPORT AudioDeviceCaptureCapability {
// getUserMedia() with device capture for devices that are currently in use.
explicit AudioDeviceCaptureCapability(MediaStreamAudioSource* source);
+ AudioDeviceCaptureCapability(const AudioDeviceCaptureCapability& other);
+
// If this capability represents a device currently in use, this method
// returns a pointer to the MediaStreamAudioSource object associated with the
// device. Otherwise, it returns null.
@@ -64,6 +68,9 @@ class CONTENT_EXPORT AudioDeviceCaptureCapability {
// processing constraints.
const std::string& DeviceID() const;
+ // Returns the group ID of the device associated with this capability.
+ const std::string& GroupID() const;
+
// Returns the audio parameters for the device associated with this
// capability. If DeviceID() returns an empty string, these parameters contain
// default values that work well for content capture.
@@ -72,6 +79,7 @@ class CONTENT_EXPORT AudioDeviceCaptureCapability {
private:
MediaStreamAudioSource* source_ = nullptr;
std::string device_id_;
+ std::string group_id_;
media::AudioParameters parameters_;
};
@@ -81,17 +89,17 @@ using AudioDeviceCaptureCapabilities =
// This function implements the SelectSettings algorithm for audio tracks as
// described in https://w3c.github.io/mediacapture-main/#dfn-selectsettings
// The algorithm starts with a set containing all possible candidate settings
-// based on hardware capabilities (passed via the |capabilities| parameter) and
-// supported values for properties not involved in device selection. Candidates
-// that do not support the basic constraint set from |constraints| are removed.
-// If the set of candidates is empty after this step, the function returns an
-// AudioCaptureSettings object without value and whose failed_constraint_name()
-// method returns the name of one of the (possibly many) constraints that could
-// not be satisfied or an empty string if the set of candidates was initially
-// empty (e.g., if there are no devices in the system).
-// After the basic constraint set is applied, advanced constraint sets are
-// applied. If no candidates can satisfy an advanced set, the advanced set is
-// ignored, otherwise the candidates that cannot satisfy the advanced set are
+// based on system/hardware capabilities (passed via the |capabilities|
+// parameter) and supported values for properties not involved in device
+// selection. Candidates that do not support the basic constraint set from
+// |constraints| are removed. If the set of candidates is empty after this step,
+// the function returns an AudioCaptureSettings object without value and whose
+// failed_constraint_name() method returns the name of one of the (possibly
+// many) constraints that could not be satisfied or an empty string if the set
+// of candidates was initially empty (e.g., if there are no devices in the
+// system). After the basic constraint set is applied, advanced constraint sets
+// are applied. If no candidates can satisfy an advanced set, the advanced set
+// is ignored, otherwise the candidates that cannot satisfy the advanced set are
// removed.
// Once all constraint sets are applied, the result is selected from the
// remaining candidates by giving preference to candidates closest to the ideal
@@ -112,16 +120,10 @@ using AudioDeviceCaptureCapabilities =
// * Audio processing. The remaining constraints are used to control audio
// processing. This is how audio-processing properties are set for device
// capture(see the content::AudioProcessingProperties struct) :
-// - enable_sw_echo_cancellation: If the selected device has hardware echo
-// cancellation, software echo cancellation is disabled regardless of
-// any constraint values. Otherwise, it is enabled by default unless
-// either the echo_cancellation or the goog_echo_cancellation constraint
-// has a final value of false after applying all constraint sets. Note
-// that if these constraints have contradictory values, SelectSettings
-// fails and returns no value.
-// - disable_hw_echo_cancellation: For devices that have hardware echo
-// cancellation, the feature is disabled if the echo_cancellation or
-// goog_echo_cancellation constraints have a final value of false.
+// - echo_cancellation_type: mapped from the experimental constraint with
+// the same name. "System" is selected only if the device supports it.
+// If constraint is not specified, "system" is selected if supported,
+// with exception for experimental system echo cancellation.
// - goog_audio_mirroring: This property is mapped directly from the final
// value of the goog_audio_mirroring constraint. If no value is
// explicitly specified, the default value is false.
@@ -140,7 +142,7 @@ using AudioDeviceCaptureCapabilities =
// all constraints and properties. For example, the echo_cancellation and
// goog_echo_cancellation constraints are not directly mapped to any
// property, but they, together with hardware characteristics, influence the
-// enabling and disabling of software and hardware echo cancellation.
+// selection of echo cancellation type.
// Moreover, the echo_cancellation constraint influences most other
// audio-processing properties for which no explicit value is provided in
// their corresponding constraints.
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
index 00bb3314bd7..2977c75f436 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_audio_unittest.cc
@@ -25,6 +25,8 @@
namespace content {
+using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
+
namespace {
using BoolSetFunction = void (blink::BooleanConstraint::*)(bool);
@@ -59,6 +61,22 @@ static bool Contains(const std::vector<T>& vector, T value) {
} // namespace
+// This class is only used for setting |override_aec3_|. We simply inject the
+// current task runner since they are not used.
+class AecDumpMessageFilterForTest : public AecDumpMessageFilter {
+ public:
+ AecDumpMessageFilterForTest()
+ : AecDumpMessageFilter(base::MessageLoopCurrent::Get()->task_runner(),
+ base::MessageLoopCurrent::Get()->task_runner()) {}
+
+ void set_override_aec3(base::Optional<bool> override_aec3) {
+ override_aec3_ = override_aec3;
+ }
+
+ protected:
+ ~AecDumpMessageFilterForTest() override {}
+};
+
class MediaStreamConstraintsUtilAudioTest
: public testing::TestWithParam<std::string> {
public:
@@ -66,31 +84,23 @@ class MediaStreamConstraintsUtilAudioTest
ResetFactory();
if (IsDeviceCapture()) {
capabilities_.emplace_back(
- "default_device",
+ "default_device", "fake_group1",
media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
media::CHANNEL_LAYOUT_STEREO,
media::AudioParameters::kAudioCDSampleRate,
1000));
- media::AudioParameters hw_echo_canceller_parameters(
+ media::AudioParameters system_echo_canceller_parameters(
media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
media::CHANNEL_LAYOUT_STEREO,
media::AudioParameters::kAudioCDSampleRate, 1000);
- hw_echo_canceller_parameters.set_effects(
+ system_echo_canceller_parameters.set_effects(
media::AudioParameters::ECHO_CANCELLER);
- capabilities_.emplace_back("hw_echo_canceller_device",
- hw_echo_canceller_parameters);
-
- media::AudioParameters geometry_parameters(
- media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
- media::CHANNEL_LAYOUT_STEREO,
- media::AudioParameters::kAudioCDSampleRate, 1000);
- geometry_parameters.set_mic_positions(kMicPositions);
- capabilities_.emplace_back("geometry device", geometry_parameters);
+ capabilities_.emplace_back("system_echo_canceller_device", "fake_group2",
+ system_echo_canceller_parameters);
default_device_ = &capabilities_[0];
- hw_echo_canceller_device_ = &capabilities_[1];
- geometry_device_ = &capabilities_[2];
+ system_echo_canceller_device_ = &capabilities_[1];
} else {
// For content capture, use a single capability that admits all possible
// settings.
@@ -99,15 +109,16 @@ class MediaStreamConstraintsUtilAudioTest
}
protected:
- void MakeHardwareEchoCancellerDeviceExperimental() {
- media::AudioParameters experimental_hw_echo_canceller_parameters(
+ void MakeSystemEchoCancellerDeviceExperimental() {
+ media::AudioParameters experimental_system_echo_canceller_parameters(
media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
media::CHANNEL_LAYOUT_STEREO,
media::AudioParameters::kAudioCDSampleRate, 1000);
- experimental_hw_echo_canceller_parameters.set_effects(
+ experimental_system_echo_canceller_parameters.set_effects(
media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER);
- capabilities_[1] = {"experimental_hw_echo_canceller_device",
- experimental_hw_echo_canceller_parameters};
+ capabilities_[1] = {"experimental_system_echo_canceller_device",
+ "fake_group3",
+ experimental_system_echo_canceller_parameters};
}
void SetMediaStreamSource(const std::string& source) {}
@@ -160,13 +171,13 @@ class MediaStreamConstraintsUtilAudioTest
}
std::unique_ptr<LocalMediaStreamAudioSource> GetLocalMediaStreamAudioSource(
- bool enable_hardware_echo_canceller,
+ bool enable_system_echo_canceller,
bool hotword_enabled,
bool disable_local_echo,
bool render_to_associated_sink) {
MediaStreamDevice device;
device.type = GetMediaStreamType();
- if (enable_hardware_echo_canceller)
+ if (enable_system_echo_canceller)
device.input.set_effects(media::AudioParameters::ECHO_CANCELLER);
if (render_to_associated_sink)
device.matched_output_device_id = std::string("some_device_id");
@@ -214,19 +225,6 @@ class MediaStreamConstraintsUtilAudioTest
const auto& properties = result.audio_processing_properties();
if (!Contains(exclude_audio_properties,
- &AudioProcessingProperties::enable_sw_echo_cancellation)) {
- EXPECT_TRUE(properties.enable_sw_echo_cancellation);
- }
- if (!Contains(exclude_audio_properties,
- &AudioProcessingProperties::disable_hw_echo_cancellation)) {
- EXPECT_TRUE(properties.disable_hw_echo_cancellation);
- }
- if (!Contains(exclude_audio_properties,
- &AudioProcessingProperties::
- enable_experimental_hw_echo_cancellation)) {
- EXPECT_FALSE(properties.enable_experimental_hw_echo_cancellation);
- }
- if (!Contains(exclude_audio_properties,
&AudioProcessingProperties::goog_audio_mirroring)) {
EXPECT_FALSE(properties.goog_audio_mirroring);
}
@@ -253,10 +251,6 @@ class MediaStreamConstraintsUtilAudioTest
EXPECT_TRUE(properties.goog_experimental_noise_suppression);
}
if (!Contains(exclude_audio_properties,
- &AudioProcessingProperties::goog_beamforming)) {
- EXPECT_TRUE(properties.goog_beamforming);
- }
- if (!Contains(exclude_audio_properties,
&AudioProcessingProperties::goog_highpass_filter)) {
EXPECT_TRUE(properties.goog_highpass_filter);
}
@@ -287,19 +281,6 @@ class MediaStreamConstraintsUtilAudioTest
const auto& properties = result.audio_processing_properties();
if (!Contains(exclude_audio_properties,
- &AudioProcessingProperties::enable_sw_echo_cancellation)) {
- EXPECT_FALSE(properties.enable_sw_echo_cancellation);
- }
- if (!Contains(exclude_audio_properties,
- &AudioProcessingProperties::disable_hw_echo_cancellation)) {
- EXPECT_TRUE(properties.disable_hw_echo_cancellation);
- }
- if (!Contains(exclude_audio_properties,
- &AudioProcessingProperties::
- enable_experimental_hw_echo_cancellation)) {
- EXPECT_FALSE(properties.enable_experimental_hw_echo_cancellation);
- }
- if (!Contains(exclude_audio_properties,
&AudioProcessingProperties::goog_audio_mirroring)) {
EXPECT_FALSE(properties.goog_audio_mirroring);
}
@@ -326,10 +307,6 @@ class MediaStreamConstraintsUtilAudioTest
EXPECT_FALSE(properties.goog_experimental_noise_suppression);
}
if (!Contains(exclude_audio_properties,
- &AudioProcessingProperties::goog_beamforming)) {
- EXPECT_FALSE(properties.goog_beamforming);
- }
- if (!Contains(exclude_audio_properties,
&AudioProcessingProperties::goog_highpass_filter)) {
EXPECT_FALSE(properties.goog_highpass_filter);
}
@@ -353,6 +330,17 @@ class MediaStreamConstraintsUtilAudioTest
}
}
+ void CheckEchoCancellationTypeDefault(const AudioCaptureSettings& result) {
+ const auto& properties = result.audio_processing_properties();
+ if (IsDeviceCapture()) {
+ EXPECT_EQ(properties.echo_cancellation_type,
+ EchoCancellationType::kEchoCancellationAec2);
+ } else {
+ EXPECT_EQ(properties.echo_cancellation_type,
+ EchoCancellationType::kEchoCancellationDisabled);
+ }
+ }
+
void CheckDevice(const AudioDeviceCaptureCapability& expected_device,
const AudioCaptureSettings& result) {
EXPECT_EQ(expected_device.DeviceID(), result.device_id());
@@ -371,23 +359,18 @@ class MediaStreamConstraintsUtilAudioTest
EXPECT_TRUE(result.device_id().empty());
}
- void CheckGeometryDefaults(const AudioCaptureSettings& result) {
- EXPECT_TRUE(
- result.audio_processing_properties().goog_array_geometry.empty());
- }
-
void CheckAllDefaults(
const AudioSettingsBoolMembers& exclude_main_settings,
const AudioPropertiesBoolMembers& exclude_audio_properties,
const AudioCaptureSettings& result) {
CheckBoolDefaults(exclude_main_settings, exclude_audio_properties, result);
+ CheckEchoCancellationTypeDefault(result);
CheckDeviceDefaults(result);
- CheckGeometryDefaults(result);
}
// Assumes that echoCancellation is set to true as a basic, exact constraint.
void CheckAudioProcessingPropertiesForExactEchoCancellationType(
- bool request_hw_echo_cancellation,
+ const blink::WebString& echo_cancellation_type_constraint,
const AudioCaptureSettings& result) {
const AudioProcessingProperties& properties =
result.audio_processing_properties();
@@ -397,31 +380,28 @@ class MediaStreamConstraintsUtilAudioTest
// With content capture, the echo_cancellation constraint controls
// only the echo_cancellation properties. The other audio processing
// properties default to false.
- const bool enable_sw_audio_processing = IsDeviceCapture();
-
- if (IsDeviceCapture()) {
- EXPECT_NE(request_hw_echo_cancellation,
- properties.enable_sw_echo_cancellation);
- EXPECT_NE(request_hw_echo_cancellation,
- properties.disable_hw_echo_cancellation);
- EXPECT_EQ(request_hw_echo_cancellation,
- properties.enable_experimental_hw_echo_cancellation);
- } else {
- EXPECT_TRUE(properties.enable_sw_echo_cancellation);
- EXPECT_TRUE(properties.disable_hw_echo_cancellation);
- EXPECT_FALSE(properties.enable_experimental_hw_echo_cancellation);
+ const EchoCancellationType expected_ec_type =
+ GetEchoCancellationTypeFromConstraintString(
+ echo_cancellation_type_constraint);
+ if (!IsDeviceCapture()) {
+ ASSERT_NE(EchoCancellationType::kEchoCancellationSystem,
+ expected_ec_type);
}
- EXPECT_EQ(enable_sw_audio_processing, properties.goog_auto_gain_control);
- CheckGoogExperimentalEchoCancellationDefault(properties,
- enable_sw_audio_processing);
- EXPECT_EQ(enable_sw_audio_processing,
+ EXPECT_EQ(expected_ec_type, properties.echo_cancellation_type);
+
+ const bool enable_webrtc_audio_processing = IsDeviceCapture();
+ EXPECT_EQ(enable_webrtc_audio_processing,
+ properties.goog_auto_gain_control);
+ CheckGoogExperimentalEchoCancellationDefault(
+ properties, enable_webrtc_audio_processing);
+ EXPECT_EQ(enable_webrtc_audio_processing,
properties.goog_typing_noise_detection);
- EXPECT_EQ(enable_sw_audio_processing, properties.goog_noise_suppression);
- EXPECT_EQ(enable_sw_audio_processing,
+ EXPECT_EQ(enable_webrtc_audio_processing,
+ properties.goog_noise_suppression);
+ EXPECT_EQ(enable_webrtc_audio_processing,
properties.goog_experimental_noise_suppression);
- EXPECT_EQ(enable_sw_audio_processing, properties.goog_beamforming);
- EXPECT_EQ(enable_sw_audio_processing, properties.goog_highpass_filter);
- EXPECT_EQ(enable_sw_audio_processing,
+ EXPECT_EQ(enable_webrtc_audio_processing, properties.goog_highpass_filter);
+ EXPECT_EQ(enable_webrtc_audio_processing,
properties.goog_experimental_auto_gain_control);
// The following are not audio processing.
@@ -431,9 +411,11 @@ class MediaStreamConstraintsUtilAudioTest
result.disable_local_echo());
EXPECT_FALSE(result.render_to_associated_sink());
if (IsDeviceCapture()) {
- CheckDevice(request_hw_echo_cancellation ? *hw_echo_canceller_device_
- : *default_device_,
- result);
+ CheckDevice(
+ expected_ec_type == EchoCancellationType::kEchoCancellationSystem
+ ? *system_echo_canceller_device_
+ : *default_device_,
+ result);
} else {
EXPECT_TRUE(result.device_id().empty());
}
@@ -444,15 +426,13 @@ class MediaStreamConstraintsUtilAudioTest
const AudioProcessingProperties& properties =
result.audio_processing_properties();
- EXPECT_FALSE(properties.enable_sw_echo_cancellation);
- EXPECT_FALSE(properties.disable_hw_echo_cancellation);
- EXPECT_TRUE(properties.enable_experimental_hw_echo_cancellation);
+ EXPECT_EQ(EchoCancellationType::kEchoCancellationSystem,
+ properties.echo_cancellation_type);
EXPECT_TRUE(properties.goog_auto_gain_control);
CheckGoogExperimentalEchoCancellationDefault(properties, true);
EXPECT_TRUE(properties.goog_typing_noise_detection);
EXPECT_TRUE(properties.goog_noise_suppression);
EXPECT_TRUE(properties.goog_experimental_noise_suppression);
- EXPECT_TRUE(properties.goog_beamforming);
EXPECT_TRUE(properties.goog_highpass_filter);
EXPECT_TRUE(properties.goog_experimental_auto_gain_control);
@@ -462,17 +442,34 @@ class MediaStreamConstraintsUtilAudioTest
EXPECT_EQ(GetMediaStreamSource() != kMediaStreamSourceDesktop,
result.disable_local_echo());
EXPECT_FALSE(result.render_to_associated_sink());
- CheckDevice(*hw_echo_canceller_device_, result);
+ CheckDevice(*system_echo_canceller_device_, result);
+ }
+
+ EchoCancellationType GetEchoCancellationTypeFromConstraintString(
+ const blink::WebString& constraint_string) {
+ if (constraint_string == kEchoCancellationTypeValues[0])
+ return EchoCancellationType::kEchoCancellationAec2;
+ if (constraint_string == kEchoCancellationTypeValues[1])
+ return EchoCancellationType::kEchoCancellationAec3;
+ if (constraint_string == kEchoCancellationTypeValues[2])
+ return EchoCancellationType::kEchoCancellationSystem;
+
+ ADD_FAILURE() << "Invalid echo cancellation type constraint: "
+ << constraint_string.Ascii();
+ return EchoCancellationType::kEchoCancellationDisabled;
}
MockConstraintFactory constraint_factory_;
AudioDeviceCaptureCapabilities capabilities_;
const AudioDeviceCaptureCapability* default_device_ = nullptr;
- const AudioDeviceCaptureCapability* hw_echo_canceller_device_ = nullptr;
- const AudioDeviceCaptureCapability* geometry_device_ = nullptr;
+ const AudioDeviceCaptureCapability* system_echo_canceller_device_ = nullptr;
const std::vector<media::Point> kMicPositions = {{8, 8, 8}, {4, 4, 4}};
+
+ // TODO(grunell): Store these as separate constants and compare against those
+ // in tests, instead of indexing the vector.
const std::vector<blink::WebString> kEchoCancellationTypeValues = {
blink::WebString::FromASCII("browser"),
+ blink::WebString::FromASCII("aec3"),
blink::WebString::FromASCII("system")};
private:
@@ -541,7 +538,6 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SingleBoolConstraint) {
&AudioProcessingProperties::goog_typing_noise_detection,
&AudioProcessingProperties::goog_noise_suppression,
&AudioProcessingProperties::goog_experimental_noise_suppression,
- &AudioProcessingProperties::goog_beamforming,
&AudioProcessingProperties::goog_highpass_filter,
&AudioProcessingProperties::goog_experimental_auto_gain_control};
@@ -556,7 +552,6 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SingleBoolConstraint) {
&blink::WebMediaTrackConstraintSet::goog_noise_suppression,
&blink::WebMediaTrackConstraintSet::
goog_experimental_noise_suppression,
- &blink::WebMediaTrackConstraintSet::goog_beamforming,
&blink::WebMediaTrackConstraintSet::goog_highpass_filter,
&blink::WebMediaTrackConstraintSet::
goog_experimental_auto_gain_control,
@@ -608,7 +603,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, ExactArbitraryDeviceID) {
EXPECT_EQ(kArbitraryDeviceID, result.device_id());
CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
result);
- CheckGeometryDefaults(result);
+ CheckEchoCancellationTypeDefault(result);
}
}
@@ -628,7 +623,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, IdealArbitraryDeviceID) {
EXPECT_EQ(kArbitraryDeviceID, result.device_id());
CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
result);
- CheckGeometryDefaults(result);
+ CheckEchoCancellationTypeDefault(result);
}
TEST_P(MediaStreamConstraintsUtilAudioTest, ExactValidDeviceID) {
@@ -638,30 +633,52 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, ExactValidDeviceID) {
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
CheckDevice(device, result);
- CheckBoolDefaults(
- AudioSettingsBoolMembers(),
- {&AudioProcessingProperties::enable_sw_echo_cancellation,
- &AudioProcessingProperties::disable_hw_echo_cancellation},
- result);
- bool has_hw_echo_cancellation =
- device.Parameters().effects() & media::AudioParameters::ECHO_CANCELLER;
- EXPECT_EQ(IsDeviceCapture() && !has_hw_echo_cancellation,
- result.audio_processing_properties().enable_sw_echo_cancellation);
- EXPECT_NE(
- IsDeviceCapture() && has_hw_echo_cancellation,
- result.audio_processing_properties().disable_hw_echo_cancellation);
- if (&device == geometry_device_) {
- EXPECT_EQ(kMicPositions,
- result.audio_processing_properties().goog_array_geometry);
- } else {
- CheckGeometryDefaults(result);
+ CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
+ result);
+ EchoCancellationType expected_echo_cancellation_type =
+ EchoCancellationType::kEchoCancellationDisabled;
+ if (IsDeviceCapture()) {
+ const bool has_system_echo_cancellation =
+ device.Parameters().effects() &
+ media::AudioParameters::ECHO_CANCELLER;
+ expected_echo_cancellation_type =
+ has_system_echo_cancellation
+ ? EchoCancellationType::kEchoCancellationSystem
+ : EchoCancellationType::kEchoCancellationAec2;
+ }
+ EXPECT_EQ(expected_echo_cancellation_type,
+ result.audio_processing_properties().echo_cancellation_type);
+ }
+}
+
+TEST_P(MediaStreamConstraintsUtilAudioTest, ExactGroupID) {
+ for (const auto& device : capabilities_) {
+ constraint_factory_.basic().group_id.SetExact(
+ blink::WebString::FromASCII(device.GroupID()));
+ auto result = SelectSettings();
+ EXPECT_TRUE(result.HasValue());
+ CheckDevice(device, result);
+ CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
+ result);
+ EchoCancellationType expected_echo_cancellation_type =
+ EchoCancellationType::kEchoCancellationDisabled;
+ if (IsDeviceCapture()) {
+ const bool has_system_echo_cancellation =
+ device.Parameters().effects() &
+ media::AudioParameters::ECHO_CANCELLER;
+ expected_echo_cancellation_type =
+ has_system_echo_cancellation
+ ? EchoCancellationType::kEchoCancellationSystem
+ : EchoCancellationType::kEchoCancellationAec2;
}
+ EXPECT_EQ(expected_echo_cancellation_type,
+ result.audio_processing_properties().echo_cancellation_type);
}
}
-// Tests the echoCancellation constraint with a device without hardware echo
+// Tests the echoCancellation constraint with a device without system echo
// cancellation.
-TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationWithSw) {
+TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationWithWebRtc) {
for (auto set_function : kBoolSetFunctions) {
for (auto accessor : kFactoryAccessors) {
// Ideal advanced is ignored by the SelectSettings algorithm.
@@ -684,22 +701,26 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationWithSw) {
// With content capture, the echo_cancellation constraint controls
// only the echo_cancellation properties. The other audio processing
// properties default to false.
- bool enable_sw_audio_processing = IsDeviceCapture() ? value : false;
- EXPECT_EQ(value, properties.enable_sw_echo_cancellation);
- EXPECT_TRUE(properties.disable_hw_echo_cancellation);
- EXPECT_EQ(enable_sw_audio_processing,
+ const EchoCancellationType expected_echo_cancellation_type =
+ value ? EchoCancellationType::kEchoCancellationAec2
+ : EchoCancellationType::kEchoCancellationDisabled;
+ EXPECT_EQ(expected_echo_cancellation_type,
+ properties.echo_cancellation_type);
+ const bool enable_webrtc_audio_processing =
+ IsDeviceCapture() ? value : false;
+ EXPECT_EQ(enable_webrtc_audio_processing,
properties.goog_auto_gain_control);
CheckGoogExperimentalEchoCancellationDefault(
- properties, enable_sw_audio_processing);
- EXPECT_EQ(enable_sw_audio_processing,
+ properties, enable_webrtc_audio_processing);
+ EXPECT_EQ(enable_webrtc_audio_processing,
properties.goog_typing_noise_detection);
- EXPECT_EQ(enable_sw_audio_processing,
+ EXPECT_EQ(enable_webrtc_audio_processing,
properties.goog_noise_suppression);
- EXPECT_EQ(enable_sw_audio_processing,
+ EXPECT_EQ(enable_webrtc_audio_processing,
properties.goog_experimental_noise_suppression);
- EXPECT_EQ(enable_sw_audio_processing, properties.goog_beamforming);
- EXPECT_EQ(enable_sw_audio_processing, properties.goog_highpass_filter);
- EXPECT_EQ(enable_sw_audio_processing,
+ EXPECT_EQ(enable_webrtc_audio_processing,
+ properties.goog_highpass_filter);
+ EXPECT_EQ(enable_webrtc_audio_processing,
properties.goog_experimental_auto_gain_control);
// The following are not audio processing.
@@ -718,10 +739,10 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationWithSw) {
}
}
-// Tests the echoCancellation constraint with a device with hardware echo
+// Tests the echoCancellation constraint with a device with system echo
// cancellation.
-TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationWithHw) {
- // With content capture, there is no hardware echo cancellation, so
+TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationWithSystem) {
+ // With content capture, there is no system echo cancellation, so
// nothing to test.
if (!IsDeviceCapture())
return;
@@ -738,25 +759,28 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationWithHw) {
for (bool value : kBoolValues) {
ResetFactory();
constraint_factory_.basic().device_id.SetExact(
- blink::WebString::FromASCII(hw_echo_canceller_device_->DeviceID()));
+ blink::WebString::FromASCII(
+ system_echo_canceller_device_->DeviceID()));
((constraint_factory_.*accessor)().echo_cancellation.*
set_function)(value);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
const AudioProcessingProperties& properties =
result.audio_processing_properties();
- // With hardware echo cancellation, the echo_cancellation constraint
- // enables/disables all audio processing by default, software echo
- // cancellation is always disabled, and hardware echo cancellation is
+ // With system echo cancellation, the echo_cancellation constraint
+ // enables/disables all audio processing by default, WebRTC echo
+ // cancellation is always disabled, and system echo cancellation is
// disabled if the echo_cancellation constraint is false.
- EXPECT_FALSE(properties.enable_sw_echo_cancellation);
- EXPECT_EQ(!value, properties.disable_hw_echo_cancellation);
+ const EchoCancellationType expected_echo_cancellation_type =
+ value ? EchoCancellationType::kEchoCancellationSystem
+ : EchoCancellationType::kEchoCancellationDisabled;
+ EXPECT_EQ(expected_echo_cancellation_type,
+ properties.echo_cancellation_type);
EXPECT_EQ(value, properties.goog_auto_gain_control);
CheckGoogExperimentalEchoCancellationDefault(properties, value);
EXPECT_EQ(value, properties.goog_typing_noise_detection);
EXPECT_EQ(value, properties.goog_noise_suppression);
EXPECT_EQ(value, properties.goog_experimental_noise_suppression);
- EXPECT_EQ(value, properties.goog_beamforming);
EXPECT_EQ(value, properties.goog_highpass_filter);
EXPECT_EQ(value, properties.goog_experimental_auto_gain_control);
@@ -766,15 +790,15 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationWithHw) {
EXPECT_EQ(GetMediaStreamSource() != kMediaStreamSourceDesktop,
result.disable_local_echo());
EXPECT_FALSE(result.render_to_associated_sink());
- CheckDevice(*hw_echo_canceller_device_, result);
+ CheckDevice(*system_echo_canceller_device_, result);
}
}
}
}
-// Tests the googEchoCancellation constraint with a device without hardware echo
+// Tests the googEchoCancellation constraint with a device without system echo
// cancellation.
-TEST_P(MediaStreamConstraintsUtilAudioTest, GoogEchoCancellationWithSw) {
+TEST_P(MediaStreamConstraintsUtilAudioTest, GoogEchoCancellationWithWebRtc) {
for (auto set_function : kBoolSetFunctions) {
for (auto accessor : kFactoryAccessors) {
// Ideal advanced is ignored by the SelectSettings algorithm.
@@ -795,15 +819,13 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, GoogEchoCancellationWithSw) {
// The goog_echo_cancellation constraint controls only the
// echo_cancellation properties. The other audio processing properties
// use the default values.
- EXPECT_EQ(value, properties.enable_sw_echo_cancellation);
- EXPECT_TRUE(properties.disable_hw_echo_cancellation);
- CheckBoolDefaults(
- AudioSettingsBoolMembers(),
- {
- &AudioProcessingProperties::enable_sw_echo_cancellation,
- &AudioProcessingProperties::disable_hw_echo_cancellation,
- },
- result);
+ const EchoCancellationType expected_echo_cancellation_type =
+ value ? EchoCancellationType::kEchoCancellationAec2
+ : EchoCancellationType::kEchoCancellationDisabled;
+ EXPECT_EQ(expected_echo_cancellation_type,
+ properties.echo_cancellation_type);
+ CheckBoolDefaults(AudioSettingsBoolMembers(),
+ AudioPropertiesBoolMembers(), result);
if (IsDeviceCapture()) {
CheckDevice(*default_device_, result);
} else {
@@ -814,10 +836,10 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, GoogEchoCancellationWithSw) {
}
}
-// Tests the googEchoCancellation constraint with a device with hardware echo
+// Tests the googEchoCancellation constraint with a device with system echo
// cancellation.
-TEST_P(MediaStreamConstraintsUtilAudioTest, GoogEchoCancellationWithHw) {
- // With content capture, there is no hardware echo cancellation, so
+TEST_P(MediaStreamConstraintsUtilAudioTest, GoogEchoCancellationWithSystem) {
+ // With content capture, there is no system echo cancellation, so
// nothing to test.
if (!IsDeviceCapture())
return;
@@ -834,44 +856,40 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, GoogEchoCancellationWithHw) {
for (bool value : kBoolValues) {
ResetFactory();
constraint_factory_.basic().device_id.SetExact(
- blink::WebString::FromASCII(hw_echo_canceller_device_->DeviceID()));
+ blink::WebString::FromASCII(
+ system_echo_canceller_device_->DeviceID()));
((constraint_factory_.*accessor)().goog_echo_cancellation.*
set_function)(value);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
const AudioProcessingProperties& properties =
result.audio_processing_properties();
- // With hardware echo cancellation, software echo cancellation is always
- // disabled, and hardware echo cancellation is disabled if
+ // With system echo cancellation, WebRTC echo cancellation is always
+ // disabled, and system echo cancellation is disabled if
// goog_echo_cancellation is false.
- EXPECT_FALSE(properties.enable_sw_echo_cancellation);
- EXPECT_EQ(!value, properties.disable_hw_echo_cancellation);
- CheckBoolDefaults(
- AudioSettingsBoolMembers(),
- {
- &AudioProcessingProperties::enable_sw_echo_cancellation,
- &AudioProcessingProperties::disable_hw_echo_cancellation,
- },
- result);
- CheckDevice(*hw_echo_canceller_device_, result);
+ const EchoCancellationType expected_echo_cancellation_type =
+ value ? EchoCancellationType::kEchoCancellationSystem
+ : EchoCancellationType::kEchoCancellationDisabled;
+ EXPECT_EQ(expected_echo_cancellation_type,
+ properties.echo_cancellation_type);
+ CheckBoolDefaults(AudioSettingsBoolMembers(),
+ AudioPropertiesBoolMembers(), result);
+ CheckDevice(*system_echo_canceller_device_, result);
}
}
}
}
// Tests the echoCancellationType constraint without constraining to a device
-// with hardware echo cancellation. Tested as basic exact constraints.
+// with system echo cancellation. Tested as basic exact constraints.
TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationTypeExact) {
for (blink::WebString value : kEchoCancellationTypeValues) {
- const bool request_hw_echo_cancellation =
- value == kEchoCancellationTypeValues[1];
-
ResetFactory();
constraint_factory_.basic().echo_cancellation.SetExact(true);
constraint_factory_.basic().echo_cancellation_type.SetExact(value);
auto result = SelectSettings();
// If content capture and EC type "system", we expect failure.
- if (!IsDeviceCapture() && request_hw_echo_cancellation) {
+ if (!IsDeviceCapture() && value == kEchoCancellationTypeValues[2]) {
EXPECT_FALSE(result.HasValue());
EXPECT_EQ(result.failed_constraint_name(),
constraint_factory_.basic().echo_cancellation_type.GetName());
@@ -879,22 +897,21 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationTypeExact) {
}
ASSERT_TRUE(result.HasValue());
- CheckAudioProcessingPropertiesForExactEchoCancellationType(
- request_hw_echo_cancellation, result);
+ CheckAudioProcessingPropertiesForExactEchoCancellationType(value, result);
}
}
-// Like the test above, but changes the device with hardware echo cancellation
-// support to only support experimental hardware echo cancellation. It should
+// Like the test above, but changes the device with system echo cancellation
+// support to only support experimental system echo cancellation. It should
// still be picked if requested.
TEST_P(MediaStreamConstraintsUtilAudioTest,
EchoCancellationTypeExact_Experimental) {
if (!IsDeviceCapture())
return;
- // Replace the device with one that only supports experimental hardware echo
+ // Replace the device with one that only supports experimental system echo
// cancellation.
- MakeHardwareEchoCancellerDeviceExperimental();
+ MakeSystemEchoCancellerDeviceExperimental();
for (blink::WebString value : kEchoCancellationTypeValues) {
ResetFactory();
@@ -902,60 +919,57 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
constraint_factory_.basic().echo_cancellation_type.SetExact(value);
auto result = SelectSettings();
ASSERT_TRUE(result.HasValue());
- const bool request_hw_echo_cancellation =
- value == kEchoCancellationTypeValues[1];
- CheckAudioProcessingPropertiesForExactEchoCancellationType(
- request_hw_echo_cancellation, result);
+ CheckAudioProcessingPropertiesForExactEchoCancellationType(value, result);
}
}
// Tests the echoCancellationType constraint without constraining to a device
-// with hardware echo cancellation. Tested as basic ideal constraints.
+// with system echo cancellation. Tested as basic ideal constraints.
TEST_P(MediaStreamConstraintsUtilAudioTest, EchoCancellationTypeIdeal) {
- // With content capture, there is no hardware echo cancellation, so
+ // With content capture, there is no system echo cancellation, so
// nothing to test.
if (!IsDeviceCapture())
return;
constraint_factory_.basic().echo_cancellation.SetExact(true);
constraint_factory_.basic().echo_cancellation_type.SetIdeal(
- kEchoCancellationTypeValues[1]);
+ kEchoCancellationTypeValues[2]);
auto result = SelectSettings();
ASSERT_TRUE(result.HasValue());
CheckAudioProcessingPropertiesForIdealEchoCancellationType(result);
}
-// Like the test above, but only having a device with experimental hardware echo
+// Like the test above, but only having a device with experimental system echo
// cancellation available.
TEST_P(MediaStreamConstraintsUtilAudioTest,
EchoCancellationTypeIdeal_Experimental) {
- // With content capture, there is no hardware echo cancellation, so
+ // With content capture, there is no system echo cancellation, so
// nothing to test.
if (!IsDeviceCapture())
return;
- // Replace the device with one that only supports experimental hardware echo
+ // Replace the device with one that only supports experimental system echo
// cancellation.
- MakeHardwareEchoCancellerDeviceExperimental();
+ MakeSystemEchoCancellerDeviceExperimental();
constraint_factory_.basic().echo_cancellation.SetExact(true);
constraint_factory_.basic().echo_cancellation_type.SetIdeal(
- kEchoCancellationTypeValues[1]);
+ kEchoCancellationTypeValues[2]);
auto result = SelectSettings();
ASSERT_TRUE(result.HasValue());
CheckAudioProcessingPropertiesForIdealEchoCancellationType(result);
}
// Tests the echoCancellationType constraint with constraining to a device with
-// experimental hardware echo cancellation.
+// experimental system echo cancellation.
TEST_P(MediaStreamConstraintsUtilAudioTest,
- EchoCancellationTypeWithExpHwDeviceConstraint) {
+ EchoCancellationTypeWithExpSystemDeviceConstraint) {
// With content capture, there is no system echo cancellation, so
// nothing to test.
if (!IsDeviceCapture())
return;
- MakeHardwareEchoCancellerDeviceExperimental();
+ MakeSystemEchoCancellerDeviceExperimental();
// Include leaving the echoCancellationType constraint unset in the tests.
// It should then behave as before the constraint was introduced.
@@ -976,7 +990,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
ResetFactory();
constraint_factory_.basic().device_id.SetExact(
blink::WebString::FromASCII(
- hw_echo_canceller_device_->DeviceID()));
+ system_echo_canceller_device_->DeviceID()));
constraint_factory_.basic().echo_cancellation.SetExact(ec_value);
if (!ec_type_value.IsNull())
((constraint_factory_.*accessor)().echo_cancellation_type.*
@@ -998,32 +1012,28 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
const AudioProcessingProperties& properties =
result.audio_processing_properties();
- // With experimental hardware echo cancellation (echo canceller type
+ // With experimental system echo cancellation (echo canceller type
// "system"), the echo_cancellation constraint enables/disables all
- // audio processing by default, software echo cancellation is always
- // disabled, and experimental hardware echo cancellation is disabled
+ // audio processing by default, WebRTC echo cancellation is always
+ // disabled, and experimental system echo cancellation is disabled
// if the echo_cancellation constraint is false.
- bool request_hw_echo_cancellation =
- ec_type_value == kEchoCancellationTypeValues[1];
-
if (ec_value) {
- EXPECT_NE(request_hw_echo_cancellation,
- properties.enable_sw_echo_cancellation);
- EXPECT_NE(request_hw_echo_cancellation,
- properties.disable_hw_echo_cancellation);
- EXPECT_EQ(request_hw_echo_cancellation,
- properties.enable_experimental_hw_echo_cancellation);
+ const EchoCancellationType expected_echo_cancellation_type =
+ ec_type_value == blink::WebString()
+ ? EchoCancellationType::kEchoCancellationAec2
+ : GetEchoCancellationTypeFromConstraintString(
+ ec_type_value);
+ EXPECT_EQ(expected_echo_cancellation_type,
+ properties.echo_cancellation_type);
} else {
- EXPECT_FALSE(properties.enable_sw_echo_cancellation);
- EXPECT_TRUE(properties.disable_hw_echo_cancellation);
- EXPECT_FALSE(properties.enable_experimental_hw_echo_cancellation);
+ EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
+ properties.echo_cancellation_type);
}
EXPECT_EQ(ec_value, properties.goog_auto_gain_control);
CheckGoogExperimentalEchoCancellationDefault(properties, ec_value);
EXPECT_EQ(ec_value, properties.goog_typing_noise_detection);
EXPECT_EQ(ec_value, properties.goog_noise_suppression);
EXPECT_EQ(ec_value, properties.goog_experimental_noise_suppression);
- EXPECT_EQ(ec_value, properties.goog_beamforming);
EXPECT_EQ(ec_value, properties.goog_highpass_filter);
EXPECT_EQ(ec_value, properties.goog_experimental_auto_gain_control);
@@ -1033,7 +1043,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
EXPECT_EQ(GetMediaStreamSource() != kMediaStreamSourceDesktop,
result.disable_local_echo());
EXPECT_FALSE(result.render_to_associated_sink());
- CheckDevice(*hw_echo_canceller_device_, result);
+ CheckDevice(*system_echo_canceller_device_, result);
}
}
}
@@ -1041,9 +1051,9 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
}
// Tests the echoCancellationType constraint with constraining to a device
-// without experimental hardware echo cancellation, which should fail.
+// without experimental system echo cancellation, which should fail.
TEST_P(MediaStreamConstraintsUtilAudioTest,
- EchoCancellationTypeWithSwDeviceConstraint) {
+ EchoCancellationTypeWithWebRtcDeviceConstraint) {
if (!IsDeviceCapture())
return;
@@ -1051,7 +1061,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
blink::WebString::FromASCII(default_device_->DeviceID()));
constraint_factory_.basic().echo_cancellation.SetExact(true);
constraint_factory_.basic().echo_cancellation_type.SetExact(
- kEchoCancellationTypeValues[1]);
+ kEchoCancellationTypeValues[2]);
auto result = SelectSettings();
EXPECT_FALSE(result.HasValue());
@@ -1059,6 +1069,57 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
constraint_factory_.basic().device_id.GetName());
}
+// Tests the echoCancellationType constraint when also the AEC3 has been
+// selected via the extension API. That selection ends up in
+// AecDumpMessageFilter and MediaStreamConstraintsUtil checks there if set and
+// to what. It can be unset, true or false. The constraint has precedence over
+// the extension API selection. Tested as basic exact constraints.
+TEST_P(MediaStreamConstraintsUtilAudioTest,
+ EchoCancellationTypeAndAec3Selection) {
+ // First test AEC3 selection when no echo cancellation type constraint has
+ // been set.
+ scoped_refptr<AecDumpMessageFilterForTest> admf =
+ new AecDumpMessageFilterForTest();
+ admf->set_override_aec3(true);
+
+ ResetFactory();
+ constraint_factory_.basic().echo_cancellation.SetExact(true);
+ auto result = SelectSettings();
+ ASSERT_TRUE(result.HasValue());
+
+ CheckAudioProcessingPropertiesForExactEchoCancellationType(
+ kEchoCancellationTypeValues[1], // AEC3
+ result);
+
+ // Set the echo cancellation type constraint to browser and expect that as
+ // result.
+ ResetFactory();
+ constraint_factory_.basic().echo_cancellation.SetExact(true);
+ constraint_factory_.basic().echo_cancellation_type.SetExact(
+ kEchoCancellationTypeValues[0]);
+ result = SelectSettings();
+ ASSERT_TRUE(result.HasValue());
+
+ CheckAudioProcessingPropertiesForExactEchoCancellationType(
+ kEchoCancellationTypeValues[0], // Browser
+ result);
+
+ // Set the AEC3 selection to false and echo cancellation type constraint to
+ // AEC3 and expect AEC3 as result.
+ admf->set_override_aec3(false);
+
+ ResetFactory();
+ constraint_factory_.basic().echo_cancellation.SetExact(true);
+ constraint_factory_.basic().echo_cancellation_type.SetExact(
+ kEchoCancellationTypeValues[1]);
+ result = SelectSettings();
+ ASSERT_TRUE(result.HasValue());
+
+ CheckAudioProcessingPropertiesForExactEchoCancellationType(
+ kEchoCancellationTypeValues[1], // AEC3
+ result);
+}
+
// Test that having differing mandatory values for echoCancellation and
// googEchoCancellation fails.
TEST_P(MediaStreamConstraintsUtilAudioTest, ContradictoryEchoCancellation) {
@@ -1083,7 +1144,6 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
&AudioProcessingProperties::goog_typing_noise_detection,
&AudioProcessingProperties::goog_noise_suppression,
&AudioProcessingProperties::goog_experimental_noise_suppression,
- &AudioProcessingProperties::goog_beamforming,
&AudioProcessingProperties::goog_highpass_filter,
&AudioProcessingProperties::goog_experimental_auto_gain_control};
@@ -1098,7 +1158,6 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
&blink::WebMediaTrackConstraintSet::goog_noise_suppression,
&blink::WebMediaTrackConstraintSet::
goog_experimental_noise_suppression,
- &blink::WebMediaTrackConstraintSet::goog_beamforming,
&blink::WebMediaTrackConstraintSet::goog_highpass_filter,
&blink::WebMediaTrackConstraintSet::
goog_experimental_auto_gain_control,
@@ -1123,10 +1182,8 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
set_function)(true);
auto result = SelectSettings();
EXPECT_TRUE(result.HasValue());
- EXPECT_FALSE(
- result.audio_processing_properties().enable_sw_echo_cancellation);
- EXPECT_TRUE(
- result.audio_processing_properties().disable_hw_echo_cancellation);
+ EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
+ result.audio_processing_properties().echo_cancellation_type);
EXPECT_TRUE(result.audio_processing_properties().*
kAudioProcessingProperties[i]);
for (size_t j = 0; j < kAudioProcessingProperties.size(); ++j) {
@@ -1152,7 +1209,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, AdvancedCompatibleConstraints) {
&AudioCaptureSettings::render_to_associated_sink;
CheckBoolDefaults({render_to_associated_sink},
{&AudioProcessingProperties::goog_audio_mirroring}, result);
- CheckGeometryDefaults(result);
+ CheckEchoCancellationTypeDefault(result);
EXPECT_TRUE(result.render_to_associated_sink());
EXPECT_TRUE(result.audio_processing_properties().goog_audio_mirroring);
}
@@ -1177,7 +1234,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
{&AudioProcessingProperties::goog_audio_mirroring,
&AudioProcessingProperties::goog_highpass_filter},
result);
- CheckGeometryDefaults(result);
+ CheckEchoCancellationTypeDefault(result);
EXPECT_FALSE(result.hotword_enabled());
EXPECT_TRUE(result.audio_processing_properties().goog_audio_mirroring);
EXPECT_TRUE(result.audio_processing_properties().goog_highpass_filter);
@@ -1199,129 +1256,13 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, AdvancedConflictingLastConstraint) {
{&AudioProcessingProperties::goog_audio_mirroring,
&AudioProcessingProperties::goog_highpass_filter},
result);
- CheckGeometryDefaults(result);
+ CheckEchoCancellationTypeDefault(result);
// The fourth advanced set is ignored because it contradicts the second set.
EXPECT_TRUE(result.hotword_enabled());
EXPECT_TRUE(result.audio_processing_properties().goog_audio_mirroring);
EXPECT_TRUE(result.audio_processing_properties().goog_highpass_filter);
}
-// Test that a valid geometry is interpreted correctly in all the ways it can
-// be set.
-TEST_P(MediaStreamConstraintsUtilAudioTest, ValidGeometry) {
- const blink::WebString kGeometry =
- blink::WebString::FromASCII("-0.02 0 0 0.02 0 1.01");
-
- for (auto set_function : kStringSetFunctions) {
- for (auto accessor : kFactoryAccessors) {
- // Ideal advanced is ignored by the SelectSettings algorithm.
- // Using array elements instead of pointer values due to the comparison
- // failing on some build configurations.
- if (set_function == kStringSetFunctions[1] &&
- accessor == kFactoryAccessors[1]) {
- continue;
- }
- ResetFactory();
- ((constraint_factory_.*accessor)().goog_array_geometry.*
- set_function)(kGeometry);
- auto result = SelectSettings();
- EXPECT_TRUE(result.HasValue());
- CheckDeviceDefaults(result);
- CheckBoolDefaults(AudioSettingsBoolMembers(),
- AudioPropertiesBoolMembers(), result);
- const std::vector<media::Point>& geometry =
- result.audio_processing_properties().goog_array_geometry;
- EXPECT_EQ(2u, geometry.size());
- EXPECT_EQ(media::Point(-0.02, 0, 0), geometry[0]);
- EXPECT_EQ(media::Point(0.02, 0, 1.01), geometry[1]);
- }
- }
-}
-
-// Test that an invalid geometry is interpreted as empty in all the ways it can
-// be set.
-TEST_P(MediaStreamConstraintsUtilAudioTest, InvalidGeometry) {
- const blink::WebString kGeometry =
- blink::WebString::FromASCII("1 1 1 invalid");
-
- for (auto set_function : kStringSetFunctions) {
- for (auto accessor : kFactoryAccessors) {
- // Ideal advanced is ignored by the SelectSettings algorithm.
- // Using array elements instead of pointer values due to the comparison
- // failing on some build configurations.
- if (set_function == kStringSetFunctions[1] &&
- accessor == kFactoryAccessors[1]) {
- continue;
- }
- ResetFactory();
- ((constraint_factory_.*accessor)().goog_array_geometry.*
- set_function)(kGeometry);
- auto result = SelectSettings();
- EXPECT_TRUE(result.HasValue());
- CheckDeviceDefaults(result);
- CheckBoolDefaults(AudioSettingsBoolMembers(),
- AudioPropertiesBoolMembers(), result);
- const std::vector<media::Point>& geometry =
- result.audio_processing_properties().goog_array_geometry;
- EXPECT_EQ(0u, geometry.size());
- }
- }
-}
-
-// Test that an invalid geometry is interpreted as empty in all the ways it can
-// be set.
-TEST_P(MediaStreamConstraintsUtilAudioTest, DeviceGeometry) {
- if (!IsDeviceCapture())
- return;
-
- constraint_factory_.basic().device_id.SetExact(
- blink::WebString::FromASCII(geometry_device_->DeviceID()));
-
- {
- const blink::WebString kValidGeometry =
- blink::WebString::FromASCII("-0.02 0 0 0.02 0 1.01");
- constraint_factory_.basic().goog_array_geometry.SetExact(kValidGeometry);
- auto result = SelectSettings();
- EXPECT_TRUE(result.HasValue());
- CheckDevice(*geometry_device_, result);
- CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
- result);
- // Constraints geometry should be preferred over device geometry.
- const std::vector<media::Point>& geometry =
- result.audio_processing_properties().goog_array_geometry;
- EXPECT_EQ(2u, geometry.size());
- EXPECT_EQ(media::Point(-0.02, 0, 0), geometry[0]);
- EXPECT_EQ(media::Point(0.02, 0, 1.01), geometry[1]);
- }
-
- {
- constraint_factory_.basic().goog_array_geometry.SetExact(
- blink::WebString());
- auto result = SelectSettings();
- EXPECT_TRUE(result.HasValue());
- CheckDevice(*geometry_device_, result);
- CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
- result);
- // Empty geometry is valid and should be preferred over device geometry.
- EXPECT_TRUE(
- result.audio_processing_properties().goog_array_geometry.empty());
- }
-
- {
- const blink::WebString kInvalidGeometry =
- blink::WebString::FromASCII("1 1 1 invalid");
- constraint_factory_.basic().goog_array_geometry.SetExact(kInvalidGeometry);
- auto result = SelectSettings();
- EXPECT_TRUE(result.HasValue());
- CheckDevice(*geometry_device_, result);
- CheckBoolDefaults(AudioSettingsBoolMembers(), AudioPropertiesBoolMembers(),
- result);
- // Device geometry should be preferred over invalid constraints geometry.
- EXPECT_EQ(kMicPositions,
- result.audio_processing_properties().goog_array_geometry);
- }
-}
-
// NoDevices tests verify that the case with no devices is handled correctly.
TEST_P(MediaStreamConstraintsUtilAudioTest, NoDevicesNoConstraints) {
// This test makes sense only for device capture.
@@ -1354,7 +1295,7 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithNoAudioProcessing) {
for (bool enable_properties : {true, false}) {
std::unique_ptr<LocalMediaStreamAudioSource> source =
GetLocalMediaStreamAudioSource(
- enable_properties /* enable_hardware_echo_canceller */,
+ enable_properties /* enable_system_echo_canceller */,
enable_properties /* hotword_enabled */,
enable_properties /* disable_local_echo */,
enable_properties /* render_to_associated_sink */);
@@ -1406,10 +1347,10 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
EchoCancellationTypeWithSourceWithNoAudioProcessing) {
for (blink::WebString value : kEchoCancellationTypeValues) {
std::unique_ptr<LocalMediaStreamAudioSource> source =
- GetLocalMediaStreamAudioSource(
- false /* enable_hardware_echo_canceller */,
- false /* hotword_enabled */, false /* disable_local_echo */,
- false /* render_to_associated_sink */);
+ GetLocalMediaStreamAudioSource(false /* enable_system_echo_canceller */,
+ false /* hotword_enabled */,
+ false /* disable_local_echo */,
+ false /* render_to_associated_sink */);
// No echo cancellation is available so we expect failure.
constraint_factory_.Reset();
@@ -1436,10 +1377,9 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
for (bool use_defaults : {true, false}) {
AudioProcessingProperties properties;
- properties.disable_hw_echo_cancellation = true;
if (!use_defaults) {
- properties.enable_sw_echo_cancellation =
- !properties.enable_sw_echo_cancellation;
+ properties.echo_cancellation_type =
+ EchoCancellationType::kEchoCancellationDisabled;
properties.goog_audio_mirroring = !properties.goog_audio_mirroring;
properties.goog_auto_gain_control = !properties.goog_auto_gain_control;
properties.goog_experimental_echo_cancellation =
@@ -1449,11 +1389,9 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
properties.goog_noise_suppression = !properties.goog_noise_suppression;
properties.goog_experimental_noise_suppression =
!properties.goog_experimental_noise_suppression;
- properties.goog_beamforming = !properties.goog_beamforming;
properties.goog_highpass_filter = !properties.goog_highpass_filter;
properties.goog_experimental_auto_gain_control =
!properties.goog_experimental_auto_gain_control;
- properties.goog_array_geometry = {{1, 1, 1}, {2, 2, 2}};
}
std::unique_ptr<ProcessedLocalAudioSource> source =
@@ -1464,7 +1402,6 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
const std::vector<
blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*>
kAudioProcessingConstraints = {
- &blink::WebMediaTrackConstraintSet::echo_cancellation,
&blink::WebMediaTrackConstraintSet::goog_audio_mirroring,
&blink::WebMediaTrackConstraintSet::goog_auto_gain_control,
&blink::WebMediaTrackConstraintSet::
@@ -1473,20 +1410,17 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
&blink::WebMediaTrackConstraintSet::goog_noise_suppression,
&blink::WebMediaTrackConstraintSet::
goog_experimental_noise_suppression,
- &blink::WebMediaTrackConstraintSet::goog_beamforming,
&blink::WebMediaTrackConstraintSet::goog_highpass_filter,
&blink::WebMediaTrackConstraintSet::
goog_experimental_auto_gain_control,
};
const AudioPropertiesBoolMembers kAudioProcessingProperties = {
- &AudioProcessingProperties::enable_sw_echo_cancellation,
&AudioProcessingProperties::goog_audio_mirroring,
&AudioProcessingProperties::goog_auto_gain_control,
&AudioProcessingProperties::goog_experimental_echo_cancellation,
&AudioProcessingProperties::goog_typing_noise_detection,
&AudioProcessingProperties::goog_noise_suppression,
&AudioProcessingProperties::goog_experimental_noise_suppression,
- &AudioProcessingProperties::goog_beamforming,
&AudioProcessingProperties::goog_highpass_filter,
&AudioProcessingProperties::goog_experimental_auto_gain_control};
@@ -1524,24 +1458,34 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
EXPECT_TRUE(result.HasValue());
}
- {
- constraint_factory_.Reset();
- // TODO(guidou): Support any semantically equivalent strings for the
- // goog_array_geometry constrainable property. http://crbug.com/796955
- constraint_factory_.basic().goog_array_geometry.SetExact(
- blink::WebString("1 1 1 2 2 2"));
- auto result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
- EXPECT_EQ(result.HasValue(), !use_defaults);
+ // Test same as above but for echo cancellation.
+ constraint_factory_.Reset();
+ constraint_factory_.basic().echo_cancellation.SetExact(
+ properties.echo_cancellation_type ==
+ EchoCancellationType::kEchoCancellationAec2);
+ auto result = SelectSettingsAudioCapture(
+ source.get(), constraint_factory_.CreateWebMediaConstraints());
+ EXPECT_TRUE(result.HasValue());
- // Setting ideal should succeed.
- constraint_factory_.Reset();
- constraint_factory_.basic().goog_array_geometry.SetIdeal(
- blink::WebString("4 4 4 5 5 5"));
- result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
- EXPECT_TRUE(result.HasValue());
- }
+ constraint_factory_.Reset();
+ constraint_factory_.basic().echo_cancellation.SetExact(
+ properties.echo_cancellation_type !=
+ EchoCancellationType::kEchoCancellationAec2);
+ result = SelectSettingsAudioCapture(
+ source.get(), constraint_factory_.CreateWebMediaConstraints());
+ EXPECT_FALSE(result.HasValue());
+
+ constraint_factory_.Reset();
+ constraint_factory_.basic().echo_cancellation.SetIdeal(true);
+ result = SelectSettingsAudioCapture(
+ source.get(), constraint_factory_.CreateWebMediaConstraints());
+ EXPECT_TRUE(result.HasValue());
+
+ constraint_factory_.Reset();
+ constraint_factory_.basic().echo_cancellation.SetIdeal(false);
+ result = SelectSettingsAudioCapture(
+ source.get(), constraint_factory_.CreateWebMediaConstraints());
+ EXPECT_TRUE(result.HasValue());
// These constraints are false in |source|.
const std::vector<
@@ -1579,6 +1523,31 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, SourceWithAudioProcessing) {
source.get(), constraint_factory_.CreateWebMediaConstraints());
EXPECT_TRUE(result.HasValue());
}
+
+ // Test same as above for echo cancellation.
+ constraint_factory_.Reset();
+ constraint_factory_.basic().echo_cancellation.SetExact(use_defaults);
+ result = SelectSettingsAudioCapture(
+ source.get(), constraint_factory_.CreateWebMediaConstraints());
+ EXPECT_TRUE(result.HasValue());
+
+ constraint_factory_.Reset();
+ constraint_factory_.basic().echo_cancellation.SetExact(!use_defaults);
+ result = SelectSettingsAudioCapture(
+ source.get(), constraint_factory_.CreateWebMediaConstraints());
+ EXPECT_FALSE(result.HasValue());
+
+ constraint_factory_.Reset();
+ constraint_factory_.basic().echo_cancellation.SetIdeal(true);
+ result = SelectSettingsAudioCapture(
+ source.get(), constraint_factory_.CreateWebMediaConstraints());
+ EXPECT_TRUE(result.HasValue());
+
+ constraint_factory_.Reset();
+ constraint_factory_.basic().echo_cancellation.SetIdeal(false);
+ result = SelectSettingsAudioCapture(
+ source.get(), constraint_factory_.CreateWebMediaConstraints());
+ EXPECT_TRUE(result.HasValue());
}
}
@@ -1590,46 +1559,42 @@ TEST_P(MediaStreamConstraintsUtilAudioTest,
if (!IsDeviceCapture())
return;
- for (bool enable_sw_ec : kBoolValues) {
- for (bool enable_exp_hw_ec : kBoolValues) {
- // Both sw and hw echo cancellation can't be enabled.
- if (enable_sw_ec && enable_exp_hw_ec)
- continue;
+ const EchoCancellationType kEchoCancellationTypes[] = {
+ EchoCancellationType::kEchoCancellationDisabled,
+ EchoCancellationType::kEchoCancellationAec2,
+ EchoCancellationType::kEchoCancellationAec3,
+ EchoCancellationType::kEchoCancellationSystem};
- AudioProcessingProperties properties;
- properties.DisableDefaultProperties();
- properties.enable_sw_echo_cancellation = enable_sw_ec;
- properties.enable_experimental_hw_echo_cancellation = enable_exp_hw_ec;
-
- std::unique_ptr<ProcessedLocalAudioSource> source =
- GetProcessedLocalAudioSource(
- properties, false /* hotword_enabled */,
- false /* disable_local_echo */,
- false /* render_to_associated_sink */,
- enable_exp_hw_ec
- ? media::AudioParameters::PlatformEffectsMask::
- EXPERIMENTAL_ECHO_CANCELLER
- : media::AudioParameters::PlatformEffectsMask::NO_EFFECTS);
-
- for (blink::WebString value : kEchoCancellationTypeValues) {
- bool system_ec_type = value == kEchoCancellationTypeValues[1];
-
- constraint_factory_.Reset();
- constraint_factory_.basic().echo_cancellation_type.SetExact(value);
- auto result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
- const bool should_have_result_value =
- (enable_sw_ec && !system_ec_type) ||
- (enable_exp_hw_ec && system_ec_type);
- EXPECT_EQ(should_have_result_value, result.HasValue());
-
- // Setting just ideal values should always succeed.
- constraint_factory_.Reset();
- constraint_factory_.basic().echo_cancellation_type.SetIdeal(value);
- result = SelectSettingsAudioCapture(
- source.get(), constraint_factory_.CreateWebMediaConstraints());
- EXPECT_TRUE(result.HasValue());
- }
+ for (EchoCancellationType ec_type : kEchoCancellationTypes) {
+ AudioProcessingProperties properties;
+ properties.DisableDefaultProperties();
+ properties.echo_cancellation_type = ec_type;
+
+ std::unique_ptr<ProcessedLocalAudioSource> source =
+ GetProcessedLocalAudioSource(
+ properties, false /* hotword_enabled */,
+ false /* disable_local_echo */,
+ false /* render_to_associated_sink */,
+ ec_type == EchoCancellationType::kEchoCancellationSystem
+ ? media::AudioParameters::PlatformEffectsMask::
+ EXPERIMENTAL_ECHO_CANCELLER
+ : media::AudioParameters::PlatformEffectsMask::NO_EFFECTS);
+
+ for (blink::WebString value : kEchoCancellationTypeValues) {
+ constraint_factory_.Reset();
+ constraint_factory_.basic().echo_cancellation_type.SetExact(value);
+ auto result = SelectSettingsAudioCapture(
+ source.get(), constraint_factory_.CreateWebMediaConstraints());
+ const bool should_have_result_value =
+ ec_type == GetEchoCancellationTypeFromConstraintString(value);
+ EXPECT_EQ(should_have_result_value, result.HasValue());
+
+ // Setting just ideal values should always succeed.
+ constraint_factory_.Reset();
+ constraint_factory_.basic().echo_cancellation_type.SetIdeal(value);
+ result = SelectSettingsAudioCapture(
+ source.get(), constraint_factory_.CreateWebMediaConstraints());
+ EXPECT_TRUE(result.HasValue());
}
}
}
@@ -1641,17 +1606,16 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, UsedAndUnusedSources) {
return;
AudioProcessingProperties properties;
- properties.enable_sw_echo_cancellation = true;
-
std::unique_ptr<ProcessedLocalAudioSource> processed_source =
GetProcessedLocalAudioSource(properties, false /* hotword_enabled */,
false /* disable_local_echo */,
false /* render_to_associated_sink */);
const std::string kUnusedDeviceID = "unused_device";
+ const std::string kGroupID = "fake_group";
AudioDeviceCaptureCapabilities capabilities;
capabilities.emplace_back(processed_source.get());
- capabilities.emplace_back(kUnusedDeviceID,
+ capabilities.emplace_back(kUnusedDeviceID, kGroupID,
media::AudioParameters::UnavailableDeviceParams());
{
@@ -1663,8 +1627,8 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, UsedAndUnusedSources) {
false /* should_disable_hardware_noise_suppression */);
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(result.device_id(), kUnusedDeviceID);
- EXPECT_FALSE(
- result.audio_processing_properties().enable_sw_echo_cancellation);
+ EXPECT_EQ(result.audio_processing_properties().echo_cancellation_type,
+ EchoCancellationType::kEchoCancellationDisabled);
}
{
@@ -1675,8 +1639,8 @@ TEST_P(MediaStreamConstraintsUtilAudioTest, UsedAndUnusedSources) {
false /* should_disable_hardware_noise_suppression */);
EXPECT_TRUE(result.HasValue());
EXPECT_EQ(result.device_id(), processed_source->device().id);
- EXPECT_TRUE(
- result.audio_processing_properties().enable_sw_echo_cancellation);
+ EXPECT_EQ(result.audio_processing_properties().echo_cancellation_type,
+ EchoCancellationType::kEchoCancellationAec2);
}
}
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_sets.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_sets.cc
index 9ce80b68a18..385ff981515 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_sets.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_sets.cc
@@ -10,6 +10,7 @@
#include "third_party/blink/public/platform/web_media_constraints.h"
namespace content {
+namespace media_constraints {
using Point = ResolutionSet::Point;
@@ -553,4 +554,5 @@ DiscreteSet<bool> BoolSetFromConstraint(
return DiscreteSet<bool>({constraint.Exact()});
}
+} // namespace media_constraints
} // namespace content
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_sets.h b/chromium/content/renderer/media/stream/media_stream_constraints_util_sets.h
index 28b07606700..23509132424 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_sets.h
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_sets.h
@@ -22,6 +22,7 @@ struct WebMediaTrackConstraintSet;
}
namespace content {
+namespace media_constraints {
// This class template represents a set of candidates suitable for a numeric
// range-based constraint.
@@ -392,6 +393,7 @@ class CONTENT_EXPORT ResolutionSet {
ResolutionSet::Point CONTENT_EXPORT operator*(double d,
const ResolutionSet::Point& p);
+} // namespace media_constraints
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_CONSTRAINTS_UTIL_SETS_H_
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_sets_unittest.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_sets_unittest.cc
index 105ae0784e6..62f74c126cb 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_sets_unittest.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_sets_unittest.cc
@@ -12,6 +12,7 @@
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
+namespace media_constraints {
using Point = ResolutionSet::Point;
@@ -1266,4 +1267,5 @@ TEST_F(MediaStreamConstraintsUtilSetsTest, DiscreteSetBool) {
EXPECT_TRUE(intersection.IsEmpty());
}
+} // namespace media_constraints
} // namespace content
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_unittest.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_unittest.cc
index 182870876bc..9b0a9ffdd62 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_unittest.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_unittest.cc
@@ -29,7 +29,8 @@ namespace content {
class MediaStreamConstraintsUtilTest : public testing::Test {
protected:
- using DoubleRangeSet = NumericRangeSet<double>;
+ using DoubleRangeSet = media_constraints::NumericRangeSet<double>;
+ using ResolutionSet = media_constraints::ResolutionSet;
};
TEST_F(MediaStreamConstraintsUtilTest, BooleanConstraints) {
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_content.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_content.cc
index dfa2734c8a5..7fa6b1f9c08 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_content.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_content.cc
@@ -39,9 +39,11 @@ const double kDefaultScreenCastFrameRate =
namespace {
+using ResolutionSet = media_constraints::ResolutionSet;
using Point = ResolutionSet::Point;
-using StringSet = DiscreteSet<std::string>;
-using BoolSet = DiscreteSet<bool>;
+using StringSet = media_constraints::DiscreteSet<std::string>;
+using BoolSet = media_constraints::DiscreteSet<bool>;
+using DoubleRangeSet = media_constraints::NumericRangeSet<double>;
constexpr double kMinScreenCastAspectRatio =
static_cast<double>(kMinScreenCastDimension) /
@@ -50,7 +52,6 @@ constexpr double kMaxScreenCastAspectRatio =
static_cast<double>(kMaxScreenCastDimension) /
static_cast<double>(kMinScreenCastDimension);
-using DoubleRangeSet = NumericRangeSet<double>;
class VideoContentCaptureCandidates {
public:
@@ -69,9 +70,10 @@ class VideoContentCaptureCandidates {
DoubleRangeSet::FromConstraint(constraint_set.frame_rate,
0.0,
kMaxScreenCastFrameRate)),
- device_id_set_(StringSetFromConstraint(constraint_set.device_id)),
- noise_reduction_set_(
- BoolSetFromConstraint(constraint_set.goog_noise_reduction)) {}
+ device_id_set_(media_constraints::StringSetFromConstraint(
+ constraint_set.device_id)),
+ noise_reduction_set_(media_constraints::BoolSetFromConstraint(
+ constraint_set.goog_noise_reduction)) {}
VideoContentCaptureCandidates(VideoContentCaptureCandidates&& other) =
default;
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_content.h b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_content.h
index 75e989191d3..cbc9db71fb4 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_content.h
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_content.h
@@ -9,7 +9,6 @@
#include "content/common/content_export.h"
#include "content/renderer/media/stream/media_stream_constraints_util.h"
-#include "third_party/webrtc/api/optional.h"
namespace blink {
class WebMediaConstraints;
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.cc
index 1e361d3de3d..66c6cabdd42 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device.cc
@@ -21,6 +21,9 @@ namespace content {
namespace {
+using ResolutionSet = media_constraints::ResolutionSet;
+using DoubleRangeSet = media_constraints::NumericRangeSet<double>;
+
// Number of default settings to be used as final tie-breaking criteria for
// settings that are equally good at satisfying constraints:
// device ID, power-line frequency, noise reduction, resolution and frame rate.
@@ -40,7 +43,7 @@ blink::WebString ToWebString(media::VideoFacingMode facing_mode) {
case media::MEDIA_VIDEO_FACING_ENVIRONMENT:
return blink::WebString::FromASCII("environment");
default:
- return blink::WebString::FromASCII("");
+ return blink::WebString();
}
}
@@ -125,7 +128,7 @@ class ConstrainedFormat {
const ResolutionSet& constrained_resolution() const {
return constrained_resolution_;
}
- const NumericRangeSet<double>& constrained_frame_rate() const {
+ const DoubleRangeSet& constrained_frame_rate() const {
return constrained_frame_rate_;
}
@@ -153,9 +156,8 @@ class ConstrainedFormat {
auto resolution_intersection = constrained_resolution_.Intersection(
ResolutionSet::FromConstraintSet(constraint_set));
auto frame_rate_intersection = constrained_frame_rate_.Intersection(
- NumericRangeSet<double>::FromConstraint(
- constraint_set.frame_rate, 0.0,
- media::limits::kMaxFramesPerSecond));
+ DoubleRangeSet::FromConstraint(constraint_set.frame_rate, 0.0,
+ media::limits::kMaxFramesPerSecond));
if (resolution_intersection.IsEmpty() ||
frame_rate_intersection.IsEmpty() ||
frame_rate_intersection.Min().value_or(0.0) > native_frame_rate_) {
@@ -173,7 +175,7 @@ class ConstrainedFormat {
long native_width_;
double native_frame_rate_;
ResolutionSet constrained_resolution_;
- NumericRangeSet<double> constrained_frame_rate_;
+ DoubleRangeSet constrained_frame_rate_;
};
VideoCaptureSettings ComputeVideoDeviceCaptureSettings(
@@ -241,6 +243,25 @@ double StringConstraintSourceDistance(const blink::WebString& value,
return HUGE_VAL;
}
+double FacingModeConstraintSourceDistance(
+ media::VideoFacingMode value,
+ const blink::StringConstraint& facing_mode_constraint,
+ const char** failed_constraint_name) {
+ blink::WebString string_value = ToWebString(value);
+ if (string_value.IsNull()) {
+ if (facing_mode_constraint.Exact().empty())
+ return 0.0;
+
+ if (failed_constraint_name)
+ *failed_constraint_name = facing_mode_constraint.GetName();
+ return HUGE_VAL;
+ }
+
+ double ret = StringConstraintSourceDistance(
+ string_value, facing_mode_constraint, failed_constraint_name);
+ return ret;
+}
+
// Returns a custom distance between a source screen dimension and |constraint|.
// The source supports the range [|min_source_value|, |max_source_value|], using
// cropping if necessary. This range may differ from the native range of the
@@ -446,9 +467,8 @@ double DeviceSourceDistance(
StringConstraintSourceDistance(blink::WebString::FromASCII(group_id),
constraint_set.group_id,
failed_constraint_name) +
- StringConstraintSourceDistance(ToWebString(facing_mode),
- constraint_set.facing_mode,
- failed_constraint_name);
+ FacingModeConstraintSourceDistance(
+ facing_mode, constraint_set.facing_mode, failed_constraint_name);
}
// Returns a custom distance between |constraint_set| and |format| given that
diff --git a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc
index dc0188d8aaa..8a9a13eb380 100644
--- a/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc
+++ b/chromium/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc
@@ -260,6 +260,18 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, OverconstrainedOnFacingMode) {
result.failed_constraint_name());
}
+TEST_F(MediaStreamConstraintsUtilVideoDeviceTest,
+ OverconstrainedOnEmptyFacingMode) {
+ constraint_factory_.Reset();
+ // Empty is not a valid facingMode value.
+ constraint_factory_.basic().facing_mode.SetExact(
+ blink::WebString::FromASCII(""));
+ auto result = SelectSettings();
+ EXPECT_FALSE(result.HasValue());
+ EXPECT_EQ(constraint_factory_.basic().facing_mode.GetName(),
+ result.failed_constraint_name());
+}
+
TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, OverconstrainedOnVideoKind) {
constraint_factory_.Reset();
// No device in |capabilities_| has video kind infrared.
diff --git a/chromium/content/renderer/media/stream/media_stream_renderer_factory_impl.cc b/chromium/content/renderer/media/stream/media_stream_renderer_factory_impl.cc
index 4e60ebaab8a..65151b93498 100644
--- a/chromium/content/renderer/media/stream/media_stream_renderer_factory_impl.cc
+++ b/chromium/content/renderer/media/stream/media_stream_renderer_factory_impl.cc
@@ -59,8 +59,8 @@ MediaStreamRendererFactoryImpl::GetVideoRenderer(
DVLOG(1) << "MediaStreamRendererFactoryImpl::GetVideoRenderer stream:"
<< web_stream.Id().Utf8();
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- web_stream.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ web_stream.VideoTracks();
if (video_tracks.IsEmpty() ||
!MediaStreamVideoTrack::GetTrack(video_tracks[0])) {
return nullptr;
@@ -76,8 +76,8 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer(
int render_frame_id,
const std::string& device_id) {
DCHECK(!web_stream.IsNull());
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- web_stream.AudioTracks(audio_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks =
+ web_stream.AudioTracks();
if (audio_tracks.IsEmpty()) {
WebRtcLogMessage("No audio tracks in media stream (return null).");
return nullptr;
diff --git a/chromium/content/renderer/media/stream/mock_constraint_factory.cc b/chromium/content/renderer/media/stream/mock_constraint_factory.cc
index b68c7cf159d..7f07e50046f 100644
--- a/chromium/content/renderer/media/stream/mock_constraint_factory.cc
+++ b/chromium/content/renderer/media/stream/mock_constraint_factory.cc
@@ -39,7 +39,6 @@ void MockConstraintFactory::DisableDefaultAudioConstraints() {
basic_.goog_highpass_filter.SetExact(false);
basic_.goog_typing_noise_detection.SetExact(false);
basic_.goog_experimental_noise_suppression.SetExact(false);
- basic_.goog_beamforming.SetExact(false);
}
void MockConstraintFactory::DisableAecAudioConstraints() {
diff --git a/chromium/content/renderer/media/stream/processed_local_audio_source.cc b/chromium/content/renderer/media/stream/processed_local_audio_source.cc
index 9a13797562c..1f4094f216d 100644
--- a/chromium/content/renderer/media/stream/processed_local_audio_source.cc
+++ b/chromium/content/renderer/media/stream/processed_local_audio_source.cc
@@ -10,7 +10,7 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
#include "content/renderer/media/stream/media_stream_constraints_util.h"
#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
@@ -24,6 +24,8 @@
namespace content {
+using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
+
namespace {
// Used as an identifier for ProcessedLocalAudioSource::From().
void* const kProcessedLocalAudioSourceIdentifier =
@@ -97,19 +99,22 @@ bool ProcessedLocalAudioSource::EnsureSourceIsStarted() {
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)) {
+ // Disable system echo cancellation if specified by
+ // |audio_processing_properties_|.
+ if (audio_processing_properties_.echo_cancellation_type !=
+ EchoCancellationType::kEchoCancellationSystem &&
+ device().input.effects() & media::AudioParameters::ECHO_CANCELLER) {
modified_device.input.set_effects(modified_device.input.effects() &
~media::AudioParameters::ECHO_CANCELLER);
device_is_modified = true;
- } else if (audio_processing_properties_
- .enable_experimental_hw_echo_cancellation &&
+ } else if (audio_processing_properties_.echo_cancellation_type ==
+ EchoCancellationType::kEchoCancellationSystem &&
(device().input.effects() &
media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER)) {
// Set the ECHO_CANCELLER effect, since that is what controls what's
// actually being used. The EXPERIMENTAL_ flag only indicates availability.
+ // TODO(grunell): AND with
+ // ~media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER.
modified_device.input.set_effects(modified_device.input.effects() |
media::AudioParameters::ECHO_CANCELLER);
device_is_modified = true;
diff --git a/chromium/content/renderer/media/stream/processed_local_audio_source_unittest.cc b/chromium/content/renderer/media/stream/processed_local_audio_source_unittest.cc
index 19df6b92642..6cc48ae1c3e 100644
--- a/chromium/content/renderer/media/stream/processed_local_audio_source_unittest.cc
+++ b/chromium/content/renderer/media/stream/processed_local_audio_source_unittest.cc
@@ -9,7 +9,7 @@
#include "base/message_loop/message_loop.h"
#include "build/build_config.h"
#include "content/public/renderer/media_stream_audio_sink.h"
-#include "content/renderer/media/mock_audio_device_factory.h"
+#include "content/renderer/media/audio/mock_audio_device_factory.h"
#include "content/renderer/media/stream/media_stream_audio_processor_options.h"
#include "content/renderer/media/stream/media_stream_audio_track.h"
#include "content/renderer/media/stream/processed_local_audio_source.h"
diff --git a/chromium/content/renderer/media/stream/track_audio_renderer.cc b/chromium/content/renderer/media/stream/track_audio_renderer.cc
index 826d403c76d..bcedaf56920 100644
--- a/chromium/content/renderer/media/stream/track_audio_renderer.cc
+++ b/chromium/content/renderer/media/stream/track_audio_renderer.cc
@@ -12,7 +12,7 @@
#include "base/synchronization/lock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "content/renderer/media/stream/media_stream_audio_track.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_latency.h"
diff --git a/chromium/content/renderer/media/stream/user_media_client_impl_unittest.cc b/chromium/content/renderer/media/stream/user_media_client_impl_unittest.cc
index 0415951c66b..703ea988283 100644
--- a/chromium/content/renderer/media/stream/user_media_client_impl_unittest.cc
+++ b/chromium/content/renderer/media/stream/user_media_client_impl_unittest.cc
@@ -42,6 +42,8 @@ using testing::_;
namespace content {
+using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
+
namespace {
blink::WebMediaConstraints CreateDefaultConstraints() {
@@ -469,10 +471,10 @@ class UserMediaClientImplTest : public ::testing::Test {
EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
blink::WebMediaStream desc = user_media_processor_->last_generated_stream();
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- desc.AudioTracks(audio_tracks);
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- desc.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks =
+ desc.AudioTracks();
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ desc.VideoTracks();
EXPECT_EQ(1u, audio_tracks.size());
EXPECT_EQ(1u, video_tracks.size());
@@ -490,10 +492,10 @@ class UserMediaClientImplTest : public ::testing::Test {
blink::WebMediaStream web_stream =
user_media_processor_->last_generated_stream();
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- web_stream.AudioTracks(audio_tracks);
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- web_stream.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks =
+ web_stream.AudioTracks();
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ web_stream.VideoTracks();
EXPECT_EQ(audio_tracks.size(), 0U);
EXPECT_EQ(video_tracks.size(), 1U);
@@ -515,10 +517,10 @@ class UserMediaClientImplTest : public ::testing::Test {
EXPECT_EQ(REQUEST_SUCCEEDED, request_state());
blink::WebMediaStream desc = user_media_processor_->last_generated_stream();
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- desc.AudioTracks(audio_tracks);
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- desc.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks =
+ desc.AudioTracks();
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ desc.VideoTracks();
EXPECT_EQ(audio_tracks.size(), 1u);
EXPECT_TRUE(video_tracks.empty());
@@ -617,20 +619,20 @@ TEST_F(UserMediaClientImplTest, GenerateTwoMediaStreamsWithSameSource) {
blink::WebMediaStream desc1 = RequestLocalMediaStream();
blink::WebMediaStream desc2 = RequestLocalMediaStream();
- blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
- desc1.VideoTracks(desc1_video_tracks);
- blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
- desc2.VideoTracks(desc2_video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks =
+ desc1.VideoTracks();
+ blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks =
+ desc2.VideoTracks();
EXPECT_EQ(desc1_video_tracks[0].Source().Id(),
desc2_video_tracks[0].Source().Id());
EXPECT_EQ(desc1_video_tracks[0].Source().GetExtraData(),
desc2_video_tracks[0].Source().GetExtraData());
- blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
- desc1.AudioTracks(desc1_audio_tracks);
- blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
- desc2.AudioTracks(desc2_audio_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks =
+ desc1.AudioTracks();
+ blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks =
+ desc2.AudioTracks();
EXPECT_EQ(desc1_audio_tracks[0].Source().Id(),
desc2_audio_tracks[0].Source().Id());
@@ -647,20 +649,20 @@ TEST_F(UserMediaClientImplTest, GenerateTwoMediaStreamsWithDifferentSources) {
mock_dispatcher_host_.IncrementSessionId();
blink::WebMediaStream desc2 = RequestLocalMediaStream();
- blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks;
- desc1.VideoTracks(desc1_video_tracks);
- blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks;
- desc2.VideoTracks(desc2_video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> desc1_video_tracks =
+ desc1.VideoTracks();
+ blink::WebVector<blink::WebMediaStreamTrack> desc2_video_tracks =
+ desc2.VideoTracks();
EXPECT_NE(desc1_video_tracks[0].Source().Id(),
desc2_video_tracks[0].Source().Id());
EXPECT_NE(desc1_video_tracks[0].Source().GetExtraData(),
desc2_video_tracks[0].Source().GetExtraData());
- blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks;
- desc1.AudioTracks(desc1_audio_tracks);
- blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks;
- desc2.AudioTracks(desc2_audio_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> desc1_audio_tracks =
+ desc1.AudioTracks();
+ blink::WebVector<blink::WebMediaStreamTrack> desc2_audio_tracks =
+ desc2.AudioTracks();
EXPECT_NE(desc1_audio_tracks[0].Source().Id(),
desc2_audio_tracks[0].Source().Id());
@@ -672,15 +674,15 @@ TEST_F(UserMediaClientImplTest, StopLocalTracks) {
// Generate a stream with both audio and video.
blink::WebMediaStream mixed_desc = RequestLocalMediaStream();
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- mixed_desc.AudioTracks(audio_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks =
+ mixed_desc.AudioTracks();
MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
audio_track->Stop();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- mixed_desc.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ mixed_desc.VideoTracks();
MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
video_track->Stop();
base::RunLoop().RunUntilIdle();
@@ -696,29 +698,29 @@ TEST_F(UserMediaClientImplTest, StopLocalTracksWhenTwoStreamUseSameDevices) {
blink::WebMediaStream desc1 = RequestLocalMediaStream();
blink::WebMediaStream desc2 = RequestLocalMediaStream();
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks1;
- desc1.AudioTracks(audio_tracks1);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks1 =
+ desc1.AudioTracks();
MediaStreamTrack* audio_track1 = MediaStreamTrack::GetTrack(audio_tracks1[0]);
audio_track1->Stop();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0, mock_dispatcher_host_.stop_audio_device_counter());
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks2;
- desc2.AudioTracks(audio_tracks2);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks2 =
+ desc2.AudioTracks();
MediaStreamTrack* audio_track2 = MediaStreamTrack::GetTrack(audio_tracks2[0]);
audio_track2->Stop();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks1;
- desc1.VideoTracks(video_tracks1);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks1 =
+ desc1.VideoTracks();
MediaStreamTrack* video_track1 = MediaStreamTrack::GetTrack(video_tracks1[0]);
video_track1->Stop();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0, mock_dispatcher_host_.stop_video_device_counter());
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks2;
- desc2.VideoTracks(video_tracks2);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks2 =
+ desc2.VideoTracks();
MediaStreamTrack* video_track2 = MediaStreamTrack::GetTrack(video_tracks2[0]);
video_track2->Stop();
base::RunLoop().RunUntilIdle();
@@ -823,15 +825,15 @@ TEST_F(UserMediaClientImplTest, StopTrackAfterReload) {
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);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks =
+ mixed_desc.AudioTracks();
MediaStreamTrack* audio_track = MediaStreamTrack::GetTrack(audio_tracks[0]);
audio_track->Stop();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, mock_dispatcher_host_.stop_audio_device_counter());
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- mixed_desc.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ mixed_desc.VideoTracks();
MediaStreamTrack* video_track = MediaStreamTrack::GetTrack(video_tracks[0]);
video_track->Stop();
base::RunLoop().RunUntilIdle();
@@ -859,8 +861,8 @@ TEST_F(UserMediaClientImplTest, DefaultConstraintsPropagate) {
const AudioProcessingProperties& properties =
audio_capture_settings.audio_processing_properties();
- EXPECT_TRUE(properties.enable_sw_echo_cancellation);
- EXPECT_TRUE(properties.disable_hw_echo_cancellation);
+ EXPECT_EQ(EchoCancellationType::kEchoCancellationAec2,
+ properties.echo_cancellation_type);
EXPECT_FALSE(properties.goog_audio_mirroring);
EXPECT_TRUE(properties.goog_auto_gain_control);
// The default value for goog_experimental_echo_cancellation is platform
@@ -870,10 +872,8 @@ TEST_F(UserMediaClientImplTest, DefaultConstraintsPropagate) {
EXPECT_TRUE(properties.goog_typing_noise_detection);
EXPECT_TRUE(properties.goog_noise_suppression);
EXPECT_TRUE(properties.goog_experimental_noise_suppression);
- EXPECT_TRUE(properties.goog_beamforming);
EXPECT_TRUE(properties.goog_highpass_filter);
EXPECT_TRUE(properties.goog_experimental_auto_gain_control);
- EXPECT_TRUE(properties.goog_array_geometry.empty());
EXPECT_TRUE(video_capture_settings.HasValue());
EXPECT_EQ(video_capture_settings.Width(),
@@ -928,18 +928,16 @@ TEST_F(UserMediaClientImplTest, DefaultTabCapturePropagate) {
const AudioProcessingProperties& properties =
audio_capture_settings.audio_processing_properties();
- EXPECT_FALSE(properties.enable_sw_echo_cancellation);
- EXPECT_TRUE(properties.disable_hw_echo_cancellation);
+ EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
+ properties.echo_cancellation_type);
EXPECT_FALSE(properties.goog_audio_mirroring);
EXPECT_FALSE(properties.goog_auto_gain_control);
EXPECT_FALSE(properties.goog_experimental_echo_cancellation);
EXPECT_FALSE(properties.goog_typing_noise_detection);
EXPECT_FALSE(properties.goog_noise_suppression);
EXPECT_FALSE(properties.goog_experimental_noise_suppression);
- EXPECT_FALSE(properties.goog_beamforming);
EXPECT_FALSE(properties.goog_highpass_filter);
EXPECT_FALSE(properties.goog_experimental_auto_gain_control);
- EXPECT_TRUE(properties.goog_array_geometry.empty());
EXPECT_TRUE(video_capture_settings.HasValue());
EXPECT_EQ(video_capture_settings.Width(), kDefaultScreenCastWidth);
@@ -991,18 +989,16 @@ TEST_F(UserMediaClientImplTest, DefaultDesktopCapturePropagate) {
const AudioProcessingProperties& properties =
audio_capture_settings.audio_processing_properties();
- EXPECT_FALSE(properties.enable_sw_echo_cancellation);
- EXPECT_TRUE(properties.disable_hw_echo_cancellation);
+ EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
+ properties.echo_cancellation_type);
EXPECT_FALSE(properties.goog_audio_mirroring);
EXPECT_FALSE(properties.goog_auto_gain_control);
EXPECT_FALSE(properties.goog_experimental_echo_cancellation);
EXPECT_FALSE(properties.goog_typing_noise_detection);
EXPECT_FALSE(properties.goog_noise_suppression);
EXPECT_FALSE(properties.goog_experimental_noise_suppression);
- EXPECT_FALSE(properties.goog_beamforming);
EXPECT_FALSE(properties.goog_highpass_filter);
EXPECT_FALSE(properties.goog_experimental_auto_gain_control);
- EXPECT_TRUE(properties.goog_array_geometry.empty());
EXPECT_TRUE(video_capture_settings.HasValue());
EXPECT_EQ(video_capture_settings.Width(), kDefaultScreenCastWidth);
@@ -1038,8 +1034,6 @@ TEST_F(UserMediaClientImplTest, NonDefaultAudioConstraintsPropagate) {
factory.basic().echo_cancellation.SetExact(false);
factory.basic().goog_audio_mirroring.SetExact(true);
factory.basic().goog_typing_noise_detection.SetExact(true);
- factory.basic().goog_array_geometry.SetExact(
- blink::WebString::FromASCII("1 1 1"));
blink::WebMediaConstraints audio_constraints =
factory.CreateWebMediaConstraints();
// Request contains only audio
@@ -1063,19 +1057,16 @@ TEST_F(UserMediaClientImplTest, NonDefaultAudioConstraintsPropagate) {
const AudioProcessingProperties& properties =
audio_capture_settings.audio_processing_properties();
- EXPECT_FALSE(properties.enable_sw_echo_cancellation);
- EXPECT_TRUE(properties.disable_hw_echo_cancellation);
+ EXPECT_EQ(EchoCancellationType::kEchoCancellationDisabled,
+ properties.echo_cancellation_type);
EXPECT_TRUE(properties.goog_audio_mirroring);
EXPECT_FALSE(properties.goog_auto_gain_control);
EXPECT_FALSE(properties.goog_experimental_echo_cancellation);
EXPECT_TRUE(properties.goog_typing_noise_detection);
EXPECT_FALSE(properties.goog_noise_suppression);
EXPECT_FALSE(properties.goog_experimental_noise_suppression);
- EXPECT_FALSE(properties.goog_beamforming);
EXPECT_FALSE(properties.goog_highpass_filter);
EXPECT_FALSE(properties.goog_experimental_auto_gain_control);
- const std::vector<media::Point> kGeometry = {{1.0, 1.0, 1.0}};
- EXPECT_EQ(kGeometry, properties.goog_array_geometry);
}
TEST_F(UserMediaClientImplTest, CreateWithMandatoryInvalidAudioDeviceId) {
diff --git a/chromium/content/renderer/media/stream/user_media_processor.cc b/chromium/content/renderer/media/stream/user_media_processor.cc
index cba8d68a14e..bd5929a359b 100644
--- a/chromium/content/renderer/media/stream/user_media_processor.cc
+++ b/chromium/content/renderer/media/stream/user_media_processor.cc
@@ -47,6 +47,10 @@
#include "url/origin.h"
namespace content {
+
+using blink::WebMediaStreamSource;
+using EchoCancellationType = AudioProcessingProperties::EchoCancellationType;
+
namespace {
void CopyFirstString(const blink::StringConstraint& constraint,
@@ -101,37 +105,48 @@ bool IsValidVideoContentSource(const std::string& source) {
void SurfaceAudioProcessingSettings(blink::WebMediaStreamSource* source) {
MediaStreamAudioSource* source_impl =
static_cast<MediaStreamAudioSource*>(source->GetExtraData());
- bool sw_echo_cancellation = false, auto_gain_control = false,
- noise_supression = false, hw_echo_cancellation = false;
+
+ // If the source is a processed source, get the properties from it.
if (ProcessedLocalAudioSource* processed_source =
ProcessedLocalAudioSource::From(source_impl)) {
AudioProcessingProperties properties =
processed_source->audio_processing_properties();
- sw_echo_cancellation = properties.enable_sw_echo_cancellation;
- auto_gain_control = properties.goog_auto_gain_control;
- noise_supression = properties.goog_noise_suppression;
- // The ECHO_CANCELLER flag will be set if either:
- // - The device advertises the ECHO_CANCELLER flag and
- // disable_hw_echo_cancellation is false; or if
- // - The device advertises the EXPERIMENTAL_ECHO_CANCELLER flag and
- // enable_experimental_hw_echo_cancellation is true.
- // See: ProcessedLocalAudioSource::EnsureSourceIsStarted().
- const media::AudioParameters& params = processed_source->device().input;
- hw_echo_cancellation =
- params.IsValid() &&
- (params.effects() & media::AudioParameters::ECHO_CANCELLER);
- }
+ WebMediaStreamSource::EchoCancellationMode echo_cancellation_mode;
- using blink::WebMediaStreamSource;
- const WebMediaStreamSource::EchoCancellationMode echo_cancellation_mode =
- hw_echo_cancellation
- ? WebMediaStreamSource::EchoCancellationMode::kHardware
- : sw_echo_cancellation
- ? WebMediaStreamSource::EchoCancellationMode::kSoftware
- : WebMediaStreamSource::EchoCancellationMode::kDisabled;
+ switch (properties.echo_cancellation_type) {
+ case EchoCancellationType::kEchoCancellationDisabled:
+ echo_cancellation_mode =
+ WebMediaStreamSource::EchoCancellationMode::kDisabled;
+ break;
+ case EchoCancellationType::kEchoCancellationAec2:
+ echo_cancellation_mode =
+ WebMediaStreamSource::EchoCancellationMode::kBrowser;
+ break;
+ case EchoCancellationType::kEchoCancellationAec3:
+ echo_cancellation_mode =
+ WebMediaStreamSource::EchoCancellationMode::kAec3;
+ break;
+ case EchoCancellationType::kEchoCancellationSystem:
+ echo_cancellation_mode =
+ WebMediaStreamSource::EchoCancellationMode::kSystem;
+ break;
+ }
+
+ source->SetAudioProcessingProperties(echo_cancellation_mode,
+ properties.goog_auto_gain_control,
+ properties.goog_noise_suppression);
+ } else {
+ // If the source is not a processed source, it could still support system
+ // echo cancellation. Surface that if it does.
+ media::AudioParameters params = source_impl->GetAudioParameters();
+ const WebMediaStreamSource::EchoCancellationMode echo_cancellation_mode =
+ params.IsValid() &&
+ (params.effects() & media::AudioParameters::ECHO_CANCELLER)
+ ? WebMediaStreamSource::EchoCancellationMode::kSystem
+ : WebMediaStreamSource::EchoCancellationMode::kDisabled;
- source->SetAudioProcessingProperties(echo_cancellation_mode,
- auto_gain_control, noise_supression);
+ source->SetAudioProcessingProperties(echo_cancellation_mode, false, false);
+ }
}
} // namespace
@@ -458,10 +473,12 @@ void UserMediaProcessor::SelectAudioDeviceSettings(
if (source->device().type == MEDIA_DEVICE_AUDIO_CAPTURE)
audio_source = static_cast<MediaStreamAudioSource*>(source);
}
- if (audio_source)
+ if (audio_source) {
capabilities.emplace_back(audio_source);
- else
- capabilities.emplace_back(device->device_id, device->parameters);
+ } else {
+ capabilities.emplace_back(device->device_id, device->group_id,
+ device->parameters);
+ }
}
SelectAudioSettings(web_request, capabilities);
@@ -864,9 +881,11 @@ blink::WebMediaStreamSource UserMediaProcessor::InitializeAudioSourceObject(
blink::WebMediaStreamSource::Capabilities capabilities;
capabilities.echo_cancellation = {true, false};
- capabilities.echo_cancellation_type.reserve(2);
+ capabilities.echo_cancellation_type.reserve(3);
capabilities.echo_cancellation_type.emplace_back(
blink::WebString::FromASCII(blink::kEchoCancellationTypeBrowser));
+ capabilities.echo_cancellation_type.emplace_back(
+ blink::WebString::FromASCII(blink::kEchoCancellationTypeAec3));
if (device.input.effects() &
(media::AudioParameters::ECHO_CANCELLER |
media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER)) {
@@ -1010,15 +1029,13 @@ void UserMediaProcessor::OnCreateNativeTracksCompleted(
} else {
GetUserMediaRequestFailed(result, constraint_name);
- blink::WebVector<blink::WebMediaStreamTrack> tracks;
- request_info->web_stream()->AudioTracks(tracks);
- for (auto& web_track : tracks) {
+ for (auto& web_track : request_info->web_stream()->AudioTracks()) {
MediaStreamTrack* track = MediaStreamTrack::GetTrack(web_track);
if (track)
track->Stop();
}
- request_info->web_stream()->VideoTracks(tracks);
- for (auto& web_track : tracks) {
+
+ for (auto& web_track : request_info->web_stream()->VideoTracks()) {
MediaStreamTrack* track = MediaStreamTrack::GetTrack(web_track);
if (track)
track->Stop();
diff --git a/chromium/content/renderer/media/stream/webmediaplayer_ms.cc b/chromium/content/renderer/media/stream/webmediaplayer_ms.cc
index d8483027e0a..2d13eb7cb58 100644
--- a/chromium/content/renderer/media/stream/webmediaplayer_ms.cc
+++ b/chromium/content/renderer/media/stream/webmediaplayer_ms.cc
@@ -323,9 +323,10 @@ WebMediaPlayerMS::~WebMediaPlayerMS() {
delegate_->RemoveObserver(delegate_id_);
}
-void WebMediaPlayerMS::Load(LoadType load_type,
- const blink::WebMediaPlayerSource& source,
- CORSMode /*cors_mode*/) {
+blink::WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load(
+ LoadType load_type,
+ const blink::WebMediaPlayerSource& source,
+ CORSMode /*cors_mode*/) {
DVLOG(1) << __func__;
DCHECK(thread_checker_.CalledOnValidThread());
@@ -376,7 +377,7 @@ void WebMediaPlayerMS::Load(LoadType load_type,
if (!video_frame_provider_ && !audio_renderer_) {
SetNetworkState(WebMediaPlayer::kNetworkStateNetworkError);
- return;
+ return blink::WebMediaPlayer::LoadTiming::kImmediate;
}
if (audio_renderer_) {
@@ -384,9 +385,9 @@ void WebMediaPlayerMS::Load(LoadType load_type,
audio_renderer_->Start();
// Store the ID of audio track being played in |current_video_track_id_|
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
if (!web_stream_.IsNull()) {
- web_stream_.AudioTracks(audio_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks =
+ web_stream_.AudioTracks();
DCHECK_GT(audio_tracks.size(), 0U);
current_audio_track_id_ = audio_tracks[0].Id();
}
@@ -397,8 +398,8 @@ void WebMediaPlayerMS::Load(LoadType load_type,
// Store the ID of video track being played in |current_video_track_id_|
if (!web_stream_.IsNull()) {
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- web_stream_.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ web_stream_.VideoTracks();
DCHECK_GT(video_tracks.size(), 0U);
current_video_track_id_ = video_tracks[0].Id();
}
@@ -413,6 +414,8 @@ void WebMediaPlayerMS::Load(LoadType load_type,
SetReadyState(WebMediaPlayer::kReadyStateHaveMetadata);
SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData);
}
+
+ return blink::WebMediaPlayer::LoadTiming::kImmediate;
}
void WebMediaPlayerMS::TrackAdded(const blink::WebMediaStreamTrack& track) {
@@ -455,9 +458,8 @@ void WebMediaPlayerMS::Reload() {
void WebMediaPlayerMS::ReloadVideo() {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!web_stream_.IsNull());
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- // VideoTracks() is a getter.
- web_stream_.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ web_stream_.VideoTracks();
RendererReloadAction renderer_action = RendererReloadAction::KEEP_RENDERER;
if (video_tracks.IsEmpty()) {
@@ -506,9 +508,8 @@ void WebMediaPlayerMS::ReloadAudio() {
if (!frame)
return;
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- // AudioTracks() is a getter.
- web_stream_.AudioTracks(audio_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks =
+ web_stream_.AudioTracks();
RendererReloadAction renderer_action = RendererReloadAction::KEEP_RENDERER;
if (audio_tracks.IsEmpty()) {
@@ -763,7 +764,7 @@ bool WebMediaPlayerMS::DidLoadingProgress() {
return true;
}
-void WebMediaPlayerMS::Paint(blink::WebCanvas* canvas,
+void WebMediaPlayerMS::Paint(cc::PaintCanvas* canvas,
const blink::WebRect& rect,
cc::PaintFlags& flags,
int already_uploaded_id,
@@ -921,6 +922,11 @@ void WebMediaPlayerMS::OnPictureInPictureModeEnded() {
NOTIMPLEMENTED();
}
+void WebMediaPlayerMS::OnPictureInPictureControlClicked(
+ const std::string& control_id) {
+ NOTIMPLEMENTED();
+}
+
bool WebMediaPlayerMS::CopyVideoTextureToPlatformTexture(
gpu::gles2::GLES2Interface* gl,
unsigned target,
diff --git a/chromium/content/renderer/media/stream/webmediaplayer_ms.h b/chromium/content/renderer/media/stream/webmediaplayer_ms.h
index fe0de43a473..4af79567b43 100644
--- a/chromium/content/renderer/media/stream/webmediaplayer_ms.h
+++ b/chromium/content/renderer/media/stream/webmediaplayer_ms.h
@@ -86,9 +86,10 @@ class CONTENT_EXPORT WebMediaPlayerMS
~WebMediaPlayerMS() override;
- void Load(LoadType load_type,
- const blink::WebMediaPlayerSource& source,
- CORSMode cors_mode) override;
+ blink::WebMediaPlayer::LoadTiming Load(
+ LoadType load_type,
+ const blink::WebMediaPlayerSource& source,
+ CORSMode cors_mode) override;
// Playback controls.
void Play() override;
@@ -109,7 +110,7 @@ class CONTENT_EXPORT WebMediaPlayerMS
blink::WebTimeRanges Seekable() const override;
// Methods for painting.
- void Paint(blink::WebCanvas* canvas,
+ void Paint(cc::PaintCanvas* canvas,
const blink::WebRect& rect,
cc::PaintFlags& flags,
int already_uploaded_id,
@@ -165,6 +166,7 @@ class CONTENT_EXPORT WebMediaPlayerMS
void OnVolumeMultiplierUpdate(double multiplier) override;
void OnBecamePersistentVideo(bool value) override;
void OnPictureInPictureModeEnded() override;
+ void OnPictureInPictureControlClicked(const std::string& control_id) override;
bool CopyVideoTextureToPlatformTexture(
gpu::gles2::GLES2Interface* gl,
diff --git a/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.cc b/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.cc
index 207339b835a..c123ce1f0ec 100644
--- a/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.cc
+++ b/chromium/content/renderer/media/stream/webmediaplayer_ms_compositor.cc
@@ -73,20 +73,21 @@ scoped_refptr<media::VideoFrame> CopyFrame(
const bool result = bitmap.peekPixels(&pixmap);
DCHECK(result) << "Error trying to access SkBitmap's pixels";
- const uint32 source_pixel_format =
+ const uint32_t source_pixel_format =
(kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR
: libyuv::FOURCC_ARGB;
- libyuv::ConvertToI420(
- static_cast<const uint8*>(pixmap.addr(0, 0)), pixmap.computeByteSize(),
- new_frame->visible_data(media::VideoFrame::kYPlane),
- new_frame->stride(media::VideoFrame::kYPlane),
- new_frame->visible_data(media::VideoFrame::kUPlane),
- new_frame->stride(media::VideoFrame::kUPlane),
- new_frame->visible_data(media::VideoFrame::kVPlane),
- new_frame->stride(media::VideoFrame::kVPlane), 0 /* crop_x */,
- 0 /* crop_y */, pixmap.width(), pixmap.height(),
- new_frame->visible_rect().width(), new_frame->visible_rect().height(),
- libyuv::kRotate0, source_pixel_format);
+ libyuv::ConvertToI420(static_cast<const uint8_t*>(pixmap.addr(0, 0)),
+ pixmap.computeByteSize(),
+ new_frame->visible_data(media::VideoFrame::kYPlane),
+ new_frame->stride(media::VideoFrame::kYPlane),
+ new_frame->visible_data(media::VideoFrame::kUPlane),
+ new_frame->stride(media::VideoFrame::kUPlane),
+ new_frame->visible_data(media::VideoFrame::kVPlane),
+ new_frame->stride(media::VideoFrame::kVPlane),
+ 0 /* crop_x */, 0 /* crop_y */, pixmap.width(),
+ pixmap.height(), new_frame->visible_rect().width(),
+ new_frame->visible_rect().height(), libyuv::kRotate0,
+ source_pixel_format);
} else {
DCHECK(frame->IsMappable());
DCHECK(frame->format() == media::PIXEL_FORMAT_I420A ||
@@ -145,7 +146,7 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor(
blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
if (!web_stream.IsNull())
- web_stream.VideoTracks(video_tracks);
+ video_tracks = web_stream.VideoTracks();
const bool remote_video =
video_tracks.size() && video_tracks[0].Source().Remote();
diff --git a/chromium/content/renderer/media/stream/webmediaplayer_ms_unittest.cc b/chromium/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
index 00933375538..5f7235954c0 100644
--- a/chromium/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
+++ b/chromium/content/renderer/media/stream/webmediaplayer_ms_unittest.cc
@@ -514,7 +514,6 @@ class WebMediaPlayerMSTest
void Repaint() override {}
void DurationChanged() override {}
void SizeChanged() override;
- void PlaybackStateChanged() override {}
void SetCcLayer(cc::Layer* layer) override;
blink::WebMediaPlayer::TrackId AddAudioTrack(const blink::WebString& id,
AudioTrackKind,
@@ -545,7 +544,7 @@ class WebMediaPlayerMSTest
void RemotePlaybackCompatibilityChanged(const blink::WebURL& url,
bool is_compatible) override {}
void OnBecamePersistentVideo(bool) override {}
- bool IsAutoplayingMuted() override { return false; }
+ bool WasAlwaysMuted() override { return false; }
bool HasSelectedVideoTrack() override { return false; }
blink::WebMediaPlayer::TrackId GetSelectedVideoTrackId() override {
return blink::WebMediaPlayer::TrackId();
@@ -562,12 +561,17 @@ class WebMediaPlayerMSTest
void MediaRemotingStopped(
blink::WebLocalizedString::Name error_msg) override {}
void PictureInPictureStopped() override {}
+ void PictureInPictureControlClicked(
+ const blink::WebString& control_id) override {}
+ void RequestPlay() override {}
+ void RequestPause() override {}
// Implementation of cc::VideoFrameProvider::Client
void StopUsingProvider() override;
void StartRendering() override;
void StopRendering() override;
void DidReceiveFrame() override;
+ bool IsDrivingFrameUpdates() const override { return true; }
// For test use
void SetBackgroundRendering(bool background_rendering) {
diff --git a/chromium/content/renderer/media/video_capture_impl.cc b/chromium/content/renderer/media/video_capture_impl.cc
index d5c5d8358c0..edf50675310 100644
--- a/chromium/content/renderer/media/video_capture_impl.cc
+++ b/chromium/content/renderer/media/video_capture_impl.cc
@@ -41,6 +41,9 @@ struct VideoCaptureImpl::BufferContext
InitializeFromSharedMemory(
std::move(buffer_handle->get_shared_buffer_handle()));
break;
+ case VideoFrameBufferHandleType::SHARED_MEMORY_VIA_RAW_FILE_DESCRIPTOR:
+ NOTREACHED();
+ break;
case VideoFrameBufferHandleType::MAILBOX_HANDLES:
InitializeFromMailbox(std::move(buffer_handle->get_mailbox_handles()));
break;
@@ -346,6 +349,9 @@ void VideoCaptureImpl::OnBufferReady(int32_t buffer_id,
buffer_context->shared_memory()->handle(),
0 /* shared_memory_offset */, info->timestamp);
break;
+ case VideoFrameBufferHandleType::SHARED_MEMORY_VIA_RAW_FILE_DESCRIPTOR:
+ NOTREACHED();
+ break;
case VideoFrameBufferHandleType::MAILBOX_HANDLES:
gpu::MailboxHolder mailbox_holder_array[media::VideoFrame::kMaxPlanes];
CHECK_EQ(media::VideoFrame::kMaxPlanes,
diff --git a/chromium/content/renderer/media/webrtc/audio_codec_factory.cc b/chromium/content/renderer/media/webrtc/audio_codec_factory.cc
index be2d15aa1c5..73abab19515 100644
--- a/chromium/content/renderer/media/webrtc/audio_codec_factory.cc
+++ b/chromium/content/renderer/media/webrtc/audio_codec_factory.cc
@@ -28,7 +28,7 @@ namespace {
template <typename T>
struct NotAdvertisedEncoder {
using Config = typename T::Config;
- static rtc::Optional<Config> SdpToConfig(
+ static absl::optional<Config> SdpToConfig(
const webrtc::SdpAudioFormat& audio_format) {
return T::SdpToConfig(audio_format);
}
@@ -42,7 +42,7 @@ struct NotAdvertisedEncoder {
static std::unique_ptr<webrtc::AudioEncoder> MakeAudioEncoder(
const Config& config,
int payload_type,
- rtc::Optional<webrtc::AudioCodecPairId> codec_pair_id) {
+ absl::optional<webrtc::AudioCodecPairId> codec_pair_id) {
return T::MakeAudioEncoder(config, payload_type, codec_pair_id);
}
};
@@ -51,7 +51,7 @@ struct NotAdvertisedEncoder {
template <typename T>
struct NotAdvertisedDecoder {
using Config = typename T::Config;
- static rtc::Optional<Config> SdpToConfig(
+ static absl::optional<Config> SdpToConfig(
const webrtc::SdpAudioFormat& audio_format) {
return T::SdpToConfig(audio_format);
}
@@ -61,7 +61,7 @@ struct NotAdvertisedDecoder {
}
static std::unique_ptr<webrtc::AudioDecoder> MakeAudioDecoder(
const Config& config,
- rtc::Optional<webrtc::AudioCodecPairId> codec_pair_id) {
+ absl::optional<webrtc::AudioCodecPairId> codec_pair_id) {
return T::MakeAudioDecoder(config, codec_pair_id);
}
};
diff --git a/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc b/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc
new file mode 100644
index 00000000000..acb9937d405
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc
@@ -0,0 +1,193 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h"
+
+namespace content {
+
+blink::WebMediaStreamTrack CreateWebMediaStreamTrack(const std::string& id) {
+ blink::WebMediaStreamSource web_source;
+ web_source.Initialize(blink::WebString::FromUTF8(id),
+ blink::WebMediaStreamSource::kTypeAudio,
+ blink::WebString::FromUTF8("audio_track"), false);
+ MediaStreamAudioSource* audio_source = new MediaStreamAudioSource(true);
+ // Takes ownership of |audio_source|.
+ web_source.SetExtraData(audio_source);
+
+ blink::WebMediaStreamTrack web_track;
+ web_track.Initialize(web_source.Id(), web_source);
+ audio_source->ConnectToTrack(web_track);
+ return web_track;
+}
+
+FakeRTCRtpSender::FakeRTCRtpSender(base::Optional<std::string> track_id,
+ std::vector<std::string> stream_ids)
+ : track_id_(std::move(track_id)), stream_ids_(std::move(stream_ids)) {}
+
+FakeRTCRtpSender::FakeRTCRtpSender(const FakeRTCRtpSender&) = default;
+
+FakeRTCRtpSender::~FakeRTCRtpSender() {}
+
+FakeRTCRtpSender& FakeRTCRtpSender::operator=(const FakeRTCRtpSender&) =
+ default;
+
+std::unique_ptr<blink::WebRTCRtpSender> FakeRTCRtpSender::ShallowCopy() const {
+ return std::make_unique<FakeRTCRtpSender>(*this);
+}
+
+uintptr_t FakeRTCRtpSender::Id() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+blink::WebMediaStreamTrack FakeRTCRtpSender::Track() const {
+ return track_id_ ? CreateWebMediaStreamTrack(*track_id_)
+ : blink::WebMediaStreamTrack(); // null
+}
+
+blink::WebVector<blink::WebString> FakeRTCRtpSender::StreamIds() const {
+ blink::WebVector<blink::WebString> web_stream_ids(stream_ids_.size());
+ for (size_t i = 0; i < stream_ids_.size(); ++i) {
+ web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids_[i]);
+ }
+ return web_stream_ids;
+}
+
+void FakeRTCRtpSender::ReplaceTrack(blink::WebMediaStreamTrack with_track,
+ blink::WebRTCVoidRequest request) {
+ NOTIMPLEMENTED();
+}
+
+std::unique_ptr<blink::WebRTCDTMFSenderHandler>
+FakeRTCRtpSender::GetDtmfSender() const {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+std::unique_ptr<webrtc::RtpParameters> FakeRTCRtpSender::GetParameters() const {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+void FakeRTCRtpSender::SetParameters(
+ blink::WebVector<webrtc::RtpEncodingParameters>,
+ webrtc::DegradationPreference,
+ blink::WebRTCVoidRequest) {
+ NOTIMPLEMENTED();
+}
+
+void FakeRTCRtpSender::GetStats(
+ std::unique_ptr<blink::WebRTCStatsReportCallback>) {
+ NOTIMPLEMENTED();
+}
+
+FakeRTCRtpReceiver::FakeRTCRtpReceiver(const std::string& track_id,
+ std::vector<std::string> stream_ids)
+ : track_(CreateWebMediaStreamTrack(track_id)),
+ stream_ids_(std::move(stream_ids)) {}
+
+FakeRTCRtpReceiver::FakeRTCRtpReceiver(const FakeRTCRtpReceiver&) = default;
+
+FakeRTCRtpReceiver::~FakeRTCRtpReceiver() {}
+
+FakeRTCRtpReceiver& FakeRTCRtpReceiver::operator=(const FakeRTCRtpReceiver&) =
+ default;
+
+std::unique_ptr<blink::WebRTCRtpReceiver> FakeRTCRtpReceiver::ShallowCopy()
+ const {
+ return std::make_unique<FakeRTCRtpReceiver>(*this);
+}
+
+uintptr_t FakeRTCRtpReceiver::Id() const {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+const blink::WebMediaStreamTrack& FakeRTCRtpReceiver::Track() const {
+ return track_;
+}
+
+blink::WebVector<blink::WebString> FakeRTCRtpReceiver::StreamIds() const {
+ blink::WebVector<blink::WebString> web_stream_ids(stream_ids_.size());
+ for (size_t i = 0; i < stream_ids_.size(); ++i) {
+ web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids_[i]);
+ }
+ return web_stream_ids;
+}
+
+blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
+FakeRTCRtpReceiver::GetSources() {
+ NOTIMPLEMENTED();
+ return {};
+}
+
+void FakeRTCRtpReceiver::GetStats(
+ std::unique_ptr<blink::WebRTCStatsReportCallback>) {
+ NOTIMPLEMENTED();
+}
+
+FakeRTCRtpTransceiver::FakeRTCRtpTransceiver(
+ base::Optional<std::string> mid,
+ FakeRTCRtpSender sender,
+ FakeRTCRtpReceiver receiver,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction)
+ : mid_(std::move(mid)),
+ sender_(std::move(sender)),
+ receiver_(std::move(receiver)),
+ stopped_(stopped),
+ direction_(std::move(direction)),
+ current_direction_(std::move(current_direction)) {}
+
+FakeRTCRtpTransceiver::~FakeRTCRtpTransceiver() {}
+
+blink::WebRTCRtpTransceiverImplementationType
+FakeRTCRtpTransceiver::ImplementationType() const {
+ return blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver;
+}
+
+uintptr_t FakeRTCRtpTransceiver::Id() const {
+ NOTIMPLEMENTED();
+ return 0u;
+}
+
+blink::WebString FakeRTCRtpTransceiver::Mid() const {
+ return mid_ ? blink::WebString::FromUTF8(*mid_) : blink::WebString();
+}
+
+std::unique_ptr<blink::WebRTCRtpSender> FakeRTCRtpTransceiver::Sender() const {
+ return sender_.ShallowCopy();
+}
+
+std::unique_ptr<blink::WebRTCRtpReceiver> FakeRTCRtpTransceiver::Receiver()
+ const {
+ return receiver_.ShallowCopy();
+}
+
+bool FakeRTCRtpTransceiver::Stopped() const {
+ return stopped_;
+}
+
+webrtc::RtpTransceiverDirection FakeRTCRtpTransceiver::Direction() const {
+ return direction_;
+}
+
+void FakeRTCRtpTransceiver::SetDirection(
+ webrtc::RtpTransceiverDirection direction) {
+ NOTIMPLEMENTED();
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+FakeRTCRtpTransceiver::CurrentDirection() const {
+ return current_direction_;
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+FakeRTCRtpTransceiver::FiredDirection() const {
+ NOTIMPLEMENTED();
+ return base::nullopt;
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h b/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h
new file mode 100644
index 00000000000..7f8dbfed61a
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h
@@ -0,0 +1,111 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_FAKE_RTC_RTP_TRANSCEIVER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_FAKE_RTC_RTP_TRANSCEIVER_H_
+
+#include <memory>
+
+#include "content/renderer/media/stream/media_stream_audio_source.h"
+#include "third_party/blink/public/platform/web_media_constraints.h"
+#include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/platform/web_media_stream_track.h"
+#include "third_party/blink/public/platform/web_rtc_dtmf_sender_handler.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_contributing_source.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_sender.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
+
+namespace content {
+
+// TODO(https://crbug.com/868868): Similar methods to this exist in many content
+// unittests. Move to a separate file and reuse it in all of them.
+blink::WebMediaStreamTrack CreateWebMediaStreamTrack(const std::string& id);
+
+class CONTENT_EXPORT FakeRTCRtpSender : public blink::WebRTCRtpSender {
+ public:
+ FakeRTCRtpSender(base::Optional<std::string> track_id,
+ std::vector<std::string> stream_ids);
+ FakeRTCRtpSender(const FakeRTCRtpSender&);
+ ~FakeRTCRtpSender() override;
+ FakeRTCRtpSender& operator=(const FakeRTCRtpSender&);
+
+ std::unique_ptr<blink::WebRTCRtpSender> ShallowCopy() const override;
+ uintptr_t Id() const override;
+ blink::WebMediaStreamTrack Track() const override;
+ blink::WebVector<blink::WebString> StreamIds() const override;
+ void ReplaceTrack(blink::WebMediaStreamTrack with_track,
+ blink::WebRTCVoidRequest request) override;
+ std::unique_ptr<blink::WebRTCDTMFSenderHandler> GetDtmfSender()
+ const override;
+ std::unique_ptr<webrtc::RtpParameters> GetParameters() const override;
+ void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters>,
+ webrtc::DegradationPreference,
+ blink::WebRTCVoidRequest) override;
+ void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>) override;
+
+ private:
+ base::Optional<std::string> track_id_;
+ std::vector<std::string> stream_ids_;
+};
+
+class CONTENT_EXPORT FakeRTCRtpReceiver : public blink::WebRTCRtpReceiver {
+ public:
+ FakeRTCRtpReceiver(const std::string& track_id,
+ std::vector<std::string> stream_ids);
+ FakeRTCRtpReceiver(const FakeRTCRtpReceiver&);
+ ~FakeRTCRtpReceiver() override;
+ FakeRTCRtpReceiver& operator=(const FakeRTCRtpReceiver&);
+
+ std::unique_ptr<blink::WebRTCRtpReceiver> ShallowCopy() const override;
+ uintptr_t Id() const override;
+ const blink::WebMediaStreamTrack& Track() const override;
+ blink::WebVector<blink::WebString> StreamIds() const override;
+ blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
+ GetSources() override;
+ void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>) override;
+
+ private:
+ blink::WebMediaStreamTrack track_;
+ std::vector<std::string> stream_ids_;
+};
+
+class CONTENT_EXPORT FakeRTCRtpTransceiver
+ : public blink::WebRTCRtpTransceiver {
+ public:
+ FakeRTCRtpTransceiver(
+ base::Optional<std::string> mid,
+ FakeRTCRtpSender sender,
+ FakeRTCRtpReceiver receiver,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction);
+ ~FakeRTCRtpTransceiver() override;
+
+ blink::WebRTCRtpTransceiverImplementationType ImplementationType()
+ const override;
+ uintptr_t Id() const override;
+ blink::WebString Mid() const override;
+ std::unique_ptr<blink::WebRTCRtpSender> Sender() const override;
+ std::unique_ptr<blink::WebRTCRtpReceiver> Receiver() const override;
+ bool Stopped() const override;
+ webrtc::RtpTransceiverDirection Direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection direction) override;
+ base::Optional<webrtc::RtpTransceiverDirection> CurrentDirection()
+ const override;
+ base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
+ const override;
+
+ private:
+ base::Optional<std::string> mid_;
+ FakeRTCRtpSender sender_;
+ FakeRTCRtpReceiver receiver_;
+ bool stopped_;
+ webrtc::RtpTransceiverDirection direction_;
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_FAKE_RTC_RTP_TRANSCEIVER_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 eb85960b29c..0e810df0728 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
@@ -71,6 +71,7 @@ class MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate
// Timestamp of the first received frame.
base::TimeDelta start_timestamp_;
+
// WebRTC Chromium timestamp diff
const base::TimeDelta time_diff_;
};
@@ -117,16 +118,16 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
scoped_refptr<media::VideoFrame> video_frame;
scoped_refptr<webrtc::VideoFrameBuffer> buffer(
incoming_frame.video_frame_buffer());
+ const gfx::Size size(buffer->width(), buffer->height());
- if (buffer->type() == webrtc::VideoFrameBuffer::Type::kNative) {
- video_frame = static_cast<WebRtcVideoFrameAdapter*>(buffer.get())
- ->getMediaVideoFrame();
- video_frame->set_timestamp(elapsed_timestamp);
- } else {
- const gfx::Size size(buffer->width(), buffer->height());
- const bool has_alpha =
- buffer->type() == webrtc::VideoFrameBuffer::Type::kI420A;
- if (has_alpha) {
+ switch (buffer->type()) {
+ case webrtc::VideoFrameBuffer::Type::kNative: {
+ video_frame = static_cast<WebRtcVideoFrameAdapter*>(buffer.get())
+ ->getMediaVideoFrame();
+ video_frame->set_timestamp(elapsed_timestamp);
+ break;
+ }
+ case webrtc::VideoFrameBuffer::Type::kI420A: {
const webrtc::I420ABufferInterface* yuva_buffer = buffer->GetI420A();
video_frame = media::VideoFrame::WrapExternalYuvaData(
media::PIXEL_FORMAT_I420A, size, gfx::Rect(size), size,
@@ -136,36 +137,64 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame(
const_cast<uint8_t*>(yuva_buffer->DataU()),
const_cast<uint8_t*>(yuva_buffer->DataV()),
const_cast<uint8_t*>(yuva_buffer->DataA()), 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_I444;
- } else {
- yuv_buffer = buffer->ToI420();
- pixel_format = media::PIXEL_FORMAT_I420;
- }
- // 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.
+ break;
+ }
+ case webrtc::VideoFrameBuffer::Type::kI420: {
+ rtc::scoped_refptr<webrtc::I420BufferInterface> yuv_buffer =
+ buffer->ToI420();
video_frame = media::VideoFrame::WrapExternalYuvData(
- pixel_format, size, gfx::Rect(size), size, yuv_buffer->StrideY(),
- yuv_buffer->StrideU(), yuv_buffer->StrideV(),
+ media::PIXEL_FORMAT_I420, 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);
+ break;
}
- if (!video_frame)
- return;
- // The bind ensures that we keep a reference to the underlying buffer.
- video_frame->AddDestructionObserver(base::BindOnce(&DoNothing, buffer));
+ case webrtc::VideoFrameBuffer::Type::kI444: {
+ webrtc::I444BufferInterface* yuv_buffer = buffer->GetI444();
+ video_frame = media::VideoFrame::WrapExternalYuvData(
+ media::PIXEL_FORMAT_I444, 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);
+ break;
+ }
+ case webrtc::VideoFrameBuffer::Type::kI010: {
+ webrtc::I010BufferInterface* yuv_buffer = buffer->GetI010();
+ // WebRTC defines I010 data as uint16 whereas Chromium uses uint8 for all
+ // video formats, so conversion and cast is needed.
+ video_frame = media::VideoFrame::WrapExternalYuvData(
+ media::PIXEL_FORMAT_YUV420P10, size, gfx::Rect(size), size,
+ yuv_buffer->StrideY() * 2, yuv_buffer->StrideU() * 2,
+ yuv_buffer->StrideV() * 2,
+ const_cast<uint8_t*>(
+ reinterpret_cast<const uint8_t*>(yuv_buffer->DataY())),
+ const_cast<uint8_t*>(
+ reinterpret_cast<const uint8_t*>(yuv_buffer->DataU())),
+ const_cast<uint8_t*>(
+ reinterpret_cast<const uint8_t*>(yuv_buffer->DataV())),
+ elapsed_timestamp);
+ break;
+ }
+ default:
+ NOTREACHED();
}
+
+ if (!video_frame)
+ return;
+
+ // The bind ensures that we keep a reference to the underlying buffer.
+ if (buffer->type() != webrtc::VideoFrameBuffer::Type::kNative)
+ video_frame->AddDestructionObserver(base::BindOnce(&DoNothing, buffer));
+
+ // Rotation may be explicitly set sometimes.
if (incoming_frame.rotation() != webrtc::kVideoRotation_0) {
video_frame->metadata()->SetRotation(
media::VideoFrameMetadata::ROTATION,
WebRTCToMediaVideoRotation(incoming_frame.rotation()));
}
+
// Run render smoothness algorithm only when we don't have to render
// immediately.
if (!render_immediately) {
@@ -235,7 +264,7 @@ void MediaStreamRemoteVideoSource::StopSourceImpl() {
}
rtc::VideoSinkInterface<webrtc::VideoFrame>*
-MediaStreamRemoteVideoSource::SinkInterfaceForTest() {
+MediaStreamRemoteVideoSource::SinkInterfaceForTesting() {
return delegate_.get();
}
diff --git a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.h b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.h
index 494b11b8f45..f07b411c77c 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.h
+++ b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source.h
@@ -24,7 +24,7 @@ class TrackObserver;
// to make sure there is no difference between a video track where the source is
// a local source and a video track where the source is a remote video track.
class CONTENT_EXPORT MediaStreamRemoteVideoSource
- : public MediaStreamVideoSource {
+ : public MediaStreamVideoSource {
public:
explicit MediaStreamRemoteVideoSource(
std::unique_ptr<TrackObserver> observer);
@@ -44,7 +44,7 @@ class CONTENT_EXPORT MediaStreamRemoteVideoSource
// Used by tests to test that a frame can be received and that the
// MediaStreamRemoteVideoSource behaves as expected.
- rtc::VideoSinkInterface<webrtc::VideoFrame>* SinkInterfaceForTest();
+ rtc::VideoSinkInterface<webrtc::VideoFrame>* SinkInterfaceForTesting();
private:
void OnChanged(webrtc::MediaStreamTrackInterface::TrackState state);
diff --git a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
index 34db57bbd4b..e721651a012 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
@@ -36,7 +36,7 @@ class MediaStreamRemoteVideoSourceUnderTest
explicit MediaStreamRemoteVideoSourceUnderTest(
std::unique_ptr<TrackObserver> observer)
: MediaStreamRemoteVideoSource(std::move(observer)) {}
- using MediaStreamRemoteVideoSource::SinkInterfaceForTest;
+ using MediaStreamRemoteVideoSource::SinkInterfaceForTesting;
};
class MediaStreamRemoteVideoSourceTest
@@ -171,7 +171,7 @@ TEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) {
webrtc::I420Buffer::SetBlack(buffer);
- source()->SinkInterfaceForTest()->OnFrame(
+ source()->SinkInterfaceForTesting()->OnFrame(
webrtc::VideoFrame(buffer, webrtc::kVideoRotation_0, 1000));
run_loop.Run();
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 e84c5e83b71..30ea304614b 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc
+++ b/chromium/content/renderer/media/webrtc/media_stream_track_metrics.cc
@@ -5,7 +5,6 @@
#include "content/renderer/media/webrtc/media_stream_track_metrics.h"
#include <inttypes.h>
-#include <set>
#include <string>
#include "base/md5.h"
@@ -14,133 +13,44 @@
#include "content/public/common/service_names.mojom.h"
#include "content/renderer/render_thread_impl.h"
#include "services/service_manager/public/cpp/connector.h"
-#include "third_party/webrtc/api/mediastreaminterface.h"
-
-using webrtc::AudioTrackVector;
-using webrtc::MediaStreamInterface;
-using webrtc::MediaStreamTrackInterface;
-using webrtc::PeerConnectionInterface;
-using webrtc::VideoTrackVector;
namespace content {
-namespace {
-typedef std::set<std::string> IdSet;
-
-template <class T>
-IdSet GetTrackIds(const std::vector<rtc::scoped_refptr<T>>& tracks) {
- IdSet track_ids;
- for (const auto& track : tracks)
- track_ids.insert(track->id());
- return track_ids;
-}
-
-// TODO(tommi): Consolidate this and TrackObserver since these implementations
-// are fundamentally achieving the same thing (aside from specific logic inside
-// the OnChanged callbacks).
-class MediaStreamObserver
- : public base::RefCountedThreadSafe<MediaStreamObserver>,
- public webrtc::ObserverInterface {
- public:
- typedef base::Callback<
- void(const IdSet& audio_track_ids, const IdSet& video_track_ids)>
- OnChangedCallback;
-
- MediaStreamObserver(
- const OnChangedCallback& callback,
- const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
- webrtc::MediaStreamInterface* stream)
- : main_thread_(main_thread), stream_(stream), callback_(callback) {
- signaling_thread_.DetachFromThread();
- stream_->RegisterObserver(this);
- }
-
- const scoped_refptr<webrtc::MediaStreamInterface>& stream() const {
- DCHECK(main_thread_->BelongsToCurrentThread());
- return stream_;
- }
-
- void Unregister() {
- DCHECK(main_thread_->BelongsToCurrentThread());
- callback_.Reset();
- stream_->UnregisterObserver(this);
- stream_ = nullptr;
- }
-
- private:
- friend class base::RefCountedThreadSafe<MediaStreamObserver>;
- ~MediaStreamObserver() override {
- DCHECK(!stream_.get()) << "must have been unregistered before deleting";
- }
-
- // webrtc::ObserverInterface implementation.
- void OnChanged() override {
- DCHECK(signaling_thread_.CalledOnValidThread());
- main_thread_->PostTask(
- FROM_HERE, base::BindOnce(&MediaStreamObserver::OnChangedOnMainThread,
- this, GetTrackIds(stream_->GetAudioTracks()),
- GetTrackIds(stream_->GetVideoTracks())));
- }
-
- void OnChangedOnMainThread(const IdSet& audio_track_ids,
- const IdSet& video_track_ids) {
- DCHECK(main_thread_->BelongsToCurrentThread());
- if (!callback_.is_null())
- callback_.Run(audio_track_ids, video_track_ids);
- }
-
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- scoped_refptr<webrtc::MediaStreamInterface> stream_;
- OnChangedCallback callback_; // Only touched on the main thread.
- base::ThreadChecker signaling_thread_;
-};
-
-} // namespace
class MediaStreamTrackMetricsObserver {
public:
- MediaStreamTrackMetricsObserver(
- MediaStreamTrackMetrics::StreamType stream_type,
- MediaStreamInterface* stream,
- MediaStreamTrackMetrics* owner);
+ MediaStreamTrackMetricsObserver(MediaStreamTrackMetrics::Direction direction,
+ MediaStreamTrackMetrics::Kind kind,
+ std::string track_id,
+ MediaStreamTrackMetrics* owner);
~MediaStreamTrackMetricsObserver();
- // Sends begin/end messages for all tracks currently tracked.
- void SendLifetimeMessages(MediaStreamTrackMetrics::LifetimeEvent event);
+ // Sends begin/end messages for the track if not already reported.
+ void SendLifetimeMessageForTrack(
+ MediaStreamTrackMetrics::LifetimeEvent event);
- MediaStreamInterface* stream() {
+ MediaStreamTrackMetrics::Direction direction() {
DCHECK(thread_checker_.CalledOnValidThread());
- return observer_->stream().get();
+ return direction_;
}
- MediaStreamTrackMetrics::StreamType stream_type() {
+ MediaStreamTrackMetrics::Kind kind() {
DCHECK(thread_checker_.CalledOnValidThread());
- return stream_type_;
+ return kind_;
}
- private:
- void OnChanged(const IdSet& audio_track_ids, const IdSet& video_track_ids);
-
- void ReportAddedAndRemovedTracks(
- const IdSet& new_ids,
- const IdSet& old_ids,
- MediaStreamTrackMetrics::TrackType track_type);
-
- // Sends a lifetime message for the given tracks. OK to call with an
- // empty |ids|, in which case the method has no side effects.
- void ReportTracks(const IdSet& ids,
- MediaStreamTrackMetrics::TrackType track_type,
- MediaStreamTrackMetrics::LifetimeEvent event);
+ std::string track_id() const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ return track_id_;
+ }
+ private:
// False until start/end of lifetime messages have been sent.
bool has_reported_start_;
bool has_reported_end_;
- // IDs of audio and video tracks in the stream being observed.
- IdSet audio_track_ids_;
- IdSet video_track_ids_;
-
- MediaStreamTrackMetrics::StreamType stream_type_;
- scoped_refptr<MediaStreamObserver> observer_;
+ MediaStreamTrackMetrics::Direction direction_;
+ MediaStreamTrackMetrics::Kind kind_;
+ std::string track_id_;
// Non-owning.
MediaStreamTrackMetrics* owner_;
@@ -151,47 +61,46 @@ namespace {
// Used with std::find_if.
struct ObserverFinder {
- ObserverFinder(MediaStreamTrackMetrics::StreamType stream_type,
- MediaStreamInterface* stream)
- : stream_type(stream_type), stream_(stream) {}
+ ObserverFinder(MediaStreamTrackMetrics::Direction direction,
+ MediaStreamTrackMetrics::Kind kind,
+ const std::string& track_id)
+ : direction_(direction), kind_(kind), track_id_(track_id) {}
bool operator()(
const std::unique_ptr<MediaStreamTrackMetricsObserver>& observer) {
- return stream_ == observer->stream() &&
- stream_type == observer->stream_type();
+ return direction_ == observer->direction() && kind_ == observer->kind() &&
+ track_id_ == observer->track_id();
}
- MediaStreamTrackMetrics::StreamType stream_type;
- MediaStreamInterface* stream_;
+ MediaStreamTrackMetrics::Direction direction_;
+ MediaStreamTrackMetrics::Kind kind_;
+ std::string track_id_;
};
} // namespace
MediaStreamTrackMetricsObserver::MediaStreamTrackMetricsObserver(
- MediaStreamTrackMetrics::StreamType stream_type,
- MediaStreamInterface* stream,
+ MediaStreamTrackMetrics::Direction direction,
+ MediaStreamTrackMetrics::Kind kind,
+ std::string track_id,
MediaStreamTrackMetrics* owner)
: has_reported_start_(false),
has_reported_end_(false),
- audio_track_ids_(GetTrackIds(stream->GetAudioTracks())),
- video_track_ids_(GetTrackIds(stream->GetVideoTracks())),
- stream_type_(stream_type),
- observer_(new MediaStreamObserver(
- base::Bind(&MediaStreamTrackMetricsObserver::OnChanged,
- base::Unretained(this)),
- base::ThreadTaskRunnerHandle::Get(),
- stream)),
+ direction_(direction),
+ kind_(kind),
+ track_id_(std::move(track_id)),
owner_(owner) {
+ DCHECK(owner);
}
MediaStreamTrackMetricsObserver::~MediaStreamTrackMetricsObserver() {
DCHECK(thread_checker_.CalledOnValidThread());
- observer_->Unregister();
- SendLifetimeMessages(MediaStreamTrackMetrics::DISCONNECTED);
+ SendLifetimeMessageForTrack(
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected);
}
-void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
+void MediaStreamTrackMetricsObserver::SendLifetimeMessageForTrack(
MediaStreamTrackMetrics::LifetimeEvent event) {
DCHECK(thread_checker_.CalledOnValidThread());
- if (event == MediaStreamTrackMetrics::CONNECTED) {
+ if (event == MediaStreamTrackMetrics::LifetimeEvent::kConnected) {
// Both ICE CONNECTED and COMPLETED can trigger the first
// start-of-life event, so we only report the first.
if (has_reported_start_)
@@ -199,7 +108,7 @@ void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
DCHECK(!has_reported_start_ && !has_reported_end_);
has_reported_start_ = true;
} else {
- DCHECK(event == MediaStreamTrackMetrics::DISCONNECTED);
+ DCHECK(event == MediaStreamTrackMetrics::LifetimeEvent::kDisconnected);
// We only report the first end-of-life event, since there are
// several cases where end-of-life can be reached. We also don't
@@ -209,10 +118,9 @@ void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
has_reported_end_ = true;
}
- ReportTracks(audio_track_ids_, MediaStreamTrackMetrics::AUDIO_TRACK, event);
- ReportTracks(video_track_ids_, MediaStreamTrackMetrics::VIDEO_TRACK, event);
+ owner_->SendLifetimeMessage(track_id_, kind_, event, direction_);
- if (event == MediaStreamTrackMetrics::DISCONNECTED) {
+ if (event == MediaStreamTrackMetrics::LifetimeEvent::kDisconnected) {
// After disconnection, we can get reconnected, so we need to
// forget that we've sent lifetime events, while retaining all
// other state.
@@ -222,76 +130,33 @@ void MediaStreamTrackMetricsObserver::SendLifetimeMessages(
}
}
-void MediaStreamTrackMetricsObserver::OnChanged(
- const IdSet& audio_track_ids, const IdSet& video_track_ids) {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // We only report changes after our initial report, and never after
- // our last report.
- if (has_reported_start_ && !has_reported_end_) {
- ReportAddedAndRemovedTracks(audio_track_ids,
- audio_track_ids_,
- MediaStreamTrackMetrics::AUDIO_TRACK);
- ReportAddedAndRemovedTracks(video_track_ids,
- video_track_ids_,
- MediaStreamTrackMetrics::VIDEO_TRACK);
- }
-
- // We always update our sets of tracks.
- audio_track_ids_ = audio_track_ids;
- video_track_ids_ = video_track_ids;
-}
-
-void MediaStreamTrackMetricsObserver::ReportAddedAndRemovedTracks(
- const IdSet& new_ids,
- const IdSet& old_ids,
- MediaStreamTrackMetrics::TrackType track_type) {
- DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(has_reported_start_ && !has_reported_end_);
-
- IdSet added_tracks = base::STLSetDifference<IdSet>(new_ids, old_ids);
- IdSet removed_tracks = base::STLSetDifference<IdSet>(old_ids, new_ids);
-
- ReportTracks(added_tracks, track_type, MediaStreamTrackMetrics::CONNECTED);
- ReportTracks(
- removed_tracks, track_type, MediaStreamTrackMetrics::DISCONNECTED);
-}
-
-void MediaStreamTrackMetricsObserver::ReportTracks(
- const IdSet& ids,
- MediaStreamTrackMetrics::TrackType track_type,
- MediaStreamTrackMetrics::LifetimeEvent event) {
- DCHECK(thread_checker_.CalledOnValidThread());
- for (IdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) {
- owner_->SendLifetimeMessage(*it, track_type, event, stream_type_);
- }
-}
-
MediaStreamTrackMetrics::MediaStreamTrackMetrics()
: ice_state_(webrtc::PeerConnectionInterface::kIceConnectionNew) {}
MediaStreamTrackMetrics::~MediaStreamTrackMetrics() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
for (const auto& observer : observers_) {
- observer->SendLifetimeMessages(DISCONNECTED);
+ observer->SendLifetimeMessageForTrack(LifetimeEvent::kDisconnected);
}
}
-void MediaStreamTrackMetrics::AddStream(StreamType type,
- MediaStreamInterface* stream) {
+void MediaStreamTrackMetrics::AddTrack(Direction direction,
+ Kind kind,
+ const std::string& track_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- observers_.push_back(
- std::make_unique<MediaStreamTrackMetricsObserver>(type, stream, this));
+ observers_.push_back(std::make_unique<MediaStreamTrackMetricsObserver>(
+ direction, kind, std::move(track_id), this));
SendLifeTimeMessageDependingOnIceState(observers_.back().get());
}
-void MediaStreamTrackMetrics::RemoveStream(StreamType type,
- MediaStreamInterface* stream) {
+void MediaStreamTrackMetrics::RemoveTrack(Direction direction,
+ Kind kind,
+ const std::string& track_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto it = std::find_if(observers_.begin(), observers_.end(),
- ObserverFinder(type, stream));
+ ObserverFinder(direction, kind, track_id));
if (it == observers_.end()) {
- // Since external apps could call removeStream with a stream they
+ // Since external apps could call removeTrack() with a stream they
// never added, this can happen without it being an error.
return;
}
@@ -300,40 +165,41 @@ void MediaStreamTrackMetrics::RemoveStream(StreamType type,
}
void MediaStreamTrackMetrics::IceConnectionChange(
- PeerConnectionInterface::IceConnectionState new_state) {
+ webrtc::PeerConnectionInterface::IceConnectionState new_state) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ice_state_ = new_state;
for (const auto& observer : observers_) {
SendLifeTimeMessageDependingOnIceState(observer.get());
}
}
+
void MediaStreamTrackMetrics::SendLifeTimeMessageDependingOnIceState(
MediaStreamTrackMetricsObserver* observer) {
// There is a state transition diagram for these states at
// http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-RTCIceConnectionState
switch (ice_state_) {
- case PeerConnectionInterface::kIceConnectionConnected:
- case PeerConnectionInterface::kIceConnectionCompleted:
- observer->SendLifetimeMessages(CONNECTED);
+ case webrtc::PeerConnectionInterface::kIceConnectionConnected:
+ case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
+ observer->SendLifetimeMessageForTrack(LifetimeEvent::kConnected);
break;
- case PeerConnectionInterface::kIceConnectionFailed:
- // We don't really need to handle FAILED (it is only supposed
- // to be preceded by CHECKING so we wouldn't yet have sent a
- // lifetime message) but we might as well use belt and
- // suspenders and handle it the same as the other "end call"
- // states. It will be ignored anyway if the call is not
- // already connected.
- case PeerConnectionInterface::kIceConnectionNew:
- // It's a bit weird to count NEW as an end-lifetime event, but
- // it's possible to transition directly from a connected state
- // (CONNECTED or COMPLETED) to NEW, which can then be followed
- // by a new connection. The observer will ignore the end
- // lifetime event if it was not preceded by a begin-lifetime
- // event.
- case PeerConnectionInterface::kIceConnectionDisconnected:
- case PeerConnectionInterface::kIceConnectionClosed:
- observer->SendLifetimeMessages(DISCONNECTED);
+ case webrtc::PeerConnectionInterface::kIceConnectionFailed:
+ // We don't really need to handle FAILED (it is only supposed
+ // to be preceded by CHECKING so we wouldn't yet have sent a
+ // lifetime message) but we might as well use belt and
+ // suspenders and handle it the same as the other "end call"
+ // states. It will be ignored anyway if the call is not
+ // already connected.
+ case webrtc::PeerConnectionInterface::kIceConnectionNew:
+ // It's a bit weird to count NEW as an end-lifetime event, but
+ // it's possible to transition directly from a connected state
+ // (CONNECTED or COMPLETED) to NEW, which can then be followed
+ // by a new connection. The observer will ignore the end
+ // lifetime event if it was not preceded by a begin-lifetime
+ // event.
+ case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
+ case webrtc::PeerConnectionInterface::kIceConnectionClosed:
+ observer->SendLifetimeMessageForTrack(LifetimeEvent::kDisconnected);
break;
default:
@@ -345,28 +211,28 @@ void MediaStreamTrackMetrics::SendLifeTimeMessageDependingOnIceState(
}
void MediaStreamTrackMetrics::SendLifetimeMessage(const std::string& track_id,
- TrackType track_type,
+ Kind kind,
LifetimeEvent event,
- StreamType stream_type) {
+ Direction direction) {
RenderThreadImpl* render_thread = RenderThreadImpl::current();
// |render_thread| can be NULL in certain cases when running as part
// |of a unit test.
if (render_thread) {
- if (event == CONNECTED) {
+ if (event == LifetimeEvent::kConnected) {
GetMediaStreamTrackMetricsHost()->AddTrack(
- MakeUniqueId(track_id, stream_type), track_type == AUDIO_TRACK,
- stream_type == RECEIVED_STREAM);
+ MakeUniqueId(track_id, direction), kind == Kind::kAudio,
+ direction == Direction::kReceive);
} else {
- DCHECK_EQ(DISCONNECTED, event);
+ DCHECK_EQ(LifetimeEvent::kDisconnected, event);
GetMediaStreamTrackMetricsHost()->RemoveTrack(
- MakeUniqueId(track_id, stream_type));
+ MakeUniqueId(track_id, direction));
}
}
}
uint64_t MediaStreamTrackMetrics::MakeUniqueIdImpl(uint64_t pc_id,
const std::string& track_id,
- StreamType stream_type) {
+ Direction direction) {
// We use a hash over the |track| pointer and the PeerConnection ID,
// plus a boolean flag indicating whether the track is remote (since
// you might conceivably have a remote track added back as a sent
@@ -376,10 +242,8 @@ uint64_t MediaStreamTrackMetrics::MakeUniqueIdImpl(uint64_t pc_id,
// no longer be considered), just one with virtually zero chance of
// collisions when faced with non-malicious data.
std::string unique_id_string =
- base::StringPrintf("%" PRIu64 " %s %d",
- pc_id,
- track_id.c_str(),
- stream_type == RECEIVED_STREAM ? 1 : 0);
+ base::StringPrintf("%" PRIu64 " %s %d", pc_id, track_id.c_str(),
+ direction == Direction::kReceive ? 1 : 0);
base::MD5Context ctx;
base::MD5Init(&ctx);
@@ -392,10 +256,10 @@ uint64_t MediaStreamTrackMetrics::MakeUniqueIdImpl(uint64_t pc_id,
}
uint64_t MediaStreamTrackMetrics::MakeUniqueId(const std::string& track_id,
- StreamType stream_type) {
+ Direction direction) {
return MakeUniqueIdImpl(
reinterpret_cast<uint64_t>(reinterpret_cast<void*>(this)), track_id,
- stream_type);
+ direction);
}
mojom::MediaStreamTrackMetricsHostPtr&
diff --git a/chromium/content/renderer/media/webrtc/media_stream_track_metrics.h b/chromium/content/renderer/media/webrtc/media_stream_track_metrics.h
index 779318660ab..addd76a632b 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_track_metrics.h
+++ b/chromium/content/renderer/media/webrtc/media_stream_track_metrics.h
@@ -15,10 +15,6 @@
#include "content/common/media/media_stream.mojom.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
-namespace webrtc {
-class MediaStreamInterface;
-}
-
namespace content {
class MediaStreamTrackMetricsObserver;
@@ -36,19 +32,16 @@ class CONTENT_EXPORT MediaStreamTrackMetrics {
explicit MediaStreamTrackMetrics();
~MediaStreamTrackMetrics();
- enum StreamType { SENT_STREAM, RECEIVED_STREAM };
-
- enum TrackType { AUDIO_TRACK, VIDEO_TRACK };
-
- enum LifetimeEvent { CONNECTED, DISCONNECTED };
+ enum class Direction { kSend, kReceive };
+ enum class Kind { kAudio, kVideo };
+ enum class LifetimeEvent { kConnected, kDisconnected };
- // Starts tracking lifetimes of all the tracks in |stream| and any
- // tracks added or removed to/from the stream until |RemoveStream|
- // is called or this object's lifetime ends.
- void AddStream(StreamType type, webrtc::MediaStreamInterface* stream);
+ // Starts tracking the lifetime of the track until |RemoveTrack| is called
+ // or this object's lifetime ends.
+ void AddTrack(Direction direction, Kind kind, const std::string& track_id);
- // Stops tracking lifetimes of tracks in |stream|.
- void RemoveStream(StreamType type, webrtc::MediaStreamInterface* stream);
+ // Stops tracking the lifetime of the track.
+ void RemoveTrack(Direction direction, Kind kind, const std::string& track_id);
// Called to indicate changes in the ICE connection state for the
// PeerConnection this object is associated with. Used to generate
@@ -71,9 +64,9 @@ class CONTENT_EXPORT MediaStreamTrackMetrics {
// PeerConnection), false for local streams (sent over a
// PeerConnection).
virtual void SendLifetimeMessage(const std::string& track_id,
- TrackType track_type,
+ Kind kind,
LifetimeEvent lifetime_event,
- StreamType stream_type);
+ Direction direction);
protected:
// Calls SendLifetimeMessage for |observer| depending on |ice_state_|.
@@ -86,12 +79,12 @@ class CONTENT_EXPORT MediaStreamTrackMetrics {
// is a one-to-one relationship).
uint64_t MakeUniqueIdImpl(uint64_t pc_id,
const std::string& track,
- StreamType stream_type);
+ Direction direction);
private:
// Make a unique ID for the given track, that is valid while the
// track object and the PeerConnection it is attached to both exist.
- uint64_t MakeUniqueId(const std::string& track, StreamType stream_type);
+ uint64_t MakeUniqueId(const std::string& track_id, Direction direction);
mojom::MediaStreamTrackMetricsHostPtr& GetMediaStreamTrackMetricsHost();
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 d8819aa62a5..4fb4ff31bc0 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
@@ -78,8 +78,7 @@ class MockMediaStreamTrackMetrics : public MediaStreamTrackMetrics {
virtual ~MockMediaStreamTrackMetrics() {}
MOCK_METHOD4(SendLifetimeMessage,
- void(const std::string&, TrackType, LifetimeEvent, StreamType));
-
+ void(const std::string&, Kind, LifetimeEvent, Direction));
using MediaStreamTrackMetrics::MakeUniqueIdImpl;
};
@@ -170,88 +169,82 @@ TEST_F(MediaStreamTrackMetricsTest, MakeUniqueId) {
// Lower 32 bits the same, upper 32 differ.
EXPECT_NE(
- metrics_->MakeUniqueIdImpl(
- 0x1000000000000001, "x", MediaStreamTrackMetrics::RECEIVED_STREAM),
- metrics_->MakeUniqueIdImpl(
- 0x2000000000000001, "x", MediaStreamTrackMetrics::RECEIVED_STREAM));
+ metrics_->MakeUniqueIdImpl(0x1000000000000001, "x",
+ MediaStreamTrackMetrics::Direction::kReceive),
+ metrics_->MakeUniqueIdImpl(0x2000000000000001, "x",
+ MediaStreamTrackMetrics::Direction::kReceive));
// Track ID differs.
EXPECT_NE(metrics_->MakeUniqueIdImpl(
- 42, "x", MediaStreamTrackMetrics::RECEIVED_STREAM),
+ 42, "x", MediaStreamTrackMetrics::Direction::kReceive),
metrics_->MakeUniqueIdImpl(
- 42, "y", MediaStreamTrackMetrics::RECEIVED_STREAM));
+ 42, "y", MediaStreamTrackMetrics::Direction::kReceive));
// Remove vs. local track differs.
EXPECT_NE(metrics_->MakeUniqueIdImpl(
- 42, "x", MediaStreamTrackMetrics::RECEIVED_STREAM),
+ 42, "x", MediaStreamTrackMetrics::Direction::kReceive),
metrics_->MakeUniqueIdImpl(
- 42, "x", MediaStreamTrackMetrics::SENT_STREAM));
+ 42, "x", MediaStreamTrackMetrics::Direction::kSend));
}
TEST_F(MediaStreamTrackMetricsTest, BasicRemoteStreams) {
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
- stream_->AddTrack(audio.get());
- stream_->AddTrack(video.get());
- metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionDisconnected);
}
TEST_F(MediaStreamTrackMetricsTest, BasicLocalStreams) {
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
- stream_->AddTrack(audio.get());
- stream_->AddTrack(video.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
}
@@ -259,341 +252,226 @@ TEST_F(MediaStreamTrackMetricsTest, LocalStreamAddedAferIceConnect) {
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
-
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
- stream_->AddTrack(audio.get());
- stream_->AddTrack(video.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamAddedAferIceConnect) {
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
-
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
- stream_->AddTrack(audio.get());
- stream_->AddTrack(video.get());
- metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
-}
-
-TEST_F(MediaStreamTrackMetricsTest, RemoteStreamTrackAdded) {
- scoped_refptr<MockAudioTrackInterface> initial(MakeAudioTrack("initial"));
- scoped_refptr<MockAudioTrackInterface> added(MakeAudioTrack("added"));
- stream_->AddTrack(initial.get());
- metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("initial",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- metrics_->IceConnectionChange(
- PeerConnectionInterface::kIceConnectionConnected);
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("added",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- AddAudioTrack(added.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("initial",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("added",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
- metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
+
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
}
TEST_F(MediaStreamTrackMetricsTest, LocalStreamTrackRemoved) {
- scoped_refptr<MockAudioTrackInterface> first(MakeAudioTrack("first"));
- scoped_refptr<MockAudioTrackInterface> second(MakeAudioTrack("second"));
- stream_->AddTrack(first.get());
- stream_->AddTrack(second.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("first",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("second",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "first");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "second");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "first", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "second", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("first",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- stream_->RemoveTrack(first.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("second",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("first", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "first");
+
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("second", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
}
-TEST_F(MediaStreamTrackMetricsTest, LocalStreamModificationsBeforeAndAfter) {
- scoped_refptr<MockAudioTrackInterface> first(MakeAudioTrack("first"));
- scoped_refptr<MockAudioTrackInterface> second(MakeAudioTrack("second"));
- stream_->AddTrack(first.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
-
- // This gets added after we start observing, but no lifetime message
- // should be sent at this point since the call is not connected. It
- // should get sent only once it gets connected.
- AddAudioTrack(second.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("first",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("second",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+TEST_F(MediaStreamTrackMetricsTest, RemoveAfterDisconnect) {
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("first",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("second",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
// This happens after the call is disconnected so no lifetime
// message should be sent.
- RemoveAudioTrack(first.get());
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamMultipleDisconnects) {
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- stream_->AddTrack(audio.get());
- metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionDisconnected);
metrics_->IceConnectionChange(PeerConnectionInterface::kIceConnectionFailed);
- RemoveAudioTrack(audio.get());
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
}
TEST_F(MediaStreamTrackMetricsTest, RemoteStreamConnectDisconnectTwice) {
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- stream_->AddTrack(audio.get());
- metrics_->AddStream(MediaStreamTrackMetrics::RECEIVED_STREAM, stream_.get());
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
for (size_t i = 0; i < 2; ++i) {
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::RECEIVED_STREAM));
+ SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kReceive));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionDisconnected);
}
- RemoveAudioTrack(audio.get());
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
}
TEST_F(MediaStreamTrackMetricsTest, LocalStreamRemovedNoDisconnect) {
- scoped_refptr<MockAudioTrackInterface> audio(MakeAudioTrack("audio"));
- scoped_refptr<MockVideoTrackInterface> video(MakeVideoTrack("video"));
- stream_->AddTrack(audio.get());
- stream_->AddTrack(video.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- metrics_->RemoveStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
}
TEST_F(MediaStreamTrackMetricsTest, LocalStreamLargerTest) {
- scoped_refptr<MockAudioTrackInterface> audio1(MakeAudioTrack("audio1"));
- scoped_refptr<MockAudioTrackInterface> audio2(MakeAudioTrack("audio2"));
- scoped_refptr<MockAudioTrackInterface> audio3(MakeAudioTrack("audio3"));
- scoped_refptr<MockVideoTrackInterface> video1(MakeVideoTrack("video1"));
- scoped_refptr<MockVideoTrackInterface> video2(MakeVideoTrack("video2"));
- scoped_refptr<MockVideoTrackInterface> video3(MakeVideoTrack("video3"));
- stream_->AddTrack(audio1.get());
- stream_->AddTrack(video1.get());
- metrics_->AddStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio1",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video1",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
+
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
metrics_->IceConnectionChange(
PeerConnectionInterface::kIceConnectionConnected);
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio2",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- AddAudioTrack(audio2.get());
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video2",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- AddVideoTrack(video2.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio1",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- RemoveAudioTrack(audio1.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio3",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- AddAudioTrack(audio3.get());
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video3",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- AddVideoTrack(video3.get());
-
- // Add back audio1
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio1",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::CONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- AddAudioTrack(audio1.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio2",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- RemoveAudioTrack(audio2.get());
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video2",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- RemoveVideoTrack(video2.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio1",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- RemoveAudioTrack(audio1.get());
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video1",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- RemoveVideoTrack(video1.get());
-
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("audio3",
- MediaStreamTrackMetrics::AUDIO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- EXPECT_CALL(*metrics_,
- SendLifetimeMessage("video3",
- MediaStreamTrackMetrics::VIDEO_TRACK,
- MediaStreamTrackMetrics::DISCONNECTED,
- MediaStreamTrackMetrics::SENT_STREAM));
- metrics_->RemoveStream(MediaStreamTrackMetrics::SENT_STREAM, stream_.get());
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+
+ // Add back audio
+ EXPECT_CALL(*metrics_, SendLifetimeMessage(
+ "audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kConnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("audio", MediaStreamTrackMetrics::Kind::kAudio,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kAudio, "audio");
+ EXPECT_CALL(
+ *metrics_,
+ SendLifetimeMessage("video", MediaStreamTrackMetrics::Kind::kVideo,
+ MediaStreamTrackMetrics::LifetimeEvent::kDisconnected,
+ MediaStreamTrackMetrics::Direction::kSend));
+ metrics_->RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetrics::Kind::kVideo, "video");
}
} // namespace content
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 be896490fc6..837f67cfe22 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
@@ -28,8 +28,8 @@ namespace content {
namespace {
-rtc::Optional<bool> ToRtcOptionalBool(const base::Optional<bool>& value) {
- return value ? rtc::Optional<bool>(*value) : rtc::Optional<bool>();
+absl::optional<bool> ToAbslOptionalBool(const base::Optional<bool>& value) {
+ return value ? absl::optional<bool>(*value) : absl::nullopt;
}
} // namespace
@@ -39,8 +39,8 @@ class MediaStreamVideoWebRtcSink::WebRtcVideoSource
public:
WebRtcVideoSource(WebRtcVideoCapturerAdapter* capture_adapter,
bool is_screencast,
- rtc::Optional<bool> needs_denoising)
- : VideoTrackSource(capture_adapter, false),
+ absl::optional<bool> needs_denoising)
+ : VideoTrackSource(false),
capture_adapter_(capture_adapter),
is_screencast_(is_screencast),
needs_denoising_(needs_denoising) {}
@@ -50,14 +50,19 @@ class MediaStreamVideoWebRtcSink::WebRtcVideoSource
}
bool is_screencast() const override { return is_screencast_; }
- rtc::Optional<bool> needs_denoising() const override {
+ absl::optional<bool> needs_denoising() const override {
return needs_denoising_;
}
+ protected:
+ rtc::VideoSourceInterface<webrtc::VideoFrame>* source() override {
+ return capture_adapter_.get();
+ }
+
private:
std::unique_ptr<WebRtcVideoCapturerAdapter> const capture_adapter_;
const bool is_screencast_;
- const rtc::Optional<bool> needs_denoising_;
+ const absl::optional<bool> needs_denoising_;
};
namespace {
@@ -84,6 +89,8 @@ webrtc::VideoTrackInterface::ContentHint ContentHintTypeToWebRtcContentHint(
return webrtc::VideoTrackInterface::ContentHint::kFluid;
case blink::WebMediaStreamTrack::ContentHintType::kVideoDetail:
return webrtc::VideoTrackInterface::ContentHint::kDetailed;
+ case blink::WebMediaStreamTrack::ContentHintType::kVideoText:
+ return webrtc::VideoTrackInterface::ContentHint::kText;
}
NOTREACHED();
return webrtc::VideoTrackInterface::ContentHint::kNone;
@@ -269,8 +276,8 @@ MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink(
MediaStreamVideoTrack::GetVideoTrack(track);
DCHECK(video_track);
- rtc::Optional<bool> needs_denoising =
- ToRtcOptionalBool(video_track->noise_reduction());
+ absl::optional<bool> needs_denoising =
+ ToAbslOptionalBool(video_track->noise_reduction());
bool is_screencast = video_track->is_screencast();
base::Optional<double> min_frame_rate = video_track->min_frame_rate();
@@ -364,8 +371,8 @@ void MediaStreamVideoWebRtcSink::RequestRefreshFrame() {
content::RequestRefreshFrameFromVideoTrack(connected_track());
}
-rtc::Optional<bool> MediaStreamVideoWebRtcSink::SourceNeedsDenoisingForTesting()
- const {
+absl::optional<bool>
+MediaStreamVideoWebRtcSink::SourceNeedsDenoisingForTesting() const {
return video_source_->needs_denoising();
}
diff --git a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
index 8ff0331d038..d8039286fa8 100644
--- a/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
+++ b/chromium/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
@@ -43,7 +43,7 @@ class CONTENT_EXPORT MediaStreamVideoWebRtcSink : public MediaStreamVideoSink {
return video_track_.get();
}
- rtc::Optional<bool> SourceNeedsDenoisingForTesting() const;
+ absl::optional<bool> SourceNeedsDenoisingForTesting() const;
protected:
// Implementation of MediaStreamSink.
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 5265f9477fb..d33db26d3c6 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
@@ -25,8 +25,8 @@ class MediaStreamVideoWebRtcSinkTest : public ::testing::Test {
void SetVideoTrack() {
registry_.Init("stream URL");
registry_.AddVideoTrack("test video track");
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- registry_.test_stream().VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ registry_.test_stream().VideoTracks();
track_ = video_tracks[0];
// TODO(hta): Verify that track_ is valid. When constraints produce
// no valid format, using the track will cause a crash.
@@ -36,8 +36,8 @@ class MediaStreamVideoWebRtcSinkTest : public ::testing::Test {
registry_.Init("stream URL");
registry_.AddVideoTrack("test video track", VideoTrackAdapterSettings(),
noise_reduction, false, 0.0);
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- registry_.test_stream().VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ registry_.test_stream().VideoTracks();
track_ = video_tracks[0];
// TODO(hta): Verify that track_ is valid. When constraints produce
// no valid format, using the track will cause a crash.
diff --git a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc
index ebc81901bd4..ee019112cb9 100644
--- a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc
+++ b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.cc
@@ -9,8 +9,10 @@
#include <vector>
#include "base/logging.h"
+#include "base/stl_util.h"
#include "content/renderer/media/webrtc/mock_data_channel_impl.h"
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
+#include "content/renderer/media/webrtc/webrtc_util.h"
#include "third_party/webrtc/api/rtpreceiverinterface.h"
#include "third_party/webrtc/rtc_base/refcountedobject.h"
@@ -58,19 +60,6 @@ class MockStreamCollection : public webrtc::StreamCollectionInterface {
}
return nullptr;
}
- std::vector<webrtc::MediaStreamInterface*> FindStreamsOfTrack(
- webrtc::MediaStreamTrackInterface* track) {
- std::vector<webrtc::MediaStreamInterface*> streams_of_track;
- if (!track)
- return streams_of_track;
- for (size_t i = 0; i < streams_.size(); ++i) {
- if (streams_.at(i)->FindAudioTrack(track->id()) ||
- streams_.at(i)->FindVideoTrack(track->id())) {
- streams_of_track.push_back(streams_.at(i));
- }
- }
- return streams_of_track;
- }
void AddStream(MediaStreamInterface* stream) {
streams_.push_back(stream);
}
@@ -95,8 +84,6 @@ class MockStreamCollection : public webrtc::StreamCollectionInterface {
class MockDtmfSender : public DtmfSenderInterface {
public:
- explicit MockDtmfSender(AudioTrackInterface* track)
- : track_(track), observer_(nullptr), duration_(0), inter_tone_gap_(0) {}
void RegisterObserver(DtmfSenderObserverInterface* observer) override {
observer_ = observer;
}
@@ -110,25 +97,21 @@ class MockDtmfSender : public DtmfSenderInterface {
inter_tone_gap_ = inter_tone_gap;
return true;
}
- const AudioTrackInterface* track() const override { return track_.get(); }
std::string tones() const override { return tones_; }
int duration() const override { return duration_; }
int inter_tone_gap() const override { return inter_tone_gap_; }
- protected:
- ~MockDtmfSender() override {}
-
private:
- rtc::scoped_refptr<AudioTrackInterface> track_;
- DtmfSenderObserverInterface* observer_;
+ DtmfSenderObserverInterface* observer_ = nullptr;
std::string tones_;
- int duration_;
- int inter_tone_gap_;
+ int duration_ = 0;
+ int inter_tone_gap_ = 0;
};
FakeRtpSender::FakeRtpSender(
- rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track)
- : track_(std::move(track)) {}
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ std::vector<std::string> stream_ids)
+ : track_(std::move(track)), stream_ids_(std::move(stream_ids)) {}
FakeRtpSender::~FakeRtpSender() {}
@@ -158,11 +141,10 @@ std::string FakeRtpSender::id() const {
}
std::vector<std::string> FakeRtpSender::stream_ids() const {
- NOTIMPLEMENTED();
- return {};
+ return stream_ids_;
}
-webrtc::RtpParameters FakeRtpSender::GetParameters() const {
+webrtc::RtpParameters FakeRtpSender::GetParameters() {
NOTIMPLEMENTED();
return webrtc::RtpParameters();
}
@@ -175,8 +157,7 @@ webrtc::RTCError FakeRtpSender::SetParameters(
rtc::scoped_refptr<webrtc::DtmfSenderInterface> FakeRtpSender::GetDtmfSender()
const {
- NOTIMPLEMENTED();
- return nullptr;
+ return new rtc::RefCountedObject<MockDtmfSender>();
}
FakeRtpReceiver::FakeRtpReceiver(
@@ -226,6 +207,69 @@ std::vector<webrtc::RtpSource> FakeRtpReceiver::GetSources() const {
return std::vector<webrtc::RtpSource>();
}
+FakeRtpTransceiver::FakeRtpTransceiver(
+ cricket::MediaType media_type,
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender,
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+ base::Optional<std::string> mid,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction)
+ : media_type_(media_type),
+ sender_(std::move(sender)),
+ receiver_(std::move(receiver)),
+ mid_(ToAbslOptional(mid)),
+ stopped_(stopped),
+ direction_(direction),
+ current_direction_(ToAbslOptional(current_direction)) {}
+
+FakeRtpTransceiver::~FakeRtpTransceiver() {}
+
+cricket::MediaType FakeRtpTransceiver::media_type() const {
+ return media_type_;
+}
+
+absl::optional<std::string> FakeRtpTransceiver::mid() const {
+ return mid_;
+}
+
+rtc::scoped_refptr<webrtc::RtpSenderInterface> FakeRtpTransceiver::sender()
+ const {
+ return sender_;
+}
+
+rtc::scoped_refptr<webrtc::RtpReceiverInterface> FakeRtpTransceiver::receiver()
+ const {
+ return receiver_;
+}
+
+bool FakeRtpTransceiver::stopped() const {
+ return stopped_;
+}
+
+webrtc::RtpTransceiverDirection FakeRtpTransceiver::direction() const {
+ return direction_;
+}
+
+void FakeRtpTransceiver::SetDirection(
+ webrtc::RtpTransceiverDirection new_direction) {
+ NOTIMPLEMENTED();
+}
+
+absl::optional<webrtc::RtpTransceiverDirection>
+FakeRtpTransceiver::current_direction() const {
+ return current_direction_;
+}
+
+void FakeRtpTransceiver::Stop() {
+ NOTIMPLEMENTED();
+}
+
+void FakeRtpTransceiver::SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) {
+ NOTIMPLEMENTED();
+}
+
const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer";
const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer";
@@ -233,7 +277,6 @@ MockPeerConnectionImpl::MockPeerConnectionImpl(
MockPeerConnectionDependencyFactory* factory,
webrtc::PeerConnectionObserver* observer)
: dependency_factory_(factory),
- local_streams_(new rtc::RefCountedObject<MockStreamCollection>),
remote_streams_(new rtc::RefCountedObject<MockStreamCollection>),
hint_audio_(false),
hint_video_(false),
@@ -257,73 +300,42 @@ MockPeerConnectionImpl::MockPeerConnectionImpl(
MockPeerConnectionImpl::~MockPeerConnectionImpl() {}
-rtc::scoped_refptr<webrtc::StreamCollectionInterface>
-MockPeerConnectionImpl::local_streams() {
- return local_streams_;
-}
-
-rtc::scoped_refptr<webrtc::StreamCollectionInterface>
-MockPeerConnectionImpl::remote_streams() {
- return remote_streams_;
-}
-
-rtc::scoped_refptr<webrtc::RtpSenderInterface> MockPeerConnectionImpl::AddTrack(
- webrtc::MediaStreamTrackInterface* track,
- std::vector<webrtc::MediaStreamInterface*> streams) {
+webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>>
+MockPeerConnectionImpl::AddTrack(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ const std::vector<std::string>& stream_ids) {
DCHECK(track);
- DCHECK_EQ(1u, streams.size());
+ DCHECK_EQ(1u, stream_ids.size());
for (const auto& sender : senders_) {
if (sender->track() == track)
- return nullptr;
+ return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER);
}
- for (auto* stream : streams) {
- if (!local_streams_->find(stream->id())) {
- stream_label_ = stream->id();
- local_streams_->AddStream(stream);
+ for (const auto& stream_id : stream_ids) {
+ if (!base::ContainsValue(local_stream_ids_, stream_id)) {
+ stream_label_ = stream_id;
+ local_stream_ids_.push_back(stream_id);
}
}
- auto* sender = new rtc::RefCountedObject<FakeRtpSender>(track);
+ auto* sender = new rtc::RefCountedObject<FakeRtpSender>(track, stream_ids);
senders_.push_back(sender);
- return sender;
+ return rtc::scoped_refptr<webrtc::RtpSenderInterface>(sender);
}
-bool MockPeerConnectionImpl::RemoveTrack(webrtc::RtpSenderInterface* sender) {
- auto it = std::find(senders_.begin(), senders_.end(),
- static_cast<FakeRtpSender*>(sender));
+bool MockPeerConnectionImpl::RemoveTrack(webrtc::RtpSenderInterface* s) {
+ rtc::scoped_refptr<FakeRtpSender> sender = static_cast<FakeRtpSender*>(s);
+ auto it = std::find(senders_.begin(), senders_.end(), sender);
if (it == senders_.end())
return false;
senders_.erase(it);
auto track = sender->track();
- for (auto* stream : local_streams_->FindStreamsOfTrack(track)) {
- bool stream_has_senders = false;
- for (const auto& track : stream->GetAudioTracks()) {
- for (const auto& sender : senders_) {
- if (sender->track() == track) {
- stream_has_senders = true;
- break;
- }
- }
- }
- for (const auto& track : stream->GetVideoTracks()) {
- for (const auto& sender : senders_) {
- if (sender->track() == track) {
- stream_has_senders = true;
- break;
- }
- }
- }
- if (!stream_has_senders)
- local_streams_->RemoveStream(stream);
- }
- return true;
-}
-rtc::scoped_refptr<DtmfSenderInterface>
-MockPeerConnectionImpl::CreateDtmfSender(AudioTrackInterface* track) {
- if (!track) {
- return nullptr;
+ for (const auto& stream_id : sender->stream_ids()) {
+ auto local_stream_it = std::find(local_stream_ids_.begin(),
+ local_stream_ids_.end(), stream_id);
+ if (local_stream_it != local_stream_ids_.end())
+ local_stream_ids_.erase(local_stream_it);
}
- return new rtc::RefCountedObject<MockDtmfSender>(track);
+ return true;
}
std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>>
@@ -477,11 +489,6 @@ bool MockPeerConnectionImpl::AddIceCandidate(
return candidate->ToString(&ice_sdp_);
}
-void MockPeerConnectionImpl::RegisterUMAObserver(
- webrtc::UMAObserver* observer) {
- NOTIMPLEMENTED();
-}
-
webrtc::RTCError MockPeerConnectionImpl::SetBitrate(
const webrtc::BitrateSettings& bitrate) {
NOTIMPLEMENTED();
diff --git a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h
index da06e71438e..5d348e74b72 100644
--- a/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h
+++ b/chromium/content/renderer/media/webrtc/mock_peer_connection_impl.h
@@ -11,6 +11,7 @@
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/optional.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
#include "third_party/webrtc/api/stats/rtcstatsreport.h"
@@ -22,7 +23,8 @@ class MockStreamCollection;
class FakeRtpSender : public webrtc::RtpSenderInterface {
public:
- FakeRtpSender(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track);
+ FakeRtpSender(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ std::vector<std::string> stream_ids);
~FakeRtpSender() override;
bool SetTrack(webrtc::MediaStreamTrackInterface* track) override;
@@ -31,7 +33,7 @@ class FakeRtpSender : public webrtc::RtpSenderInterface {
cricket::MediaType media_type() const override;
std::string id() const override;
std::vector<std::string> stream_ids() const override;
- webrtc::RtpParameters GetParameters() const override;
+ webrtc::RtpParameters GetParameters() override;
webrtc::RTCError SetParameters(
const webrtc::RtpParameters& parameters) override;
rtc::scoped_refptr<webrtc::DtmfSenderInterface> GetDtmfSender()
@@ -39,6 +41,7 @@ class FakeRtpSender : public webrtc::RtpSenderInterface {
private:
rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track_;
+ std::vector<std::string> stream_ids_;
};
class FakeRtpReceiver : public webrtc::RtpReceiverInterface {
@@ -63,6 +66,43 @@ class FakeRtpReceiver : public webrtc::RtpReceiverInterface {
std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams_;
};
+class FakeRtpTransceiver : public webrtc::RtpTransceiverInterface {
+ public:
+ FakeRtpTransceiver(
+ cricket::MediaType media_type,
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender,
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+ base::Optional<std::string> mid,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction);
+ ~FakeRtpTransceiver() override;
+
+ FakeRtpTransceiver& operator=(const FakeRtpTransceiver& other) = default;
+
+ cricket::MediaType media_type() const override;
+ absl::optional<std::string> mid() const override;
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender() const override;
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver() const override;
+ bool stopped() const override;
+ webrtc::RtpTransceiverDirection direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection new_direction) override;
+ absl::optional<webrtc::RtpTransceiverDirection> current_direction()
+ const override;
+ void Stop() override;
+ void SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override;
+
+ private:
+ cricket::MediaType media_type_;
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender_;
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver_;
+ absl::optional<std::string> mid_;
+ bool stopped_;
+ webrtc::RtpTransceiverDirection direction_;
+ absl::optional<webrtc::RtpTransceiverDirection> current_direction_;
+};
+
// TODO(hbos): The use of fakes and mocks is the wrong approach for testing of
// this. It introduces complexity, is error prone (not testing the right thing
// and bugs in the mocks). This class is a maintenance burden and should be
@@ -73,10 +113,16 @@ class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface {
webrtc::PeerConnectionObserver* observer);
// PeerConnectionInterface implementation.
- rtc::scoped_refptr<webrtc::StreamCollectionInterface>
- local_streams() override;
- rtc::scoped_refptr<webrtc::StreamCollectionInterface>
- remote_streams() override;
+ rtc::scoped_refptr<webrtc::StreamCollectionInterface> local_streams()
+ override {
+ NOTIMPLEMENTED();
+ return nullptr;
+ }
+ rtc::scoped_refptr<webrtc::StreamCollectionInterface> remote_streams()
+ override {
+ NOTIMPLEMENTED();
+ return nullptr;
+ }
bool AddStream(webrtc::MediaStreamInterface* local_stream) override {
NOTIMPLEMENTED();
return false;
@@ -84,14 +130,10 @@ class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface {
void RemoveStream(webrtc::MediaStreamInterface* local_stream) override {
NOTIMPLEMENTED();
}
- // TODO(hbos): Use AddTrack() taking stream labels instead of stream pointers.
- // https://crbug.com/810708
- rtc::scoped_refptr<webrtc::RtpSenderInterface> AddTrack(
- webrtc::MediaStreamTrackInterface* track,
- std::vector<webrtc::MediaStreamInterface*> streams) override;
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> AddTrack(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ const std::vector<std::string>& stream_ids) override;
bool RemoveTrack(webrtc::RtpSenderInterface* sender) override;
- rtc::scoped_refptr<webrtc::DtmfSenderInterface>
- CreateDtmfSender(webrtc::AudioTrackInterface* track) override;
std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> GetSenders()
const override;
std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> GetReceivers()
@@ -174,7 +216,6 @@ class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface {
bool SetConfiguration(const RTCConfiguration& configuration,
webrtc::RTCError* error) override;
bool AddIceCandidate(const webrtc::IceCandidateInterface* candidate) override;
- void RegisterUMAObserver(webrtc::UMAObserver* observer) override;
webrtc::RTCError SetBitrate(const webrtc::BitrateSettings& bitrate) override;
@@ -207,7 +248,7 @@ class MockPeerConnectionImpl : public webrtc::PeerConnectionInterface {
MockPeerConnectionDependencyFactory* dependency_factory_;
std::string stream_label_;
- rtc::scoped_refptr<MockStreamCollection> local_streams_;
+ std::vector<std::string> local_stream_ids_;
rtc::scoped_refptr<MockStreamCollection> remote_streams_;
std::vector<rtc::scoped_refptr<FakeRtpSender>> senders_;
std::unique_ptr<webrtc::SessionDescriptionInterface> local_desc_;
diff --git a/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc b/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc
index 6d8afca21d7..a1ec79ef9f7 100644
--- a/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc
+++ b/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc
@@ -20,14 +20,13 @@ MockWebRTCPeerConnectionHandlerClient()
.WillByDefault(
testing::Invoke(this, &MockWebRTCPeerConnectionHandlerClient::
didGenerateICECandidateWorker));
- ON_CALL(*this, DidAddRemoteTrackForMock(_))
+ ON_CALL(*this, DidAddReceiverPlanBForMock(_))
.WillByDefault(testing::Invoke(
- this,
- &MockWebRTCPeerConnectionHandlerClient::didAddRemoteTrackWorker));
- ON_CALL(*this, DidRemoveRemoteTrackForMock(_))
+ this, &MockWebRTCPeerConnectionHandlerClient::didAddReceiverWorker));
+ ON_CALL(*this, DidRemoveReceiverPlanBForMock(_))
.WillByDefault(testing::Invoke(
this,
- &MockWebRTCPeerConnectionHandlerClient::didRemoveRemoteTrackWorker));
+ &MockWebRTCPeerConnectionHandlerClient::didRemoveReceiverWorker));
}
MockWebRTCPeerConnectionHandlerClient::
@@ -40,17 +39,17 @@ void MockWebRTCPeerConnectionHandlerClient::didGenerateICECandidateWorker(
candidate_mid_ = candidate->SdpMid().Utf8();
}
-void MockWebRTCPeerConnectionHandlerClient::didAddRemoteTrackWorker(
+void MockWebRTCPeerConnectionHandlerClient::didAddReceiverWorker(
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];
+ blink::WebVector<blink::WebString> stream_ids =
+ (*web_rtp_receiver)->StreamIds();
+ DCHECK_EQ(1u, stream_ids.size());
+ remote_stream_id_ = stream_ids[0];
}
-void MockWebRTCPeerConnectionHandlerClient::didRemoveRemoteTrackWorker(
+void MockWebRTCPeerConnectionHandlerClient::didRemoveReceiverWorker(
std::unique_ptr<blink::WebRTCRtpReceiver>* web_rtp_receiver) {
- remote_stream_.Reset();
+ remote_stream_id_ = blink::WebString();
}
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h b/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h
index 6958818c8c2..32ec4d023d4 100644
--- a/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h
+++ b/chromium/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h
@@ -14,6 +14,7 @@
#include "third_party/blink/public/platform/web_rtc_ice_candidate.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h"
#include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
namespace content {
@@ -27,33 +28,42 @@ class MockWebRTCPeerConnectionHandlerClient
MOCK_METHOD0(NegotiationNeeded, void());
MOCK_METHOD1(DidGenerateICECandidate,
void(scoped_refptr<blink::WebRTCICECandidate> candidate));
- MOCK_METHOD1(DidChangeSignalingState, void(SignalingState state));
+ MOCK_METHOD1(DidChangeSignalingState,
+ void(webrtc::PeerConnectionInterface::SignalingState state));
MOCK_METHOD1(DidChangeICEGatheringState, void(ICEGatheringState state));
MOCK_METHOD1(DidChangeICEConnectionState, void(ICEConnectionState state));
- void DidAddRemoteTrack(
+ void DidAddReceiverPlanB(
std::unique_ptr<blink::WebRTCRtpReceiver> web_rtp_receiver) override {
- DidAddRemoteTrackForMock(&web_rtp_receiver);
+ DidAddReceiverPlanBForMock(&web_rtp_receiver);
}
- void DidRemoveRemoteTrack(
+ void DidRemoveReceiverPlanB(
std::unique_ptr<blink::WebRTCRtpReceiver> web_rtp_receiver) override {
- DidRemoveRemoteTrackForMock(&web_rtp_receiver);
+ DidRemoveReceiverPlanBForMock(&web_rtp_receiver);
+ }
+ void DidModifyTransceivers(
+ std::vector<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+ web_transceivers,
+ bool is_remote_description) override {
+ DidModifyTransceiversForMock(&web_transceivers, is_remote_description);
}
MOCK_METHOD1(DidAddRemoteDataChannel, void(blink::WebRTCDataChannelHandler*));
MOCK_METHOD0(ReleasePeerConnectionHandler, void());
- MOCK_METHOD0(GetOriginTrials, WebRTCOriginTrials());
// Move-only arguments do not play nicely with MOCK, the workaround is to
// EXPECT_CALL with these instead.
- MOCK_METHOD1(DidAddRemoteTrackForMock,
+ MOCK_METHOD1(DidAddReceiverPlanBForMock,
void(std::unique_ptr<blink::WebRTCRtpReceiver>*));
- MOCK_METHOD1(DidRemoveRemoteTrackForMock,
+ MOCK_METHOD1(DidRemoveReceiverPlanBForMock,
void(std::unique_ptr<blink::WebRTCRtpReceiver>*));
+ MOCK_METHOD2(DidModifyTransceiversForMock,
+ void(std::vector<std::unique_ptr<blink::WebRTCRtpTransceiver>>*,
+ bool));
void didGenerateICECandidateWorker(
scoped_refptr<blink::WebRTCICECandidate> candidate);
- void didAddRemoteTrackWorker(
+ void didAddReceiverWorker(
std::unique_ptr<blink::WebRTCRtpReceiver>* stream_web_rtp_receivers);
- void didRemoveRemoteTrackWorker(
+ void didRemoveReceiverWorker(
std::unique_ptr<blink::WebRTCRtpReceiver>* stream_web_rtp_receivers);
const std::string& candidate_sdp() const { return candidate_sdp_; }
@@ -61,10 +71,10 @@ class MockWebRTCPeerConnectionHandlerClient
return candidate_mline_index_;
}
const std::string& candidate_mid() const { return candidate_mid_ ; }
- const blink::WebMediaStream& remote_stream() const { return remote_stream_; }
+ const blink::WebString& remote_stream_id() const { return remote_stream_id_; }
private:
- blink::WebMediaStream remote_stream_;
+ blink::WebString remote_stream_id_;
std::string candidate_sdp_;
int candidate_mline_index_;
std::string candidate_mid_;
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 d57e983c03b..d0c4b1b96f9 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -620,4 +620,30 @@ void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() {
audio_device_ = new rtc::RefCountedObject<WebRtcAudioDeviceImpl>();
}
+std::unique_ptr<webrtc::RtpCapabilities>
+PeerConnectionDependencyFactory::GetSenderCapabilities(
+ const std::string& kind) {
+ if (kind == "audio") {
+ return std::make_unique<webrtc::RtpCapabilities>(
+ GetPcFactory()->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO));
+ } else if (kind == "video") {
+ return std::make_unique<webrtc::RtpCapabilities>(
+ GetPcFactory()->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO));
+ }
+ return nullptr;
+}
+
+std::unique_ptr<webrtc::RtpCapabilities>
+PeerConnectionDependencyFactory::GetReceiverCapabilities(
+ const std::string& kind) {
+ if (kind == "audio") {
+ return std::make_unique<webrtc::RtpCapabilities>(
+ GetPcFactory()->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_AUDIO));
+ } else if (kind == "video") {
+ return std::make_unique<webrtc::RtpCapabilities>(
+ GetPcFactory()->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_VIDEO));
+ }
+ return nullptr;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h
index 8f1cbd22a8c..db7919fe1e5 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h
+++ b/chromium/content/renderer/media/webrtc/peer_connection_dependency_factory.h
@@ -94,6 +94,13 @@ class CONTENT_EXPORT PeerConnectionDependencyFactory
int sdp_mline_index,
const std::string& sdp);
+ // Returns the most optimistic view of the capabilities of the system for
+ // sending or receiving media of the given kind ("audio" or "video").
+ virtual std::unique_ptr<webrtc::RtpCapabilities> GetSenderCapabilities(
+ const std::string& kind);
+ virtual std::unique_ptr<webrtc::RtpCapabilities> GetReceiverCapabilities(
+ const std::string& kind);
+
WebRtcAudioDeviceImpl* GetWebRtcAudioDevice();
void EnsureInitialized();
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc b/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc
index 85ce26f5918..4566c247f7b 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_tracker.cc
@@ -87,39 +87,111 @@ static std::string SerializeAnswerOptions(
return result.str();
}
-static std::string SerializeMediaStreamComponent(
- const blink::WebMediaStreamTrack& component) {
- return component.Source().Id().Utf8();
-}
-
-static std::string SerializeMediaDescriptor(
- const blink::WebMediaStream& stream) {
- std::string id = stream.Id().Utf8();
- std::string result = "id: " + id;
- blink::WebVector<blink::WebMediaStreamTrack> tracks;
- stream.AudioTracks(tracks);
- if (!tracks.IsEmpty()) {
- result += ", audio: [";
- for (size_t i = 0; i < tracks.size(); ++i) {
- result += SerializeMediaStreamComponent(tracks[i]);
- if (i != tracks.size() - 1)
- result += ", ";
- }
- result += "]";
+static std::string SerializeMediaStreamIds(
+ const blink::WebVector<blink::WebString>& stream_ids) {
+ if (!stream_ids.size())
+ return "[]";
+ std::string result = "[";
+ for (const auto& stream_id : stream_ids) {
+ if (result.size() > 2u)
+ result += ",";
+ result += "'" + stream_id.Utf8() + "'";
}
- stream.VideoTracks(tracks);
- if (!tracks.IsEmpty()) {
- result += ", video: [";
- for (size_t i = 0; i < tracks.size(); ++i) {
- result += SerializeMediaStreamComponent(tracks[i]);
- if (i != tracks.size() - 1)
- result += ", ";
- }
- result += "]";
+ result += "]";
+ return result;
+}
+
+static const char* SerializeDirection(
+ webrtc::RtpTransceiverDirection direction) {
+ switch (direction) {
+ case webrtc::RtpTransceiverDirection::kSendRecv:
+ return "'sendrecv'";
+ case webrtc::RtpTransceiverDirection::kSendOnly:
+ return "'sendonly'";
+ case webrtc::RtpTransceiverDirection::kRecvOnly:
+ return "'recvonly'";
+ case webrtc::RtpTransceiverDirection::kInactive:
+ return "'inactive'";
+ }
+}
+
+static const char* SerializeOptionalDirection(
+ const base::Optional<webrtc::RtpTransceiverDirection>& direction) {
+ return direction ? SerializeDirection(*direction) : "null";
+}
+
+static std::string SerializeSender(const std::string& indent,
+ const blink::WebRTCRtpSender& sender) {
+ std::string result = "{\n";
+ // track:'id',
+ result += indent + " track:";
+ if (sender.Track().IsNull()) {
+ result += "null";
+ } else {
+ result += "'" + sender.Track().Source().Id().Utf8() + "'";
}
+ result += ",\n";
+ // streams:['id,'id'],
+ result += indent +
+ " streams:" + SerializeMediaStreamIds(sender.StreamIds()) + ",\n";
+ result += indent + "}";
+ return result;
+}
+
+static std::string SerializeReceiver(const std::string& indent,
+ const blink::WebRTCRtpReceiver& receiver) {
+ std::string result = "{\n";
+ // track:'id',
+ DCHECK(!receiver.Track().IsNull());
+ result +=
+ indent + " track:'" + receiver.Track().Source().Id().Utf8() + "',\n";
+ // streams:['id,'id'],
+ result += indent +
+ " streams:" + SerializeMediaStreamIds(receiver.StreamIds()) +
+ ",\n";
+ result += indent + "}";
return result;
}
+static std::string SerializeTransceiver(
+ const blink::WebRTCRtpTransceiver& transceiver) {
+ if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver) {
+ std::string result = "{\n";
+ // mid:'foo',
+ if (transceiver.Mid().IsNull())
+ result += " mid:null,\n";
+ else
+ result += " mid:'" + transceiver.Mid().Utf8() + "',\n";
+ // sender:{...},
+ result +=
+ " sender:" + SerializeSender(" ", *transceiver.Sender()) + ",\n";
+ // receiver:{...},
+ result += " receiver:" + SerializeReceiver(" ", *transceiver.Receiver()) +
+ ",\n";
+ // stopped:false,
+ result += " stopped:" +
+ std::string(SerializeBoolean(transceiver.Stopped())) + ",\n";
+ // direction:'sendrecv',
+ result += " direction:" +
+ std::string(SerializeDirection(transceiver.Direction())) + ",\n";
+ // currentDirection:null,
+ result += " currentDirection:" +
+ std::string(
+ SerializeOptionalDirection(transceiver.CurrentDirection())) +
+ ",\n";
+ result += "}";
+ return result;
+ }
+ if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly) {
+ return SerializeSender("", *transceiver.Sender());
+ }
+ DCHECK(transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ return SerializeReceiver("", *transceiver.Receiver());
+}
+
static const char* SerializeIceTransportType(
webrtc::PeerConnectionInterface::IceTransportsType type) {
const char* transport_type = "";
@@ -216,15 +288,21 @@ static std::string SerializeConfiguration(
// strings on chrome://webrtc-internals.
static const char* GetSignalingStateString(
- WebRTCPeerConnectionHandlerClient::SignalingState state) {
+ webrtc::PeerConnectionInterface::SignalingState state) {
const char* result = "";
switch (state) {
- GET_STRING_OF_STATE(SignalingStateStable)
- GET_STRING_OF_STATE(SignalingStateHaveLocalOffer)
- GET_STRING_OF_STATE(SignalingStateHaveRemoteOffer)
- GET_STRING_OF_STATE(SignalingStateHaveLocalPrAnswer)
- GET_STRING_OF_STATE(SignalingStateHaveRemotePrAnswer)
- GET_STRING_OF_STATE(SignalingStateClosed)
+ case webrtc::PeerConnectionInterface::SignalingState::kStable:
+ return "SignalingStateStable";
+ case webrtc::PeerConnectionInterface::SignalingState::kHaveLocalOffer:
+ return "SignalingStateHaveLocalOffer";
+ case webrtc::PeerConnectionInterface::SignalingState::kHaveRemoteOffer:
+ return "SignalingStateHaveRemoteOffer";
+ case webrtc::PeerConnectionInterface::SignalingState::kHaveLocalPrAnswer:
+ return "SignalingStateHaveLocalPrAnswer";
+ case webrtc::PeerConnectionInterface::SignalingState::kHaveRemotePrAnswer:
+ return "SignalingStateHaveRemotePrAnswer";
+ case webrtc::PeerConnectionInterface::SignalingState::kClosed:
+ return "SignalingStateClosed";
default:
NOTREACHED();
break;
@@ -264,6 +342,24 @@ static const char* GetIceGatheringStateString(
return result;
}
+static const char* GetTransceiverUpdatedReasonString(
+ PeerConnectionTracker::TransceiverUpdatedReason reason) {
+ switch (reason) {
+ case PeerConnectionTracker::TransceiverUpdatedReason::kAddTransceiver:
+ return "addTransceiver";
+ case PeerConnectionTracker::TransceiverUpdatedReason::kAddTrack:
+ return "addTrack";
+ case PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack:
+ return "removeTrack";
+ case PeerConnectionTracker::TransceiverUpdatedReason::kSetLocalDescription:
+ return "setLocalDescription";
+ case PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription:
+ return "setRemoteDescription";
+ }
+ NOTREACHED();
+ return nullptr;
+}
+
// Builds a DictionaryValue from the StatsReport.
// Note:
// The format must be consistent with what webrtc_internals.js expects.
@@ -613,30 +709,73 @@ void PeerConnectionTracker::TrackAddIceCandidate(
SendPeerConnectionUpdate(id, event, value);
}
-void PeerConnectionTracker::TrackAddStream(
+void PeerConnectionTracker::TrackAddTransceiver(
RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream,
- Source source) {
- DCHECK(main_thread_.CalledOnValidThread());
- int id = GetLocalIDForHandler(pc_handler);
- if (id == -1)
- return;
- SendPeerConnectionUpdate(
- id, source == SOURCE_LOCAL ? "addStream" : "onAddStream",
- SerializeMediaDescriptor(stream));
+ PeerConnectionTracker::TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index) {
+ TrackTransceiver("Added", pc_handler, reason, transceiver, transceiver_index);
}
-void PeerConnectionTracker::TrackRemoveStream(
+void PeerConnectionTracker::TrackModifyTransceiver(
RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream,
- Source source) {
+ PeerConnectionTracker::TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index) {
+ TrackTransceiver("Modified", pc_handler, reason, transceiver,
+ transceiver_index);
+}
+
+void PeerConnectionTracker::TrackRemoveTransceiver(
+ RTCPeerConnectionHandler* pc_handler,
+ PeerConnectionTracker::TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index) {
+ TrackTransceiver("Removed", pc_handler, reason, transceiver,
+ transceiver_index);
+}
+
+void PeerConnectionTracker::TrackTransceiver(
+ const char* callback_type_ending,
+ RTCPeerConnectionHandler* pc_handler,
+ PeerConnectionTracker::TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index) {
DCHECK(main_thread_.CalledOnValidThread());
int id = GetLocalIDForHandler(pc_handler);
if (id == -1)
return;
- SendPeerConnectionUpdate(
- id, source == SOURCE_LOCAL ? "removeStream" : "onRemoveStream",
- SerializeMediaDescriptor(stream));
+ std::string callback_type;
+ if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver) {
+ callback_type = "transceiver";
+ } else if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly) {
+ callback_type = "sender";
+ } else {
+ callback_type = "receiver";
+ }
+ callback_type += callback_type_ending;
+
+ std::string result;
+ result += "Caused by: ";
+ result += GetTransceiverUpdatedReasonString(reason);
+ result += "\n\n";
+ if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver) {
+ result += "getTransceivers()";
+ } else if (transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly) {
+ result += "getSenders()";
+ } else {
+ DCHECK_EQ(
+ transceiver.ImplementationType(),
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ result += "getReceivers()";
+ }
+ result += "[" + base::UintToString(transceiver_index) + "]:";
+ result += SerializeTransceiver(transceiver);
+ SendPeerConnectionUpdate(id, callback_type, result);
}
void PeerConnectionTracker::TrackCreateDataChannel(
@@ -664,8 +803,8 @@ void PeerConnectionTracker::TrackStop(RTCPeerConnectionHandler* pc_handler) {
}
void PeerConnectionTracker::TrackSignalingStateChange(
- RTCPeerConnectionHandler* pc_handler,
- WebRTCPeerConnectionHandlerClient::SignalingState state) {
+ RTCPeerConnectionHandler* pc_handler,
+ webrtc::PeerConnectionInterface::SignalingState state) {
DCHECK(main_thread_.CalledOnValidThread());
int id = GetLocalIDForHandler(pc_handler);
if (id == -1)
@@ -779,11 +918,11 @@ int PeerConnectionTracker::GetLocalIDForHandler(
void PeerConnectionTracker::SendPeerConnectionUpdate(
int local_id,
- const char* callback_type,
+ const std::string& callback_type,
const std::string& value) {
DCHECK(main_thread_.CalledOnValidThread());
GetPeerConnectionTrackerHost().get()->UpdatePeerConnection(
- local_id, std::string(callback_type), value);
+ local_id, callback_type, value);
}
void PeerConnectionTracker::OverrideSendTargetForTesting(RenderThread* target) {
@@ -797,6 +936,6 @@ PeerConnectionTracker::GetPeerConnectionTrackerHost() {
&peer_connection_tracker_host_ptr_);
}
return peer_connection_tracker_host_ptr_;
-};
+}
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_tracker.h b/chromium/content/renderer/media/webrtc/peer_connection_tracker.h
index 0c35de2047e..24e0fd85e1c 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_tracker.h
+++ b/chromium/content/renderer/media/webrtc/peer_connection_tracker.h
@@ -16,6 +16,7 @@
#include "ipc/ipc_platform_file.h"
#include "third_party/blink/public/platform/web_media_stream.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
#include "third_party/blink/public/platform/web_rtc_session_description.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
@@ -60,6 +61,16 @@ class CONTENT_EXPORT PeerConnectionTracker
ACTION_CREATE_ANSWER
};
+ // In Plan B: "Transceiver" refers to RTCRtpSender or RTCRtpReceiver.
+ // In Unified Plan: "Transceiver" refers to RTCRtpTransceiver.
+ enum class TransceiverUpdatedReason {
+ kAddTransceiver,
+ kAddTrack,
+ kRemoveTrack,
+ kSetLocalDescription,
+ kSetRemoteDescription,
+ };
+
// RenderThreadObserver implementation.
bool OnControlMessageReceived(const IPC::Message& message) override;
@@ -116,15 +127,31 @@ class CONTENT_EXPORT PeerConnectionTracker
Source source,
bool succeeded);
- // Sends an update when a media stream is added.
- virtual void TrackAddStream(
+ // Sends an update when a transceiver is added, modified or removed. This can
+ // happen as a result of any of the methods indicated by |reason|.
+ // In Plan B: |transceiver| refers to its Sender() or Receiver() depending on
+ // ImplementationType(). Example events: "senderAdded", "receiverRemoved".
+ // In Plan B: |transceiver| has a fully implemented ImplementationType().
+ // Example events: "transceiverAdded", "transceiverModified".
+ // See peer_connection_tracker_unittest.cc for expected resulting event
+ // strings.
+ virtual void TrackAddTransceiver(
RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream, Source source);
-
- // Sends an update when a media stream is removed.
- virtual void TrackRemoveStream(
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index);
+ virtual void TrackModifyTransceiver(
RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream, Source source);
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index);
+ // TODO(hbos): When Plan B is removed this is no longer applicable.
+ // https://crbug.com/857004
+ virtual void TrackRemoveTransceiver(
+ RTCPeerConnectionHandler* pc_handler,
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index);
// Sends an update when a DataChannel is created.
virtual void TrackCreateDataChannel(
@@ -137,7 +164,7 @@ class CONTENT_EXPORT PeerConnectionTracker
// Sends an update when the signaling state of a PeerConnection has changed.
virtual void TrackSignalingStateChange(
RTCPeerConnectionHandler* pc_handler,
- blink::WebRTCPeerConnectionHandlerClient::SignalingState state);
+ webrtc::PeerConnectionInterface::SignalingState state);
// Sends an update when the Ice connection state
// of a PeerConnection has changed.
@@ -180,6 +207,12 @@ class CONTENT_EXPORT PeerConnectionTracker
// is not registered, the return value will be -1.
int GetLocalIDForHandler(RTCPeerConnectionHandler* handler) const;
+ void TrackTransceiver(const char* callback_type_ending,
+ RTCPeerConnectionHandler* pc_handler,
+ PeerConnectionTracker::TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index);
+
// IPC Message handler for getting all stats.
void OnGetAllStats();
@@ -211,7 +244,7 @@ class CONTENT_EXPORT PeerConnectionTracker
// |value| - A json serialized string containing all the information for the
// update event.
void SendPeerConnectionUpdate(int local_id,
- const char* callback_type,
+ const std::string& callback_type,
const std::string& value);
RenderThread* SendTarget();
diff --git a/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc b/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc
index 647a6462d8c..84865974755 100644
--- a/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/peer_connection_tracker_unittest.cc
@@ -8,6 +8,7 @@
#include "content/common/media/peer_connection_tracker.mojom.h"
#include "content/common/media/peer_connection_tracker_messages.h"
#include "content/public/test/mock_render_thread.h"
+#include "content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h"
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h"
#include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
@@ -18,11 +19,42 @@
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_media_constraints.h"
#include "third_party/blink/public/platform/web_rtc_offer_options.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_sender.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
using ::testing::_;
namespace content {
+const char* kDefaultTransceiverString =
+ "getTransceivers()[0]:{\n"
+ " mid:null,\n"
+ " sender:{\n"
+ " track:'senderTrackId',\n"
+ " streams:['senderStreamId'],\n"
+ " },\n"
+ " receiver:{\n"
+ " track:'receiverTrackId',\n"
+ " streams:['receiverStreamId'],\n"
+ " },\n"
+ " stopped:false,\n"
+ " direction:'sendonly',\n"
+ " currentDirection:null,\n"
+ "}";
+
+const char* kDefaultSenderString =
+ "getSenders()[0]:{\n"
+ " track:'senderTrackId',\n"
+ " streams:['senderStreamId'],\n"
+ "}";
+
+const char* kDefaultReceiverString =
+ "getReceivers()[0]:{\n"
+ " track:'receiverTrackId',\n"
+ " streams:['receiverStreamId'],\n"
+ "}";
+
class MockPeerConnectionTrackerHost : public mojom::PeerConnectionTrackerHost {
public:
MockPeerConnectionTrackerHost() : binding_(this) {}
@@ -47,7 +79,41 @@ class MockPeerConnectionTrackerHost : public mojom::PeerConnectionTrackerHost {
mojo::AssociatedBinding<mojom::PeerConnectionTrackerHost> binding_;
};
+// Creates a transceiver that is expected to be logged as
+// |kDefaultTransceiverString|, |kDefaultSenderString| or
+// |kDefaultReceiverString| depending on if |implementation_type| refers to a
+// fully implemented, sender-only or receiver-only transceiver.
+//
+// This is used in unittests that don't care about the specific attributes of
+// the transceiver.
+std::unique_ptr<blink::WebRTCRtpTransceiver> CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType implementation_type) {
+ std::unique_ptr<blink::WebRTCRtpTransceiver> transceiver;
+ FakeRTCRtpSender sender("senderTrackId", {"senderStreamId"});
+ FakeRTCRtpReceiver receiver("receiverTrackId", {"receiverStreamId"});
+ if (implementation_type ==
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver) {
+ transceiver = std::make_unique<FakeRTCRtpTransceiver>(
+ base::nullopt, std::move(sender), std::move(receiver),
+ false /* stopped */,
+ webrtc::RtpTransceiverDirection::kSendOnly /* direction */,
+ base::nullopt /* current_direction */);
+ } else if (implementation_type ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly) {
+ transceiver = std::make_unique<RTCRtpSenderOnlyTransceiver>(
+ std::make_unique<FakeRTCRtpSender>(sender));
+ } else {
+ DCHECK_EQ(
+ implementation_type,
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ transceiver = std::make_unique<RTCRtpReceiverOnlyTransceiver>(
+ std::make_unique<FakeRTCRtpReceiver>(receiver));
+ }
+ return transceiver;
+}
+
namespace {
+
class MockSendTargetThread : public MockRenderThread {
public:
MOCK_METHOD1(OnAddPeerConnection, void(PeerConnectionInfo));
@@ -66,6 +132,7 @@ bool MockSendTargetThread::OnMessageReceived(const IPC::Message& msg) {
return handled;
}
+// TODO(https://crbug.com/868868): Move this into a separate file.
class MockPeerConnectionHandler : public RTCPeerConnectionHandler {
public:
MockPeerConnectionHandler()
@@ -81,8 +148,30 @@ class MockPeerConnectionHandler : public RTCPeerConnectionHandler {
};
class PeerConnectionTrackerTest : public ::testing::Test {
- private:
+ public:
+ void CreateTrackerWithMocks() {
+ mock_host_.reset(new MockPeerConnectionTrackerHost());
+ tracker_.reset(
+ new PeerConnectionTracker(mock_host_->CreateInterfacePtrAndBind()));
+ target_thread_.reset(new MockSendTargetThread());
+ tracker_->OverrideSendTargetForTesting(target_thread_.get());
+ }
+
+ void CreateAndRegisterPeerConnectionHandler() {
+ mock_handler_.reset(new MockPeerConnectionHandler());
+ EXPECT_CALL(*target_thread_, OnAddPeerConnection(_));
+ tracker_->RegisterPeerConnection(
+ mock_handler_.get(),
+ webrtc::PeerConnectionInterface::RTCConfiguration(),
+ blink::WebMediaConstraints(), nullptr);
+ }
+
+ protected:
base::MessageLoop message_loop_;
+ std::unique_ptr<MockPeerConnectionTrackerHost> mock_host_;
+ std::unique_ptr<PeerConnectionTracker> tracker_;
+ std::unique_ptr<MockSendTargetThread> target_thread_;
+ std::unique_ptr<MockPeerConnectionHandler> mock_handler_;
};
} // namespace
@@ -92,47 +181,258 @@ TEST_F(PeerConnectionTrackerTest, CreatingObject) {
}
TEST_F(PeerConnectionTrackerTest, TrackCreateOffer) {
- MockPeerConnectionTrackerHost mock_peer_connection_tracker_host;
- PeerConnectionTracker tracker(
- mock_peer_connection_tracker_host.CreateInterfacePtrAndBind());
- // mojom::PeerConnectionTrackerHostAssociatedPtr
- // mock_peer_connection_tracker_host_ptr_
- // = mock_peer_connection_tracker_host.CreateInterfacePtrAndBind();
- // tracker.SetPeerConnectionTrackerHostForTesting(std::move(ptr1));
- // Note: blink::WebRTCOfferOptions is not mockable. So we can't write
- // tests for anything but a null options parameter.
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ // Note: blink::WebRTCOfferOptions is not mockable. So we can't write tests
+ // for anything but a null options parameter.
blink::WebRTCOfferOptions options(0, 0, false, false);
- // Initialization stuff. This can be separated into a test class.
- MockPeerConnectionHandler pc_handler;
- MockSendTargetThread target_thread;
- webrtc::PeerConnectionInterface::RTCConfiguration config;
- blink::WebMediaConstraints constraints;
- tracker.OverrideSendTargetForTesting(&target_thread);
- EXPECT_CALL(target_thread, OnAddPeerConnection(_));
- tracker.RegisterPeerConnection(&pc_handler, config, constraints, nullptr);
- // Back to the test.
- EXPECT_CALL(mock_peer_connection_tracker_host,
+ EXPECT_CALL(*mock_host_,
UpdatePeerConnection(
_, "createOffer",
"options: {offerToReceiveVideo: 0, offerToReceiveAudio: 0, "
"voiceActivityDetection: false, iceRestart: false}"));
- tracker.TrackCreateOffer(&pc_handler, options);
+ tracker_->TrackCreateOffer(mock_handler_.get(), options);
base::RunLoop().RunUntilIdle();
}
TEST_F(PeerConnectionTrackerTest, OnSuspend) {
- PeerConnectionTracker tracker;
- // Initialization stuff.
- MockPeerConnectionHandler pc_handler;
- MockSendTargetThread target_thread;
- webrtc::PeerConnectionInterface::RTCConfiguration config;
- blink::WebMediaConstraints constraints;
- tracker.OverrideSendTargetForTesting(&target_thread);
- EXPECT_CALL(target_thread, OnAddPeerConnection(_));
- tracker.RegisterPeerConnection(&pc_handler, config, constraints, nullptr);
- EXPECT_CALL(pc_handler, CloseClientPeerConnection());
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ EXPECT_CALL(*mock_handler_, CloseClientPeerConnection());
std::unique_ptr<IPC::Message> message(new PeerConnectionTracker_OnSuspend());
- tracker.OnControlMessageReceived(*message.get());
+ tracker_->OnControlMessageReceived(*message.get());
+}
+
+TEST_F(PeerConnectionTrackerTest, AddTransceiverWithOptionalValuesPresent) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ FakeRTCRtpTransceiver transceiver(
+ "midValue", FakeRTCRtpSender("senderTrackId", {"streamIdA", "streamIdB"}),
+ FakeRTCRtpReceiver("receiverTrackId", {"streamIdC"}), true /* stopped */,
+ webrtc::RtpTransceiverDirection::kSendRecv /* direction */,
+ webrtc::RtpTransceiverDirection::kInactive /* current_direction */);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "transceiverAdded", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackAddTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kAddTrack, transceiver,
+ 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: addTrack\n"
+ "\n"
+ "getTransceivers()[0]:{\n"
+ " mid:'midValue',\n"
+ " sender:{\n"
+ " track:'senderTrackId',\n"
+ " streams:['streamIdA','streamIdB'],\n"
+ " },\n"
+ " receiver:{\n"
+ " track:'receiverTrackId',\n"
+ " streams:['streamIdC'],\n"
+ " },\n"
+ " stopped:true,\n"
+ " direction:'sendrecv',\n"
+ " currentDirection:'inactive',\n"
+ "}",
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, AddTransceiverWithOptionalValuesNull) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ FakeRTCRtpTransceiver transceiver(
+ base::nullopt, FakeRTCRtpSender(base::nullopt, {}),
+ FakeRTCRtpReceiver("receiverTrackId", {}), false /* stopped */,
+ webrtc::RtpTransceiverDirection::kInactive /* direction */,
+ base::nullopt /* current_direction */);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "transceiverAdded", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackAddTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kAddTransceiver,
+ transceiver, 1u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: addTransceiver\n"
+ "\n"
+ "getTransceivers()[1]:{\n"
+ " mid:null,\n"
+ " sender:{\n"
+ " track:null,\n"
+ " streams:[],\n"
+ " },\n"
+ " receiver:{\n"
+ " track:'receiverTrackId',\n"
+ " streams:[],\n"
+ " },\n"
+ " stopped:false,\n"
+ " direction:'inactive',\n"
+ " currentDirection:null,\n"
+ "}",
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, ModifyTransceiver) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto transceiver = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "transceiverModified", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackModifyTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetLocalDescription,
+ *transceiver, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setLocalDescription\n"
+ "\n" +
+ std::string(kDefaultTransceiverString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, RemoveTransceiver) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto transceiver = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "transceiverRemoved", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackRemoveTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack,
+ *transceiver, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: removeTrack\n"
+ "\n" +
+ std::string(kDefaultTransceiverString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, AddSender) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto sender_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "senderAdded", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackAddTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetLocalDescription,
+ *sender_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setLocalDescription\n"
+ "\n" +
+ std::string(kDefaultSenderString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, ModifySender) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto sender_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "senderModified", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackModifyTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *sender_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setRemoteDescription\n"
+ "\n" +
+ std::string(kDefaultSenderString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, RemoveSender) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto sender_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "senderRemoved", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackRemoveTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *sender_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setRemoteDescription\n"
+ "\n" +
+ std::string(kDefaultSenderString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, AddReceiver) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto receiver_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "receiverAdded", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackAddTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *receiver_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setRemoteDescription\n"
+ "\n" +
+ std::string(kDefaultReceiverString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, ModifyReceiver) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto receiver_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "receiverModified", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackModifyTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *receiver_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setRemoteDescription\n"
+ "\n" +
+ std::string(kDefaultReceiverString),
+ update_value);
+}
+
+TEST_F(PeerConnectionTrackerTest, RemoveReceiver) {
+ CreateTrackerWithMocks();
+ CreateAndRegisterPeerConnectionHandler();
+ auto receiver_only = CreateDefaultTransceiver(
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ std::string update_value;
+ EXPECT_CALL(*mock_host_, UpdatePeerConnection(_, "receiverRemoved", _))
+ .WillOnce(testing::SaveArg<2>(&update_value));
+ tracker_->TrackRemoveTransceiver(
+ mock_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *receiver_only, 0u);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(
+ "Caused by: setRemoteDescription\n"
+ "\n" +
+ std::string(kDefaultReceiverString),
+ update_value);
}
// TODO(hta): Write tests for the other tracking functions.
diff --git a/chromium/content/renderer/media/webrtc/rtc_certificate_generator.cc b/chromium/content/renderer/media/webrtc/rtc_certificate_generator.cc
index 8eb3a817560..4f5ff473c80 100644
--- a/chromium/content/renderer/media/webrtc/rtc_certificate_generator.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_certificate_generator.cc
@@ -39,7 +39,7 @@ rtc::KeyParams WebRTCKeyParamsToKeyParams(
}
// A certificate generation request spawned by
-// |RTCCertificateGenerator::generateCertificateWithOptionalExpiration|. This
+// |GenerateCertificateWithOptionalExpiration|. This
// is handled by a separate class so that reference counting can keep the
// request alive independently of the |RTCCertificateGenerator| that spawned it.
class RTCCertificateGeneratorRequest
@@ -60,7 +60,7 @@ class RTCCertificateGeneratorRequest
void GenerateCertificateAsync(
const blink::WebRTCKeyParams& key_params,
- const rtc::Optional<uint64_t>& expires_ms,
+ const absl::optional<uint64_t>& expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer) {
DCHECK(main_thread_->BelongsToCurrentThread());
DCHECK(observer);
@@ -80,7 +80,7 @@ class RTCCertificateGeneratorRequest
void GenerateCertificateOnWorkerThread(
const blink::WebRTCKeyParams key_params,
- const rtc::Optional<uint64_t> expires_ms,
+ const absl::optional<uint64_t> expires_ms,
CertificateCallbackPtr observer) {
DCHECK(worker_thread_->BelongsToCurrentThread());
@@ -114,41 +114,40 @@ class RTCCertificateGeneratorRequest
const scoped_refptr<base::SingleThreadTaskRunner> worker_thread_;
};
-} // namespace
-
-void RTCCertificateGenerator::GenerateCertificate(
+void GenerateCertificateWithOptionalExpiration(
const blink::WebRTCKeyParams& key_params,
+ const absl::optional<uint64_t>& expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- generateCertificateWithOptionalExpiration(
- key_params, rtc::Optional<uint64_t>(), std::move(observer), task_runner);
+ DCHECK(WebRTCKeyParamsToKeyParams(key_params).IsValid());
+ PeerConnectionDependencyFactory* pc_dependency_factory =
+ RenderThreadImpl::current()->GetPeerConnectionDependencyFactory();
+ pc_dependency_factory->EnsureInitialized();
+
+ scoped_refptr<RTCCertificateGeneratorRequest> request =
+ new RTCCertificateGeneratorRequest(
+ task_runner, pc_dependency_factory->GetWebRtcWorkerThread());
+ request->GenerateCertificateAsync(key_params, expires_ms,
+ std::move(observer));
}
-void RTCCertificateGenerator::GenerateCertificateWithExpiration(
+} // namespace
+
+void RTCCertificateGenerator::GenerateCertificate(
const blink::WebRTCKeyParams& key_params,
- uint64_t expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- generateCertificateWithOptionalExpiration(key_params,
- rtc::Optional<uint64_t>(expires_ms),
+ GenerateCertificateWithOptionalExpiration(key_params, absl::nullopt,
std::move(observer), task_runner);
}
-void RTCCertificateGenerator::generateCertificateWithOptionalExpiration(
+void RTCCertificateGenerator::GenerateCertificateWithExpiration(
const blink::WebRTCKeyParams& key_params,
- const rtc::Optional<uint64_t>& expires_ms,
+ uint64_t expires_ms,
std::unique_ptr<blink::WebRTCCertificateCallback> observer,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- DCHECK(IsSupportedKeyParams(key_params));
- PeerConnectionDependencyFactory* pc_dependency_factory =
- RenderThreadImpl::current()->GetPeerConnectionDependencyFactory();
- pc_dependency_factory->EnsureInitialized();
-
- scoped_refptr<RTCCertificateGeneratorRequest> request =
- new RTCCertificateGeneratorRequest(
- task_runner, pc_dependency_factory->GetWebRtcWorkerThread());
- request->GenerateCertificateAsync(
- key_params, expires_ms, std::move(observer));
+ GenerateCertificateWithOptionalExpiration(key_params, expires_ms,
+ std::move(observer), task_runner);
}
bool RTCCertificateGenerator::IsSupportedKeyParams(
diff --git a/chromium/content/renderer/media/webrtc/rtc_certificate_generator.h b/chromium/content/renderer/media/webrtc/rtc_certificate_generator.h
index 248cd21846c..5e29c7f62d4 100644
--- a/chromium/content/renderer/media/webrtc/rtc_certificate_generator.h
+++ b/chromium/content/renderer/media/webrtc/rtc_certificate_generator.h
@@ -10,7 +10,6 @@
#include "third_party/blink/public/platform/web_rtc_certificate.h"
#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
#include "third_party/blink/public/platform/web_rtc_key_params.h"
-#include "third_party/webrtc/api/optional.h"
namespace content {
@@ -38,12 +37,6 @@ class RTCCertificateGenerator : public blink::WebRTCCertificateGenerator {
blink::WebString pem_certificate) override;
private:
- void generateCertificateWithOptionalExpiration(
- const blink::WebRTCKeyParams& key_params,
- const rtc::Optional<uint64_t>& expires_ms,
- std::unique_ptr<blink::WebRTCCertificateCallback> observer,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-
DISALLOW_COPY_AND_ASSIGN(RTCCertificateGenerator);
};
diff --git a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.cc b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
index e972ef0a8dd..64bf108735c 100644
--- a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
@@ -18,6 +18,7 @@
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
+#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -36,8 +37,7 @@
#include "content/renderer/media/webrtc/rtc_event_log_output_sink_proxy.h"
#include "content/renderer/media/webrtc/rtc_stats.h"
#include "content/renderer/media/webrtc/webrtc_audio_device_impl.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/webrtc_set_description_observer.h"
#include "content/renderer/media/webrtc/webrtc_uma_histograms.h"
#include "content/renderer/render_thread_impl.h"
#include "media/base/media_switches.h"
@@ -49,6 +49,7 @@
#include "third_party/blink/public/platform/web_rtc_legacy_stats.h"
#include "third_party/blink/public/platform/web_rtc_offer_options.h"
#include "third_party/blink/public/platform/web_rtc_rtp_sender.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
#include "third_party/blink/public/platform/web_rtc_session_description.h"
#include "third_party/blink/public/platform/web_rtc_session_description_request.h"
#include "third_party/blink/public/platform/web_rtc_void_request.h"
@@ -119,30 +120,6 @@ GetWebKitIceConnectionState(
}
}
-blink::WebRTCPeerConnectionHandlerClient::SignalingState
-GetWebKitSignalingState(webrtc::PeerConnectionInterface::SignalingState state) {
- using blink::WebRTCPeerConnectionHandlerClient;
- switch (state) {
- case webrtc::PeerConnectionInterface::kStable:
- return WebRTCPeerConnectionHandlerClient::kSignalingStateStable;
- case webrtc::PeerConnectionInterface::kHaveLocalOffer:
- return WebRTCPeerConnectionHandlerClient::kSignalingStateHaveLocalOffer;
- case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
- return WebRTCPeerConnectionHandlerClient::
- kSignalingStateHaveLocalPrAnswer;
- case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
- return WebRTCPeerConnectionHandlerClient::kSignalingStateHaveRemoteOffer;
- case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
- return WebRTCPeerConnectionHandlerClient::
- kSignalingStateHaveRemotePrAnswer;
- case webrtc::PeerConnectionInterface::kClosed:
- return WebRTCPeerConnectionHandlerClient::kSignalingStateClosed;
- default:
- NOTREACHED();
- return WebRTCPeerConnectionHandlerClient::kSignalingStateClosed;
- }
-}
-
blink::WebRTCSessionDescription CreateWebKitSessionDescription(
const std::string& sdp, const std::string& type) {
blink::WebRTCSessionDescription description;
@@ -257,14 +234,13 @@ void GetNativeRtcConfiguration(
}
switch (blink_config.sdp_semantics) {
- case blink::WebRTCSdpSemantics::kDefault:
case blink::WebRTCSdpSemantics::kPlanB:
webrtc_config->sdp_semantics = webrtc::SdpSemantics::kPlanB;
break;
case blink::WebRTCSdpSemantics::kUnifiedPlan:
webrtc_config->sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
break;
- default:
+ case blink::WebRTCSdpSemantics::kDefault:
NOTREACHED();
}
@@ -279,6 +255,16 @@ void GetNativeRtcConfiguration(
webrtc_config->ice_candidate_pool_size = blink_config.ice_candidate_pool_size;
}
+absl::optional<bool> ConstraintToOptional(
+ const blink::WebMediaConstraints& constraints,
+ const blink::BooleanConstraint blink::WebMediaTrackConstraintSet::*picker) {
+ bool value;
+ if (GetConstraintValueAsBoolean(constraints, picker, &value)) {
+ return absl::optional<bool>(value);
+ }
+ return absl::nullopt;
+}
+
void CopyConstraintsIntoRtcConfiguration(
const blink::WebMediaConstraints constraints,
webrtc::PeerConnectionInterface::RTCConfiguration* configuration) {
@@ -329,7 +315,7 @@ void CopyConstraintsIntoRtcConfiguration(
constraints,
&blink::WebMediaTrackConstraintSet::goog_screencast_min_bitrate,
&rate)) {
- configuration->screencast_min_bitrate = rtc::Optional<int>(rate);
+ configuration->screencast_min_bitrate = rate;
}
configuration->combined_audio_video_bwe = ConstraintToOptional(
constraints,
@@ -338,42 +324,6 @@ void CopyConstraintsIntoRtcConfiguration(
constraints, &blink::WebMediaTrackConstraintSet::enable_dtls_srtp);
}
-class SessionDescriptionRequestTracker {
- public:
- SessionDescriptionRequestTracker(
- const base::WeakPtr<RTCPeerConnectionHandler>& handler,
- const base::WeakPtr<PeerConnectionTracker>& tracker,
- PeerConnectionTracker::Action action)
- : handler_(handler), tracker_(tracker), action_(action) {}
-
- void TrackOnSuccess(const webrtc::SessionDescriptionInterface* desc) {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (tracker_ && handler_) {
- std::string value;
- if (desc) {
- desc->ToString(&value);
- value = "type: " + desc->type() + ", sdp: " + value;
- }
- tracker_->TrackSessionDescriptionCallback(
- handler_.get(), action_, "OnSuccess", value);
- }
- }
-
- void TrackOnFailure(const webrtc::RTCError& error) {
- DCHECK(thread_checker_.CalledOnValidThread());
- if (handler_ && tracker_) {
- tracker_->TrackSessionDescriptionCallback(handler_.get(), action_,
- "OnFailure", error.message());
- }
- }
-
- private:
- const base::WeakPtr<RTCPeerConnectionHandler> handler_;
- const base::WeakPtr<PeerConnectionTracker> tracker_;
- PeerConnectionTracker::Action action_;
- base::ThreadChecker thread_checker_;
-};
-
// Class mapping responses from calls to libjingle CreateOffer/Answer and
// the blink::WebRTCSessionDescriptionRequest.
class CreateSessionDescriptionRequest
@@ -387,8 +337,9 @@ class CreateSessionDescriptionRequest
PeerConnectionTracker::Action action)
: main_thread_(main_thread),
webkit_request_(request),
- tracker_(handler, tracker, action) {
- }
+ handler_(handler),
+ tracker_(tracker),
+ action_(action) {}
void OnSuccess(webrtc::SessionDescriptionInterface* desc) override {
if (!main_thread_->BelongsToCurrentThread()) {
@@ -398,7 +349,15 @@ class CreateSessionDescriptionRequest
return;
}
- tracker_.TrackOnSuccess(desc);
+ if (tracker_ && handler_) {
+ std::string value;
+ if (desc) {
+ desc->ToString(&value);
+ value = "type: " + desc->type() + ", sdp: " + value;
+ }
+ tracker_->TrackSessionDescriptionCallback(handler_.get(), action_,
+ "OnSuccess", value);
+ }
webkit_request_.RequestSucceeded(CreateWebKitSessionDescription(desc));
webkit_request_.Reset();
delete desc;
@@ -411,7 +370,10 @@ class CreateSessionDescriptionRequest
return;
}
- tracker_.TrackOnFailure(error);
+ if (handler_ && tracker_) {
+ tracker_->TrackSessionDescriptionCallback(handler_.get(), action_,
+ "OnFailure", error.message());
+ }
// TODO(hta): Convert CreateSessionDescriptionRequest.OnFailure
webkit_request_.RequestFailed(error);
webkit_request_.Reset();
@@ -430,62 +392,9 @@ class CreateSessionDescriptionRequest
const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
blink::WebRTCSessionDescriptionRequest webkit_request_;
- SessionDescriptionRequestTracker tracker_;
-};
-
-// Class mapping responses from calls to libjingle SetLocalDescription and a
-// blink::WebRTCVoidRequest.
-class SetLocalDescriptionRequest
- : public webrtc::SetSessionDescriptionObserver {
- public:
- explicit SetLocalDescriptionRequest(
- const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
- const blink::WebRTCVoidRequest& request,
- const base::WeakPtr<RTCPeerConnectionHandler>& handler,
- const base::WeakPtr<PeerConnectionTracker>& tracker,
- PeerConnectionTracker::Action action)
- : main_thread_(main_thread),
- webkit_request_(request),
- tracker_(handler, tracker, action) {}
-
- void OnSuccess() override {
- if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&SetLocalDescriptionRequest::OnSuccess, this));
- return;
- }
- tracker_.TrackOnSuccess(nullptr);
- webkit_request_.RequestSucceeded();
- webkit_request_.Reset();
- }
- void OnFailure(webrtc::RTCError error) override {
- if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE, base::BindOnce(&SetLocalDescriptionRequest::OnFailure,
- this, std::move(error)));
- return;
- }
- tracker_.TrackOnFailure(error);
- webkit_request_.RequestFailed(error);
- webkit_request_.Reset();
- }
-
- protected:
- ~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())
- << "SetLocalDescriptionRequest not completed. Shutting down?";
- }
-
- private:
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- blink::WebRTCVoidRequest webkit_request_;
- SessionDescriptionRequestTracker tracker_;
+ const base::WeakPtr<RTCPeerConnectionHandler> handler_;
+ const base::WeakPtr<PeerConnectionTracker> tracker_;
+ PeerConnectionTracker::Action action_;
};
blink::WebRTCLegacyStatsMemberType
@@ -704,139 +613,6 @@ void GetRTCStatsOnSignalingThread(
RTCStatsCollectorCallbackImpl::Create(main_thread, std::move(callback)));
}
-class PeerConnectionUMAObserver : public webrtc::UMAObserver {
- public:
- PeerConnectionUMAObserver() {}
- ~PeerConnectionUMAObserver() override {}
- void IncrementEnumCounter(webrtc::PeerConnectionEnumCounterType counter_type,
- int counter,
- int counter_max) override {
- switch (counter_type) {
- case webrtc::kEnumCounterAddressFamily:
- UMA_HISTOGRAM_EXACT_LINEAR("WebRTC.PeerConnection.IPMetrics", counter,
- counter_max);
- break;
- case webrtc::kEnumCounterIceCandidatePairTypeUdp:
- UMA_HISTOGRAM_EXACT_LINEAR(
- "WebRTC.PeerConnection.CandidatePairType_UDP", counter,
- counter_max);
- break;
- case webrtc::kEnumCounterIceCandidatePairTypeTcp:
- UMA_HISTOGRAM_EXACT_LINEAR(
- "WebRTC.PeerConnection.CandidatePairType_TCP", counter,
- counter_max);
- break;
- case webrtc::kEnumCounterDtlsHandshakeError:
- UMA_HISTOGRAM_EXACT_LINEAR("WebRTC.PeerConnection.DtlsHandshakeError",
- counter, counter_max);
- break;
- case webrtc::kEnumCounterIceRestart:
- UMA_HISTOGRAM_EXACT_LINEAR("WebRTC.PeerConnection.IceRestartState",
- counter, counter_max);
- break;
- case webrtc::kEnumCounterIceRegathering:
- UMA_HISTOGRAM_EXACT_LINEAR("WebRTC.PeerConnection.IceRegatheringReason",
- counter, counter_max);
- break;
- case webrtc::kEnumCounterKeyProtocol:
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.KeyProtocol",
- static_cast<webrtc::KeyExchangeProtocolType>(counter),
- webrtc::kEnumCounterKeyProtocolMax);
- break;
- case webrtc::kEnumCounterSdpSemanticNegotiated:
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.SdpSemanticNegotiated",
- static_cast<webrtc::SdpSemanticNegotiated>(counter),
- webrtc::kSdpSemanticNegotiatedMax);
- break;
- case webrtc::kEnumCounterKeyProtocolMediaType:
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.KeyProtocolByMedia",
- static_cast<webrtc::KeyExchangeProtocolMedia>(counter),
- webrtc::kEnumCounterKeyProtocolMediaTypeMax);
- break;
- case webrtc::kEnumCounterSdpFormatReceived:
- UMA_HISTOGRAM_ENUMERATION(
- "WebRTC.PeerConnection.SdpFormatReceived",
- static_cast<webrtc::SdpFormatReceived>(counter),
- webrtc::kSdpFormatReceivedMax);
- break;
- default:
- // The default clause is expected to be reached when new enum types are
- // added.
- break;
- }
- }
-
- void IncrementSparseEnumCounter(
- webrtc::PeerConnectionEnumCounterType counter_type,
- int counter) override {
- switch (counter_type) {
- case webrtc::kEnumCounterAudioSrtpCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SrtpCryptoSuite.Audio",
- counter);
- break;
- case webrtc::kEnumCounterAudioSslCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SslCipherSuite.Audio",
- counter);
- break;
- case webrtc::kEnumCounterVideoSrtpCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SrtpCryptoSuite.Video",
- counter);
- break;
- case webrtc::kEnumCounterVideoSslCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SslCipherSuite.Video",
- counter);
- break;
- case webrtc::kEnumCounterDataSrtpCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SrtpCryptoSuite.Data",
- counter);
- break;
- case webrtc::kEnumCounterDataSslCipher:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SslCipherSuite.Data",
- counter);
- break;
- case webrtc::kEnumCounterSrtpUnprotectError:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SrtpUnprotectError",
- counter);
- break;
- case webrtc::kEnumCounterSrtcpUnprotectError:
- base::UmaHistogramSparse("WebRTC.PeerConnection.SrtcpUnprotectError",
- counter);
- break;
- default:
- // The default clause is expected to reach when new enum types are
- // added.
- break;
- }
- }
-
- void AddHistogramSample(webrtc::PeerConnectionUMAMetricsName type,
- int value) override {
- // Runs on libjingle's signaling thread.
- switch (type) {
- case webrtc::kTimeToConnect:
- UMA_HISTOGRAM_MEDIUM_TIMES(
- "WebRTC.PeerConnection.TimeToConnect",
- base::TimeDelta::FromMilliseconds(value));
- break;
- case webrtc::kNetworkInterfaces_IPv4:
- UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv4Interfaces",
- value);
- break;
- case webrtc::kNetworkInterfaces_IPv6:
- UMA_HISTOGRAM_COUNTS_100("WebRTC.PeerConnection.IPv6Interfaces",
- value);
- break;
- default:
- // The default clause is expected to reach when new enum types are
- // added.
- break;
- }
- }
-};
-
void ConvertOfferOptionsToWebrtcOfferOptions(
const blink::WebRTCOfferOptions& options,
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions* output) {
@@ -890,15 +666,14 @@ std::set<RTCPeerConnectionHandler*>* GetPeerConnectionHandlers() {
return handlers;
}
-// Counts the number of senders that have |web_stream| as an associated stream.
+// Counts the number of senders that have |stream_id| as an associated stream.
size_t GetLocalStreamUsageCount(
const std::vector<std::unique_ptr<RTCRtpSender>>& rtp_senders,
- const blink::WebMediaStream& web_stream) {
+ const std::string stream_id) {
size_t usage_count = 0;
for (const auto& sender : rtp_senders) {
- for (const auto& stream_ref : sender->stream_refs()) {
- if (stream_ref->adapter().web_stream().UniqueId() ==
- web_stream.UniqueId()) {
+ for (const auto& sender_stream_id : sender->state().stream_ids()) {
+ if (sender_stream_id == stream_id) {
++usage_count;
break;
}
@@ -907,17 +682,16 @@ size_t GetLocalStreamUsageCount(
return usage_count;
}
-// 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;
+bool IsRemoteStream(
+ const std::vector<std::unique_ptr<RTCRtpReceiver>>& rtp_receivers,
+ const std::string& stream_id) {
+ for (const auto& receiver : rtp_receivers) {
+ for (const auto& receiver_stream_id : receiver->state().stream_ids()) {
+ if (stream_id == receiver_stream_id)
+ return true;
+ }
}
- return usage_count;
+ return false;
}
enum SdpSemanticRequested {
@@ -941,6 +715,13 @@ SdpSemanticRequested GetSdpSemanticRequested(
return kSdpSemanticRequestedDefault;
}
+MediaStreamTrackMetrics::Kind MediaStreamTrackMetricsKind(
+ const blink::WebMediaStreamTrack& track) {
+ return track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio
+ ? MediaStreamTrackMetrics::Kind::kAudio
+ : MediaStreamTrackMetrics::Kind::kVideo;
+}
+
} // namespace
// Implementation of LocalRTCStatsRequest.
@@ -978,175 +759,146 @@ void LocalRTCStatsResponse::addStats(const blink::WebRTCLegacyStats& stats) {
impl_.AddStats(stats);
}
-// Processes the resulting state changes of a SetRemoteDescription call.
-class RTCPeerConnectionHandler::WebRtcSetRemoteDescriptionObserverImpl
- : public WebRtcSetRemoteDescriptionObserver {
+// Processes the resulting state changes of a SetLocalDescription() or
+// SetRemoteDescription() call.
+class RTCPeerConnectionHandler::WebRtcSetDescriptionObserverImpl
+ : public WebRtcSetDescriptionObserver {
public:
- WebRtcSetRemoteDescriptionObserverImpl(
+ WebRtcSetDescriptionObserverImpl(
base::WeakPtr<RTCPeerConnectionHandler> handler,
blink::WebRTCVoidRequest web_request,
base::WeakPtr<PeerConnectionTracker> tracker,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ PeerConnectionTracker::Action action,
+ blink::WebRTCSdpSemantics sdp_semantics)
: handler_(handler),
main_thread_(task_runner),
web_request_(web_request),
- tracker_(tracker) {}
+ tracker_(tracker),
+ action_(action),
+ sdp_semantics_(sdp_semantics) {
+ DCHECK(sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB ||
+ sdp_semantics_ == blink::WebRTCSdpSemantics::kUnifiedPlan);
+ }
- void OnSetRemoteDescriptionComplete(
- webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>
- states_or_error) override {
- if (!states_or_error.ok()) {
- auto& error = states_or_error.error();
+ void OnSetDescriptionComplete(
+ webrtc::RTCError error,
+ WebRtcSetDescriptionObserver::States states) override {
+ if (!error.ok()) {
if (tracker_ && handler_) {
- tracker_->TrackSessionDescriptionCallback(
- handler_.get(),
- PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION, "OnFailure",
- error.message());
+ tracker_->TrackSessionDescriptionCallback(handler_.get(), action_,
+ "OnFailure", error.message());
}
web_request_.RequestFailed(error);
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));
+ handler_->OnSignalingChange(states.signaling_state);
+
+ // Process the rest of the state changes differently depending on SDP
+ // semantics.
+ if (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB) {
+ ProcessStateChangesPlanB(std::move(states));
+ } else {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ ProcessStateChangesUnifiedPlan(std::move(states));
}
- // 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",
- "");
+ tracker_->TrackSessionDescriptionCallback(handler_.get(), action_,
+ "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));
+ if (action_ == PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION) {
+ // 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::
+ WebRtcSetDescriptionObserverImpl::ResolvePromise,
+ this));
+ } else {
+ // Resolve promise immediately if we can. https://crbug.com/788558 still
+ // needs to be addressed for "setLocalDescription(answer)" rejecting a
+ // transceiver in Unified Plan, but this is a minor edge-case.
+ ResolvePromise();
+ }
}
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;
- };
+ ~WebRtcSetDescriptionObserverImpl() override {}
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();
+ void ProcessStateChangesPlanB(WebRtcSetDescriptionObserver::States states) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kPlanB);
+ // 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), states.transceiver_states))
+ removed_receivers.push_back(it->get());
+ }
+
+ // Process the addition of remote receivers/tracks.
+ for (auto& transceiver_state : states.transceiver_states) {
+ if (ReceiverWasAdded(transceiver_state)) {
+ handler_->OnAddReceiverPlanB(transceiver_state.MoveReceiverState());
+ }
+ }
+ // Process the removal of remote receivers/tracks.
+ for (auto* removed_receiver : removed_receivers) {
+ handler_->OnRemoveReceiverPlanB(RTCRtpReceiver::getId(
+ removed_receiver->state().webrtc_receiver().get()));
+ }
}
- 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())
+ bool ReceiverWasAdded(const RtpTransceiverState& transceiver_state) {
+ uintptr_t receiver_id = RTCRtpReceiver::getId(
+ transceiver_state.receiver_state()->webrtc_receiver().get());
+ for (const auto& receiver : handler_->rtp_receivers_) {
+ if (receiver->Id() == receiver_id)
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) {
- states.CheckInvariants();
- 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) {
- CHECK(stream_ref);
- CHECK(stream_ref->adapter().is_initialized());
- CHECK(!stream_ref->adapter().web_stream().IsNull());
- CHECK(stream_ref->adapter().webrtc_stream());
- auto* stream_state =
- GetOrAddStreamStateForStream(*stream_ref, &stream_states);
- auto track_ref = receiver_state.track_ref->Copy();
- CHECK(!track_ref->web_track().IsNull());
- CHECK(track_ref->webrtc_track());
- stream_state->track_refs.push_back(std::move(track_ref));
- }
- }
- // 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()) {
- CHECK(!stream_ref->adapter().web_stream().IsNull());
- CHECK(stream_ref->adapter().webrtc_stream());
- GetOrAddStreamStateForStream(*stream_ref, &stream_states);
- }
- }
- states.CheckInvariants();
- 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;
+ bool ReceiverWasRemoved(
+ const RTCRtpReceiver& receiver,
+ const std::vector<RtpTransceiverState>& transceiver_states) {
+ for (const auto& transceiver_state : transceiver_states) {
+ if (transceiver_state.receiver_state()->webrtc_receiver() ==
+ receiver.state().webrtc_receiver()) {
+ return false;
}
}
- stream_states->push_back(StreamState(stream_ref.Copy()));
- return &stream_states->back();
+ return true;
+ }
+
+ void ProcessStateChangesUnifiedPlan(
+ WebRtcSetDescriptionObserver::States states) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ handler_->OnModifyTransceivers(
+ std::move(states.transceiver_states),
+ action_ == PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION);
}
base::WeakPtr<RTCPeerConnectionHandler> handler_;
scoped_refptr<base::SequencedTaskRunner> main_thread_;
blink::WebRTCVoidRequest web_request_;
base::WeakPtr<PeerConnectionTracker> tracker_;
+ PeerConnectionTracker::Action action_;
+ blink::WebRTCSdpSemantics sdp_semantics_;
};
// Receives notifications from a PeerConnection object about state changes. The
@@ -1181,19 +933,8 @@ class RTCPeerConnectionHandler::Observer
friend class base::RefCountedThreadSafe<RTCPeerConnectionHandler::Observer>;
~Observer() override = default;
- void OnSignalingChange(
- PeerConnectionInterface::SignalingState new_state) override {
- if (!main_thread_->BelongsToCurrentThread()) {
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&RTCPeerConnectionHandler::Observer::OnSignalingChange,
- this, new_state));
- } else if (handler_) {
- handler_->OnSignalingChange(new_state);
- }
- }
-
// TODO(hbos): Remove once no longer mandatory to implement.
+ void OnSignalingChange(PeerConnectionInterface::SignalingState) override {}
void OnAddStream(rtc::scoped_refptr<MediaStreamInterface>) override {}
void OnRemoveStream(rtc::scoped_refptr<MediaStreamInterface>) override {}
@@ -1293,9 +1034,8 @@ RTCPeerConnectionHandler::RTCPeerConnectionHandler(
track_adapter_map_(
new WebRtcMediaStreamTrackAdapterMap(dependency_factory_,
task_runner)),
- stream_adapter_map_(new WebRtcMediaStreamAdapterMap(dependency_factory_,
- task_runner,
- track_adapter_map_)),
+ // This will be overwritten to the actual value used at Initialize().
+ sdp_semantics_(blink::WebRTCSdpSemantics::kDefault),
task_runner_(std::move(task_runner)),
weak_factory_(this) {
CHECK(client_);
@@ -1304,7 +1044,7 @@ RTCPeerConnectionHandler::RTCPeerConnectionHandler(
}
RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
Stop();
@@ -1317,15 +1057,16 @@ RTCPeerConnectionHandler::~RTCPeerConnectionHandler() {
}
void RTCPeerConnectionHandler::associateWithFrame(blink::WebLocalFrame* frame) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK(frame);
frame_ = frame;
}
bool RTCPeerConnectionHandler::Initialize(
const blink::WebRTCConfiguration& server_configuration,
- const blink::WebMediaConstraints& options) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ const blink::WebMediaConstraints& options,
+ blink::WebRTCSdpSemantics original_sdp_semantics_value) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK(frame_);
CHECK(!initialize_called_);
@@ -1334,6 +1075,9 @@ bool RTCPeerConnectionHandler::Initialize(
peer_connection_tracker_ =
RenderThreadImpl::current()->peer_connection_tracker()->AsWeakPtr();
+ sdp_semantics_ = server_configuration.sdp_semantics;
+ DCHECK(sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB ||
+ sdp_semantics_ == blink::WebRTCSdpSemantics::kUnifiedPlan);
GetNativeRtcConfiguration(server_configuration, &configuration_);
// Choose between RTC smoothness algorithm and prerenderer smoothing.
@@ -1363,12 +1107,9 @@ bool RTCPeerConnectionHandler::Initialize(
options, frame_);
}
- uma_observer_ = new rtc::RefCountedObject<PeerConnectionUMAObserver>();
- native_peer_connection_->RegisterUMAObserver(uma_observer_.get());
-
UMA_HISTOGRAM_ENUMERATION(
"WebRTC.PeerConnection.SdpSemanticRequested",
- GetSdpSemanticRequested(server_configuration.sdp_semantics),
+ GetSdpSemanticRequested(original_sdp_semantics_value),
kSdpSemanticRequestedMax);
return true;
@@ -1378,11 +1119,14 @@ bool RTCPeerConnectionHandler::InitializeForTest(
const blink::WebRTCConfiguration& server_configuration,
const blink::WebMediaConstraints& options,
const base::WeakPtr<PeerConnectionTracker>& peer_connection_tracker) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
CHECK(!initialize_called_);
initialize_called_ = true;
+ sdp_semantics_ = server_configuration.sdp_semantics;
+ DCHECK(sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB ||
+ sdp_semantics_ == blink::WebRTCSdpSemantics::kUnifiedPlan);
GetNativeRtcConfiguration(server_configuration, &configuration_);
peer_connection_observer_ =
@@ -1402,7 +1146,7 @@ bool RTCPeerConnectionHandler::InitializeForTest(
void RTCPeerConnectionHandler::CreateOffer(
const blink::WebRTCSessionDescriptionRequest& request,
const blink::WebMediaConstraints& options) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createOffer");
scoped_refptr<CreateSessionDescriptionRequest> description_request(
@@ -1424,7 +1168,7 @@ void RTCPeerConnectionHandler::CreateOffer(
void RTCPeerConnectionHandler::CreateOffer(
const blink::WebRTCSessionDescriptionRequest& request,
const blink::WebRTCOfferOptions& options) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createOffer");
scoped_refptr<CreateSessionDescriptionRequest> description_request(
@@ -1446,7 +1190,7 @@ void RTCPeerConnectionHandler::CreateOffer(
void RTCPeerConnectionHandler::CreateAnswer(
const blink::WebRTCSessionDescriptionRequest& request,
const blink::WebMediaConstraints& options) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createAnswer");
scoped_refptr<CreateSessionDescriptionRequest> description_request(
new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
@@ -1466,7 +1210,7 @@ void RTCPeerConnectionHandler::CreateAnswer(
void RTCPeerConnectionHandler::CreateAnswer(
const blink::WebRTCSessionDescriptionRequest& request,
const blink::WebRTCAnswerOptions& options) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createAnswer");
scoped_refptr<CreateSessionDescriptionRequest> description_request(
new rtc::RefCountedObject<CreateSessionDescriptionRequest>(
@@ -1491,7 +1235,7 @@ bool IsOfferOrAnswer(const webrtc::SessionDescriptionInterface* native_desc) {
void RTCPeerConnectionHandler::SetLocalDescription(
const blink::WebRTCVoidRequest& request,
const blink::WebRTCSessionDescription& description) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::setLocalDescription");
std::string sdp = description.Sdp().Utf8();
@@ -1532,18 +1276,27 @@ void RTCPeerConnectionHandler::SetLocalDescription(
}
}
- scoped_refptr<SetLocalDescriptionRequest> set_request(
- new rtc::RefCountedObject<SetLocalDescriptionRequest>(
- task_runner_, request, weak_factory_.GetWeakPtr(),
- peer_connection_tracker_,
- PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION));
+ scoped_refptr<WebRtcSetDescriptionObserverImpl> content_observer(
+ new WebRtcSetDescriptionObserverImpl(
+ weak_factory_.GetWeakPtr(), request, peer_connection_tracker_,
+ task_runner_, PeerConnectionTracker::ACTION_SET_LOCAL_DESCRIPTION,
+ sdp_semantics_));
+
+ bool surface_receivers_only =
+ (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB);
+ scoped_refptr<webrtc::SetSessionDescriptionObserver> webrtc_observer(
+ WebRtcSetLocalDescriptionObserverHandler::Create(
+ task_runner_, signaling_thread(), native_peer_connection_,
+ track_adapter_map_, content_observer, surface_receivers_only)
+ .get());
signaling_thread()->PostTask(
FROM_HERE,
base::BindOnce(
&RunClosureWithTrace,
base::Bind(&webrtc::PeerConnectionInterface::SetLocalDescription,
- native_peer_connection_, base::RetainedRef(set_request),
+ native_peer_connection_,
+ base::RetainedRef(webrtc_observer),
base::Unretained(native_desc)),
"SetLocalDescription"));
}
@@ -1551,7 +1304,7 @@ void RTCPeerConnectionHandler::SetLocalDescription(
void RTCPeerConnectionHandler::SetRemoteDescription(
const blink::WebRTCVoidRequest& request,
const blink::WebRTCSessionDescription& description) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::setRemoteDescription");
std::string sdp = description.Sdp().Utf8();
std::string type = description.GetType().Utf8();
@@ -1592,15 +1345,19 @@ void RTCPeerConnectionHandler::SetRemoteDescription(
}
}
- scoped_refptr<WebRtcSetRemoteDescriptionObserverImpl> content_observer(
- new WebRtcSetRemoteDescriptionObserverImpl(
+ scoped_refptr<WebRtcSetDescriptionObserverImpl> content_observer(
+ new WebRtcSetDescriptionObserverImpl(
weak_factory_.GetWeakPtr(), request, peer_connection_tracker_,
- task_runner_));
+ task_runner_, PeerConnectionTracker::ACTION_SET_REMOTE_DESCRIPTION,
+ sdp_semantics_));
+ bool surface_receivers_only =
+ (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB);
rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface>
webrtc_observer(WebRtcSetRemoteDescriptionObserverHandler::Create(
- task_runner_, native_peer_connection_,
- stream_adapter_map_, content_observer)
+ task_runner_, signaling_thread(),
+ native_peer_connection_, track_adapter_map_,
+ content_observer, surface_receivers_only)
.get());
signaling_thread()->PostTask(
@@ -1619,7 +1376,7 @@ void RTCPeerConnectionHandler::SetRemoteDescription(
}
blink::WebRTCSessionDescription RTCPeerConnectionHandler::LocalDescription() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::localDescription");
// Since local_description returns a pointer to a non-reference-counted object
@@ -1640,7 +1397,7 @@ blink::WebRTCSessionDescription RTCPeerConnectionHandler::LocalDescription() {
}
blink::WebRTCSessionDescription RTCPeerConnectionHandler::RemoteDescription() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::remoteDescription");
// Since local_description returns a pointer to a non-reference-counted object
// that lives on the signaling thread, we cannot fetch a pointer to it and use
@@ -1661,7 +1418,7 @@ blink::WebRTCSessionDescription RTCPeerConnectionHandler::RemoteDescription() {
webrtc::RTCErrorType RTCPeerConnectionHandler::SetConfiguration(
const blink::WebRTCConfiguration& blink_config) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::setConfiguration");
GetNativeRtcConfiguration(blink_config, &configuration_);
@@ -1680,7 +1437,7 @@ webrtc::RTCErrorType RTCPeerConnectionHandler::SetConfiguration(
bool RTCPeerConnectionHandler::AddICECandidate(
const blink::WebRTCVoidRequest& request,
scoped_refptr<blink::WebRTCICECandidate> candidate) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::addICECandidate");
// Libjingle currently does not accept callbacks for addICECandidate.
// For that reason we are going to call callbacks from here.
@@ -1698,7 +1455,7 @@ bool RTCPeerConnectionHandler::AddICECandidate(
bool RTCPeerConnectionHandler::AddICECandidate(
scoped_refptr<blink::WebRTCICECandidate> candidate) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::addICECandidate");
std::unique_ptr<webrtc::IceCandidateInterface> native_candidate(
dependency_factory_->CreateIceCandidate(candidate->SdpMid().Utf8(),
@@ -1724,7 +1481,7 @@ bool RTCPeerConnectionHandler::AddICECandidate(
void RTCPeerConnectionHandler::OnaddICECandidateResult(
const blink::WebRTCVoidRequest& webkit_request, bool result) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnaddICECandidateResult");
if (!result) {
// We don't have the actual error code from the libjingle, so for now
@@ -1739,7 +1496,7 @@ void RTCPeerConnectionHandler::OnaddICECandidateResult(
void RTCPeerConnectionHandler::GetStats(
const blink::WebRTCStatsRequest& request) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
scoped_refptr<LocalRTCStatsRequest> inner_request(
new rtc::RefCountedObject<LocalRTCStatsRequest>(request));
getStats(inner_request);
@@ -1747,7 +1504,7 @@ void RTCPeerConnectionHandler::GetStats(
void RTCPeerConnectionHandler::getStats(
const scoped_refptr<LocalRTCStatsRequest>& request) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::getStats");
rtc::scoped_refptr<webrtc::StatsObserver> observer(
@@ -1777,7 +1534,7 @@ void RTCPeerConnectionHandler::GetStats(
webrtc::StatsObserver* observer,
webrtc::PeerConnectionInterface::StatsOutputLevel level,
rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> selector) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
signaling_thread()->PostTask(
FROM_HERE,
base::BindOnce(&GetStatsOnSignalingThread, native_peer_connection_, level,
@@ -1786,96 +1543,347 @@ void RTCPeerConnectionHandler::GetStats(
void RTCPeerConnectionHandler::GetStats(
std::unique_ptr<blink::WebRTCStatsReportCallback> callback) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
signaling_thread()->PostTask(
FROM_HERE, base::BindOnce(&GetRTCStatsOnSignalingThread, task_runner_,
native_peer_connection_, std::move(callback)));
}
-std::unique_ptr<blink::WebRTCRtpSender> RTCPeerConnectionHandler::AddTrack(
+webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+RTCPeerConnectionHandler::AddTransceiverWithTrack(
+ const blink::WebMediaStreamTrack& web_track,
+ const webrtc::RtpTransceiverInit& init) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref =
+ track_adapter_map_->GetOrCreateLocalTrackAdapter(web_track);
+ TransceiverStateSurfacer transceiver_state_surfacer(task_runner_,
+ signaling_thread());
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ error_or_transceiver;
+ RunSynchronousClosureOnSignalingThread(
+ base::BindRepeating(
+ &RTCPeerConnectionHandler::AddTransceiverWithTrackOnSignalingThread,
+ base::Unretained(this), base::RetainedRef(track_ref->webrtc_track()),
+ base::ConstRef(init), base::Unretained(&transceiver_state_surfacer),
+ base::Unretained(&error_or_transceiver)),
+ "AddTransceiverWithTrackOnSignalingThread");
+ if (!error_or_transceiver.ok()) {
+ // Don't leave the surfacer in a pending state.
+ transceiver_state_surfacer.ObtainStates();
+ return error_or_transceiver.MoveError();
+ }
+
+ auto transceiver_states = transceiver_state_surfacer.ObtainStates();
+ auto transceiver =
+ CreateOrUpdateTransceiver(std::move(transceiver_states[0]));
+ std::unique_ptr<blink::WebRTCRtpTransceiver> web_transceiver =
+ std::move(transceiver);
+ return std::move(web_transceiver);
+}
+
+void RTCPeerConnectionHandler::AddTransceiverWithTrackOnSignalingThread(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
+ webrtc::RtpTransceiverInit init,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>*
+ error_or_transceiver) {
+ *error_or_transceiver =
+ native_peer_connection_->AddTransceiver(webrtc_track, init);
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> transceivers;
+ if (error_or_transceiver->ok())
+ transceivers.push_back(error_or_transceiver->value());
+ transceiver_state_surfacer->Initialize(track_adapter_map_, transceivers);
+}
+
+webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+RTCPeerConnectionHandler::AddTransceiverWithKind(
+ std::string kind,
+ const webrtc::RtpTransceiverInit& init) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ cricket::MediaType media_type;
+ if (kind == webrtc::MediaStreamTrackInterface::kAudioKind) {
+ media_type = cricket::MEDIA_TYPE_AUDIO;
+ } else {
+ DCHECK_EQ(kind, webrtc::MediaStreamTrackInterface::kVideoKind);
+ media_type = cricket::MEDIA_TYPE_VIDEO;
+ }
+ TransceiverStateSurfacer transceiver_state_surfacer(task_runner_,
+ signaling_thread());
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ error_or_transceiver;
+ RunSynchronousClosureOnSignalingThread(
+ base::BindRepeating(&RTCPeerConnectionHandler::
+ AddTransceiverWithMediaTypeOnSignalingThread,
+ base::Unretained(this), base::ConstRef(media_type),
+ base::ConstRef(init),
+ base::Unretained(&transceiver_state_surfacer),
+ base::Unretained(&error_or_transceiver)),
+ "AddTransceiverWithMediaTypeOnSignalingThread");
+ if (!error_or_transceiver.ok()) {
+ // Don't leave the surfacer in a pending state.
+ transceiver_state_surfacer.ObtainStates();
+ return error_or_transceiver.MoveError();
+ }
+
+ auto transceiver_states = transceiver_state_surfacer.ObtainStates();
+ auto transceiver =
+ CreateOrUpdateTransceiver(std::move(transceiver_states[0]));
+ std::unique_ptr<blink::WebRTCRtpTransceiver> web_transceiver =
+ std::move(transceiver);
+ return std::move(web_transceiver);
+}
+
+void RTCPeerConnectionHandler::AddTransceiverWithMediaTypeOnSignalingThread(
+ cricket::MediaType media_type,
+ webrtc::RtpTransceiverInit init,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>*
+ error_or_transceiver) {
+ *error_or_transceiver =
+ native_peer_connection_->AddTransceiver(media_type, init);
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> transceivers;
+ if (error_or_transceiver->ok())
+ transceivers.push_back(error_or_transceiver->value());
+ transceiver_state_surfacer->Initialize(track_adapter_map_, transceivers);
+}
+
+webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+RTCPeerConnectionHandler::AddTrack(
const blink::WebMediaStreamTrack& track,
const blink::WebVector<blink::WebMediaStream>& streams) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::AddTrack");
- // Get or create the associated track and stream adapters.
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter =
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref =
track_adapter_map_->GetOrCreateLocalTrackAdapter(track);
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_adapters(streams.size());
- std::vector<webrtc::MediaStreamInterface*> webrtc_streams(streams.size());
- for (size_t i = 0; i < streams.size(); ++i) {
- stream_adapters[i] =
- stream_adapter_map_->GetOrCreateLocalStreamAdapter(streams[i]);
- webrtc_streams[i] = stream_adapters[i]->adapter().webrtc_stream().get();
- }
-
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender =
- native_peer_connection_->AddTrack(track_adapter->webrtc_track(),
- webrtc_streams);
- if (!webrtc_sender)
- return nullptr;
- DCHECK(FindSender(RTCRtpSender::getId(webrtc_sender)) == rtp_senders_.end());
- rtp_senders_.push_back(std::make_unique<RTCRtpSender>(
- native_peer_connection_, task_runner_, signaling_thread(),
- stream_adapter_map_, std::move(webrtc_sender), std::move(track_adapter),
- std::move(stream_adapters)));
- for (const auto& stream_ref : rtp_senders_.back()->stream_refs()) {
- if (GetLocalStreamUsageCount(rtp_senders_,
- stream_ref->adapter().web_stream()) == 1u) {
+ std::vector<std::string> stream_ids(streams.size());
+ for (size_t i = 0; i < streams.size(); ++i)
+ stream_ids[i] = streams[i].Id().Utf8();
+
+ // Invoke native AddTrack() on the signaling thread and surface the resulting
+ // transceiver (Plan B: sender only).
+ // TODO(hbos): Implement and surface full transceiver support under Unified
+ // Plan. https://crbug.com/777617
+ TransceiverStateSurfacer transceiver_state_surfacer(task_runner_,
+ signaling_thread());
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>>
+ error_or_sender;
+ RunSynchronousClosureOnSignalingThread(
+ base::BindRepeating(
+ &RTCPeerConnectionHandler::AddTrackOnSignalingThread,
+ base::Unretained(this), base::RetainedRef(track_ref->webrtc_track()),
+ std::move(stream_ids), base::Unretained(&transceiver_state_surfacer),
+ base::Unretained(&error_or_sender)),
+ "AddTrackOnSignalingThread");
+ DCHECK(transceiver_state_surfacer.is_initialized());
+ if (!error_or_sender.ok()) {
+ // Don't leave the surfacer in a pending state.
+ transceiver_state_surfacer.ObtainStates();
+ return error_or_sender.MoveError();
+ }
+ track_metrics_.AddTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetricsKind(track),
+ track.Id().Utf8());
+
+ auto transceiver_states = transceiver_state_surfacer.ObtainStates();
+ DCHECK_EQ(transceiver_states.size(), 1u);
+ auto transceiver_state = std::move(transceiver_states[0]);
+
+ std::unique_ptr<blink::WebRTCRtpTransceiver> web_transceiver;
+ if (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB) {
+ // Plan B: Create sender only.
+ DCHECK(transceiver_state.sender_state());
+ auto webrtc_sender = transceiver_state.sender_state()->webrtc_sender();
+ DCHECK(FindSender(RTCRtpSender::getId(webrtc_sender.get())) ==
+ rtp_senders_.end());
+ RtpSenderState sender_state = transceiver_state.MoveSenderState();
+ DCHECK(sender_state.is_initialized());
+ rtp_senders_.push_back(std::make_unique<RTCRtpSender>(
+ native_peer_connection_, track_adapter_map_, std::move(sender_state)));
+ web_transceiver = std::make_unique<RTCRtpSenderOnlyTransceiver>(
+ std::make_unique<RTCRtpSender>(*rtp_senders_.back().get()));
+ } else {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ // Unified Plan: Create or recycle a transceiver.
+ auto transceiver = CreateOrUpdateTransceiver(std::move(transceiver_state));
+ web_transceiver = std::move(transceiver);
+ }
+ if (peer_connection_tracker_) {
+ size_t transceiver_index = GetTransceiverIndex(*web_transceiver.get());
+ peer_connection_tracker_->TrackAddTransceiver(
+ this, PeerConnectionTracker::TransceiverUpdatedReason::kAddTrack,
+ *web_transceiver.get(), transceiver_index);
+ }
+ for (const auto& stream_id : rtp_senders_.back()->state().stream_ids()) {
+ if (GetLocalStreamUsageCount(rtp_senders_, stream_id) == 1u) {
// This is the first occurrence of this stream.
- if (peer_connection_tracker_) {
- peer_connection_tracker_->TrackAddStream(
- this, stream_ref->adapter().web_stream(),
- PeerConnectionTracker::SOURCE_LOCAL);
- }
PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
- track_metrics_.AddStream(MediaStreamTrackMetrics::SENT_STREAM,
- stream_ref->adapter().webrtc_stream().get());
}
}
- return rtp_senders_.back()->ShallowCopy();
+ return web_transceiver;
+}
+
+void RTCPeerConnectionHandler::AddTrackOnSignalingThread(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ std::vector<std::string> stream_ids,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>>*
+ error_or_sender) {
+ *error_or_sender = native_peer_connection_->AddTrack(track, stream_ids);
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> transceivers;
+ if (error_or_sender->ok()) {
+ auto sender = error_or_sender->value();
+ if (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB) {
+ transceivers = {new SurfaceSenderStateOnly(sender)};
+ } else {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ rtc::scoped_refptr<webrtc::RtpTransceiverInterface>
+ transceiver_for_sender = nullptr;
+ for (const auto& transceiver :
+ native_peer_connection_->GetTransceivers()) {
+ if (transceiver->sender() == sender) {
+ transceiver_for_sender = transceiver;
+ break;
+ }
+ }
+ DCHECK(transceiver_for_sender);
+ transceivers = {transceiver_for_sender};
+ }
+ }
+ transceiver_state_surfacer->Initialize(track_adapter_map_,
+ std::move(transceivers));
}
-bool RTCPeerConnectionHandler::RemoveTrack(blink::WebRTCRtpSender* web_sender) {
- DCHECK(thread_checker_.CalledOnValidThread());
+webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+RTCPeerConnectionHandler::RemoveTrack(blink::WebRTCRtpSender* web_sender) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::RemoveTrack");
+ if (sdp_semantics_ == blink::WebRTCSdpSemantics::kPlanB) {
+ if (RemoveTrackPlanB(web_sender)) {
+ // In Plan B, null indicates success.
+ std::unique_ptr<blink::WebRTCRtpTransceiver> web_transceiver = nullptr;
+ return std::move(web_transceiver);
+ }
+ // TODO(hbos): Surface RTCError from third_party/webrtc when
+ // peerconnectioninterface.h is updated. https://crbug.com/webrtc/9534
+ return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE);
+ }
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ return RemoveTrackUnifiedPlan(web_sender);
+}
+
+bool RTCPeerConnectionHandler::RemoveTrackPlanB(
+ blink::WebRTCRtpSender* web_sender) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kPlanB);
+ auto web_track = web_sender->Track();
auto it = FindSender(web_sender->Id());
if (it == rtp_senders_.end())
return false;
if (!(*it)->RemoveFromPeerConnection(native_peer_connection_.get()))
return false;
- auto stream_refs = (*it)->stream_refs();
- // TODO(hbos): In Unified Plan, senders are never removed. The lower layer
- // needs to tell us what to do with the sender: Update its states and/or
- // remove it. https://crbug.com/799030
+ track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kSend,
+ MediaStreamTrackMetricsKind(web_track),
+ web_track.Id().Utf8());
+ if (peer_connection_tracker_) {
+ auto sender_only_transceiver =
+ std::make_unique<RTCRtpSenderOnlyTransceiver>(
+ std::make_unique<RTCRtpSender>(*it->get()));
+ size_t sender_index = GetTransceiverIndex(*sender_only_transceiver);
+ peer_connection_tracker_->TrackRemoveTransceiver(
+ this, PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack,
+ *sender_only_transceiver.get(), sender_index);
+ }
+ std::vector<std::string> stream_ids = (*it)->state().stream_ids();
rtp_senders_.erase(it);
- for (const auto& stream_ref : stream_refs) {
- if (GetLocalStreamUsageCount(rtp_senders_,
- stream_ref->adapter().web_stream()) == 0u) {
+ for (const auto& stream_id : stream_ids) {
+ if (GetLocalStreamUsageCount(rtp_senders_, stream_id) == 0u) {
// This was the last occurrence of this stream.
- if (peer_connection_tracker_) {
- peer_connection_tracker_->TrackRemoveStream(
- this, stream_ref->adapter().web_stream(),
- PeerConnectionTracker::SOURCE_LOCAL);
- }
PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter();
- track_metrics_.RemoveStream(MediaStreamTrackMetrics::SENT_STREAM,
- stream_ref->adapter().webrtc_stream().get());
}
}
return true;
}
+webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+RTCPeerConnectionHandler::RemoveTrackUnifiedPlan(
+ blink::WebRTCRtpSender* web_sender) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ auto it = FindSender(web_sender->Id());
+ if (it == rtp_senders_.end())
+ return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER);
+ const auto& sender = *it;
+ auto webrtc_sender = sender->state().webrtc_sender();
+
+ TransceiverStateSurfacer transceiver_state_surfacer(task_runner_,
+ signaling_thread());
+ bool result;
+ RunSynchronousClosureOnSignalingThread(
+ base::BindRepeating(
+ &RTCPeerConnectionHandler::RemoveTrackUnifiedPlanOnSignalingThread,
+ base::Unretained(this), base::RetainedRef(webrtc_sender),
+ base::Unretained(&transceiver_state_surfacer),
+ base::Unretained(&result)),
+ "RemoveTrackUnifiedPlanOnSignalingThread");
+ DCHECK(transceiver_state_surfacer.is_initialized());
+ if (!result) {
+ // Don't leave the surfacer in a pending state.
+ transceiver_state_surfacer.ObtainStates();
+ // TODO(hbos): Surface RTCError from third_party/webrtc when
+ // peerconnectioninterface.h is updated. https://crbug.com/webrtc/9534
+ return webrtc::RTCError(webrtc::RTCErrorType::INTERNAL_ERROR);
+ }
+
+ auto transceiver_states = transceiver_state_surfacer.ObtainStates();
+ DCHECK_EQ(transceiver_states.size(), 1u);
+ auto transceiver_state = std::move(transceiver_states[0]);
+
+ // Update the transceiver.
+ auto transceiver = CreateOrUpdateTransceiver(std::move(transceiver_state));
+ if (peer_connection_tracker_) {
+ size_t transceiver_index = GetTransceiverIndex(*transceiver);
+ peer_connection_tracker_->TrackModifyTransceiver(
+ this, PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack,
+ *transceiver.get(), transceiver_index);
+ }
+ std::unique_ptr<blink::WebRTCRtpTransceiver> web_transceiver =
+ std::move(transceiver);
+ return web_transceiver;
+}
+
+void RTCPeerConnectionHandler::RemoveTrackUnifiedPlanOnSignalingThread(
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ bool* result) {
+ *result = native_peer_connection_->RemoveTrack(sender);
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> transceivers;
+ if (*result) {
+ rtc::scoped_refptr<webrtc::RtpTransceiverInterface> transceiver_for_sender =
+ nullptr;
+ for (const auto& transceiver : native_peer_connection_->GetTransceivers()) {
+ if (transceiver->sender() == sender) {
+ transceiver_for_sender = transceiver;
+ break;
+ }
+ }
+ DCHECK(transceiver_for_sender);
+ transceivers = {transceiver_for_sender};
+ }
+ transceiver_state_surfacer->Initialize(track_adapter_map_,
+ std::move(transceivers));
+}
+
void RTCPeerConnectionHandler::CloseClientPeerConnection() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (!is_closed_)
client_->ClosePeerConnection();
}
void RTCPeerConnectionHandler::StartEventLog(IPC::PlatformFileForTransit file,
int64_t max_file_size_bytes) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
DCHECK(file != IPC::InvalidPlatformFileForTransit());
// TODO(eladalon): StartRtcEventLog() return value is not useful; remove it
// or find a way to be able to use it.
@@ -1885,7 +1893,7 @@ void RTCPeerConnectionHandler::StartEventLog(IPC::PlatformFileForTransit file,
}
void RTCPeerConnectionHandler::StartEventLog() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
// TODO(eladalon): StartRtcEventLog() return value is not useful; remove it
// or find a way to be able to use it.
// https://crbug.com/775415
@@ -1896,13 +1904,13 @@ void RTCPeerConnectionHandler::StartEventLog() {
}
void RTCPeerConnectionHandler::StopEventLog() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
native_peer_connection_->StopRtcEventLog();
}
void RTCPeerConnectionHandler::OnWebRtcEventLogWrite(
const std::string& output) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (peer_connection_tracker_) {
peer_connection_tracker_->TrackRtcEventLogWrite(this, output);
}
@@ -1911,7 +1919,7 @@ void RTCPeerConnectionHandler::OnWebRtcEventLogWrite(
blink::WebRTCDataChannelHandler* RTCPeerConnectionHandler::CreateDataChannel(
const blink::WebString& label,
const blink::WebRTCDataChannelInit& init) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::createDataChannel");
DVLOG(1) << "createDataChannel label " << label.Utf8();
@@ -1943,7 +1951,7 @@ blink::WebRTCDataChannelHandler* RTCPeerConnectionHandler::CreateDataChannel(
}
void RTCPeerConnectionHandler::Stop() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
DVLOG(1) << "RTCPeerConnectionHandler::stop";
if (is_closed_ || !native_peer_connection_.get())
@@ -1964,22 +1972,20 @@ blink::WebString RTCPeerConnectionHandler::Id() const {
void RTCPeerConnectionHandler::OnSignalingChange(
webrtc::PeerConnectionInterface::SignalingState new_state) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnSignalingChange");
- blink::WebRTCPeerConnectionHandlerClient::SignalingState state =
- GetWebKitSignalingState(new_state);
if (peer_connection_tracker_)
- peer_connection_tracker_->TrackSignalingStateChange(this, state);
+ peer_connection_tracker_->TrackSignalingStateChange(this, new_state);
if (!is_closed_)
- client_->DidChangeSignalingState(state);
+ client_->DidChangeSignalingState(new_state);
}
// Called any time the IceConnectionState changes
void RTCPeerConnectionHandler::OnIceConnectionChange(
webrtc::PeerConnectionInterface::IceConnectionState new_state) {
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceConnectionChange");
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
ReportICEState(new_state);
if (new_state == webrtc::PeerConnectionInterface::kIceConnectionChecking) {
ice_connection_checking_start_ = base::TimeTicks::Now();
@@ -2014,7 +2020,7 @@ void RTCPeerConnectionHandler::OnIceConnectionChange(
// Called any time the IceGatheringState changes
void RTCPeerConnectionHandler::OnIceGatheringChange(
webrtc::PeerConnectionInterface::IceGatheringState new_state) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceGatheringChange");
if (new_state == webrtc::PeerConnectionInterface::kIceGatheringComplete) {
@@ -2039,7 +2045,7 @@ void RTCPeerConnectionHandler::OnIceGatheringChange(
}
void RTCPeerConnectionHandler::OnRenegotiationNeeded() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnRenegotiationNeeded");
if (peer_connection_tracker_)
peer_connection_tracker_->TrackOnRenegotiationNeeded(this);
@@ -2047,89 +2053,129 @@ void RTCPeerConnectionHandler::OnRenegotiationNeeded() {
client_->NegotiationNeeded();
}
-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::OnAddRemoteTrack");
-
- for (const auto& remote_stream_adapter_ref : remote_stream_adapter_refs) {
+void RTCPeerConnectionHandler::OnAddReceiverPlanB(
+ RtpReceiverState receiver_state) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ DCHECK(receiver_state.is_initialized());
+ TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnAddReceiverPlanB");
+ auto web_track = receiver_state.track_ref()->web_track();
+ // Update metrics.
+ track_metrics_.AddTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetricsKind(web_track),
+ web_track.Id().Utf8());
+ for (const auto& stream_id : receiver_state.stream_ids()) {
// New remote stream?
- if (GetRemoteStreamUsageCount(
- rtp_receivers_,
- remote_stream_adapter_ref->adapter().webrtc_stream().get()) == 0) {
- // 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);
- }
+ if (!IsRemoteStream(rtp_receivers_, stream_id))
PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
- track_metrics_.AddStream(
- MediaStreamTrackMetrics::RECEIVED_STREAM,
- remote_stream_adapter_ref->adapter().webrtc_stream().get());
- }
}
-
- 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>(
- native_peer_connection_, task_runner_, signaling_thread(),
- webrtc_receiver.get(), std::move(remote_track_adapter_ref),
- std::move(remote_stream_adapter_refs))))
- .first->second;
+ uintptr_t receiver_id =
+ RTCRtpReceiver::getId(receiver_state.webrtc_receiver().get());
+ DCHECK(FindReceiver(receiver_id) == rtp_receivers_.end());
+ auto rtp_receiver = std::make_unique<RTCRtpReceiver>(
+ native_peer_connection_, std::move(receiver_state));
+ rtp_receivers_.push_back(std::make_unique<RTCRtpReceiver>(*rtp_receiver));
+ if (peer_connection_tracker_) {
+ auto receiver_only_transceiver =
+ std::make_unique<RTCRtpReceiverOnlyTransceiver>(
+ std::make_unique<RTCRtpReceiver>(*rtp_receiver));
+ size_t receiver_index = GetTransceiverIndex(*receiver_only_transceiver);
+ peer_connection_tracker_->TrackAddTransceiver(
+ this,
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *receiver_only_transceiver.get(), receiver_index);
+ }
if (!is_closed_)
- client_->DidAddRemoteTrack(rtp_receiver->ShallowCopy());
+ client_->DidAddReceiverPlanB(rtp_receiver->ShallowCopy());
}
-void RTCPeerConnectionHandler::OnRemoveRemoteTrack(
- scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver) {
- DCHECK(thread_checker_.CalledOnValidThread());
- TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnRemoveRemoteTrack");
+void RTCPeerConnectionHandler::OnRemoveReceiverPlanB(uintptr_t receiver_id) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+ TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnRemoveReceiverPlanB");
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- remote_stream_adapter_refs;
- {
- uintptr_t receiver_id = RTCRtpReceiver::getId(webrtc_receiver.get());
- auto it = rtp_receivers_.find(receiver_id);
- DCHECK(it != rtp_receivers_.end());
- 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) {
- // 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);
+ auto it = FindReceiver(receiver_id);
+ DCHECK(it != rtp_receivers_.end());
+ auto receiver = std::make_unique<RTCRtpReceiver>(*(*it));
+ // Update metrics.
+ track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive,
+ MediaStreamTrackMetricsKind(receiver->Track()),
+ receiver->Track().Id().Utf8());
+ if (peer_connection_tracker_) {
+ auto receiver_only_transceiver =
+ std::make_unique<RTCRtpReceiverOnlyTransceiver>(
+ std::make_unique<RTCRtpReceiver>(*receiver));
+ size_t receiver_index = GetTransceiverIndex(*receiver_only_transceiver);
+ peer_connection_tracker_->TrackRemoveTransceiver(
+ this,
+ PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription,
+ *receiver_only_transceiver.get(), receiver_index);
+ }
+ rtp_receivers_.erase(it);
+ for (const auto& stream_id : receiver->state().stream_ids()) {
+ // This was the last occurence of the stream?
+ if (!IsRemoteStream(rtp_receivers_, stream_id))
+ PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter();
+ }
+ if (!is_closed_)
+ client_->DidRemoveReceiverPlanB(std::move(receiver));
+}
+
+void RTCPeerConnectionHandler::OnModifyTransceivers(
+ std::vector<RtpTransceiverState> transceiver_states,
+ bool is_remote_description) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ std::vector<std::unique_ptr<blink::WebRTCRtpTransceiver>> web_transceivers(
+ transceiver_states.size());
+ PeerConnectionTracker::TransceiverUpdatedReason update_reason =
+ !is_remote_description ? PeerConnectionTracker::TransceiverUpdatedReason::
+ kSetLocalDescription
+ : PeerConnectionTracker::TransceiverUpdatedReason::
+ kSetRemoteDescription;
+ for (size_t i = 0; i < transceiver_states.size(); ++i) {
+ // Figure out if this transceiver is new or if setting the state modified
+ // the transceiver such that it should be logged by the
+ // |peer_connection_tracker_|.
+ uintptr_t transceiver_id = RTCRtpTransceiver::GetId(
+ transceiver_states[i].webrtc_transceiver().get());
+ auto it = FindTransceiver(transceiver_id);
+ bool transceiver_is_new = (it == rtp_transceivers_.end());
+ bool transceiver_was_modified = false;
+ if (!transceiver_is_new) {
+ const auto& previous_state = (*it)->state();
+ transceiver_was_modified =
+ previous_state.mid() != transceiver_states[i].mid() ||
+ previous_state.stopped() != transceiver_states[i].stopped() ||
+ previous_state.direction() != transceiver_states[i].direction() ||
+ previous_state.current_direction() !=
+ transceiver_states[i].current_direction();
+ }
+
+ // Update the transceiver.
+ web_transceivers[i] =
+ CreateOrUpdateTransceiver(std::move(transceiver_states[i]));
+
+ // Log a "transcieverAdded" or "transceiverModified" event in
+ // chrome://webrtc-internals if new or modified.
+ if (peer_connection_tracker_ &&
+ (transceiver_is_new || transceiver_was_modified)) {
+ size_t transceiver_index = GetTransceiverIndex(*web_transceivers[i]);
+ if (transceiver_is_new) {
+ peer_connection_tracker_->TrackAddTransceiver(
+ this, update_reason, *web_transceivers[i].get(), transceiver_index);
+ } else if (transceiver_was_modified) {
+ peer_connection_tracker_->TrackModifyTransceiver(
+ this, update_reason, *web_transceivers[i].get(), transceiver_index);
}
}
}
+ if (!is_closed_) {
+ client_->DidModifyTransceivers(std::move(web_transceivers),
+ is_remote_description);
+ }
}
void RTCPeerConnectionHandler::OnDataChannel(
std::unique_ptr<RtcDataChannelHandler> handler) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnDataChannelImpl");
if (peer_connection_tracker_) {
@@ -2144,7 +2190,7 @@ void RTCPeerConnectionHandler::OnDataChannel(
void RTCPeerConnectionHandler::OnIceCandidate(
const std::string& sdp, const std::string& sdp_mid, int sdp_mline_index,
int component, int address_family) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnIceCandidateImpl");
scoped_refptr<blink::WebRTCICECandidate> web_candidate =
blink::WebRTCICECandidate::Create(blink::WebString::FromUTF8(sdp),
@@ -2224,16 +2270,103 @@ RTCPeerConnectionHandler::FindSender(uintptr_t id) {
return rtp_senders_.end();
}
+std::vector<std::unique_ptr<RTCRtpReceiver>>::iterator
+RTCPeerConnectionHandler::FindReceiver(uintptr_t id) {
+ for (auto it = rtp_receivers_.begin(); it != rtp_receivers_.end(); ++it) {
+ if ((*it)->Id() == id)
+ return it;
+ }
+ return rtp_receivers_.end();
+}
+
+std::vector<std::unique_ptr<RTCRtpTransceiver>>::iterator
+RTCPeerConnectionHandler::FindTransceiver(uintptr_t id) {
+ for (auto it = rtp_transceivers_.begin(); it != rtp_transceivers_.end();
+ ++it) {
+ if ((*it)->Id() == id)
+ return it;
+ }
+ return rtp_transceivers_.end();
+}
+
+size_t RTCPeerConnectionHandler::GetTransceiverIndex(
+ const blink::WebRTCRtpTransceiver& web_transceiver) {
+ if (web_transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver) {
+ for (size_t i = 0; i < rtp_transceivers_.size(); ++i) {
+ if (web_transceiver.Id() == rtp_transceivers_[i]->Id())
+ return i;
+ }
+ } else if (web_transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly) {
+ const auto web_sender = web_transceiver.Sender();
+ for (size_t i = 0; i < rtp_senders_.size(); ++i) {
+ if (web_sender->Id() == rtp_senders_[i]->Id())
+ return i;
+ }
+ } else {
+ RTC_DCHECK(
+ web_transceiver.ImplementationType() ==
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly);
+ const auto web_receiver = web_transceiver.Receiver();
+ for (size_t i = 0; i < rtp_receivers_.size(); ++i) {
+ if (web_receiver->Id() == rtp_receivers_[i]->Id())
+ return i;
+ }
+ }
+ NOTREACHED();
+ return 0u;
+}
+
+std::unique_ptr<RTCRtpTransceiver>
+RTCPeerConnectionHandler::CreateOrUpdateTransceiver(
+ RtpTransceiverState transceiver_state) {
+ DCHECK_EQ(sdp_semantics_, blink::WebRTCSdpSemantics::kUnifiedPlan);
+ DCHECK(transceiver_state.is_initialized());
+ DCHECK(transceiver_state.sender_state());
+ DCHECK(transceiver_state.receiver_state());
+ auto webrtc_transceiver = transceiver_state.webrtc_transceiver();
+ auto webrtc_sender = transceiver_state.sender_state()->webrtc_sender();
+ auto webrtc_receiver = transceiver_state.receiver_state()->webrtc_receiver();
+
+ std::unique_ptr<RTCRtpTransceiver> transceiver;
+ auto it = FindTransceiver(RTCRtpTransceiver::GetId(webrtc_transceiver.get()));
+ if (it == rtp_transceivers_.end()) {
+ // Create a new transceiver, including a sender and a receiver.
+ transceiver = std::make_unique<RTCRtpTransceiver>(
+ native_peer_connection_, track_adapter_map_,
+ std::move(transceiver_state));
+ rtp_transceivers_.push_back(transceiver->ShallowCopy());
+ DCHECK(FindSender(RTCRtpSender::getId(webrtc_sender.get())) ==
+ rtp_senders_.end());
+ rtp_senders_.push_back(
+ std::make_unique<RTCRtpSender>(*transceiver->content_sender()));
+ DCHECK(FindReceiver(RTCRtpReceiver::getId(webrtc_receiver.get())) ==
+ rtp_receivers_.end());
+ rtp_receivers_.push_back(
+ std::make_unique<RTCRtpReceiver>(*transceiver->content_receiver()));
+ } else {
+ // Update the transceiver. This also updates the sender and receiver.
+ transceiver = (*it)->ShallowCopy();
+ transceiver->set_state(std::move(transceiver_state));
+ DCHECK(FindSender(RTCRtpSender::getId(webrtc_sender.get())) !=
+ rtp_senders_.end());
+ DCHECK(FindReceiver(RTCRtpReceiver::getId(webrtc_receiver.get())) !=
+ rtp_receivers_.end());
+ }
+ return transceiver;
+}
+
scoped_refptr<base::SingleThreadTaskRunner>
RTCPeerConnectionHandler::signaling_thread() const {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
return dependency_factory_->GetWebRtcSignalingThread();
}
void RTCPeerConnectionHandler::RunSynchronousClosureOnSignalingThread(
const base::Closure& closure,
const char* trace_event_name) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
scoped_refptr<base::SingleThreadTaskRunner> thread(signaling_thread());
if (!thread.get() || thread->BelongsToCurrentThread()) {
TRACE_EVENT0("webrtc", trace_event_name);
@@ -2251,7 +2384,7 @@ void RTCPeerConnectionHandler::RunSynchronousClosureOnSignalingThread(
void RTCPeerConnectionHandler::ReportICEState(
webrtc::PeerConnectionInterface::IceConnectionState new_state) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (ice_state_seen_[new_state])
return;
ice_state_seen_[new_state] = true;
@@ -2260,7 +2393,7 @@ void RTCPeerConnectionHandler::ReportICEState(
}
void RTCPeerConnectionHandler::ResetUMAStats() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
num_local_candidates_ipv6_ = 0;
num_local_candidates_ipv4_ = 0;
ice_connection_checking_start_ = base::TimeTicks();
diff --git a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.h b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.h
index a4b038365d2..74cb1b77c1a 100644
--- a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.h
+++ b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler.h
@@ -18,15 +18,15 @@
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
-#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/transceiver_state_surfacer.h"
#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
#include "ipc/ipc_platform_file.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/platform/web_rtc_configuration.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
#include "third_party/blink/public/platform/web_rtc_stats_request.h"
#include "third_party/blink/public/platform/web_rtc_stats_response.h"
@@ -45,6 +45,7 @@ namespace content {
class PeerConnectionDependencyFactory;
class PeerConnectionTracker;
class RtcDataChannelHandler;
+class SetLocalDescriptionRequest;
// Mockable wrapper for blink::WebRTCStatsResponse
class CONTENT_EXPORT LocalRTCStatsResponse : public rtc::RefCountInterface {
@@ -107,8 +108,10 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
const base::WeakPtr<PeerConnectionTracker>& peer_connection_tracker);
// blink::WebRTCPeerConnectionHandler implementation
- bool Initialize(const blink::WebRTCConfiguration& server_configuration,
- const blink::WebMediaConstraints& options) override;
+ bool Initialize(
+ const blink::WebRTCConfiguration& server_configuration,
+ const blink::WebMediaConstraints& options,
+ blink::WebRTCSdpSemantics original_sdp_semantics_value) override;
void CreateOffer(const blink::WebRTCSessionDescriptionRequest& request,
const blink::WebMediaConstraints& options) override;
@@ -143,10 +146,17 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
void GetStats(const blink::WebRTCStatsRequest& request) override;
void GetStats(
std::unique_ptr<blink::WebRTCStatsReportCallback> callback) override;
- std::unique_ptr<blink::WebRTCRtpSender> AddTrack(
+ webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+ AddTransceiverWithTrack(const blink::WebMediaStreamTrack& web_track,
+ const webrtc::RtpTransceiverInit& init) override;
+ webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+ AddTransceiverWithKind(std::string kind,
+ const webrtc::RtpTransceiverInit& init) override;
+ webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>> AddTrack(
const blink::WebMediaStreamTrack& web_track,
const blink::WebVector<blink::WebMediaStream>& web_streams) override;
- bool RemoveTrack(blink::WebRTCRtpSender* web_sender) override;
+ webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>> RemoveTrack(
+ blink::WebRTCRtpSender* web_sender) override;
blink::WebRTCDataChannelHandler* CreateDataChannel(
const blink::WebString& label,
@@ -185,8 +195,10 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
class Observer;
friend class Observer;
- class WebRtcSetRemoteDescriptionObserverImpl;
- friend class WebRtcSetRemoteDescriptionObserverImpl;
+ class WebRtcSetDescriptionObserverImpl;
+ friend class WebRtcSetDescriptionObserverImpl;
+ class SetLocalDescriptionRequest;
+ friend class SetLocalDescriptionRequest;
void OnSignalingChange(
webrtc::PeerConnectionInterface::SignalingState new_state);
@@ -195,14 +207,10 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
void OnIceGatheringChange(
webrtc::PeerConnectionInterface::IceGatheringState new_state);
void OnRenegotiationNeeded();
- 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 OnAddReceiverPlanB(RtpReceiverState receiver_state);
+ void OnRemoveReceiverPlanB(uintptr_t receiver_id);
+ void OnModifyTransceivers(std::vector<RtpTransceiverState> transceiver_states,
+ bool is_remote_description);
void OnDataChannel(std::unique_ptr<RtcDataChannelHandler> handler);
void OnIceCandidate(const std::string& sdp,
const std::string& sdp_mid,
@@ -240,7 +248,47 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
void ReportFirstSessionDescriptions(const FirstSessionDescription& local,
const FirstSessionDescription& remote);
+ void AddTransceiverWithTrackOnSignalingThread(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
+ webrtc::RtpTransceiverInit init,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>*
+ error_or_transceiver);
+ void AddTransceiverWithMediaTypeOnSignalingThread(
+ cricket::MediaType media_type,
+ webrtc::RtpTransceiverInit init,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>*
+ error_or_transceiver);
+ void AddTrackOnSignalingThread(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ std::vector<std::string> stream_ids,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>>*
+ error_or_sender);
+ bool RemoveTrackPlanB(blink::WebRTCRtpSender* web_sender);
+ webrtc::RTCErrorOr<std::unique_ptr<blink::WebRTCRtpTransceiver>>
+ RemoveTrackUnifiedPlan(blink::WebRTCRtpSender* web_sender);
+ void RemoveTrackUnifiedPlanOnSignalingThread(
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender,
+ TransceiverStateSurfacer* transceiver_state_surfacer,
+ bool* result);
std::vector<std::unique_ptr<RTCRtpSender>>::iterator FindSender(uintptr_t id);
+ std::vector<std::unique_ptr<RTCRtpReceiver>>::iterator FindReceiver(
+ uintptr_t id);
+ std::vector<std::unique_ptr<RTCRtpTransceiver>>::iterator FindTransceiver(
+ uintptr_t id);
+ // For full transceiver implementations, returns the index of
+ // |rtp_transceivers_| that correspond to |web_transceiver|.
+ // For sender-only transceiver implementations, returns the index of
+ // |rtp_senders_| that correspond to |web_transceiver.Sender()|.
+ // For receiver-only transceiver implementations, returns the index of
+ // |rtp_receivers_| that correspond to |web_transceiver.Receiver()|.
+ // NOTREACHED()-crashes if no correspondent is found.
+ size_t GetTransceiverIndex(
+ const blink::WebRTCRtpTransceiver& web_transceiver);
+ std::unique_ptr<RTCRtpTransceiver> CreateOrUpdateTransceiver(
+ RtpTransceiverState transceiver_state);
scoped_refptr<base::SingleThreadTaskRunner> signaling_thread() const;
@@ -254,8 +302,6 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
// first call fails.
bool initialize_called_;
- base::ThreadChecker thread_checker_;
-
// |client_| is a weak pointer to the blink object (blink::RTCPeerConnection)
// that owns this object.
// It is valid for the lifetime of this object.
@@ -279,20 +325,20 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
// needs to reference it, and automatically disposed when there are no longer
// any components referencing it.
scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
- // Map and owners of stream adapters. Every stream that is in use by the peer
- // connection has an associated blink and webrtc layer representation of it.
- // The map keeps track of the relationship between |blink::WebMediaStream|s
- // and |webrtc::MediaStreamInterface|s. Stream adapters are created on the fly
- // when a component (such as a sender or receiver) needs to reference it, and
- // automatically disposed when there are no longer any components referencing
- // it.
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map_;
+ // In Plan B, senders and receivers are added or removed independently of one
+ // another. In Unified Plan, senders and receivers are created in pairs as
+ // transceivers. Transceivers may become inactive, but are never removed.
+ // The value of this member affects the behavior of some methods and what
+ // information is surfaced from webrtc. After Initialize(), this is the actual
+ // mode used, meaning "kDefault" is no longer a valid value.
+ // TODO(hbos): Implement transceiver behaviors. https://crbug.com/777617
+ blink::WebRTCSdpSemantics sdp_semantics_;
// Content layer correspondents of |webrtc::RtpSenderInterface|.
std::vector<std::unique_ptr<RTCRtpSender>> rtp_senders_;
- // 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_;
+ // Content layer correspondents of |webrtc::RtpReceiverInterface|.
+ std::vector<std::unique_ptr<RTCRtpReceiver>> rtp_receivers_;
+ // Content layer correspondents of |webrtc::RtpTransceiverInterface|.
+ std::vector<std::unique_ptr<RTCRtpTransceiver>> rtp_transceivers_;
base::WeakPtr<PeerConnectionTracker> peer_connection_tracker_;
@@ -308,7 +354,6 @@ class CONTENT_EXPORT RTCPeerConnectionHandler
// To make sure the observers are released after native_peer_connection_,
// they have to come first.
scoped_refptr<Observer> peer_connection_observer_;
- scoped_refptr<webrtc::UMAObserver> uma_observer_;
// |native_peer_connection_| is the libjingle native PeerConnection object.
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
diff --git a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
index 3d9ade84d75..51a6af48d59 100644
--- a/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
@@ -23,7 +23,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "content/child/child_process.h"
-#include "content/renderer/media/mock_audio_device_factory.h"
+#include "content/renderer/media/audio/mock_audio_device_factory.h"
#include "content/renderer/media/stream/media_stream_audio_source.h"
#include "content/renderer/media/stream/media_stream_audio_track.h"
#include "content/renderer/media/stream/media_stream_source.h"
@@ -171,14 +171,21 @@ class MockPeerConnectionTracker : public PeerConnectionTracker {
scoped_refptr<blink::WebRTCICECandidate> candidate,
Source source,
bool succeeded));
- MOCK_METHOD3(TrackAddStream,
+ MOCK_METHOD4(TrackAddTransceiver,
void(RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream,
- Source source));
- MOCK_METHOD3(TrackRemoveStream,
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index));
+ MOCK_METHOD4(TrackModifyTransceiver,
void(RTCPeerConnectionHandler* pc_handler,
- const blink::WebMediaStream& stream,
- Source source));
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index));
+ MOCK_METHOD4(TrackRemoveTransceiver,
+ void(RTCPeerConnectionHandler* pc_handler,
+ TransceiverUpdatedReason reason,
+ const blink::WebRTCRtpTransceiver& transceiver,
+ size_t transceiver_index));
MOCK_METHOD1(TrackOnIceComplete,
void(RTCPeerConnectionHandler* pc_handler));
MOCK_METHOD3(TrackCreateDataChannel,
@@ -188,11 +195,11 @@ class MockPeerConnectionTracker : public PeerConnectionTracker {
MOCK_METHOD1(TrackStop, void(RTCPeerConnectionHandler* pc_handler));
MOCK_METHOD2(TrackSignalingStateChange,
void(RTCPeerConnectionHandler* pc_handler,
- WebRTCPeerConnectionHandlerClient::SignalingState state));
+ webrtc::PeerConnectionInterface::SignalingState state));
MOCK_METHOD2(
TrackIceConnectionStateChange,
void(RTCPeerConnectionHandler* pc_handler,
- WebRTCPeerConnectionHandlerClient::ICEConnectionState state));
+ MockWebRTCPeerConnectionHandlerClient::ICEConnectionState state));
MOCK_METHOD2(
TrackIceGatheringStateChange,
void(RTCPeerConnectionHandler* pc_handler,
@@ -273,6 +280,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
pc_handler_ = CreateRTCPeerConnectionHandlerUnderTest();
mock_tracker_.reset(new NiceMock<MockPeerConnectionTracker>());
blink::WebRTCConfiguration config;
+ config.sdp_semantics = blink::WebRTCSdpSemantics::kPlanB;
blink::WebMediaConstraints constraints;
EXPECT_TRUE(pc_handler_->InitializeForTest(
config, constraints, mock_tracker_.get()->AsWeakPtr()));
@@ -373,14 +381,9 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
}
void StopAllTracks(const blink::WebMediaStream& stream) {
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- stream.AudioTracks(audio_tracks);
- for (const auto& track : audio_tracks)
+ for (const auto& track : stream.AudioTracks())
MediaStreamAudioTrack::From(track)->Stop();
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- stream.VideoTracks(video_tracks);
- for (const auto& track : video_tracks)
+ for (const auto& track : stream.VideoTracks())
MediaStreamVideoTrack::GetVideoTrack(track)->Stop();
}
@@ -390,22 +393,26 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
bool AddStream(const blink::WebMediaStream& web_stream) {
size_t senders_size_before_add = senders_.size();
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks;
- web_stream.AudioTracks(web_audio_tracks);
- for (const auto& web_audio_track : web_audio_tracks) {
- auto sender = pc_handler_->AddTrack(
+ for (const auto& web_audio_track : web_stream.AudioTracks()) {
+ auto error_or_transceiver = pc_handler_->AddTrack(
web_audio_track, std::vector<blink::WebMediaStream>({web_stream}));
- if (sender) {
+ if (error_or_transceiver.ok()) {
+ DCHECK_EQ(
+ error_or_transceiver.value()->ImplementationType(),
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly);
+ auto sender = error_or_transceiver.value()->Sender();
senders_.push_back(std::unique_ptr<RTCRtpSender>(
static_cast<RTCRtpSender*>(sender.release())));
}
}
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks;
- web_stream.VideoTracks(web_video_tracks);
- for (const auto& web_video_track : web_video_tracks) {
- auto sender = pc_handler_->AddTrack(
+ for (const auto& web_video_track : web_stream.VideoTracks()) {
+ auto error_or_transceiver = pc_handler_->AddTrack(
web_video_track, std::vector<blink::WebMediaStream>({web_stream}));
- if (sender) {
+ if (error_or_transceiver.ok()) {
+ DCHECK_EQ(
+ error_or_transceiver.value()->ImplementationType(),
+ blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly);
+ auto sender = error_or_transceiver.value()->Sender();
senders_.push_back(std::unique_ptr<RTCRtpSender>(
static_cast<RTCRtpSender*>(sender.release())));
}
@@ -424,20 +431,16 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
bool RemoveStream(const blink::WebMediaStream& web_stream) {
size_t senders_size_before_remove = senders_.size();
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks;
- web_stream.AudioTracks(web_audio_tracks);
// TODO(hbos): With Unified Plan senders are not removed.
// https://crbug.com/799030
- for (const auto& web_audio_track : web_audio_tracks) {
+ for (const auto& web_audio_track : web_stream.AudioTracks()) {
auto it = FindSenderForTrack(web_audio_track);
- if (it != senders_.end() && pc_handler_->RemoveTrack((*it).get()))
+ if (it != senders_.end() && pc_handler_->RemoveTrack((*it).get()).ok())
senders_.erase(it);
}
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks;
- web_stream.VideoTracks(web_video_tracks);
- for (const auto& web_video_track : web_video_tracks) {
+ for (const auto& web_video_track : web_stream.VideoTracks()) {
auto it = FindSenderForTrack(web_video_track);
- if (it != senders_.end() && pc_handler_->RemoveTrack((*it).get()))
+ if (it != senders_.end() && pc_handler_->RemoveTrack((*it).get()).ok())
senders_.erase(it);
}
return senders_size_before_remove > senders_.size();
@@ -607,12 +610,12 @@ TEST_F(RTCPeerConnectionHandlerTest, NoCallbacksToClientAfterStop) {
pc_handler_->observer()->OnIceConnectionChange(
webrtc::PeerConnectionInterface::kIceConnectionDisconnected);
- EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_)).Times(0);
+ EXPECT_CALL(*mock_client_.get(), DidAddReceiverPlanBForMock(_)).Times(0);
rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
AddRemoteMockMediaStream("remote_stream", "video", "audio"));
InvokeOnAddStream(remote_stream);
- EXPECT_CALL(*mock_client_.get(), DidRemoveRemoteTrackForMock(_)).Times(0);
+ EXPECT_CALL(*mock_client_.get(), DidRemoveReceiverPlanBForMock(_)).Times(0);
InvokeOnRemoveStream(remote_stream);
EXPECT_CALL(*mock_client_.get(), DidAddRemoteDataChannel(_)).Times(0);
@@ -762,6 +765,7 @@ TEST_F(RTCPeerConnectionHandlerTest, setRemoteDescriptionParseError) {
TEST_F(RTCPeerConnectionHandlerTest, setConfiguration) {
blink::WebRTCConfiguration config;
+ config.sdp_semantics = blink::WebRTCSdpSemantics::kPlanB;
EXPECT_CALL(*mock_tracker_.get(),
TrackSetConfiguration(pc_handler_.get(), _));
@@ -775,6 +779,7 @@ TEST_F(RTCPeerConnectionHandlerTest, setConfiguration) {
// blink error and false is returned.
TEST_F(RTCPeerConnectionHandlerTest, setConfigurationError) {
blink::WebRTCConfiguration config;
+ config.sdp_semantics = blink::WebRTCSdpSemantics::kPlanB;
mock_peer_connection_->set_setconfiguration_error_type(
webrtc::RTCErrorType::INVALID_MODIFICATION);
@@ -802,22 +807,25 @@ TEST_F(RTCPeerConnectionHandlerTest, addAndRemoveStream) {
blink::WebMediaStream local_stream(
CreateLocalMediaStream(stream_label));
- EXPECT_CALL(*mock_tracker_.get(),
- TrackAddStream(pc_handler_.get(), _,
- PeerConnectionTracker::SOURCE_LOCAL));
- EXPECT_CALL(*mock_tracker_.get(),
- TrackRemoveStream(pc_handler_.get(), _,
- PeerConnectionTracker::SOURCE_LOCAL));
+ EXPECT_CALL(
+ *mock_tracker_.get(),
+ TrackAddTransceiver(
+ pc_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kAddTrack, _, _))
+ .Times(2);
+ EXPECT_CALL(
+ *mock_tracker_.get(),
+ TrackRemoveTransceiver(
+ pc_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack, _, _))
+ .Times(2);
EXPECT_TRUE(AddStream(local_stream));
EXPECT_EQ(stream_label, mock_peer_connection_->stream_label());
- EXPECT_EQ(1u,
- mock_peer_connection_->local_streams()->at(0)->GetAudioTracks().size());
- EXPECT_EQ(1u,
- mock_peer_connection_->local_streams()->at(0)->GetVideoTracks().size());
+ EXPECT_EQ(2u, mock_peer_connection_->GetSenders().size());
EXPECT_FALSE(AddStream(local_stream));
EXPECT_TRUE(RemoveStream(local_stream));
- EXPECT_EQ(0u, mock_peer_connection_->local_streams()->count());
+ EXPECT_EQ(0u, mock_peer_connection_->GetSenders().size());
StopAllTracks(local_stream);
}
@@ -827,14 +835,14 @@ TEST_F(RTCPeerConnectionHandlerTest, addStreamWithStoppedAudioAndVideoTrack) {
blink::WebMediaStream local_stream(
CreateLocalMediaStream(stream_label));
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- local_stream.AudioTracks(audio_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks =
+ local_stream.AudioTracks();
MediaStreamAudioSource* native_audio_source =
MediaStreamAudioSource::From(audio_tracks[0].Source());
native_audio_source->StopSource();
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- local_stream.VideoTracks(video_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks =
+ local_stream.VideoTracks();
MediaStreamVideoSource* native_video_source =
static_cast<MediaStreamVideoSource*>(
video_tracks[0].Source().GetExtraData());
@@ -842,12 +850,7 @@ TEST_F(RTCPeerConnectionHandlerTest, addStreamWithStoppedAudioAndVideoTrack) {
EXPECT_TRUE(AddStream(local_stream));
EXPECT_EQ(stream_label, mock_peer_connection_->stream_label());
- EXPECT_EQ(
- 1u,
- mock_peer_connection_->local_streams()->at(0)->GetAudioTracks().size());
- EXPECT_EQ(
- 1u,
- mock_peer_connection_->local_streams()->at(0)->GetVideoTracks().size());
+ EXPECT_EQ(2u, mock_peer_connection_->GetSenders().size());
StopAllTracks(local_stream);
}
@@ -876,8 +879,8 @@ TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithLocalSelector) {
blink::WebMediaStream local_stream(
CreateLocalMediaStream("local_stream"));
EXPECT_TRUE(AddStream(local_stream));
- blink::WebVector<blink::WebMediaStreamTrack> tracks;
- local_stream.AudioTracks(tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> tracks =
+ local_stream.AudioTracks();
ASSERT_LE(1ul, tracks.size());
scoped_refptr<MockRTCStatsRequest> request(
@@ -890,45 +893,13 @@ TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithLocalSelector) {
StopAllTracks(local_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"));
- 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;
- webkit_stream.AudioTracks(tracks);
- ASSERT_LE(1ul, tracks.size());
-
- scoped_refptr<MockRTCStatsRequest> request(
- new rtc::RefCountedObject<MockRTCStatsRequest>());
- request->setSelector(tracks[0]);
- pc_handler_->getStats(request.get());
- RunMessageLoopsUntilIdle();
- EXPECT_EQ(1, request->result()->report_count());
-}
-
TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithBadSelector) {
// The setup is the same as GetStatsWithLocalSelector, but the stream is not
// added to the PeerConnection.
blink::WebMediaStream local_stream(
CreateLocalMediaStream("local_stream_2"));
- blink::WebVector<blink::WebMediaStreamTrack> tracks;
-
- local_stream.AudioTracks(tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> tracks =
+ local_stream.AudioTracks();
blink::WebMediaStreamTrack component = tracks[0];
mock_peer_connection_->SetGetStatsResult(false);
@@ -1063,67 +1034,6 @@ TEST_F(RTCPeerConnectionHandlerTest, GetRTCStats) {
EXPECT_EQ(defined_stats_count, 1);
}
-TEST_F(RTCPeerConnectionHandlerTest, OnSignalingChange) {
- testing::InSequence sequence;
-
- webrtc::PeerConnectionInterface::SignalingState new_state =
- webrtc::PeerConnectionInterface::kHaveRemoteOffer;
- EXPECT_CALL(
- *mock_tracker_.get(),
- TrackSignalingStateChange(
- pc_handler_.get(),
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveRemoteOffer));
- EXPECT_CALL(
- *mock_client_.get(),
- DidChangeSignalingState(
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveRemoteOffer));
- pc_handler_->observer()->OnSignalingChange(new_state);
-
- new_state = webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
- EXPECT_CALL(
- *mock_tracker_.get(),
- TrackSignalingStateChange(
- pc_handler_.get(),
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveLocalPrAnswer));
- EXPECT_CALL(
- *mock_client_.get(),
- DidChangeSignalingState(
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveLocalPrAnswer));
- pc_handler_->observer()->OnSignalingChange(new_state);
-
- new_state = webrtc::PeerConnectionInterface::kHaveLocalOffer;
- EXPECT_CALL(
- *mock_tracker_.get(),
- TrackSignalingStateChange(
- pc_handler_.get(),
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveLocalOffer));
- EXPECT_CALL(
- *mock_client_.get(),
- DidChangeSignalingState(
- WebRTCPeerConnectionHandlerClient::kSignalingStateHaveLocalOffer));
- pc_handler_->observer()->OnSignalingChange(new_state);
-
- new_state = webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
- EXPECT_CALL(*mock_tracker_.get(),
- TrackSignalingStateChange(pc_handler_.get(),
- WebRTCPeerConnectionHandlerClient::
- kSignalingStateHaveRemotePrAnswer));
- EXPECT_CALL(*mock_client_.get(),
- DidChangeSignalingState(WebRTCPeerConnectionHandlerClient::
- kSignalingStateHaveRemotePrAnswer));
- pc_handler_->observer()->OnSignalingChange(new_state);
-
- new_state = webrtc::PeerConnectionInterface::kClosed;
- EXPECT_CALL(*mock_tracker_.get(),
- TrackSignalingStateChange(
- pc_handler_.get(),
- WebRTCPeerConnectionHandlerClient::kSignalingStateClosed));
- EXPECT_CALL(*mock_client_.get(),
- DidChangeSignalingState(
- WebRTCPeerConnectionHandlerClient::kSignalingStateClosed));
- pc_handler_->observer()->OnSignalingChange(new_state);
-}
-
TEST_F(RTCPeerConnectionHandlerTest, OnIceConnectionChange) {
testing::InSequence sequence;
@@ -1263,28 +1173,27 @@ TEST_F(RTCPeerConnectionHandlerTest, DISABLED_OnAddAndOnRemoveStream) {
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(_))
+ EXPECT_CALL(*mock_client_.get(), DidAddReceiverPlanBForMock(_))
.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));
+ EXPECT_CALL(
+ *mock_tracker_.get(),
+ TrackAddTransceiver(
+ pc_handler_.get(),
+ PeerConnectionTracker::TransceiverUpdatedReason::kAddTrack, _, _))
+ .Times(2);
// 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(
+ TrackRemoveTransceiver(
pc_handler_.get(),
- testing::Property(&blink::WebMediaStream::Id,
- blink::WebString::FromASCII("remote_stream")),
- PeerConnectionTracker::SOURCE_REMOTE));
- EXPECT_CALL(*mock_client_.get(), DidRemoveRemoteTrackForMock(_))
+ PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack, _, _))
+ .Times(2);
+ EXPECT_CALL(*mock_client_.get(), DidRemoveReceiverPlanBForMock(_))
.WillRepeatedly(
Invoke([&receivers_removed](
std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) {
@@ -1303,211 +1212,6 @@ TEST_F(RTCPeerConnectionHandlerTest, DISABLED_OnAddAndOnRemoveStream) {
EXPECT_EQ(receivers_added[1]->Id(), receivers_removed[1]->Id());
}
-// This test that WebKit is notified about remote track state changes.
-// 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", "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);
- RunMessageLoopsUntilIdle();
- EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
-
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- webkit_stream.AudioTracks(audio_tracks);
- EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive,
- audio_tracks[0].Source().GetReadyState());
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- webkit_stream.VideoTracks(video_tracks);
- EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive,
- video_tracks[0].Source().GetReadyState());
-
- InvokeOnSignalingThread(
- base::Bind(&MockWebRtcAudioTrack::SetEnded,
- base::Unretained(static_cast<MockWebRtcAudioTrack*>(
- remote_stream->GetAudioTracks()[0].get()))));
- EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded,
- audio_tracks[0].Source().GetReadyState());
-
- InvokeOnSignalingThread(
- base::Bind(&MockWebRtcVideoTrack::SetEnded,
- base::Unretained(static_cast<MockWebRtcVideoTrack*>(
- remote_stream->GetVideoTracks()[0].get()))));
- EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded,
- video_tracks[0].Source().GetReadyState());
-}
-
-// 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", "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);
- RunMessageLoopsUntilIdle();
- EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
-
- {
- // Test in a small scope so that |audio_tracks| don't hold on to destroyed
- // source later.
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- webkit_stream.AudioTracks(audio_tracks);
- EXPECT_EQ(1u, audio_tracks.size());
- }
-
- // Remove the Webrtc audio track from the Webrtc MediaStream.
- scoped_refptr<webrtc::AudioTrackInterface> webrtc_track =
- remote_stream->GetAudioTracks()[0].get();
- InvokeRemoveTrack(remote_stream, webrtc_track.get());
-
- {
- blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks1;
- webkit_stream.AudioTracks(modified_audio_tracks1);
- EXPECT_EQ(0u, modified_audio_tracks1.size());
- }
-
- blink::WebHeap::CollectGarbageForTesting();
-
- // Add the WebRtc audio track again.
- InvokeAddTrack(remote_stream, webrtc_track.get());
- blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks2;
- webkit_stream.AudioTracks(modified_audio_tracks2);
- EXPECT_EQ(1u, modified_audio_tracks2.size());
-}
-
-// 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", "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);
- RunMessageLoopsUntilIdle();
- EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
-
- {
- // Test in a small scope so that |video_tracks| don't hold on to destroyed
- // source later.
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- webkit_stream.VideoTracks(video_tracks);
- EXPECT_EQ(1u, video_tracks.size());
- }
-
- // Remove the Webrtc video track from the Webrtc MediaStream.
- scoped_refptr<webrtc::VideoTrackInterface> webrtc_track =
- remote_stream->GetVideoTracks()[0].get();
- InvokeRemoveTrack(remote_stream, webrtc_track.get());
- RunMessageLoopsUntilIdle();
- {
- blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks1;
- webkit_stream.VideoTracks(modified_video_tracks1);
- EXPECT_EQ(0u, modified_video_tracks1.size());
- }
-
- blink::WebHeap::CollectGarbageForTesting();
-
- // Add the WebRtc video track again.
- InvokeAddTrack(remote_stream, webrtc_track.get());
- RunMessageLoopsUntilIdle();
- blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks2;
- webkit_stream.VideoTracks(modified_video_tracks2);
- EXPECT_EQ(1u, modified_video_tracks2.size());
-}
-
-// 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", "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);
- RunMessageLoopsUntilIdle();
- EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers));
-
- {
- // Test in a small scope so that |audio_tracks| don't hold on to destroyed
- // source later.
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- webkit_stream.AudioTracks(audio_tracks);
- EXPECT_EQ(1u, audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- webkit_stream.VideoTracks(video_tracks);
- EXPECT_EQ(1u, video_tracks.size());
- }
-
- // Remove the Webrtc tracks from the MediaStream.
- auto audio_track = remote_stream->GetAudioTracks()[0];
- InvokeRemoveTrack(remote_stream, audio_track.get());
- auto video_track = remote_stream->GetVideoTracks()[0];
- InvokeRemoveTrack(remote_stream, video_track.get());
- RunMessageLoopsUntilIdle();
-
- {
- blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks;
- webkit_stream.AudioTracks(modified_audio_tracks);
- EXPECT_EQ(0u, modified_audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks;
- webkit_stream.VideoTracks(modified_video_tracks);
- EXPECT_EQ(0u, modified_video_tracks.size());
- }
-
- blink::WebHeap::CollectGarbageForTesting();
-
- // Add the tracks again.
- InvokeAddTrack(remote_stream, audio_track.get());
- InvokeAddTrack(remote_stream, video_track.get());
-
- blink::WebHeap::CollectGarbageForTesting();
-
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- webkit_stream.AudioTracks(audio_tracks);
- EXPECT_EQ(1u, audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- webkit_stream.VideoTracks(video_tracks);
- EXPECT_EQ(1u, video_tracks.size());
-}
-
TEST_F(RTCPeerConnectionHandlerTest, OnIceCandidate) {
testing::InSequence sequence;
EXPECT_CALL(*mock_tracker_.get(),
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc
index a988bd10bb5..200b00beb9e 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.cc
@@ -11,6 +11,96 @@
namespace content {
+RtpReceiverState::RtpReceiverState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+ std::vector<std::string> stream_id)
+ : main_task_runner_(std::move(main_task_runner)),
+ signaling_task_runner_(std::move(signaling_task_runner)),
+ webrtc_receiver_(std::move(webrtc_receiver)),
+ is_initialized_(false),
+ track_ref_(std::move(track_ref)),
+ stream_ids_(std::move(stream_id)) {
+ DCHECK(main_task_runner_);
+ DCHECK(signaling_task_runner_);
+ DCHECK(webrtc_receiver_);
+ DCHECK(track_ref_);
+}
+
+RtpReceiverState::RtpReceiverState(RtpReceiverState&& other)
+ : main_task_runner_(other.main_task_runner_),
+ signaling_task_runner_(other.signaling_task_runner_),
+ webrtc_receiver_(std::move(other.webrtc_receiver_)),
+ is_initialized_(other.is_initialized_),
+ track_ref_(std::move(other.track_ref_)),
+ stream_ids_(std::move(other.stream_ids_)) {
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+}
+
+RtpReceiverState::~RtpReceiverState() {
+ // It's OK to not be on the main thread if this state has been moved, in which
+ // case |main_task_runner_| is null.
+ DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread());
+}
+
+RtpReceiverState& RtpReceiverState::operator=(RtpReceiverState&& other) {
+ DCHECK_EQ(main_task_runner_, other.main_task_runner_);
+ DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_);
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+ webrtc_receiver_ = std::move(other.webrtc_receiver_);
+ track_ref_ = std::move(other.track_ref_);
+ stream_ids_ = std::move(other.stream_ids_);
+ return *this;
+}
+
+bool RtpReceiverState::is_initialized() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return is_initialized_;
+}
+
+void RtpReceiverState::Initialize() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ if (is_initialized_)
+ return;
+ track_ref_->InitializeOnMainThread();
+ is_initialized_ = true;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> RtpReceiverState::main_task_runner()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return main_task_runner_;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+RtpReceiverState::signaling_task_runner() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return signaling_task_runner_;
+}
+
+scoped_refptr<webrtc::RtpReceiverInterface> RtpReceiverState::webrtc_receiver()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return webrtc_receiver_;
+}
+
+const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+RtpReceiverState::track_ref() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return track_ref_;
+}
+
+const std::vector<std::string>& RtpReceiverState::stream_ids() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return stream_ids_;
+}
+
class RTCRtpReceiver::RTCRtpReceiverInternal
: public base::RefCountedThreadSafe<
RTCRtpReceiver::RTCRtpReceiverInternal,
@@ -18,37 +108,34 @@ class RTCRtpReceiver::RTCRtpReceiverInternal
public:
RTCRtpReceiverInternal(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- track_adapter,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_adapter_refs)
+ RtpReceiverState state)
: native_peer_connection_(std::move(native_peer_connection)),
- main_thread_(std::move(main_thread)),
- signaling_thread_(std::move(signaling_thread)),
- 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_);
+ main_task_runner_(state.main_task_runner()),
+ signaling_task_runner_(state.signaling_task_runner()),
+ webrtc_receiver_(state.webrtc_receiver()),
+ state_(std::move(state)) {
+ DCHECK(native_peer_connection_);
+ DCHECK(state_.is_initialized());
}
- const blink::WebMediaStreamTrack& Track() const {
- return track_adapter_->web_track();
+ const RtpReceiverState& state() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return state_;
}
- blink::WebVector<blink::WebMediaStream> 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;
+ void set_state(RtpReceiverState state) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(state.main_task_runner() == main_task_runner_);
+ DCHECK(state.signaling_task_runner() == signaling_task_runner_);
+ DCHECK(state.webrtc_receiver() == webrtc_receiver_);
+ DCHECK(state.is_initialized());
+ state_ = std::move(state);
}
blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
GetSources() {
+ // The webrtc_recever_ is a proxy, so this is a blocking call to the webrtc
+ // signalling thread.
auto webrtc_sources = webrtc_receiver_->GetSources();
blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
sources(webrtc_sources.size());
@@ -60,64 +147,34 @@ class RTCRtpReceiver::RTCRtpReceiverInternal
}
void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback> callback) {
- signaling_thread_->PostTask(
+ signaling_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&RTCRtpReceiverInternal::GetStatsOnSignalingThread, this,
std::move(callback)));
}
- webrtc::RtpReceiverInterface* webrtc_receiver() const {
- return webrtc_receiver_.get();
- }
-
- const webrtc::MediaStreamTrackInterface& webrtc_track() const {
- DCHECK(track_adapter_->webrtc_track());
- return *track_adapter_->webrtc_track();
- }
-
- bool 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>>
- 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;
- }
-
private:
friend struct RTCRtpReceiver::RTCRtpReceiverInternalTraits;
- ~RTCRtpReceiverInternal() { DCHECK(main_thread_->BelongsToCurrentThread()); }
+ ~RTCRtpReceiverInternal() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ }
void GetStatsOnSignalingThread(
std::unique_ptr<blink::WebRTCStatsReportCallback> callback) {
- native_peer_connection_->GetStats(webrtc_receiver_,
- RTCStatsCollectorCallbackImpl::Create(
- main_thread_, std::move(callback)));
+ native_peer_connection_->GetStats(
+ webrtc_receiver_.get(), RTCStatsCollectorCallbackImpl::Create(
+ main_task_runner_, std::move(callback)));
}
const scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_;
- 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_;
+ // Task runners and webrtc receiver: Same information as stored in
+ // |state_| but const and safe to touch on the signaling thread to
+ // avoid race with set_state().
+ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ const scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver_;
+ RtpReceiverState state_;
};
struct RTCRtpReceiver::RTCRtpReceiverInternalTraits {
@@ -128,8 +185,8 @@ struct RTCRtpReceiver::RTCRtpReceiverInternalTraits {
static void Destruct(const RTCRtpReceiverInternal* receiver) {
// RTCRtpReceiverInternal owns AdapterRefs which have to be destroyed on the
// main thread, this ensures delete always happens there.
- if (!receiver->main_thread_->BelongsToCurrentThread()) {
- receiver->main_thread_->PostTask(
+ if (!receiver->main_task_runner_->BelongsToCurrentThread()) {
+ receiver->main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpReceiver::RTCRtpReceiverInternalTraits::Destruct,
@@ -147,18 +204,9 @@ uintptr_t RTCRtpReceiver::getId(
RTCRtpReceiver::RTCRtpReceiver(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_adapter_refs)
+ RtpReceiverState state)
: internal_(new RTCRtpReceiverInternal(std::move(native_peer_connection),
- std::move(main_thread),
- std::move(signaling_thread),
- std::move(webrtc_receiver),
- std::move(track_adapter),
- std::move(stream_adapter_refs))) {}
+ std::move(state))) {}
RTCRtpReceiver::RTCRtpReceiver(const RTCRtpReceiver& other)
: internal_(other.internal_) {}
@@ -170,20 +218,32 @@ RTCRtpReceiver& RTCRtpReceiver::operator=(const RTCRtpReceiver& other) {
return *this;
}
-std::unique_ptr<RTCRtpReceiver> RTCRtpReceiver::ShallowCopy() const {
+const RtpReceiverState& RTCRtpReceiver::state() const {
+ return internal_->state();
+}
+
+void RTCRtpReceiver::set_state(RtpReceiverState state) {
+ internal_->set_state(std::move(state));
+}
+
+std::unique_ptr<blink::WebRTCRtpReceiver> RTCRtpReceiver::ShallowCopy() const {
return std::make_unique<RTCRtpReceiver>(*this);
}
uintptr_t RTCRtpReceiver::Id() const {
- return getId(internal_->webrtc_receiver());
+ return getId(internal_->state().webrtc_receiver().get());
}
const blink::WebMediaStreamTrack& RTCRtpReceiver::Track() const {
- return internal_->Track();
+ return internal_->state().track_ref()->web_track();
}
-blink::WebVector<blink::WebMediaStream> RTCRtpReceiver::Streams() const {
- return internal_->Streams();
+blink::WebVector<blink::WebString> RTCRtpReceiver::StreamIds() const {
+ const auto& stream_ids = internal_->state().stream_ids();
+ blink::WebVector<blink::WebString> web_stream_ids(stream_ids.size());
+ for (size_t i = 0; i < stream_ids.size(); ++i)
+ web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids[i]);
+ return web_stream_ids;
}
blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
@@ -196,22 +256,66 @@ void RTCRtpReceiver::GetStats(
internal_->GetStats(std::move(callback));
}
-webrtc::RtpReceiverInterface* RTCRtpReceiver::webrtc_receiver() const {
- return internal_->webrtc_receiver();
+RTCRtpReceiverOnlyTransceiver::RTCRtpReceiverOnlyTransceiver(
+ std::unique_ptr<blink::WebRTCRtpReceiver> receiver)
+ : receiver_(std::move(receiver)) {
+ DCHECK(receiver_);
+}
+
+RTCRtpReceiverOnlyTransceiver::~RTCRtpReceiverOnlyTransceiver() {}
+
+blink::WebRTCRtpTransceiverImplementationType
+RTCRtpReceiverOnlyTransceiver::ImplementationType() const {
+ return blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly;
+}
+
+uintptr_t RTCRtpReceiverOnlyTransceiver::Id() const {
+ NOTIMPLEMENTED();
+ return 0u;
+}
+
+blink::WebString RTCRtpReceiverOnlyTransceiver::Mid() const {
+ NOTIMPLEMENTED();
+ return blink::WebString();
+}
+
+std::unique_ptr<blink::WebRTCRtpSender> RTCRtpReceiverOnlyTransceiver::Sender()
+ const {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+std::unique_ptr<blink::WebRTCRtpReceiver>
+RTCRtpReceiverOnlyTransceiver::Receiver() const {
+ return receiver_->ShallowCopy();
+}
+
+bool RTCRtpReceiverOnlyTransceiver::Stopped() const {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+webrtc::RtpTransceiverDirection RTCRtpReceiverOnlyTransceiver::Direction()
+ const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
}
-const webrtc::MediaStreamTrackInterface& RTCRtpReceiver::webrtc_track() const {
- return internal_->webrtc_track();
+void RTCRtpReceiverOnlyTransceiver::SetDirection(
+ webrtc::RtpTransceiverDirection direction) {
+ NOTIMPLEMENTED();
}
-bool RTCRtpReceiver::HasStream(
- const webrtc::MediaStreamInterface* webrtc_stream) const {
- return internal_->HasStream(webrtc_stream);
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpReceiverOnlyTransceiver::CurrentDirection() const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
}
-std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
-RTCRtpReceiver::StreamAdapterRefs() const {
- return internal_->StreamAdapterRefs();
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpReceiverOnlyTransceiver::FiredDirection() const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
}
} // 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 29420ae5220..1eb373ad13f 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver.h
@@ -9,17 +9,88 @@
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.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/blink/public/platform/web_media_stream.h"
#include "third_party/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
#include "third_party/webrtc/api/mediastreaminterface.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
#include "third_party/webrtc/api/rtpreceiverinterface.h"
namespace content {
+// This class represents the state of a receiver; a snapshot of what a
+// webrtc-layer receiver looked like when it was inspected on the signaling
+// thread such that this information can be moved to the main thread in a single
+// PostTask. It is used to surface state changes to make the blink-layer
+// receiver up-to-date.
+//
+// Blink objects live on the main thread and webrtc objects live on the
+// signaling thread. If multiple asynchronous operations begin execution on the
+// main thread they are posted and executed in order on the signaling thread.
+// For example, operation A and operation B are called in JavaScript. When A is
+// done on the signaling thread, webrtc object states will be updated. A
+// callback is posted to the main thread so that blink objects can be updated to
+// match the result of operation A. But if callback A tries to inspect the
+// webrtc objects from the main thread this requires posting back to the
+// signaling thread and waiting, which also includes waiting for the previously
+// posted task: operation B. Inspecting the webrtc object like this does not
+// guarantee you to get the state of operation A.
+//
+// As such, all state changes associated with an operation have to be surfaced
+// in the same callback. This includes copying any states into a separate object
+// so that it can be inspected on the main thread without any additional thread
+// hops.
+//
+// The RtpReceiverState is a snapshot of what the webrtc::RtpReceiverInterface
+// looked like when the RtpReceiverState was created on the signaling thread. It
+// also takes care of initializing track adapters, such that we have access to a
+// blink track corresponding to the webrtc track of the receiver.
+//
+// Except for initialization logic and operator=(), the RtpReceiverState is
+// immutable and only accessible on the main thread.
+//
+// TODO(hbos): [Onion Soup] When the sender implementation is moved to blink
+// this will be part of the blink sender instead of the content sender.
+// https://crbug.com/787254
+class CONTENT_EXPORT RtpReceiverState {
+ public:
+ RtpReceiverState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+ std::vector<std::string> stream_ids);
+ RtpReceiverState(RtpReceiverState&&);
+ RtpReceiverState(const RtpReceiverState&) = delete;
+ ~RtpReceiverState();
+
+ // This is intended to be used for moving the object from the signaling thread
+ // to the main thread and as such has no thread checks. Once moved to the main
+ // this should only be invoked on the main thread.
+ RtpReceiverState& operator=(RtpReceiverState&&);
+ RtpReceiverState& operator=(const RtpReceiverState&) = delete;
+
+ bool is_initialized() const;
+ void Initialize();
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner() const;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const;
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver() const;
+ const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+ track_ref() const;
+ const std::vector<std::string>& stream_ids() const;
+
+ private:
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver_;
+ bool is_initialized_;
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref_;
+ std::vector<std::string> stream_ids_;
+};
+
// Used to surface |webrtc::RtpReceiverInterface| to blink. Multiple
// |RTCRtpReceiver|s could reference the same webrtc receiver; |id| is the value
// of the pointer to the webrtc receiver.
@@ -30,35 +101,23 @@ class CONTENT_EXPORT RTCRtpReceiver : public blink::WebRTCRtpReceiver {
RTCRtpReceiver(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- track_adapter,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_adapter_refs);
+ RtpReceiverState state);
RTCRtpReceiver(const RTCRtpReceiver& other);
~RTCRtpReceiver() override;
RTCRtpReceiver& operator=(const RTCRtpReceiver& other);
- // Creates a shallow copy of the receiver, representing the same underlying
- // webrtc receiver as the original.
- std::unique_ptr<RTCRtpReceiver> ShallowCopy() const;
+ const RtpReceiverState& state() const;
+ void set_state(RtpReceiverState state);
+ std::unique_ptr<blink::WebRTCRtpReceiver> ShallowCopy() const override;
uintptr_t Id() const override;
const blink::WebMediaStreamTrack& Track() const override;
- blink::WebVector<blink::WebMediaStream> Streams() const override;
+ blink::WebVector<blink::WebString> StreamIds() const override;
blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>>
GetSources() override;
void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>) 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:
class RTCRtpReceiverInternal;
struct RTCRtpReceiverInternalTraits;
@@ -66,6 +125,31 @@ class CONTENT_EXPORT RTCRtpReceiver : public blink::WebRTCRtpReceiver {
scoped_refptr<RTCRtpReceiverInternal> internal_;
};
+class CONTENT_EXPORT RTCRtpReceiverOnlyTransceiver
+ : public blink::WebRTCRtpTransceiver {
+ public:
+ RTCRtpReceiverOnlyTransceiver(
+ std::unique_ptr<blink::WebRTCRtpReceiver> receiver);
+ ~RTCRtpReceiverOnlyTransceiver() override;
+
+ blink::WebRTCRtpTransceiverImplementationType ImplementationType()
+ const override;
+ uintptr_t Id() const override;
+ blink::WebString Mid() const override;
+ std::unique_ptr<blink::WebRTCRtpSender> Sender() const override;
+ std::unique_ptr<blink::WebRTCRtpReceiver> Receiver() const override;
+ bool Stopped() const override;
+ webrtc::RtpTransceiverDirection Direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection direction) override;
+ base::Optional<webrtc::RtpTransceiverDirection> CurrentDirection()
+ const override;
+ base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
+ const override;
+
+ private:
+ std::unique_ptr<blink::WebRTCRtpReceiver> receiver_;
+};
+
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_RECEIVER_H_
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc
index f55c2b22c4c..ebe77e3780c 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc
@@ -16,7 +16,6 @@
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
#include "content/renderer/media/webrtc/test/webrtc_stats_report_obtainer.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/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -34,10 +33,8 @@ class RTCRtpReceiverTest : public ::testing::Test {
void SetUp() override {
dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
- stream_map_ = new WebRtcMediaStreamAdapterMap(
- dependency_factory_.get(), main_thread_,
- new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
- main_thread_));
+ track_map_ = new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
+ main_thread_);
peer_connection_ = new rtc::RefCountedObject<MockPeerConnectionImpl>(
dependency_factory_.get(), nullptr);
}
@@ -63,23 +60,23 @@ class RTCRtpReceiverTest : public ::testing::Test {
std::unique_ptr<RTCRtpReceiver> CreateReceiver(
scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track) {
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter;
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
base::RunLoop run_loop;
dependency_factory_->GetWebRtcSignalingThread()->PostTask(
FROM_HERE,
base::BindOnce(&RTCRtpReceiverTest::CreateReceiverOnSignalingThread,
base::Unretained(this), std::move(webrtc_track),
- base::Unretained(&track_adapter),
+ base::Unretained(&track_ref),
base::Unretained(&run_loop)));
run_loop.Run();
DCHECK(mock_webrtc_receiver_);
- DCHECK(track_adapter);
- return std::make_unique<RTCRtpReceiver>(
- peer_connection_.get(), main_thread_,
- dependency_factory_->GetWebRtcSignalingThread(),
- mock_webrtc_receiver_.get(), std::move(track_adapter),
- std::vector<
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>());
+ DCHECK(track_ref);
+ RtpReceiverState state(
+ main_thread_, dependency_factory_->GetWebRtcSignalingThread(),
+ mock_webrtc_receiver_.get(), std::move(track_ref), {});
+ state.Initialize();
+ return std::make_unique<RTCRtpReceiver>(peer_connection_.get(),
+ std::move(state));
}
scoped_refptr<WebRTCStatsReportObtainer> GetStats() {
@@ -92,14 +89,11 @@ class RTCRtpReceiverTest : public ::testing::Test {
protected:
void CreateReceiverOnSignalingThread(
scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>*
- track_adapter,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>* track_ref,
base::RunLoop* run_loop) {
mock_webrtc_receiver_ =
new rtc::RefCountedObject<webrtc::MockRtpReceiver>();
- *track_adapter =
- stream_map_->track_adapter_map()->GetOrCreateRemoteTrackAdapter(
- webrtc_track);
+ *track_ref = track_map_->GetOrCreateRemoteTrackAdapter(webrtc_track);
run_loop->Quit();
}
@@ -110,7 +104,7 @@ class RTCRtpReceiverTest : public ::testing::Test {
std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map_;
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
rtc::scoped_refptr<MockPeerConnectionImpl> peer_connection_;
rtc::scoped_refptr<webrtc::MockRtpReceiver> mock_webrtc_receiver_;
std::unique_ptr<RTCRtpReceiver> receiver_;
@@ -122,25 +116,25 @@ TEST_F(RTCRtpReceiverTest, CreateReceiver) {
receiver_ = CreateReceiver(webrtc_track);
EXPECT_FALSE(receiver_->Track().IsNull());
EXPECT_EQ(receiver_->Track().Id().Utf8(), webrtc_track->id());
- EXPECT_EQ(&receiver_->webrtc_track(), webrtc_track);
+ EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track);
}
TEST_F(RTCRtpReceiverTest, ShallowCopy) {
scoped_refptr<MockWebRtcAudioTrack> webrtc_track =
MockWebRtcAudioTrack::Create("webrtc_track");
receiver_ = CreateReceiver(webrtc_track);
- auto copy = receiver_->ShallowCopy();
- EXPECT_EQ(&receiver_->webrtc_track(), webrtc_track);
- auto* webrtc_receiver = receiver_->webrtc_receiver();
+ auto copy = std::make_unique<RTCRtpReceiver>(*receiver_);
+ EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track);
+ const auto& webrtc_receiver = receiver_->state().webrtc_receiver();
auto web_track_unique_id = receiver_->Track().UniqueId();
// Copy is identical to original.
- EXPECT_EQ(copy->webrtc_receiver(), webrtc_receiver);
- EXPECT_EQ(&copy->webrtc_track(), webrtc_track);
+ EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver);
+ EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track);
EXPECT_EQ(copy->Track().UniqueId(), web_track_unique_id);
// Copy keeps the internal state alive.
receiver_.reset();
- EXPECT_EQ(copy->webrtc_receiver(), webrtc_receiver);
- EXPECT_EQ(&copy->webrtc_track(), webrtc_track);
+ EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver);
+ EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track);
EXPECT_EQ(copy->Track().UniqueId(), web_track_unique_id);
}
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
index 528c8d26a15..a2d16ec7de7 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.cc
@@ -36,6 +36,100 @@ void OnSetParametersCompleted(blink::WebRTCVoidRequest request,
} // namespace
+RtpSenderState::RtpSenderState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+ std::vector<std::string> stream_ids)
+ : main_task_runner_(std::move(main_task_runner)),
+ signaling_task_runner_(std::move(signaling_task_runner)),
+ webrtc_sender_(std::move(webrtc_sender)),
+ is_initialized_(false),
+ track_ref_(std::move(track_ref)),
+ stream_ids_(std::move(stream_ids)) {
+ DCHECK(main_task_runner_);
+ DCHECK(signaling_task_runner_);
+ DCHECK(webrtc_sender_);
+}
+
+RtpSenderState::RtpSenderState(RtpSenderState&& other)
+ : main_task_runner_(other.main_task_runner_),
+ signaling_task_runner_(other.signaling_task_runner_),
+ webrtc_sender_(std::move(other.webrtc_sender_)),
+ is_initialized_(other.is_initialized_),
+ track_ref_(std::move(other.track_ref_)),
+ stream_ids_(std::move(other.stream_ids_)) {
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+}
+
+RtpSenderState::~RtpSenderState() {
+ // It's OK to not be on the main thread if this state has been moved, in which
+ // case |main_task_runner_| is null.
+ DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread());
+}
+
+RtpSenderState& RtpSenderState::operator=(RtpSenderState&& other) {
+ DCHECK_EQ(main_task_runner_, other.main_task_runner_);
+ DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_);
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+ webrtc_sender_ = std::move(other.webrtc_sender_);
+ is_initialized_ = other.is_initialized_;
+ track_ref_ = std::move(other.track_ref_);
+ stream_ids_ = std::move(other.stream_ids_);
+ return *this;
+}
+
+bool RtpSenderState::is_initialized() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return is_initialized_;
+}
+
+void RtpSenderState::Initialize() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ if (track_ref_)
+ track_ref_->InitializeOnMainThread();
+ is_initialized_ = true;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner> RtpSenderState::main_task_runner()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return main_task_runner_;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+RtpSenderState::signaling_task_runner() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return signaling_task_runner_;
+}
+
+scoped_refptr<webrtc::RtpSenderInterface> RtpSenderState::webrtc_sender()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return webrtc_sender_;
+}
+
+const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+RtpSenderState::track_ref() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return track_ref_;
+}
+
+void RtpSenderState::set_track_ref(
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(!is_initialized_ || !track_ref || track_ref->is_initialized());
+ track_ref_ = std::move(track_ref);
+}
+
+std::vector<std::string> RtpSenderState::stream_ids() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return stream_ids_;
+}
+
class RTCRtpSender::RTCRtpSenderInternal
: public base::RefCountedThreadSafe<
RTCRtpSender::RTCRtpSenderInternal,
@@ -43,86 +137,42 @@ class RTCRtpSender::RTCRtpSenderInternal
public:
RTCRtpSenderInternal(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- blink::WebMediaStreamTrack web_track,
- std::vector<blink::WebMediaStream> web_streams)
- : native_peer_connection_(std::move(native_peer_connection)),
- main_thread_(std::move(main_thread)),
- signaling_thread_(std::move(signaling_thread)),
- stream_map_(std::move(stream_map)),
- webrtc_sender_(std::move(webrtc_sender)) {
- DCHECK(main_thread_);
- DCHECK(signaling_thread_);
- DCHECK(stream_map_);
- DCHECK(webrtc_sender_);
- if (!web_track.IsNull()) {
- track_ref_ =
- stream_map_->track_adapter_map()->GetOrCreateLocalTrackAdapter(
- web_track);
- }
- for (size_t i = 0; i < web_streams.size(); ++i) {
- if (!web_streams[i].IsNull()) {
- stream_refs_.push_back(
- stream_map_->GetOrCreateLocalStreamAdapter(web_streams[i]));
- }
- }
- }
-
- RTCRtpSenderInternal(
- scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs)
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpSenderState state)
: native_peer_connection_(std::move(native_peer_connection)),
- main_thread_(std::move(main_thread)),
- signaling_thread_(std::move(signaling_thread)),
- stream_map_(std::move(stream_map)),
- webrtc_sender_(std::move(webrtc_sender)),
- track_ref_(std::move(track_ref)),
- stream_refs_(std::move(stream_refs)) {
- DCHECK(main_thread_);
- DCHECK(signaling_thread_);
- DCHECK(stream_map_);
- DCHECK(webrtc_sender_);
- }
-
- webrtc::RtpSenderInterface* webrtc_sender() const {
- return webrtc_sender_.get();
+ track_map_(std::move(track_map)),
+ main_task_runner_(state.main_task_runner()),
+ signaling_task_runner_(state.signaling_task_runner()),
+ webrtc_sender_(state.webrtc_sender()),
+ state_(std::move(state)) {
+ DCHECK(track_map_);
+ DCHECK(state_.is_initialized());
}
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref()
- const {
- return track_ref_ ? track_ref_->Copy() : nullptr;
+ const RtpSenderState& state() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return state_;
}
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs() const {
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_ref_copies(stream_refs_.size());
- for (size_t i = 0; i < stream_refs_.size(); ++i)
- stream_ref_copies[i] = stream_refs_[i]->Copy();
- return stream_ref_copies;
+ void set_state(RtpSenderState state) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK_EQ(state.main_task_runner(), main_task_runner_);
+ DCHECK_EQ(state.signaling_task_runner(), signaling_task_runner_);
+ DCHECK(state.webrtc_sender() == webrtc_sender_);
+ DCHECK(state.is_initialized());
+ state_ = std::move(state);
}
void ReplaceTrack(blink::WebMediaStreamTrack with_track,
base::OnceCallback<void(bool)> callback) {
- DCHECK(main_thread_->BelongsToCurrentThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
webrtc::MediaStreamTrackInterface* webrtc_track = nullptr;
if (!with_track.IsNull()) {
- track_ref =
- stream_map_->track_adapter_map()->GetOrCreateLocalTrackAdapter(
- with_track);
+ track_ref = track_map_->GetOrCreateLocalTrackAdapter(with_track);
webrtc_track = track_ref->webrtc_track();
}
- signaling_thread_->PostTask(
+ signaling_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpSender::RTCRtpSenderInternal::ReplaceTrackOnSignalingThread,
@@ -131,14 +181,16 @@ class RTCRtpSender::RTCRtpSenderInternal
}
std::unique_ptr<blink::WebRTCDTMFSenderHandler> GetDtmfSender() const {
- // The webrtc_sender is a proxy, so this is a blocking call to the
+ // The webrtc_sender() is a proxy, so this is a blocking call to the
// webrtc signalling thread.
- DCHECK(main_thread_->BelongsToCurrentThread());
- auto dtmf_sender = webrtc_sender()->GetDtmfSender();
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ auto dtmf_sender = webrtc_sender_->GetDtmfSender();
return std::make_unique<RtcDtmfSenderHandler>(dtmf_sender);
}
std::unique_ptr<webrtc::RtpParameters> GetParameters() {
+ // The webrtc_sender() is a proxy, so this is a blocking call to the
+ // webrtc signalling thread.
parameters_ = webrtc_sender_->GetParameters();
return std::make_unique<webrtc::RtpParameters>(parameters_);
}
@@ -146,7 +198,7 @@ class RTCRtpSender::RTCRtpSenderInternal
void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters> encodings,
webrtc::DegradationPreference degradation_preference,
base::OnceCallback<void(webrtc::RTCError)> callback) {
- DCHECK(main_thread_->BelongsToCurrentThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
webrtc::RtpParameters new_parameters = parameters_;
@@ -171,7 +223,7 @@ class RTCRtpSender::RTCRtpSenderInternal
encoding.scale_resolution_down_by;
}
- signaling_thread_->PostTask(
+ signaling_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpSender::RTCRtpSenderInternal::SetParametersOnSignalingThread,
@@ -179,7 +231,7 @@ class RTCRtpSender::RTCRtpSenderInternal
}
void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback> callback) {
- signaling_thread_->PostTask(
+ signaling_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpSender::RTCRtpSenderInternal::GetStatsOnSignalingThread,
@@ -187,13 +239,14 @@ class RTCRtpSender::RTCRtpSenderInternal
}
bool RemoveFromPeerConnection(webrtc::PeerConnectionInterface* pc) {
- if (!pc->RemoveTrack(webrtc_sender_))
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ if (!pc->RemoveTrack(webrtc_sender_.get()))
return false;
// TODO(hbos): Removing the track should null the sender's track, or we
// should do |webrtc_sender_->SetTrack(null)| but that is not allowed on a
// stopped sender. In the meantime, there is a discrepancy between layers.
// https://crbug.com/webrtc/7945
- track_ref_.reset();
+ state_.set_track_ref(nullptr);
return true;
}
@@ -202,7 +255,7 @@ class RTCRtpSender::RTCRtpSenderInternal
~RTCRtpSenderInternal() {
// Ensured by destructor traits.
- DCHECK(main_thread_->BelongsToCurrentThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
}
// |webrtc_track| is passed as an argument because |track_ref->webrtc_track()|
@@ -211,9 +264,9 @@ class RTCRtpSender::RTCRtpSenderInternal
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
webrtc::MediaStreamTrackInterface* webrtc_track,
base::OnceCallback<void(bool)> callback) {
- DCHECK(signaling_thread_->BelongsToCurrentThread());
+ DCHECK(signaling_task_runner_->BelongsToCurrentThread());
bool result = webrtc_sender_->SetTrack(webrtc_track);
- main_thread_->PostTask(
+ main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpSender::RTCRtpSenderInternal::ReplaceTrackCallback, this,
@@ -224,25 +277,25 @@ class RTCRtpSender::RTCRtpSenderInternal
bool result,
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
base::OnceCallback<void(bool)> callback) {
- DCHECK(main_thread_->BelongsToCurrentThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
if (result)
- track_ref_ = std::move(track_ref);
+ state_.set_track_ref(std::move(track_ref));
std::move(callback).Run(result);
}
void GetStatsOnSignalingThread(
std::unique_ptr<blink::WebRTCStatsReportCallback> callback) {
- native_peer_connection_->GetStats(webrtc_sender_,
- RTCStatsCollectorCallbackImpl::Create(
- main_thread_, std::move(callback)));
+ native_peer_connection_->GetStats(
+ webrtc_sender_.get(), RTCStatsCollectorCallbackImpl::Create(
+ main_task_runner_, std::move(callback)));
}
void SetParametersOnSignalingThread(
webrtc::RtpParameters parameters,
base::OnceCallback<void(webrtc::RTCError)> callback) {
- DCHECK(signaling_thread_->BelongsToCurrentThread());
+ DCHECK(signaling_task_runner_->BelongsToCurrentThread());
webrtc::RTCError result = webrtc_sender_->SetParameters(parameters);
- main_thread_->PostTask(
+ main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&RTCRtpSender::RTCRtpSenderInternal::SetParametersCallback, this,
@@ -252,23 +305,19 @@ class RTCRtpSender::RTCRtpSenderInternal
void SetParametersCallback(
webrtc::RTCError result,
base::OnceCallback<void(webrtc::RTCError)> callback) {
- DCHECK(main_thread_->BelongsToCurrentThread());
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
std::move(callback).Run(std::move(result));
}
const scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_;
- const scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map_;
- const rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender_;
- // 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 sender.
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref_;
- // Similarly, reference needs to be kept to the stream adapters of the
- // sender's associated set of streams.
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs_;
+ const scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
+ // Task runners and webrtc sender: Same information as stored in
+ // |state_| but const and safe to touch on the signaling thread to
+ // avoid race with set_state().
+ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ const scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender_;
+ RtpSenderState state_;
webrtc::RtpParameters parameters_;
};
@@ -280,8 +329,8 @@ struct RTCRtpSender::RTCRtpSenderInternalTraits {
static void Destruct(const RTCRtpSenderInternal* sender) {
// RTCRtpSenderInternal owns AdapterRefs which have to be destroyed on the
// main thread, this ensures delete always happens there.
- if (!sender->main_thread_->BelongsToCurrentThread()) {
- sender->main_thread_->PostTask(
+ if (!sender->main_task_runner_->BelongsToCurrentThread()) {
+ sender->main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&RTCRtpSender::RTCRtpSenderInternalTraits::Destruct,
base::Unretained(sender)));
@@ -297,36 +346,11 @@ uintptr_t RTCRtpSender::getId(const webrtc::RtpSenderInterface* webrtc_sender) {
RTCRtpSender::RTCRtpSender(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- blink::WebMediaStreamTrack web_track,
- std::vector<blink::WebMediaStream> web_streams)
- : internal_(new RTCRtpSenderInternal(std::move(native_peer_connection),
- std::move(main_thread),
- std::move(signaling_thread),
- std::move(stream_map),
- std::move(webrtc_sender),
- std::move(web_track),
- std::move(web_streams))) {}
-
-RTCRtpSender::RTCRtpSender(
- scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs)
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpSenderState state)
: internal_(new RTCRtpSenderInternal(std::move(native_peer_connection),
- std::move(main_thread),
- std::move(signaling_thread),
- std::move(stream_map),
- std::move(webrtc_sender),
- std::move(track_ref),
- std::move(stream_refs))) {}
+ std::move(track_map),
+ std::move(state))) {}
RTCRtpSender::RTCRtpSender(const RTCRtpSender& other)
: internal_(other.internal_) {}
@@ -338,19 +362,35 @@ RTCRtpSender& RTCRtpSender::operator=(const RTCRtpSender& other) {
return *this;
}
-std::unique_ptr<RTCRtpSender> RTCRtpSender::ShallowCopy() const {
+const RtpSenderState& RTCRtpSender::state() const {
+ return internal_->state();
+}
+
+void RTCRtpSender::set_state(RtpSenderState state) {
+ internal_->set_state(std::move(state));
+}
+
+std::unique_ptr<blink::WebRTCRtpSender> RTCRtpSender::ShallowCopy() const {
return std::make_unique<RTCRtpSender>(*this);
}
uintptr_t RTCRtpSender::Id() const {
- return getId(internal_->webrtc_sender());
+ return getId(internal_->state().webrtc_sender().get());
}
blink::WebMediaStreamTrack RTCRtpSender::Track() const {
- auto track_ref = internal_->track_ref();
+ const auto& track_ref = internal_->state().track_ref();
return track_ref ? track_ref->web_track() : blink::WebMediaStreamTrack();
}
+blink::WebVector<blink::WebString> RTCRtpSender::StreamIds() const {
+ const auto& stream_ids = internal_->state().stream_ids();
+ blink::WebVector<blink::WebString> web_stream_ids(stream_ids.size());
+ for (size_t i = 0; i < stream_ids.size(); ++i)
+ web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids[i]);
+ return web_stream_ids;
+}
+
void RTCRtpSender::ReplaceTrack(blink::WebMediaStreamTrack with_track,
blink::WebRTCVoidRequest request) {
internal_->ReplaceTrack(
@@ -381,20 +421,6 @@ void RTCRtpSender::GetStats(
internal_->GetStats(std::move(callback));
}
-webrtc::RtpSenderInterface* RTCRtpSender::webrtc_sender() const {
- return internal_->webrtc_sender();
-}
-
-const webrtc::MediaStreamTrackInterface* RTCRtpSender::webrtc_track() const {
- auto track_ref = internal_->track_ref();
- return track_ref ? track_ref->webrtc_track() : nullptr;
-}
-
-std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
-RTCRtpSender::stream_refs() const {
- return internal_->stream_refs();
-}
-
void RTCRtpSender::ReplaceTrack(blink::WebMediaStreamTrack with_track,
base::OnceCallback<void(bool)> callback) {
internal_->ReplaceTrack(std::move(with_track), std::move(callback));
@@ -405,4 +431,65 @@ bool RTCRtpSender::RemoveFromPeerConnection(
return internal_->RemoveFromPeerConnection(pc);
}
+RTCRtpSenderOnlyTransceiver::RTCRtpSenderOnlyTransceiver(
+ std::unique_ptr<blink::WebRTCRtpSender> sender)
+ : sender_(std::move(sender)) {
+ DCHECK(sender_);
+}
+
+RTCRtpSenderOnlyTransceiver::~RTCRtpSenderOnlyTransceiver() {}
+
+blink::WebRTCRtpTransceiverImplementationType
+RTCRtpSenderOnlyTransceiver::ImplementationType() const {
+ return blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly;
+}
+
+uintptr_t RTCRtpSenderOnlyTransceiver::Id() const {
+ NOTIMPLEMENTED();
+ return 0u;
+}
+
+blink::WebString RTCRtpSenderOnlyTransceiver::Mid() const {
+ NOTIMPLEMENTED();
+ return blink::WebString();
+}
+
+std::unique_ptr<blink::WebRTCRtpSender> RTCRtpSenderOnlyTransceiver::Sender()
+ const {
+ return sender_->ShallowCopy();
+}
+
+std::unique_ptr<blink::WebRTCRtpReceiver>
+RTCRtpSenderOnlyTransceiver::Receiver() const {
+ NOTIMPLEMENTED();
+ return nullptr;
+}
+
+bool RTCRtpSenderOnlyTransceiver::Stopped() const {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+webrtc::RtpTransceiverDirection RTCRtpSenderOnlyTransceiver::Direction() const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
+}
+
+void RTCRtpSenderOnlyTransceiver::SetDirection(
+ webrtc::RtpTransceiverDirection direction) {
+ NOTIMPLEMENTED();
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpSenderOnlyTransceiver::CurrentDirection() const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpSenderOnlyTransceiver::FiredDirection() const {
+ NOTIMPLEMENTED();
+ return webrtc::RtpTransceiverDirection::kSendOnly;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.h b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.h
index 990b21fb64c..7a96b39e38f 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_sender.h
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_sender.h
@@ -11,10 +11,10 @@
#include "base/callback.h"
#include "base/single_thread_task_runner.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/blink/public/platform/web_media_stream_track.h"
#include "third_party/blink/public/platform/web_rtc_rtp_sender.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
#include "third_party/blink/public/platform/web_rtc_stats.h"
#include "third_party/webrtc/api/peerconnectioninterface.h"
#include "third_party/webrtc/api/rtpsenderinterface.h"
@@ -22,43 +22,108 @@
namespace content {
+// This class represents the state of a sender; a snapshot of what a
+// webrtc-layer sender looked like when it was inspected on the signaling thread
+// such that this information can be moved to the main thread in a single
+// PostTask. It is used to surface state changes to make the blink-layer sender
+// up-to-date.
+//
+// Blink objects live on the main thread and webrtc objects live on the
+// signaling thread. If multiple asynchronous operations begin execution on the
+// main thread they are posted and executed in order on the signaling thread.
+// For example, operation A and operation B are called in JavaScript. When A is
+// done on the signaling thread, webrtc object states will be updated. A
+// callback is posted to the main thread so that blink objects can be updated to
+// match the result of operation A. But if callback A tries to inspect the
+// webrtc objects from the main thread this requires posting back to the
+// signaling thread and waiting, which also includes waiting for the previously
+// posted task: operation B. Inspecting the webrtc object like this does not
+// guarantee you to get the state of operation A.
+//
+// As such, all state changes associated with an operation have to be surfaced
+// in the same callback. This includes copying any states into a separate object
+// so that it can be inspected on the main thread without any additional thread
+// hops.
+//
+// The RtpSenderState is a snapshot of what the webrtc::RtpSenderInterface
+// looked like when the RtpSenderState was created on the signaling thread. It
+// also takes care of initializing track adapters, such that we have access to a
+// blink track corresponding to the webrtc track of the sender.
+//
+// Except for initialization logic and operator=(), the RtpSenderState is
+// immutable and only accessible on the main thread.
+//
+// TODO(hbos): [Onion Soup] When the sender implementation is moved to blink
+// this will be part of the blink sender instead of the content sender.
+// https://crbug.com/787254
+class CONTENT_EXPORT RtpSenderState {
+ public:
+ RtpSenderState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+ std::vector<std::string> stream_ids);
+ RtpSenderState(RtpSenderState&&);
+ RtpSenderState(const RtpSenderState&) = delete;
+ ~RtpSenderState();
+
+ // This is intended to be used for moving the object from the signaling thread
+ // to the main thread and as such has no thread checks. Once moved to the main
+ // this should only be invoked on the main thread.
+ RtpSenderState& operator=(RtpSenderState&&);
+ RtpSenderState& operator=(const RtpSenderState&) = delete;
+
+ bool is_initialized() const;
+ void Initialize();
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner() const;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const;
+ scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender() const;
+ const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+ track_ref() const;
+ void set_track_ref(
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref);
+ std::vector<std::string> stream_ids() const;
+
+ private:
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender_;
+ bool is_initialized_;
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref_;
+ std::vector<std::string> stream_ids_;
+};
+
// Used to surface |webrtc::RtpSenderInterface| to blink. Multiple
// |RTCRtpSender|s could reference the same webrtc sender; |id| is the value
// of the pointer to the webrtc sender.
+// TODO(hbos): [Onion Soup] Move all of the implementation inside the blink
+// object and remove this class and interface. The blink object is reference
+// counted and we can get rid of this "Web"-copyable with "internal" nonsense,
+// all the blink object will need is the RtpSenderState. Requires coordination
+// with transceivers and receivers since these are tightly coupled.
+// https://crbug.com/787254
class CONTENT_EXPORT RTCRtpSender : public blink::WebRTCRtpSender {
public:
static uintptr_t getId(const webrtc::RtpSenderInterface* webrtc_sender);
RTCRtpSender(
scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- blink::WebMediaStreamTrack web_track,
- std::vector<blink::WebMediaStream> web_streams);
- RTCRtpSender(
- scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<base::SingleThreadTaskRunner> signaling_thread,
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map,
- rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs);
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpSenderState state);
RTCRtpSender(const RTCRtpSender& other);
~RTCRtpSender() override;
-
RTCRtpSender& operator=(const RTCRtpSender& other);
- // Creates a shallow copy of the sender, representing the same underlying
- // webrtc sender as the original.
- // TODO(hbos): Remove in favor of constructor. https://crbug.com/790007
- std::unique_ptr<RTCRtpSender> ShallowCopy() const;
+ const RtpSenderState& state() const;
+ void set_state(RtpSenderState state);
// blink::WebRTCRtpSender.
+ std::unique_ptr<blink::WebRTCRtpSender> ShallowCopy() const override;
uintptr_t Id() const override;
blink::WebMediaStreamTrack Track() const override;
+ blink::WebVector<blink::WebString> StreamIds() const override;
void ReplaceTrack(blink::WebMediaStreamTrack with_track,
blink::WebRTCVoidRequest request) override;
std::unique_ptr<blink::WebRTCDTMFSenderHandler> GetDtmfSender()
@@ -69,10 +134,6 @@ class CONTENT_EXPORT RTCRtpSender : public blink::WebRTCRtpSender {
blink::WebRTCVoidRequest) override;
void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>) override;
- webrtc::RtpSenderInterface* webrtc_sender() const;
- const webrtc::MediaStreamTrackInterface* webrtc_track() const;
- std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>
- stream_refs() const;
// The ReplaceTrack() that takes a blink::WebRTCVoidRequest is implemented on
// top of this, which returns the result in a callback instead. Allows doing
// ReplaceTrack() without having a blink::WebRTCVoidRequest, which can only be
@@ -88,6 +149,30 @@ class CONTENT_EXPORT RTCRtpSender : public blink::WebRTCRtpSender {
scoped_refptr<RTCRtpSenderInternal> internal_;
};
+class CONTENT_EXPORT RTCRtpSenderOnlyTransceiver
+ : public blink::WebRTCRtpTransceiver {
+ public:
+ RTCRtpSenderOnlyTransceiver(std::unique_ptr<blink::WebRTCRtpSender> sender);
+ ~RTCRtpSenderOnlyTransceiver() override;
+
+ blink::WebRTCRtpTransceiverImplementationType ImplementationType()
+ const override;
+ uintptr_t Id() const override;
+ blink::WebString Mid() const override;
+ std::unique_ptr<blink::WebRTCRtpSender> Sender() const override;
+ std::unique_ptr<blink::WebRTCRtpReceiver> Receiver() const override;
+ bool Stopped() const override;
+ webrtc::RtpTransceiverDirection Direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection direction) override;
+ base::Optional<webrtc::RtpTransceiverDirection> CurrentDirection()
+ const override;
+ base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
+ const override;
+
+ private:
+ std::unique_ptr<blink::WebRTCRtpSender> sender_;
+};
+
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_SENDER_H_
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc
index eb086d2e0d2..0f3f27f9dad 100644
--- a/chromium/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc
@@ -16,7 +16,6 @@
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
#include "content/renderer/media/webrtc/test/webrtc_stats_report_obtainer.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/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -40,10 +39,8 @@ class RTCRtpSenderTest : public ::testing::Test {
void SetUp() override {
dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
- stream_map_ = new WebRtcMediaStreamAdapterMap(
- dependency_factory_.get(), main_thread_,
- new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
- main_thread_));
+ track_map_ = new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
+ main_thread_);
peer_connection_ = new rtc::RefCountedObject<MockPeerConnectionImpl>(
dependency_factory_.get(), nullptr);
mock_webrtc_sender_ = new rtc::RefCountedObject<webrtc::MockRtpSender>();
@@ -84,11 +81,18 @@ class RTCRtpSenderTest : public ::testing::Test {
std::unique_ptr<RTCRtpSender> CreateSender(
blink::WebMediaStreamTrack web_track) {
- return std::make_unique<RTCRtpSender>(
- peer_connection_.get(), main_thread_,
- dependency_factory_->GetWebRtcSignalingThread(), stream_map_,
- mock_webrtc_sender_.get(), std::move(web_track),
- std::vector<blink::WebMediaStream>());
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
+ if (!web_track.IsNull()) {
+ track_ref = track_map_->GetOrCreateLocalTrackAdapter(web_track);
+ DCHECK(track_ref->is_initialized());
+ }
+ RtpSenderState sender_state(main_thread_,
+ dependency_factory_->GetWebRtcSignalingThread(),
+ mock_webrtc_sender_.get(), std::move(track_ref),
+ std::vector<std::string>());
+ sender_state.Initialize();
+ return std::make_unique<RTCRtpSender>(peer_connection_.get(), track_map_,
+ std::move(sender_state));
}
// Calls replaceTrack(), which is asynchronous, returning a callback that when
@@ -139,7 +143,7 @@ class RTCRtpSenderTest : public ::testing::Test {
std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map_;
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
rtc::scoped_refptr<MockPeerConnectionImpl> peer_connection_;
rtc::scoped_refptr<webrtc::MockRtpSender> mock_webrtc_sender_;
std::unique_ptr<RTCRtpSender> sender_;
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.cc
new file mode 100644
index 00000000000..7bdda93416d
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.cc
@@ -0,0 +1,357 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc/rtc_rtp_transceiver.h"
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+
+namespace content {
+
+RtpTransceiverState::RtpTransceiverState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver,
+ base::Optional<RtpSenderState> sender_state,
+ base::Optional<RtpReceiverState> receiver_state,
+ base::Optional<std::string> mid,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction,
+ base::Optional<webrtc::RtpTransceiverDirection> fired_direction)
+ : main_task_runner_(std::move(main_task_runner)),
+ signaling_task_runner_(std::move(signaling_task_runner)),
+ webrtc_transceiver_(std::move(webrtc_transceiver)),
+ is_initialized_(false),
+ sender_state_(std::move(sender_state)),
+ receiver_state_(std::move(receiver_state)),
+ mid_(std::move(mid)),
+ stopped_(std::move(stopped)),
+ direction_(std::move(direction)),
+ current_direction_(std::move(current_direction)),
+ fired_direction_(std::move(fired_direction)) {
+ DCHECK(main_task_runner_);
+ DCHECK(signaling_task_runner_);
+ DCHECK(webrtc_transceiver_);
+}
+
+RtpTransceiverState::RtpTransceiverState(RtpTransceiverState&& other)
+ : main_task_runner_(other.main_task_runner_),
+ signaling_task_runner_(other.signaling_task_runner_),
+ webrtc_transceiver_(std::move(other.webrtc_transceiver_)),
+ is_initialized_(other.is_initialized_),
+ sender_state_(std::move(other.sender_state_)),
+ receiver_state_(std::move(other.receiver_state_)),
+ mid_(std::move(other.mid_)),
+ stopped_(std::move(other.stopped_)),
+ direction_(std::move(other.direction_)),
+ current_direction_(std::move(other.current_direction_)),
+ fired_direction_(std::move(other.fired_direction_)) {
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+}
+
+RtpTransceiverState::~RtpTransceiverState() {
+ // It's OK to not be on the main thread if this state has been moved, in which
+ // case |main_task_runner_| is null.
+ DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread());
+}
+
+RtpTransceiverState& RtpTransceiverState::operator=(
+ RtpTransceiverState&& other) {
+ DCHECK_EQ(main_task_runner_, other.main_task_runner_);
+ DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_);
+ // Need to be on main thread for sender/receiver state's destructor that can
+ // be triggered by replacing .
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+ webrtc_transceiver_ = std::move(other.webrtc_transceiver_);
+ is_initialized_ = other.is_initialized_;
+ sender_state_ = std::move(other.sender_state_);
+ receiver_state_ = std::move(other.receiver_state_);
+ mid_ = std::move(other.mid_);
+ stopped_ = std::move(other.stopped_);
+ direction_ = std::move(other.direction_);
+ current_direction_ = std::move(other.current_direction_);
+ fired_direction_ = std::move(other.fired_direction_);
+ return *this;
+}
+
+bool RtpTransceiverState::is_initialized() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return is_initialized_;
+}
+
+void RtpTransceiverState::Initialize() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ if (sender_state_)
+ sender_state_->Initialize();
+ if (receiver_state_)
+ receiver_state_->Initialize();
+ is_initialized_ = true;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+RtpTransceiverState::main_task_runner() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return main_task_runner_;
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+RtpTransceiverState::signaling_task_runner() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return signaling_task_runner_;
+}
+
+scoped_refptr<webrtc::RtpTransceiverInterface>
+RtpTransceiverState::webrtc_transceiver() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return webrtc_transceiver_;
+}
+
+const base::Optional<RtpSenderState>& RtpTransceiverState::sender_state()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return sender_state_;
+}
+
+RtpSenderState RtpTransceiverState::MoveSenderState() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ base::Optional<RtpSenderState> temp(base::nullopt);
+ sender_state_.swap(temp);
+ return *std::move(temp);
+}
+
+const base::Optional<RtpReceiverState>& RtpTransceiverState::receiver_state()
+ const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return receiver_state_;
+}
+
+RtpReceiverState RtpTransceiverState::MoveReceiverState() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ base::Optional<RtpReceiverState> temp(base::nullopt);
+ receiver_state_.swap(temp);
+ return *std::move(temp);
+}
+
+base::Optional<std::string> RtpTransceiverState::mid() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return mid_;
+}
+
+bool RtpTransceiverState::stopped() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return stopped_;
+}
+
+webrtc::RtpTransceiverDirection RtpTransceiverState::direction() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return direction_;
+}
+
+void RtpTransceiverState::set_direction(
+ webrtc::RtpTransceiverDirection direction) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ direction_ = direction;
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RtpTransceiverState::current_direction() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return current_direction_;
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RtpTransceiverState::fired_direction() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return fired_direction_;
+}
+
+class RTCRtpTransceiver::RTCRtpTransceiverInternal
+ : public base::RefCountedThreadSafe<
+ RTCRtpTransceiver::RTCRtpTransceiverInternal,
+ RTCRtpTransceiver::RTCRtpTransceiverInternalTraits> {
+ public:
+ RTCRtpTransceiverInternal(
+ scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpTransceiverState state)
+ : main_task_runner_(state.main_task_runner()),
+ signaling_task_runner_(state.signaling_task_runner()),
+ webrtc_transceiver_(state.webrtc_transceiver()),
+ state_(std::move(state)) {
+ sender_ = std::make_unique<RTCRtpSender>(native_peer_connection, track_map,
+ state_.MoveSenderState());
+ receiver_ = std::make_unique<RTCRtpReceiver>(native_peer_connection,
+ state_.MoveReceiverState());
+ }
+
+ const RtpTransceiverState& state() const {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return state_;
+ }
+
+ void set_state(RtpTransceiverState state) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK_EQ(state.main_task_runner(), main_task_runner_);
+ DCHECK_EQ(state.signaling_task_runner(), signaling_task_runner_);
+ DCHECK(state.webrtc_transceiver() == webrtc_transceiver_);
+ DCHECK(state.is_initialized());
+ state_ = std::move(state);
+ sender_->set_state(state_.MoveSenderState());
+ receiver_->set_state(state_.MoveReceiverState());
+ }
+
+ RTCRtpSender* content_sender() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return sender_.get();
+ }
+
+ RTCRtpReceiver* content_receiver() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ return receiver_.get();
+ }
+
+ void SetDirection(webrtc::RtpTransceiverDirection direction) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ // This implicitly performs a blocking invoke on the webrtc signaling thread
+ // due to use of PROXY references for |webrtc_transceiver_|.
+ webrtc_transceiver_->SetDirection(direction);
+ state_.set_direction(webrtc_transceiver_->direction());
+ }
+
+ private:
+ friend struct RTCRtpTransceiver::RTCRtpTransceiverInternalTraits;
+
+ ~RTCRtpTransceiverInternal() {
+ // Ensured by destructor traits.
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ }
+
+ // Task runners and webrtc transceiver: Same information as stored in |state_|
+ // but const and safe to touch on the signaling thread to avoid race with
+ // set_state().
+ const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ const scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver_;
+ RtpTransceiverState state_;
+ std::unique_ptr<RTCRtpSender> sender_;
+ std::unique_ptr<RTCRtpReceiver> receiver_;
+};
+
+struct RTCRtpTransceiver::RTCRtpTransceiverInternalTraits {
+ private:
+ friend class base::RefCountedThreadSafe<RTCRtpTransceiverInternal,
+ RTCRtpTransceiverInternalTraits>;
+
+ static void Destruct(const RTCRtpTransceiverInternal* transceiver) {
+ // RTCRtpTransceiverInternal owns AdapterRefs which have to be destroyed on
+ // the main thread, this ensures delete always happens there.
+ if (!transceiver->main_task_runner_->BelongsToCurrentThread()) {
+ transceiver->main_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &RTCRtpTransceiver::RTCRtpTransceiverInternalTraits::Destruct,
+ base::Unretained(transceiver)));
+ return;
+ }
+ delete transceiver;
+ }
+};
+
+uintptr_t RTCRtpTransceiver::GetId(
+ const webrtc::RtpTransceiverInterface* webrtc_transceiver) {
+ return reinterpret_cast<uintptr_t>(webrtc_transceiver);
+}
+
+RTCRtpTransceiver::RTCRtpTransceiver(
+ scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpTransceiverState transceiver_state)
+ : internal_(new RTCRtpTransceiverInternal(std::move(native_peer_connection),
+ std::move(track_map),
+ std::move(transceiver_state))) {}
+
+RTCRtpTransceiver::RTCRtpTransceiver(const RTCRtpTransceiver& other)
+ : internal_(other.internal_) {}
+
+RTCRtpTransceiver::~RTCRtpTransceiver() {}
+
+RTCRtpTransceiver& RTCRtpTransceiver::operator=(
+ const RTCRtpTransceiver& other) {
+ internal_ = other.internal_;
+ return *this;
+}
+
+std::unique_ptr<RTCRtpTransceiver> RTCRtpTransceiver::ShallowCopy() const {
+ return std::make_unique<RTCRtpTransceiver>(*this);
+}
+
+const RtpTransceiverState& RTCRtpTransceiver::state() const {
+ return internal_->state();
+}
+
+RTCRtpSender* RTCRtpTransceiver::content_sender() {
+ return internal_->content_sender();
+}
+
+RTCRtpReceiver* RTCRtpTransceiver::content_receiver() {
+ return internal_->content_receiver();
+}
+
+void RTCRtpTransceiver::set_state(RtpTransceiverState transceiver_state) {
+ internal_->set_state(std::move(transceiver_state));
+}
+
+blink::WebRTCRtpTransceiverImplementationType
+RTCRtpTransceiver::ImplementationType() const {
+ return blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver;
+}
+
+uintptr_t RTCRtpTransceiver::Id() const {
+ return GetId(internal_->state().webrtc_transceiver().get());
+}
+
+blink::WebString RTCRtpTransceiver::Mid() const {
+ const auto& mid = internal_->state().mid();
+ return mid ? blink::WebString::FromUTF8(*mid)
+ : blink::WebString(); // IsNull()
+}
+
+std::unique_ptr<blink::WebRTCRtpSender> RTCRtpTransceiver::Sender() const {
+ return internal_->content_sender()->ShallowCopy();
+}
+
+std::unique_ptr<blink::WebRTCRtpReceiver> RTCRtpTransceiver::Receiver() const {
+ return internal_->content_receiver()->ShallowCopy();
+}
+
+bool RTCRtpTransceiver::Stopped() const {
+ return internal_->state().stopped();
+}
+
+webrtc::RtpTransceiverDirection RTCRtpTransceiver::Direction() const {
+ return internal_->state().direction();
+}
+
+void RTCRtpTransceiver::SetDirection(
+ webrtc::RtpTransceiverDirection direction) {
+ internal_->SetDirection(direction);
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpTransceiver::CurrentDirection() const {
+ return internal_->state().current_direction();
+}
+
+base::Optional<webrtc::RtpTransceiverDirection>
+RTCRtpTransceiver::FiredDirection() const {
+ return internal_->state().fired_direction();
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.h b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.h
new file mode 100644
index 00000000000..5eadedf1955
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver.h
@@ -0,0 +1,160 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_TRANSCEIVER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_TRANSCEIVER_H_
+
+#include "base/memory/scoped_refptr.h"
+#include "base/optional.h"
+#include "base/single_thread_task_runner.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_track_adapter_map.h"
+#include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
+#include "third_party/webrtc/api/rtptransceiverinterface.h"
+
+namespace content {
+
+// This class represents the state of a transceiver; a snapshot of what a
+// webrtc-layer transceiver looked like when it was inspected on the signaling
+// thread such that this information can be moved to the main thread in a single
+// PostTask. It is used to surface state changes to make the blink-layer
+// transceiver up-to-date.
+//
+// Blink objects live on the main thread and webrtc objects live on the
+// signaling thread. If multiple asynchronous operations begin execution on the
+// main thread they are posted and executed in order on the signaling thread.
+// For example, operation A and operation B are called in JavaScript. When A is
+// done on the signaling thread, webrtc object states will be updated. A
+// callback is posted to the main thread so that blink objects can be updated to
+// match the result of operation A. But if callback A tries to inspect the
+// webrtc objects from the main thread this requires posting back to the
+// signaling thread and waiting, which also includes waiting for the previously
+// posted task: operation B. Inspecting the webrtc object like this does not
+// guarantee you to get the state of operation A.
+//
+// As such, all state changes associated with an operation have to be surfaced
+// in the same callback. This includes copying any states into a separate object
+// so that it can be inspected on the main thread without any additional thread
+// hops.
+//
+// The RtpTransceiverState is a snapshot of what the
+// webrtc::RtpTransceiverInterface looked like when the RtpTransceiverState was
+// created on the signaling thread. It also takes care of initializing sender
+// and receiver states, including their track adapters such that we have access
+// to a blink track corresponding to the webrtc tracks of the sender and
+// receiver.
+//
+// Except for initialization logic and operator=(), the RtpTransceiverState is
+// immutable and only accessible on the main thread.
+//
+// TODO(hbos): [Onion Soup] When the transceiver implementation is moved to
+// blink this will be part of the blink transceiver instead of the content
+// transceiver. https://crbug.com/787254
+class CONTENT_EXPORT RtpTransceiverState {
+ public:
+ RtpTransceiverState(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver,
+ base::Optional<RtpSenderState> sender_state,
+ base::Optional<RtpReceiverState> receiver_state,
+ base::Optional<std::string> mid,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction,
+ base::Optional<webrtc::RtpTransceiverDirection> fired_direction);
+ RtpTransceiverState(RtpTransceiverState&&);
+ RtpTransceiverState(const RtpTransceiverState&) = delete;
+ ~RtpTransceiverState();
+
+ // This is intended to be used for moving the object from the signaling thread
+ // to the main thread and as such has no thread checks. Once moved to the main
+ // this should only be invoked on the main thread.
+ RtpTransceiverState& operator=(RtpTransceiverState&&);
+ RtpTransceiverState& operator=(const RtpTransceiverState&) = delete;
+
+ bool is_initialized() const;
+ void Initialize();
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner() const;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const;
+ scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver() const;
+ const base::Optional<RtpSenderState>& sender_state() const;
+ RtpSenderState MoveSenderState();
+ const base::Optional<RtpReceiverState>& receiver_state() const;
+ RtpReceiverState MoveReceiverState();
+ base::Optional<std::string> mid() const;
+ bool stopped() const;
+ webrtc::RtpTransceiverDirection direction() const;
+ void set_direction(webrtc::RtpTransceiverDirection);
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction() const;
+ base::Optional<webrtc::RtpTransceiverDirection> fired_direction() const;
+
+ private:
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver_;
+ bool is_initialized_;
+ base::Optional<RtpSenderState> sender_state_;
+ base::Optional<RtpReceiverState> receiver_state_;
+ base::Optional<std::string> mid_;
+ bool stopped_;
+ webrtc::RtpTransceiverDirection direction_;
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction_;
+ base::Optional<webrtc::RtpTransceiverDirection> fired_direction_;
+};
+
+// Used to surface |webrtc::RtpTransceiverInterface| to blink. Multiple
+// |RTCRtpTransceiver|s could reference the same webrtc transceiver; |id| is
+// unique per webrtc transceiver.
+// Its methods are accessed on the main thread, internally also performs
+// operations on the signaling thread.
+// TODO(hbos): [Onion Soup] Remove the content layer versions of this class and
+// rely on webrtc directly from blink. Requires coordination with senders and
+// receivers. https://crbug.com/787254
+class CONTENT_EXPORT RTCRtpTransceiver : public blink::WebRTCRtpTransceiver {
+ public:
+ static uintptr_t GetId(
+ const webrtc::RtpTransceiverInterface* webrtc_transceiver);
+
+ RTCRtpTransceiver(
+ scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+ RtpTransceiverState state);
+ RTCRtpTransceiver(const RTCRtpTransceiver& other);
+ ~RTCRtpTransceiver() override;
+
+ RTCRtpTransceiver& operator=(const RTCRtpTransceiver& other);
+ std::unique_ptr<RTCRtpTransceiver> ShallowCopy() const;
+
+ const RtpTransceiverState& state() const;
+ void set_state(RtpTransceiverState state);
+ RTCRtpSender* content_sender();
+ RTCRtpReceiver* content_receiver();
+
+ blink::WebRTCRtpTransceiverImplementationType ImplementationType()
+ const override;
+ uintptr_t Id() const override;
+ blink::WebString Mid() const override;
+ std::unique_ptr<blink::WebRTCRtpSender> Sender() const override;
+ std::unique_ptr<blink::WebRTCRtpReceiver> Receiver() const override;
+ bool Stopped() const override;
+ webrtc::RtpTransceiverDirection Direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection direction) override;
+ base::Optional<webrtc::RtpTransceiverDirection> CurrentDirection()
+ const override;
+ base::Optional<webrtc::RtpTransceiverDirection> FiredDirection()
+ const override;
+
+ private:
+ class RTCRtpTransceiverInternal;
+ struct RTCRtpTransceiverInternalTraits;
+
+ scoped_refptr<RTCRtpTransceiverInternal> internal_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_TRANSCEIVER_H_
diff --git a/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
new file mode 100644
index 00000000000..3690936bfc8
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
@@ -0,0 +1,363 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc/rtc_rtp_transceiver.h"
+
+#include <memory>
+
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/optional.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/synchronization/waitable_event.h"
+#include "build/build_config.h"
+#include "content/child/child_process.h"
+#include "content/renderer/media/stream/media_stream_audio_source.h"
+#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
+#include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "content/renderer/media/webrtc/webrtc_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/web_heap.h"
+#include "third_party/webrtc/api/test/mock_rtpreceiver.h"
+#include "third_party/webrtc/api/test/mock_rtpsender.h"
+
+namespace content {
+
+class RTCRtpTransceiverTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
+ main_task_runner_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
+ track_map_ = new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
+ main_task_runner_);
+ peer_connection_ = new rtc::RefCountedObject<MockPeerConnectionImpl>(
+ dependency_factory_.get(), nullptr);
+ }
+
+ void TearDown() override {
+ // Syncing up with the signaling thread ensures any pending operations on
+ // that thread are executed. If they post back to the main thread, such as
+ // the sender or receiver destructor traits, this is allowed to execute
+ // before the test shuts down the threads.
+ SyncWithSignalingThread();
+ blink::WebHeap::CollectAllGarbageForTesting();
+ }
+
+ // Wait for the signaling thread to perform any queued tasks, executing tasks
+ // posted to the current thread in the meantime while waiting.
+ void SyncWithSignalingThread() const {
+ base::RunLoop run_loop;
+ dependency_factory_->GetWebRtcSignalingThread()->PostTask(
+ FROM_HERE, run_loop.QuitClosure());
+ run_loop.Run();
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const {
+ return dependency_factory_->GetWebRtcSignalingThread();
+ }
+
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ CreateLocalTrackAndAdapter(const std::string& id) {
+ return track_map_->GetOrCreateLocalTrackAdapter(CreateBlinkLocalTrack(id));
+ }
+
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ CreateRemoteTrackAndAdapter(const std::string& id) {
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track =
+ MockWebRtcAudioTrack::Create(id).get();
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
+ base::RunLoop run_loop;
+ signaling_task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &RTCRtpTransceiverTest::CreateRemoteTrackAdapterOnSignalingThread,
+ base::Unretained(this), std::move(webrtc_track),
+ base::Unretained(&track_ref), base::Unretained(&run_loop)));
+ run_loop.Run();
+ DCHECK(track_ref);
+ return track_ref;
+ }
+
+ rtc::scoped_refptr<FakeRtpSender> CreateWebRtcSender(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ const std::string& stream_id) {
+ return new rtc::RefCountedObject<FakeRtpSender>(
+ std::move(track), std::vector<std::string>({stream_id}));
+ }
+
+ rtc::scoped_refptr<FakeRtpReceiver> CreateWebRtcReceiver(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ const std::string& stream_id) {
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ new rtc::RefCountedObject<MockMediaStream>(stream_id));
+ return new rtc::RefCountedObject<FakeRtpReceiver>(
+ track.get(),
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>(
+ {remote_stream}));
+ }
+
+ rtc::scoped_refptr<FakeRtpTransceiver> CreateWebRtcTransceiver(
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender,
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
+ base::Optional<std::string> mid,
+ bool stopped,
+ webrtc::RtpTransceiverDirection direction,
+ base::Optional<webrtc::RtpTransceiverDirection> current_direction) {
+ DCHECK(!sender->track() ||
+ sender->track()->kind() == receiver->track()->kind());
+ return new rtc::RefCountedObject<FakeRtpTransceiver>(
+ receiver->track()->kind() ==
+ webrtc::MediaStreamTrackInterface::kAudioKind
+ ? cricket::MEDIA_TYPE_AUDIO
+ : cricket::MEDIA_TYPE_VIDEO,
+ std::move(sender), std::move(receiver), std::move(mid), stopped,
+ direction, std::move(current_direction));
+ }
+
+ RtpTransceiverState CreateTransceiverState(
+ rtc::scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ sender_track_ref,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ receiver_track_ref) {
+ std::vector<std::string> receiver_stream_ids;
+ for (const auto& stream : webrtc_transceiver->receiver()->streams()) {
+ receiver_stream_ids.push_back(stream->id());
+ }
+ return RtpTransceiverState(
+ main_task_runner_, signaling_task_runner(), webrtc_transceiver.get(),
+ RtpSenderState(main_task_runner_, signaling_task_runner(),
+ webrtc_transceiver->sender().get(),
+ std::move(sender_track_ref),
+ webrtc_transceiver->sender()->stream_ids()),
+ RtpReceiverState(main_task_runner_, signaling_task_runner(),
+ webrtc_transceiver->receiver().get(),
+ std::move(receiver_track_ref),
+ std::move(receiver_stream_ids)),
+ ToBaseOptional(webrtc_transceiver->mid()),
+ webrtc_transceiver->stopped(), webrtc_transceiver->direction(),
+ ToBaseOptional(webrtc_transceiver->current_direction()),
+ ToBaseOptional(webrtc_transceiver->fired_direction()));
+ }
+
+ protected:
+ blink::WebMediaStreamTrack CreateBlinkLocalTrack(const std::string& id) {
+ blink::WebMediaStreamSource web_source;
+ web_source.Initialize(
+ blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio,
+ blink::WebString::FromUTF8("local_audio_track"), false);
+ MediaStreamAudioSource* audio_source = new MediaStreamAudioSource(true);
+ // Takes ownership of |audio_source|.
+ web_source.SetExtraData(audio_source);
+
+ blink::WebMediaStreamTrack web_track;
+ web_track.Initialize(web_source.Id(), web_source);
+ audio_source->ConnectToTrack(web_track);
+ return web_track;
+ }
+
+ void CreateRemoteTrackAdapterOnSignalingThread(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>* track_ref,
+ base::RunLoop* run_loop) {
+ *track_ref = track_map_->GetOrCreateRemoteTrackAdapter(webrtc_track.get());
+ run_loop->Quit();
+ }
+
+ private:
+ base::MessageLoop message_loop_;
+
+ protected:
+ std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
+ rtc::scoped_refptr<MockPeerConnectionImpl> peer_connection_;
+};
+
+TEST_F(RTCRtpTransceiverTest, InitializeTransceiverState) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track");
+ auto webrtc_transceiver = CreateWebRtcTransceiver(
+ CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream"),
+ CreateWebRtcReceiver(remote_track_adapter->webrtc_track(),
+ "remote_stream"),
+ base::nullopt, false, webrtc::RtpTransceiverDirection::kSendRecv,
+ base::nullopt);
+ RtpTransceiverState transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, std::move(local_track_adapter),
+ std::move(remote_track_adapter));
+ EXPECT_FALSE(transceiver_state.is_initialized());
+ transceiver_state.Initialize();
+
+ EXPECT_TRUE(transceiver_state.is_initialized());
+ // Inspect sender states.
+ const auto& sender_state = transceiver_state.sender_state();
+ EXPECT_TRUE(sender_state);
+ EXPECT_TRUE(sender_state->is_initialized());
+ const auto& webrtc_sender = webrtc_transceiver->sender();
+ EXPECT_EQ(sender_state->webrtc_sender().get(), webrtc_sender.get());
+ EXPECT_TRUE(sender_state->track_ref()->is_initialized());
+ EXPECT_EQ(sender_state->track_ref()->webrtc_track(),
+ webrtc_sender->track().get());
+ EXPECT_EQ(sender_state->stream_ids(), webrtc_sender->stream_ids());
+ // Inspect receiver states.
+ const auto& receiver_state = transceiver_state.receiver_state();
+ EXPECT_TRUE(receiver_state);
+ EXPECT_TRUE(receiver_state->is_initialized());
+ const auto& webrtc_receiver = webrtc_transceiver->receiver();
+ EXPECT_EQ(receiver_state->webrtc_receiver().get(), webrtc_receiver.get());
+ EXPECT_TRUE(receiver_state->track_ref()->is_initialized());
+ EXPECT_EQ(receiver_state->track_ref()->webrtc_track(),
+ webrtc_receiver->track().get());
+ std::vector<std::string> receiver_stream_ids;
+ for (const auto& stream : webrtc_receiver->streams()) {
+ receiver_stream_ids.push_back(stream->id());
+ }
+ EXPECT_EQ(receiver_state->stream_ids(), receiver_stream_ids);
+ // Inspect transceiver states.
+ EXPECT_TRUE(
+ OptionalEquals(transceiver_state.mid(), webrtc_transceiver->mid()));
+ EXPECT_EQ(transceiver_state.stopped(), webrtc_transceiver->stopped());
+ EXPECT_TRUE(transceiver_state.direction() == webrtc_transceiver->direction());
+ EXPECT_TRUE(OptionalEquals(transceiver_state.current_direction(),
+ webrtc_transceiver->current_direction()));
+ EXPECT_TRUE(OptionalEquals(transceiver_state.fired_direction(),
+ webrtc_transceiver->fired_direction()));
+}
+
+TEST_F(RTCRtpTransceiverTest, CreateTranceiver) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track");
+ auto webrtc_transceiver = CreateWebRtcTransceiver(
+ CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream"),
+ CreateWebRtcReceiver(remote_track_adapter->webrtc_track(),
+ "remote_stream"),
+ base::nullopt, false, webrtc::RtpTransceiverDirection::kSendRecv,
+ base::nullopt);
+ RtpTransceiverState transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, std::move(local_track_adapter),
+ std::move(remote_track_adapter));
+ EXPECT_FALSE(transceiver_state.is_initialized());
+ transceiver_state.Initialize();
+
+ RTCRtpTransceiver transceiver(peer_connection_.get(), track_map_,
+ std::move(transceiver_state));
+ EXPECT_TRUE(transceiver.Mid().IsNull());
+ EXPECT_TRUE(transceiver.Sender());
+ EXPECT_TRUE(transceiver.Receiver());
+ EXPECT_FALSE(transceiver.Stopped());
+ EXPECT_EQ(transceiver.Direction(),
+ webrtc::RtpTransceiverDirection::kSendRecv);
+ EXPECT_FALSE(transceiver.CurrentDirection());
+ EXPECT_FALSE(transceiver.FiredDirection());
+}
+
+TEST_F(RTCRtpTransceiverTest, ModifyTransceiver) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track");
+ auto webrtc_sender =
+ CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream");
+ auto webrtc_receiver = CreateWebRtcReceiver(
+ remote_track_adapter->webrtc_track(), "remote_stream");
+ auto webrtc_transceiver = CreateWebRtcTransceiver(
+ webrtc_sender, webrtc_receiver, base::nullopt, false,
+ webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt);
+
+ // Create initial state.
+ RtpTransceiverState initial_transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(),
+ remote_track_adapter->Copy());
+ EXPECT_FALSE(initial_transceiver_state.is_initialized());
+ initial_transceiver_state.Initialize();
+
+ // Modify the webrtc transceiver and create a new state object for the
+ // modified state.
+ *webrtc_transceiver =
+ *CreateWebRtcTransceiver(webrtc_sender, webrtc_receiver, "MidyMacMidface",
+ true, webrtc::RtpTransceiverDirection::kInactive,
+ webrtc::RtpTransceiverDirection::kSendRecv);
+ RtpTransceiverState modified_transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(),
+ remote_track_adapter->Copy());
+ EXPECT_FALSE(modified_transceiver_state.is_initialized());
+ modified_transceiver_state.Initialize();
+
+ // Modifying the webrtc transceiver after the initial state was created should
+ // not have affected the transceiver state.
+ RTCRtpTransceiver transceiver(peer_connection_.get(), track_map_,
+ std::move(initial_transceiver_state));
+ EXPECT_TRUE(transceiver.Mid().IsNull());
+ EXPECT_TRUE(transceiver.Sender());
+ EXPECT_TRUE(transceiver.Receiver());
+ EXPECT_FALSE(transceiver.Stopped());
+ EXPECT_EQ(transceiver.Direction(),
+ webrtc::RtpTransceiverDirection::kSendRecv);
+ EXPECT_FALSE(transceiver.CurrentDirection());
+ EXPECT_FALSE(transceiver.FiredDirection());
+
+ // Setting the state should make the transceiver state up-to-date.
+ transceiver.set_state(std::move(modified_transceiver_state));
+ EXPECT_EQ(transceiver.Mid(), "MidyMacMidface");
+ EXPECT_TRUE(transceiver.Sender());
+ EXPECT_TRUE(transceiver.Receiver());
+ EXPECT_TRUE(transceiver.Stopped());
+ EXPECT_EQ(transceiver.Direction(),
+ webrtc::RtpTransceiverDirection::kInactive);
+ EXPECT_TRUE(transceiver.CurrentDirection() ==
+ webrtc::RtpTransceiverDirection::kSendRecv);
+ EXPECT_FALSE(transceiver.FiredDirection());
+}
+
+TEST_F(RTCRtpTransceiverTest, ShallowCopy) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track");
+ auto webrtc_sender =
+ CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream");
+ auto webrtc_receiver = CreateWebRtcReceiver(
+ remote_track_adapter->webrtc_track(), "remote_stream");
+ auto webrtc_transceiver = CreateWebRtcTransceiver(
+ webrtc_sender, webrtc_receiver, base::nullopt, false /* stopped */,
+ webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt);
+
+ std::unique_ptr<RTCRtpTransceiver> transceiver;
+ // Create transceiver.
+ {
+ RtpTransceiverState transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(),
+ remote_track_adapter->Copy());
+ EXPECT_FALSE(transceiver_state.is_initialized());
+ transceiver_state.Initialize();
+ transceiver.reset(new RTCRtpTransceiver(peer_connection_.get(), track_map_,
+ std::move(transceiver_state)));
+ }
+ DCHECK(transceiver);
+ EXPECT_FALSE(transceiver->Stopped());
+
+ std::unique_ptr<RTCRtpTransceiver> shallow_copy = transceiver->ShallowCopy();
+ // Modifying the shallow copy should modify the original too since they have a
+ // shared internal state.
+ {
+ // Modify webrtc transceiver to be stopped.
+ *webrtc_transceiver = *CreateWebRtcTransceiver(
+ webrtc_sender, webrtc_receiver, base::nullopt, true /* stopped */,
+ webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt);
+ RtpTransceiverState transceiver_state =
+ CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(),
+ remote_track_adapter->Copy());
+ EXPECT_FALSE(transceiver_state.is_initialized());
+ transceiver_state.Initialize();
+ // Set the state of the shallow copy.
+ shallow_copy->set_state(std::move(transceiver_state));
+ }
+ EXPECT_TRUE(shallow_copy->Stopped());
+ EXPECT_TRUE(transceiver->Stopped());
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/rtc_stats.cc b/chromium/content/renderer/media/webrtc/rtc_stats.cc
index 0c7478f8646..a24ef5bc613 100644
--- a/chromium/content/renderer/media/webrtc/rtc_stats.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_stats.cc
@@ -4,6 +4,7 @@
#include "content/renderer/media/webrtc/rtc_stats.h"
+#include <algorithm>
#include <set>
#include <string>
@@ -57,6 +58,22 @@ bool IsWhitelistedStats(const webrtc::RTCStats& stats) {
return GetStatsWhitelist()->IsWhitelisted(stats);
}
+// Filters out any unstandardized members; stats should only be surfaced to JS
+// if they're standardized.
+std::vector<const webrtc::RTCStatsMemberInterface*> StandardizedMembers(
+ std::vector<const webrtc::RTCStatsMemberInterface*> stats_members) {
+ // Note that using "is_standarized" avoids having to maintain a whitelist of
+ // every single standardized member, as we do at the "stats object" level
+ // with "RTCStatsWhitelist".
+ stats_members.erase(
+ std::remove_if(stats_members.begin(), stats_members.end(),
+ [](const webrtc::RTCStatsMemberInterface* member) {
+ return !member->is_standardized();
+ }),
+ stats_members.end());
+ return stats_members;
+}
+
} // namespace
RTCStatsReport::RTCStatsReport(
@@ -105,7 +122,7 @@ RTCStats::RTCStats(
const webrtc::RTCStats* stats)
: stats_owner_(stats_owner),
stats_(stats),
- stats_members_(stats->Members()) {
+ stats_members_(StandardizedMembers(stats->Members())) {
DCHECK(stats_owner_);
DCHECK(stats_);
DCHECK(stats_owner_->Get(stats_->id()));
diff --git a/chromium/content/renderer/media/webrtc/rtc_stats.h b/chromium/content/renderer/media/webrtc/rtc_stats.h
index 937cb25f3f0..370ab41d587 100644
--- a/chromium/content/renderer/media/webrtc/rtc_stats.h
+++ b/chromium/content/renderer/media/webrtc/rtc_stats.h
@@ -15,6 +15,9 @@
namespace content {
+// Wrapper around a webrtc::RTCStatsReport that also filters out any stats
+// objects that aren't whitelisted, and any members that aren't standardized
+// (using RTCStatsMemberInterface::is_standardized).
class CONTENT_EXPORT RTCStatsReport : public blink::WebRTCStatsReport {
public:
RTCStatsReport(
diff --git a/chromium/content/renderer/media/webrtc/rtc_stats_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_stats_unittest.cc
index 379f3bc0918..6cf1d5bd49b 100644
--- a/chromium/content/renderer/media/webrtc/rtc_stats_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_stats_unittest.cc
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <memory>
+
#include "content/renderer/media/webrtc/rtc_stats.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -45,4 +47,47 @@ TEST(RTCStatsTest, OnlyIncludeWhitelistedStats_Iteration) {
EXPECT_FALSE(report.Next());
}
+// Stats object with both a standard and non-standard member, used for the test
+// below.
+namespace {
+class TestStats : public webrtc::RTCStats {
+ public:
+ WEBRTC_RTCSTATS_DECL();
+
+ TestStats(const std::string& id, int64_t timestamp_us);
+ ~TestStats() override = default;
+
+ webrtc::RTCStatsMember<int32_t> standardized;
+ webrtc::RTCNonStandardStatsMember<int32_t> non_standardized;
+};
+
+WEBRTC_RTCSTATS_IMPL(TestStats,
+ webrtc::RTCStats,
+ "teststats",
+ &standardized,
+ &non_standardized);
+
+TestStats::TestStats(const std::string& id, int64_t timestamp_us)
+ : RTCStats(id, timestamp_us),
+ standardized("standardized"),
+ non_standardized("non_standardized") {}
+} // namespace
+
+// Similar to how only whitelisted stats objects should be surfaced, only
+// standardized members of the whitelisted objects should be surfaced.
+TEST(RTCStatsTest, OnlyIncludeStandarizedMembers) {
+ rtc::scoped_refptr<webrtc::RTCStatsReport> webrtc_report =
+ webrtc::RTCStatsReport::Create(42);
+ WhitelistStatsForTesting(TestStats::kType);
+ webrtc_report->AddStats(std::make_unique<TestStats>("id", 0));
+
+ // TestStats has two members, but the non-standard member should be filtered
+ // out.
+ RTCStatsReport report(webrtc_report.get());
+ std::unique_ptr<blink::WebRTCStats> stats = report.Next();
+ ASSERT_NE(nullptr, stats);
+ ASSERT_EQ(1u, stats->MembersCount());
+ EXPECT_EQ("standardized", stats->GetMember(0)->GetName());
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_decoder_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_video_decoder_unittest.cc
index 050c9f61d84..864cb65f90c 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_decoder_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_decoder_unittest.cc
@@ -70,6 +70,8 @@ class RTCVideoDecoderTest
capabilities_.supported_profiles.push_back(supported_profile);
supported_profile.profile = media::VP8PROFILE_ANY;
capabilities_.supported_profiles.push_back(supported_profile);
+ supported_profile.profile = media::VP9PROFILE_MIN;
+ capabilities_.supported_profiles.push_back(supported_profile);
EXPECT_CALL(*mock_gpu_factories_.get(), GetTaskRunner())
.WillRepeatedly(Return(vda_task_runner_));
@@ -231,6 +233,24 @@ TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) {
rtc_decoder_->Decode(input_image, missingFrames, nullptr, 0));
}
+TEST_F(RTCVideoDecoderTest, FallBackToSoftwareOnVp9Svc) {
+ // HW VP9 decoders don't handle more than one spatial layer. See
+ // https://crbug.com/webrtc/9304, https://crbug.com/webrtc/9518 for details.
+ // The RTC video decoder triggers software fallback if it receives stream
+ // with more than one spatial layer.
+ CreateDecoder(webrtc::kVideoCodecVP9);
+ Initialize();
+
+ webrtc::CodecSpecificInfo codec_specific_info;
+ codec_specific_info.codecType = webrtc::kVideoCodecVP9;
+ codec_specific_info.codecSpecific.VP9.ss_data_available = true;
+ codec_specific_info.codecSpecific.VP9.num_spatial_layers = 2;
+
+ webrtc::EncodedImage input_image;
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE,
+ rtc_decoder_->Decode(input_image, false, &codec_specific_info, 0));
+}
+
TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) {
CreateDecoder(webrtc::kVideoCodecVP8);
Initialize();
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc b/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc
index bfa722c5fc2..69f49db28bc 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_encoder.cc
@@ -17,7 +17,6 @@
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
-#include "base/rand_util.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
@@ -115,7 +114,8 @@ class RTCVideoEncoder::Impl
public base::RefCountedThreadSafe<RTCVideoEncoder::Impl> {
public:
Impl(media::GpuVideoAcceleratorFactories* gpu_factories,
- webrtc::VideoCodecType video_codec_type);
+ webrtc::VideoCodecType video_codec_type,
+ webrtc::VideoContentType video_content_type);
// Create the VEA and call Initialize() on it. Called once per instantiation,
// and then the instance is bound forevermore to whichever thread made the
@@ -163,10 +163,9 @@ class RTCVideoEncoder::Impl
void RequireBitstreamBuffers(unsigned int input_count,
const gfx::Size& input_coded_size,
size_t output_buffer_size) override;
- void BitstreamBufferReady(int32_t bitstream_buffer_id,
- size_t payload_size,
- bool key_frame,
- base::TimeDelta timestamp) override;
+ void BitstreamBufferReady(
+ int32_t bitstream_buffer_id,
+ const media::BitstreamBufferMetadata& metadata) override;
void NotifyError(media::VideoEncodeAccelerator::Error error) override;
private:
@@ -206,8 +205,7 @@ class RTCVideoEncoder::Impl
// Return an encoded output buffer to WebRTC.
void ReturnEncodedImage(const webrtc::EncodedImage& image,
- int32_t bitstream_buffer_id,
- uint16_t picture_id);
+ int32_t bitstream_buffer_id);
void SetStatus(int32_t status);
@@ -262,15 +260,15 @@ class RTCVideoEncoder::Impl
// encoder.
int output_buffers_free_count_;
- // 15 bits running index of the VP8 frames. See VP8 RTP spec for details.
- uint16_t picture_id_;
-
// webrtc::VideoEncoder encode complete callback.
webrtc::EncodedImageCallback* encoded_image_callback_;
// The video codec type, as reported to WebRTC.
const webrtc::VideoCodecType video_codec_type_;
+ // The content type, as reported to WebRTC (screenshare vs realtime video).
+ const webrtc::VideoContentType video_content_type_;
+
// Protect |status_|. |status_| is read or written on |gpu_task_runner_| in
// Impl. It can be read in RTCVideoEncoder on other threads.
mutable base::Lock status_lock_;
@@ -285,7 +283,8 @@ class RTCVideoEncoder::Impl
};
RTCVideoEncoder::Impl::Impl(media::GpuVideoAcceleratorFactories* gpu_factories,
- webrtc::VideoCodecType video_codec_type)
+ webrtc::VideoCodecType video_codec_type,
+ webrtc::VideoContentType video_content_type)
: gpu_factories_(gpu_factories),
async_waiter_(nullptr),
async_retval_(nullptr),
@@ -295,10 +294,9 @@ RTCVideoEncoder::Impl::Impl(media::GpuVideoAcceleratorFactories* gpu_factories,
output_buffers_free_count_(0),
encoded_image_callback_(nullptr),
video_codec_type_(video_codec_type),
+ video_content_type_(video_content_type),
status_(WEBRTC_VIDEO_CODEC_UNINITIALIZED) {
thread_checker_.DetachFromThread();
- // Picture ID should start on a random number.
- picture_id_ = static_cast<uint16_t>(base::RandInt(0, 0x7FFF));
}
void RTCVideoEncoder::Impl::CreateAndInitializeVEA(
@@ -505,13 +503,13 @@ void RTCVideoEncoder::Impl::RequireBitstreamBuffers(
SignalAsyncWaiter(WEBRTC_VIDEO_CODEC_OK);
}
-void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id,
- size_t payload_size,
- bool key_frame,
- base::TimeDelta timestamp) {
+void RTCVideoEncoder::Impl::BitstreamBufferReady(
+ int32_t bitstream_buffer_id,
+ const media::BitstreamBufferMetadata& metadata) {
DVLOG(3) << __func__ << " bitstream_buffer_id=" << bitstream_buffer_id
- << ", payload_size=" << payload_size << ", key_frame=" << key_frame
- << ", timestamp ms=" << timestamp.InMilliseconds();
+ << ", payload_size=" << metadata.payload_size_bytes
+ << ", key_frame=" << metadata.key_frame
+ << ", timestamp ms=" << metadata.timestamp.InMilliseconds();
DCHECK(thread_checker_.CalledOnValidThread());
if (bitstream_buffer_id < 0 ||
@@ -522,7 +520,7 @@ void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id,
}
base::SharedMemory* output_buffer =
output_buffers_[bitstream_buffer_id].get();
- if (payload_size > output_buffer->mapped_size()) {
+ if (metadata.payload_size_bytes > output_buffer->mapped_size()) {
LogAndNotifyError(FROM_HERE, "invalid payload_size",
media::VideoEncodeAccelerator::kPlatformFailureError);
return;
@@ -537,7 +535,7 @@ void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id,
// Pop timestamps until we have a match.
while (!pending_timestamps_.empty()) {
const auto& front_timestamps = pending_timestamps_.front();
- if (front_timestamps.media_timestamp_ == timestamp) {
+ if (front_timestamps.media_timestamp_ == metadata.timestamp) {
rtp_timestamp = front_timestamps.rtp_timestamp;
capture_timestamp_ms = front_timestamps.capture_time_ms;
pending_timestamps_.pop_front();
@@ -558,19 +556,18 @@ void RTCVideoEncoder::Impl::BitstreamBufferReady(int32_t bitstream_buffer_id,
}
webrtc::EncodedImage image(
- reinterpret_cast<uint8_t*>(output_buffer->memory()), payload_size,
- output_buffer->mapped_size());
+ reinterpret_cast<uint8_t*>(output_buffer->memory()),
+ metadata.payload_size_bytes, output_buffer->mapped_size());
image._encodedWidth = input_visible_size_.width();
image._encodedHeight = input_visible_size_.height();
image._timeStamp = rtp_timestamp.value();
image.capture_time_ms_ = capture_timestamp_ms.value();
image._frameType =
- (key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta);
+ (metadata.key_frame ? webrtc::kVideoFrameKey : webrtc::kVideoFrameDelta);
+ image.content_type_ = video_content_type_;
image._completeFrame = true;
- ReturnEncodedImage(image, bitstream_buffer_id, picture_id_);
- // Picture ID must wrap after reaching the maximum.
- picture_id_ = (picture_id_ + 1) & 0x7FFF;
+ ReturnEncodedImage(image, bitstream_buffer_id);
}
void RTCVideoEncoder::Impl::NotifyError(
@@ -759,11 +756,9 @@ void RTCVideoEncoder::Impl::RegisterEncodeCompleteCallback(
void RTCVideoEncoder::Impl::ReturnEncodedImage(
const webrtc::EncodedImage& image,
- int32_t bitstream_buffer_id,
- uint16_t picture_id) {
+ int32_t bitstream_buffer_id) {
DCHECK(thread_checker_.CalledOnValidThread());
- DVLOG(3) << __func__ << " bitstream_buffer_id=" << bitstream_buffer_id
- << ", picture_id=" << picture_id;
+ DVLOG(3) << __func__ << " bitstream_buffer_id=" << bitstream_buffer_id;
if (!encoded_image_callback_)
return;
@@ -798,8 +793,6 @@ void RTCVideoEncoder::Impl::ReturnEncodedImage(
info.codecType = video_codec_type_;
info.codec_name = ImplementationName();
if (video_codec_type_ == webrtc::kVideoCodecVP8) {
- info.codecSpecific.VP8.pictureId = picture_id;
- info.codecSpecific.VP8.tl0PicIdx = -1;
info.codecSpecific.VP8.keyIdx = -1;
}
@@ -840,7 +833,7 @@ int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
Release();
if (codec_settings->codecType == webrtc::kVideoCodecVP8 &&
- codec_settings->mode == webrtc::kScreensharing &&
+ codec_settings->mode == webrtc::VideoCodecMode::kScreensharing &&
codec_settings->VP8().numberOfTemporalLayers > 1) {
// This is a VP8 stream with screensharing using temporal layers for
// temporal scalability. Since this implementation does not yet implement
@@ -854,7 +847,11 @@ int32_t RTCVideoEncoder::InitEncode(const webrtc::VideoCodec* codec_settings,
}
}
- impl_ = new Impl(gpu_factories_, ProfileToWebRtcVideoCodecType(profile_));
+ impl_ =
+ new Impl(gpu_factories_, ProfileToWebRtcVideoCodecType(profile_),
+ (codec_settings->mode == webrtc::VideoCodecMode::kScreensharing)
+ ? webrtc::VideoContentType::SCREENSHARE
+ : webrtc::VideoContentType::UNSPECIFIED);
base::WaitableEvent initialization_waiter(
base::WaitableEvent::ResetPolicy::MANUAL,
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_encoder_factory.cc b/chromium/content/renderer/media/webrtc/rtc_video_encoder_factory.cc
index 3307c40e0b8..7b89e610a23 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_encoder_factory.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_encoder_factory.cc
@@ -73,7 +73,7 @@ base::Optional<cricket::VideoCodec> VEAToWebRTCCodec(
const int fps = profile.max_framerate_numerator;
DCHECK_EQ(1u, profile.max_framerate_denominator);
- const rtc::Optional<webrtc::H264::Level> h264_level =
+ const absl::optional<webrtc::H264::Level> h264_level =
webrtc::H264::SupportedLevel(width * height, fps);
const webrtc::H264::ProfileLevelId profile_level_id(
h264_profile, h264_level.value_or(webrtc::H264::kLevel1));
diff --git a/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc b/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc
index d3defba9124..2d142d5aa82 100644
--- a/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/rtc_video_encoder_unittest.cc
@@ -180,7 +180,9 @@ class RTCVideoEncoderTest
void ReturnFrameWithTimeStamp(const scoped_refptr<media::VideoFrame>& frame,
bool force_keyframe) {
- client_->BitstreamBufferReady(0, 0, force_keyframe, frame->timestamp());
+ client_->BitstreamBufferReady(
+ 0,
+ media::BitstreamBufferMetadata(0, force_keyframe, frame->timestamp()));
}
void VerifyTimestamp(uint32_t rtp_timestamp,
diff --git a/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc
new file mode 100644
index 00000000000..4792cefac27
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.cc
@@ -0,0 +1,225 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc/transceiver_state_surfacer.h"
+
+#include "content/renderer/media/webrtc/webrtc_util.h"
+#include "third_party/webrtc/api/rtptransceiverinterface.h"
+
+namespace content {
+
+TransceiverStateSurfacer::TransceiverStateSurfacer(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner)
+ : main_task_runner_(std::move(main_task_runner)),
+ signaling_task_runner_(std::move(signaling_task_runner)),
+ is_initialized_(false),
+ states_obtained_(false) {
+ DCHECK(main_task_runner_);
+ DCHECK(signaling_task_runner_);
+}
+
+TransceiverStateSurfacer::TransceiverStateSurfacer(
+ TransceiverStateSurfacer&& other)
+ : main_task_runner_(other.main_task_runner_),
+ signaling_task_runner_(other.signaling_task_runner_),
+ is_initialized_(other.is_initialized_),
+ states_obtained_(other.states_obtained_),
+ transceiver_states_(std::move(other.transceiver_states_)) {
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+}
+
+TransceiverStateSurfacer::~TransceiverStateSurfacer() {
+ // It's OK to not be on the main thread if this object has been moved, in
+ // which case |main_task_runner_| is null.
+ DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread());
+}
+
+TransceiverStateSurfacer& TransceiverStateSurfacer::operator=(
+ TransceiverStateSurfacer&& other) {
+ main_task_runner_ = other.main_task_runner_;
+ signaling_task_runner_ = other.signaling_task_runner_;
+ states_obtained_ = other.states_obtained_;
+ transceiver_states_ = std::move(other.transceiver_states_);
+ // Explicitly null |other|'s task runners for use in destructor.
+ other.main_task_runner_ = nullptr;
+ other.signaling_task_runner_ = nullptr;
+ return *this;
+}
+
+void TransceiverStateSurfacer::Initialize(
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ webrtc_transceivers) {
+ DCHECK(signaling_task_runner_->BelongsToCurrentThread());
+ DCHECK(!is_initialized_);
+ for (auto& webrtc_transceiver : webrtc_transceivers) {
+ // Create the sender state.
+ base::Optional<RtpSenderState> sender_state;
+ auto webrtc_sender = webrtc_transceiver->sender();
+ if (webrtc_sender) {
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ sender_track_ref;
+ if (webrtc_sender->track()) {
+ // The track adapter for this track must already exist for us to obtain
+ // it, since this cannot be created from the signaling thread.
+ // TODO(hbos): Consider either making it possible to create local track
+ // adapters on the signaling thread for initialization on the main
+ // thread or wait for Onion Souping to simplify this.
+ // https://crbug.com/787254
+ sender_track_ref =
+ track_adapter_map->GetLocalTrackAdapter(webrtc_sender->track());
+ CHECK(sender_track_ref);
+ }
+ sender_state = RtpSenderState(
+ main_task_runner_, signaling_task_runner_, webrtc_sender.get(),
+ std::move(sender_track_ref), webrtc_sender->stream_ids());
+ }
+ // Create the receiver state.
+ base::Optional<RtpReceiverState> receiver_state;
+ auto webrtc_receiver = webrtc_transceiver->receiver();
+ if (webrtc_receiver) {
+ DCHECK(webrtc_receiver->track());
+ auto receiver_track_ref =
+ track_adapter_map->GetOrCreateRemoteTrackAdapter(
+ webrtc_receiver->track().get());
+ DCHECK(receiver_track_ref);
+ std::vector<std::string> receiver_stream_ids;
+ for (auto& stream : webrtc_receiver->streams()) {
+ receiver_stream_ids.push_back(stream->id());
+ }
+ receiver_state = RtpReceiverState(
+ main_task_runner_, signaling_task_runner_, webrtc_receiver.get(),
+ std::move(receiver_track_ref), std::move(receiver_stream_ids));
+ }
+ // Create the transceiver state.
+ transceiver_states_.push_back(RtpTransceiverState(
+ main_task_runner_, signaling_task_runner_, webrtc_transceiver.get(),
+ std::move(sender_state), std::move(receiver_state),
+ ToBaseOptional(webrtc_transceiver->mid()),
+ webrtc_transceiver->stopped(), webrtc_transceiver->direction(),
+ ToBaseOptional(webrtc_transceiver->current_direction()),
+ ToBaseOptional(webrtc_transceiver->fired_direction())));
+ }
+ is_initialized_ = true;
+}
+
+std::vector<RtpTransceiverState> TransceiverStateSurfacer::ObtainStates() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(is_initialized_);
+ for (auto& transceiver_state : transceiver_states_)
+ transceiver_state.Initialize();
+ states_obtained_ = true;
+ return std::move(transceiver_states_);
+}
+
+SurfaceSenderStateOnly::SurfaceSenderStateOnly(
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender)
+ : sender_(std::move(sender)) {
+ DCHECK(sender_);
+}
+
+SurfaceSenderStateOnly::~SurfaceSenderStateOnly() {}
+
+cricket::MediaType SurfaceSenderStateOnly::media_type() const {
+ return sender_->media_type();
+}
+
+absl::optional<std::string> SurfaceSenderStateOnly::mid() const {
+ return absl::nullopt;
+}
+
+rtc::scoped_refptr<webrtc::RtpSenderInterface> SurfaceSenderStateOnly::sender()
+ const {
+ return sender_;
+}
+
+rtc::scoped_refptr<webrtc::RtpReceiverInterface>
+SurfaceSenderStateOnly::receiver() const {
+ return nullptr;
+}
+
+bool SurfaceSenderStateOnly::stopped() const {
+ return false;
+}
+
+webrtc::RtpTransceiverDirection SurfaceSenderStateOnly::direction() const {
+ return webrtc::RtpTransceiverDirection::kSendOnly;
+}
+
+void SurfaceSenderStateOnly::SetDirection(
+ webrtc::RtpTransceiverDirection new_direction) {
+ NOTIMPLEMENTED();
+}
+
+absl::optional<webrtc::RtpTransceiverDirection>
+SurfaceSenderStateOnly::current_direction() const {
+ return absl::nullopt;
+}
+
+void SurfaceSenderStateOnly::Stop() {
+ NOTIMPLEMENTED();
+}
+
+void SurfaceSenderStateOnly::SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) {
+ NOTIMPLEMENTED();
+}
+
+SurfaceReceiverStateOnly::SurfaceReceiverStateOnly(
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver)
+ : receiver_(std::move(receiver)) {
+ DCHECK(receiver_);
+}
+
+SurfaceReceiverStateOnly::~SurfaceReceiverStateOnly() {}
+
+cricket::MediaType SurfaceReceiverStateOnly::media_type() const {
+ return receiver_->media_type();
+}
+
+absl::optional<std::string> SurfaceReceiverStateOnly::mid() const {
+ return absl::nullopt;
+}
+
+rtc::scoped_refptr<webrtc::RtpSenderInterface>
+SurfaceReceiverStateOnly::sender() const {
+ return nullptr;
+}
+
+rtc::scoped_refptr<webrtc::RtpReceiverInterface>
+SurfaceReceiverStateOnly::receiver() const {
+ return receiver_;
+}
+
+bool SurfaceReceiverStateOnly::stopped() const {
+ return false;
+}
+
+webrtc::RtpTransceiverDirection SurfaceReceiverStateOnly::direction() const {
+ return webrtc::RtpTransceiverDirection::kRecvOnly;
+}
+
+void SurfaceReceiverStateOnly::SetDirection(
+ webrtc::RtpTransceiverDirection new_direction) {
+ NOTIMPLEMENTED();
+}
+
+absl::optional<webrtc::RtpTransceiverDirection>
+SurfaceReceiverStateOnly::current_direction() const {
+ return absl::nullopt;
+}
+
+void SurfaceReceiverStateOnly::Stop() {
+ NOTIMPLEMENTED();
+}
+
+void SurfaceReceiverStateOnly::SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) {
+ NOTIMPLEMENTED();
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h
new file mode 100644
index 00000000000..ab7cdfeb695
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer.h
@@ -0,0 +1,112 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_TRANSCEIVER_STATE_SURFACER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_TRANSCEIVER_STATE_SURFACER_H_
+
+#include "content/renderer/media/webrtc/rtc_rtp_transceiver.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/webrtc/api/rtptransceiverinterface.h"
+#include "third_party/webrtc/rtc_base/refcount.h"
+#include "third_party/webrtc/rtc_base/refcountedobject.h"
+
+namespace content {
+
+// Takes care of creating and initializing transceiver states (including sender
+// and receiver states). This is usable for both blocking and non-blocking calls
+// to the webrtc signaling thread.
+//
+// The surfacer is initialized on the signaling thread and states are obtained
+// on the main thread. It is designed to be initialized and handed off; it is
+// not thread safe for concurrent thread usage.
+class CONTENT_EXPORT TransceiverStateSurfacer {
+ public:
+ TransceiverStateSurfacer(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner);
+ TransceiverStateSurfacer(TransceiverStateSurfacer&&);
+ TransceiverStateSurfacer(const TransceiverStateSurfacer&) = delete;
+ ~TransceiverStateSurfacer();
+
+ // This is intended to be used for moving the object from the signaling thread
+ // to the main thread and as such has no thread checks. Once moved to the main
+ // this should only be invoked on the main thread.
+ TransceiverStateSurfacer& operator=(TransceiverStateSurfacer&&);
+ TransceiverStateSurfacer& operator=(const TransceiverStateSurfacer&) = delete;
+
+ bool is_initialized() const { return is_initialized_; }
+
+ // Must be invoked on the signaling thread.
+ void Initialize(
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ transceivers);
+
+ // Must be invoked on the main thread.
+ std::vector<RtpTransceiverState> ObtainStates();
+
+ protected:
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ bool is_initialized_;
+ bool states_obtained_;
+ std::vector<RtpTransceiverState> transceiver_states_;
+};
+
+// A dummy implementation of a transceiver used to surface sender state
+// information only. It is not thread safe, only designed to be passed on to
+// TransceiverStateSurfacer::Initialize().
+class CONTENT_EXPORT SurfaceSenderStateOnly
+ : public rtc::RefCountedObject<webrtc::RtpTransceiverInterface> {
+ public:
+ SurfaceSenderStateOnly(rtc::scoped_refptr<webrtc::RtpSenderInterface> sender);
+ ~SurfaceSenderStateOnly() override;
+
+ cricket::MediaType media_type() const override;
+ absl::optional<std::string> mid() const override;
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender() const override;
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver() const override;
+ bool stopped() const override;
+ webrtc::RtpTransceiverDirection direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection new_direction) override;
+ absl::optional<webrtc::RtpTransceiverDirection> current_direction()
+ const override;
+ void Stop() override;
+ void SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override;
+
+ private:
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender_;
+};
+
+// A dummy implementation of a transceiver used to surface receiver state
+// information only. It is not thread safe, only designed to be passed on to
+// TransceiverStateSurfacer::Initialize().
+class CONTENT_EXPORT SurfaceReceiverStateOnly
+ : public rtc::RefCountedObject<webrtc::RtpTransceiverInterface> {
+ public:
+ SurfaceReceiverStateOnly(
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver);
+ ~SurfaceReceiverStateOnly() override;
+
+ cricket::MediaType media_type() const override;
+ absl::optional<std::string> mid() const override;
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> sender() const override;
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver() const override;
+ bool stopped() const override;
+ webrtc::RtpTransceiverDirection direction() const override;
+ void SetDirection(webrtc::RtpTransceiverDirection new_direction) override;
+ absl::optional<webrtc::RtpTransceiverDirection> current_direction()
+ const override;
+ void Stop() override;
+ void SetCodecPreferences(
+ rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override;
+
+ private:
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_TRANSCEIVER_STATE_SURFACER_H_
diff --git a/chromium/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc
new file mode 100644
index 00000000000..7f469865324
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc
@@ -0,0 +1,294 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc/transceiver_state_surfacer.h"
+
+#include <memory>
+#include <tuple>
+
+#include "base/memory/ref_counted.h"
+#include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_task_environment.h"
+#include "content/child/child_process.h"
+#include "content/renderer/media/stream/media_stream_audio_source.h"
+#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
+#include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
+#include "content/renderer/media/webrtc/webrtc_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/public/platform/web_media_stream_source.h"
+#include "third_party/blink/public/platform/web_media_stream_track.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/web_heap.h"
+
+namespace content {
+
+class TransceiverStateSurfacerTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
+ main_task_runner_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
+ track_adapter_map_ = new WebRtcMediaStreamTrackAdapterMap(
+ dependency_factory_.get(), main_task_runner_);
+ surfacer_.reset(new TransceiverStateSurfacer(main_task_runner_,
+ signaling_task_runner()));
+ }
+
+ void TearDown() override {
+ // Make sure posted tasks get a chance to execute or else the stuff is
+ // teared down while things are in flight.
+ base::RunLoop().RunUntilIdle();
+ blink::WebHeap::CollectAllGarbageForTesting();
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const {
+ return dependency_factory_->GetWebRtcSignalingThread();
+ }
+
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+ CreateLocalTrackAndAdapter(const std::string& id) {
+ return track_adapter_map_->GetOrCreateLocalTrackAdapter(
+ CreateBlinkLocalTrack(id));
+ }
+
+ rtc::scoped_refptr<webrtc::RtpTransceiverInterface> CreateWebRtcTransceiver(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> local_track,
+ const std::string& local_stream_id,
+ const std::string& remote_track_id,
+ const std::string& remote_stream_id) {
+ return new rtc::RefCountedObject<FakeRtpTransceiver>(
+ local_track->kind() == webrtc::MediaStreamTrackInterface::kAudioKind
+ ? cricket::MEDIA_TYPE_AUDIO
+ : cricket::MEDIA_TYPE_VIDEO,
+ CreateWebRtcSender(local_track, local_stream_id),
+ CreateWebRtcReceiver(remote_track_id, remote_stream_id), base::nullopt,
+ false, webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt);
+ }
+
+ rtc::scoped_refptr<webrtc::RtpSenderInterface> CreateWebRtcSender(
+ rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track,
+ const std::string& stream_id) {
+ return new rtc::RefCountedObject<FakeRtpSender>(
+ std::move(track), std::vector<std::string>({stream_id}));
+ }
+
+ rtc::scoped_refptr<webrtc::RtpReceiverInterface> CreateWebRtcReceiver(
+ const std::string& track_id,
+ const std::string& stream_id) {
+ rtc::scoped_refptr<webrtc::AudioTrackInterface> remote_track =
+ MockWebRtcAudioTrack::Create(track_id).get();
+ rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream(
+ new rtc::RefCountedObject<MockMediaStream>(stream_id));
+ return new rtc::RefCountedObject<FakeRtpReceiver>(
+ remote_track.get(),
+ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>(
+ {remote_stream}));
+ }
+
+ // Initializes the surfacer on the signaling thread and signals the waitable
+ // event when done. The WaitableEvent's Wait() blocks the main thread until
+ // initialization occurs.
+ std::unique_ptr<base::WaitableEvent> AsyncInitializeSurfacerWithWaitableEvent(
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ transceivers) {
+ std::unique_ptr<base::WaitableEvent> waitable_event(new base::WaitableEvent(
+ base::WaitableEvent::ResetPolicy::MANUAL,
+ base::WaitableEvent::InitialState::NOT_SIGNALED));
+ signaling_task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &TransceiverStateSurfacerTest::
+ AsyncInitializeSurfacerWithWaitableEventOnSignalingThread,
+ base::Unretained(this), std::move(transceivers),
+ waitable_event.get()));
+ return waitable_event;
+ }
+
+ // Initializes the surfacer on the signaling thread and posts back to the main
+ // thread to execute the callback when done. The RunLoop quits after the
+ // callback is executed. Use the RunLoop's Run() method to allow the posted
+ // task (such as the callback) to be executed while waiting. The caller must
+ // let the loop Run() before destroying it.
+ std::unique_ptr<base::RunLoop> AsyncInitializeSurfacerWithCallback(
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ transceivers,
+ base::OnceCallback<void()> callback) {
+ std::unique_ptr<base::RunLoop> run_loop(new base::RunLoop());
+ signaling_task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&TransceiverStateSurfacerTest::
+ AsyncInitializeSurfacerWithCallbackOnSignalingThread,
+ base::Unretained(this), std::move(transceivers),
+ std::move(callback), run_loop.get()));
+ return run_loop;
+ }
+
+ void ObtainStatesAndExpectInitialized(
+ rtc::scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver) {
+ auto transceiver_states = surfacer_->ObtainStates();
+ EXPECT_EQ(1u, transceiver_states.size());
+ auto& transceiver_state = transceiver_states[0];
+ EXPECT_EQ(transceiver_state.webrtc_transceiver().get(),
+ webrtc_transceiver.get());
+ // Inspect sender states.
+ const auto& sender_state = transceiver_state.sender_state();
+ EXPECT_TRUE(sender_state);
+ EXPECT_TRUE(sender_state->is_initialized());
+ const auto& webrtc_sender = webrtc_transceiver->sender();
+ EXPECT_EQ(sender_state->webrtc_sender().get(), webrtc_sender.get());
+ EXPECT_TRUE(sender_state->track_ref()->is_initialized());
+ EXPECT_EQ(sender_state->track_ref()->webrtc_track(),
+ webrtc_sender->track().get());
+ EXPECT_EQ(sender_state->stream_ids(), webrtc_sender->stream_ids());
+ // Inspect receiver states.
+ const auto& receiver_state = transceiver_state.receiver_state();
+ EXPECT_TRUE(receiver_state);
+ EXPECT_TRUE(receiver_state->is_initialized());
+ const auto& webrtc_receiver = webrtc_transceiver->receiver();
+ EXPECT_EQ(receiver_state->webrtc_receiver().get(), webrtc_receiver.get());
+ EXPECT_TRUE(receiver_state->track_ref()->is_initialized());
+ EXPECT_EQ(receiver_state->track_ref()->webrtc_track(),
+ webrtc_receiver->track().get());
+ std::vector<std::string> receiver_stream_ids;
+ for (const auto& stream : webrtc_receiver->streams()) {
+ receiver_stream_ids.push_back(stream->id());
+ }
+ EXPECT_EQ(receiver_state->stream_ids(), receiver_stream_ids);
+ // Inspect transceiver states.
+ EXPECT_TRUE(
+ OptionalEquals(transceiver_state.mid(), webrtc_transceiver->mid()));
+ EXPECT_EQ(transceiver_state.stopped(), webrtc_transceiver->stopped());
+ EXPECT_TRUE(transceiver_state.direction() ==
+ webrtc_transceiver->direction());
+ EXPECT_TRUE(OptionalEquals(transceiver_state.current_direction(),
+ webrtc_transceiver->current_direction()));
+ }
+
+ private:
+ blink::WebMediaStreamTrack CreateBlinkLocalTrack(const std::string& id) {
+ blink::WebMediaStreamSource web_source;
+ web_source.Initialize(
+ blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio,
+ blink::WebString::FromUTF8("local_audio_track"), false);
+ MediaStreamAudioSource* audio_source = new MediaStreamAudioSource(true);
+ // Takes ownership of |audio_source|.
+ web_source.SetExtraData(audio_source);
+
+ blink::WebMediaStreamTrack web_track;
+ web_track.Initialize(web_source.Id(), web_source);
+ audio_source->ConnectToTrack(web_track);
+ return web_track;
+ }
+
+ void AsyncInitializeSurfacerWithWaitableEventOnSignalingThread(
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ transceivers,
+ base::WaitableEvent* waitable_event) {
+ DCHECK(signaling_task_runner()->BelongsToCurrentThread());
+ surfacer_->Initialize(track_adapter_map_, std::move(transceivers));
+ waitable_event->Signal();
+ }
+
+ void AsyncInitializeSurfacerWithCallbackOnSignalingThread(
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ transceivers,
+ base::OnceCallback<void()> callback,
+ base::RunLoop* run_loop) {
+ DCHECK(signaling_task_runner()->BelongsToCurrentThread());
+ surfacer_->Initialize(track_adapter_map_, std::move(transceivers));
+ main_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&TransceiverStateSurfacerTest::
+ AsyncInitializeSurfacerWithCallbackOnMainThread,
+ base::Unretained(this), std::move(callback), run_loop));
+ }
+
+ void AsyncInitializeSurfacerWithCallbackOnMainThread(
+ base::OnceCallback<void()> callback,
+ base::RunLoop* run_loop) {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(surfacer_->is_initialized());
+ std::move(callback).Run();
+ run_loop->Quit();
+ }
+
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+
+ protected:
+ std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
+ std::unique_ptr<TransceiverStateSurfacer> surfacer_;
+};
+
+TEST_F(TransceiverStateSurfacerTest, SurfaceTransceiverBlockingly) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto webrtc_transceiver =
+ CreateWebRtcTransceiver(local_track_adapter->webrtc_track(),
+ "local_stream", "remote_track", "remote_stream");
+ auto waitable_event =
+ AsyncInitializeSurfacerWithWaitableEvent({webrtc_transceiver});
+ waitable_event->Wait();
+ ObtainStatesAndExpectInitialized(webrtc_transceiver);
+}
+
+TEST_F(TransceiverStateSurfacerTest, SurfaceTransceiverInCallback) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto webrtc_transceiver =
+ CreateWebRtcTransceiver(local_track_adapter->webrtc_track(),
+ "local_stream", "remote_track", "remote_stream");
+ auto run_loop = AsyncInitializeSurfacerWithCallback(
+ {webrtc_transceiver},
+ base::BindOnce(
+ &TransceiverStateSurfacerTest::ObtainStatesAndExpectInitialized,
+ base::Unretained(this), webrtc_transceiver));
+ run_loop->Run();
+}
+
+TEST_F(TransceiverStateSurfacerTest, SurfaceSenderStateOnly) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto webrtc_sender =
+ CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream");
+ auto waitable_event = AsyncInitializeSurfacerWithWaitableEvent(
+ {new SurfaceSenderStateOnly(webrtc_sender)});
+ waitable_event->Wait();
+ auto transceiver_states = surfacer_->ObtainStates();
+ EXPECT_EQ(1u, transceiver_states.size());
+ auto& transceiver_state = transceiver_states[0];
+ EXPECT_TRUE(transceiver_state.sender_state());
+ EXPECT_TRUE(transceiver_state.sender_state()->is_initialized());
+ EXPECT_FALSE(transceiver_state.receiver_state());
+ // Expect transceiver members be be missing for optional members and have
+ // sensible values for non-optional members.
+ EXPECT_FALSE(transceiver_state.mid());
+ EXPECT_FALSE(transceiver_state.stopped());
+ EXPECT_EQ(transceiver_state.direction(),
+ webrtc::RtpTransceiverDirection::kSendOnly);
+ EXPECT_FALSE(transceiver_state.current_direction());
+}
+
+TEST_F(TransceiverStateSurfacerTest, SurfaceReceiverStateOnly) {
+ auto local_track_adapter = CreateLocalTrackAndAdapter("local_track");
+ auto webrtc_receiver = CreateWebRtcReceiver("remote_track", "remote_stream");
+ auto waitable_event = AsyncInitializeSurfacerWithWaitableEvent(
+ {new SurfaceReceiverStateOnly(webrtc_receiver)});
+ waitable_event->Wait();
+ auto transceiver_states = surfacer_->ObtainStates();
+ EXPECT_EQ(1u, transceiver_states.size());
+ auto& transceiver_state = transceiver_states[0];
+ EXPECT_FALSE(transceiver_state.sender_state());
+ EXPECT_TRUE(transceiver_state.receiver_state());
+ EXPECT_TRUE(transceiver_state.receiver_state()->is_initialized());
+ // Expect transceiver members be be missing for optional members and have
+ // sensible values for non-optional members.
+ EXPECT_FALSE(transceiver_state.mid());
+ EXPECT_FALSE(transceiver_state.stopped());
+ EXPECT_EQ(transceiver_state.direction(),
+ webrtc::RtpTransceiverDirection::kRecvOnly);
+ EXPECT_FALSE(transceiver_state.current_direction());
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc
index b18f49d21f8..c1ea561596d 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer.cc
@@ -11,10 +11,11 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
+#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "content/renderer/media/stream/media_stream_audio_track.h"
#include "content/renderer/media/webrtc/peer_connection_remote_audio_source.h"
#include "content/renderer/media/webrtc_logging.h"
@@ -93,8 +94,7 @@ class SharedAudioRenderer : public MediaStreamAudioRenderer {
void Play() override {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(started_);
- if (playing_state_.playing())
+ if (!started_ || playing_state_.playing())
return;
playing_state_.set_playing(true);
on_play_state_changed_.Run(media_stream_, &playing_state_);
@@ -102,8 +102,7 @@ class SharedAudioRenderer : public MediaStreamAudioRenderer {
void Pause() override {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(started_);
- if (!playing_state_.playing())
+ if (!started_ || !playing_state_.playing())
return;
playing_state_.set_playing(false);
on_play_state_changed_.Run(media_stream_, &playing_state_);
@@ -549,7 +548,7 @@ bool WebRtcAudioRenderer::AddPlayingState(
DCHECK(state->playing());
// Look up or add the |source| to the map.
PlayingStates& array = source_playing_states_[source];
- if (std::find(array.begin(), array.end(), state) != array.end())
+ if (base::ContainsValue(array, state))
return false;
array.push_back(state);
@@ -584,8 +583,8 @@ void WebRtcAudioRenderer::OnPlayStateChanged(
const blink::WebMediaStream& media_stream,
PlayingState* state) {
DCHECK(thread_checker_.CalledOnValidThread());
- blink::WebVector<blink::WebMediaStreamTrack> web_tracks;
- media_stream.AudioTracks(web_tracks);
+ blink::WebVector<blink::WebMediaStreamTrack> web_tracks =
+ media_stream.AudioTracks();
for (const blink::WebMediaStreamTrack& web_track : web_tracks) {
// WebRtcAudioRenderer can only render audio tracks received from a remote
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc
index 7e886d27945..e3e2cce259b 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_renderer_unittest.cc
@@ -13,7 +13,7 @@
#include "base/run_loop.h"
#include "build/build_config.h"
#include "content/public/renderer/media_stream_audio_renderer.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "content/renderer/media/webrtc/webrtc_audio_device_impl.h"
#include "media/base/audio_capturer_source.h"
#include "media/base/mock_audio_renderer_sink.h"
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
index ba37c80ba94..b5a59a0e32e 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.cc
@@ -27,26 +27,26 @@ WebRtcAudioSink::WebRtcAudioSink(
}
WebRtcAudioSink::~WebRtcAudioSink() {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DVLOG(1) << "WebRtcAudioSink::~WebRtcAudioSink()";
}
void WebRtcAudioSink::SetAudioProcessor(
scoped_refptr<MediaStreamAudioProcessor> processor) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(processor.get());
adapter_->set_processor(std::move(processor));
}
void WebRtcAudioSink::SetLevel(
scoped_refptr<MediaStreamAudioLevelCalculator::Level> level) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(level.get());
adapter_->set_level(std::move(level));
}
void WebRtcAudioSink::OnEnabledChanged(bool enabled) {
- DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
adapter_->signaling_task_runner()->PostTask(
FROM_HERE,
base::BindOnce(base::IgnoreResult(&WebRtcAudioSink::Adapter::set_enabled),
@@ -55,17 +55,14 @@ void WebRtcAudioSink::OnEnabledChanged(bool enabled) {
void WebRtcAudioSink::OnData(const media::AudioBus& audio_bus,
base::TimeTicks estimated_capture_time) {
- DCHECK(audio_thread_checker_.CalledOnValidThread());
+ // No thread check: OnData might be called on different threads (but not
+ // concurrently).
// The following will result in zero, one, or multiple synchronous calls to
// DeliverRebufferedAudio().
fifo_.Push(audio_bus);
}
void WebRtcAudioSink::OnSetFormat(const media::AudioParameters& params) {
- // On a format change, the thread delivering audio might have also changed.
- audio_thread_checker_.DetachFromThread();
- DCHECK(audio_thread_checker_.CalledOnValidThread());
-
DCHECK(params.IsValid());
params_ = params;
// Make sure that our params always reflect a buffer size of 10ms.
@@ -78,7 +75,6 @@ void WebRtcAudioSink::OnSetFormat(const media::AudioParameters& params) {
void WebRtcAudioSink::DeliverRebufferedAudio(const media::AudioBus& audio_bus,
int frame_delay) {
- DCHECK(audio_thread_checker_.CalledOnValidThread());
DCHECK(params_.IsValid());
// TODO(miu): Why doesn't a WebRTC sink care about reference time passed to
diff --git a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
index d330bcd1d2f..fee1d51f999 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_audio_sink.h
@@ -8,6 +8,8 @@
#include <stdint.h>
#include <memory>
+#include <string>
+#include <utility>
#include <vector>
#include "base/macros.h"
@@ -166,11 +168,7 @@ class CONTENT_EXPORT WebRtcAudioSink : public MediaStreamAudioSink {
// In debug builds, check that WebRtcAudioSink's public methods are all being
// called on the main render thread.
- base::ThreadChecker thread_checker_;
-
- // Used to DCHECK that OnSetFormat() and OnData() are called on the same
- // thread.
- base::ThreadChecker audio_thread_checker_;
+ THREAD_CHECKER(thread_checker_);
DISALLOW_COPY_AND_ASSIGN(WebRtcAudioSink);
};
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc
deleted file mode 100644
index 835d6194e24..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.cc
+++ /dev/null
@@ -1,292 +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/webrtc/webrtc_media_stream_adapter.h"
-
-#include <utility>
-
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/renderer/media/stream/media_stream_audio_track.h"
-#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-
-namespace content {
-
-// static
-std::unique_ptr<WebRtcMediaStreamAdapter>
-WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- PeerConnectionDependencyFactory* factory,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- const blink::WebMediaStream& web_stream) {
- return std::make_unique<LocalWebRtcMediaStreamAdapter>(
- factory, std::move(track_adapter_map), web_stream);
-}
-
-// static
-std::unique_ptr<WebRtcMediaStreamAdapter>
-WebRtcMediaStreamAdapter::CreateRemoteStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream) {
- return std::make_unique<RemoteWebRtcMediaStreamAdapter>(
- std::move(main_thread), std::move(track_adapter_map),
- std::move(webrtc_stream));
-}
-
-WebRtcMediaStreamAdapter::WebRtcMediaStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream,
- const blink::WebMediaStream& web_stream)
- : main_thread_(std::move(main_thread)),
- track_adapter_map_(std::move(track_adapter_map)),
- webrtc_stream_(std::move(webrtc_stream)),
- web_stream_(web_stream) {
- DCHECK(main_thread_);
- DCHECK(track_adapter_map_);
-}
-
-WebRtcMediaStreamAdapter::~WebRtcMediaStreamAdapter() {
- DCHECK(main_thread_->BelongsToCurrentThread());
-}
-
-LocalWebRtcMediaStreamAdapter::LocalWebRtcMediaStreamAdapter(
- PeerConnectionDependencyFactory* factory,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- const blink::WebMediaStream& web_stream)
- : WebRtcMediaStreamAdapter(base::ThreadTaskRunnerHandle::Get(),
- std::move(track_adapter_map),
- nullptr,
- web_stream),
- factory_(factory) {
- webrtc_stream_ = factory_->CreateLocalMediaStream(web_stream.Id().Utf8());
-
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- web_stream_.AudioTracks(audio_tracks);
- for (blink::WebMediaStreamTrack& audio_track : audio_tracks)
- TrackAdded(audio_track);
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- web_stream_.VideoTracks(video_tracks);
- for (blink::WebMediaStreamTrack& video_track : video_tracks)
- TrackAdded(video_track);
-
- web_stream_.AddObserver(this);
-}
-
-LocalWebRtcMediaStreamAdapter::~LocalWebRtcMediaStreamAdapter() {
- DCHECK(main_thread_->BelongsToCurrentThread());
- web_stream_.RemoveObserver(this);
-
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- web_stream_.AudioTracks(audio_tracks);
- for (blink::WebMediaStreamTrack& audio_track : audio_tracks)
- TrackRemoved(audio_track);
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- web_stream_.VideoTracks(video_tracks);
- for (blink::WebMediaStreamTrack& video_track : video_tracks)
- TrackRemoved(video_track);
-}
-
-bool LocalWebRtcMediaStreamAdapter::is_initialized() const {
- return true;
-}
-
-const scoped_refptr<webrtc::MediaStreamInterface>&
-LocalWebRtcMediaStreamAdapter::webrtc_stream() const {
- return webrtc_stream_;
-}
-
-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());
- bool is_audio_track =
- (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio);
- if (is_audio_track && !MediaStreamAudioTrack::From(web_track)) {
- DLOG(ERROR) << "No native track for blink audio track.";
- return;
- }
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter_ref =
- track_adapter_map_->GetOrCreateLocalTrackAdapter(web_track);
- if (is_audio_track) {
- webrtc_stream_->AddTrack(
- static_cast<webrtc::AudioTrackInterface*>(adapter_ref->webrtc_track()));
- } else {
- webrtc_stream_->AddTrack(
- static_cast<webrtc::VideoTrackInterface*>(adapter_ref->webrtc_track()));
- }
- adapter_refs_.insert(
- std::make_pair(web_track.UniqueId(), std::move(adapter_ref)));
-}
-
-void LocalWebRtcMediaStreamAdapter::TrackRemoved(
- const blink::WebMediaStreamTrack& web_track) {
- auto it = adapter_refs_.find(web_track.UniqueId());
- if (it == adapter_refs_.end()) {
- // This can happen for audio tracks that don't have a source, these would
- // never be added in the first place.
- return;
- }
- if (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio) {
- webrtc_stream_->RemoveTrack(
- static_cast<webrtc::AudioTrackInterface*>(it->second->webrtc_track()));
- } else {
- webrtc_stream_->RemoveTrack(
- static_cast<webrtc::VideoTrackInterface*>(it->second->webrtc_track()));
- }
- adapter_refs_.erase(it);
-}
-
-// 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;
- }
- return false;
-}
-
-// static
-RemoteWebRtcMediaStreamAdapter::RemoteAdapterRefs
-RemoteWebRtcMediaStreamAdapter::GetRemoteAdapterRefsFromWebRtcStream(
- const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
- webrtc::MediaStreamInterface* webrtc_stream) {
- // 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()) {
- adapter_refs.push_back(track_adapter_map->GetOrCreateRemoteTrackAdapter(
- webrtc_audio_track.get()));
- }
- for (auto& webrtc_video_track : webrtc_stream->GetVideoTracks()) {
- adapter_refs.push_back(track_adapter_map->GetOrCreateRemoteTrackAdapter(
- webrtc_video_track.get()));
- }
- return adapter_refs;
-}
-
-RemoteWebRtcMediaStreamAdapter::RemoteWebRtcMediaStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream)
- : WebRtcMediaStreamAdapter(std::move(main_thread),
- std::move(track_adapter_map),
- std::move(webrtc_stream),
- // "null" |WebMediaStream|
- blink::WebMediaStream()),
- is_initialized_(false),
- weak_factory_(this) {
- CHECK(!main_thread_->BelongsToCurrentThread());
- CHECK(track_adapter_map_);
-
- RemoteAdapterRefs adapter_refs = GetRemoteAdapterRefsFromWebRtcStream(
- track_adapter_map_, webrtc_stream_.get());
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(&RemoteWebRtcMediaStreamAdapter::InitializeOnMainThread,
- weak_factory_.GetWeakPtr(), webrtc_stream_->id(),
- std::move(adapter_refs),
- webrtc_stream_->GetAudioTracks().size(),
- webrtc_stream_->GetVideoTracks().size()));
-}
-
-RemoteWebRtcMediaStreamAdapter::~RemoteWebRtcMediaStreamAdapter() {
- DCHECK(main_thread_->BelongsToCurrentThread());
- SetTracks(RemoteAdapterRefs());
-}
-
-bool RemoteWebRtcMediaStreamAdapter::is_initialized() const {
- base::AutoLock scoped_lock(lock_);
- return is_initialized_;
-}
-
-const scoped_refptr<webrtc::MediaStreamInterface>&
-RemoteWebRtcMediaStreamAdapter::webrtc_stream() const {
- base::AutoLock scoped_lock(lock_);
- DCHECK(is_initialized_);
- return webrtc_stream_;
-}
-
-const blink::WebMediaStream& RemoteWebRtcMediaStreamAdapter::web_stream()
- const {
- base::AutoLock scoped_lock(lock_);
- DCHECK(is_initialized_);
- return web_stream_;
-}
-
-void RemoteWebRtcMediaStreamAdapter::InitializeOnMainThread(
- const std::string& label,
- RemoteAdapterRefs adapter_refs,
- size_t audio_track_count,
- size_t video_track_count) {
- CHECK(main_thread_->BelongsToCurrentThread());
- CHECK_EQ(audio_track_count + video_track_count, adapter_refs.size());
-
- adapter_refs_ = std::move(adapter_refs);
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks(
- audio_track_count);
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks(
- video_track_count);
- size_t audio_i = 0;
- size_t video_i = 0;
- 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
- web_video_tracks[video_i++] = web_track;
- }
-
- web_stream_.Initialize(blink::WebString::FromUTF8(label), web_audio_tracks,
- web_video_tracks);
- CHECK(!web_stream_.IsNull());
-
- base::AutoLock scoped_lock(lock_);
- is_initialized_ = true;
-}
-
-void RemoteWebRtcMediaStreamAdapter::SetTracks(
- WebRtcMediaStreamAdapter::TrackAdapterRefs track_refs) {
- DCHECK(main_thread_->BelongsToCurrentThread());
-
- // Find removed tracks.
- 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& 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));
- }
- }
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h
deleted file mode 100644
index 49c6388ec5a..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter.h
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_H_
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequenced_task_runner.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/webrtc/api/mediastreaminterface.h"
-
-namespace content {
-
-class PeerConnectionDependencyFactory;
-
-// An adapter is the glue between webrtc and blink media streams. Adapters of
-// local media streams are created from a blink stream and get a webrtc stream
-// correspondent. Adapters of remote media streams are created from a webrtc
-// stream and get a blink stream correspondent. The adapter makes sure that when
-// the stream it was created from is modified the correspondent is updated to
-// reflect the new state.
-// The adapters are thread safe but must be constructed on the correct thread
-// (local adapters: main thread, remote adapters: webrtc signaling thread) and
-// 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(
- PeerConnectionDependencyFactory* factory,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- const blink::WebMediaStream& web_stream);
- // Creates an adapter for a remote media stream. Invoked on the webrtc
- // signaling thread. The adapter is initialized in a post to the main thread.
- static std::unique_ptr<WebRtcMediaStreamAdapter> CreateRemoteStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream);
- // Invoke on the main thread.
- virtual ~WebRtcMediaStreamAdapter();
-
- // Once initialized, |webrtc_stream| and |web_stream| are accessible. An
- // initialized adapter remains initialized until destroyed.
- virtual bool is_initialized() const = 0;
- virtual const scoped_refptr<webrtc::MediaStreamInterface>& webrtc_stream()
- const = 0;
- virtual const blink::WebMediaStream& web_stream() const = 0;
- bool IsEqual(const blink::WebMediaStream& stream) const {
- return (web_stream_.IsNull() && stream.IsNull()) ||
- (web_stream_.Id() == stream.Id());
- }
-
- virtual void SetTracks(TrackAdapterRefs track_refs) = 0;
-
- protected:
- WebRtcMediaStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream,
- const blink::WebMediaStream& web_stream);
-
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- // The map and owner of all track adapters for the associated peer connection.
- // When a track is added or removed from this stream, the map provides us with
- // a reference to the corresponding track adapter, creating a new one if
- // necessary.
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
-
- // If |is_initialized()| both of these need to be set and remain constant.
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream_;
- blink::WebMediaStream web_stream_;
-
- DISALLOW_COPY_AND_ASSIGN(WebRtcMediaStreamAdapter);
-};
-
-// Adapter implementation for a local |blink::WebMediaStream|. Created and
-// destroyed on the main thread.
-class LocalWebRtcMediaStreamAdapter : public WebRtcMediaStreamAdapter,
- blink::WebMediaStreamObserver {
- public:
- LocalWebRtcMediaStreamAdapter(
- PeerConnectionDependencyFactory* factory,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- const blink::WebMediaStream& web_stream);
- ~LocalWebRtcMediaStreamAdapter() override;
-
- // |WebRtcMediaStreamAdapter| implementation.
- bool is_initialized() const override;
- 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.
- using LocalAdapterRefMap =
- std::map<int, // blink::WebMediaStreamTrack::UniqueId()
- std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>>;
-
- // |MediaStreamObserver| implementation. Also used as a helper functions when
- // adding/removing all tracks in the constructor/destructor.
- void TrackAdded(const blink::WebMediaStreamTrack& web_track) override;
- void TrackRemoved(const blink::WebMediaStreamTrack& web_track) override;
-
- // Pointer to a |PeerConnectionDependencyFactory|, owned by the
- // |RenderThread|. It's valid for the lifetime of |RenderThread|.
- PeerConnectionDependencyFactory* const factory_;
-
- // 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.
- LocalAdapterRefMap adapter_refs_;
-
- DISALLOW_COPY_AND_ASSIGN(LocalWebRtcMediaStreamAdapter);
-};
-
-// Adapter implementation for a remote |webrtc::MediaStreamInterface|. Created
-// on the the webrtc signaling thread, initialized on the main thread where it
-// must be destroyed.
-class RemoteWebRtcMediaStreamAdapter : public WebRtcMediaStreamAdapter {
- public:
- RemoteWebRtcMediaStreamAdapter(
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream);
- ~RemoteWebRtcMediaStreamAdapter() override;
-
- // |WebRtcMediaStreamAdapter| implementation.
- bool is_initialized() const override;
- const scoped_refptr<webrtc::MediaStreamInterface>& webrtc_stream()
- const override;
- const blink::WebMediaStream& web_stream() const override;
- void SetTracks(TrackAdapterRefs track_refs) override;
-
- private:
- // 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 RemoteAdapterRefs GetRemoteAdapterRefsFromWebRtcStream(
- const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
- webrtc::MediaStreamInterface* webrtc_stream);
-
- void InitializeOnMainThread(const std::string& label,
- RemoteAdapterRefs track_adapter_refs,
- size_t audio_track_count,
- size_t video_track_count);
-
- mutable base::Lock lock_;
- bool is_initialized_;
- // 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.
- RemoteAdapterRefs adapter_refs_;
- base::WeakPtrFactory<RemoteWebRtcMediaStreamAdapter> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(RemoteWebRtcMediaStreamAdapter);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_H_
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
deleted file mode 100644
index b445ce8c893..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.cc
+++ /dev/null
@@ -1,227 +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/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
-
-namespace content {
-
-WebRtcMediaStreamAdapterMap::AdapterEntry::AdapterEntry(
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter)
- : adapter(std::move(adapter)), ref_count(0) {
- DCHECK(this->adapter);
-}
-
-WebRtcMediaStreamAdapterMap::AdapterEntry::AdapterEntry(AdapterEntry&& other)
- : adapter(other.adapter.release()), ref_count(other.ref_count) {}
-
-WebRtcMediaStreamAdapterMap::AdapterEntry::~AdapterEntry() {
- // |ref_count| is allowed to be non-zero only if this entry has been moved
- // which is the case if the |adapter| has already been released.
- DCHECK(!ref_count || !adapter);
-}
-
-WebRtcMediaStreamAdapterMap::AdapterRef::AdapterRef(
- scoped_refptr<WebRtcMediaStreamAdapterMap> map,
- Type type,
- AdapterEntry* adapter_entry)
- : map_(std::move(map)), type_(type), adapter_entry_(adapter_entry) {
- DCHECK(map_);
- DCHECK(adapter_entry_);
- map_->lock_.AssertAcquired();
- ++adapter_entry_->ref_count;
-}
-
-WebRtcMediaStreamAdapterMap::AdapterRef::~AdapterRef() {
- DCHECK(map_->main_thread_->BelongsToCurrentThread());
- std::unique_ptr<WebRtcMediaStreamAdapter> removed_adapter;
- {
- base::AutoLock scoped_lock(map_->lock_);
- --adapter_entry_->ref_count;
- if (adapter_entry_->ref_count == 0) {
- removed_adapter = std::move(adapter_entry_->adapter);
- // "GetOrCreate..." ensures the adapter is initialized and the secondary
- // key is set before the last |AdapterRef| is destroyed. We can use either
- // the primary or secondary key for removal.
- if (type_ == Type::kLocal) {
- map_->local_stream_adapters_.EraseByPrimary(
- removed_adapter->web_stream().UniqueId());
- } else {
- map_->remote_stream_adapters_.EraseByPrimary(
- removed_adapter->webrtc_stream().get());
- }
- }
- }
- // Destroy the adapter whilst not holding the lock so that it is safe for
- // destructors to use the signaling thread synchronously without any risk of
- // deadlock.
- removed_adapter.reset();
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::AdapterRef::Copy() const {
- base::AutoLock scoped_lock(map_->lock_);
- return base::WrapUnique(new AdapterRef(map_, type_, adapter_entry_));
-}
-
-WebRtcMediaStreamAdapterMap::WebRtcMediaStreamAdapterMap(
- PeerConnectionDependencyFactory* const factory,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map)
- : factory_(factory),
- main_thread_(std::move(main_thread)),
- track_adapter_map_(std::move(track_adapter_map)) {
- DCHECK(factory_);
- DCHECK(main_thread_);
- DCHECK(track_adapter_map_);
-}
-
-WebRtcMediaStreamAdapterMap::~WebRtcMediaStreamAdapterMap() {
- DCHECK(local_stream_adapters_.empty());
- DCHECK(remote_stream_adapters_.empty());
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetLocalStreamAdapter(
- const blink::WebMediaStream& web_stream) {
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- local_stream_adapters_.FindByPrimary(web_stream.UniqueId());
- if (!adapter_entry)
- return nullptr;
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kLocal, adapter_entry));
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetLocalStreamAdapter(
- webrtc::MediaStreamInterface* webrtc_stream) {
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- local_stream_adapters_.FindBySecondary(webrtc_stream);
- if (!adapter_entry)
- return nullptr;
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kLocal, adapter_entry));
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetOrCreateLocalStreamAdapter(
- const blink::WebMediaStream& web_stream) {
- CHECK(main_thread_->BelongsToCurrentThread());
- CHECK(!web_stream.IsNull());
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- local_stream_adapters_.FindByPrimary(web_stream.UniqueId());
- if (!adapter_entry) {
- 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));
- CHECK(adapter_entry->adapter->is_initialized());
- CHECK(adapter_entry->adapter->webrtc_stream());
- local_stream_adapters_.SetSecondaryKey(
- web_stream.UniqueId(), adapter_entry->adapter->webrtc_stream().get());
- }
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kLocal, adapter_entry));
-}
-
-size_t WebRtcMediaStreamAdapterMap::GetLocalStreamCount() const {
- base::AutoLock scoped_lock(lock_);
- return local_stream_adapters_.PrimarySize();
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetRemoteStreamAdapter(
- const blink::WebMediaStream& web_stream) {
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- remote_stream_adapters_.FindBySecondary(web_stream.UniqueId());
- if (!adapter_entry)
- return nullptr;
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kRemote, adapter_entry));
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetRemoteStreamAdapter(
- webrtc::MediaStreamInterface* webrtc_stream) {
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- remote_stream_adapters_.FindByPrimary(webrtc_stream);
- if (!adapter_entry)
- return nullptr;
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kRemote, adapter_entry));
-}
-
-std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
-WebRtcMediaStreamAdapterMap::GetOrCreateRemoteStreamAdapter(
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream) {
- CHECK(!main_thread_->BelongsToCurrentThread());
- CHECK(webrtc_stream);
- base::AutoLock scoped_lock(lock_);
- AdapterEntry* adapter_entry =
- remote_stream_adapters_.FindByPrimary(webrtc_stream.get());
- if (!adapter_entry) {
- // 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
- // there is at least one |AdapterRef| alive until after the adapter is
- // initialized and its secondary key is set.
- main_thread_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &WebRtcMediaStreamAdapterMap::OnRemoteStreamAdapterInitialized,
- this,
- base::WrapUnique(new AdapterRef(this, AdapterRef::Type::kRemote,
- adapter_entry))));
- }
- return base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kRemote, adapter_entry));
-}
-
-size_t WebRtcMediaStreamAdapterMap::GetRemoteStreamCount() const {
- base::AutoLock scoped_lock(lock_);
- return remote_stream_adapters_.PrimarySize();
-}
-
-void WebRtcMediaStreamAdapterMap::OnRemoteStreamAdapterInitialized(
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref) {
- CHECK(main_thread_->BelongsToCurrentThread());
- CHECK(adapter_ref->is_initialized());
- CHECK(!adapter_ref->adapter().web_stream().IsNull());
- {
- base::AutoLock scoped_lock(lock_);
- remote_stream_adapters_.SetSecondaryKey(
- adapter_ref->adapter().webrtc_stream().get(),
- adapter_ref->adapter().web_stream().UniqueId());
- }
-}
-
-} // namespace content
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
deleted file mode 100644
index 1d9c40b6692..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h
+++ /dev/null
@@ -1,168 +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.
-
-#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_MAP_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_MAP_H_
-
-#include <map>
-#include <memory>
-
-#include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/lock.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/two_keys_adapter_map.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/webrtc/api/mediastreaminterface.h"
-
-namespace content {
-
-// A map and owner of |WebRtcMediaStreamAdapter|s. Adapters are the glue between
-// blink and webrtc layer versions of streams. As long as a stream is in use by
-// a peer connection there has to exist an adapter for it. The map takes care of
-// creating and disposing stream adapters. Adapters are accessed via
-// |AdapterRef|s, when all references to an adapter are destroyed it is
-// destroyed and removed from the map.
-class CONTENT_EXPORT WebRtcMediaStreamAdapterMap
- : public base::RefCountedThreadSafe<WebRtcMediaStreamAdapterMap> {
- private:
- // The map's entries are reference counted in order to remove the adapter when
- // all |AdapterRef|s referencing an entry are destroyed.
- // Private section needed here due to |AdapterRef|'s usage of |AdapterEntry|.
- struct AdapterEntry {
- AdapterEntry(std::unique_ptr<WebRtcMediaStreamAdapter> adapter);
- AdapterEntry(AdapterEntry&& other);
- ~AdapterEntry();
-
- AdapterEntry(const AdapterEntry&) = delete;
- AdapterEntry& operator=(const AdapterEntry&) = delete;
-
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter;
- size_t ref_count;
- };
-
- public:
- // Accessor to an adapter to take care of reference counting. When the last
- // |AdapterRef| is destroyed, the corresponding adapter is destroyed and
- // removed from the map.
- class CONTENT_EXPORT AdapterRef {
- public:
- // Must be invoked on the main thread. If this was the last reference to the
- // adapter it will be disposed and removed from the map.
- ~AdapterRef();
-
- std::unique_ptr<AdapterRef> Copy() const;
- bool is_initialized() const { return adapter().is_initialized(); }
- const WebRtcMediaStreamAdapter& adapter() const {
- return *adapter_entry_->adapter;
- }
- WebRtcMediaStreamAdapter& adapter() { return *adapter_entry_->adapter; }
-
- private:
- friend class WebRtcMediaStreamAdapterMap;
-
- enum class Type { kLocal, kRemote };
-
- // Increments the |AdapterEntry::ref_count|. Assumes map's |lock_| is held.
- AdapterRef(scoped_refptr<WebRtcMediaStreamAdapterMap> map,
- Type type,
- AdapterEntry* adapter_entry);
-
- scoped_refptr<WebRtcMediaStreamAdapterMap> map_;
- Type type_;
- AdapterEntry* adapter_entry_;
- };
-
- // Must be invoked on the main thread.
- WebRtcMediaStreamAdapterMap(
- PeerConnectionDependencyFactory* const factory,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread,
- scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map);
-
- // Gets a new reference to the local stream adapter, or null if no such
- // adapter was found. When all references are destroyed the adapter is
- // destroyed and removed from the map. This can be called on any thread, but
- // references must be destroyed on the main thread.
- // The adapter is a associated with a blink and webrtc stream, lookup works by
- // either stream.
- std::unique_ptr<AdapterRef> GetLocalStreamAdapter(
- const blink::WebMediaStream& web_stream);
- std::unique_ptr<AdapterRef> GetLocalStreamAdapter(
- webrtc::MediaStreamInterface* webrtc_stream);
- // Invoke on the main thread. Gets a new reference to the local stream adapter
- // for the web stream. If no adapter exists for the stream one is created.
- // When all references are destroyed the adapter is destroyed and removed from
- // the map. References must be destroyed on the main thread.
- std::unique_ptr<AdapterRef> GetOrCreateLocalStreamAdapter(
- const blink::WebMediaStream& web_stream);
- size_t GetLocalStreamCount() const;
-
- // Gets a new reference to the remote stream adapter by ID, or null if no such
- // adapter was found. When all references are destroyed the adapter is
- // destroyed and removed from the map. This can be called on any thread, but
- // references must be destroyed on the main thread. The adapter is a
- // associated with a blink and webrtc stream, lookup works by either stream.
- // First variety: If an adapter exists it will already be initialized, if one
- // does not exist null is returned.
- std::unique_ptr<AdapterRef> GetRemoteStreamAdapter(
- const blink::WebMediaStream& web_stream);
- // Second variety: If an adapter exists it may or may not be initialized, see
- // |AdapterRef::is_initialized|. If an adapter does not exist null is
- // returned.
- std::unique_ptr<AdapterRef> GetRemoteStreamAdapter(
- webrtc::MediaStreamInterface* webrtc_stream);
- // Invoke on the webrtc signaling thread. Gets a new reference to the remote
- // stream adapter for the webrtc stream. If no adapter exists for the stream
- // one is created and initialization completes on the main thread in a post.
- // When all references are destroyed the adapter is destroyed and removed from
- // the map. References must be destroyed on the main thread.
- std::unique_ptr<AdapterRef> GetOrCreateRemoteStreamAdapter(
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream);
- size_t GetRemoteStreamCount() const;
-
- const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map()
- const {
- return track_adapter_map_;
- }
-
- private:
- friend class base::RefCountedThreadSafe<WebRtcMediaStreamAdapterMap>;
-
- // "(blink::WebMediaStream, webrtc::MediaStreamInterface) -> AdapterEntry"
- // maps. The primary key is based on the object used to create the adapter.
- // Local streams are created from |blink::WebMediaStream|s, remote streams are
- // created from |webrtc::MediaStreamInterface|s.
- // The adapter keeps the |webrtc::MediaStreamInterface| alive with ref
- // counting making it safe to use a raw pointer for key.
- using LocalStreamAdapterMap =
- TwoKeysAdapterMap<int, // blink::WebMediaStream::UniqueId()
- webrtc::MediaStreamInterface*,
- AdapterEntry>;
- using RemoteStreamAdapterMap =
- TwoKeysAdapterMap<webrtc::MediaStreamInterface*,
- int, // blink::WebMediaStream::UniqueId()
- AdapterEntry>;
-
- // Invoke on the main thread.
- virtual ~WebRtcMediaStreamAdapterMap();
-
- void OnRemoteStreamAdapterInitialized(
- std::unique_ptr<AdapterRef> adapter_ref);
-
- // Pointer to a |PeerConnectionDependencyFactory| owned by the |RenderThread|.
- // It's valid for the lifetime of |RenderThread|.
- PeerConnectionDependencyFactory* const factory_;
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- // Takes care of creating and owning track adapters, used by stream adapters.
- const scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
-
- mutable base::Lock lock_;
- LocalStreamAdapterMap local_stream_adapters_;
- RemoteStreamAdapterMap remote_stream_adapters_;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_ADAPTER_MAP_H_
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc
deleted file mode 100644
index 87f0032a8bd..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc
+++ /dev/null
@@ -1,206 +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/renderer/media/webrtc/webrtc_media_stream_adapter_map.h"
-
-#include <memory>
-#include <string>
-
-#include "base/memory/ref_counted.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/test/scoped_task_environment.h"
-#include "content/child/child_process.h"
-#include "content/renderer/media/mock_audio_device_factory.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
-#include "content/renderer/media/stream/mock_media_stream_video_source.h"
-#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/web_heap.h"
-
-using ::testing::_;
-
-namespace content {
-
-class WebRtcMediaStreamAdapterMapTest : public ::testing::Test {
- public:
- void SetUp() override {
- dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
- main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
- map_ = new WebRtcMediaStreamAdapterMap(
- dependency_factory_.get(), main_thread_,
- new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
- main_thread_));
- }
-
- void TearDown() override { blink::WebHeap::CollectAllGarbageForTesting(); }
-
- blink::WebMediaStream CreateLocalStream(const std::string& id) {
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks(
- static_cast<size_t>(1));
- blink::WebMediaStreamSource video_source;
- video_source.Initialize("video_source",
- blink::WebMediaStreamSource::kTypeVideo,
- "video_source", false /* remote */);
- MediaStreamVideoSource* native_source = new MockMediaStreamVideoSource();
- video_source.SetExtraData(native_source);
- web_video_tracks[0] = MediaStreamVideoTrack::CreateVideoTrack(
- native_source, MediaStreamVideoSource::ConstraintsCallback(), true);
-
- blink::WebMediaStream web_stream;
- web_stream.Initialize(blink::WebString::FromUTF8(id),
- blink::WebVector<blink::WebMediaStreamTrack>(),
- web_video_tracks);
- return web_stream;
- }
-
- scoped_refptr<webrtc::MediaStreamInterface> CreateRemoteStream(
- const std::string& id) {
- scoped_refptr<webrtc::MediaStreamInterface> stream(
- new rtc::RefCountedObject<MockMediaStream>(id));
- stream->AddTrack(MockWebRtcAudioTrack::Create("remote_audio_track").get());
- stream->AddTrack(MockWebRtcVideoTrack::Create("remote_video_track").get());
- return stream;
- }
-
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>
- GetOrCreateRemoteStreamAdapter(webrtc::MediaStreamInterface* webrtc_stream) {
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref;
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE,
- base::BindOnce(&WebRtcMediaStreamAdapterMapTest::
- GetOrCreateRemoteStreamAdapterOnSignalingThread,
- base::Unretained(this), base::Unretained(webrtc_stream),
- base::Unretained(&adapter_ref)));
- RunMessageLoopsUntilIdle();
- DCHECK(adapter_ref);
- return adapter_ref;
- }
-
- protected:
- void GetOrCreateRemoteStreamAdapterOnSignalingThread(
- webrtc::MediaStreamInterface* webrtc_stream,
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>* adapter_ref) {
- *adapter_ref = map_->GetOrCreateRemoteStreamAdapter(webrtc_stream);
- EXPECT_TRUE(*adapter_ref);
- }
-
- // Runs message loops on the webrtc signaling thread and the main thread until
- // idle.
- void RunMessageLoopsUntilIdle() {
- base::WaitableEvent waitable_event(
- base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE, base::BindOnce(&WebRtcMediaStreamAdapterMapTest::SignalEvent,
- base::Unretained(this), &waitable_event));
- waitable_event.Wait();
- base::RunLoop().RunUntilIdle();
- }
-
- void SignalEvent(base::WaitableEvent* waitable_event) {
- waitable_event->Signal();
- }
-
- // Message loop and child processes is needed for task queues and threading to
- // work, as is necessary to create tracks and adapters.
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- ChildProcess child_process_;
-
- std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- scoped_refptr<WebRtcMediaStreamAdapterMap> map_;
-};
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, AddAndRemoveLocalStreamAdapter) {
- blink::WebMediaStream local_web_stream = CreateLocalStream("local_stream");
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref =
- map_->GetOrCreateLocalStreamAdapter(local_web_stream);
- EXPECT_TRUE(adapter_ref);
- EXPECT_TRUE(adapter_ref->adapter().IsEqual(local_web_stream));
- EXPECT_EQ(1u, map_->GetLocalStreamCount());
-
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref2 =
- map_->GetLocalStreamAdapter(local_web_stream);
- EXPECT_TRUE(adapter_ref2);
- EXPECT_EQ(&adapter_ref2->adapter(), &adapter_ref->adapter());
- EXPECT_EQ(1u, map_->GetLocalStreamCount());
-
- adapter_ref.reset();
- EXPECT_EQ(1u, map_->GetLocalStreamCount());
- adapter_ref2.reset();
- EXPECT_EQ(0u, map_->GetLocalStreamCount());
-}
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, LookUpLocalAdapterByWebRtcStream) {
- blink::WebMediaStream local_web_stream = CreateLocalStream("local_stream");
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref =
- map_->GetOrCreateLocalStreamAdapter(local_web_stream);
- EXPECT_TRUE(adapter_ref);
- EXPECT_TRUE(adapter_ref->adapter().IsEqual(local_web_stream));
- EXPECT_EQ(1u, map_->GetLocalStreamCount());
-
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref2 =
- map_->GetLocalStreamAdapter(adapter_ref->adapter().web_stream());
- EXPECT_TRUE(adapter_ref2);
- EXPECT_EQ(&adapter_ref2->adapter(), &adapter_ref->adapter());
-}
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, GetLocalStreamAdapterInvalidID) {
- blink::WebMediaStream local_web_stream = CreateLocalStream("missing");
- EXPECT_FALSE(map_->GetLocalStreamAdapter(local_web_stream));
-}
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, AddAndRemoveRemoteStreamAdapter) {
- scoped_refptr<webrtc::MediaStreamInterface> remote_webrtc_stream =
- CreateRemoteStream("remote_stream");
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref =
- GetOrCreateRemoteStreamAdapter(remote_webrtc_stream.get());
- EXPECT_EQ(remote_webrtc_stream, adapter_ref->adapter().webrtc_stream());
- EXPECT_EQ(1u, map_->GetRemoteStreamCount());
-
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref2 =
- map_->GetRemoteStreamAdapter(remote_webrtc_stream.get());
- EXPECT_TRUE(adapter_ref2);
- EXPECT_EQ(&adapter_ref2->adapter(), &adapter_ref->adapter());
- EXPECT_EQ(1u, map_->GetRemoteStreamCount());
-
- adapter_ref.reset();
- EXPECT_EQ(1u, map_->GetRemoteStreamCount());
- adapter_ref2.reset();
- EXPECT_EQ(0u, map_->GetRemoteStreamCount());
-}
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, LookUpRemoteAdapterByWebStream) {
- scoped_refptr<webrtc::MediaStreamInterface> remote_webrtc_stream =
- CreateRemoteStream("remote_stream");
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref =
- GetOrCreateRemoteStreamAdapter(remote_webrtc_stream.get());
- EXPECT_EQ(remote_webrtc_stream, adapter_ref->adapter().webrtc_stream());
- EXPECT_EQ(1u, map_->GetRemoteStreamCount());
-
- std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> adapter_ref2 =
- map_->GetRemoteStreamAdapter(
- adapter_ref->adapter().webrtc_stream().get());
- EXPECT_TRUE(adapter_ref2);
- EXPECT_EQ(&adapter_ref2->adapter(), &adapter_ref->adapter());
-}
-
-TEST_F(WebRtcMediaStreamAdapterMapTest, GetRemoteStreamAdapterInvalidID) {
- scoped_refptr<webrtc::MediaStreamInterface> remote_webrtc_stream =
- CreateRemoteStream("missing");
- EXPECT_FALSE(map_->GetRemoteStreamAdapter(remote_webrtc_stream.get()));
-}
-
-} // namespace content
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
deleted file mode 100644
index ec8ffdca628..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc
+++ /dev/null
@@ -1,400 +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/webrtc/webrtc_media_stream_adapter.h"
-
-#include <stddef.h>
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#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/mock_audio_device_factory.h"
-#include "content/renderer/media/stream/media_stream_video_source.h"
-#include "content/renderer/media/stream/media_stream_video_track.h"
-#include "content/renderer/media/stream/mock_constraint_factory.h"
-#include "content/renderer/media/stream/mock_media_stream_video_source.h"
-#include "content/renderer/media/stream/processed_local_audio_source.h"
-#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/web_heap.h"
-
-using ::testing::_;
-
-namespace content {
-
-class WebRtcMediaStreamAdapterTest : public ::testing::Test {
- public:
- void SetUp() override {
- dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
- track_adapter_map_ = new WebRtcMediaStreamTrackAdapterMap(
- dependency_factory_.get(),
- blink::scheduler::GetSingleThreadTaskRunnerForTesting());
- }
-
- void TearDown() override {
- track_adapter_map_ = nullptr;
- blink::WebHeap::CollectAllGarbageForTesting();
- }
-
- protected:
- // 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_;
-};
-
-class LocalWebRtcMediaStreamAdapterTest : public WebRtcMediaStreamAdapterTest {
- public:
- blink::WebMediaStream CreateWebMediaStream(
- const std::string& audio_track_id,
- const std::string& video_track_id) {
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks(
- static_cast<size_t>(1u));
- blink::WebMediaStreamSource audio_source;
- audio_source.Initialize(blink::WebString::FromUTF8(audio_track_id),
- blink::WebMediaStreamSource::kTypeAudio,
- blink::WebString::FromUTF8(audio_track_id),
- false /* remote */);
- ProcessedLocalAudioSource* const source = new ProcessedLocalAudioSource(
- -1 /* consumer_render_frame_id is N/A for non-browser tests */,
- MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, "mock_audio_device_id",
- "Mock audio device",
- media::AudioParameters::kAudioCDSampleRate,
- media::CHANNEL_LAYOUT_STEREO,
- media::AudioParameters::kAudioCDSampleRate / 50),
- false /* hotword_enabled */, false /* disable_local_echo */,
- AudioProcessingProperties(),
- base::Bind(&LocalWebRtcMediaStreamAdapterTest::OnAudioSourceStarted),
- dependency_factory_.get());
- source->SetAllowInvalidRenderFrameIdForTesting(true);
- audio_source.SetExtraData(source); // Takes ownership.
- audio_tracks[0].Initialize(blink::WebString::FromUTF8(audio_track_id),
- audio_source);
- EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(),
- Initialize(_, _));
- EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(),
- SetAutomaticGainControl(true));
- EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(), Start());
- EXPECT_CALL(*mock_audio_device_factory_.mock_capturer_source(), Stop());
- CHECK(source->ConnectToTrack(audio_tracks[0]));
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks(
- static_cast<size_t>(1u));
- MediaStreamSource::SourceStoppedCallback dummy_callback;
- blink::WebMediaStreamSource video_source;
- video_source.Initialize(blink::WebString::FromUTF8(video_track_id),
- blink::WebMediaStreamSource::kTypeVideo,
- blink::WebString::FromUTF8(video_track_id),
- false /* remote */);
- MediaStreamVideoSource* native_source = new MockMediaStreamVideoSource();
- video_source.SetExtraData(native_source);
- video_tracks[0] = MediaStreamVideoTrack::CreateVideoTrack(
- blink::WebString::FromUTF8(video_track_id), native_source,
- MediaStreamVideoSource::ConstraintsCallback(), true);
-
- blink::WebMediaStream stream_desc;
- stream_desc.Initialize("stream_id", audio_tracks, video_tracks);
- return stream_desc;
- }
-
- private:
- static void OnAudioSourceStarted(MediaStreamSource* source,
- MediaStreamRequestResult result,
- const blink::WebString& result_name) {}
-
- MockAudioDeviceFactory mock_audio_device_factory_;
-};
-
-class RemoteWebRtcMediaStreamAdapterTest : public WebRtcMediaStreamAdapterTest {
- public:
- scoped_refptr<webrtc::MediaStreamInterface> CreateWebRtcMediaStream(
- const std::string& audio_track_id,
- const std::string& video_track_id) {
- scoped_refptr<webrtc::MediaStreamInterface> stream(
- new rtc::RefCountedObject<MockMediaStream>("remote_stream"));
- stream->AddTrack(MockWebRtcAudioTrack::Create(audio_track_id).get());
- stream->AddTrack(MockWebRtcVideoTrack::Create(video_track_id).get());
- return stream;
- }
-
- std::unique_ptr<WebRtcMediaStreamAdapter> CreateRemoteStreamAdapter(
- webrtc::MediaStreamInterface* webrtc_stream) {
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter;
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE,
- base::BindOnce(
- &RemoteWebRtcMediaStreamAdapterTest::
- CreateRemoteStreamAdapterOnSignalingThread,
- base::Unretained(this),
- base::Unretained(
- blink::scheduler::GetSingleThreadTaskRunnerForTesting().get()),
- base::Unretained(webrtc_stream), base::Unretained(&adapter)));
- RunMessageLoopsUntilIdle();
- DCHECK(adapter);
- return adapter;
- }
-
- // Adds the track and gets the adapters for the stream's resulting tracks.
- template <typename TrackType>
- 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>
- WebRtcMediaStreamAdapter::TrackAdapterRefs RemoveTrack(
- webrtc::MediaStreamInterface* webrtc_stream,
- TrackType* webrtc_track) {
- typedef bool (webrtc::MediaStreamInterface::*RemoveTrack)(TrackType*);
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- FROM_HERE,
- base::BindOnce(base::IgnoreResult<RemoveTrack>(
- &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:
- void CreateRemoteStreamAdapterOnSignalingThread(
- base::SingleThreadTaskRunner* main_thread,
- webrtc::MediaStreamInterface* webrtc_stream,
- std::unique_ptr<WebRtcMediaStreamAdapter>* adapter) {
- *adapter = WebRtcMediaStreamAdapter::CreateRemoteStreamAdapter(
- main_thread, track_adapter_map_, webrtc_stream);
- 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() {
- base::WaitableEvent waitable_event(
- base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- dependency_factory_->GetWebRtcSignalingThread()->PostTask(
- 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();
- }
-
- void SignalEvent(base::WaitableEvent* waitable_event) {
- waitable_event->Signal();
- }
-};
-
-TEST_F(LocalWebRtcMediaStreamAdapterTest, CreateStreamAdapter) {
- blink::WebMediaStream web_stream =
- CreateWebMediaStream("audio_track_id", "video_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- dependency_factory_.get(), track_adapter_map_, web_stream);
- EXPECT_TRUE(adapter->IsEqual(web_stream));
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetAudioTracks().size());
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetVideoTracks().size());
- EXPECT_EQ(web_stream.Id().Utf8(), adapter->webrtc_stream()->id());
-}
-
-TEST_F(LocalWebRtcMediaStreamAdapterTest,
- CreateStreamAdapterWithSharedTrackIds) {
- blink::WebMediaStream web_stream =
- CreateWebMediaStream("shared_track_id", "shared_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- dependency_factory_.get(), track_adapter_map_, web_stream);
- EXPECT_TRUE(adapter->IsEqual(web_stream));
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetAudioTracks().size());
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetVideoTracks().size());
- EXPECT_EQ(web_stream.Id().Utf8(), adapter->webrtc_stream()->id());
-}
-
-// It should not crash if |MediaStream| is created in blink with an unknown
-// audio source. This can happen if a |MediaStream| is created with remote audio
-// track.
-TEST_F(LocalWebRtcMediaStreamAdapterTest,
- AdapterForWebStreamWithoutAudioSource) {
- // Create a blink MediaStream description.
- blink::WebMediaStreamSource audio_source;
- audio_source.Initialize("audio source",
- blink::WebMediaStreamSource::kTypeAudio, "something",
- false /* remote */);
- // Without |audio_source.SetExtraData()| it is possible to initialize tracks
- // and streams but the source is a dummy.
-
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks(
- static_cast<size_t>(1));
- audio_tracks[0].Initialize(audio_source.Id(), audio_source);
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks(
- static_cast<size_t>(0));
-
- blink::WebMediaStream web_stream;
- web_stream.Initialize("stream_id", audio_tracks, video_tracks);
-
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- dependency_factory_.get(), track_adapter_map_, web_stream);
- EXPECT_TRUE(adapter->IsEqual(web_stream));
- EXPECT_EQ(0u, adapter->webrtc_stream()->GetAudioTracks().size());
- EXPECT_EQ(0u, adapter->webrtc_stream()->GetVideoTracks().size());
- EXPECT_EQ(web_stream.Id().Utf8(), adapter->webrtc_stream()->id());
-}
-
-TEST_F(LocalWebRtcMediaStreamAdapterTest, RemoveAndAddTrack) {
- blink::WebMediaStream web_stream =
- CreateWebMediaStream("audio_track_id", "video_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- WebRtcMediaStreamAdapter::CreateLocalStreamAdapter(
- dependency_factory_.get(), track_adapter_map_, web_stream);
- EXPECT_TRUE(adapter->IsEqual(web_stream));
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetAudioTracks().size());
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetVideoTracks().size());
- EXPECT_EQ(web_stream.Id().Utf8(), adapter->webrtc_stream()->id());
-
- // Modify the web layer stream, make sure the webrtc layer stream is updated.
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- web_stream.AudioTracks(audio_tracks);
-
- web_stream.RemoveTrack(audio_tracks[0]);
- EXPECT_TRUE(adapter->webrtc_stream()->GetAudioTracks().empty());
-
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- web_stream.VideoTracks(video_tracks);
-
- web_stream.RemoveTrack(video_tracks[0]);
- EXPECT_TRUE(adapter->webrtc_stream()->GetVideoTracks().empty());
-
- web_stream.AddTrack(audio_tracks[0]);
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetAudioTracks().size());
-
- web_stream.AddTrack(video_tracks[0]);
- EXPECT_EQ(1u, adapter->webrtc_stream()->GetVideoTracks().size());
-}
-
-TEST_F(RemoteWebRtcMediaStreamAdapterTest, CreateStreamAdapter) {
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream =
- CreateWebRtcMediaStream("audio_track_id", "video_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- CreateRemoteStreamAdapter(webrtc_stream.get());
- EXPECT_TRUE(adapter->is_initialized());
- EXPECT_EQ(webrtc_stream, adapter->webrtc_stream());
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks;
- adapter->web_stream().AudioTracks(web_audio_tracks);
- EXPECT_EQ(1u, web_audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks;
- adapter->web_stream().VideoTracks(web_video_tracks);
- EXPECT_EQ(1u, web_video_tracks.size());
-}
-
-TEST_F(RemoteWebRtcMediaStreamAdapterTest,
- CreateStreamAdapterWithSharedTrackIds) {
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream =
- CreateWebRtcMediaStream("shared_track_id", "shared_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- CreateRemoteStreamAdapter(webrtc_stream.get());
- EXPECT_TRUE(adapter->is_initialized());
- EXPECT_EQ(webrtc_stream, adapter->webrtc_stream());
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks;
- adapter->web_stream().AudioTracks(web_audio_tracks);
- EXPECT_EQ(1u, web_audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks;
- adapter->web_stream().VideoTracks(web_video_tracks);
- EXPECT_EQ(1u, web_video_tracks.size());
-}
-
-TEST_F(RemoteWebRtcMediaStreamAdapterTest, RemoveAndAddTrack) {
- scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream =
- CreateWebRtcMediaStream("audio_track_id", "video_track_id");
- std::unique_ptr<WebRtcMediaStreamAdapter> adapter =
- CreateRemoteStreamAdapter(webrtc_stream.get());
- EXPECT_TRUE(adapter->is_initialized());
- EXPECT_EQ(webrtc_stream, adapter->webrtc_stream());
- blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks;
- adapter->web_stream().AudioTracks(web_audio_tracks);
- EXPECT_EQ(1u, web_audio_tracks.size());
- blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks;
- adapter->web_stream().VideoTracks(web_video_tracks);
- EXPECT_EQ(1u, web_video_tracks.size());
-
- // 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];
- 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];
- adapter->SetTracks(
- RemoveTrack(webrtc_stream.get(), webrtc_video_track.get()));
- adapter->web_stream().VideoTracks(web_video_tracks);
- EXPECT_EQ(0u, web_video_tracks.size());
-
- adapter->SetTracks(AddTrack(webrtc_stream.get(), webrtc_audio_track.get()));
- adapter->web_stream().AudioTracks(web_audio_tracks);
- EXPECT_EQ(1u, web_audio_tracks.size());
-
- adapter->SetTracks(AddTrack(webrtc_stream.get(), webrtc_video_track.get()));
- adapter->web_stream().VideoTracks(web_video_tracks);
- EXPECT_EQ(1u, web_video_tracks.size());
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
index e03d1719ee0..a20adaaae7b 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
@@ -63,22 +63,24 @@ WebRtcMediaStreamTrackAdapter::WebRtcMediaStreamTrackAdapter(
remote_track_can_complete_initialization_(
base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED),
- is_initialized_(false) {
+ is_initialized_(false),
+ is_disposed_(false) {
DCHECK(factory_);
DCHECK(main_thread_);
}
WebRtcMediaStreamTrackAdapter::~WebRtcMediaStreamTrackAdapter() {
DCHECK(!remote_track_can_complete_initialization_.IsSignaled());
- DCHECK(!is_initialized_);
+ DCHECK(is_disposed_);
}
void WebRtcMediaStreamTrackAdapter::Dispose() {
DCHECK(main_thread_->BelongsToCurrentThread());
- if (!is_initialized_)
+ DCHECK(is_initialized_);
+ if (is_disposed_)
return;
remote_track_can_complete_initialization_.Reset();
- is_initialized_ = false;
+ is_disposed_ = true;
if (web_track_.Source().GetType() ==
blink::WebMediaStreamSource::kTypeAudio) {
if (local_track_audio_sink_)
@@ -99,10 +101,19 @@ bool WebRtcMediaStreamTrackAdapter::is_initialized() const {
return is_initialized_;
}
+void WebRtcMediaStreamTrackAdapter::InitializeOnMainThread() {
+ DCHECK(main_thread_->BelongsToCurrentThread());
+ if (is_initialized_)
+ return;
+ // TODO(hbos): Only ever initialize explicitly,
+ // remove EnsureTrackIsInitialized(). https://crbug.com/857458
+ EnsureTrackIsInitialized();
+}
+
const blink::WebMediaStreamTrack& WebRtcMediaStreamTrackAdapter::web_track() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!web_track_.IsNull());
EnsureTrackIsInitialized();
+ DCHECK(!web_track_.IsNull());
return web_track_;
}
@@ -231,6 +242,7 @@ void WebRtcMediaStreamTrackAdapter::
}
void WebRtcMediaStreamTrackAdapter::EnsureTrackIsInitialized() {
+ DCHECK(main_thread_->BelongsToCurrentThread());
if (is_initialized_)
return;
@@ -242,7 +254,6 @@ void WebRtcMediaStreamTrackAdapter::EnsureTrackIsInitialized() {
void WebRtcMediaStreamTrackAdapter::DisposeLocalAudioTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!is_initialized_);
DCHECK(local_track_audio_sink_);
DCHECK_EQ(web_track_.Source().GetType(),
blink::WebMediaStreamSource::kTypeAudio);
@@ -256,7 +267,6 @@ void WebRtcMediaStreamTrackAdapter::DisposeLocalAudioTrack() {
void WebRtcMediaStreamTrackAdapter::DisposeLocalVideoTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!is_initialized_);
DCHECK(local_track_video_sink_);
DCHECK_EQ(web_track_.Source().GetType(),
blink::WebMediaStreamSource::kTypeVideo);
@@ -267,7 +277,6 @@ void WebRtcMediaStreamTrackAdapter::DisposeLocalVideoTrack() {
void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!is_initialized_);
DCHECK(remote_audio_track_adapter_);
DCHECK_EQ(web_track_.Source().GetType(),
blink::WebMediaStreamSource::kTypeAudio);
@@ -280,7 +289,6 @@ void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() {
void WebRtcMediaStreamTrackAdapter::DisposeRemoteVideoTrack() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!is_initialized_);
DCHECK(remote_video_track_adapter_);
DCHECK_EQ(web_track_.Source().GetType(),
blink::WebMediaStreamSource::kTypeVideo);
@@ -300,7 +308,7 @@ void WebRtcMediaStreamTrackAdapter::
void WebRtcMediaStreamTrackAdapter::FinalizeRemoteTrackDisposingOnMainThread() {
DCHECK(main_thread_->BelongsToCurrentThread());
- DCHECK(!is_initialized_);
+ DCHECK(is_disposed_);
remote_audio_track_adapter_ = nullptr;
remote_video_track_adapter_ = nullptr;
webrtc_track_ = nullptr;
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h
index 722738c3950..8be75b5b895 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h
@@ -53,6 +53,7 @@ class CONTENT_EXPORT WebRtcMediaStreamTrackAdapter
void Dispose();
bool is_initialized() const;
+ void InitializeOnMainThread();
// These methods must be called on the main thread.
// TODO(hbos): Allow these methods to be called on any thread and make them
// const. https://crbug.com/756436
@@ -116,6 +117,7 @@ class CONTENT_EXPORT WebRtcMediaStreamTrackAdapter
// completed on the main thread.
base::WaitableEvent remote_track_can_complete_initialization_;
bool is_initialized_;
+ bool is_disposed_;
blink::WebMediaStreamTrack web_track_;
scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_;
// If the track is local, a sink is added to the local webrtc track that is
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc
index 28d6c1713a4..de3f036beff 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc
@@ -59,6 +59,17 @@ WebRtcMediaStreamTrackAdapterMap::AdapterRef::Copy() const {
return base::WrapUnique(new AdapterRef(map_, type_, adapter_));
}
+void WebRtcMediaStreamTrackAdapterMap::AdapterRef::InitializeOnMainThread() {
+ adapter_->InitializeOnMainThread();
+ if (type_ == WebRtcMediaStreamTrackAdapterMap::AdapterRef::Type::kRemote) {
+ base::AutoLock scoped_lock(map_->lock_);
+ if (!map_->remote_track_adapters_.FindBySecondary(web_track().UniqueId())) {
+ map_->remote_track_adapters_.SetSecondaryKey(webrtc_track(),
+ web_track().UniqueId());
+ }
+ }
+}
+
WebRtcMediaStreamTrackAdapterMap::WebRtcMediaStreamTrackAdapterMap(
PeerConnectionDependencyFactory* const factory,
scoped_refptr<base::SingleThreadTaskRunner> main_thread)
@@ -182,13 +193,13 @@ WebRtcMediaStreamTrackAdapterMap::GetOrCreateRemoteTrackAdapter(
// entry as its secondary key. This ensures that there is at least one
// |AdapterRef| alive until after the adapter is initialized and its secondary
// key is set.
+ auto adapter_ref = base::WrapUnique(
+ new AdapterRef(this, AdapterRef::Type::kRemote, new_adapter));
main_thread_->PostTask(
FROM_HERE,
base::BindOnce(
- &WebRtcMediaStreamTrackAdapterMap::OnRemoteTrackAdapterInitialized,
- this,
- base::WrapUnique(
- new AdapterRef(this, AdapterRef::Type::kRemote, new_adapter))));
+ &WebRtcMediaStreamTrackAdapterMap::AdapterRef::InitializeOnMainThread,
+ std::move(adapter_ref)));
return base::WrapUnique(
new AdapterRef(this, AdapterRef::Type::kRemote, new_adapter));
}
@@ -198,14 +209,4 @@ size_t WebRtcMediaStreamTrackAdapterMap::GetRemoteTrackCount() const {
return remote_track_adapters_.PrimarySize();
}
-void WebRtcMediaStreamTrackAdapterMap::OnRemoteTrackAdapterInitialized(
- std::unique_ptr<AdapterRef> adapter_ref) {
- DCHECK(adapter_ref->is_initialized());
- {
- base::AutoLock scoped_lock(lock_);
- remote_track_adapters_.SetSecondaryKey(adapter_ref->webrtc_track(),
- adapter_ref->web_track().UniqueId());
- }
-}
-
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h
index c7ef9ed9b92..8c9cbf17c0d 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h
@@ -38,6 +38,7 @@ class CONTENT_EXPORT WebRtcMediaStreamTrackAdapterMap
std::unique_ptr<AdapterRef> Copy() const;
bool is_initialized() const { return adapter_->is_initialized(); }
+ void InitializeOnMainThread();
const blink::WebMediaStreamTrack& web_track() const {
return adapter_->web_track();
}
@@ -137,8 +138,6 @@ class CONTENT_EXPORT WebRtcMediaStreamTrackAdapterMap
// Invoke on the main thread.
virtual ~WebRtcMediaStreamTrackAdapterMap();
- void OnRemoteTrackAdapterInitialized(std::unique_ptr<AdapterRef> adapter_ref);
-
// Pointer to a |PeerConnectionDependencyFactory| owned by the |RenderThread|.
// It's valid for the lifetime of |RenderThread|.
PeerConnectionDependencyFactory* const factory_;
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc
index 8c5fd3e426f..a141ce50156 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc
@@ -53,8 +53,8 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test {
}
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
- GetOrCreateRemoteTrackAdapter(
- webrtc::MediaStreamTrackInterface* webrtc_track) {
+ GetOrCreateRemoteTrackAdapter(webrtc::MediaStreamTrackInterface* webrtc_track,
+ bool wait_for_initialization = true) {
DCHECK(main_thread_->BelongsToCurrentThread());
std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter;
signaling_thread()->PostTask(
@@ -63,7 +63,13 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test {
GetOrCreateRemoteTrackAdapterOnSignalingThread,
base::Unretained(this), base::Unretained(webrtc_track),
&adapter));
- RunMessageLoopsUntilIdle();
+ RunMessageLoopsUntilIdle(wait_for_initialization);
+ DCHECK(adapter);
+ if (wait_for_initialization) {
+ DCHECK(adapter->is_initialized());
+ } else {
+ DCHECK(!adapter->is_initialized());
+ }
return adapter;
}
@@ -76,7 +82,7 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test {
// Runs message loops on the webrtc signaling thread and the main thread until
// idle.
- void RunMessageLoopsUntilIdle() {
+ void RunMessageLoopsUntilIdle(bool run_loop_on_main_thread = true) {
DCHECK(main_thread_->BelongsToCurrentThread());
base::WaitableEvent waitable_event(
base::WaitableEvent::ResetPolicy::MANUAL,
@@ -86,7 +92,8 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test {
RunMessageLoopUntilIdleOnSignalingThread,
base::Unretained(this), &waitable_event));
waitable_event.Wait();
- base::RunLoop().RunUntilIdle();
+ if (run_loop_on_main_thread)
+ base::RunLoop().RunUntilIdle();
}
void RunMessageLoopUntilIdleOnSignalingThread(
@@ -168,6 +175,29 @@ TEST_F(WebRtcMediaStreamTrackAdapterMapTest, AddAndRemoveRemoteTrackAdapter) {
}
TEST_F(WebRtcMediaStreamTrackAdapterMapTest,
+ InitializeRemoteTrackAdapterExplicitly) {
+ scoped_refptr<MockWebRtcAudioTrack> webrtc_track =
+ MockWebRtcAudioTrack::Create("remote_track");
+ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter_ref =
+ GetOrCreateRemoteTrackAdapter(webrtc_track.get(), false);
+ EXPECT_FALSE(adapter_ref->is_initialized());
+ adapter_ref->InitializeOnMainThread();
+ EXPECT_TRUE(adapter_ref->is_initialized());
+
+ EXPECT_EQ(1u, map_->GetRemoteTrackCount());
+ // Ensure the implicit initialization's posted task is run after it is already
+ // initialized.
+ RunMessageLoopsUntilIdle();
+ // Destroying all references to the adapter should remove it from the map and
+ // dispose it.
+ adapter_ref.reset();
+ EXPECT_EQ(0u, map_->GetRemoteTrackCount());
+ EXPECT_EQ(nullptr, map_->GetRemoteTrackAdapter(webrtc_track.get()));
+ // Allow the disposing of track to occur.
+ RunMessageLoopsUntilIdle();
+}
+
+TEST_F(WebRtcMediaStreamTrackAdapterMapTest,
LocalAndRemoteTrackAdaptersWithSameID) {
// Local and remote tracks should be able to use the same id without conflict.
const char* id = "id";
diff --git a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
index 7ca513bc07f..74f586d44b1 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
@@ -37,7 +37,6 @@ class WebRtcMediaStreamTrackAdapterTest : public ::testing::Test {
if (track_adapter_) {
EXPECT_TRUE(track_adapter_->is_initialized());
track_adapter_->Dispose();
- EXPECT_FALSE(track_adapter_->is_initialized());
track_adapter_ = nullptr;
RunMessageLoopsUntilIdle();
}
@@ -80,9 +79,9 @@ class WebRtcMediaStreamTrackAdapterTest : public ::testing::Test {
dependency_factory_.get(), main_thread_, webrtc_track);
}
- // Runs message loops on the webrtc signaling thread and the main thread until
- // idle.
- void RunMessageLoopsUntilIdle() {
+ // Runs message loops on the webrtc signaling thread and optionally the main
+ // thread until idle.
+ void RunMessageLoopsUntilIdle(bool run_loop_on_main_thread = true) {
base::WaitableEvent waitable_event(
base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED);
@@ -91,7 +90,8 @@ class WebRtcMediaStreamTrackAdapterTest : public ::testing::Test {
RunMessageLoopUntilIdleOnSignalingThread,
base::Unretained(this), &waitable_event));
waitable_event.Wait();
- base::RunLoop().RunUntilIdle();
+ if (run_loop_on_main_thread)
+ base::RunLoop().RunUntilIdle();
}
void RunMessageLoopUntilIdleOnSignalingThread(
@@ -157,6 +157,7 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteAudioTrack) {
base::BindOnce(
&WebRtcMediaStreamTrackAdapterTest::CreateRemoteTrackAdapter,
base::Unretained(this), base::Unretained(webrtc_track.get())));
+ // The adapter is initialized implicitly in a PostTask, allow it to run.
RunMessageLoopsUntilIdle();
DCHECK(track_adapter_);
EXPECT_TRUE(track_adapter_->is_initialized());
@@ -181,6 +182,7 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteVideoTrack) {
base::BindOnce(
&WebRtcMediaStreamTrackAdapterTest::CreateRemoteTrackAdapter,
base::Unretained(this), base::Unretained(webrtc_track.get())));
+ // The adapter is initialized implicitly in a PostTask, allow it to run.
RunMessageLoopsUntilIdle();
DCHECK(track_adapter_);
EXPECT_TRUE(track_adapter_->is_initialized());
@@ -197,4 +199,33 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteVideoTrack) {
track_adapter_->GetRemoteVideoTrackAdapterForTesting()->initialized());
}
+TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteTrackExplicitlyInitialized) {
+ scoped_refptr<MockWebRtcAudioTrack> webrtc_track =
+ MockWebRtcAudioTrack::Create("remote_audio_track");
+ dependency_factory_->GetWebRtcSignalingThread()->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &WebRtcMediaStreamTrackAdapterTest::CreateRemoteTrackAdapter,
+ base::Unretained(this), base::Unretained(webrtc_track.get())));
+ // Wait for the CreateRemoteTrackAdapter() call, but don't run the main thread
+ // loop that would have implicitly initialized the adapter.
+ RunMessageLoopsUntilIdle(false);
+ DCHECK(track_adapter_);
+ EXPECT_FALSE(track_adapter_->is_initialized());
+ // Explicitly initialize before the main thread loop has a chance to run.
+ track_adapter_->InitializeOnMainThread();
+ EXPECT_TRUE(track_adapter_->is_initialized());
+ EXPECT_TRUE(!track_adapter_->web_track().IsNull());
+ EXPECT_EQ(track_adapter_->web_track().Source().GetType(),
+ blink::WebMediaStreamSource::kTypeAudio);
+ EXPECT_TRUE(track_adapter_->webrtc_track());
+ EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
+ webrtc::MediaStreamTrackInterface::kAudioKind);
+ EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(),
+ track_adapter_->web_track().Id());
+ EXPECT_TRUE(track_adapter_->GetRemoteAudioTrackAdapterForTesting());
+ EXPECT_TRUE(
+ track_adapter_->GetRemoteAudioTrackAdapterForTesting()->initialized());
+}
+
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.cc b/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.cc
new file mode 100644
index 00000000000..f36ef07ad97
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.cc
@@ -0,0 +1,166 @@
+// 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_description_observer.h"
+
+#include "base/logging.h"
+
+namespace content {
+
+WebRtcSetDescriptionObserver::States::States()
+ : signaling_state(
+ webrtc::PeerConnectionInterface::SignalingState::kClosed) {}
+
+WebRtcSetDescriptionObserver::States::States(States&& other)
+ : signaling_state(other.signaling_state),
+ transceiver_states(std::move(other.transceiver_states)) {}
+
+WebRtcSetDescriptionObserver::States::~States() = default;
+
+WebRtcSetDescriptionObserver::States& WebRtcSetDescriptionObserver::States::
+operator=(States&& other) {
+ signaling_state = other.signaling_state;
+ transceiver_states = std::move(other.transceiver_states);
+ return *this;
+}
+
+WebRtcSetDescriptionObserver::WebRtcSetDescriptionObserver() = default;
+
+WebRtcSetDescriptionObserver::~WebRtcSetDescriptionObserver() = default;
+
+WebRtcSetDescriptionObserverHandlerImpl::
+ WebRtcSetDescriptionObserverHandlerImpl(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only)
+ : main_task_runner_(std::move(main_task_runner)),
+ signaling_task_runner_(std::move(signaling_task_runner)),
+ pc_(std::move(pc)),
+ track_adapter_map_(std::move(track_adapter_map)),
+ observer_(std::move(observer)),
+ surface_receivers_only_(surface_receivers_only) {}
+
+WebRtcSetDescriptionObserverHandlerImpl::
+ ~WebRtcSetDescriptionObserverHandlerImpl() = default;
+
+void WebRtcSetDescriptionObserverHandlerImpl::OnSetDescriptionComplete(
+ webrtc::RTCError error) {
+ CHECK(signaling_task_runner_->BelongsToCurrentThread());
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
+ receiver_only_transceivers;
+ std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> transceivers;
+ if (surface_receivers_only_) {
+ for (const auto& receiver : pc_->GetReceivers()) {
+ transceivers.push_back(new SurfaceReceiverStateOnly(receiver));
+ }
+ } else {
+ transceivers = pc_->GetTransceivers();
+ }
+ TransceiverStateSurfacer transceiver_state_surfacer(main_task_runner_,
+ signaling_task_runner_);
+ transceiver_state_surfacer.Initialize(track_adapter_map_,
+ std::move(transceivers));
+ main_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&WebRtcSetDescriptionObserverHandlerImpl::
+ OnSetDescriptionCompleteOnMainThread,
+ this, std::move(error), pc_->signaling_state(),
+ std::move(transceiver_state_surfacer)));
+}
+
+void WebRtcSetDescriptionObserverHandlerImpl::
+ OnSetDescriptionCompleteOnMainThread(
+ webrtc::RTCError error,
+ webrtc::PeerConnectionInterface::SignalingState signaling_state,
+ TransceiverStateSurfacer transceiver_state_surfacer) {
+ CHECK(main_task_runner_->BelongsToCurrentThread());
+ WebRtcSetDescriptionObserver::States states;
+ states.signaling_state = signaling_state;
+ states.transceiver_states = transceiver_state_surfacer.ObtainStates();
+ observer_->OnSetDescriptionComplete(std::move(error), std::move(states));
+}
+
+scoped_refptr<WebRtcSetLocalDescriptionObserverHandler>
+WebRtcSetLocalDescriptionObserverHandler::Create(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only) {
+ return new rtc::RefCountedObject<WebRtcSetLocalDescriptionObserverHandler>(
+ std::move(main_task_runner), std::move(signaling_task_runner),
+ std::move(pc), std::move(track_adapter_map), std::move(observer),
+ surface_receivers_only);
+}
+
+WebRtcSetLocalDescriptionObserverHandler::
+ WebRtcSetLocalDescriptionObserverHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only)
+ : handler_impl_(new WebRtcSetDescriptionObserverHandlerImpl(
+ std::move(main_task_runner),
+ std::move(signaling_task_runner),
+ std::move(pc),
+ std::move(track_adapter_map),
+ std::move(observer),
+ surface_receivers_only)) {}
+
+WebRtcSetLocalDescriptionObserverHandler::
+ ~WebRtcSetLocalDescriptionObserverHandler() = default;
+
+void WebRtcSetLocalDescriptionObserverHandler::OnSuccess() {
+ handler_impl_->OnSetDescriptionComplete(webrtc::RTCError::OK());
+}
+
+void WebRtcSetLocalDescriptionObserverHandler::OnFailure(
+ webrtc::RTCError error) {
+ handler_impl_->OnSetDescriptionComplete(std::move(error));
+}
+
+scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler>
+WebRtcSetRemoteDescriptionObserverHandler::Create(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only) {
+ return new rtc::RefCountedObject<WebRtcSetRemoteDescriptionObserverHandler>(
+ std::move(main_task_runner), std::move(signaling_task_runner),
+ std::move(pc), std::move(track_adapter_map), std::move(observer),
+ surface_receivers_only);
+}
+
+WebRtcSetRemoteDescriptionObserverHandler::
+ WebRtcSetRemoteDescriptionObserverHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only)
+ : handler_impl_(new WebRtcSetDescriptionObserverHandlerImpl(
+ std::move(main_task_runner),
+ std::move(signaling_task_runner),
+ std::move(pc),
+ std::move(track_adapter_map),
+ std::move(observer),
+ surface_receivers_only)) {}
+
+WebRtcSetRemoteDescriptionObserverHandler::
+ ~WebRtcSetRemoteDescriptionObserverHandler() = default;
+
+void WebRtcSetRemoteDescriptionObserverHandler::OnSetRemoteDescriptionComplete(
+ webrtc::RTCError error) {
+ handler_impl_->OnSetDescriptionComplete(std::move(error));
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.h b/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.h
new file mode 100644
index 00000000000..41e84950259
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/webrtc_set_description_observer.h
@@ -0,0 +1,186 @@
+// 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_DESCRIPTION_OBSERVER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_SET_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/webrtc/rtc_peer_connection_handler.h"
+#include "content/renderer/media/webrtc/rtc_rtp_receiver.h"
+#include "content/renderer/media/webrtc/rtc_rtp_sender.h"
+#include "content/renderer/media/webrtc/rtc_rtp_transceiver.h"
+#include "content/renderer/media/webrtc/transceiver_state_surfacer.h"
+#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/webrtc/api/jsep.h"
+#include "third_party/webrtc/api/peerconnectioninterface.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 {
+
+// The content layer correspondent of the setLocalDescription() observer
+// (webrtc::SetSessionDescriptionObserver) and setRemoteDescription() observer
+// (webrtc::SetRemoteDescriptionObserverInterface). The implementation should
+// process the state changes of the Set[Local/Remote]Description() by inspecting
+// the updated States.
+class CONTENT_EXPORT WebRtcSetDescriptionObserver
+ : public base::RefCountedThreadSafe<WebRtcSetDescriptionObserver> {
+ public:
+ // The states as they were when the operation finished on the webrtc signaling
+ // thread. Note that other operations may have occurred while jumping back to
+ // the main thread, but these must be handled separately.
+ struct CONTENT_EXPORT States {
+ States();
+ States(States&& other);
+ ~States();
+
+ States& operator=(States&& other);
+
+ webrtc::PeerConnectionInterface::SignalingState signaling_state;
+ std::vector<RtpTransceiverState> transceiver_states;
+
+ DISALLOW_COPY_AND_ASSIGN(States);
+ };
+
+ WebRtcSetDescriptionObserver();
+
+ // Invoked in a PostTask() on the main thread after the SetLocalDescription()
+ // or SetRemoteDescription() operation completed on the webrtc signaling
+ // thread.
+ virtual void OnSetDescriptionComplete(webrtc::RTCError error,
+ States states) = 0;
+
+ protected:
+ friend class base::RefCountedThreadSafe<WebRtcSetDescriptionObserver>;
+ virtual ~WebRtcSetDescriptionObserver();
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcSetDescriptionObserver);
+};
+
+// Takes care of surfacing WebRtcSetDescriptionObserver::State information from
+// the webrtc signaling thread to the main thread. With the state information
+// obtained, invokes |observer_|'s
+// WebRtcSetDescriptionObserver::OnSetDescriptionComplete() on the main thread.
+//
+// This implements the behavior
+// of both WebRtcSetLocalDescriptionObserverHandler and
+// WebRtcSetRemoteDescriptionObserverHandler, but these are put in different
+// classes because local and remote description observers have different
+// interfaces in webrtc.
+class CONTENT_EXPORT WebRtcSetDescriptionObserverHandlerImpl
+ : public base::RefCountedThreadSafe<
+ WebRtcSetDescriptionObserverHandlerImpl> {
+ public:
+ WebRtcSetDescriptionObserverHandlerImpl(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only);
+
+ // Must be called on the webrtc signaling thread internally by the handler
+ // when the Set[Local/Remote]Description() operation finishes.
+ void OnSetDescriptionComplete(webrtc::RTCError error);
+
+ private:
+ friend class base::RefCountedThreadSafe<
+ WebRtcSetDescriptionObserverHandlerImpl>;
+ virtual ~WebRtcSetDescriptionObserverHandlerImpl();
+
+ void OnSetDescriptionCompleteOnMainThread(
+ webrtc::RTCError error,
+ webrtc::PeerConnectionInterface::SignalingState signaling_state,
+ TransceiverStateSurfacer transceiver_state_surfacer);
+
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
+ scoped_refptr<webrtc::PeerConnectionInterface> pc_;
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
+ scoped_refptr<WebRtcSetDescriptionObserver> observer_;
+ bool surface_receivers_only_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcSetDescriptionObserverHandlerImpl);
+};
+
+// An implementation of webrtc::SetSessionDescriptionObserver for performing the
+// operations of WebRtcSetDescriptionObserverHandlerImpl.
+class CONTENT_EXPORT WebRtcSetLocalDescriptionObserverHandler
+ : public webrtc::SetSessionDescriptionObserver {
+ public:
+ static scoped_refptr<WebRtcSetLocalDescriptionObserverHandler> Create(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only);
+
+ // webrtc::SetSessionDescriptionObserver implementation. Implementation calls
+ // WebRtcSetDescriptionObserverHandlerImpl::OnSetDescriptionComplete().
+ void OnSuccess() override;
+ void OnFailure(webrtc::RTCError error) override;
+
+ protected:
+ WebRtcSetLocalDescriptionObserverHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only);
+ ~WebRtcSetLocalDescriptionObserverHandler() override;
+
+ scoped_refptr<WebRtcSetDescriptionObserverHandlerImpl> handler_impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcSetLocalDescriptionObserverHandler);
+};
+
+// An implementation of webrtc::SetRemoteDescriptionObserverInterface for
+// performing the operations of WebRtcSetDescriptionObserverHandlerImpl.
+class CONTENT_EXPORT WebRtcSetRemoteDescriptionObserverHandler
+ : public webrtc::SetRemoteDescriptionObserverInterface {
+ public:
+ static scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler> Create(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only);
+
+ // webrtc::SetRemoteDescriptionObserverInterface implementation.
+ // Implementation calls
+ // WebRtcSetDescriptionObserverHandlerImpl::OnSetDescriptionComplete().
+ void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override;
+
+ protected:
+ WebRtcSetRemoteDescriptionObserverHandler(
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
+ scoped_refptr<webrtc::PeerConnectionInterface> pc,
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+ scoped_refptr<WebRtcSetDescriptionObserver> observer,
+ bool surface_receivers_only);
+ ~WebRtcSetRemoteDescriptionObserverHandler() override;
+
+ scoped_refptr<WebRtcSetDescriptionObserverHandlerImpl> handler_impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcSetRemoteDescriptionObserverHandler);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_SET_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_description_observer_unittest.cc
index 5b861458a11..c2f7dc786b0 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_set_description_observer_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/renderer/media/webrtc/webrtc_set_remote_description_observer.h"
+#include "content/renderer/media/webrtc/webrtc_set_description_observer.h"
#include <memory>
#include <utility>
@@ -16,7 +16,6 @@
#include "content/child/child_process.h"
#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/mock_peer_connection_impl.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/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -29,35 +28,41 @@ using ::testing::Return;
namespace content {
-class WebRtcSetRemoteDescriptionObserverForTest
- : public WebRtcSetRemoteDescriptionObserver {
+class WebRtcSetDescriptionObserverForTest
+ : public WebRtcSetDescriptionObserver {
public:
- bool called() const { return states_or_error_.has_value(); }
- bool result() const { return states_or_error_->ok(); }
+ bool called() const { return called_; }
- const WebRtcSetRemoteDescriptionObserver::States& states() const {
- DCHECK(called() && result());
- return states_or_error_->value();
+ const WebRtcSetDescriptionObserver::States& states() const {
+ DCHECK(called_);
+ return states_;
}
const webrtc::RTCError& error() const {
- DCHECK(called() && !result());
- return states_or_error_->error();
+ DCHECK(called_);
+ return error_;
}
- // WebRtcSetRemoteDescriptionObserver implementation.
- void OnSetRemoteDescriptionComplete(
- webrtc::RTCErrorOr<States> states_or_error) override {
- states_or_error_ = std::move(states_or_error);
+ // WebRtcSetDescriptionObserver implementation.
+ void OnSetDescriptionComplete(
+ webrtc::RTCError error,
+ WebRtcSetDescriptionObserver::States states) override {
+ called_ = true;
+ error_ = std::move(error);
+ states_ = std::move(states);
}
private:
- ~WebRtcSetRemoteDescriptionObserverForTest() override {}
+ ~WebRtcSetDescriptionObserverForTest() override {}
- base::Optional<webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>>
- states_or_error_;
- WebRtcSetRemoteDescriptionObserver::States states_;
+ bool called_ = false;
+ webrtc::RTCError error_;
+ WebRtcSetDescriptionObserver::States states_;
};
+// TODO(hbos): This only tests WebRtcSetRemoteDescriptionObserverHandler,
+// parameterize the test to make it also test
+// WebRtcSetLocalDescriptionObserverHandler and with "surface_receivers_only" as
+// both true and false. https://crbug.com/865006
class WebRtcSetRemoteDescriptionObserverHandlerTest : public ::testing::Test {
public:
void SetUp() override {
@@ -66,14 +71,13 @@ class WebRtcSetRemoteDescriptionObserverHandlerTest : public ::testing::Test {
new cricket::FakeMediaEngine())));
dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
- scoped_refptr<WebRtcMediaStreamAdapterMap> map =
- new WebRtcMediaStreamAdapterMap(
- dependency_factory_.get(), main_thread_,
- new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
- main_thread_));
- observer_ = new WebRtcSetRemoteDescriptionObserverForTest();
+ scoped_refptr<WebRtcMediaStreamTrackAdapterMap> map =
+ new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
+ main_thread_);
+ observer_ = new WebRtcSetDescriptionObserverForTest();
observer_handler_ = WebRtcSetRemoteDescriptionObserverHandler::Create(
- main_thread_, pc_, map, observer_);
+ main_thread_, dependency_factory_->GetWebRtcSignalingThread(), pc_, map,
+ observer_, true /* surface_receivers_only*/);
}
void TearDown() override { blink::WebHeap::CollectAllGarbageForTesting(); }
@@ -106,7 +110,7 @@ class WebRtcSetRemoteDescriptionObserverHandlerTest : public ::testing::Test {
scoped_refptr<webrtc::MockPeerConnection> pc_;
std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
- scoped_refptr<WebRtcSetRemoteDescriptionObserverForTest> observer_;
+ scoped_refptr<WebRtcSetDescriptionObserverForTest> observer_;
scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler> observer_handler_;
std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> receivers_;
@@ -124,28 +128,65 @@ TEST_F(WebRtcSetRemoteDescriptionObserverHandlerTest, OnSuccess) {
{added_stream.get()})));
receivers_.push_back(added_receiver.get());
+ EXPECT_CALL(*pc_, signaling_state())
+ .WillRepeatedly(Return(webrtc::PeerConnectionInterface::kStable));
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());
+ EXPECT_TRUE(observer_->error().ok());
+
+ EXPECT_EQ(webrtc::PeerConnectionInterface::kStable,
+ observer_->states().signaling_state);
+
+ EXPECT_EQ(1u, observer_->states().transceiver_states.size());
+ const RtpTransceiverState& transceiver_state =
+ observer_->states().transceiver_states[0];
+ EXPECT_FALSE(transceiver_state.sender_state());
+ EXPECT_TRUE(transceiver_state.receiver_state());
+ const RtpReceiverState& receiver_state = *transceiver_state.receiver_state();
+ EXPECT_EQ(added_receiver, receiver_state.webrtc_receiver());
+ EXPECT_EQ(added_track, receiver_state.track_ref()->webrtc_track());
+ EXPECT_EQ(1u, receiver_state.stream_ids().size());
+ EXPECT_EQ(added_stream->id(), receiver_state.stream_ids()[0]);
}
TEST_F(WebRtcSetRemoteDescriptionObserverHandlerTest, OnFailure) {
- webrtc::RTCError error(webrtc::RTCErrorType::INVALID_PARAMETER, "Oh noes!");
- InvokeOnSetRemoteDescriptionComplete(std::move(error));
+ 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_, signaling_state())
+ .WillRepeatedly(Return(webrtc::PeerConnectionInterface::kStable));
+ EXPECT_CALL(*pc_, GetReceivers()).WillRepeatedly(Return(receivers_));
+
+ InvokeOnSetRemoteDescriptionComplete(
+ webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, "Oh noes!"));
EXPECT_TRUE(observer_->called());
- EXPECT_FALSE(observer_->result());
+ EXPECT_FALSE(observer_->error().ok());
EXPECT_EQ(std::string("Oh noes!"), observer_->error().message());
+
+ // Verify states were surfaced even though we got an error.
+ EXPECT_EQ(webrtc::PeerConnectionInterface::kStable,
+ observer_->states().signaling_state);
+
+ EXPECT_EQ(1u, observer_->states().transceiver_states.size());
+ const RtpTransceiverState& transceiver_state =
+ observer_->states().transceiver_states[0];
+ EXPECT_FALSE(transceiver_state.sender_state());
+ EXPECT_TRUE(transceiver_state.receiver_state());
+ const RtpReceiverState& receiver_state = *transceiver_state.receiver_state();
+ EXPECT_EQ(added_receiver, receiver_state.webrtc_receiver());
+ EXPECT_EQ(added_track, receiver_state.track_ref()->webrtc_track());
+ EXPECT_EQ(1u, receiver_state.stream_ids().size());
+ EXPECT_EQ(added_stream->id(), receiver_state.stream_ids()[0]);
}
} // namespace content
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
deleted file mode 100644
index 0ebb644548b..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc
+++ /dev/null
@@ -1,120 +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/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;
-}
-
-void WebRtcSetRemoteDescriptionObserver::States::CheckInvariants() const {
- // Invariants:
- // - All receiver states have a stream ref
- // - All receiver states refer to streams that are non-null.
- for (auto& receiver_state : receiver_states) {
- for (auto& stream_ref : receiver_state.stream_refs) {
- CHECK(stream_ref);
- CHECK(!stream_ref->adapter().web_stream().IsNull());
- }
- }
-}
-
-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) {
- CHECK(!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, std::move(states_or_error)));
-}
-
-void WebRtcSetRemoteDescriptionObserverHandler::
- OnSetRemoteDescriptionCompleteOnMainThread(
- webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States>
- states_or_error) {
- CHECK(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
deleted file mode 100644
index 1102c415990..00000000000
--- a/chromium/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h
+++ /dev/null
@@ -1,140 +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.
-
-#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/webrtc/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;
- // Check that the invariants for this structure hold.
- void CheckInvariants() const;
-
- 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_util.h b/chromium/content/renderer/media/webrtc/webrtc_util.h
new file mode 100644
index 00000000000..425c0ec9373
--- /dev/null
+++ b/chromium/content/renderer/media/webrtc/webrtc_util.h
@@ -0,0 +1,35 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_UTIL_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_UTIL_H_
+
+#include "base/optional.h"
+
+namespace content {
+
+template <typename OptionalT>
+base::Optional<typename OptionalT::value_type> ToBaseOptional(
+ const OptionalT& optional) {
+ return optional ? base::make_optional(*optional) : base::nullopt;
+}
+
+template <typename OptionalT>
+absl::optional<typename OptionalT::value_type> ToAbslOptional(
+ const OptionalT& optional) {
+ return optional ? absl::make_optional(*optional) : absl::nullopt;
+}
+
+template <typename OptionalT1, typename OptionalT2>
+bool OptionalEquals(const OptionalT1& lhs, const OptionalT2& rhs) {
+ if (!lhs)
+ return !rhs;
+ if (!rhs)
+ return false;
+ return *lhs == *rhs;
+}
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_UTIL_H_
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 95357d45e98..57ae21ee241 100644
--- a/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
+++ b/chromium/content/renderer/media/webrtc/webrtc_video_capturer_adapter.cc
@@ -209,7 +209,9 @@ bool WebRtcVideoCapturerAdapter::ShouldAdaptResolution() const {
return true;
}
if (content_hint_ ==
- blink::WebMediaStreamTrack::ContentHintType::kVideoDetail) {
+ blink::WebMediaStreamTrack::ContentHintType::kVideoDetail ||
+ content_hint_ ==
+ blink::WebMediaStreamTrack::ContentHintType::kVideoText) {
return false;
}
// Screencast does not adapt by default.
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 e076b3de238..ce1208152d4 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
@@ -117,44 +117,4 @@ TEST_F(WebRtcVideoCapturerAdapterTest, Scale720To640360) {
TestSourceCropFrame(1280, 720, 1280, 720, 640, 360);
}
-TEST_F(WebRtcVideoCapturerAdapterTest,
- NonScreencastAdapterDoesNotAdaptContentHintDetail) {
- // Non-screenshare adapter should not adapt frames when detail is set.
- TestContentHintResolutionAdaptation(
- false, blink::WebMediaStreamTrack::ContentHintType::kNone, true,
- blink::WebMediaStreamTrack::ContentHintType::kVideoDetail, false);
-}
-
-TEST_F(WebRtcVideoCapturerAdapterTest,
- NonScreencastAdapterAdaptsContentHintFluid) {
- // Non-screenshare adapter should still adapt frames when motion is set.
- TestContentHintResolutionAdaptation(
- false, blink::WebMediaStreamTrack::ContentHintType::kNone, true,
- blink::WebMediaStreamTrack::ContentHintType::kVideoMotion, true);
-}
-
-TEST_F(WebRtcVideoCapturerAdapterTest,
- ScreencastAdapterAdaptsContentHintFluid) {
- // Screenshare adapter should adapt frames when motion is set.
- TestContentHintResolutionAdaptation(
- true, blink::WebMediaStreamTrack::ContentHintType::kNone, false,
- blink::WebMediaStreamTrack::ContentHintType::kVideoMotion, true);
-}
-
-TEST_F(WebRtcVideoCapturerAdapterTest,
- ScreencastAdapterDoesNotAdaptContentHintDetailed) {
- // Screenshare adapter should still not adapt frames when detail is set.
- TestContentHintResolutionAdaptation(
- true, blink::WebMediaStreamTrack::ContentHintType::kNone, false,
- blink::WebMediaStreamTrack::ContentHintType::kVideoDetail, false);
-}
-
-TEST_F(WebRtcVideoCapturerAdapterTest, RespectsConstructionTimeContentHint) {
- // Non-screenshare adapter constructed with detail content hint should not
- // adapt before SetContentHint is run.
- TestContentHintResolutionAdaptation(
- false, blink::WebMediaStreamTrack::ContentHintType::kVideoDetail, false,
- blink::WebMediaStreamTrack::ContentHintType::kVideoMotion, true);
-}
-
} // namespace content
diff --git a/chromium/content/renderer/media/webrtc_local_audio_source_provider.cc b/chromium/content/renderer/media/webrtc_local_audio_source_provider.cc
index a59e3c693ac..8087bd2db3b 100644
--- a/chromium/content/renderer/media/webrtc_local_audio_source_provider.cc
+++ b/chromium/content/renderer/media/webrtc_local_audio_source_provider.cc
@@ -8,7 +8,7 @@
#include "base/logging.h"
#include "content/public/renderer/render_frame.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "media/base/audio_fifo.h"
#include "media/base/audio_parameters.h"
#include "third_party/blink/public/platform/web_audio_source_provider_client.h"
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 c2d9031674a..b6278f3162b 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
@@ -171,7 +171,7 @@ void CanvasCaptureHandler::SendNewFrame(
(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)),
+ static_cast<const uint8_t*>(pixmap.addr(0, 0)),
gfx::Size(pixmap.width(), pixmap.height()),
pixmap.rowBytes(), pixmap.colorType()),
timestamp);
@@ -402,10 +402,10 @@ scoped_refptr<media::VideoFrame> CanvasCaptureHandler::ConvertToYUVFrame(
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;
+ int (*ConvertToI420)(const uint8_t* src_argb, int src_stride_argb,
+ uint8_t* dst_y, int dst_stride_y, uint8_t* dst_u,
+ int dst_stride_u, uint8_t* dst_v, int dst_stride_v,
+ int width, int height) = nullptr;
switch (source_color_type) {
case kRGBA_8888_SkColorType:
ConvertToI420 = libyuv::ABGRToI420;
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 de6e209743c..daffde0b484 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
@@ -151,13 +151,13 @@ void HtmlVideoElementCapturerSource::sendNewFrame() {
media::PIXEL_FORMAT_I420, resolution, gfx::Rect(resolution), resolution,
current_time - start_capture_time_);
- const uint32 source_pixel_format =
+ const uint32_t source_pixel_format =
(kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR
: libyuv::FOURCC_ARGB;
if (frame &&
libyuv::ConvertToI420(
- static_cast<uint8*>(bitmap_.getPixels()), bitmap_.computeByteSize(),
+ static_cast<uint8_t*>(bitmap_.getPixels()), bitmap_.computeByteSize(),
frame->visible_data(media::VideoFrame::kYPlane),
frame->stride(media::VideoFrame::kYPlane),
frame->visible_data(media::VideoFrame::kUPlane),
diff --git a/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc b/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc
index 528442cfc54..6a05c12fd96 100644
--- a/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc
+++ b/chromium/content/renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc
@@ -37,7 +37,11 @@ class MockWebMediaPlayer : public blink::WebMediaPlayer,
MockWebMediaPlayer() = default;
~MockWebMediaPlayer() override = default;
- void Load(LoadType, const blink::WebMediaPlayerSource&, CORSMode) override {}
+ LoadTiming Load(LoadType,
+ const blink::WebMediaPlayerSource&,
+ CORSMode) override {
+ return LoadTiming::kImmediate;
+ }
void Play() override {}
void Pause() override {}
void Seek(double seconds) override {}
@@ -80,7 +84,7 @@ class MockWebMediaPlayer : public blink::WebMediaPlayer,
size_t AudioDecodedByteCount() const override { return 0; }
size_t VideoDecodedByteCount() const override { return 0; }
- void Paint(blink::WebCanvas* canvas,
+ void Paint(cc::PaintCanvas* canvas,
const blink::WebRect& paint_rectangle,
cc::PaintFlags&,
int already_uploaded_id,
diff --git a/chromium/content/renderer/media_recorder/media_recorder_handler.cc b/chromium/content/renderer/media_recorder/media_recorder_handler.cc
index f8e88b898de..8e5f6b142e2 100644
--- a/chromium/content/renderer/media_recorder/media_recorder_handler.cc
+++ b/chromium/content/renderer/media_recorder/media_recorder_handler.cc
@@ -13,7 +13,6 @@
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/sys_info.h"
-#include "content/child/scoped_web_callbacks.h"
#include "content/renderer/media/stream/media_stream_audio_track.h"
#include "content/renderer/media/stream/media_stream_track.h"
#include "content/renderer/media/webrtc/webrtc_uma_histograms.h"
@@ -27,6 +26,7 @@
#include "media/base/video_frame.h"
#include "media/muxers/webm_muxer.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_configuration.h"
+#include "third_party/blink/public/platform/scoped_web_callbacks.h"
#include "third_party/blink/public/platform/web_media_recorder_handler_client.h"
#include "third_party/blink/public/platform/web_media_stream_source.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -123,8 +123,8 @@ MediaRecorderHandler::MediaRecorderHandler(
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: video_bits_per_second_(0),
audio_bits_per_second_(0),
- video_codec_id_(VideoTrackRecorder::CodecId::VP8),
- audio_codec_id_(AudioTrackRecorder::CodecId::OPUS),
+ video_codec_id_(VideoTrackRecorder::CodecId::LAST),
+ audio_codec_id_(AudioTrackRecorder::CodecId::LAST),
recording_(false),
client_(nullptr),
task_runner_(std::move(task_runner)),
@@ -236,8 +236,8 @@ bool MediaRecorderHandler::Start(int timeslice) {
timeslice_ = TimeDelta::FromMilliseconds(timeslice);
slice_origin_timestamp_ = TimeTicks::Now();
- media_stream_.VideoTracks(video_tracks_);
- media_stream_.AudioTracks(audio_tracks_);
+ video_tracks_ = media_stream_.VideoTracks();
+ audio_tracks_ = media_stream_.AudioTracks();
if (video_tracks_.IsEmpty() && audio_tracks_.IsEmpty()) {
LOG(WARNING) << __func__ << ": no media tracks.";
@@ -350,9 +350,8 @@ void MediaRecorderHandler::EncodingInfo(
DCHECK(configuration.video_configuration ||
configuration.audio_configuration);
- ScopedWebCallbacks<WebMediaCapabilitiesQueryCallbacks> scoped_callbacks =
- make_scoped_web_callbacks(callbacks.release(),
- base::Bind(&OnEncodingInfoError));
+ auto scoped_callbacks = blink::MakeScopedWebCallbacks(
+ std::move(callbacks), base::BindOnce(&OnEncodingInfoError));
std::unique_ptr<blink::WebMediaCapabilitiesInfo> info(
new blink::WebMediaCapabilitiesInfo());
@@ -400,6 +399,72 @@ void MediaRecorderHandler::EncodingInfo(
scoped_callbacks.PassCallbacks()->OnSuccess(std::move(info));
}
+blink::WebString MediaRecorderHandler::ActualMimeType() {
+ DCHECK(main_render_thread_checker_.CalledOnValidThread());
+ DCHECK(client_) << __func__ << " should be called after Initialize()";
+
+ const bool has_video_tracks = !media_stream_.VideoTracks().empty();
+ const bool has_audio_tracks = !media_stream_.AudioTracks().empty();
+ if (!has_video_tracks && !has_audio_tracks)
+ return blink::WebString();
+
+ std::string mime_type;
+ if (!has_video_tracks && has_audio_tracks) {
+ mime_type.append("audio/webm;codecs=");
+ } else {
+ switch (video_codec_id_) {
+ case VideoTrackRecorder::CodecId::VP8:
+ case VideoTrackRecorder::CodecId::VP9:
+ mime_type.append("video/webm;codecs=");
+ break;
+#if BUILDFLAG(RTC_USE_H264)
+ case VideoTrackRecorder::CodecId::H264:
+ mime_type.append("video/x-matroska;codecs=");
+ break;
+#endif
+ case VideoTrackRecorder::CodecId::LAST:
+ // Do nothing.
+ break;
+ }
+ }
+ if (has_video_tracks) {
+ switch (video_codec_id_) {
+ case VideoTrackRecorder::CodecId::VP8:
+ mime_type.append("vp8");
+ break;
+ case VideoTrackRecorder::CodecId::VP9:
+ mime_type.append("vp9");
+ break;
+#if BUILDFLAG(RTC_USE_H264)
+ case VideoTrackRecorder::CodecId::H264:
+ mime_type.append("avc1");
+ break;
+#endif
+ case VideoTrackRecorder::CodecId::LAST:
+ DCHECK_NE(audio_codec_id_, AudioTrackRecorder::CodecId::LAST);
+ }
+ }
+ if (has_video_tracks && has_audio_tracks) {
+ if (video_codec_id_ != VideoTrackRecorder::CodecId::LAST &&
+ audio_codec_id_ != AudioTrackRecorder::CodecId::LAST) {
+ mime_type.append(",");
+ }
+ }
+ if (has_audio_tracks) {
+ switch (audio_codec_id_) {
+ case AudioTrackRecorder::CodecId::OPUS:
+ mime_type.append("opus");
+ break;
+ case AudioTrackRecorder::CodecId::PCM:
+ mime_type.append("pcm");
+ break;
+ case AudioTrackRecorder::CodecId::LAST:
+ DCHECK_NE(video_codec_id_, VideoTrackRecorder::CodecId::LAST);
+ }
+ }
+ return blink::WebString::FromUTF8(mime_type);
+}
+
void MediaRecorderHandler::OnEncodedVideo(
const media::WebmMuxer::VideoParameters& params,
std::unique_ptr<std::string> encoded_data,
@@ -463,8 +528,8 @@ bool MediaRecorderHandler::UpdateTracksAndCheckIfChanged() {
DCHECK(main_render_thread_checker_.CalledOnValidThread());
blink::WebVector<blink::WebMediaStreamTrack> video_tracks, audio_tracks;
- media_stream_.VideoTracks(video_tracks);
- media_stream_.AudioTracks(audio_tracks);
+ video_tracks = media_stream_.VideoTracks();
+ audio_tracks = media_stream_.AudioTracks();
bool video_tracks_changed = video_tracks_.size() != video_tracks.size();
bool audio_tracks_changed = audio_tracks_.size() != audio_tracks.size();
diff --git a/chromium/content/renderer/media_recorder/media_recorder_handler.h b/chromium/content/renderer/media_recorder/media_recorder_handler.h
index bffe011b465..59381c54f30 100644
--- a/chromium/content/renderer/media_recorder/media_recorder_handler.h
+++ b/chromium/content/renderer/media_recorder/media_recorder_handler.h
@@ -67,6 +67,7 @@ class CONTENT_EXPORT MediaRecorderHandler final
void EncodingInfo(
const blink::WebMediaConfiguration& configuration,
std::unique_ptr<blink::WebMediaCapabilitiesQueryCallbacks> cb) override;
+ blink::WebString ActualMimeType() override;
private:
friend class MediaRecorderHandlerTest;
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 82975448f1e..06d61dd66bf 100644
--- a/chromium/content/renderer/media_recorder/media_recorder_handler_unittest.cc
+++ b/chromium/content/renderer/media_recorder/media_recorder_handler_unittest.cc
@@ -65,11 +65,12 @@ static const MediaRecorderTestParams kMediaRecorderTestParams[] = {
{true, false, "video/webm", "vp8", true},
{true, false, "video/webm", "vp9", true},
#if BUILDFLAG(RTC_USE_H264)
- {true, false, "video/webm", "h264", false},
+ {true, false, "video/x-matroska", "avc1", false},
#endif
{false, true, "audio/webm", "opus", true},
{false, true, "audio/webm", "", true}, // Should default to opus.
{false, true, "audio/webm", "pcm", true},
+ {true, true, "video/webm", "vp9,opus", true},
};
class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams>,
@@ -429,6 +430,29 @@ TEST_P(MediaRecorderHandlerTest, WebmMuxerErrorWhileEncoding) {
run_loop.Run();
}
+ // Expect a last call on destruction, with size 0 and |lastInSlice| true.
+ EXPECT_CALL(*this, WriteData(nullptr, 0, true, _)).Times(1);
+ media_recorder_handler_.reset();
+}
+
+// Checks the ActualMimeType() versus the expected.
+TEST_P(MediaRecorderHandlerTest, ActualMimeType) {
+ AddTracks();
+ 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));
+
+ std::string actual_mime_type(GetParam().mime_type);
+ actual_mime_type.append(";codecs=");
+ if (strlen(GetParam().codecs) != 0u)
+ actual_mime_type.append(GetParam().codecs);
+ else if (GetParam().has_video)
+ actual_mime_type.append("vp8");
+ else if (GetParam().has_audio)
+ actual_mime_type.append("opus");
+
+ EXPECT_EQ(media_recorder_handler_->ActualMimeType().Utf8(), actual_mime_type);
// Expect a last call on destruction, with size 0 and |lastInSlice| true.
EXPECT_CALL(*this, WriteData(nullptr, 0, true, _)).Times(1);
diff --git a/chromium/content/renderer/media_recorder/vea_encoder.cc b/chromium/content/renderer/media_recorder/vea_encoder.cc
index 6ace838170a..269eabb0069 100644
--- a/chromium/content/renderer/media_recorder/vea_encoder.cc
+++ b/chromium/content/renderer/media_recorder/vea_encoder.cc
@@ -100,14 +100,14 @@ void VEAEncoder::RequireBitstreamBuffers(unsigned int /*input_count*/,
UseOutputBitstreamBufferId(i);
}
-void VEAEncoder::BitstreamBufferReady(int32_t bitstream_buffer_id,
- size_t payload_size,
- bool keyframe,
- base::TimeDelta timestamp) {
+void VEAEncoder::BitstreamBufferReady(
+ int32_t bitstream_buffer_id,
+ const media::BitstreamBufferMetadata& metadata) {
DVLOG(3) << __func__;
DCHECK(encoding_task_runner_->BelongsToCurrentThread());
- num_frames_after_keyframe_ = keyframe ? 0 : num_frames_after_keyframe_ + 1;
+ num_frames_after_keyframe_ =
+ metadata.key_frame ? 0 : num_frames_after_keyframe_ + 1;
if (num_frames_after_keyframe_ > kMaxKeyframeInterval) {
force_next_frame_to_be_keyframe_ = true;
num_frames_after_keyframe_ = 0;
@@ -116,7 +116,8 @@ void VEAEncoder::BitstreamBufferReady(int32_t bitstream_buffer_id,
base::SharedMemory* output_buffer =
output_buffers_[bitstream_buffer_id].get();
std::unique_ptr<std::string> data(new std::string);
- data->append(reinterpret_cast<char*>(output_buffer->memory()), payload_size);
+ data->append(reinterpret_cast<char*>(output_buffer->memory()),
+ metadata.payload_size_bytes);
const auto front_frame = frames_in_encode_.front();
frames_in_encode_.pop();
@@ -124,7 +125,7 @@ void VEAEncoder::BitstreamBufferReady(int32_t bitstream_buffer_id,
FROM_HERE,
base::BindOnce(OnFrameEncodeCompleted, on_encoded_video_callback_,
front_frame.first, std::move(data), nullptr,
- front_frame.second, keyframe));
+ front_frame.second, metadata.key_frame));
UseOutputBitstreamBufferId(bitstream_buffer_id);
}
diff --git a/chromium/content/renderer/media_recorder/vea_encoder.h b/chromium/content/renderer/media_recorder/vea_encoder.h
index e4b64fa70b7..3d06e593f91 100644
--- a/chromium/content/renderer/media_recorder/vea_encoder.h
+++ b/chromium/content/renderer/media_recorder/vea_encoder.h
@@ -41,10 +41,9 @@ class VEAEncoder final : public VideoTrackRecorder::Encoder,
void RequireBitstreamBuffers(unsigned int input_count,
const gfx::Size& input_coded_size,
size_t output_buffer_size) override;
- void BitstreamBufferReady(int32_t bitstream_buffer_id,
- size_t payload_size,
- bool key_frame,
- base::TimeDelta timestamp) override;
+ void BitstreamBufferReady(
+ int32_t bitstream_buffer_id,
+ const media::BitstreamBufferMetadata& metadata) override;
void NotifyError(media::VideoEncodeAccelerator::Error error) override;
private:
diff --git a/chromium/content/renderer/media_recorder/video_track_recorder.cc b/chromium/content/renderer/media_recorder/video_track_recorder.cc
index c1d672c52d6..c2e59536231 100644
--- a/chromium/content/renderer/media_recorder/video_track_recorder.cc
+++ b/chromium/content/renderer/media_recorder/video_track_recorder.cc
@@ -296,10 +296,10 @@ void VideoTrackRecorder::Encoder::RetrieveFrameOnMainThread(
return;
}
- const uint32 source_pixel_format =
+ const uint32_t source_pixel_format =
(kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR
: libyuv::FOURCC_ARGB;
- if (libyuv::ConvertToI420(static_cast<uint8*>(pixmap.writable_addr()),
+ if (libyuv::ConvertToI420(static_cast<uint8_t*>(pixmap.writable_addr()),
pixmap.computeByteSize(),
frame->visible_data(media::VideoFrame::kYPlane),
frame->stride(media::VideoFrame::kYPlane),
diff --git a/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc b/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
index 8b26b1cf0ce..8e046ca1fd6 100644
--- a/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
+++ b/chromium/content/renderer/mouse_lock_dispatcher_browsertest.cc
@@ -45,7 +45,9 @@ class MouseLockDispatcherTest : public RenderViewTest {
protected:
RenderViewImpl* view() { return static_cast<RenderViewImpl*>(view_); }
RenderWidget* widget() { return view()->GetWidget(); }
- MouseLockDispatcher* dispatcher() { return view()->mouse_lock_dispatcher(); }
+ MouseLockDispatcher* dispatcher() {
+ return widget()->mouse_lock_dispatcher();
+ }
int route_id_;
MockLockTarget* target_;
MockLockTarget* alternate_target_;
diff --git a/chromium/content/renderer/mus/BUILD.gn b/chromium/content/renderer/mus/BUILD.gn
index 718ad1c98d1..3fbd6316fec 100644
--- a/chromium/content/renderer/mus/BUILD.gn
+++ b/chromium/content/renderer/mus/BUILD.gn
@@ -18,13 +18,17 @@ static_library("mus") {
configs += [ "//content:content_implementation" ]
+ public_deps = [
+ "//content/public/common:common_sources",
+ ]
+
deps = [
"//base",
"//cc",
+ "//cc/mojo_embedder",
"//components/viz/client",
"//content/common",
"//content/public/child:child_sources",
- "//content/public/common:common_sources",
"//media/mojo/interfaces:remoting",
"//services/service_manager/public/cpp",
"//services/ui/public/cpp",
diff --git a/chromium/content/renderer/mus/mus_embedded_frame.cc b/chromium/content/renderer/mus/mus_embedded_frame.cc
index 25c6d8d81a8..e0fdd265386 100644
--- a/chromium/content/renderer/mus/mus_embedded_frame.cc
+++ b/chromium/content/renderer/mus/mus_embedded_frame.cc
@@ -9,7 +9,7 @@
#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 "cc/mojo_embedder/async_layer_tree_frame_sink.h"
#include "components/viz/client/hit_test_data_provider.h"
#include "components/viz/client/local_surface_id_provider.h"
#include "content/renderer/mus/renderer_window_tree_client.h"
diff --git a/chromium/content/renderer/mus/renderer_window_tree_client.cc b/chromium/content/renderer/mus/renderer_window_tree_client.cc
index 77db183fc29..ee2d0c21ea8 100644
--- a/chromium/content/renderer/mus/renderer_window_tree_client.cc
+++ b/chromium/content/renderer/mus/renderer_window_tree_client.cc
@@ -6,10 +6,11 @@
#include <map>
+#include "base/bind_helpers.h"
#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 "cc/mojo_embedder/async_layer_tree_frame_sink.h"
#include "components/viz/client/hit_test_data_provider.h"
#include "components/viz/client/hit_test_data_provider_draw_quad.h"
#include "components/viz/client/local_surface_id_provider.h"
@@ -31,7 +32,7 @@ base::LazyInstance<ConnectionMap>::Leaky g_connections =
// static
void RendererWindowTreeClient::CreateIfNecessary(int routing_id) {
- if (!features::IsMashEnabled() || Get(routing_id))
+ if (features::IsAshInBrowserProcess() || Get(routing_id))
return;
RendererWindowTreeClient* connection =
new RendererWindowTreeClient(routing_id);
@@ -90,17 +91,18 @@ void RendererWindowTreeClient::SetVisible(bool visible) {
void RendererWindowTreeClient::RequestLayerTreeFrameSink(
scoped_refptr<viz::ContextProvider> context_provider,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- const LayerTreeFrameSinkCallback& callback) {
+ LayerTreeFrameSinkCallback callback) {
DCHECK(pending_layer_tree_frame_sink_callback_.is_null());
if (tree_) {
RequestLayerTreeFrameSinkInternal(std::move(context_provider),
- gpu_memory_buffer_manager, callback);
+ gpu_memory_buffer_manager,
+ std::move(callback));
return;
}
pending_context_provider_ = std::move(context_provider);
pending_gpu_memory_buffer_manager_ = gpu_memory_buffer_manager;
- pending_layer_tree_frame_sink_callback_ = callback;
+ pending_layer_tree_frame_sink_callback_ = std::move(callback);
}
std::unique_ptr<MusEmbeddedFrame>
@@ -126,14 +128,14 @@ RendererWindowTreeClient::~RendererWindowTreeClient() {
void RendererWindowTreeClient::RequestLayerTreeFrameSinkInternal(
scoped_refptr<viz::ContextProvider> context_provider,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- const LayerTreeFrameSinkCallback& callback) {
+ LayerTreeFrameSinkCallback callback) {
viz::mojom::CompositorFrameSinkPtrInfo sink_info;
viz::mojom::CompositorFrameSinkRequest sink_request =
mojo::MakeRequest(&sink_info);
viz::mojom::CompositorFrameSinkClientPtr client;
viz::mojom::CompositorFrameSinkClientRequest client_request =
mojo::MakeRequest(&client);
- viz::ClientLayerTreeFrameSink::InitParams params;
+ cc::mojo_embedder::AsyncLayerTreeFrameSink::InitParams params;
params.gpu_memory_buffer_manager = gpu_memory_buffer_manager;
params.pipes.compositor_frame_sink_info = std::move(sink_info);
params.pipes.client_request = std::move(client_request);
@@ -145,12 +147,13 @@ void RendererWindowTreeClient::RequestLayerTreeFrameSinkInternal(
std::make_unique<viz::HitTestDataProviderDrawQuad>(
true /* should_ask_for_child_region */);
}
- auto frame_sink = std::make_unique<viz::ClientLayerTreeFrameSink>(
- std::move(context_provider), nullptr /* worker_context_provider */,
- &params);
+ auto frame_sink =
+ std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>(
+ std::move(context_provider), nullptr /* worker_context_provider */,
+ &params);
tree_->AttachCompositorFrameSink(root_window_id_, std::move(sink_request),
std::move(client));
- callback.Run(std::move(frame_sink));
+ std::move(callback).Run(std::move(frame_sink));
}
void RendererWindowTreeClient::OnEmbeddedFrameDestroyed(
@@ -207,9 +210,10 @@ void RendererWindowTreeClient::OnEmbed(
}
if (!pending_layer_tree_frame_sink_callback_.is_null()) {
- RequestLayerTreeFrameSinkInternal(std::move(pending_context_provider_),
- pending_gpu_memory_buffer_manager_,
- pending_layer_tree_frame_sink_callback_);
+ RequestLayerTreeFrameSinkInternal(
+ std::move(pending_context_provider_),
+ pending_gpu_memory_buffer_manager_,
+ std::move(pending_layer_tree_frame_sink_callback_));
pending_context_provider_ = nullptr;
pending_gpu_memory_buffer_manager_ = nullptr;
pending_layer_tree_frame_sink_callback_.Reset();
@@ -233,7 +237,7 @@ void RendererWindowTreeClient::OnFrameSinkIdAllocated(
const viz::FrameSinkId& frame_sink_id) {
// When mus is not hosting viz FrameSinkIds come from the browser, so we
// ignore them here.
- if (!base::FeatureList::IsEnabled(features::kMash))
+ if (features::IsAshInBrowserProcess())
return;
for (MusEmbeddedFrame* embedded_frame : embedded_frames_) {
@@ -334,7 +338,7 @@ void RendererWindowTreeClient::OnWindowCursorChanged(ui::Id window_id,
void RendererWindowTreeClient::OnWindowSurfaceChanged(
ui::Id window_id,
const viz::SurfaceInfo& surface_info) {
- DCHECK(base::FeatureList::IsEnabled(features::kMash));
+ DCHECK(!features::IsAshInBrowserProcess());
for (MusEmbeddedFrame* embedded_frame : embedded_frames_) {
if (embedded_frame->window_id_ == window_id) {
embedded_frame->delegate_->OnMusEmbeddedFrameSurfaceChanged(surface_info);
@@ -389,4 +393,7 @@ void RendererWindowTreeClient::GetWindowManager(
NOTREACHED();
}
+void RendererWindowTreeClient::GetScreenProviderObserver(
+ ui::mojom::ScreenProviderObserverAssociatedRequest observer) {}
+
} // 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 a8e4e5d8368..5309e209efd 100644
--- a/chromium/content/renderer/mus/renderer_window_tree_client.h
+++ b/chromium/content/renderer/mus/renderer_window_tree_client.h
@@ -72,11 +72,11 @@ class RendererWindowTreeClient : public ui::mojom::WindowTreeClient,
void SetVisible(bool visible);
using LayerTreeFrameSinkCallback =
- base::Callback<void(std::unique_ptr<cc::LayerTreeFrameSink>)>;
+ base::OnceCallback<void(std::unique_ptr<cc::LayerTreeFrameSink>)>;
void RequestLayerTreeFrameSink(
scoped_refptr<viz::ContextProvider> context_provider,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- const LayerTreeFrameSinkCallback& callback);
+ LayerTreeFrameSinkCallback callback);
// Creates a new MusEmbeddedFrame. |token| is an UnguessableToken that was
// registered for an embedding with mus (specifically ui::mojom::WindowTree).
@@ -93,7 +93,7 @@ class RendererWindowTreeClient : public ui::mojom::WindowTreeClient,
void RequestLayerTreeFrameSinkInternal(
scoped_refptr<viz::ContextProvider> context_provider,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
- const LayerTreeFrameSinkCallback& callback);
+ LayerTreeFrameSinkCallback callback);
// Called from ~MusEmbeddedFrame to cleanup up internall mapping.
void OnEmbeddedFrameDestroyed(MusEmbeddedFrame* frame);
@@ -210,6 +210,8 @@ class RendererWindowTreeClient : public ui::mojom::WindowTreeClient,
void GetWindowManager(
mojo::AssociatedInterfaceRequest<ui::mojom::WindowManager> internal)
override;
+ void GetScreenProviderObserver(
+ ui::mojom::ScreenProviderObserverAssociatedRequest observer) override;
const int routing_id_;
ui::Id root_window_id_ = 0u;
diff --git a/chromium/content/renderer/navigation_client.cc b/chromium/content/renderer/navigation_client.cc
new file mode 100644
index 00000000000..209968171ba
--- /dev/null
+++ b/chromium/content/renderer/navigation_client.cc
@@ -0,0 +1,75 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/navigation_client.h"
+#include "content/renderer/render_frame_impl.h"
+#include "third_party/blink/public/platform/task_type.h"
+
+namespace content {
+
+NavigationClient::NavigationClient(RenderFrameImpl* render_frame)
+ : navigation_client_binding_(this), render_frame_(render_frame) {}
+
+NavigationClient::~NavigationClient() {}
+
+void NavigationClient::CommitNavigation(
+ const network::ResourceResponseHead& head,
+ const CommonNavigationParams& common_params,
+ const RequestNavigationParams& request_params,
+ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
+ base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>>
+ subresource_overrides,
+ mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
+ network::mojom::URLLoaderFactoryPtr prefetch_loader_factory,
+ const base::UnguessableToken& devtools_navigation_token) {
+ // TODO(ahemery): The reset should be done when the navigation did commit
+ // (meaning at a later stage). This is not currently possible because of
+ // race conditions leading to the early deletion of NavigationRequest would
+ // unexpectedly abort the ongoing navigation. Remove when the races are fixed.
+ ResetDisconnectionHandler();
+ render_frame_->CommitNavigation(
+ head, common_params, request_params,
+ std::move(url_loader_client_endpoints), std::move(subresource_loaders),
+ std::move(subresource_overrides),
+ std::move(controller_service_worker_info),
+ std::move(prefetch_loader_factory), devtools_navigation_token,
+ mojom::FrameNavigationControl::CommitNavigationCallback());
+}
+
+void NavigationClient::CommitFailedNavigation(
+ const CommonNavigationParams& common_params,
+ const RequestNavigationParams& request_params,
+ bool has_stale_copy_in_cache,
+ int error_code,
+ const base::Optional<std::string>& error_page_content,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders) {
+ ResetDisconnectionHandler();
+ render_frame_->CommitFailedNavigation(
+ common_params, request_params, has_stale_copy_in_cache, error_code,
+ error_page_content, std::move(subresource_loaders),
+ mojom::FrameNavigationControl::CommitFailedNavigationCallback());
+}
+
+void NavigationClient::Bind(mojom::NavigationClientAssociatedRequest request) {
+ navigation_client_binding_.Bind(
+ std::move(request),
+ render_frame_->GetTaskRunner(blink::TaskType::kInternalIPC));
+ SetDisconnectionHandler();
+}
+
+void NavigationClient::SetDisconnectionHandler() {
+ navigation_client_binding_.set_connection_error_handler(base::BindOnce(
+ &NavigationClient::OnDroppedNavigation, base::Unretained(this)));
+}
+
+void NavigationClient::ResetDisconnectionHandler() {
+ navigation_client_binding_.set_connection_error_handler(base::DoNothing());
+}
+
+void NavigationClient::OnDroppedNavigation() {
+ render_frame_->OnDroppedNavigation();
+}
+
+} // namespace content
diff --git a/chromium/content/renderer/navigation_client.h b/chromium/content/renderer/navigation_client.h
new file mode 100644
index 00000000000..3f535c5d1e8
--- /dev/null
+++ b/chromium/content/renderer/navigation_client.h
@@ -0,0 +1,56 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_NAVIGATION_CLIENT_H_
+#define CONTENT_RENDERER_NAVIGATION_CLIENT_H_
+
+#include "content/common/navigation_client.mojom.h"
+#include "mojo/public/cpp/bindings/associated_binding.h"
+
+namespace content {
+
+class RenderFrameImpl;
+
+class NavigationClient : mojom::NavigationClient {
+ public:
+ explicit NavigationClient(RenderFrameImpl* render_frame);
+ ~NavigationClient() override;
+
+ // mojom::NavigationClient implementation:
+ void CommitNavigation(
+ const network::ResourceResponseHead& head,
+ const CommonNavigationParams& common_params,
+ const RequestNavigationParams& request_params,
+ network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
+ base::Optional<std::vector<::content::mojom::TransferrableURLLoaderPtr>>
+ subresource_overrides,
+ mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
+ network::mojom::URLLoaderFactoryPtr prefetch_loader_factory,
+ const base::UnguessableToken& devtools_navigation_token) override;
+ void CommitFailedNavigation(
+ const CommonNavigationParams& common_params,
+ const RequestNavigationParams& request_params,
+ bool has_stale_copy_in_cache,
+ int error_code,
+ const base::Optional<std::string>& error_page_content,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders) override;
+
+ void Bind(mojom::NavigationClientAssociatedRequest request);
+
+ private:
+ // OnDroppedNavigation is bound from BeginNavigation till CommitNavigation.
+ // During this period, it is called when the interface pipe is closed from the
+ // browser side, leading to the ongoing navigation cancelation.
+ void OnDroppedNavigation();
+ void SetDisconnectionHandler();
+ void ResetDisconnectionHandler();
+
+ mojo::AssociatedBinding<mojom::NavigationClient> navigation_client_binding_;
+ RenderFrameImpl* render_frame_;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_NAVIGATION_CLIENT_H_
diff --git a/chromium/content/renderer/navigation_state_impl.cc b/chromium/content/renderer/navigation_state_impl.cc
index 597a8ac116c..5b9e23f3d26 100644
--- a/chromium/content/renderer/navigation_state_impl.cc
+++ b/chromium/content/renderer/navigation_state_impl.cc
@@ -7,20 +7,23 @@
namespace content {
NavigationStateImpl::~NavigationStateImpl() {
+ RunCommitNavigationCallback(blink::mojom::CommitResult::Aborted);
}
NavigationStateImpl* NavigationStateImpl::CreateBrowserInitiated(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
- base::TimeTicks time_commit_requested) {
+ base::TimeTicks time_commit_requested,
+ mojom::FrameNavigationControl::CommitNavigationCallback callback) {
return new NavigationStateImpl(common_params, request_params,
- time_commit_requested, false);
+ time_commit_requested, false,
+ std::move(callback));
}
NavigationStateImpl* NavigationStateImpl::CreateContentInitiated() {
- return new NavigationStateImpl(CommonNavigationParams(),
- RequestNavigationParams(), base::TimeTicks(),
- true);
+ return new NavigationStateImpl(
+ CommonNavigationParams(), RequestNavigationParams(), base::TimeTicks(),
+ true, content::mojom::FrameNavigationControl::CommitNavigationCallback());
}
ui::PageTransition NavigationStateImpl::GetTransitionType() {
@@ -35,16 +38,25 @@ bool NavigationStateImpl::IsContentInitiated() {
return is_content_initiated_;
}
+void NavigationStateImpl::RunCommitNavigationCallback(
+ blink::mojom::CommitResult result) {
+ if (commit_callback_)
+ std::move(commit_callback_).Run(result);
+}
+
NavigationStateImpl::NavigationStateImpl(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
base::TimeTicks time_commit_requested,
- bool is_content_initiated)
+ bool is_content_initiated,
+ mojom::FrameNavigationControl::CommitNavigationCallback callback)
: request_committed_(false),
was_within_same_document_(false),
is_content_initiated_(is_content_initiated),
common_params_(common_params),
request_params_(request_params),
- time_commit_requested_(time_commit_requested) {}
+ time_commit_requested_(time_commit_requested),
+ navigation_client_(nullptr),
+ commit_callback_(std::move(callback)) {}
} // namespace content
diff --git a/chromium/content/renderer/navigation_state_impl.h b/chromium/content/renderer/navigation_state_impl.h
index 8f8f83cd5ce..9b3628b9591 100644
--- a/chromium/content/renderer/navigation_state_impl.h
+++ b/chromium/content/renderer/navigation_state_impl.h
@@ -8,8 +8,11 @@
#include <string>
#include "base/macros.h"
+#include "content/common/frame.mojom.h"
#include "content/common/navigation_params.h"
#include "content/public/renderer/navigation_state.h"
+#include "content/renderer/navigation_client.h"
+#include "third_party/blink/public/web/commit_result.mojom.h"
namespace content {
@@ -20,7 +23,8 @@ class CONTENT_EXPORT NavigationStateImpl : public NavigationState {
static NavigationStateImpl* CreateBrowserInitiated(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
- base::TimeTicks time_commit_requested);
+ base::TimeTicks time_commit_requested,
+ mojom::FrameNavigationControl::CommitNavigationCallback callback);
static NavigationStateImpl* CreateContentInitiated();
@@ -47,11 +51,26 @@ class CONTENT_EXPORT NavigationStateImpl : public NavigationState {
return time_commit_requested_;
}
+ // Only used when PerNavigationMojoInterface is enabled.
+ void set_navigation_client(
+ std::unique_ptr<NavigationClient> navigation_client_impl) {
+ navigation_client_ = std::move(navigation_client_impl);
+ }
+
+ void set_navigation_start(const base::TimeTicks& navigation_start) {
+ common_params_.navigation_start = navigation_start;
+ }
+
+ void RunCommitNavigationCallback(blink::mojom::CommitResult result);
+
private:
- NavigationStateImpl(const CommonNavigationParams& common_params,
- const RequestNavigationParams& request_params,
- base::TimeTicks time_commit_requested,
- bool is_content_initiated);
+ NavigationStateImpl(
+ const CommonNavigationParams& common_params,
+ const RequestNavigationParams& request_params,
+ base::TimeTicks time_commit_requested,
+ bool is_content_initiated,
+ content::mojom::FrameNavigationControl::CommitNavigationCallback
+ callback);
bool request_committed_;
bool was_within_same_document_;
@@ -77,6 +96,15 @@ class CONTENT_EXPORT NavigationStateImpl : public NavigationState {
// Time when RenderFrameImpl::CommitNavigation() is called.
base::TimeTicks time_commit_requested_;
+ // The NavigationClient interface gives control over the navigation ongoing in
+ // the browser process.
+ // Only used when PerNavigationMojoInterface is enabled.
+ std::unique_ptr<NavigationClient> navigation_client_;
+
+ // Used to notify whether a commit request from the browser process was
+ // successful or not.
+ mojom::FrameNavigationControl::CommitNavigationCallback commit_callback_;
+
DISALLOW_COPY_AND_ASSIGN(NavigationStateImpl);
};
diff --git a/chromium/content/renderer/p2p/OWNERS b/chromium/content/renderer/p2p/OWNERS
index cff66f72e13..70573c449d9 100644
--- a/chromium/content/renderer/p2p/OWNERS
+++ b/chromium/content/renderer/p2p/OWNERS
@@ -1,5 +1,4 @@
sergeyu@chromium.org
juberti@chromium.org
-deadbeef@chromium.org
# COMPONENT: Blink>WebRTC
diff --git a/chromium/content/renderer/pepper/audio_helper.cc b/chromium/content/renderer/pepper/audio_helper.cc
index fd92532840e..81ed67b2d2b 100644
--- a/chromium/content/renderer/pepper/audio_helper.cc
+++ b/chromium/content/renderer/pepper/audio_helper.cc
@@ -15,7 +15,7 @@ namespace content {
// AudioHelper -----------------------------------------------------------------
-AudioHelper::AudioHelper() : shared_memory_size_for_create_callback_(0) {}
+AudioHelper::AudioHelper() {}
AudioHelper::~AudioHelper() {}
@@ -28,26 +28,22 @@ int32_t AudioHelper::GetSyncSocketImpl(int* sync_socket) {
return PP_ERROR_FAILED;
}
-int32_t AudioHelper::GetSharedMemoryImpl(base::SharedMemory** shm,
- uint32_t* shm_size) {
- if (shared_memory_for_create_callback_) {
- *shm = shared_memory_for_create_callback_.get();
- *shm_size = shared_memory_size_for_create_callback_;
+int32_t AudioHelper::GetSharedMemoryImpl(base::UnsafeSharedMemoryRegion** shm) {
+ if (shared_memory_for_create_callback_.IsValid()) {
+ *shm = &shared_memory_for_create_callback_;
return PP_OK;
}
return PP_ERROR_FAILED;
}
-void AudioHelper::StreamCreated(base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size,
- base::SyncSocket::Handle socket_handle) {
+void AudioHelper::StreamCreated(
+ base::UnsafeSharedMemoryRegion shared_memory_region,
+ base::SyncSocket::Handle socket_handle) {
if (TrackedCallback::IsPending(create_callback_)) {
// Trusted side of proxy can specify a callback to receive handles. In
// this case we don't need to map any data or start the thread since it
// will be handled by the proxy.
- shared_memory_for_create_callback_.reset(
- new base::SharedMemory(shared_memory_handle, false));
- shared_memory_size_for_create_callback_ = shared_memory_size;
+ shared_memory_for_create_callback_ = std::move(shared_memory_region);
socket_for_create_callback_.reset(new base::SyncSocket(socket_handle));
create_callback_->Run(PP_OK);
@@ -60,7 +56,7 @@ void AudioHelper::StreamCreated(base::SharedMemoryHandle shared_memory_handle,
// the I/O thread and back, but this extra complexity doesn't seem worth it
// just to clean up these handles faster.
} else {
- OnSetStreamInfo(shared_memory_handle, shared_memory_size, socket_handle);
+ OnSetStreamInfo(std::move(shared_memory_region), socket_handle);
}
}
diff --git a/chromium/content/renderer/pepper/audio_helper.h b/chromium/content/renderer/pepper/audio_helper.h
index 1d4a543fdb9..d541169a20f 100644
--- a/chromium/content/renderer/pepper/audio_helper.h
+++ b/chromium/content/renderer/pepper/audio_helper.h
@@ -11,7 +11,7 @@
#include <memory>
#include "base/macros.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
#include "base/sync_socket.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/shared_impl/resource.h"
@@ -26,8 +26,7 @@ class AudioHelper {
virtual ~AudioHelper();
// Called when the stream is created.
- void StreamCreated(base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size_,
+ void StreamCreated(base::UnsafeSharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket);
void SetCreateCallback(scoped_refptr<ppapi::TrackedCallback> create_callback);
@@ -37,12 +36,12 @@ class AudioHelper {
// To be called by implementations of |PPB_Audio_API|/|PPB_AudioInput_API|.
int32_t GetSyncSocketImpl(int* sync_socket);
- int32_t GetSharedMemoryImpl(base::SharedMemory** shm, uint32_t* shm_size);
+ int32_t GetSharedMemoryImpl(base::UnsafeSharedMemoryRegion** shm);
// To be implemented by subclasses to call their |SetStreamInfo()|.
- virtual void OnSetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size,
- base::SyncSocket::Handle socket_handle) = 0;
+ virtual void OnSetStreamInfo(
+ base::UnsafeSharedMemoryRegion shared_memory_region,
+ base::SyncSocket::Handle socket_handle) = 0;
private:
scoped_refptr<ppapi::TrackedCallback> create_callback_;
@@ -51,8 +50,7 @@ class AudioHelper {
// querying from the callback. The proxy uses this to get the handles to the
// other process instead of mapping them in the renderer. These will be
// invalid all other times.
- std::unique_ptr<base::SharedMemory> shared_memory_for_create_callback_;
- size_t shared_memory_size_for_create_callback_;
+ base::UnsafeSharedMemoryRegion shared_memory_for_create_callback_;
std::unique_ptr<base::SyncSocket> socket_for_create_callback_;
DISALLOW_COPY_AND_ASSIGN(AudioHelper);
diff --git a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc
index ad9a0df001e..80e59655486 100644
--- a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc
+++ b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc
@@ -85,6 +85,20 @@ MockRendererPpapiHost::ShareSharedMemoryHandleWithRemote(
return base::SharedMemoryHandle();
}
+base::UnsafeSharedMemoryRegion
+MockRendererPpapiHost::ShareUnsafeSharedMemoryRegionWithRemote(
+ const base::UnsafeSharedMemoryRegion& region) {
+ NOTIMPLEMENTED();
+ return base::UnsafeSharedMemoryRegion();
+}
+
+base::ReadOnlySharedMemoryRegion
+MockRendererPpapiHost::ShareReadOnlySharedMemoryRegionWithRemote(
+ const base::ReadOnlySharedMemoryRegion& region) {
+ NOTIMPLEMENTED();
+ return base::ReadOnlySharedMemoryRegion();
+}
+
bool MockRendererPpapiHost::IsRunningInProcess() const { return false; }
std::string MockRendererPpapiHost::GetPluginName() const {
diff --git a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h
index 375c2127a3f..fedbf7c9e86 100644
--- a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h
+++ b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h
@@ -48,6 +48,10 @@ class MockRendererPpapiHost : public RendererPpapiHost {
bool should_close_source) override;
base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
const base::SharedMemoryHandle& handle) override;
+ base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+ const base::UnsafeSharedMemoryRegion& region) override;
+ base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+ const base::ReadOnlySharedMemoryRegion& region) override;
bool IsRunningInProcess() const override;
std::string GetPluginName() const override;
void SetToExternalPluginHost() override;
diff --git a/chromium/content/renderer/pepper/pepper_audio_input_host.cc b/chromium/content/renderer/pepper/pepper_audio_input_host.cc
index a722013fb17..08f47d7ce5d 100644
--- a/chromium/content/renderer/pepper/pepper_audio_input_host.cc
+++ b/chromium/content/renderer/pepper/pepper_audio_input_host.cc
@@ -52,14 +52,13 @@ int32_t PepperAudioInputHost::OnResourceMessageReceived(
}
void PepperAudioInputHost::StreamCreated(
- base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size,
+ base::ReadOnlySharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket) {
- OnOpenComplete(PP_OK, shared_memory_handle, shared_memory_size, socket);
+ OnOpenComplete(PP_OK, std::move(shared_memory_region), socket);
}
void PepperAudioInputHost::StreamCreationFailed() {
- OnOpenComplete(PP_ERROR_FAILED, base::SharedMemoryHandle(), 0,
+ OnOpenComplete(PP_ERROR_FAILED, base::ReadOnlySharedMemoryRegion(),
base::SyncSocket::kInvalidHandle);
}
@@ -113,12 +112,10 @@ int32_t PepperAudioInputHost::OnClose(
void PepperAudioInputHost::OnOpenComplete(
int32_t result,
- base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size,
+ base::ReadOnlySharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket_handle) {
// Make sure the handles are cleaned up.
base::SyncSocket scoped_socket(socket_handle);
- base::SharedMemory scoped_shared_memory(shared_memory_handle, false);
if (!open_context_.is_valid()) {
NOTREACHED();
@@ -128,17 +125,19 @@ void PepperAudioInputHost::OnOpenComplete(
ppapi::proxy::SerializedHandle serialized_socket_handle(
ppapi::proxy::SerializedHandle::SOCKET);
ppapi::proxy::SerializedHandle serialized_shared_memory_handle(
- ppapi::proxy::SerializedHandle::SHARED_MEMORY);
+ ppapi::proxy::SerializedHandle::SHARED_MEMORY_REGION);
if (result == PP_OK) {
IPC::PlatformFileForTransit temp_socket =
IPC::InvalidPlatformFileForTransit();
- base::SharedMemoryHandle temp_shmem;
- result = GetRemoteHandles(
- scoped_socket, scoped_shared_memory, &temp_socket, &temp_shmem);
+ base::ReadOnlySharedMemoryRegion temp_shmem;
+ result = GetRemoteHandles(scoped_socket, shared_memory_region, &temp_socket,
+ &temp_shmem);
serialized_socket_handle.set_socket(temp_socket);
- serialized_shared_memory_handle.set_shmem(temp_shmem, shared_memory_size);
+ serialized_shared_memory_handle.set_shmem_region(
+ base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
+ std::move(temp_shmem)));
}
// Send all the values, even on error. This simplifies some of our cleanup
@@ -146,25 +145,25 @@ void PepperAudioInputHost::OnOpenComplete(
// inconvenient to clean up. Our IPC code will automatically handle this for
// us, as long as the remote side always closes the handles it receives, even
// in the failure case.
- open_context_.params.AppendHandle(serialized_socket_handle);
- open_context_.params.AppendHandle(serialized_shared_memory_handle);
+ open_context_.params.AppendHandle(std::move(serialized_socket_handle));
+ open_context_.params.AppendHandle(std::move(serialized_shared_memory_handle));
SendOpenReply(result);
}
int32_t PepperAudioInputHost::GetRemoteHandles(
const base::SyncSocket& socket,
- const base::SharedMemory& shared_memory,
+ const base::ReadOnlySharedMemoryRegion& shared_memory_region,
IPC::PlatformFileForTransit* remote_socket_handle,
- base::SharedMemoryHandle* remote_shared_memory_handle) {
+ base::ReadOnlySharedMemoryRegion* remote_shared_memory_region) {
*remote_socket_handle =
renderer_ppapi_host_->ShareHandleWithRemote(socket.handle(), false);
if (*remote_socket_handle == IPC::InvalidPlatformFileForTransit())
return PP_ERROR_FAILED;
- *remote_shared_memory_handle =
- renderer_ppapi_host_->ShareSharedMemoryHandleWithRemote(
- shared_memory.handle());
- if (!base::SharedMemory::IsHandleValid(*remote_shared_memory_handle))
+ *remote_shared_memory_region =
+ renderer_ppapi_host_->ShareReadOnlySharedMemoryRegionWithRemote(
+ shared_memory_region);
+ if (!remote_shared_memory_region->IsValid())
return PP_ERROR_FAILED;
return PP_OK;
diff --git a/chromium/content/renderer/pepper/pepper_audio_input_host.h b/chromium/content/renderer/pepper/pepper_audio_input_host.h
index 084ce33ea67..366d94a1b07 100644
--- a/chromium/content/renderer/pepper/pepper_audio_input_host.h
+++ b/chromium/content/renderer/pepper/pepper_audio_input_host.h
@@ -13,7 +13,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/read_only_shared_memory_region.h"
#include "base/sync_socket.h"
#include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
#include "ipc/ipc_platform_file.h"
@@ -37,8 +37,7 @@ class PepperAudioInputHost : public ppapi::host::ResourceHost {
ppapi::host::HostMessageContext* context) override;
// Called when the stream is created.
- void StreamCreated(base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size,
+ void StreamCreated(base::ReadOnlySharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket);
void StreamCreationFailed();
@@ -51,15 +50,14 @@ class PepperAudioInputHost : public ppapi::host::ResourceHost {
int32_t OnClose(ppapi::host::HostMessageContext* context);
void OnOpenComplete(int32_t result,
- base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size,
+ base::ReadOnlySharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket_handle);
int32_t GetRemoteHandles(
const base::SyncSocket& socket,
- const base::SharedMemory& shared_memory,
+ const base::ReadOnlySharedMemoryRegion& shared_memory_region,
IPC::PlatformFileForTransit* remote_socket_handle,
- base::SharedMemoryHandle* remote_shared_memory_handle);
+ base::ReadOnlySharedMemoryRegion* remote_shared_memory_region);
void Close();
diff --git a/chromium/content/renderer/pepper/pepper_audio_output_host.cc b/chromium/content/renderer/pepper/pepper_audio_output_host.cc
index 9322bd0cc5f..49a4bb62c54 100644
--- a/chromium/content/renderer/pepper/pepper_audio_output_host.cc
+++ b/chromium/content/renderer/pepper/pepper_audio_output_host.cc
@@ -71,14 +71,13 @@ int32_t PepperAudioOutputHost::OnResourceMessageReceived(
}
void PepperAudioOutputHost::StreamCreated(
- base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size,
+ base::UnsafeSharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket) {
- OnOpenComplete(PP_OK, shared_memory_handle, shared_memory_size, socket);
+ OnOpenComplete(PP_OK, std::move(shared_memory_region), socket);
}
void PepperAudioOutputHost::StreamCreationFailed() {
- OnOpenComplete(PP_ERROR_FAILED, base::SharedMemoryHandle(), 0,
+ OnOpenComplete(PP_ERROR_FAILED, base::UnsafeSharedMemoryRegion(),
base::SyncSocket::kInvalidHandle);
}
@@ -150,12 +149,10 @@ int32_t PepperAudioOutputHost::OnClose(
void PepperAudioOutputHost::OnOpenComplete(
int32_t result,
- base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size,
+ base::UnsafeSharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket_handle) {
// Make sure the handles are cleaned up.
base::SyncSocket scoped_socket(socket_handle);
- base::SharedMemory scoped_shared_memory(shared_memory_handle, false);
if (!open_context_.is_valid()) {
NOTREACHED();
@@ -165,17 +162,19 @@ void PepperAudioOutputHost::OnOpenComplete(
ppapi::proxy::SerializedHandle serialized_socket_handle(
ppapi::proxy::SerializedHandle::SOCKET);
ppapi::proxy::SerializedHandle serialized_shared_memory_handle(
- ppapi::proxy::SerializedHandle::SHARED_MEMORY);
+ ppapi::proxy::SerializedHandle::SHARED_MEMORY_REGION);
if (result == PP_OK) {
IPC::PlatformFileForTransit temp_socket =
IPC::InvalidPlatformFileForTransit();
- base::SharedMemoryHandle temp_shmem;
- result = GetRemoteHandles(scoped_socket, scoped_shared_memory, &temp_socket,
+ base::UnsafeSharedMemoryRegion temp_shmem;
+ result = GetRemoteHandles(scoped_socket, shared_memory_region, &temp_socket,
&temp_shmem);
serialized_socket_handle.set_socket(temp_socket);
- serialized_shared_memory_handle.set_shmem(temp_shmem, shared_memory_size);
+ serialized_shared_memory_handle.set_shmem_region(
+ base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
+ std::move(temp_shmem)));
}
// Send all the values, even on error. This simplifies some of our cleanup
@@ -183,25 +182,25 @@ void PepperAudioOutputHost::OnOpenComplete(
// inconvenient to clean up. Our IPC code will automatically handle this for
// us, as long as the remote side always closes the handles it receives, even
// in the failure case.
- open_context_.params.AppendHandle(serialized_socket_handle);
- open_context_.params.AppendHandle(serialized_shared_memory_handle);
+ open_context_.params.AppendHandle(std::move(serialized_socket_handle));
+ open_context_.params.AppendHandle(std::move(serialized_shared_memory_handle));
SendOpenReply(result);
}
int32_t PepperAudioOutputHost::GetRemoteHandles(
const base::SyncSocket& socket,
- const base::SharedMemory& shared_memory,
+ const base::UnsafeSharedMemoryRegion& shared_memory_region,
IPC::PlatformFileForTransit* remote_socket_handle,
- base::SharedMemoryHandle* remote_shared_memory_handle) {
+ base::UnsafeSharedMemoryRegion* remote_shared_memory_region) {
*remote_socket_handle =
renderer_ppapi_host_->ShareHandleWithRemote(socket.handle(), false);
if (*remote_socket_handle == IPC::InvalidPlatformFileForTransit())
return PP_ERROR_FAILED;
- *remote_shared_memory_handle =
- renderer_ppapi_host_->ShareSharedMemoryHandleWithRemote(
- shared_memory.handle());
- if (!base::SharedMemory::IsHandleValid(*remote_shared_memory_handle))
+ *remote_shared_memory_region =
+ renderer_ppapi_host_->ShareUnsafeSharedMemoryRegionWithRemote(
+ shared_memory_region);
+ if (!remote_shared_memory_region->IsValid())
return PP_ERROR_FAILED;
return PP_OK;
diff --git a/chromium/content/renderer/pepper/pepper_audio_output_host.h b/chromium/content/renderer/pepper/pepper_audio_output_host.h
index e8ea573ffa7..ea2602ad24a 100644
--- a/chromium/content/renderer/pepper/pepper_audio_output_host.h
+++ b/chromium/content/renderer/pepper/pepper_audio_output_host.h
@@ -13,7 +13,7 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
#include "base/sync_socket.h"
#include "content/public/renderer/plugin_instance_throttler.h"
#include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
@@ -39,8 +39,7 @@ class PepperAudioOutputHost : public ppapi::host::ResourceHost,
ppapi::host::HostMessageContext* context) override;
// Called when the stream is created.
- void StreamCreated(base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size,
+ void StreamCreated(base::UnsafeSharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket);
void StreamCreationFailed();
void SetVolume(double volume);
@@ -55,15 +54,14 @@ class PepperAudioOutputHost : public ppapi::host::ResourceHost,
int32_t OnClose(ppapi::host::HostMessageContext* context);
void OnOpenComplete(int32_t result,
- base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size,
+ base::UnsafeSharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket_handle);
int32_t GetRemoteHandles(
const base::SyncSocket& socket,
- const base::SharedMemory& shared_memory,
+ const base::UnsafeSharedMemoryRegion& shared_memory_region,
IPC::PlatformFileForTransit* remote_socket_handle,
- base::SharedMemoryHandle* remote_shared_memory_handle);
+ base::UnsafeSharedMemoryRegion* remote_shared_memory_region);
void Close();
diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc b/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc
index b5c5bc9d90a..5110e1478a8 100644
--- a/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc
+++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc
@@ -19,9 +19,9 @@
#include "cc/paint/paint_flags.h"
#include "cc/resources/cross_thread_shared_bitmap.h"
#include "components/viz/common/gpu/context_provider.h"
-#include "components/viz/common/quads/shared_bitmap.h"
#include "components/viz/common/resources/bitmap_allocation.h"
#include "components/viz/common/resources/resource_sizes.h"
+#include "components/viz/common/resources/shared_bitmap.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/renderer_ppapi_host.h"
#include "content/renderer/pepper/gfx_conversion.h"
@@ -338,7 +338,7 @@ bool PepperGraphics2DHost::BindToInstance(
// The |backing_bitmap| must be clipped to the |plugin_rect| to avoid painting
// outside the plugin area. This can happen if the plugin has been resized since
// PaintImageData verified the image is within the plugin size.
-void PepperGraphics2DHost::Paint(blink::WebCanvas* canvas,
+void PepperGraphics2DHost::Paint(cc::PaintCanvas* canvas,
const gfx::Rect& plugin_rect,
const gfx::Rect& paint_rect) {
TRACE_EVENT0("pepper", "PepperGraphics2DHost::Paint");
@@ -387,8 +387,10 @@ void PepperGraphics2DHost::Paint(blink::WebCanvas* canvas,
canvas->scale(scale_, scale_);
pixel_origin.scale(1.0f / scale_);
}
- canvas->drawBitmap(backing_bitmap, pixel_origin.x(), pixel_origin.y(),
- &flags);
+ // TODO(khushalsagar): Can this be cached on image_data_, and invalidated when
+ // the bitmap changes?
+ canvas->drawImage(cc::PaintImage::CreateFromBitmap(std::move(backing_bitmap)),
+ pixel_origin.x(), pixel_origin.y(), &flags);
}
void PepperGraphics2DHost::ViewInitiatedPaint() {
@@ -713,7 +715,6 @@ bool PepperGraphics2DHost::PrepareTransferableResource(
0, format, GL_UNSIGNED_BYTE, nullptr);
}
- gl->GenMailboxCHROMIUM(gpu_mailbox.name);
gl->ProduceTextureDirectCHROMIUM(texture_id, gpu_mailbox.name);
}
diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host.h b/chromium/content/renderer/pepper/pepper_graphics_2d_host.h
index 069a60c5a94..4c93d109936 100644
--- a/chromium/content/renderer/pepper/pepper_graphics_2d_host.h
+++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host.h
@@ -12,13 +12,13 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "cc/paint/paint_canvas.h"
#include "cc/resources/shared_bitmap_id_registrar.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"
-#include "third_party/blink/public/platform/web_canvas.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/size.h"
@@ -74,7 +74,7 @@ class CONTENT_EXPORT PepperGraphics2DHost
// is already bound to a different instance, and nothing will happen.
bool BindToInstance(PepperPluginInstanceImpl* new_instance);
// Paints the current backing store to the web page.
- void Paint(blink::WebCanvas* canvas,
+ void Paint(cc::PaintCanvas* canvas,
const gfx::Rect& plugin_rect,
const gfx::Rect& paint_rect);
diff --git a/chromium/content/renderer/pepper/pepper_media_stream_track_host_base.cc b/chromium/content/renderer/pepper/pepper_media_stream_track_host_base.cc
index 947f8468b3a..a4304ad66a0 100644
--- a/chromium/content/renderer/pepper/pepper_media_stream_track_host_base.cc
+++ b/chromium/content/renderer/pepper/pepper_media_stream_track_host_base.cc
@@ -67,13 +67,13 @@ bool PepperMediaStreamTrackHostBase::InitBuffers(int32_t number_of_buffers,
SerializedHandle handle(host_->ShareSharedMemoryHandleWithRemote(shm_handle),
size.ValueOrDie());
bool readonly = (track_type == kRead);
+ std::vector<SerializedHandle> handles;
+ handles.push_back(std::move(handle));
host()->SendUnsolicitedReplyWithHandles(
pp_resource(),
PpapiPluginMsg_MediaStreamTrack_InitBuffers(
- number_of_buffers,
- buffer_size_aligned.ValueOrDie(),
- readonly),
- std::vector<SerializedHandle>(1, handle));
+ number_of_buffers, buffer_size_aligned.ValueOrDie(), readonly),
+ &handles);
return true;
}
diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_input.cc b/chromium/content/renderer/pepper/pepper_platform_audio_input.cc
index 1d8fb3ff295..97629b7c3c7 100644
--- a/chromium/content/renderer/pepper/pepper_platform_audio_input.cc
+++ b/chromium/content/renderer/pepper/pepper_platform_audio_input.cc
@@ -11,7 +11,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/child/child_process.h"
-#include "content/renderer/media/audio_input_ipc_factory.h"
+#include "content/renderer/media/audio/audio_input_ipc_factory.h"
#include "content/renderer/pepper/pepper_audio_input_host.h"
#include "content/renderer/pepper/pepper_media_device_manager.h"
#include "content/renderer/render_frame_impl.h"
@@ -76,34 +76,32 @@ void PepperPlatformAudioInput::ShutDown() {
}
void PepperPlatformAudioInput::OnStreamCreated(
- base::SharedMemoryHandle handle,
+ base::ReadOnlySharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket_handle,
bool initially_muted) {
+ DCHECK(shared_memory_region.IsValid());
#if defined(OS_WIN)
- DCHECK(handle.IsValid());
DCHECK(socket_handle);
#else
- DCHECK(base::SharedMemory::IsHandleValid(handle));
DCHECK_NE(-1, socket_handle);
#endif
- DCHECK(handle.GetSize());
+ DCHECK_GT(shared_memory_region.GetSize(), 0u);
if (base::ThreadTaskRunnerHandle::Get().get() != main_task_runner_.get()) {
// If shutdown has occurred, |client_| will be NULL and the handles will be
// cleaned up on the main thread.
main_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&PepperPlatformAudioInput::OnStreamCreated, this, handle,
- socket_handle, initially_muted));
+ FROM_HERE, base::BindOnce(&PepperPlatformAudioInput::OnStreamCreated,
+ this, std::move(shared_memory_region),
+ socket_handle, initially_muted));
} else {
// Must dereference the client only on the main thread. Shutdown may have
// occurred while the request was in-flight, so we need to NULL check.
if (client_) {
- client_->StreamCreated(handle, handle.GetSize(), socket_handle);
+ client_->StreamCreated(std::move(shared_memory_region), socket_handle);
} else {
- // Clean up the handles.
+ // Clean up the handle.
base::SyncSocket temp_socket(socket_handle);
- base::SharedMemory temp_shared_memory(handle, false);
}
}
}
diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_input.h b/chromium/content/renderer/pepper/pepper_platform_audio_input.h
index d7f69bbd6f0..0d83fb4355e 100644
--- a/chromium/content/renderer/pepper/pepper_platform_audio_input.h
+++ b/chromium/content/renderer/pepper/pepper_platform_audio_input.h
@@ -55,7 +55,7 @@ class PepperPlatformAudioInput
void ShutDown();
// media::AudioInputIPCDelegate.
- void OnStreamCreated(base::SharedMemoryHandle handle,
+ void OnStreamCreated(base::ReadOnlySharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket_handle,
bool initially_muted) override;
void OnError() override;
diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_output.cc b/chromium/content/renderer/pepper/pepper_platform_audio_output.cc
index 267fe95c276..fcc69c75eae 100644
--- a/chromium/content/renderer/pepper/pepper_platform_audio_output.cc
+++ b/chromium/content/renderer/pepper/pepper_platform_audio_output.cc
@@ -11,7 +11,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "content/child/child_process.h"
-#include "content/renderer/media/audio_output_ipc_factory.h"
+#include "content/renderer/media/audio/audio_output_ipc_factory.h"
#include "content/renderer/pepper/audio_helper.h"
#include "ppapi/shared_impl/ppb_audio_config_shared.h"
@@ -89,27 +89,27 @@ void PepperPlatformAudioOutput::OnDeviceAuthorized(
}
void PepperPlatformAudioOutput::OnStreamCreated(
- base::SharedMemoryHandle handle,
+ base::UnsafeSharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket_handle,
bool playing_automatically) {
- DCHECK(handle.IsValid());
+ DCHECK(shared_memory_region.IsValid());
#if defined(OS_WIN)
DCHECK(socket_handle);
#else
DCHECK_NE(-1, socket_handle);
#endif
- DCHECK(handle.GetSize());
+ DCHECK_GT(shared_memory_region.GetSize(), 0u);
if (base::ThreadTaskRunnerHandle::Get().get() == main_task_runner_.get()) {
// Must dereference the client only on the main thread. Shutdown may have
// occurred while the request was in-flight, so we need to NULL check.
if (client_)
- client_->StreamCreated(handle, handle.GetSize(), socket_handle);
+ client_->StreamCreated(std::move(shared_memory_region), socket_handle);
} else {
main_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&PepperPlatformAudioOutput::OnStreamCreated, this,
- handle, socket_handle, playing_automatically));
+ FROM_HERE, base::BindOnce(&PepperPlatformAudioOutput::OnStreamCreated,
+ this, std::move(shared_memory_region),
+ socket_handle, playing_automatically));
}
}
diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_output.h b/chromium/content/renderer/pepper/pepper_platform_audio_output.h
index 43be22d0076..fb0559ddb51 100644
--- a/chromium/content/renderer/pepper/pepper_platform_audio_output.h
+++ b/chromium/content/renderer/pepper/pepper_platform_audio_output.h
@@ -57,7 +57,7 @@ class PepperPlatformAudioOutput
void OnDeviceAuthorized(media::OutputDeviceStatus device_status,
const media::AudioParameters& output_params,
const std::string& matched_device_id) override;
- void OnStreamCreated(base::SharedMemoryHandle handle,
+ void OnStreamCreated(base::UnsafeSharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket_handle,
bool playing_automatically) override;
void OnIPCClosed() override;
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 c4f75ab84a7..7c7f53aab6e 100644
--- a/chromium/content/renderer/pepper/pepper_platform_audio_output_dev.cc
+++ b/chromium/content/renderer/pepper/pepper_platform_audio_output_dev.cc
@@ -14,7 +14,7 @@
#include "build/build_config.h"
#include "content/child/child_process.h"
#include "content/common/content_constants_internal.h"
-#include "content/renderer/media/audio_output_ipc_factory.h"
+#include "content/renderer/media/audio/audio_output_ipc_factory.h"
#include "content/renderer/pepper/audio_helper.h"
#include "content/renderer/pepper/pepper_audio_output_host.h"
#include "content/renderer/pepper/pepper_media_device_manager.h"
@@ -180,22 +180,22 @@ void PepperPlatformAudioOutputDev::OnDeviceAuthorized(
}
void PepperPlatformAudioOutputDev::OnStreamCreated(
- base::SharedMemoryHandle handle,
+ base::UnsafeSharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket_handle,
bool playing_automatically) {
- DCHECK(handle.IsValid());
+ DCHECK(shared_memory_region.IsValid());
#if defined(OS_WIN)
DCHECK(socket_handle);
#else
DCHECK_NE(-1, socket_handle);
#endif
- DCHECK(handle.GetSize());
+ DCHECK_GT(shared_memory_region.GetSize(), 0u);
if (base::ThreadTaskRunnerHandle::Get().get() == main_task_runner_.get()) {
// Must dereference the client only on the main thread. Shutdown may have
// occurred while the request was in-flight, so we need to NULL check.
if (client_)
- client_->StreamCreated(handle, handle.GetSize(), socket_handle);
+ client_->StreamCreated(std::move(shared_memory_region), socket_handle);
} else {
DCHECK(io_task_runner_->BelongsToCurrentThread());
if (state_ != CREATING_STREAM)
@@ -208,7 +208,8 @@ void PepperPlatformAudioOutputDev::OnStreamCreated(
main_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&PepperPlatformAudioOutputDev::OnStreamCreated, this,
- handle, socket_handle, playing_automatically));
+ std::move(shared_memory_region), socket_handle,
+ playing_automatically));
}
}
diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_output_dev.h b/chromium/content/renderer/pepper/pepper_platform_audio_output_dev.h
index 71ca14500f7..dbb23a45feb 100644
--- a/chromium/content/renderer/pepper/pepper_platform_audio_output_dev.h
+++ b/chromium/content/renderer/pepper/pepper_platform_audio_output_dev.h
@@ -62,7 +62,7 @@ class PepperPlatformAudioOutputDev
void OnDeviceAuthorized(media::OutputDeviceStatus device_status,
const media::AudioParameters& output_params,
const std::string& matched_device_id) override;
- void OnStreamCreated(base::SharedMemoryHandle handle,
+ void OnStreamCreated(base::UnsafeSharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket_handle,
bool playing_automatically) override;
void OnIPCClosed() override;
diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 931e2e7408a..8e7653afc9d 100644
--- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -27,7 +27,7 @@
#include "content/common/frame_messages.h"
#include "content/public/common/content_constants.h"
#include "content/public/renderer/content_renderer_client.h"
-#include "content/renderer/media/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
#include "content/renderer/pepper/event_conversion.h"
#include "content/renderer/pepper/fullscreen_container.h"
#include "content/renderer/pepper/gfx_conversion.h"
@@ -168,7 +168,6 @@ using ppapi::thunk::PPB_ImageData_API;
using ppapi::Var;
using ppapi::ArrayBufferVar;
using ppapi::ViewData;
-using blink::WebCanvas;
using blink::WebCursorInfo;
using blink::WebDocument;
using blink::WebElement;
@@ -537,7 +536,6 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl(
flash_fullscreen_(false),
desired_fullscreen_state_(false),
message_channel_(nullptr),
- sad_plugin_(nullptr),
input_event_mask_(0),
filtered_input_event_mask_(0),
text_input_type_(kPluginDefaultTextInputType),
@@ -710,16 +708,21 @@ void PepperPluginInstanceImpl::Delete() {
bool PepperPluginInstanceImpl::is_deleted() const { return is_deleted_; }
-void PepperPluginInstanceImpl::Paint(WebCanvas* canvas,
+void PepperPluginInstanceImpl::Paint(cc::PaintCanvas* canvas,
const gfx::Rect& plugin_rect,
const gfx::Rect& paint_rect) {
TRACE_EVENT0("ppapi", "PluginInstance::Paint");
if (module()->is_crashed()) {
// Crashed plugin painting.
- if (!sad_plugin_) // Lazily initialize bitmap.
- sad_plugin_ = GetContentClient()->renderer()->GetSadPluginBitmap();
- if (sad_plugin_)
- PaintSadPlugin(canvas, plugin_rect, *sad_plugin_);
+ if (!sad_plugin_image_) { // Lazily initialize bitmap.
+ if (SkBitmap* bitmap =
+ GetContentClient()->renderer()->GetSadPluginBitmap()) {
+ DCHECK(bitmap->isImmutable());
+ sad_plugin_image_ = cc::PaintImage::CreateFromBitmap(*bitmap);
+ }
+ }
+ if (sad_plugin_image_)
+ PaintSadPlugin(canvas, plugin_rect, sad_plugin_image_);
return;
}
@@ -914,7 +917,7 @@ bool PepperPluginInstanceImpl::HandleDocumentLoad(
return true;
}
- if (module()->is_crashed()) {
+ if (module()->is_crashed() || !render_frame_) {
// Don't create a resource for a crashed plugin.
container()->GetDocument().GetFrame()->StopLoading();
return false;
@@ -939,14 +942,13 @@ bool PepperPluginInstanceImpl::HandleDocumentLoad(
std::unique_ptr<ppapi::host::ResourceHost>(std::move(loader_host)));
DCHECK(pending_host_id);
- DataFromWebURLResponse(
- host_impl,
- pp_instance(),
- response,
- base::Bind(&PepperPluginInstanceImpl::DidDataFromWebURLResponse,
- weak_factory_.GetWeakPtr(),
- response,
- pending_host_id));
+ render_frame()
+ ->GetTaskRunner(blink::TaskType::kInternalLoading)
+ ->PostTask(
+ FROM_HERE,
+ base::BindOnce(&PepperPluginInstanceImpl::DidDataFromWebURLResponse,
+ weak_factory_.GetWeakPtr(), response, pending_host_id,
+ DataFromWebURLResponse(response)));
// If the load was not abandoned, document_loader_ will now be set. It's
// possible that the load was canceled by now and document_loader_ was
@@ -1979,7 +1981,7 @@ int PepperPluginInstanceImpl::PrintBegin(const WebPrintParams& print_params) {
if (LoadPdfInterface()) {
PP_PdfPrintSettings_Dev pdf_print_settings;
- pdf_print_settings.num_pages_per_sheet = print_params.num_pages_per_sheet;
+ pdf_print_settings.pages_per_sheet = print_params.pages_per_sheet;
pdf_print_settings.scale_factor = print_params.scale_factor;
num_pages = plugin_pdf_interface_->PrintBegin(
@@ -1998,7 +2000,7 @@ int PepperPluginInstanceImpl::PrintBegin(const WebPrintParams& print_params) {
}
void PepperPluginInstanceImpl::PrintPage(int page_number,
- blink::WebCanvas* canvas) {
+ cc::PaintCanvas* canvas) {
#if BUILDFLAG(ENABLE_PRINTING)
DCHECK(plugin_print_interface_);
@@ -2815,7 +2817,7 @@ PP_Bool PepperPluginInstanceImpl::SetCursor(PP_Instance instance,
SkBitmap bitmap(image_data->GetMappedBitmap());
// Make a deep copy, so that the cursor remains valid even after the original
// image data gets freed.
- SkBitmap& dst = custom_cursor->custom_image.GetSkBitmap();
+ SkBitmap& dst = custom_cursor->custom_image;
if (!dst.tryAllocPixels(bitmap.info()) ||
!bitmap.readPixels(dst.info(), dst.getPixels(), dst.rowBytes(), 0, 0)) {
return PP_FALSE;
@@ -3376,7 +3378,7 @@ MouseLockDispatcher* PepperPluginInstanceImpl::GetMouseLockDispatcher() {
return container->mouse_lock_dispatcher();
}
if (render_frame_)
- return render_frame_->render_view()->mouse_lock_dispatcher();
+ return render_frame_->render_view()->GetWidget()->mouse_lock_dispatcher();
return nullptr;
}
diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h
index 6d554119935..757177607ca 100644
--- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h
+++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -26,6 +26,7 @@
#include "cc/layers/content_layer_client.h"
#include "cc/layers/layer.h"
#include "cc/layers/texture_layer_client.h"
+#include "cc/paint/paint_canvas.h"
#include "components/viz/common/resources/transferable_resource.h"
#include "content/common/content_export.h"
#include "content/public/renderer/pepper_plugin_instance.h"
@@ -56,7 +57,6 @@
#include "ppapi/shared_impl/tracked_callback.h"
#include "ppapi/thunk/ppb_gamepad_api.h"
#include "ppapi/thunk/resource_creation_api.h"
-#include "third_party/blink/public/platform/web_canvas.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/public/web/web_associated_url_loader_client.h"
@@ -69,8 +69,6 @@
struct PP_Point;
-class SkBitmap;
-
namespace blink {
class WebCoalescedInputEvent;
class WebInputEvent;
@@ -183,7 +181,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
GURL document_url() const { return document_url_; }
// Paints the current backing store to the web page.
- void Paint(blink::WebCanvas* canvas,
+ void Paint(cc::PaintCanvas* canvas,
const gfx::Rect& plugin_rect,
const gfx::Rect& paint_rect);
@@ -276,7 +274,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
bool SupportsPrintInterface();
bool IsPrintScalingDisabled();
int PrintBegin(const blink::WebPrintParams& print_params);
- void PrintPage(int page_number, blink::WebCanvas* canvas);
+ void PrintPage(int page_number, cc::PaintCanvas* canvas);
void PrintEnd();
bool GetPrintPresetOptionsFromDocument(
blink::WebPrintPresetOptions* preset_options);
@@ -850,8 +848,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// only valid as long as |message_channel_object_| is alive.
MessageChannel* message_channel_;
- // Bitmap for crashed plugin. Lazily initialized, non-owning pointer.
- SkBitmap* sad_plugin_;
+ // Bitmap for crashed plugin. Lazily initialized.
+ cc::PaintImage sad_plugin_image_;
typedef std::set<PluginObject*> PluginObjectSet;
PluginObjectSet live_plugin_objects_;
diff --git a/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc b/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc
index c97d6a5c56a..e026b2fef3d 100644
--- a/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc
+++ b/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc
@@ -39,4 +39,18 @@ PepperProxyChannelDelegateImpl::ShareSharedMemoryHandleWithRemote(
return base::SharedMemory::DuplicateHandle(handle);
}
+base::UnsafeSharedMemoryRegion
+PepperProxyChannelDelegateImpl::ShareUnsafeSharedMemoryRegionWithRemote(
+ const base::UnsafeSharedMemoryRegion& region,
+ base::ProcessId remote_pid) {
+ return region.Duplicate();
+}
+
+base::ReadOnlySharedMemoryRegion
+PepperProxyChannelDelegateImpl::ShareReadOnlySharedMemoryRegionWithRemote(
+ const base::ReadOnlySharedMemoryRegion& region,
+ base::ProcessId remote_pid) {
+ return region.Duplicate();
+}
+
} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h b/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h
index 6bfd2a1b6bb..147c68cc9f8 100644
--- a/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h
+++ b/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h
@@ -25,6 +25,12 @@ class PepperProxyChannelDelegateImpl
base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
const base::SharedMemoryHandle& handle,
base::ProcessId remote_pid) override;
+ base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+ const base::UnsafeSharedMemoryRegion& region,
+ base::ProcessId remote_pid) override;
+ base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+ const base::ReadOnlySharedMemoryRegion& region,
+ base::ProcessId remote_pid) override;
};
} // namespace content
diff --git a/chromium/content/renderer/pepper/pepper_url_loader_host.cc b/chromium/content/renderer/pepper/pepper_url_loader_host.cc
index 3d2914bfb7d..681130e7db9 100644
--- a/chromium/content/renderer/pepper/pepper_url_loader_host.cc
+++ b/chromium/content/renderer/pepper/pepper_url_loader_host.cc
@@ -57,8 +57,7 @@ PepperURLLoaderHost::PepperURLLoaderHost(RendererPpapiHostImpl* host,
total_bytes_to_be_sent_(-1),
bytes_received_(0),
total_bytes_to_be_received_(-1),
- pending_response_(false),
- weak_factory_(this) {
+ pending_response_(false) {
DCHECK((main_document_loader && !resource) ||
(!main_document_loader && resource));
}
@@ -405,21 +404,12 @@ void PepperURLLoaderHost::SaveResponse(const WebURLResponse& response) {
DCHECK(!pending_response_);
pending_response_ = true;
- DataFromWebURLResponse(
- renderer_ppapi_host_,
- pp_instance(),
- response,
- base::Bind(&PepperURLLoaderHost::DidDataFromWebURLResponse,
- weak_factory_.GetWeakPtr()));
+ SendUpdateToPlugin(
+ std::make_unique<PpapiPluginMsg_URLLoader_ReceivedResponse>(
+ DataFromWebURLResponse(response)));
}
}
-void PepperURLLoaderHost::DidDataFromWebURLResponse(
- const ppapi::URLResponseInfoData& data) {
- SendUpdateToPlugin(
- std::make_unique<PpapiPluginMsg_URLLoader_ReceivedResponse>(data));
-}
-
void PepperURLLoaderHost::UpdateProgress() {
bool record_download = request_data_.record_download_progress;
bool record_upload = request_data_.record_upload_progress;
diff --git a/chromium/content/renderer/pepper/pepper_url_loader_host.h b/chromium/content/renderer/pepper/pepper_url_loader_host.h
index 1f3510907d3..f5ff3d7eff1 100644
--- a/chromium/content/renderer/pepper/pepper_url_loader_host.h
+++ b/chromium/content/renderer/pepper/pepper_url_loader_host.h
@@ -11,7 +11,6 @@
#include <vector>
#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "ppapi/host/resource_host.h"
#include "ppapi/proxy/resource_message_params.h"
@@ -96,7 +95,6 @@ class PepperURLLoaderHost : public ppapi::host::ResourceHost,
// Converts a WebURLResponse to a URLResponseInfo and saves it.
void SaveResponse(const blink::WebURLResponse& response);
- void DidDataFromWebURLResponse(const ppapi::URLResponseInfoData& data);
// Sends the UpdateProgress message (if necessary) to the plugin.
void UpdateProgress();
@@ -139,8 +137,6 @@ class PepperURLLoaderHost : public ppapi::host::ResourceHost,
// ordering constraints on following messages to the plugin.
bool pending_response_;
- base::WeakPtrFactory<PepperURLLoaderHost> weak_factory_;
-
DISALLOW_COPY_AND_ASSIGN(PepperURLLoaderHost);
};
diff --git a/chromium/content/renderer/pepper/pepper_url_request_unittest.cc b/chromium/content/renderer/pepper/pepper_url_request_unittest.cc
index 845aca9a3ef..b091332f7a6 100644
--- a/chromium/content/renderer/pepper/pepper_url_request_unittest.cc
+++ b/chromium/content/renderer/pepper/pepper_url_request_unittest.cc
@@ -14,8 +14,8 @@
#include "ppapi/thunk/thunk.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_url_request.h"
-#include "third_party/blink/public/web/web_frame_client.h"
#include "third_party/blink/public/web/web_local_frame.h"
+#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_view.h"
// This test is a end-to-end test from the resource to the WebKit request
@@ -23,7 +23,7 @@
// test it by making sure the conversion routines actually work at the same
// time.
-using blink::WebFrameClient;
+using blink::WebLocalFrameClient;
using blink::WebString;
using blink::WebView;
using blink::WebURL;
@@ -32,7 +32,7 @@ using blink::WebURLRequest;
namespace {
// The base class destructor is protected, so derive.
-class TestWebFrameClient : public WebFrameClient {};
+class TestWebFrameClient : public WebLocalFrameClient {};
} // namespace
@@ -61,14 +61,6 @@ class URLRequestInfoTest : public RenderViewTest {
RenderViewTest::TearDown();
}
- bool GetDownloadToFile() {
- WebURLRequest web_request;
- URLRequestInfoData data = info_->GetData();
- if (!CreateWebURLRequest(pp_instance_, &data, GetMainFrame(), &web_request))
- return false;
- return web_request.DownloadToFile();
- }
-
WebString GetURL() {
WebURLRequest web_request;
URLRequestInfoData data = info_->GetData();
@@ -129,13 +121,8 @@ TEST_F(URLRequestInfoTest, AsURLRequestInfo) {
TEST_F(URLRequestInfoTest, StreamToFile) {
SetStringProperty(PP_URLREQUESTPROPERTY_URL, "http://www.google.com");
- EXPECT_FALSE(GetDownloadToFile());
-
EXPECT_FALSE(SetBooleanProperty(PP_URLREQUESTPROPERTY_STREAMTOFILE, true));
- EXPECT_FALSE(GetDownloadToFile());
-
EXPECT_FALSE(SetBooleanProperty(PP_URLREQUESTPROPERTY_STREAMTOFILE, false));
- EXPECT_FALSE(GetDownloadToFile());
}
TEST_F(URLRequestInfoTest, FollowRedirects) {
diff --git a/chromium/content/renderer/pepper/pepper_video_decoder_host.cc b/chromium/content/renderer/pepper/pepper_video_decoder_host.cc
index d3fb411d87c..5201b8dc049 100644
--- a/chromium/content/renderer/pepper/pepper_video_decoder_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_decoder_host.cc
@@ -215,7 +215,7 @@ int32_t PepperVideoDecoderHost::OnHostMsgGetShm(
shm_size);
ppapi::host::ReplyMessageContext reply_context =
context->MakeReplyMessageContext();
- reply_context.params.AppendHandle(handle);
+ reply_context.params.AppendHandle(std::move(handle));
host()->SendReply(reply_context,
PpapiPluginMsg_VideoDecoder_GetShmReply(shm_size));
@@ -256,9 +256,12 @@ int32_t PepperVideoDecoderHost::OnHostMsgDecode(
int32_t PepperVideoDecoderHost::OnHostMsgAssignTextures(
ppapi::host::HostMessageContext* context,
const PP_Size& size,
- const std::vector<uint32_t>& texture_ids) {
+ const std::vector<uint32_t>& texture_ids,
+ const std::vector<gpu::Mailbox>& mailboxes) {
if (!initialized_)
return PP_ERROR_FAILED;
+ if (texture_ids.size() != mailboxes.size())
+ return PP_ERROR_FAILED;
DCHECK(decoder_);
pending_texture_requests_--;
@@ -304,6 +307,7 @@ int32_t PepperVideoDecoderHost::OnHostMsgAssignTextures(
gfx::Size(size.width, size.height), ids);
picture_buffers.push_back(buffer);
}
+ texture_mailboxes_ = mailboxes;
decoder_->AssignPictureBuffers(picture_buffers);
return PP_OK;
}
@@ -375,10 +379,12 @@ void PepperVideoDecoderHost::ProvidePictureBuffers(
const gfx::Size& dimensions,
uint32_t texture_target) {
DCHECK_EQ(1u, textures_per_buffer);
- RequestTextures(std::max(min_picture_count_, requested_num_of_buffers),
- dimensions,
- texture_target,
- std::vector<gpu::Mailbox>());
+ pending_texture_requests_++;
+ host()->SendUnsolicitedReply(
+ pp_resource(), PpapiPluginMsg_VideoDecoder_RequestTextures(
+ std::max(min_picture_count_, requested_num_of_buffers),
+ PP_MakeSize(dimensions.width(), dimensions.height()),
+ texture_target));
}
void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) {
@@ -476,21 +482,6 @@ const uint8_t* PepperVideoDecoderHost::DecodeIdToAddress(uint32_t decode_id) {
return static_cast<uint8_t*>(shm_buffers_[shm_id]->memory());
}
-void PepperVideoDecoderHost::RequestTextures(
- uint32_t requested_num_of_buffers,
- const gfx::Size& dimensions,
- uint32_t texture_target,
- const std::vector<gpu::Mailbox>& mailboxes) {
- pending_texture_requests_++;
- host()->SendUnsolicitedReply(
- pp_resource(),
- PpapiPluginMsg_VideoDecoder_RequestTextures(
- requested_num_of_buffers,
- PP_MakeSize(dimensions.width(), dimensions.height()),
- texture_target,
- mailboxes));
-}
-
bool PepperVideoDecoderHost::TryFallbackToSoftwareDecoder() {
#if defined(OS_ANDROID)
return false;
diff --git a/chromium/content/renderer/pepper/pepper_video_decoder_host.h b/chromium/content/renderer/pepper/pepper_video_decoder_host.h
index e58aa1e9862..2983f48853e 100644
--- a/chromium/content/renderer/pepper/pepper_video_decoder_host.h
+++ b/chromium/content/renderer/pepper/pepper_video_decoder_host.h
@@ -16,6 +16,7 @@
#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "content/common/content_export.h"
+#include "gpu/command_buffer/common/mailbox.h"
#include "media/video/video_decode_accelerator.h"
#include "ppapi/c/pp_codecs.h"
#include "ppapi/host/host_message_context.h"
@@ -95,7 +96,8 @@ class CONTENT_EXPORT PepperVideoDecoderHost
int32_t decode_id);
int32_t OnHostMsgAssignTextures(ppapi::host::HostMessageContext* context,
const PP_Size& size,
- const std::vector<uint32_t>& texture_ids);
+ const std::vector<uint32_t>& texture_ids,
+ const std::vector<gpu::Mailbox>& mailboxes);
int32_t OnHostMsgRecyclePicture(ppapi::host::HostMessageContext* context,
uint32_t picture_id);
int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context);
@@ -104,10 +106,9 @@ class CONTENT_EXPORT PepperVideoDecoderHost
// These methods are needed by VideoDecodeShim, to look like a
// VideoDecodeAccelerator.
const uint8_t* DecodeIdToAddress(uint32_t decode_id);
- void RequestTextures(uint32_t requested_num_of_buffers,
- const gfx::Size& dimensions,
- uint32_t texture_target,
- const std::vector<gpu::Mailbox>& mailboxes);
+ std::vector<gpu::Mailbox> TakeMailboxes() {
+ return std::move(texture_mailboxes_);
+ }
// Tries to initialize software decoder. Returns true on success.
bool TryFallbackToSoftwareDecoder();
@@ -143,6 +144,10 @@ class CONTENT_EXPORT PepperVideoDecoderHost
typedef std::map<uint32_t, PictureBufferState> PictureBufferMap;
PictureBufferMap picture_buffer_map_;
+ // Mailboxes corresponding to textures given to AssignPictureBuffers, to allow
+ // VideoDecoderShim to use them from another context.
+ std::vector<gpu::Mailbox> texture_mailboxes_;
+
// Keeps list of pending decodes.
PendingDecodeList pending_decodes_;
diff --git a/chromium/content/renderer/pepper/pepper_video_encoder_host.cc b/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
index 913820c20f3..8c3565b2b23 100644
--- a/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_encoder_host.cc
@@ -375,9 +375,10 @@ void PepperVideoEncoderHost::RequireBitstreamBuffers(
}
host()->SendUnsolicitedReplyWithHandles(
- pp_resource(), PpapiPluginMsg_VideoEncoder_BitstreamBuffers(
- static_cast<uint32_t>(output_buffer_size)),
- handles);
+ pp_resource(),
+ PpapiPluginMsg_VideoEncoder_BitstreamBuffers(
+ static_cast<uint32_t>(output_buffer_size)),
+ &handles);
if (!initialized_) {
// Tell the plugin that initialization has been successful if we
@@ -400,10 +401,9 @@ void PepperVideoEncoderHost::RequireBitstreamBuffers(
AllocateVideoFrames();
}
-void PepperVideoEncoderHost::BitstreamBufferReady(int32_t buffer_id,
- size_t payload_size,
- bool key_frame,
- base::TimeDelta /* timestamp */) {
+void PepperVideoEncoderHost::BitstreamBufferReady(
+ int32_t buffer_id,
+ const media::BitstreamBufferMetadata& metadata) {
DCHECK(RenderThreadImpl::current());
DCHECK(shm_buffers_[buffer_id]->in_use);
@@ -412,7 +412,8 @@ void PepperVideoEncoderHost::BitstreamBufferReady(int32_t buffer_id,
host()->SendUnsolicitedReply(
pp_resource(),
PpapiPluginMsg_VideoEncoder_BitstreamBufferReady(
- buffer_id, static_cast<uint32_t>(payload_size), key_frame));
+ buffer_id, base::checked_cast<uint32_t>(metadata.payload_size_bytes),
+ metadata.key_frame));
}
void PepperVideoEncoderHost::NotifyError(
diff --git a/chromium/content/renderer/pepper/pepper_video_encoder_host.h b/chromium/content/renderer/pepper/pepper_video_encoder_host.h
index 264c668cdc8..cbf01cf672f 100644
--- a/chromium/content/renderer/pepper/pepper_video_encoder_host.h
+++ b/chromium/content/renderer/pepper/pepper_video_encoder_host.h
@@ -27,6 +27,10 @@ namespace gpu {
class CommandBufferProxyImpl;
}
+namespace media {
+struct BitstreamBufferMetadata;
+} // namespace media
+
namespace content {
class RendererPpapiHost;
@@ -63,10 +67,9 @@ class CONTENT_EXPORT PepperVideoEncoderHost
void RequireBitstreamBuffers(unsigned int input_count,
const gfx::Size& input_coded_size,
size_t output_buffer_size) override;
- void BitstreamBufferReady(int32_t bitstream_buffer_id,
- size_t payload_size,
- bool key_frame,
- base::TimeDelta timestamp) override;
+ void BitstreamBufferReady(
+ int32_t bitstream_buffer_id,
+ const media::BitstreamBufferMetadata& metadata) override;
void NotifyError(media::VideoEncodeAccelerator::Error error) override;
// ResourceHost implementation.
diff --git a/chromium/content/renderer/pepper/pepper_video_source_host.cc b/chromium/content/renderer/pepper/pepper_video_source_host.cc
index 1de7bbf7168..48047137deb 100644
--- a/chromium/content/renderer/pepper/pepper_video_source_host.cc
+++ b/chromium/content/renderer/pepper/pepper_video_source_host.cc
@@ -291,7 +291,7 @@ void PepperVideoSourceHost::SendGetFrameReply() {
ppapi::proxy::SerializedHandle serialized_handle;
serialized_handle.set_shmem(image_handle, byte_count);
- reply_context_.params.AppendHandle(serialized_handle);
+ reply_context_.params.AppendHandle(std::move(serialized_handle));
host()->SendReply(reply_context_,
PpapiPluginMsg_VideoSource_GetFrameReply(
diff --git a/chromium/content/renderer/pepper/pepper_webplugin_impl.cc b/chromium/content/renderer/pepper/pepper_webplugin_impl.cc
index a2701cacf15..ed9dd9bcee9 100644
--- a/chromium/content/renderer/pepper/pepper_webplugin_impl.cc
+++ b/chromium/content/renderer/pepper/pepper_webplugin_impl.cc
@@ -41,7 +41,6 @@
#include "url/gurl.h"
using ppapi::V8ObjectVar;
-using blink::WebCanvas;
using blink::WebPlugin;
using blink::WebPluginContainer;
using blink::WebPluginParams;
@@ -190,7 +189,7 @@ v8::Local<v8::Object> PepperWebPluginImpl::V8ScriptableObject(
return result;
}
-void PepperWebPluginImpl::Paint(WebCanvas* canvas, const WebRect& rect) {
+void PepperWebPluginImpl::Paint(cc::PaintCanvas* canvas, const WebRect& rect) {
// Re-entrancy may cause JS to try to execute script on the plugin before it
// is fully initialized. See: crbug.com/715747.
if (instance_ && !instance_->FlashIsFullscreenOrPending())
@@ -441,7 +440,7 @@ int PepperWebPluginImpl::PrintBegin(const WebPrintParams& print_params) {
return instance_->PrintBegin(print_params);
}
-void PepperWebPluginImpl::PrintPage(int page_number, blink::WebCanvas* canvas) {
+void PepperWebPluginImpl::PrintPage(int page_number, cc::PaintCanvas* canvas) {
// Re-entrancy may cause JS to try to execute script on the plugin before it
// is fully initialized. See: crbug.com/715747.
if (instance_)
diff --git a/chromium/content/renderer/pepper/pepper_webplugin_impl.h b/chromium/content/renderer/pepper/pepper_webplugin_impl.h
index 64e09efce8f..fb0a58b0d9e 100644
--- a/chromium/content/renderer/pepper/pepper_webplugin_impl.h
+++ b/chromium/content/renderer/pepper/pepper_webplugin_impl.h
@@ -44,7 +44,7 @@ class PepperWebPluginImpl : public blink::WebPlugin {
void Destroy() override;
v8::Local<v8::Object> V8ScriptableObject(v8::Isolate* isolate) override;
void UpdateAllLifecyclePhases() override {}
- void Paint(blink::WebCanvas* canvas, const blink::WebRect& rect) override;
+ void Paint(cc::PaintCanvas* canvas, const blink::WebRect& rect) override;
void UpdateGeometry(const blink::WebRect& window_rect,
const blink::WebRect& clip_rect,
const blink::WebRect& unobscured_rect,
@@ -80,7 +80,7 @@ class PepperWebPluginImpl : public blink::WebPlugin {
bool IsPrintScalingDisabled() override;
int PrintBegin(const blink::WebPrintParams& print_params) override;
- void PrintPage(int page_number, blink::WebCanvas* canvas) override;
+ void PrintPage(int page_number, cc::PaintCanvas* canvas) override;
void PrintEnd() override;
bool CanRotateView() override;
diff --git a/chromium/content/renderer/pepper/ppb_audio_impl.cc b/chromium/content/renderer/pepper/ppb_audio_impl.cc
index 21d939262aa..98f3a272a36 100644
--- a/chromium/content/renderer/pepper/ppb_audio_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_audio_impl.cc
@@ -152,20 +152,15 @@ int32_t PPB_Audio_Impl::GetSyncSocket(int* sync_socket) {
return GetSyncSocketImpl(sync_socket);
}
-int32_t PPB_Audio_Impl::GetSharedMemory(base::SharedMemory** shm,
- uint32_t* shm_size) {
- return GetSharedMemoryImpl(shm, shm_size);
+int32_t PPB_Audio_Impl::GetSharedMemory(base::UnsafeSharedMemoryRegion** shm) {
+ return GetSharedMemoryImpl(shm);
}
void PPB_Audio_Impl::OnSetStreamInfo(
- base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size,
+ base::UnsafeSharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket_handle) {
EnterResourceNoLock<PPB_AudioConfig_API> enter(config_, true);
- SetStreamInfo(pp_instance(),
- shared_memory_handle,
- shared_memory_size,
- socket_handle,
+ SetStreamInfo(pp_instance(), std::move(shared_memory_region), socket_handle,
enter.object()->GetSampleRate(),
enter.object()->GetSampleFrameCount());
}
diff --git a/chromium/content/renderer/pepper/ppb_audio_impl.h b/chromium/content/renderer/pepper/ppb_audio_impl.h
index e0618ffb29d..abcd04b08a4 100644
--- a/chromium/content/renderer/pepper/ppb_audio_impl.h
+++ b/chromium/content/renderer/pepper/ppb_audio_impl.h
@@ -10,7 +10,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
#include "base/sync_socket.h"
#include "content/public/renderer/plugin_instance_throttler.h"
#include "content/renderer/pepper/audio_helper.h"
@@ -47,8 +47,7 @@ class PPB_Audio_Impl : public ppapi::Resource,
int32_t Open(PP_Resource config_id,
scoped_refptr<ppapi::TrackedCallback> create_callback) override;
int32_t GetSyncSocket(int* sync_socket) override;
- int32_t GetSharedMemory(base::SharedMemory** shm,
- uint32_t* shm_size) override;
+ int32_t GetSharedMemory(base::UnsafeSharedMemoryRegion** shm) override;
void SetVolume(double volume);
@@ -56,8 +55,7 @@ class PPB_Audio_Impl : public ppapi::Resource,
~PPB_Audio_Impl() override;
// AudioHelper implementation.
- void OnSetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
- size_t shared_memory_size_,
+ void OnSetStreamInfo(base::UnsafeSharedMemoryRegion shared_memory_region,
base::SyncSocket::Handle socket) override;
// PluginInstanceThrottler::Observer implementation.
diff --git a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
index 50f971cd3d4..4e2717ba4b3 100644
--- a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
+++ b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -68,7 +68,7 @@ PP_Resource PPB_Graphics3D_Impl::CreateRaw(
PP_Resource share_context,
const gpu::ContextCreationAttribs& attrib_helper,
gpu::Capabilities* capabilities,
- base::SharedMemoryHandle* shared_state_handle,
+ const base::UnsafeSharedMemoryRegion** shared_state_region,
gpu::CommandBufferId* command_buffer_id) {
PPB_Graphics3D_API* share_api = nullptr;
if (share_context) {
@@ -80,7 +80,7 @@ PP_Resource PPB_Graphics3D_Impl::CreateRaw(
scoped_refptr<PPB_Graphics3D_Impl> graphics_3d(
new PPB_Graphics3D_Impl(instance));
if (!graphics_3d->InitRaw(share_api, attrib_helper, capabilities,
- shared_state_handle, command_buffer_id))
+ shared_state_region, command_buffer_id))
return 0;
return graphics_3d->GetReference();
}
@@ -125,11 +125,6 @@ void PPB_Graphics3D_Impl::EnsureWorkVisible() {
}
void PPB_Graphics3D_Impl::TakeFrontBuffer() {
- if (!taken_front_buffer_.IsZero()) {
- DLOG(ERROR)
- << "TakeFrontBuffer should only be called once before DoSwapBuffers";
- return;
- }
taken_front_buffer_ = GenerateMailbox();
command_buffer_->TakeFrontBuffer(taken_front_buffer_);
}
@@ -195,7 +190,6 @@ int32_t PPB_Graphics3D_Impl::DoSwapBuffers(const gpu::SyncToken& sync_token,
viz::TransferableResource::MakeGLOverlay(taken_front_buffer_, GL_LINEAR,
target, sync_token, size,
is_overlay_candidate);
- taken_front_buffer_.SetZero();
HostGlobals::Get()
->GetInstance(pp_instance())
->CommitTransferableResource(resource);
@@ -214,7 +208,7 @@ bool PPB_Graphics3D_Impl::InitRaw(
PPB_Graphics3D_API* share_context,
const gpu::ContextCreationAttribs& requested_attribs,
gpu::Capabilities* capabilities,
- base::SharedMemoryHandle* shared_state_handle,
+ const base::UnsafeSharedMemoryRegion** shared_state_region,
gpu::CommandBufferId* command_buffer_id) {
PepperPluginInstanceImpl* plugin_instance =
HostGlobals::Get()->GetInstance(pp_instance());
@@ -279,8 +273,8 @@ bool PPB_Graphics3D_Impl::InitRaw(
command_buffer_->SetGpuControlClient(this);
- if (shared_state_handle)
- *shared_state_handle = command_buffer_->GetSharedStateHandle();
+ if (shared_state_region)
+ *shared_state_region = &command_buffer_->GetSharedStateRegion();
if (capabilities)
*capabilities = command_buffer_->GetCapabilities();
if (command_buffer_id)
diff --git a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h
index 396faa7e1aa..389d2912861 100644
--- a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h
+++ b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h
@@ -10,7 +10,7 @@
#include <memory>
#include "base/macros.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
#include "base/memory/weak_ptr.h"
#include "gpu/command_buffer/client/gpu_control_client.h"
#include "gpu/command_buffer/common/command_buffer_id.h"
@@ -30,12 +30,13 @@ namespace content {
class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared,
public gpu::GpuControlClient {
public:
- static PP_Resource CreateRaw(PP_Instance instance,
- PP_Resource share_context,
- const gpu::ContextCreationAttribs& attrib_helper,
- gpu::Capabilities* capabilities,
- base::SharedMemoryHandle* shared_state_handle,
- gpu::CommandBufferId* command_buffer_id);
+ static PP_Resource CreateRaw(
+ PP_Instance instance,
+ PP_Resource share_context,
+ const gpu::ContextCreationAttribs& attrib_helper,
+ gpu::Capabilities* capabilities,
+ const base::UnsafeSharedMemoryRegion** shared_state_region,
+ gpu::CommandBufferId* command_buffer_id);
// PPB_Graphics3D_API trusted implementation.
PP_Bool SetGetBuffer(int32_t transfer_buffer_id) override;
@@ -82,7 +83,7 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared,
bool InitRaw(PPB_Graphics3D_API* share_context,
const gpu::ContextCreationAttribs& requested_attribs,
gpu::Capabilities* capabilities,
- base::SharedMemoryHandle* shared_state_handle,
+ const base::UnsafeSharedMemoryRegion** shared_state_region,
gpu::CommandBufferId* command_buffer_id);
// GpuControlClient implementation.
diff --git a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc
index 2e9658abdbf..9568688db4f 100644
--- a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc
+++ b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc
@@ -237,6 +237,26 @@ RendererPpapiHostImpl::ShareSharedMemoryHandleWithRemote(
return dispatcher_->ShareSharedMemoryHandleWithRemote(handle);
}
+base::UnsafeSharedMemoryRegion
+RendererPpapiHostImpl::ShareUnsafeSharedMemoryRegionWithRemote(
+ const base::UnsafeSharedMemoryRegion& region) {
+ if (!dispatcher_) {
+ DCHECK(is_running_in_process_);
+ return region.Duplicate();
+ }
+ return dispatcher_->ShareUnsafeSharedMemoryRegionWithRemote(region);
+}
+
+base::ReadOnlySharedMemoryRegion
+RendererPpapiHostImpl::ShareReadOnlySharedMemoryRegionWithRemote(
+ const base::ReadOnlySharedMemoryRegion& region) {
+ if (!dispatcher_) {
+ DCHECK(is_running_in_process_);
+ return region.Duplicate();
+ }
+ return dispatcher_->ShareReadOnlySharedMemoryRegionWithRemote(region);
+}
+
bool RendererPpapiHostImpl::IsRunningInProcess() const {
return is_running_in_process_;
}
diff --git a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h
index d8d6eddaf93..a94ef56ae66 100644
--- a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h
+++ b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h
@@ -89,6 +89,10 @@ class RendererPpapiHostImpl : public RendererPpapiHost {
bool should_close_source) override;
base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
const base::SharedMemoryHandle& handle) override;
+ base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+ const base::UnsafeSharedMemoryRegion& region) override;
+ base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+ const base::ReadOnlySharedMemoryRegion& region) override;
bool IsRunningInProcess() const override;
std::string GetPluginName() const override;
void SetToExternalPluginHost() override;
diff --git a/chromium/content/renderer/pepper/resource_creation_impl.cc b/chromium/content/renderer/pepper/resource_creation_impl.cc
index 64c9d9dbaa5..418806ab0db 100644
--- a/chromium/content/renderer/pepper/resource_creation_impl.cc
+++ b/chromium/content/renderer/pepper/resource_creation_impl.cc
@@ -128,7 +128,7 @@ PP_Resource ResourceCreationImpl::CreateGraphics3DRaw(
PP_Resource share_context,
const gpu::ContextCreationAttribs& attrib_helper,
gpu::Capabilities* capabilities,
- base::SharedMemoryHandle* shared_state,
+ const base::UnsafeSharedMemoryRegion** shared_state,
gpu::CommandBufferId* command_buffer_id) {
return PPB_Graphics3D_Impl::CreateRaw(instance, share_context, attrib_helper,
capabilities, shared_state,
diff --git a/chromium/content/renderer/pepper/resource_creation_impl.h b/chromium/content/renderer/pepper/resource_creation_impl.h
index df4c1fc07b5..d89ded28eac 100644
--- a/chromium/content/renderer/pepper/resource_creation_impl.h
+++ b/chromium/content/renderer/pepper/resource_creation_impl.h
@@ -60,7 +60,7 @@ class ResourceCreationImpl : public ppapi::thunk::ResourceCreationAPI {
PP_Resource share_context,
const gpu::ContextCreationAttribs& attrib_helper,
gpu::Capabilities* capabilities,
- base::SharedMemoryHandle* shared_state,
+ const base::UnsafeSharedMemoryRegion** shared_state,
gpu::CommandBufferId* command_buffer_id) override;
PP_Resource CreateHostResolver(PP_Instance instance) override;
PP_Resource CreateHostResolverPrivate(PP_Instance instance) override;
diff --git a/chromium/content/renderer/pepper/url_request_info_util.cc b/chromium/content/renderer/pepper/url_request_info_util.cc
index dd7047665c1..f5b4028d7fa 100644
--- a/chromium/content/renderer/pepper/url_request_info_util.cc
+++ b/chromium/content/renderer/pepper/url_request_info_util.cc
@@ -171,14 +171,8 @@ bool CreateWebURLRequest(PP_Instance instance,
dest->SetURL(
frame->GetDocument().CompleteURL(WebString::FromUTF8(data->url)));
- dest->SetDownloadToFile(data->stream_to_file);
dest->SetReportUploadProgress(data->record_upload_progress);
- if (data->stream_to_file) {
- frame->BlinkFeatureUsageReport({static_cast<int>(
- blink::mojom::WebFeature::kPPAPIURLRequestStreamToFile)});
- }
-
if (!data->method.empty())
dest->SetHTTPMethod(WebString::FromUTF8(data->method));
diff --git a/chromium/content/renderer/pepper/url_response_info_util.cc b/chromium/content/renderer/pepper/url_response_info_util.cc
index e2e23fb308c..d7539ce56c0 100644
--- a/chromium/content/renderer/pepper/url_response_info_util.cc
+++ b/chromium/content/renderer/pepper/url_response_info_util.cc
@@ -6,18 +6,7 @@
#include <stdint.h>
-#include "base/bind.h"
-#include "base/files/file_path.h"
-#include "base/location.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/public/renderer/renderer_ppapi_host.h"
-#include "content/renderer/pepper/pepper_file_ref_renderer_host.h"
-#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
-#include "ipc/ipc_message.h"
-#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/url_response_info_data.h"
-#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/web_http_header_visitor.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url.h"
@@ -52,33 +41,10 @@ class HeadersToString : public WebHTTPHeaderVisitor {
bool IsRedirect(int32_t status) { return status >= 300 && status <= 399; }
-void DidCreateResourceHosts(const ppapi::URLResponseInfoData& in_data,
- const base::FilePath& external_path,
- int renderer_pending_host_id,
- const DataFromWebURLResponseCallback& callback,
- const std::vector<int>& browser_pending_host_ids) {
- DCHECK_EQ(1U, browser_pending_host_ids.size());
- int browser_pending_host_id = 0;
-
- if (browser_pending_host_ids.size() == 1)
- browser_pending_host_id = browser_pending_host_ids[0];
-
- ppapi::URLResponseInfoData data = in_data;
-
- data.body_as_file_ref =
- ppapi::MakeExternalFileRefCreateInfo(external_path,
- std::string(),
- browser_pending_host_id,
- renderer_pending_host_id);
- callback.Run(data);
-}
-
} // namespace
-void DataFromWebURLResponse(RendererPpapiHostImpl* host_impl,
- PP_Instance pp_instance,
- const WebURLResponse& response,
- const DataFromWebURLResponseCallback& callback) {
+ppapi::URLResponseInfoData DataFromWebURLResponse(
+ const WebURLResponse& response) {
ppapi::URLResponseInfoData data;
data.url = response.Url().GetString().Utf8();
data.status_code = response.HttpStatusCode();
@@ -91,31 +57,7 @@ void DataFromWebURLResponse(RendererPpapiHostImpl* host_impl,
HeadersToString headers_to_string;
response.VisitHTTPHeaderFields(&headers_to_string);
data.headers = headers_to_string.buffer();
-
- WebString file_path = response.DownloadFilePath();
- if (!file_path.IsEmpty()) {
- base::FilePath external_path = blink::WebStringToFilePath(file_path);
- // TODO(teravest): Write a utility function to create resource hosts in the
- // renderer and browser.
- PepperFileRefRendererHost* renderer_host =
- new PepperFileRefRendererHost(host_impl, pp_instance, 0, external_path);
- int renderer_pending_host_id =
- host_impl->GetPpapiHost()->AddPendingResourceHost(
- std::unique_ptr<ppapi::host::ResourceHost>(renderer_host));
-
- std::vector<IPC::Message> create_msgs;
- create_msgs.push_back(PpapiHostMsg_FileRef_CreateForRawFS(external_path));
- host_impl->CreateBrowserResourceHosts(pp_instance,
- create_msgs,
- base::Bind(&DidCreateResourceHosts,
- data,
- external_path,
- renderer_pending_host_id,
- callback));
- } else {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(callback, data));
- }
+ return data;
}
} // namespace content
diff --git a/chromium/content/renderer/pepper/url_response_info_util.h b/chromium/content/renderer/pepper/url_response_info_util.h
index d7570627ed0..a4996086e40 100644
--- a/chromium/content/renderer/pepper/url_response_info_util.h
+++ b/chromium/content/renderer/pepper/url_response_info_util.h
@@ -5,8 +5,6 @@
#ifndef CONTENT_RENDERER_PEPPER_URL_RESPONSE_INFO_UTIL_H_
#define CONTENT_RENDERER_PEPPER_URL_RESPONSE_INFO_UTIL_H_
-#include "base/callback.h"
-#include "ppapi/c/pp_instance.h"
#include "ppapi/shared_impl/url_response_info_data.h"
namespace blink {
@@ -14,18 +12,9 @@ class WebURLResponse;
}
namespace content {
-class RendererPpapiHostImpl;
-typedef base::Callback<void(const ppapi::URLResponseInfoData&)>
- DataFromWebURLResponseCallback;
-
-// The returned object will have one plugin reference to the "body_as_file_ref"
-// if it's non-null. It's expected that the result of this function will be
-// passed to the plugin.
-void DataFromWebURLResponse(RendererPpapiHostImpl* host_impl,
- PP_Instance pp_instance,
- const blink::WebURLResponse& response,
- const DataFromWebURLResponseCallback& callback);
+ppapi::URLResponseInfoData DataFromWebURLResponse(
+ const blink::WebURLResponse& response);
} // namespace content
diff --git a/chromium/content/renderer/pepper/video_decoder_shim.cc b/chromium/content/renderer/pepper/video_decoder_shim.cc
index 231a4f63044..ca39cdef7d7 100644
--- a/chromium/content/renderer/pepper/video_decoder_shim.cc
+++ b/chromium/content/renderer/pepper/video_decoder_shim.cc
@@ -929,20 +929,20 @@ void VideoDecoderShim::AssignPictureBuffers(
NOTREACHED();
return;
}
- DCHECK_EQ(buffers.size(), pending_texture_mailboxes_.size());
+ std::vector<gpu::Mailbox> mailboxes = host_->TakeMailboxes();
+ DCHECK_EQ(buffers.size(), mailboxes.size());
GLuint num_textures = base::checked_cast<GLuint>(buffers.size());
std::vector<uint32_t> local_texture_ids(num_textures);
gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
for (uint32_t i = 0; i < num_textures; i++) {
DCHECK_EQ(1u, buffers[i].client_texture_ids().size());
- local_texture_ids[i] = gles2->CreateAndConsumeTextureCHROMIUM(
- pending_texture_mailboxes_[i].name);
+ local_texture_ids[i] =
+ gles2->CreateAndConsumeTextureCHROMIUM(mailboxes[i].name);
// Map the plugin texture id to the local texture id.
uint32_t plugin_texture_id = buffers[i].client_texture_ids()[0];
texture_id_map_[plugin_texture_id] = local_texture_ids[i];
available_textures_.insert(plugin_texture_id);
}
- pending_texture_mailboxes_.clear();
SendPictures();
}
@@ -1026,13 +1026,9 @@ void VideoDecoderShim::OnOutputComplete(std::unique_ptr<PendingFrame> frame) {
available_textures_.clear();
FlushCommandBuffer();
- DCHECK(pending_texture_mailboxes_.empty());
- for (uint32_t i = 0; i < texture_pool_size_; i++)
- pending_texture_mailboxes_.push_back(gpu::Mailbox::Generate());
-
- host_->RequestTextures(texture_pool_size_,
- frame->video_frame->coded_size(), GL_TEXTURE_2D,
- pending_texture_mailboxes_);
+ host_->ProvidePictureBuffers(texture_pool_size_, media::PIXEL_FORMAT_ARGB,
+ 1, frame->video_frame->coded_size(),
+ GL_TEXTURE_2D);
texture_size_ = frame->video_frame->coded_size();
}
diff --git a/chromium/content/renderer/pepper/video_decoder_shim.h b/chromium/content/renderer/pepper/video_decoder_shim.h
index 16e93d716ff..44a1b6d4f00 100644
--- a/chromium/content/renderer/pepper/video_decoder_shim.h
+++ b/chromium/content/renderer/pepper/video_decoder_shim.h
@@ -14,7 +14,6 @@
#include "base/containers/queue.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "gpu/command_buffer/common/mailbox.h"
#include "media/base/video_decoder_config.h"
#include "media/video/video_decode_accelerator.h"
#include "ppapi/c/pp_codecs.h"
@@ -92,8 +91,6 @@ class VideoDecoderShim : public media::VideoDecodeAccelerator {
TextureIdSet available_textures_;
// Track textures that are no longer needed (these are plugin ids.)
TextureIdSet textures_to_dismiss_;
- // Mailboxes for pending texture requests, to write to plugin's textures.
- std::vector<gpu::Mailbox> pending_texture_mailboxes_;
// Queue of completed decode ids, for notifying the host.
using CompletedDecodeQueue = base::queue<uint32_t>;
diff --git a/chromium/content/renderer/pepper/video_encoder_shim.cc b/chromium/content/renderer/pepper/video_encoder_shim.cc
index 58d4391f145..a8ce1b77691 100644
--- a/chromium/content/renderer/pepper/video_encoder_shim.cc
+++ b/chromium/content/renderer/pepper/video_encoder_shim.cc
@@ -487,8 +487,9 @@ void VideoEncoderShim::OnBitstreamBufferReady(
bool key_frame) {
DCHECK(RenderThreadImpl::current());
- host_->BitstreamBufferReady(bitstream_buffer_id, payload_size, key_frame,
- frame->timestamp());
+ host_->BitstreamBufferReady(bitstream_buffer_id,
+ media::BitstreamBufferMetadata(
+ payload_size, key_frame, frame->timestamp()));
}
void VideoEncoderShim::OnNotifyError(
diff --git a/chromium/content/renderer/push_messaging/push_messaging_client.cc b/chromium/content/renderer/push_messaging/push_messaging_client.cc
index 9fc24d41d5d..512d3e23f06 100644
--- a/chromium/content/renderer/push_messaging/push_messaging_client.cc
+++ b/chromium/content/renderer/push_messaging/push_messaging_client.cc
@@ -21,7 +21,7 @@
#include "third_party/blink/public/platform/modules/push_messaging/web_push_error.h"
#include "third_party/blink/public/platform/modules/push_messaging/web_push_subscription.h"
#include "third_party/blink/public/platform/modules/push_messaging/web_push_subscription_options.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_registration.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_registration.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/web_console_message.h"
#include "third_party/blink/public/web/web_local_frame.h"
diff --git a/chromium/content/renderer/render_frame_impl.cc b/chromium/content/renderer/render_frame_impl.cc
index c027c4df342..f6adabc683c 100644
--- a/chromium/content/renderer/render_frame_impl.cc
+++ b/chromium/content/renderer/render_frame_impl.cc
@@ -35,6 +35,8 @@
#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_piece.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
#include "base/task_scheduler/post_task.h"
@@ -61,12 +63,12 @@
#include "content/common/renderer_host.mojom.h"
#include "content/common/savable_subframe.h"
#include "content/common/service_worker/service_worker_types.h"
-#include "content/common/service_worker/service_worker_utils.h"
#include "content/common/swapped_out_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/appcache_info.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"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
@@ -101,7 +103,7 @@
#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/gpu/layer_tree_view.h"
#include "content/renderer/history_entry.h"
#include "content/renderer/history_serialization.h"
#include "content/renderer/image_downloader/image_downloader_impl.h"
@@ -115,17 +117,20 @@
#include "content/renderer/loader/tracked_child_url_loader_factory_bundle.h"
#include "content/renderer/loader/web_url_loader_impl.h"
#include "content/renderer/loader/web_url_request_util.h"
+#include "content/renderer/loader/web_worker_fetch_context_impl.h"
#include "content/renderer/loader/weburlresponse_extradata_impl.h"
+#include "content/renderer/low_memory_mode_controller.h"
#include "content/renderer/manifest/manifest_change_notifier.h"
#include "content/renderer/manifest/manifest_manager.h"
-#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/audio_output_ipc_factory.h"
-#include "content/renderer/media/audio_renderer_sink_cache.h"
+#include "content/renderer/media/audio/audio_device_factory.h"
+#include "content/renderer/media/audio/audio_output_ipc_factory.h"
+#include "content/renderer/media/audio/audio_renderer_sink_cache.h"
#include "content/renderer/media/media_permission_dispatcher.h"
#include "content/renderer/media/stream/media_stream_device_observer.h"
#include "content/renderer/media/stream/user_media_client_impl.h"
#include "content/renderer/media/webrtc/rtc_peer_connection_handler.h"
#include "content/renderer/mojo/blink_interface_registry_impl.h"
+#include "content/renderer/navigation_client.h"
#include "content/renderer/navigation_state_impl.h"
#include "content/renderer/pepper/pepper_audio_controller.h"
#include "content/renderer/pepper/plugin_instance_throttler_impl.h"
@@ -142,13 +147,10 @@
#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/speech_recognition_dispatcher.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"
#include "crypto/sha2.h"
@@ -161,6 +163,7 @@
#include "net/http/http_util.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
@@ -168,15 +171,18 @@
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/frame/sandbox_flags.h"
+#include "third_party/blink/public/common/frame/user_activation_update_type.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/interface_provider.h"
#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
#include "third_party/blink/public/platform/modules/permissions/permission.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_network_provider.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_focus_type.h"
+#include "third_party/blink/public/platform/web_http_body.h"
#include "third_party/blink/public/platform/web_keyboard_event.h"
#include "third_party/blink/public/platform/web_media_player.h"
#include "third_party/blink/public/platform/web_media_player_source.h"
@@ -202,6 +208,7 @@
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_media_stream_registry.h"
#include "third_party/blink/public/web/web_navigation_policy.h"
+#include "third_party/blink/public/web/web_navigation_timings.h"
#include "third_party/blink/public/web/web_plugin.h"
#include "third_party/blink/public/web/web_plugin_container.h"
#include "third_party/blink/public/web/web_plugin_document.h"
@@ -231,6 +238,12 @@
#include "content/renderer/pepper/plugin_module.h"
#endif
+#if defined(OS_WIN)
+#include "base/process/kill.h"
+#elif defined(OS_POSIX)
+#include <signal.h>
+#endif
+
#if defined(OS_ANDROID)
#include <cpu-features.h>
@@ -301,12 +314,16 @@ namespace content {
// Helper struct keeping track in one place of all the parameters the browser
// provided to the renderer to commit a navigation.
struct PendingNavigationParams {
- PendingNavigationParams(const CommonNavigationParams& common_params,
- const RequestNavigationParams& request_params,
- base::TimeTicks time_commit_requested)
+ PendingNavigationParams(
+ const CommonNavigationParams& common_params,
+ const RequestNavigationParams& request_params,
+ base::TimeTicks time_commit_requested,
+ content::mojom::FrameNavigationControl::CommitNavigationCallback
+ commit_callback)
: common_params(common_params),
request_params(request_params),
- time_commit_requested(time_commit_requested) {}
+ time_commit_requested(time_commit_requested),
+ commit_callback_(std::move(commit_callback)) {}
~PendingNavigationParams() = default;
CommonNavigationParams common_params;
@@ -314,13 +331,13 @@ struct PendingNavigationParams {
// Time when RenderFrameImpl::CommitNavigation() is called.
base::TimeTicks time_commit_requested;
+
+ content::mojom::FrameNavigationControl::CommitNavigationCallback
+ commit_callback_;
};
namespace {
-const base::Feature kConsumeGestureOnNavigation = {
- "ConsumeGestureOnNavigation", base::FEATURE_ENABLED_BY_DEFAULT};
-
const int kExtraCharsBeforeAndAfterSelection = 100;
// Maximum number of burst download requests allowed.
@@ -422,8 +439,7 @@ WebURLRequest CreateURLRequestForNavigation(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
std::unique_ptr<NavigationResponseOverrideParameters> response_override,
- bool is_view_source_mode_enabled,
- bool is_same_document_navigation) {
+ bool is_view_source_mode_enabled) {
// Use the original navigation url to construct the WebURLRequest. The
// WebURLloaderImpl will replay the redirects afterwards and will eventually
// commit the final url.
@@ -456,10 +472,11 @@ WebURLRequest CreateURLRequestForNavigation(
request.SetHTTPReferrer(web_referrer, common_params.referrer.policy);
}
- request.SetIsSameDocumentNavigation(is_same_document_navigation);
request.SetPreviewsState(
static_cast<WebURLRequest::PreviewsState>(common_params.previews_state));
+ request.SetOriginPolicy(WebString::FromUTF8(common_params.origin_policy));
+
auto extra_data = std::make_unique<RequestExtraData>();
extra_data->set_navigation_response_override(std::move(response_override));
extra_data->set_navigation_initiated_by_renderer(
@@ -467,56 +484,17 @@ WebURLRequest CreateURLRequestForNavigation(
request.SetExtraData(std::move(extra_data));
request.SetWasDiscarded(request_params.was_discarded);
- // Set the ui timestamp for this navigation. Currently the timestamp here is
- // only non empty when the navigation was triggered by an Android intent. The
- // timestamp is converted to a double version supported by blink. It will be
- // passed back to the browser in the DidCommitProvisionalLoad and the
- // DocumentLoadComplete IPCs.
- base::TimeDelta ui_timestamp = common_params.ui_timestamp - base::TimeTicks();
- request.SetUiStartTime(ui_timestamp.InSecondsF());
- request.SetInputPerfMetricReportPolicy(
- static_cast<WebURLRequest::InputToLoadPerfMetricReportPolicy>(
- common_params.report_type));
return request;
}
-// Sanitizes the navigation_start timestamp for browser-initiated navigations,
-// where the browser possibly has a better notion of start time than the
-// renderer. In the case of cross-process navigations, this carries over the
-// time of finishing the onbeforeunload handler of the previous page.
-// TimeTicks is sometimes not monotonic across processes, and because
-// |browser_navigation_start| is likely before this process existed,
-// InterProcessTimeTicksConverter won't help. The timestamp is sanitized by
-// clamping it to renderer_navigation_start, initialized earlier in the call
-// stack.
-base::TimeTicks SanitizeNavigationTiming(
- const base::TimeTicks& browser_navigation_start,
- const base::TimeTicks& renderer_navigation_start) {
- DCHECK(!browser_navigation_start.is_null());
- return std::min(browser_navigation_start, renderer_navigation_start);
-}
-
CommonNavigationParams MakeCommonNavigationParams(
- const blink::WebFrameClient::NavigationPolicyInfo& info,
+ const blink::WebLocalFrameClient::NavigationPolicyInfo& info,
int load_flags) {
Referrer referrer(
GURL(info.url_request.HttpHeaderField(WebString::FromUTF8("Referer"))
.Latin1()),
info.url_request.GetReferrerPolicy());
- // Set the ui timestamp for this navigation. Currently the timestamp here is
- // only non empty when the navigation was triggered by an Android intent, or
- // by the user clicking on a link. The timestamp is converted from a double
- // version supported by blink. It will be passed back to the renderer in the
- // CommitNavigation IPC, and then back to the browser again in the
- // DidCommitProvisionalLoad and the DocumentLoadComplete IPCs.
- base::TimeTicks ui_timestamp =
- base::TimeTicks() +
- base::TimeDelta::FromSecondsD(info.url_request.UiStartTime());
- FrameMsg_UILoadMetricsReportType::Value report_type =
- static_cast<FrameMsg_UILoadMetricsReportType::Value>(
- info.url_request.InputPerfMetricReportPolicy());
-
// No history-navigation is expected to happen.
DCHECK(info.navigation_type != blink::kWebNavigationTypeBackForward);
@@ -549,8 +527,7 @@ CommonNavigationParams MakeCommonNavigationParams(
DCHECK(extra_data);
return CommonNavigationParams(
info.url_request.Url(), referrer, extra_data->transition_type(),
- navigation_type, true, info.replaces_current_history_item, ui_timestamp,
- report_type, GURL(), GURL(),
+ navigation_type, true, info.replaces_current_history_item, GURL(), GURL(),
static_cast<PreviewsState>(info.url_request.GetPreviewsState()),
base::TimeTicks::Now(), info.url_request.HttpMethod().Latin1(),
GetRequestBodyForWebURLRequest(info.url_request), source_location,
@@ -816,6 +793,139 @@ blink::mojom::BlobURLTokenPtrInfo CloneBlobURLToken(
return result;
}
+// Creates a fully functional DocumentState in the case where we do not have
+// pending_navigation_params_ available in the RenderFrameImpl.
+std::unique_ptr<DocumentState> BuildDocumentState() {
+ std::unique_ptr<DocumentState> document_state =
+ std::make_unique<DocumentState>();
+ document_state->set_navigation_state(
+ NavigationStateImpl::CreateContentInitiated());
+ return document_state;
+}
+
+// Creates a fully functional DocumentState in the case where we have
+// pending_navigation_params_ available in the RenderFrameImpl.
+// TODO(ahemery): This currently removes the callback from the pending params
+// which is a bit counterintuitive. We would like to leave
+// pending_navigation_params in a valid state. Callback should probably not be
+// a part of PendingNavigationParams.
+std::unique_ptr<DocumentState> BuildDocumentStateFromPending(
+ PendingNavigationParams* pending_navigation_params) {
+ std::unique_ptr<DocumentState> document_state(new DocumentState());
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDocumentState(document_state.get());
+
+ const CommonNavigationParams& common_params =
+ pending_navigation_params->common_params;
+ const RequestNavigationParams& request_params =
+ pending_navigation_params->request_params;
+
+ DCHECK(!common_params.navigation_start.is_null());
+ DCHECK(!common_params.url.SchemeIs(url::kJavaScriptScheme));
+
+ if (common_params.navigation_type == FrameMsg_Navigate_Type::RESTORE) {
+ // We're doing a load of a page that was restored from the last session.
+ // By default this prefers the cache over loading
+ // (LOAD_SKIP_CACHE_VALIDATION) which can result in stale data for pages
+ // that are set to expire. We explicitly override that by setting the
+ // policy here so that as necessary we load from the network.
+ //
+ // TODO(davidben): Remove this in favor of passing a cache policy to the
+ // loadHistoryItem call in OnNavigate. That requires not overloading
+ // UseProtocolCachePolicy to mean both "normal load" and "determine cache
+ // policy based on load type, etc".
+ internal_data->set_cache_policy_override(
+ blink::mojom::FetchCacheMode::kDefault);
+ }
+
+ internal_data->set_is_overriding_user_agent(
+ request_params.is_overriding_user_agent);
+ internal_data->set_must_reset_scroll_and_scale_state(
+ common_params.navigation_type ==
+ FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL);
+ document_state->set_can_load_local_resources(
+ request_params.can_load_local_resources);
+
+ bool load_data = !common_params.base_url_for_data_url.is_empty() &&
+ !common_params.history_url_for_data_url.is_empty() &&
+ common_params.url.SchemeIs(url::kDataScheme);
+ document_state->set_was_load_data_with_base_url_request(load_data);
+ if (load_data)
+ document_state->set_data_url(common_params.url);
+
+ document_state->set_navigation_state(
+ NavigationStateImpl::CreateBrowserInitiated(
+ pending_navigation_params->common_params,
+ pending_navigation_params->request_params,
+ pending_navigation_params->time_commit_requested,
+ std::move(pending_navigation_params->commit_callback_)));
+ return document_state;
+}
+
+void ApplyFilePathAlias(blink::WebURLRequest* request) {
+ const base::CommandLine::StringType file_url_path_alias =
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(
+ switches::kFileUrlPathAlias);
+ if (file_url_path_alias.empty())
+ return;
+
+ const auto alias_mapping =
+ base::SplitString(file_url_path_alias, FILE_PATH_LITERAL("="),
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ if (alias_mapping.size() != 2) {
+ LOG(ERROR) << "Invalid file path alias format.";
+ return;
+ }
+
+#if defined(OS_WIN)
+ base::string16 path = request->Url().GetString().Utf16();
+ const base::string16 file_prefix =
+ base::ASCIIToUTF16(url::kFileScheme) +
+ base::ASCIIToUTF16(url::kStandardSchemeSeparator);
+#else
+ std::string path = request->Url().GetString().Utf8();
+ const std::string file_prefix =
+ std::string(url::kFileScheme) + url::kStandardSchemeSeparator;
+#endif
+ if (!base::StartsWith(path, file_prefix + alias_mapping[0],
+ base::CompareCase::SENSITIVE)) {
+ return;
+ }
+
+ base::ReplaceFirstSubstringAfterOffset(&path, 0, alias_mapping[0],
+ alias_mapping[1]);
+ request->SetURL(blink::WebURL(GURL(path)));
+}
+
+// Packs all navigation timings sent by the browser to a blink understandable
+// format, blink::WebNavigationTimings.
+blink::WebNavigationTimings BuildNavigationTimings(
+ const base::TimeTicks& navigation_start,
+ const NavigationTiming& browser_navigation_timings) {
+ blink::WebNavigationTimings renderer_navigation_timings;
+
+ // Sanitizes the navigation_start timestamp for browser-initiated navigations,
+ // where the browser possibly has a better notion of start time than the
+ // renderer. In the case of cross-process navigations, this carries over the
+ // time of finishing the onbeforeunload handler of the previous page.
+ // TimeTicks is sometimes not monotonic across processes, and because
+ // |browser_navigation_start| is likely before this process existed,
+ // InterProcessTimeTicksConverter won't help. The timestamp is sanitized by
+ // clamping it to now.
+ DCHECK(!navigation_start.is_null());
+ renderer_navigation_timings.navigation_start =
+ std::min(navigation_start, base::TimeTicks::Now());
+
+ renderer_navigation_timings.redirect_start =
+ browser_navigation_timings.redirect_start;
+ renderer_navigation_timings.redirect_end =
+ browser_navigation_timings.redirect_end;
+ renderer_navigation_timings.fetch_start =
+ browser_navigation_timings.fetch_start;
+
+ return renderer_navigation_timings;
+}
+
} // namespace
class RenderFrameImpl::FrameURLLoaderFactory
@@ -828,7 +938,8 @@ class RenderFrameImpl::FrameURLLoaderFactory
std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
const WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
+ std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle>
+ task_runner_handle) override {
// This should not be called if the frame is detached.
DCHECK(frame_);
@@ -837,9 +948,18 @@ class RenderFrameImpl::FrameURLLoaderFactory
frame_->GetFrameHost()->IssueKeepAliveHandle(
mojo::MakeRequest(&keep_alive_handle));
}
+ scoped_refptr<network::SharedURLLoaderFactory> loader_factory =
+ frame_->GetLoaderFactoryBundle();
+ if (request.GetRequestContext() == WebURLRequest::kRequestContextPrefetch &&
+ frame_->prefetch_loader_factory_) {
+ // The frame should be alive when this factory is used.
+ loader_factory =
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+ frame_->prefetch_loader_factory_.get());
+ }
return std::make_unique<WebURLLoaderImpl>(
RenderThreadImpl::current()->resource_dispatcher(),
- std::move(task_runner), frame_->GetLoaderFactoryBundle(),
+ std::move(task_runner_handle), std::move(loader_factory),
std::move(keep_alive_handle));
}
@@ -908,11 +1028,20 @@ void HandleChromeDebugURL(const GURL& url) {
// base::debug::SetDumpWithoutCrashingFunction. Refer to the documentation
// of base::debug::DumpWithoutCrashing for more details.
base::debug::DumpWithoutCrashing();
+#if defined(OS_WIN) || defined(OS_POSIX)
} else if (url == kChromeUIKillURL) {
LOG(ERROR) << "Intentionally terminating current process because user"
" navigated to "
<< url.spec();
- base::Process::TerminateCurrentProcessImmediately(1);
+ // Simulate termination such that the base::GetTerminationStatus() API will
+ // return TERMINATION_STATUS_PROCESS_WAS_KILLED.
+#if defined(OS_WIN)
+ base::Process::TerminateCurrentProcessImmediately(
+ base::win::kProcessKilledExitCode);
+#elif defined(OS_POSIX)
+ PCHECK(kill(base::Process::Current().Pid(), SIGTERM) == 0);
+#endif
+#endif // defined(OS_WIN) || defined(OS_POSIX)
} else if (url == kChromeUIHangURL) {
LOG(ERROR) << "Intentionally hanging ourselves with sleep infinite loop"
<< " because user navigated to " << url.spec();
@@ -1334,6 +1463,7 @@ RenderFrameImpl::RenderFrameImpl(CreateParams params)
frame_bindings_control_binding_(this),
frame_navigation_control_binding_(this),
fullscreen_binding_(this),
+ navigation_client_impl_(nullptr),
has_accessed_initial_document_(false),
media_factory_(this,
base::Bind(&RenderFrameImpl::RequestOverlayRoutingToken,
@@ -1369,6 +1499,9 @@ RenderFrameImpl::RenderFrameImpl(CreateParams params)
#endif
manifest_manager_ = std::make_unique<ManifestManager>(this);
+ // TODO(ajwong): This always returns true as is_main_frame_ gets initialized
+ // later in RenderFrameImpl::Initialize(). Should the conditional be in
+ // RenderFrameImpl::Initialize()? https://crbug.com/840533
if (IsMainFrame()) {
// Manages its own lifetime.
new ManifestChangeNotifier(this);
@@ -1401,6 +1534,12 @@ RenderFrameImpl::~RenderFrameImpl() {
if (auto* factory = AudioOutputIPCFactory::get())
factory->MaybeDeregisterRemoteFactory(GetRoutingID());
+ // |thread| may be null in tests.
+ if (auto* thread = RenderThreadImpl::current()) {
+ if (auto* controller = thread->low_memory_mode_controller())
+ controller->OnFrameDestroyed(IsMainFrame());
+ }
+
if (is_main_frame_) {
// Ensure the RenderView doesn't point to this object, once it is destroyed.
// TODO(nasko): Add a check that the |main_render_frame_| of |render_view_|
@@ -1436,6 +1575,12 @@ void RenderFrameImpl::Initialize() {
"parent", parent_id);
}
+ // |thread| may be null in tests.
+ if (auto* thread = RenderThreadImpl::current()) {
+ if (auto* controller = thread->low_memory_mode_controller())
+ controller->OnFrameCreated(IsMainFrame());
+ }
+
#if BUILDFLAG(ENABLE_PLUGINS)
new PepperBrowserConnection(this);
#endif
@@ -1562,14 +1707,14 @@ RenderWidgetFullscreenPepper* RenderFrameImpl::CreatePepperFullscreenContainer(
// Synchronous IPC to obtain a routing id for the fullscreen widget.
int32_t fullscreen_widget_routing_id = MSG_ROUTING_NONE;
if (!RenderThreadImpl::current_render_message_filter()
- ->CreateFullscreenWidget(render_view()->routing_id(),
+ ->CreateFullscreenWidget(render_view()->GetRoutingID(),
std::move(widget_channel),
&fullscreen_widget_routing_id)) {
return nullptr;
}
RenderWidget::ShowCallback show_callback =
- base::Bind(&RenderViewImpl::ShowCreatedFullscreenWidget,
- render_view()->GetWeakPtr());
+ base::BindOnce(&RenderViewImpl::ShowCreatedFullscreenWidget,
+ render_view()->GetWeakPtr());
// TODO(fsamuel): It's not clear if we should be passing in the
// web ScreenInfo or the original ScreenInfo here.
@@ -1778,6 +1923,7 @@ bool RenderFrameImpl::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(FrameMsg_SetOverlayRoutingToken,
OnSetOverlayRoutingToken)
IPC_MESSAGE_HANDLER(FrameMsg_NotifyUserActivation, OnNotifyUserActivation)
+ IPC_MESSAGE_HANDLER(FrameMsg_MediaPlayerActionAt, OnMediaPlayerActionAt)
#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
#if defined(OS_MACOSX)
@@ -1837,6 +1983,12 @@ void RenderFrameImpl::BindFrameNavigationControl(
std::move(request), GetTaskRunner(blink::TaskType::kInternalIPC));
}
+void RenderFrameImpl::BindNavigationClient(
+ mojom::NavigationClientAssociatedRequest request) {
+ navigation_client_impl_ = std::make_unique<NavigationClient>(this);
+ navigation_client_impl_->Bind(std::move(request));
+}
+
blink::mojom::ManifestManager& RenderFrameImpl::GetManifestManager() {
return *manifest_manager_;
}
@@ -1897,6 +2049,12 @@ void RenderFrameImpl::OnSwapOut(
bool is_main_frame = is_main_frame_;
int routing_id = GetRoutingID();
+ // Before |this| is destroyed, grab the TaskRunner to be used for sending the
+ // SwapOut ACK. This will be used to schedule SwapOut ACK to be sent after
+ // any postMessage IPCs scheduled from the unload event above.
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner =
+ GetTaskRunner(blink::TaskType::kPostedMessage);
+
// Now that all of the cleanup is complete and the browser side is notified,
// start using the RenderFrameProxy.
//
@@ -1931,15 +2089,23 @@ void RenderFrameImpl::OnSwapOut(
// process that is now rendering the frame.
proxy->SetReplicatedState(replicated_frame_state);
- // Safe to exit if no one else is using the process.
- // TODO(nasko): Remove the dependency on RenderViewImpl here and ref count
- // the process based on the lifetime of this RenderFrameImpl object.
- if (is_main_frame)
- render_view->WasSwappedOut();
-
// Notify the browser that this frame was swapped. Use the RenderThread
- // directly because |this| is deleted.
- RenderThread::Get()->Send(new FrameHostMsg_SwapOut_ACK(routing_id));
+ // directly because |this| is deleted. Post a task to send the ACK, so that
+ // any postMessage IPCs scheduled from the unload handler are sent before
+ // the ACK (see https://crbug.com/857274).
+ auto send_swapout_ack = base::BindOnce(
+ [](int routing_id, bool is_main_frame) {
+ RenderThread::Get()->Send(new FrameHostMsg_SwapOut_ACK(routing_id));
+ // Now that the unload handler, and any postMessages posted from it,
+ // have finished, and we've sent the swapout ACK, it's safe to exit if
+ // no one else is using the process. Release the process if we've
+ // swapped the main frame out, and hence transitioned the
+ // RenderView/Widget to swapped out state.
+ if (is_main_frame)
+ RenderProcess::current()->ReleaseProcess();
+ },
+ routing_id, is_main_frame);
+ task_runner->PostTask(FROM_HERE, std::move(send_swapout_ack));
}
void RenderFrameImpl::OnSwapIn() {
@@ -2311,8 +2477,8 @@ void RenderFrameImpl::OnPostMessageEvent(
}
void RenderFrameImpl::OnReload(bool bypass_cache) {
- frame_->Reload(bypass_cache ? WebFrameLoadType::kReloadBypassingCache
- : WebFrameLoadType::kReload);
+ frame_->StartReload(bypass_cache ? WebFrameLoadType::kReloadBypassingCache
+ : WebFrameLoadType::kReload);
}
void RenderFrameImpl::OnReloadLoFiImages() {
@@ -2356,13 +2522,22 @@ bool RenderFrameImpl::RunJavaScriptDialog(JavaScriptDialogType type,
message_length);
}
+ if (is_main_frame_)
+ UMA_HISTOGRAM_COUNTS("JSDialogs.CharacterCount.MainFrame", message_length);
+ else
+ UMA_HISTOGRAM_COUNTS("JSDialogs.CharacterCount.Subframe", message_length);
+
+ // 10k ought to be enough for anyone.
+ const base::string16::size_type kMaxMessageSize = 10 * 1024;
+ base::string16 truncated_message = message.substr(0, kMaxMessageSize);
+
bool success = false;
base::string16 result_temp;
if (!result)
result = &result_temp;
- Send(new FrameHostMsg_RunJavaScriptDialog(routing_id_, message, default_value,
- type, &success, result));
+ Send(new FrameHostMsg_RunJavaScriptDialog(
+ routing_id_, truncated_message, default_value, type, &success, result));
return success;
}
@@ -2426,10 +2601,8 @@ void RenderFrameImpl::DidFailProvisionalLoadInternal(
// 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());
+ NavigationStateImpl* navigation_state = static_cast<NavigationStateImpl*>(
+ DocumentState::FromDocumentLoader(document_loader)->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.
@@ -2442,13 +2615,23 @@ void RenderFrameImpl::DidFailProvisionalLoadInternal(
if (!navigation_state->IsContentInitiated()) {
pending_navigation_params_.reset(new PendingNavigationParams(
navigation_state->common_params(), navigation_state->request_params(),
- base::TimeTicks() // not used for failed navigation.
- ));
+ base::TimeTicks(), // not used for failed navigation.
+ CommitNavigationCallback()));
}
- // Load an error page.
+ std::unique_ptr<DocumentState> document_state;
+ // If we sent a successful navigation to commit but for whatever reason the
+ // commit was interrupted we might end up with empty
+ // |pending_navigation_params_| here. For example, if
+ // there's no byte in the response and the network connection gets closed. In
+ // that case, the provisional load does not commit and we get a
+ // DidFailProvisionalLoad.
+ if (pending_navigation_params_)
+ document_state =
+ BuildDocumentStateFromPending(pending_navigation_params_.get());
+
LoadNavigationErrorPage(failed_request, error, replace, nullptr,
- error_page_content);
+ error_page_content, std::move(document_state));
}
void RenderFrameImpl::LoadNavigationErrorPage(
@@ -2456,7 +2639,8 @@ void RenderFrameImpl::LoadNavigationErrorPage(
const WebURLError& error,
bool replace,
HistoryEntry* entry,
- const base::Optional<std::string>& error_page_content) {
+ const base::Optional<std::string>& error_page_content,
+ std::unique_ptr<blink::WebDocumentLoader::ExtraData> navigation_data) {
blink::WebFrameLoadType frame_load_type =
entry ? blink::WebFrameLoadType::kBackForward
: blink::WebFrameLoadType::kStandard;
@@ -2475,7 +2659,8 @@ void RenderFrameImpl::LoadNavigationErrorPage(
const blink::WebHistoryItem& blank_history_item = blink::WebHistoryItem();
frame_load_type = blink::WebFrameLoadType::kStandard;
LoadNavigationErrorPageInternal("", GURL("data:,"), WebURL(), replace,
- frame_load_type, blank_history_item);
+ frame_load_type, blank_history_item,
+ std::move(navigation_data));
return;
}
@@ -2490,7 +2675,7 @@ void RenderFrameImpl::LoadNavigationErrorPage(
}
LoadNavigationErrorPageInternal(error_html, GURL(kUnreachableWebDataURL),
error.url(), replace, frame_load_type,
- history_item);
+ history_item, std::move(navigation_data));
}
void RenderFrameImpl::LoadNavigationErrorPageForHttpStatusError(
@@ -2498,7 +2683,8 @@ void RenderFrameImpl::LoadNavigationErrorPageForHttpStatusError(
const GURL& unreachable_url,
int http_status,
bool replace,
- HistoryEntry* entry) {
+ HistoryEntry* entry,
+ std::unique_ptr<blink::WebDocumentLoader::ExtraData> navigation_data) {
blink::WebFrameLoadType frame_load_type =
entry ? blink::WebFrameLoadType::kBackForward
: blink::WebFrameLoadType::kStandard;
@@ -2508,9 +2694,10 @@ void RenderFrameImpl::LoadNavigationErrorPageForHttpStatusError(
std::string error_html;
GetContentClient()->renderer()->PrepareErrorPageForHttpStatusError(
this, failed_request, unreachable_url, http_status, &error_html, nullptr);
+ std::unique_ptr<DocumentState> document_state(BuildDocumentState());
LoadNavigationErrorPageInternal(error_html, GURL(kUnreachableWebDataURL),
unreachable_url, replace, frame_load_type,
- history_item);
+ history_item, std::move(document_state));
}
void RenderFrameImpl::LoadNavigationErrorPageInternal(
@@ -2519,11 +2706,13 @@ void RenderFrameImpl::LoadNavigationErrorPageInternal(
const GURL& error_url,
bool replace,
blink::WebFrameLoadType frame_load_type,
- const blink::WebHistoryItem& history_item) {
- frame_->LoadData(error_html, WebString::FromUTF8("text/html"),
- WebString::FromUTF8("UTF-8"), error_page_url, error_url,
- replace, frame_load_type, history_item,
- blink::kWebHistoryDifferentDocumentLoad, false);
+ const blink::WebHistoryItem& history_item,
+ std::unique_ptr<blink::WebDocumentLoader::ExtraData> navigation_data) {
+ frame_->CommitDataNavigation(error_html, WebString::FromUTF8("text/html"),
+ WebString::FromUTF8("UTF-8"), error_page_url,
+ error_url, replace, frame_load_type,
+ history_item, false, std::move(navigation_data),
+ blink::WebNavigationTimings());
}
void RenderFrameImpl::DidMeaningfulLayout(
@@ -2646,11 +2835,11 @@ void RenderFrameImpl::LoadErrorPage(int reason) {
this, frame_->GetDocumentLoader()->GetRequest(), error, &error_html,
nullptr);
- frame_->LoadData(error_html, WebString::FromUTF8("text/html"),
- WebString::FromUTF8("UTF-8"), GURL(kUnreachableWebDataURL),
- error.url(), true, blink::WebFrameLoadType::kStandard,
- blink::WebHistoryItem(),
- blink::kWebHistoryDifferentDocumentLoad, true);
+ frame_->CommitDataNavigation(
+ error_html, WebString::FromUTF8("text/html"),
+ WebString::FromUTF8("UTF-8"), GURL(kUnreachableWebDataURL), error.url(),
+ true, blink::WebFrameLoadType::kStandard, blink::WebHistoryItem(), true,
+ nullptr /* navigation_data */, blink::WebNavigationTimings());
}
void RenderFrameImpl::ExecuteJavaScript(const base::string16& javascript) {
@@ -2746,6 +2935,14 @@ void RenderFrameImpl::SetSelectedText(const base::string16& selection_text,
static_cast<uint32_t>(offset), range));
}
+void RenderFrameImpl::SetZoomLevel(double zoom_level) {
+ render_view_->UpdateZoomLevel(zoom_level);
+}
+
+double RenderFrameImpl::GetZoomLevel() const {
+ return render_view_->page_zoom_level();
+}
+
void RenderFrameImpl::AddMessageToConsole(ConsoleMessageLevel level,
const std::string& message) {
blink::WebConsoleMessage::Level target_level =
@@ -2868,7 +3065,9 @@ void RenderFrameImpl::CommitNavigation(
base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
subresource_overrides,
mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
- const base::UnguessableToken& devtools_navigation_token) {
+ network::mojom::URLLoaderFactoryPtr prefetch_loader_factory,
+ const base::UnguessableToken& devtools_navigation_token,
+ CommitNavigationCallback callback) {
DCHECK(!IsRendererDebugURL(common_params.url));
DCHECK(
!FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type));
@@ -2879,10 +3078,12 @@ void RenderFrameImpl::CommitNavigation(
browser_side_navigation_pending_url_ == request_params.original_url &&
request_params.nav_entry_id == 0) {
browser_side_navigation_pending_url_ = GURL();
+ std::move(callback).Run(blink::mojom::CommitResult::Aborted);
return;
}
controller_service_worker_info_ = std::move(controller_service_worker_info);
+ prefetch_loader_factory_ = std::move(prefetch_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.
@@ -2908,9 +3109,12 @@ void RenderFrameImpl::CommitNavigation(
if (request_params.is_view_source)
frame_->EnableViewSourceMode(true);
- pending_navigation_params_.reset(new PendingNavigationParams(
- common_params, request_params, base::TimeTicks::Now()));
- PrepareFrameForCommit();
+ pending_navigation_params_.reset(
+ new PendingNavigationParams(common_params, request_params,
+ base::TimeTicks::Now(), std::move(callback)));
+ PrepareFrameForCommit(common_params.url, request_params);
+ std::unique_ptr<DocumentState> document_state(
+ BuildDocumentStateFromPending(pending_navigation_params_.get()));
blink::WebFrameLoadType load_type = NavigationTypeToLoadType(
common_params.navigation_type, common_params.should_replace_current_entry,
@@ -2946,16 +3150,17 @@ void RenderFrameImpl::CommitNavigation(
#endif
if (is_main_frame_ && should_load_data_url) {
LoadDataURL(common_params, request_params, frame_, load_type,
- item_for_history_navigation,
- blink::kWebHistoryDifferentDocumentLoad, is_client_redirect);
+ item_for_history_navigation, is_client_redirect,
+ std::move(document_state));
} else {
WebURLRequest request = CreateURLRequestForCommit(
common_params, request_params, std::move(url_loader_client_endpoints),
head);
-
- frame_->CommitNavigation(request, load_type, item_for_history_navigation,
- blink::kWebHistoryDifferentDocumentLoad,
- is_client_redirect, devtools_navigation_token);
+ frame_->CommitNavigation(
+ request, load_type, item_for_history_navigation, is_client_redirect,
+ devtools_navigation_token, std::move(document_state),
+ BuildNavigationTimings(common_params.navigation_start,
+ request_params.navigation_timing));
// The commit 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,
@@ -2999,7 +3204,8 @@ void RenderFrameImpl::CommitFailedNavigation(
bool has_stale_copy_in_cache,
int error_code,
const base::Optional<std::string>& error_page_content,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories) {
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+ CommitFailedNavigationCallback callback) {
DCHECK(
!FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type));
bool is_reload =
@@ -3024,8 +3230,8 @@ void RenderFrameImpl::CommitFailedNavigation(
pending_navigation_params_.reset(new PendingNavigationParams(
common_params, request_params,
- base::TimeTicks() // Not used for failed navigation.
- ));
+ base::TimeTicks(), // Not used for failed navigation.
+ std::move(callback)));
// Send the provisional load failure.
WebURLError error(
@@ -3035,12 +3241,14 @@ void RenderFrameImpl::CommitFailedNavigation(
WebURLError::IsWebSecurityViolation::kFalse, common_params.url);
WebURLRequest failed_request = CreateURLRequestForNavigation(
common_params, request_params,
- /*response_override=*/nullptr, frame_->IsViewSourceModeEnabled(),
- false); // is_same_document_navigation
+ /*response_override=*/nullptr, frame_->IsViewSourceModeEnabled());
if (!ShouldDisplayErrorPageForFailedLoad(error_code, common_params.url)) {
// The browser expects this frame to be loading an error page. Inform it
// that the load stopped.
+ std::move(pending_navigation_params_->commit_callback_)
+ .Run(blink::mojom::CommitResult::Aborted);
+ pending_navigation_params_.reset();
Send(new FrameHostMsg_DidStopLoading(routing_id_));
browser_side_navigation_pending_ = false;
browser_side_navigation_pending_url_ = GURL();
@@ -3058,6 +3266,9 @@ void RenderFrameImpl::CommitFailedNavigation(
// either, as the frame has already been populated with something
// unrelated to this navigation failure. In that case, just send a stop
// IPC to the browser to unwind its state, and leave the frame as-is.
+ std::move(pending_navigation_params_->commit_callback_)
+ .Run(blink::mojom::CommitResult::Aborted);
+ pending_navigation_params_.reset();
Send(new FrameHostMsg_DidStopLoading(routing_id_));
}
browser_side_navigation_pending_ = false;
@@ -3109,8 +3320,10 @@ void RenderFrameImpl::CommitFailedNavigation(
// GetProvisionalDocumentLoader(), LoadNavigationErrorPage wasn't called, so
// do it now.
if (request_params.nav_entry_id != 0 || !had_provisional_document_loader) {
+ std::unique_ptr<DocumentState> document_state(
+ BuildDocumentStateFromPending(pending_navigation_params_.get()));
LoadNavigationErrorPage(failed_request, error, replace, history_entry.get(),
- error_page_content);
+ error_page_content, std::move(document_state));
if (!weak_this)
return;
}
@@ -3134,11 +3347,14 @@ void RenderFrameImpl::CommitSameDocumentNavigation(
common_params.has_user_gesture ? new blink::WebScopedUserGesture(frame_)
: nullptr);
+ // TODO(ahemery): |pending_navigation_params_| below is solely used by
+ // IsBrowserInitiated() in DecidePolicyForNavigation. Try and find a a way to
+ // avoid having to create the entire structure just for this.
pending_navigation_params_.reset(new PendingNavigationParams(
common_params, request_params,
- base::TimeTicks() // Not used for same-document navigation.
- ));
- PrepareFrameForCommit();
+ base::TimeTicks(), // Not used for same-document navigation.
+ CommitNavigationCallback()));
+ PrepareFrameForCommit(common_params.url, request_params);
blink::WebFrameLoadType load_type = NavigationTypeToLoadType(
common_params.navigation_type, common_params.should_replace_current_entry,
@@ -3231,7 +3447,8 @@ void RenderFrameImpl::SetHostZoomLevel(const GURL& url, double zoom_level) {
#endif
}
-// blink::WebFrameClient implementation ----------------------------------------
+// blink::WebLocalFrameClient implementation
+// ----------------------------------------
blink::WebPlugin* RenderFrameImpl::CreatePlugin(
const blink::WebPluginParams& params) {
@@ -3277,7 +3494,7 @@ blink::WebMediaPlayer* RenderFrameImpl::CreateMediaPlayer(
const blink::WebString& sink_id,
blink::WebLayerTreeView* layer_tree_view) {
const cc::LayerTreeSettings& settings =
- GetRenderWidget()->compositor()->GetLayerTreeSettings();
+ GetRenderWidget()->layer_tree_view()->GetLayerTreeSettings();
return media_factory_.CreateMediaPlayer(source, client, encrypted_client,
initial_cdm, sink_id, layer_tree_view,
settings);
@@ -3321,36 +3538,44 @@ RenderFrameImpl::CreateWorkerFetchContext() {
ServiceWorkerNetworkProvider::FromWebServiceWorkerNetworkProvider(
web_provider);
mojom::ServiceWorkerWorkerClientRequest service_worker_client_request;
+ mojom::ServiceWorkerWorkerClientRegistryPtrInfo
+ service_worker_worker_client_registry_ptr_info;
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) {
- service_worker_client_request =
- provider_context->CreateWorkerClientRequest();
+ provider_context->CloneWorkerClientRegistry(
+ mojo::MakeRequest(&service_worker_worker_client_registry_ptr_info));
+
+ mojom::ServiceWorkerWorkerClientPtr worker_client_ptr;
+ service_worker_client_request = mojo::MakeRequest(&worker_client_ptr);
+ provider_context->RegisterWorkerClient(std::move(worker_client_ptr));
+
// TODO(horo): Use this host pointer also when S13nServiceWorker is not
// enabled once we support navigator.serviceWorker on dedicated workers:
// crbug.com/371690. Currently we use this only to call
// GetControllerServiceWorker() from the worker thread if S13nServiceWorker
// is enabled.
- if (ServiceWorkerUtils::IsServicificationEnabled())
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
container_host_ptr_info = provider_context->CloneContainerHostPtrInfo();
}
- std::unique_ptr<WorkerFetchContextImpl> worker_fetch_context =
- std::make_unique<WorkerFetchContextImpl>(
- std::move(service_worker_client_request),
- std::move(container_host_ptr_info), GetLoaderFactoryBundle()->Clone(),
- GetLoaderFactoryBundle()->CloneWithoutDefaultFactory(),
- GetContentClient()->renderer()->CreateURLLoaderThrottleProvider(
- URLLoaderThrottleProviderType::kWorker),
- GetContentClient()
- ->renderer()
- ->CreateWebSocketHandshakeThrottleProvider(),
- ChildThreadImpl::current()->thread_safe_sender(),
- RenderThreadImpl::current()->GetIOTaskRunner());
-
- worker_fetch_context->set_parent_frame_id(routing_id_);
+ auto worker_fetch_context = std::make_unique<WebWorkerFetchContextImpl>(
+ render_view_->renderer_preferences(),
+ std::move(service_worker_client_request),
+ std::move(service_worker_worker_client_registry_ptr_info),
+ std::move(container_host_ptr_info), GetLoaderFactoryBundle()->Clone(),
+ GetLoaderFactoryBundle()->CloneWithoutDefaultFactory(),
+ GetContentClient()->renderer()->CreateURLLoaderThrottleProvider(
+ URLLoaderThrottleProviderType::kWorker),
+ GetContentClient()
+ ->renderer()
+ ->CreateWebSocketHandshakeThrottleProvider(),
+ ChildThreadImpl::current()->thread_safe_sender(),
+ ChildThreadImpl::current()->GetConnector()->Clone());
+
+ worker_fetch_context->set_ancestor_frame_id(routing_id_);
worker_fetch_context->set_site_for_cookies(
frame_->GetDocument().SiteForCookies());
worker_fetch_context->set_is_secure_context(
@@ -3687,8 +3912,9 @@ void RenderFrameImpl::DidMatchCSS(
observer.DidMatchCSS(newly_matching_selectors, stopped_matching_selectors);
}
-void RenderFrameImpl::SetHasReceivedUserGesture() {
- Send(new FrameHostMsg_SetHasReceivedUserGesture(routing_id_));
+void RenderFrameImpl::UpdateUserActivationState(
+ blink::UserActivationUpdateType update_type) {
+ Send(new FrameHostMsg_UpdateUserActivationState(routing_id_, update_type));
}
void RenderFrameImpl::SetHasReceivedUserGestureBeforeNavigation(bool value) {
@@ -3744,6 +3970,7 @@ void RenderFrameImpl::DidAddMessageToConsole(
void RenderFrameImpl::DownloadURL(
const blink::WebURLRequest& request,
+ CrossOriginRedirects cross_origin_redirect_behavior,
mojo::ScopedMessagePipeHandle blob_url_token) {
if (ShouldThrottleDownload())
return;
@@ -3756,6 +3983,8 @@ void RenderFrameImpl::DownloadURL(
params.initiator_origin = request.RequestorOrigin();
if (request.GetSuggestedFilename().has_value())
params.suggested_name = request.GetSuggestedFilename()->Utf16();
+ params.follow_cross_origin_redirects =
+ (cross_origin_redirect_behavior == CrossOriginRedirects::kFollow);
params.blob_url_token = blob_url_token.release();
Send(new FrameHostMsg_DownloadUrl(params));
@@ -3791,95 +4020,55 @@ void RenderFrameImpl::WillSubmitForm(const blink::WebFormElement& form) {
void RenderFrameImpl::DidCreateDocumentLoader(
blink::WebDocumentLoader* document_loader) {
- bool content_initiated = !pending_navigation_params_.get();
+ // Ensure that the pending_navigation_params are destroyed when doing an
+ // early return.
+ std::unique_ptr<PendingNavigationParams> pending_navigation_params(
+ std::move(pending_navigation_params_));
+ bool has_pending_params = pending_navigation_params.get();
DocumentState* document_state =
DocumentState::FromDocumentLoader(document_loader);
if (!document_state) {
- document_state = new DocumentState;
- document_loader->SetExtraData(document_state);
- if (!content_initiated)
- PopulateDocumentStateFromPending(document_state);
- }
-
- // Carry over the user agent override flag, if it exists.
- // TODO(lukasza): https://crbug.com/426555: Need OOPIF support for propagating
- // user agent overrides.
- blink::WebView* webview = render_view_->webview();
- if (content_initiated && webview && webview->MainFrame() &&
- webview->MainFrame()->IsWebLocalFrame() &&
- webview->MainFrame()->ToWebLocalFrame()->GetDocumentLoader()) {
- DocumentState* old_document_state = DocumentState::FromDocumentLoader(
- webview->MainFrame()->ToWebLocalFrame()->GetDocumentLoader());
- if (old_document_state) {
- InternalDocumentStateData* internal_data =
- InternalDocumentStateData::FromDocumentState(document_state);
- InternalDocumentStateData* old_internal_data =
- InternalDocumentStateData::FromDocumentState(old_document_state);
- internal_data->set_is_overriding_user_agent(
- old_internal_data->is_overriding_user_agent());
- }
+ // This is either a placeholder document loader or an initial empty
+ // document.
+ document_loader->SetExtraData(BuildDocumentState());
}
- // The rest of RenderView assumes that a WebDocumentLoader will always have a
- // non-null NavigationState.
- UpdateNavigationState(document_state, false /* was_within_same_document */,
- content_initiated);
-
- NavigationStateImpl* navigation_state = static_cast<NavigationStateImpl*>(
- document_state->navigation_state());
-
- // Set the navigation start time in blink.
- document_loader->SetNavigationStartTime(
- navigation_state->common_params().navigation_start);
+ // Create the serviceworker's per-document network observing object.
+ // Same document navigation do not go through here so it should never exist.
+ DCHECK(!document_loader->GetServiceWorkerNetworkProvider());
+ scoped_refptr<network::SharedURLLoaderFactory> fallback_factory =
+ network::SharedURLLoaderFactory::Create(
+ GetLoaderFactoryBundle()->CloneWithoutDefaultFactory());
+ document_loader->SetServiceWorkerNetworkProvider(
+ ServiceWorkerNetworkProvider::CreateForNavigation(
+ routing_id_,
+ has_pending_params ? &(pending_navigation_params->request_params)
+ : nullptr,
+ frame_, std::move(controller_service_worker_info_),
+ std::move(fallback_factory)));
- // If an actual navigation took place, inform the document loader of what
- // happened in the browser.
- if (!navigation_state->request_params()
- .navigation_timing.fetch_start.is_null()) {
- // Set timing of several events that happened during navigation.
- // They will be used in blink for the Navigation Timing API.
- base::TimeTicks redirect_start =
- navigation_state->request_params().navigation_timing.redirect_start;
- base::TimeTicks redirect_end =
- navigation_state->request_params().navigation_timing.redirect_end;
- base::TimeTicks fetch_start =
- navigation_state->request_params().navigation_timing.fetch_start;
+ if (!has_pending_params)
+ return;
- document_loader->UpdateNavigation(
- redirect_start, redirect_end, fetch_start,
- !navigation_state->request_params().redirects.empty());
- }
+ const CommonNavigationParams& common_params =
+ pending_navigation_params->common_params;
+ const RequestNavigationParams& request_params =
+ pending_navigation_params->request_params;
// Update the source location before processing the navigation commit.
- if (navigation_state->common_params().source_location.has_value()) {
+ if (pending_navigation_params->common_params.source_location.has_value()) {
blink::WebSourceLocation source_location;
- source_location.url = WebString::FromLatin1(
- navigation_state->common_params().source_location->url);
- source_location.line_number =
- navigation_state->common_params().source_location->line_number;
+ source_location.url =
+ WebString::FromLatin1(common_params.source_location->url);
+ source_location.line_number = common_params.source_location->line_number;
source_location.column_number =
- navigation_state->common_params().source_location->column_number;
+ common_params.source_location->column_number;
document_loader->SetSourceLocation(source_location);
}
- if (navigation_state->request_params().was_activated)
+ if (request_params.was_activated)
document_loader->SetUserActivated();
-
- // Create the serviceworker's per-document network observing object if it
- // does not exist (When navigation happens within a page, the provider already
- // exists).
- if (document_loader->GetServiceWorkerNetworkProvider())
- return;
-
- scoped_refptr<network::SharedURLLoaderFactory> fallback_factory =
- network::SharedURLLoaderFactory::Create(
- GetLoaderFactoryBundle()->CloneWithoutDefaultFactory());
- document_loader->SetServiceWorkerNetworkProvider(
- ServiceWorkerNetworkProvider::CreateForNavigation(
- routing_id_, navigation_state->request_params(), frame_,
- content_initiated, std::move(controller_service_worker_info_),
- std::move(fallback_factory)));
}
void RenderFrameImpl::DidStartProvisionalLoad(
@@ -3945,19 +4134,11 @@ void RenderFrameImpl::DidStartProvisionalLoad(
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));
}
-void RenderFrameImpl::DidReceiveServerRedirectForProvisionalLoad() {
- // TODO(creis): Determine if this can be removed or if we need to clear any
- // local state here to fix https://crbug.com/671276.
-}
-
void RenderFrameImpl::DidFailProvisionalLoad(
const WebURLError& error,
blink::WebHistoryCommitType commit_type) {
@@ -4052,8 +4233,8 @@ void RenderFrameImpl::DidCommitProvisionalLoad(
// 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());
+ if (GetRenderWidget()->layer_tree_view())
+ GetRenderWidget()->layer_tree_view()->SetURLForUkm(GetLoadingUrl());
}
service_manager::mojom::InterfaceProviderRequest
@@ -4103,6 +4284,7 @@ void RenderFrameImpl::DidCommitProvisionalLoad(
if (media_permission_dispatcher_)
media_permission_dispatcher_->OnNavigation();
+ navigation_state->RunCommitNavigationCallback(blink::mojom::CommitResult::Ok);
DidCommitNavigationInternal(item, commit_type,
false /* was_within_same_document */,
std::move(remote_interface_provider_request));
@@ -4276,9 +4458,10 @@ void RenderFrameImpl::RunScriptsAtDocumentReady(bool document_is_empty) {
int http_status_code = internal_data->http_status_code();
if (GetContentClient()->renderer()->HasErrorPage(http_status_code)) {
// This call may run scripts, e.g. via the beforeunload event.
+ std::unique_ptr<DocumentState> document_state(BuildDocumentState());
LoadNavigationErrorPageForHttpStatusError(
frame_->GetDocumentLoader()->GetRequest(), frame_->GetDocument().Url(),
- http_status_code, true, nullptr);
+ http_status_code, true, nullptr, std::move(document_state));
}
// Do not use |this| or |frame_| here without checking |weak_self|.
}
@@ -4290,18 +4473,7 @@ void RenderFrameImpl::RunScriptsAtDocumentIdle() {
void RenderFrameImpl::DidHandleOnloadEvents() {
if (!frame_->Parent()) {
- FrameMsg_UILoadMetricsReportType::Value report_type =
- static_cast<FrameMsg_UILoadMetricsReportType::Value>(
- frame_->GetDocumentLoader()
- ->GetRequest()
- .InputPerfMetricReportPolicy());
- base::TimeTicks ui_timestamp =
- base::TimeTicks() +
- base::TimeDelta::FromSecondsD(
- frame_->GetDocumentLoader()->GetRequest().UiStartTime());
-
- Send(new FrameHostMsg_DocumentOnLoadCompleted(
- routing_id_, report_type, ui_timestamp));
+ Send(new FrameHostMsg_DocumentOnLoadCompleted(routing_id_));
}
}
@@ -4346,10 +4518,6 @@ void RenderFrameImpl::DidFinishLoad() {
return;
RecordSuffixedRendererMemoryMetrics(memory_metrics,
".MainFrameDidFinishLoad");
- if (!IsControlledByServiceWorker())
- return;
- RecordSuffixedRendererMemoryMetrics(
- memory_metrics, ".ServiceWorkerControlledMainFrameDidFinishLoad");
}
void RenderFrameImpl::DidFinishSameDocumentNavigation(
@@ -4361,8 +4529,21 @@ void RenderFrameImpl::DidFinishSameDocumentNavigation(
routing_id_);
DocumentState* document_state =
DocumentState::FromDocumentLoader(frame_->GetDocumentLoader());
- UpdateNavigationState(document_state, true /* was_within_same_document */,
- content_initiated);
+
+ // If this was a browser-initiated navigation, then there could be pending
+ // navigation params, so use them. Otherwise, just reset the document state
+ // here, since if pending navigation params exist they are for some other
+ // navigation <https://crbug.com/597239>.
+ if (!pending_navigation_params_ || content_initiated) {
+ document_state->set_navigation_state(
+ NavigationStateImpl::CreateContentInitiated());
+ } else {
+ DCHECK(
+ !pending_navigation_params_->common_params.navigation_start.is_null());
+ document_state->set_navigation_state(CreateNavigationStateFromPending());
+ pending_navigation_params_.reset();
+ }
+
static_cast<NavigationStateImpl*>(document_state->navigation_state())
->set_was_within_same_document(true);
@@ -4424,7 +4605,8 @@ base::UnguessableToken RenderFrameImpl::GetDevToolsFrameToken() {
void RenderFrameImpl::AbortClientNavigation() {
browser_side_navigation_pending_ = false;
- Send(new FrameHostMsg_AbortNavigation(routing_id_));
+ if (!IsPerNavigationMojoInterfaceEnabled())
+ Send(new FrameHostMsg_AbortNavigation(routing_id_));
}
void RenderFrameImpl::DidChangeSelection(bool is_empty_selection) {
@@ -4605,6 +4787,7 @@ void RenderFrameImpl::WillSendRequest(blink::WebURLRequest& request) {
transition_type | ui::PAGE_TRANSITION_CLIENT_REDIRECT);
}
+ ApplyFilePathAlias(&request);
GURL new_url;
bool attach_same_site_cookies = false;
base::Optional<url::Origin> initiator_origin =
@@ -4788,6 +4971,33 @@ void RenderFrameImpl::DidLoadResourceFromMemoryCache(
response.MimeType().Utf8(), WebURLRequestToResourceType(request)));
}
+void RenderFrameImpl::DidStartResponse(
+ int request_id,
+ const network::ResourceResponseHead& response_head,
+ content::ResourceType resource_type) {
+ for (auto& observer : observers_)
+ observer.DidStartResponse(request_id, response_head, resource_type);
+}
+
+void RenderFrameImpl::DidCompleteResponse(
+ int request_id,
+ const network::URLLoaderCompletionStatus& status) {
+ for (auto& observer : observers_)
+ observer.DidCompleteResponse(request_id, status);
+}
+
+void RenderFrameImpl::DidCancelResponse(int request_id) {
+ for (auto& observer : observers_)
+ observer.DidCancelResponse(request_id);
+}
+
+void RenderFrameImpl::DidReceiveTransferSizeUpdate(int resource_id,
+ int received_data_length) {
+ for (auto& observer : observers_) {
+ observer.DidReceiveTransferSizeUpdate(resource_id, received_data_length);
+ }
+}
+
void RenderFrameImpl::DidDisplayInsecureContent() {
Send(new FrameHostMsg_DidDisplayInsecureContent(routing_id_));
}
@@ -4920,7 +5130,7 @@ bool RenderFrameImpl::ShouldTrackUseCounter(const blink::WebURL& url) {
void RenderFrameImpl::DidCreateScriptContext(v8::Local<v8::Context> context,
int world_id) {
- if ((enabled_bindings_ & BINDINGS_POLICY_WEB_UI) && IsMainFrame() &&
+ if ((enabled_bindings_ & BINDINGS_POLICY_MOJO_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.
@@ -4944,11 +5154,6 @@ void RenderFrameImpl::DidChangeScrollOffset() {
observer.DidChangeScrollOffset();
}
-void RenderFrameImpl::WillInsertBody() {
- Send(new FrameHostMsg_WillInsertBody(routing_id_,
- render_view_->GetRoutingID()));
-}
-
void RenderFrameImpl::ReportFindInPageMatchCount(int request_id,
int count,
bool final_update) {
@@ -5088,6 +5293,10 @@ void RenderFrameImpl::ExitFullscreen() {
Send(new FrameHostMsg_ExitFullscreen(routing_id_));
}
+void RenderFrameImpl::FullscreenStateChanged(bool is_fullscreen) {
+ GetFrameHost()->FullscreenStateChanged(is_fullscreen);
+}
+
void RenderFrameImpl::SuddenTerminationDisablerChanged(
bool present,
blink::WebSuddenTerminationDisablerType disabler_type) {
@@ -5334,15 +5543,6 @@ RenderFrameImpl::MakeDidCommitProvisionalLoadParams(
params->history_list_was_cleared =
navigation_state->request_params().should_clear_history_list;
-
- params->report_type = static_cast<FrameMsg_UILoadMetricsReportType::Value>(
- frame_->GetDocumentLoader()
- ->GetRequest()
- .InputPerfMetricReportPolicy());
- params->ui_timestamp =
- base::TimeTicks() +
- base::TimeDelta::FromSecondsD(
- frame_->GetDocumentLoader()->GetRequest().UiStartTime());
} else {
// Subframe navigation: the type depends on whether this navigation
// generated a new session history entry. When they do generate a session
@@ -5355,7 +5555,6 @@ RenderFrameImpl::MakeDidCommitProvisionalLoadParams(
DCHECK(!navigation_state->request_params().should_clear_history_list);
params->history_list_was_cleared = false;
- params->report_type = FrameMsg_UILoadMetricsReportType::NO_REPORT;
}
// Standard URLs must match the reported origin, when it is not unique.
@@ -5552,27 +5751,16 @@ void RenderFrameImpl::DidCommitNavigationInternal(
}
}
-void RenderFrameImpl::PrepareFrameForCommit() {
+void RenderFrameImpl::PrepareFrameForCommit(
+ const GURL& url,
+ const RequestNavigationParams& request_params) {
browser_side_navigation_pending_ = false;
browser_side_navigation_pending_url_ = GURL();
GetContentClient()->SetActiveURL(
- pending_navigation_params_->common_params.url,
- frame_->Top()->GetSecurityOrigin().ToString().Utf8());
-
- RenderFrameImpl::PrepareRenderViewForNavigation(
- pending_navigation_params_->common_params.url,
- pending_navigation_params_->request_params);
-
- // Lower bound for browser initiated navigation start time.
- base::TimeTicks renderer_navigation_start = base::TimeTicks::Now();
+ url, frame_->Top()->GetSecurityOrigin().ToString().Utf8());
- // Sanitize navigation start and store in |pending_navigation_params_|.
- // It will be picked up in UpdateNavigationState.
- pending_navigation_params_->common_params.navigation_start =
- SanitizeNavigationTiming(
- pending_navigation_params_->common_params.navigation_start,
- renderer_navigation_start);
+ RenderFrameImpl::PrepareRenderViewForNavigation(url, request_params);
}
blink::mojom::CommitResult RenderFrameImpl::PrepareForHistoryNavigationCommit(
@@ -5595,9 +5783,7 @@ blink::mojom::CommitResult RenderFrameImpl::PrepareForHistoryNavigationCommit(
// store the relevant frame's WebHistoryItem in the root of the
// PageState.
*item_for_history_navigation = entry->root();
- *load_type = request_params.is_history_navigation_in_new_child
- ? blink::WebFrameLoadType::kInitialHistoryLoad
- : blink::WebFrameLoadType::kBackForward;
+ *load_type = blink::WebFrameLoadType::kBackForward;
// Keep track of which subframes the browser process has history items
// for during a history navigation.
@@ -5659,13 +5845,18 @@ bool RenderFrameImpl::SwapIn() {
in_frame_tree_ = true;
// If this is the main frame going from a remote frame to a local frame,
- // it needs to set RenderViewImpl's pointer for the main frame to itself
- // and ensure RenderWidget is no longer in swapped out mode.
+ // it needs to set RenderViewImpl's pointer for the main frame to itself,
+ // ensure RenderWidget is no longer in swapped out mode, and call
+ // AddRefProcess() to prevent the process from exiting. A matching
+ // ReleaseProcess() call will be made if the RenderWidget ever becomes
+ // swapped out again - see OnSwapOut().
if (is_main_frame_) {
CHECK(!render_view_->main_render_frame_);
render_view_->main_render_frame_ = this;
- if (render_view_->is_swapped_out())
+ if (render_view_->is_swapped_out()) {
render_view_->SetSwappedOut(false);
+ RenderProcess::current()->AddRefProcess();
+ }
render_view_->UpdateWebViewWithDeviceScaleFactor();
}
@@ -5753,6 +5944,13 @@ WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
->navigation_state()
->IsContentInitiated()
: !IsBrowserInitiated(pending_navigation_params_.get());
+ // TODO(dgozman): clean this up after some Canary coverage.
+ CHECK(!pending_navigation_params_);
+ if (info.extra_data) {
+ CHECK(static_cast<DocumentState*>(info.extra_data)
+ ->navigation_state()
+ ->IsContentInitiated());
+ }
// Webkit is asking whether to navigate to a new URL.
// This is fine normally, except if we're showing UI from one security
@@ -5898,11 +6096,10 @@ WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
bool is_initial_navigation = render_view_->history_list_length_ == 0;
bool should_fork =
HasWebUIScheme(url) || HasWebUIScheme(old_url) ||
- (cumulative_bindings & BINDINGS_POLICY_WEB_UI) ||
+ (cumulative_bindings & kWebUIBindingsPolicyMask) ||
url.SchemeIs(kViewSourceScheme) ||
(frame_->IsViewSourceModeEnabled() &&
info.navigation_type != blink::kWebNavigationTypeReload);
-
if (!should_fork && url.SchemeIs(url::kFileScheme)) {
// Fork non-file to file opens. Note that this may fork unnecessarily if
// another tab (hosting a file or not) targeted this one before its
@@ -5977,7 +6174,9 @@ WebNavigationPolicy RenderFrameImpl::DecidePolicyForNavigation(
if (info.default_policy == blink::kWebNavigationPolicyDownload) {
blink::mojom::BlobURLTokenPtrInfo blob_url_token =
CloneBlobURLToken(info.blob_url_token.get());
- DownloadURL(info.url_request, blob_url_token.PassHandle());
+ DownloadURL(info.url_request,
+ blink::WebLocalFrameClient::CrossOriginRedirects::kFollow,
+ blob_url_token.PassHandle());
} else {
OpenURL(info, /*send_referrer=*/true,
/*is_history_navigation_in_new_child=*/false);
@@ -6249,6 +6448,15 @@ void RenderFrameImpl::OnNotifyUserActivation() {
frame_->NotifyUserActivation();
}
+void RenderFrameImpl::OnMediaPlayerActionAt(
+ const gfx::PointF& location,
+ const blink::WebMediaPlayerAction& action) {
+ blink::WebFloatRect viewport_position(location.x(), location.y(), 0, 0);
+ GetRenderWidget()->ConvertWindowToViewport(&viewport_position);
+ frame_->PerformMediaPlayerAction(
+ WebPoint(viewport_position.x, viewport_position.y), action);
+}
+
#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
#if defined(OS_MACOSX)
void RenderFrameImpl::OnSelectPopupMenuItem(int selected_index) {
@@ -6311,8 +6519,7 @@ void RenderFrameImpl::OpenURL(const NavigationPolicyInfo& info,
if (GetContentClient()->renderer()->AllowPopup())
params.user_gesture = true;
- if (ConsumeGestureOnNavigation() ||
- policy == blink::kWebNavigationPolicyNewBackgroundTab ||
+ if (is_main_frame_ || policy == blink::kWebNavigationPolicyNewBackgroundTab ||
policy == blink::kWebNavigationPolicyNewForegroundTab ||
policy == blink::kWebNavigationPolicyNewWindow ||
policy == blink::kWebNavigationPolicyNewPopup) {
@@ -6343,7 +6550,7 @@ WebURLRequest RenderFrameImpl::CreateURLRequestForCommit(
WebURLRequest request = CreateURLRequestForNavigation(
common_params, request_params, std::move(response_override),
- frame_->IsViewSourceModeEnabled(), false /* is_same_document */);
+ frame_->IsViewSourceModeEnabled());
request.SetFrameType(IsTopLevelNavigation(frame_)
? network::mojom::RequestContextFrameType::kTopLevel
: network::mojom::RequestContextFrameType::kNested);
@@ -6504,7 +6711,7 @@ void RenderFrameImpl::ScrollFocusedEditableElementIntoRect(
rect_for_scrolled_focused_editable_node_ = rect;
has_scrolled_focused_editable_node_into_rect_ = true;
- if (!GetRenderWidget()->compositor()->HasPendingPageScaleAnimation() &&
+ if (!GetRenderWidget()->layer_tree_view()->HasPendingPageScaleAnimation() &&
autofill_client) {
autofill_client->DidCompleteFocusChangeInFrame();
}
@@ -6655,9 +6862,21 @@ void RenderFrameImpl::BeginNavigation(const NavigationPolicyInfo& info) {
initiator ? base::make_optional<base::Value>(std::move(*initiator))
: base::nullopt);
+ mojom::NavigationClientAssociatedPtrInfo navigation_client_info;
+ if (IsPerNavigationMojoInterfaceEnabled()) {
+ WebDocumentLoader* document_loader = frame_->GetProvisionalDocumentLoader();
+ DocumentState* document_state =
+ DocumentState::FromDocumentLoader(document_loader);
+ NavigationStateImpl* navigation_state =
+ static_cast<NavigationStateImpl*>(document_state->navigation_state());
+
+ BindNavigationClient(mojo::MakeRequest(&navigation_client_info));
+ navigation_state->set_navigation_client(std::move(navigation_client_impl_));
+ }
GetFrameHost()->BeginNavigation(MakeCommonNavigationParams(info, load_flags),
std::move(begin_navigation_params),
- std::move(blob_url_token));
+ std::move(blob_url_token),
+ std::move(navigation_client_info));
}
void RenderFrameImpl::LoadDataURL(
@@ -6666,8 +6885,8 @@ void RenderFrameImpl::LoadDataURL(
WebLocalFrame* frame,
blink::WebFrameLoadType load_type,
blink::WebHistoryItem item_for_history_navigation,
- blink::WebHistoryLoadType history_load_type,
- bool is_client_redirect) {
+ bool is_client_redirect,
+ std::unique_ptr<blink::WebDocumentLoader::ExtraData> navigation_data) {
// A loadData request with a specified base URL.
GURL data_url = params.url;
#if defined(OS_ANDROID)
@@ -6692,12 +6911,15 @@ void RenderFrameImpl::LoadDataURL(
bool replace = load_type == WebFrameLoadType::kReloadBypassingCache ||
load_type == WebFrameLoadType::kReload;
- frame->LoadData(
+ frame->CommitDataNavigation(
WebData(data.c_str(), data.length()), WebString::FromUTF8(mime_type),
WebString::FromUTF8(charset), base_url,
// Needed so that history-url-only changes don't become reloads.
params.history_url_for_data_url, replace, load_type,
- item_for_history_navigation, history_load_type, is_client_redirect);
+ item_for_history_navigation, is_client_redirect,
+ std::move(navigation_data),
+ BuildNavigationTimings(params.navigation_start,
+ request_params.navigation_timing));
} else {
CHECK(false) << "Invalid URL passed: "
<< params.url.possibly_invalid_spec();
@@ -6763,81 +6985,18 @@ GURL RenderFrameImpl::GetLoadingUrl() const {
return request.Url();
}
-void RenderFrameImpl::PopulateDocumentStateFromPending(
- DocumentState* document_state) {
- InternalDocumentStateData* internal_data =
- InternalDocumentStateData::FromDocumentState(document_state);
-
- if (!pending_navigation_params_->common_params.url.SchemeIs(
- url::kJavaScriptScheme) &&
- pending_navigation_params_->common_params.navigation_type ==
- FrameMsg_Navigate_Type::RESTORE) {
- // We're doing a load of a page that was restored from the last session.
- // By default this prefers the cache over loading
- // (LOAD_SKIP_CACHE_VALIDATION) which can result in stale data for pages
- // that are set to expire. We explicitly override that by setting the
- // policy here so that as necessary we load from the network.
- //
- // TODO(davidben): Remove this in favor of passing a cache policy to the
- // loadHistoryItem call in OnNavigate. That requires not overloading
- // UseProtocolCachePolicy to mean both "normal load" and "determine cache
- // policy based on load type, etc".
- internal_data->set_cache_policy_override(
- blink::mojom::FetchCacheMode::kDefault);
- }
-
- internal_data->set_is_overriding_user_agent(
- pending_navigation_params_->request_params.is_overriding_user_agent);
- internal_data->set_must_reset_scroll_and_scale_state(
- pending_navigation_params_->common_params.navigation_type ==
- FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL);
- document_state->set_can_load_local_resources(
- pending_navigation_params_->request_params.can_load_local_resources);
-}
NavigationState* RenderFrameImpl::CreateNavigationStateFromPending() {
if (IsBrowserInitiated(pending_navigation_params_.get())) {
return NavigationStateImpl::CreateBrowserInitiated(
pending_navigation_params_->common_params,
pending_navigation_params_->request_params,
- pending_navigation_params_->time_commit_requested);
+ pending_navigation_params_->time_commit_requested,
+ std::move(pending_navigation_params_->commit_callback_));
}
return NavigationStateImpl::CreateContentInitiated();
}
-void RenderFrameImpl::UpdateNavigationState(DocumentState* document_state,
- bool was_within_same_document,
- bool content_initiated) {
- // If this was a browser-initiated navigation, then there could be pending
- // navigation params, so use them. Otherwise, just reset the document state
- // here, since if pending navigation params exist they are for some other
- // navigation <https://crbug.com/597239>.
- if (!pending_navigation_params_ || content_initiated) {
- document_state->set_navigation_state(
- NavigationStateImpl::CreateContentInitiated());
- return;
- }
-
- DCHECK(!pending_navigation_params_->common_params.navigation_start.is_null());
- document_state->set_navigation_state(CreateNavigationStateFromPending());
-
- // The |set_was_load_data_with_base_url_request| state should not change for
- // same document navigation, so skip updating it from the same document
- // navigation params in this case.
- if (!was_within_same_document) {
- const CommonNavigationParams& common_params =
- pending_navigation_params_->common_params;
- bool load_data = !common_params.base_url_for_data_url.is_empty() &&
- !common_params.history_url_for_data_url.is_empty() &&
- common_params.url.SchemeIs(url::kDataScheme);
- document_state->set_was_load_data_with_base_url_request(load_data);
- if (load_data)
- document_state->set_data_url(common_params.url);
- }
-
- pending_navigation_params_.reset();
-}
-
media::MediaPermission* RenderFrameImpl::GetMediaPermission() {
if (!media_permission_dispatcher_) {
media_permission_dispatcher_.reset(new MediaPermissionDispatcher(
@@ -6901,6 +7060,11 @@ void RenderFrameImpl::RegisterMojoInterfaces() {
base::Bind(&RenderFrameImpl::BindFrameNavigationControl,
weak_factory_.GetWeakPtr()));
+ if (IsPerNavigationMojoInterfaceEnabled()) {
+ GetAssociatedInterfaceRegistry()->AddInterface(base::BindRepeating(
+ &RenderFrameImpl::BindNavigationClient, weak_factory_.GetWeakPtr()));
+ }
+
GetAssociatedInterfaceRegistry()->AddInterface(base::BindRepeating(
&RenderFrameImpl::BindFullscreen, weak_factory_.GetWeakPtr()));
@@ -6956,12 +7120,6 @@ void RenderFrameImpl::CheckIfAudioSinkExistsAndIsAuthorized(
.device_status());
}
-blink::WebSpeechRecognizer* RenderFrameImpl::SpeechRecognizer() {
- if (!speech_recognition_dispatcher_)
- speech_recognition_dispatcher_ = new SpeechRecognitionDispatcher(this);
- return speech_recognition_dispatcher_;
-}
-
blink::mojom::PageVisibilityState RenderFrameImpl::VisibilityState() const {
const RenderFrameImpl* local_root = GetLocalRoot();
blink::mojom::PageVisibilityState current_state =
@@ -7164,16 +7322,12 @@ void RenderFrameImpl::RenderWidgetWillHandleMouseEvent() {
#endif
}
-bool RenderFrameImpl::ConsumeGestureOnNavigation() const {
- return is_main_frame_ &&
- base::FeatureList::IsEnabled(kConsumeGestureOnNavigation);
-}
-
-bool RenderFrameImpl::IsControlledByServiceWorker() {
+blink::mojom::ControllerServiceWorkerMode
+RenderFrameImpl::IsControlledByServiceWorker() {
blink::WebServiceWorkerNetworkProvider* web_provider =
frame_->GetDocumentLoader()->GetServiceWorkerNetworkProvider();
if (!web_provider)
- return false;
+ return blink::mojom::ControllerServiceWorkerMode::kNoController;
ServiceWorkerNetworkProvider* provider =
ServiceWorkerNetworkProvider::FromWebServiceWorkerNetworkProvider(
web_provider);
diff --git a/chromium/content/renderer/render_frame_impl.h b/chromium/content/renderer/render_frame_impl.h
index d841189173c..cb5ffc56b00 100644
--- a/chromium/content/renderer/render_frame_impl.h
+++ b/chromium/content/renderer/render_frame_impl.h
@@ -47,6 +47,7 @@
#include "content/public/common/referrer.h"
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/request_context_type.h"
+#include "content/public/common/resource_type.h"
#include "content/public/common/stop_find_action.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/websocket_handshake_throttle_provider.h"
@@ -73,6 +74,7 @@
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
#include "third_party/blink/public/mojom/manifest/manifest_manager.mojom.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/platform/autoplay.mojom.h"
#include "third_party/blink/public/platform/site_engagement.mojom.h"
#include "third_party/blink/public/platform/web_effective_connection_type.h"
@@ -82,11 +84,11 @@
#include "third_party/blink/public/web/commit_result.mojom.h"
#include "third_party/blink/public/web/web_ax_object.h"
#include "third_party/blink/public/web/web_document_loader.h"
-#include "third_party/blink/public/web/web_frame_client.h"
#include "third_party/blink/public/web/web_frame_load_type.h"
#include "third_party/blink/public/web/web_frame_serializer_client.h"
#include "third_party/blink/public/web/web_history_commit_type.h"
#include "third_party/blink/public/web/web_icon_url.h"
+#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_meaningful_layout.h"
#include "third_party/blink/public/web/web_script_execution_callback.h"
#include "third_party/blink/public/web/web_triggering_event_info.h"
@@ -116,11 +118,11 @@ class WebLocalFrame;
class WebPushClient;
class WebRelatedAppsFetcher;
class WebSecurityOrigin;
-class WebSpeechRecognizer;
struct FramePolicy;
struct WebContextMenuData;
struct WebCursorInfo;
struct WebFindOptions;
+struct WebMediaPlayerAction;
struct WebImeTextSpan;
struct WebScrollIntoViewParams;
} // namespace blink
@@ -151,13 +153,13 @@ namespace content {
class AssociatedInterfaceProviderImpl;
class BlinkInterfaceRegistryImpl;
class CompositorDependencies;
-class DocumentState;
class ExternalPopupMenu;
class HistoryEntry;
class ManifestManager;
class MediaPermissionDispatcher;
class MediaStreamDeviceObserver;
class NavigationState;
+class NavigationClient;
class PepperPluginInstanceImpl;
class PushMessagingClient;
class RelatedAppsFetcher;
@@ -168,7 +170,6 @@ class RenderViewImpl;
class RenderWidget;
class RenderWidgetFullscreenPepper;
class SharedWorkerRepository;
-class SpeechRecognitionDispatcher;
class UserMediaClientImpl;
struct CSPViolationParams;
struct CommonNavigationParams;
@@ -190,7 +191,7 @@ class CONTENT_EXPORT RenderFrameImpl
mojom::FullscreenVideoElementHandler,
mojom::HostZoom,
mojom::FrameBindingsControl,
- public blink::WebFrameClient,
+ public blink::WebLocalFrameClient,
public blink::WebFrameSerializerClient,
service_manager::mojom::InterfaceProvider {
public:
@@ -283,7 +284,7 @@ class CONTENT_EXPORT RenderFrameImpl
// See RenderFrameObserver::DidMeaningfulLayout declaration for details.
void DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type);
- // Draw commands have been issued by RenderWidgetCompositor.
+ // Draw commands have been issued by blink::LayerTreeView.
void DidCommitAndDrawCompositorFrame();
// Returns the unique name of the RenderFrame.
@@ -314,7 +315,7 @@ class CONTENT_EXPORT RenderFrameImpl
// Start/Stop loading notifications.
// TODO(nasko): Those are page-level methods at this time and come from
- // WebViewClient. We should move them to be WebFrameClient calls and put
+ // WebViewClient. We should move them to be WebLocalFrameClient calls and put
// logic in the browser side to balance starts/stops.
// |to_different_document| will be true unless the load is a fragment
// navigation, or triggered by history.pushState/replaceState.
@@ -480,6 +481,8 @@ class CONTENT_EXPORT RenderFrameImpl
void SetSelectedText(const base::string16& selection_text,
size_t offset,
const gfx::Range& range) override;
+ void SetZoomLevel(double zoom_level) override;
+ double GetZoomLevel() const override;
void AddMessageToConsole(ConsoleMessageLevel level,
const std::string& message) override;
void SetPreviewsState(PreviewsState previews_state) override;
@@ -525,14 +528,17 @@ class CONTENT_EXPORT RenderFrameImpl
base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
subresource_overrides,
mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
- const base::UnguessableToken& devtools_navigation_token) override;
+ network::mojom::URLLoaderFactoryPtr prefetch_loader_factory,
+ const base::UnguessableToken& devtools_navigation_token,
+ CommitNavigationCallback callback) override;
void CommitFailedNavigation(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
bool has_stale_copy_in_cache,
int error_code,
const base::Optional<std::string>& error_page_content,
- std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders) override;
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
+ CommitFailedNavigationCallback callback) override;
void CommitSameDocumentNavigation(
const CommonNavigationParams& common_params,
const RequestNavigationParams& request_params,
@@ -547,7 +553,7 @@ class CONTENT_EXPORT RenderFrameImpl
// mojom::HostZoom implementation:
void SetHostZoomLevel(const GURL& url, double zoom_level) override;
- // blink::WebFrameClient implementation:
+ // blink::WebLocalFrameClient implementation:
blink::WebPlugin* CreatePlugin(const blink::WebPluginParams& params) override;
blink::WebMediaPlayer* CreateMediaPlayer(
const blink::WebMediaPlayerSource& source,
@@ -607,7 +613,8 @@ class CONTENT_EXPORT RenderFrameImpl
const blink::WebVector<blink::WebString>& newly_matching_selectors,
const blink::WebVector<blink::WebString>& stopped_matching_selectors)
override;
- void SetHasReceivedUserGesture() override;
+ void UpdateUserActivationState(
+ blink::UserActivationUpdateType update_type) override;
void SetHasReceivedUserGestureBeforeNavigation(bool value) override;
void SetMouseCapture(bool capture) override;
bool ShouldReportDetailedMessageForSource(
@@ -617,6 +624,7 @@ class CONTENT_EXPORT RenderFrameImpl
unsigned source_line,
const blink::WebString& stack_trace) override;
void DownloadURL(const blink::WebURLRequest& request,
+ CrossOriginRedirects cross_origin_redirect_behavior,
mojo::ScopedMessagePipeHandle blob_url_token) override;
void LoadErrorPage(int reason) override;
blink::WebNavigationPolicy DecidePolicyForNavigation(
@@ -627,7 +635,6 @@ class CONTENT_EXPORT RenderFrameImpl
blink::WebDocumentLoader* document_loader) override;
void DidStartProvisionalLoad(blink::WebDocumentLoader* document_loader,
blink::WebURLRequest& request) override;
- void DidReceiveServerRedirectForProvisionalLoad() override;
void DidFailProvisionalLoad(const blink::WebURLError& error,
blink::WebHistoryCommitType commit_type) override;
void DidCommitProvisionalLoad(
@@ -702,7 +709,6 @@ class CONTENT_EXPORT RenderFrameImpl
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override;
void DidChangeScrollOffset() override;
- void WillInsertBody() override;
void ReportFindInPageMatchCount(int request_id,
int count,
bool final_update) override;
@@ -732,6 +738,7 @@ class CONTENT_EXPORT RenderFrameImpl
void DidChangeManifest() override;
void EnterFullscreen(const blink::WebFullscreenOptions& options) override;
void ExitFullscreen() override;
+ void FullscreenStateChanged(bool is_fullscreen) override;
void SuddenTerminationDisablerChanged(
bool present,
blink::WebSuddenTerminationDisablerType disabler_type) override;
@@ -743,7 +750,6 @@ class CONTENT_EXPORT RenderFrameImpl
void CheckIfAudioSinkExistsAndIsAuthorized(
const blink::WebString& sink_id,
blink::WebSetSinkIdCallbacks* web_callbacks) override;
- blink::WebSpeechRecognizer* SpeechRecognizer() override;
blink::mojom::PageVisibilityState VisibilityState() const override;
std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory() override;
void DraggableRegionsChanged() override;
@@ -785,6 +791,8 @@ class CONTENT_EXPORT RenderFrameImpl
mojom::FrameBindingsControlAssociatedRequest request);
void BindFrameNavigationControl(
mojom::FrameNavigationControlAssociatedRequest request);
+ // Only used when PerNavigationMojoInterface is enabled.
+ void BindNavigationClient(mojom::NavigationClientAssociatedRequest request);
blink::mojom::ManifestManager& GetManifestManager();
@@ -871,6 +879,18 @@ class CONTENT_EXPORT RenderFrameImpl
// frame.
void FrameDidCallFocus();
+ // Called when an ongoing renderer-initiated navigation was dropped by the
+ // browser.
+ void OnDroppedNavigation();
+
+ void DidStartResponse(int request_id,
+ const network::ResourceResponseHead& response_head,
+ content::ResourceType resource_type);
+ void DidCompleteResponse(int request_id,
+ const network::URLLoaderCompletionStatus& status);
+ void DidCancelResponse(int request_id);
+ void DidReceiveTransferSizeUpdate(int request_id, int received_data_length);
+
protected:
explicit RenderFrameImpl(CreateParams params);
@@ -982,7 +1002,6 @@ class CONTENT_EXPORT RenderFrameImpl
const FrameReplicationState& replicated_frame_state);
void OnDeleteFrame();
void OnStop();
- void OnDroppedNavigation();
void OnCollapse(bool collapse);
void OnShowContextMenu(const gfx::Point& location);
void OnContextMenuClosed(const CustomContextMenuContext& custom_context);
@@ -1042,6 +1061,8 @@ class CONTENT_EXPORT RenderFrameImpl
void OnMixedContentFound(const FrameMsg_MixedContentFound_Params& params);
void OnSetOverlayRoutingToken(const base::UnguessableToken& token);
void OnNotifyUserActivation();
+ void OnMediaPlayerActionAt(const gfx::PointF&,
+ const blink::WebMediaPlayerAction&);
#if BUILDFLAG(USE_EXTERNAL_POPUP_MENU)
#if defined(OS_MACOSX)
@@ -1116,20 +1137,23 @@ class CONTENT_EXPORT RenderFrameImpl
const blink::WebURLError& error,
bool replace,
HistoryEntry* entry,
- const base::Optional<std::string>& error_page_content);
+ const base::Optional<std::string>& error_page_content,
+ std::unique_ptr<blink::WebDocumentLoader::ExtraData> navigation_data);
void LoadNavigationErrorPageForHttpStatusError(
const blink::WebURLRequest& failed_request,
const GURL& unreachable_url,
int http_status,
bool replace,
- HistoryEntry* entry);
+ HistoryEntry* entry,
+ std::unique_ptr<blink::WebDocumentLoader::ExtraData> navigation_data);
void LoadNavigationErrorPageInternal(
const std::string& error_html,
const GURL& error_page_url,
const GURL& error_url,
bool replace,
blink::WebFrameLoadType frame_load_type,
- const blink::WebHistoryItem& history_item);
+ const blink::WebHistoryItem& history_item,
+ std::unique_ptr<blink::WebDocumentLoader::ExtraData> navigation_data);
void HandleJavascriptExecutionResult(const base::string16& javascript,
int id,
@@ -1150,13 +1174,14 @@ class CONTENT_EXPORT RenderFrameImpl
void BeginNavigation(const NavigationPolicyInfo& info);
// Loads a data url.
- void LoadDataURL(const CommonNavigationParams& params,
- const RequestNavigationParams& request_params,
- blink::WebLocalFrame* frame,
- blink::WebFrameLoadType load_type,
- blink::WebHistoryItem item_for_history_navigation,
- blink::WebHistoryLoadType history_load_type,
- bool is_client_redirect);
+ void LoadDataURL(
+ const CommonNavigationParams& params,
+ const RequestNavigationParams& request_params,
+ blink::WebLocalFrame* frame,
+ blink::WebFrameLoadType load_type,
+ blink::WebHistoryItem item_for_history_navigation,
+ bool is_client_redirect,
+ std::unique_ptr<blink::WebDocumentLoader::ExtraData> navigation_data);
// Sends a proper FrameHostMsg_DidFailProvisionalLoadWithError_Params IPC for
// the failed request |request|.
@@ -1170,20 +1195,10 @@ class CONTENT_EXPORT RenderFrameImpl
// Returns the URL being loaded by the |frame_|'s request.
GURL GetLoadingUrl() const;
- // If we initiated a navigation, this function will populate |document_state|
- // with the navigation information saved in OnNavigate().
- void PopulateDocumentStateFromPending(DocumentState* document_state);
-
// Returns a new NavigationState populated with the navigation information
// saved in OnNavigate().
NavigationState* CreateNavigationStateFromPending();
- // Sets the NavigationState on the DocumentState based on
- // the value of |pending_navigation_params_|.
- void UpdateNavigationState(DocumentState* document_state,
- bool was_within_same_document,
- bool content_initiated);
-
#if BUILDFLAG(ENABLE_PLUGINS)
void HandlePepperImeCommit(const base::string16& text);
#endif // ENABLE_PLUGINS
@@ -1232,11 +1247,8 @@ 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();
+ // Whether the frame is controlled by a service worker.
+ blink::mojom::ControllerServiceWorkerMode IsControlledByServiceWorker();
// Build DidCommitProvisionalLoad_Params based on the frame internal state.
std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
@@ -1277,7 +1289,8 @@ class CONTENT_EXPORT RenderFrameImpl
CreateWebSocketHandshakeThrottle() override;
// Updates the state of this frame when asked to commit a navigation.
- void PrepareFrameForCommit();
+ void PrepareFrameForCommit(const GURL& url,
+ const RequestNavigationParams& request_params);
// Updates the state when asked to commit a history navigation. Sets
// |item_for_history_navigation| and |load_type| to the appropriate values for
@@ -1471,11 +1484,6 @@ class CONTENT_EXPORT RenderFrameImpl
// process.
std::unique_ptr<ManifestManager> manifest_manager_;
- // The speech recognition dispatcher attached to this frame, lazily
- // initialized. It is an observer of this frame, owning itself and managing
- // its own lifetime.
- SpeechRecognitionDispatcher* speech_recognition_dispatcher_ = nullptr;
-
// The current accessibility mode.
ui::AXMode accessibility_mode_;
@@ -1554,6 +1562,9 @@ class CONTENT_EXPORT RenderFrameImpl
mojo::AssociatedBinding<mojom::FullscreenVideoElementHandler>
fullscreen_binding_;
+ // Only used when PerNavigationMojoInterface is enabled.
+ std::unique_ptr<NavigationClient> navigation_client_impl_;
+
// Indicates whether |didAccessInitialDocument| was called.
bool has_accessed_initial_document_;
@@ -1612,6 +1623,10 @@ class CONTENT_EXPORT RenderFrameImpl
// consumed to initialize a subresource loader).
mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info_;
+ // Set on CommitNavigation when Network Service is enabled, and used
+ // by FrameURLLoaderFactory for prefetch requests.
+ network::mojom::URLLoaderFactoryPtr prefetch_loader_factory_;
+
// URLLoaderFactory instances used for subresource loading.
// Depending on how the frame was created, |loader_factories_| could be:
// * |HostChildURLLoaderFactoryBundle| for standalone frames, or
diff --git a/chromium/content/renderer/render_frame_impl_browsertest.cc b/chromium/content/renderer/render_frame_impl_browsertest.cc
index a04c30ff0d6..884e79b63e8 100644
--- a/chromium/content/renderer/render_frame_impl_browsertest.cc
+++ b/chromium/content/renderer/render_frame_impl_browsertest.cc
@@ -19,6 +19,7 @@
#include "content/common/frame_owner_properties.h"
#include "content/common/renderer.mojom.h"
#include "content/common/view_messages.h"
+#include "content/public/common/content_switches.h"
#include "content/public/common/previews_state.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/document_state.h"
@@ -210,7 +211,7 @@ TEST_F(RenderFrameImplTest, FrameResize) {
TEST_F(RenderFrameImplTest, FrameWasShown) {
RenderFrameTestObserver observer(frame());
- ViewMsg_WasShown was_shown_message(0, true, ui::LatencyInfo());
+ ViewMsg_WasShown was_shown_message(0, true, base::TimeTicks());
frame_widget()->OnMessageReceived(was_shown_message);
EXPECT_FALSE(frame_widget()->is_hidden());
@@ -240,7 +241,7 @@ TEST_F(RenderFrameImplTest, LocalChildFrameWasShown) {
RenderFrameTestObserver observer(grandchild);
- ViewMsg_WasShown was_shown_message(0, true, ui::LatencyInfo());
+ ViewMsg_WasShown was_shown_message(0, true, base::TimeTicks());
frame_widget()->OnMessageReceived(was_shown_message);
EXPECT_FALSE(frame_widget()->is_hidden());
@@ -253,7 +254,7 @@ TEST_F(RenderFrameImplTest, FrameWasShownAfterWidgetClose) {
ViewMsg_Close close_message(0);
frame_widget()->OnMessageReceived(close_message);
- ViewMsg_WasShown was_shown_message(0, true, ui::LatencyInfo());
+ ViewMsg_WasShown was_shown_message(0, true, base::TimeTicks());
// Test passes if this does not crash.
static_cast<RenderViewImpl*>(view_)->OnMessageReceived(was_shown_message);
}
@@ -428,7 +429,9 @@ TEST_F(RenderFrameImplTest, DownloadUrlLimit) {
blink::WebSecurityOrigin::Create(GURL("http://test")));
for (int i = 0; i < 10; ++i) {
- frame()->DownloadURL(request, mojo::ScopedMessagePipeHandle());
+ frame()->DownloadURL(
+ request, blink::WebLocalFrameClient::CrossOriginRedirects::kNavigate,
+ mojo::ScopedMessagePipeHandle());
base::RunLoop().RunUntilIdle();
const IPC::Message* msg2 = render_thread_->sink().GetFirstMessageMatching(
FrameHostMsg_DownloadUrl::ID);
@@ -437,7 +440,9 @@ TEST_F(RenderFrameImplTest, DownloadUrlLimit) {
render_thread_->sink().ClearMessages();
}
- frame()->DownloadURL(request, mojo::ScopedMessagePipeHandle());
+ frame()->DownloadURL(
+ request, blink::WebLocalFrameClient::CrossOriginRedirects::kNavigate,
+ mojo::ScopedMessagePipeHandle());
base::RunLoop().RunUntilIdle();
const IPC::Message* msg3 = render_thread_->sink().GetFirstMessageMatching(
FrameHostMsg_DownloadUrl::ID);
@@ -650,6 +655,29 @@ TEST_F(RenderFrameImplTest, AutoplayFlags_WrongOrigin) {
AutoplayFlagsForFrame(GetMainRenderFrame()));
}
+TEST_F(RenderFrameImplTest, FileUrlPathAlias) {
+ const struct {
+ const char* original;
+ const char* transformed;
+ } kTestCases[] = {
+ {"file:///alias", "file:///replacement"},
+ {"file:///alias/path/to/file", "file:///replacement/path/to/file"},
+ {"file://alias/path/to/file", "file://alias/path/to/file"},
+ {"file:///notalias/path/to/file", "file:///notalias/path/to/file"},
+ {"file:///root/alias/path/to/file", "file:///root/alias/path/to/file"},
+ {"file:///", "file:///"},
+ };
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kFileUrlPathAlias, "/alias=/replacement");
+
+ for (const auto& test_case : kTestCases) {
+ WebURLRequest request;
+ request.SetURL(GURL(test_case.original));
+ GetMainRenderFrame()->WillSendRequest(request);
+ EXPECT_EQ(test_case.transformed, request.Url().GetString().Utf8());
+ }
+}
+
// RenderFrameRemoteInterfacesTest ------------------------------------
namespace {
diff --git a/chromium/content/renderer/render_frame_metadata_observer_impl.cc b/chromium/content/renderer/render_frame_metadata_observer_impl.cc
index 5b5c8b82ae8..c8de63db72b 100644
--- a/chromium/content/renderer/render_frame_metadata_observer_impl.cc
+++ b/chromium/content/renderer/render_frame_metadata_observer_impl.cc
@@ -4,10 +4,19 @@
#include "content/renderer/render_frame_metadata_observer_impl.h"
-#include "cc/trees/frame_token_allocator.h"
+#include <cmath>
+
+#include "build/build_config.h"
+#include "components/viz/common/quads/compositor_frame_metadata.h"
namespace content {
+namespace {
+#if defined(OS_ANDROID)
+constexpr float kEdgeThreshold = 10.0f;
+#endif
+}
+
RenderFrameMetadataObserverImpl::RenderFrameMetadataObserverImpl(
mojom::RenderFrameMetadataObserverRequest request,
mojom::RenderFrameMetadataObserverClientPtrInfo client_info)
@@ -17,38 +26,40 @@ RenderFrameMetadataObserverImpl::RenderFrameMetadataObserverImpl(
RenderFrameMetadataObserverImpl::~RenderFrameMetadataObserverImpl() {}
-void RenderFrameMetadataObserverImpl::BindToCurrentThread(
- cc::FrameTokenAllocator* frame_token_allocator) {
+void RenderFrameMetadataObserverImpl::BindToCurrentThread() {
DCHECK(request_.is_pending());
- frame_token_allocator_ = frame_token_allocator;
render_frame_metadata_observer_binding_.Bind(std::move(request_));
render_frame_metadata_observer_client_.Bind(std::move(client_info_));
}
void RenderFrameMetadataObserverImpl::OnRenderFrameSubmission(
- cc::RenderFrameMetadata metadata) {
+ const cc::RenderFrameMetadata& render_frame_metadata,
+ viz::CompositorFrameMetadata* compositor_frame_metadata) {
// By default only report metadata changes for fields which have a low
// frequency of change. However if there are changes in high frequency
// fields these can be reported while testing is enabled.
bool send_metadata = false;
+ bool needs_activation_notification = true;
if (render_frame_metadata_observer_client_) {
if (report_all_frame_submissions_for_testing_enabled_) {
- last_frame_token_ = frame_token_allocator_->GetOrAllocateFrameToken();
+ last_frame_token_ = compositor_frame_metadata->frame_token;
+ compositor_frame_metadata->send_frame_token_to_embedder = true;
render_frame_metadata_observer_client_->OnFrameSubmissionForTesting(
last_frame_token_);
send_metadata = !last_render_frame_metadata_ ||
- *last_render_frame_metadata_ != metadata;
+ *last_render_frame_metadata_ != render_frame_metadata;
} else {
send_metadata = !last_render_frame_metadata_ ||
- cc::RenderFrameMetadata::HasAlwaysUpdateMetadataChanged(
- *last_render_frame_metadata_, metadata);
+ ShouldSendRenderFrameMetadata(
+ *last_render_frame_metadata_, render_frame_metadata,
+ &needs_activation_notification);
}
}
// Allways cache the full metadata, so that it can correctly be sent upon
// ReportAllFrameSubmissionsForTesting. This must only be done after we've
// compared the two for changes.
- last_render_frame_metadata_ = metadata;
+ last_render_frame_metadata_ = render_frame_metadata;
// If the metadata is different, updates all the observers; or the metadata is
// generated for first time and same as the default value, update the default
@@ -57,18 +68,26 @@ void RenderFrameMetadataObserverImpl::OnRenderFrameSubmission(
// Sending |root_scroll_offset| outside of tests would leave the browser
// process with out of date information. It is an optional parameter
// which we clear here.
+ auto metadata_copy = render_frame_metadata;
+#if !defined(OS_ANDROID)
if (!report_all_frame_submissions_for_testing_enabled_)
- metadata.root_scroll_offset = base::nullopt;
+ metadata_copy.root_scroll_offset = base::nullopt;
+#endif
- last_frame_token_ = frame_token_allocator_->GetOrAllocateFrameToken();
+ last_frame_token_ = compositor_frame_metadata->frame_token;
+ compositor_frame_metadata->send_frame_token_to_embedder =
+ needs_activation_notification;
render_frame_metadata_observer_client_->OnRenderFrameMetadataChanged(
- last_frame_token_, metadata);
+ needs_activation_notification ? last_frame_token_ : 0u, metadata_copy);
}
// Always cache the initial frame token, so that if a test connects later on
// it can be notified of the initial state.
- if (!last_frame_token_)
- last_frame_token_ = frame_token_allocator_->GetOrAllocateFrameToken();
+ if (!last_frame_token_) {
+ last_frame_token_ = compositor_frame_metadata->frame_token;
+ compositor_frame_metadata->send_frame_token_to_embedder =
+ needs_activation_notification;
+ }
}
void RenderFrameMetadataObserverImpl::ReportAllFrameSubmissionsForTesting(
@@ -85,4 +104,72 @@ void RenderFrameMetadataObserverImpl::ReportAllFrameSubmissionsForTesting(
last_frame_token_, *last_render_frame_metadata_);
}
+// static
+bool RenderFrameMetadataObserverImpl::ShouldSendRenderFrameMetadata(
+ const cc::RenderFrameMetadata& rfm1,
+ const cc::RenderFrameMetadata& rfm2,
+ bool* needs_activation_notification) {
+ if (rfm1.root_background_color != rfm2.root_background_color ||
+ rfm1.is_scroll_offset_at_top != rfm2.is_scroll_offset_at_top ||
+ rfm1.selection != rfm2.selection ||
+ rfm1.page_scale_factor != rfm2.page_scale_factor ||
+ rfm1.is_mobile_optimized != rfm2.is_mobile_optimized ||
+ rfm1.device_scale_factor != rfm2.device_scale_factor ||
+ rfm1.viewport_size_in_pixels != rfm2.viewport_size_in_pixels ||
+ rfm1.local_surface_id != rfm2.local_surface_id) {
+ *needs_activation_notification = true;
+ return true;
+ }
+
+#if defined(OS_ANDROID)
+ if (rfm1.top_controls_height != rfm2.top_controls_height ||
+ rfm1.top_controls_shown_ratio != rfm2.top_controls_shown_ratio ||
+ rfm1.bottom_controls_height != rfm2.bottom_controls_height ||
+ rfm1.bottom_controls_shown_ratio != rfm2.bottom_controls_shown_ratio ||
+ rfm1.min_page_scale_factor != rfm2.min_page_scale_factor ||
+ rfm1.max_page_scale_factor != rfm2.max_page_scale_factor ||
+ rfm1.root_overflow_y_hidden != rfm2.root_overflow_y_hidden ||
+ rfm1.scrollable_viewport_size != rfm2.scrollable_viewport_size ||
+ rfm1.root_layer_size != rfm2.root_layer_size ||
+ rfm1.has_transparent_background != rfm2.has_transparent_background) {
+ *needs_activation_notification = true;
+ return true;
+ }
+
+ gfx::Vector2dF old_root_scroll_offset =
+ rfm1.root_scroll_offset.value_or(gfx::Vector2dF());
+ gfx::Vector2dF new_root_scroll_offset =
+ rfm2.root_scroll_offset.value_or(gfx::Vector2dF());
+ gfx::RectF old_viewport_rect(
+ gfx::PointF(old_root_scroll_offset.x(), old_root_scroll_offset.y()),
+ rfm1.scrollable_viewport_size);
+ gfx::RectF new_viewport_rect(
+ gfx::PointF(new_root_scroll_offset.x(), new_root_scroll_offset.y()),
+ rfm2.scrollable_viewport_size);
+ gfx::RectF new_root_layer_rect(rfm2.root_layer_size);
+ bool at_left_or_right_edge =
+ rfm2.root_layer_size.width() > rfm2.scrollable_viewport_size.width() &&
+ (std::abs(new_viewport_rect.right() - new_root_layer_rect.right()) <
+ kEdgeThreshold ||
+ std::abs(new_viewport_rect.x() - new_root_layer_rect.x()) <
+ kEdgeThreshold);
+
+ bool at_top_or_bottom_edge =
+ rfm2.root_layer_size.height() > rfm2.scrollable_viewport_size.height() &&
+ (std::abs(new_viewport_rect.y() - new_root_layer_rect.y()) <
+ kEdgeThreshold ||
+ std::abs(new_viewport_rect.bottom() - new_root_layer_rect.bottom()) <
+ kEdgeThreshold);
+
+ if (old_viewport_rect != new_viewport_rect &&
+ (at_left_or_right_edge || at_top_or_bottom_edge)) {
+ *needs_activation_notification = false;
+ return true;
+ }
+#endif
+
+ *needs_activation_notification = false;
+ return false;
+}
+
} // namespace content
diff --git a/chromium/content/renderer/render_frame_metadata_observer_impl.h b/chromium/content/renderer/render_frame_metadata_observer_impl.h
index d7b159165da..ffa830f9b11 100644
--- a/chromium/content/renderer/render_frame_metadata_observer_impl.h
+++ b/chromium/content/renderer/render_frame_metadata_observer_impl.h
@@ -7,13 +7,10 @@
#include "cc/trees/render_frame_metadata.h"
#include "cc/trees/render_frame_metadata_observer.h"
+#include "content/common/content_export.h"
#include "content/common/render_frame_metadata.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
-namespace cc {
-class FrameTokenAllocator;
-} // namespace cc
-
namespace content {
// Implementation of cc::RenderFrameMetadataObserver which exists in the
@@ -25,7 +22,7 @@ namespace content {
// Mojo pipe is properly bound.
//
// Subsequent usage should only be from the Compositor thread.
-class RenderFrameMetadataObserverImpl
+class CONTENT_EXPORT RenderFrameMetadataObserverImpl
: public cc::RenderFrameMetadataObserver,
public mojom::RenderFrameMetadataObserver {
public:
@@ -35,14 +32,28 @@ class RenderFrameMetadataObserverImpl
~RenderFrameMetadataObserverImpl() override;
// cc::RenderFrameMetadataObserver:
- void BindToCurrentThread(
- cc::FrameTokenAllocator* frame_token_allocator) override;
- void OnRenderFrameSubmission(cc::RenderFrameMetadata metadata) override;
+ void BindToCurrentThread() override;
+ void OnRenderFrameSubmission(
+ const cc::RenderFrameMetadata& render_frame_metadata,
+ viz::CompositorFrameMetadata* compositor_frame_metadata) override;
// mojom::RenderFrameMetadataObserver:
void ReportAllFrameSubmissionsForTesting(bool enabled) override;
private:
+ friend class RenderFrameMetadataObserverImplTest;
+
+ // Certain fields should always have their changes reported. This will return
+ // true when there is a difference between |rfm1| and |rfm2| for those fields.
+ // These fields have a low frequency rate of change.
+ // |needs_activation_notification| indicates whether the browser process
+ // expects notification of activation of the assoicated CompositorFrame from
+ // Viz.
+ static bool ShouldSendRenderFrameMetadata(
+ const cc::RenderFrameMetadata& rfm1,
+ const cc::RenderFrameMetadata& rfm2,
+ bool* needs_activation_notification);
+
// When true this will notifiy |render_frame_metadata_observer_client_| of all
// frame submissions.
bool report_all_frame_submissions_for_testing_enabled_ = false;
@@ -50,9 +61,6 @@ class RenderFrameMetadataObserverImpl
uint32_t last_frame_token_ = 0;
base::Optional<cc::RenderFrameMetadata> last_render_frame_metadata_;
- // Not owned.
- cc::FrameTokenAllocator* frame_token_allocator_ = nullptr;
-
// These are destroyed when BindToCurrentThread() is called.
mojom::RenderFrameMetadataObserverRequest request_;
mojom::RenderFrameMetadataObserverClientPtrInfo client_info_;
diff --git a/chromium/content/renderer/render_frame_metadata_observer_impl_unittest.cc b/chromium/content/renderer/render_frame_metadata_observer_impl_unittest.cc
new file mode 100644
index 00000000000..462e6392120
--- /dev/null
+++ b/chromium/content/renderer/render_frame_metadata_observer_impl_unittest.cc
@@ -0,0 +1,158 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/render_frame_metadata_observer_impl.h"
+
+#include "base/run_loop.h"
+#include "base/test/scoped_task_environment.h"
+#include "build/build_config.h"
+#include "cc/trees/render_frame_metadata.h"
+#include "components/viz/common/quads/compositor_frame_metadata.h"
+#include "content/common/render_frame_metadata.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+ACTION_P(InvokeClosure, closure) {
+ closure.Run();
+}
+
+} // namespace
+
+class MockRenderFrameMetadataObserverClient
+ : public mojom::RenderFrameMetadataObserverClient {
+ public:
+ MockRenderFrameMetadataObserverClient(
+ mojom::RenderFrameMetadataObserverClientRequest client_request,
+ mojom::RenderFrameMetadataObserverPtr observer)
+ : render_frame_metadata_observer_client_binding_(
+ this,
+ std::move(client_request)),
+ render_frame_metadata_observer_ptr_(std::move(observer)) {}
+
+ MOCK_METHOD2(OnRenderFrameMetadataChanged,
+ void(uint32_t frame_token,
+ const cc::RenderFrameMetadata& metadata));
+ MOCK_METHOD1(OnFrameSubmissionForTesting, void(uint32_t frame_token));
+
+ private:
+ mojo::Binding<mojom::RenderFrameMetadataObserverClient>
+ render_frame_metadata_observer_client_binding_;
+ mojom::RenderFrameMetadataObserverPtr render_frame_metadata_observer_ptr_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockRenderFrameMetadataObserverClient);
+};
+
+class RenderFrameMetadataObserverImplTest : public testing::Test {
+ public:
+ RenderFrameMetadataObserverImplTest() = default;
+ ~RenderFrameMetadataObserverImplTest() override = default;
+
+ RenderFrameMetadataObserverImpl& observer_impl() { return *observer_impl_; }
+
+ MockRenderFrameMetadataObserverClient& client() { return *client_; }
+
+ // testing::Test:
+ void SetUp() override {
+ mojom::RenderFrameMetadataObserverPtr ptr;
+ mojom::RenderFrameMetadataObserverRequest request = mojo::MakeRequest(&ptr);
+ mojom::RenderFrameMetadataObserverClientPtrInfo client_info;
+ mojom::RenderFrameMetadataObserverClientRequest client_request =
+ mojo::MakeRequest(&client_info);
+
+ client_ = std::make_unique<
+ testing::NiceMock<MockRenderFrameMetadataObserverClient>>(
+ std::move(client_request), std::move(ptr));
+ observer_impl_ = std::make_unique<RenderFrameMetadataObserverImpl>(
+ std::move(request), std::move(client_info));
+ observer_impl_->BindToCurrentThread();
+ }
+
+ void TearDown() override {
+ observer_impl_.reset();
+ client_.reset();
+ scoped_task_environment_.RunUntilIdle();
+ }
+
+ private:
+ base::test::ScopedTaskEnvironment scoped_task_environment_;
+ std::unique_ptr<testing::NiceMock<MockRenderFrameMetadataObserverClient>>
+ client_;
+ std::unique_ptr<RenderFrameMetadataObserverImpl> observer_impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderFrameMetadataObserverImplTest);
+};
+
+// This test verifies that the RenderFrameMetadataObserverImpl picks up
+// the frame token from CompositorFrameMetadata and passes it along to the
+// client. This test also verifies that the RenderFrameMetadata object is
+// passed along to the client.
+TEST_F(RenderFrameMetadataObserverImplTest, ShouldSendFrameToken) {
+ viz::CompositorFrameMetadata compositor_frame_metadata;
+ compositor_frame_metadata.send_frame_token_to_embedder = false;
+ compositor_frame_metadata.frame_token = 1337;
+ cc::RenderFrameMetadata render_frame_metadata;
+ render_frame_metadata.is_mobile_optimized = true;
+ observer_impl().OnRenderFrameSubmission(render_frame_metadata,
+ &compositor_frame_metadata);
+ // |is_mobile_optimized| should be synchronized with frame activation so
+ // RenderFrameMetadataObserverImpl should ask for the frame token from
+ // Viz.
+ EXPECT_TRUE(compositor_frame_metadata.send_frame_token_to_embedder);
+ {
+ base::RunLoop run_loop;
+ EXPECT_CALL(client(),
+ OnRenderFrameMetadataChanged(1337, render_frame_metadata))
+ .WillOnce(InvokeClosure(run_loop.QuitClosure()));
+ run_loop.Run();
+ }
+}
+
+// This test verifies that a frame token is not requested from viz when
+// the root scroll offset changes on Android.
+#if defined(OS_ANDROID)
+TEST_F(RenderFrameMetadataObserverImplTest, ShouldSendFrameTokenOnAndroid) {
+ viz::CompositorFrameMetadata compositor_frame_metadata;
+ compositor_frame_metadata.send_frame_token_to_embedder = false;
+ compositor_frame_metadata.frame_token = 1337;
+ cc::RenderFrameMetadata render_frame_metadata;
+ render_frame_metadata.root_scroll_offset = gfx::Vector2dF(0.f, 1.f);
+ render_frame_metadata.root_layer_size = gfx::SizeF(100.f, 100.f);
+ render_frame_metadata.scrollable_viewport_size = gfx::SizeF(100.f, 50.f);
+ observer_impl().OnRenderFrameSubmission(render_frame_metadata,
+ &compositor_frame_metadata);
+ // The first RenderFrameMetadata will always get a corresponding frame token
+ // from Viz because this is the first frame.
+ EXPECT_TRUE(compositor_frame_metadata.send_frame_token_to_embedder);
+ {
+ base::RunLoop run_loop;
+ EXPECT_CALL(client(),
+ OnRenderFrameMetadataChanged(1337, render_frame_metadata))
+ .WillOnce(InvokeClosure(run_loop.QuitClosure()));
+ run_loop.Run();
+ }
+
+ // Scroll back to the top.
+ render_frame_metadata.root_scroll_offset = gfx::Vector2dF(0.f, 0.f);
+
+ observer_impl().OnRenderFrameSubmission(render_frame_metadata,
+ &compositor_frame_metadata);
+ // Android does not need a corresponding frame token.
+ EXPECT_FALSE(compositor_frame_metadata.send_frame_token_to_embedder);
+ {
+ base::RunLoop run_loop;
+ // The 0u frame token indicates that the client should not expect
+ // a corresponding frame token from Viz.
+ EXPECT_CALL(client(),
+ OnRenderFrameMetadataChanged(0u, render_frame_metadata))
+ .WillOnce(InvokeClosure(run_loop.QuitClosure()));
+ run_loop.Run();
+ }
+}
+#endif
+
+} // namespace content
diff --git a/chromium/content/renderer/render_frame_proxy.cc b/chromium/content/renderer/render_frame_proxy.cc
index 902038d46d7..8a50e185e1f 100644
--- a/chromium/content/renderer/render_frame_proxy.cc
+++ b/chromium/content/renderer/render_frame_proxy.cc
@@ -141,8 +141,8 @@ RenderFrameProxy* RenderFrameProxy::CreateFrameProxy(
// be updated, as the OnSwapOut flow which normally does this won't happen
// in that case. See https://crbug.com/653746 and
// https://crbug.com/651980.
- if (!render_view->is_swapped_out())
- render_view->SetSwappedOut(true);
+ if (!render_widget->is_swapped_out())
+ render_widget->SetSwappedOut(true);
} else {
// Create a frame under an existing parent. The parent is always expected
// to be a RenderFrameProxy, because navigations initiated by local frames
@@ -243,7 +243,7 @@ void RenderFrameProxy::Init(blink::WebRemoteFrame* web_frame,
render_widget_->GetOriginalScreenInfo();
#if defined(USE_AURA)
- if (features::IsMashEnabled()) {
+ if (!features::IsAshInBrowserProcess()) {
RendererWindowTreeClient* renderer_window_tree_client =
RendererWindowTreeClient::Get(render_widget_->routing_id());
// It's possible a MusEmbeddedFrame has already been scheduled for creation
@@ -256,7 +256,7 @@ void RenderFrameProxy::Init(blink::WebRemoteFrame* web_frame,
#endif
}
-void RenderFrameProxy::ResendResizeParams() {
+void RenderFrameProxy::ResendVisualProperties() {
// Reset |sent_visual_properties_| in order to allocate a new
// viz::LocalSurfaceId.
sent_visual_properties_ = base::nullopt;
@@ -285,6 +285,11 @@ void RenderFrameProxy::OnScreenInfoChanged(const ScreenInfo& screen_info) {
SynchronizeVisualProperties();
}
+void RenderFrameProxy::OnZoomLevelChanged(double zoom_level) {
+ pending_visual_properties_.zoom_level = zoom_level;
+ SynchronizeVisualProperties();
+}
+
void RenderFrameProxy::UpdateCaptureSequenceNumber(
uint32_t capture_sequence_number) {
pending_visual_properties_.capture_sequence_number = capture_sequence_number;
@@ -322,8 +327,10 @@ void RenderFrameProxy::SetReplicatedState(const FrameReplicationState& state) {
web_frame_->SetReplicatedInsecureNavigationsSet(
state.insecure_navigations_set);
web_frame_->SetReplicatedFeaturePolicyHeader(state.feature_policy_header);
- if (state.has_received_user_gesture)
- web_frame_->SetHasReceivedUserGesture();
+ if (state.has_received_user_gesture) {
+ web_frame_->UpdateUserActivationState(
+ blink::UserActivationUpdateType::kNotifyActivation);
+ }
web_frame_->SetHasReceivedUserGestureBeforeNavigation(
state.has_received_user_gesture_before_nav);
@@ -367,24 +374,6 @@ void RenderFrameProxy::OnDidSetFramePolicyHeaders(
web_frame_->SetReplicatedFeaturePolicyHeader(feature_policy_header);
}
-void RenderFrameProxy::SetChildFrameSurface(
- const viz::SurfaceInfo& surface_info) {
- // 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_->SetPrimarySurfaceId(
- surface_info.id(), local_frame_size(),
- cc::DeadlinePolicy::UseDefaultDeadline());
- }
- compositing_helper_->SetFallbackSurfaceId(surface_info.id(),
- local_frame_size());
-}
-
bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) {
// Forward Page IPCs to the RenderView.
if ((IPC_MESSAGE_CLASS(msg) == PageMsgStart)) {
@@ -398,7 +387,8 @@ bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) {
IPC_BEGIN_MESSAGE_MAP(RenderFrameProxy, msg)
IPC_MESSAGE_HANDLER(FrameMsg_DeleteProxy, OnDeleteProxy)
IPC_MESSAGE_HANDLER(FrameMsg_ChildFrameProcessGone, OnChildFrameProcessGone)
- IPC_MESSAGE_HANDLER(FrameMsg_SetChildFrameSurface, OnSetChildFrameSurface)
+ IPC_MESSAGE_HANDLER(FrameMsg_FirstSurfaceActivation,
+ OnFirstSurfaceActivation)
IPC_MESSAGE_HANDLER(FrameMsg_IntrinsicSizingInfoOfChildChanged,
OnIntrinsicSizingInfoOfChildChanged)
IPC_MESSAGE_HANDLER(FrameMsg_UpdateOpener, OnUpdateOpener)
@@ -431,8 +421,8 @@ bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(FrameMsg_DisableAutoResize, OnDisableAutoResize)
IPC_MESSAGE_HANDLER(FrameMsg_SetFocusedFrame, OnSetFocusedFrame)
IPC_MESSAGE_HANDLER(FrameMsg_WillEnterFullscreen, OnWillEnterFullscreen)
- IPC_MESSAGE_HANDLER(FrameMsg_SetHasReceivedUserGesture,
- OnSetHasReceivedUserGesture)
+ IPC_MESSAGE_HANDLER(FrameMsg_UpdateUserActivationState,
+ OnUpdateUserActivationState)
IPC_MESSAGE_HANDLER(FrameMsg_ScrollRectToVisible, OnScrollRectToVisible)
IPC_MESSAGE_HANDLER(FrameMsg_BubbleLogicalScroll, OnBubbleLogicalScroll)
IPC_MESSAGE_HANDLER(FrameMsg_SetHasReceivedUserGestureBeforeNavigation,
@@ -459,9 +449,22 @@ void RenderFrameProxy::OnChildFrameProcessGone() {
screen_info().device_scale_factor);
}
-void RenderFrameProxy::OnSetChildFrameSurface(
+void RenderFrameProxy::OnFirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) {
- SetChildFrameSurface(surface_info);
+ // 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_->SetPrimarySurfaceId(
+ surface_info.id(), local_frame_size(),
+ cc::DeadlinePolicy::UseDefaultDeadline());
+ }
+ compositing_helper_->SetFallbackSurfaceId(surface_info.id(),
+ local_frame_size());
}
void RenderFrameProxy::OnIntrinsicSizingInfoOfChildChanged(
@@ -482,12 +485,12 @@ void RenderFrameProxy::OnViewChanged(
const FrameMsg_ViewChanged_Params& params) {
crashed_ = false;
// In mash the FrameSinkId comes from RendererWindowTreeClient.
- if (!base::FeatureList::IsEnabled(features::kMash))
+ if (features::IsAshInBrowserProcess())
frame_sink_id_ = *params.frame_sink_id;
// Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
// changes.
- ResendResizeParams();
+ ResendVisualProperties();
}
void RenderFrameProxy::OnDidStopLoading() {
@@ -564,8 +567,9 @@ void RenderFrameProxy::OnWillEnterFullscreen() {
web_frame_->WillEnterFullscreen();
}
-void RenderFrameProxy::OnSetHasReceivedUserGesture() {
- web_frame_->SetHasReceivedUserGesture();
+void RenderFrameProxy::OnUpdateUserActivationState(
+ blink::UserActivationUpdateType update_type) {
+ web_frame_->UpdateUserActivationState(update_type);
}
void RenderFrameProxy::OnScrollRectToVisible(
@@ -639,6 +643,8 @@ void RenderFrameProxy::SynchronizeVisualProperties() {
pending_visual_properties_.screen_space_rect.size() ||
sent_visual_properties_->screen_info !=
pending_visual_properties_.screen_info ||
+ sent_visual_properties_->zoom_level !=
+ pending_visual_properties_.zoom_level ||
capture_sequence_number_changed;
if (synchronized_props_changed)
@@ -860,17 +866,17 @@ base::UnguessableToken RenderFrameProxy::GetDevToolsFrameToken() {
#if defined(USE_AURA)
void RenderFrameProxy::OnMusEmbeddedFrameSurfaceChanged(
const viz::SurfaceInfo& surface_info) {
- SetChildFrameSurface(surface_info);
+ OnFirstSurfaceActivation(surface_info);
}
void RenderFrameProxy::OnMusEmbeddedFrameSinkIdAllocated(
const viz::FrameSinkId& frame_sink_id) {
// RendererWindowTreeClient should only call this when mus is hosting viz.
- DCHECK(base::FeatureList::IsEnabled(features::kMash));
+ DCHECK(!features::IsAshInBrowserProcess());
frame_sink_id_ = frame_sink_id;
// Resend the FrameRects and allocate a new viz::LocalSurfaceId when the view
// changes.
- ResendResizeParams();
+ ResendVisualProperties();
}
#endif
@@ -890,7 +896,7 @@ SkBitmap* RenderFrameProxy::GetSadPageBitmap() {
}
uint32_t RenderFrameProxy::Print(const blink::WebRect& rect,
- blink::WebCanvas* canvas) {
+ cc::PaintCanvas* canvas) {
#if BUILDFLAG(ENABLE_PRINTING)
printing::PdfMetafileSkia* metafile =
printing::MetafileSkiaWrapper::GetMetafileFromCanvas(canvas);
diff --git a/chromium/content/renderer/render_frame_proxy.h b/chromium/content/renderer/render_frame_proxy.h
index 06f4981a856..abe2aaa15ce 100644
--- a/chromium/content/renderer/render_frame_proxy.h
+++ b/chromium/content/renderer/render_frame_proxy.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
+#include "cc/paint/paint_canvas.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "content/common/content_export.h"
#include "content/common/frame_messages.h"
@@ -16,7 +17,7 @@
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
#include "third_party/blink/public/common/feature_policy/feature_policy.h"
-#include "third_party/blink/public/platform/web_canvas.h"
+#include "third_party/blink/public/common/frame/user_activation_update_type.h"
#include "third_party/blink/public/platform/web_focus_type.h"
#include "third_party/blink/public/platform/web_insecure_request_policy.h"
#include "third_party/blink/public/web/web_remote_frame.h"
@@ -126,7 +127,7 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
// IPC::Listener
bool OnMessageReceived(const IPC::Message& msg) override;
- // Out-of-process child frames receive a signal from RenderWidgetCompositor
+ // Out-of-process child frames receive a signal from blink::LayerTreeView
// when a compositor frame will begin.
void WillBeginCompositorFrame();
@@ -134,6 +135,10 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
// ScreenInfo has changed.
void OnScreenInfoChanged(const ScreenInfo& screen_info);
+ // Out-of-process child frames receive a signal from RenderWidget when the
+ // zoom level has changed.
+ void OnZoomLevelChanged(double zoom_level);
+
// Invoked by RenderWidget when a new capture sequence number was set,
// indicating that surfaces should be synchronized.
void UpdateCaptureSequenceNumber(uint32_t capture_sequence_number);
@@ -202,7 +207,7 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
blink::WebLocalFrame* source) override;
void FrameFocused() override;
base::UnguessableToken GetDevToolsFrameToken() override;
- uint32_t Print(const blink::WebRect& rect, blink::WebCanvas* canvas) override;
+ uint32_t Print(const blink::WebRect& rect, cc::PaintCanvas* canvas) override;
// IPC handlers
void OnDidStartLoading();
@@ -214,16 +219,13 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
RenderViewImpl* render_view,
RenderWidget* render_widget);
- void ResendResizeParams();
-
- void SetChildFrameSurface(const viz::SurfaceInfo& surface_info);
+ void ResendVisualProperties();
// IPC handlers
void OnDeleteProxy();
void OnChildFrameProcessGone();
void OnCompositorFrameSwapped(const IPC::Message& message);
- // TODO(fsamuel): Rename OnFirstSurfaceActivation().
- void OnSetChildFrameSurface(const viz::SurfaceInfo& surface_info);
+ void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info);
void OnIntrinsicSizingInfoOfChildChanged(
blink::WebIntrinsicSizingInfo sizing_info);
void OnUpdateOpener(int opener_routing_id);
@@ -249,7 +251,7 @@ class CONTENT_EXPORT RenderFrameProxy : public IPC::Listener,
void OnSetPageFocus(bool is_focused);
void OnSetFocusedFrame();
void OnWillEnterFullscreen();
- void OnSetHasReceivedUserGesture();
+ void OnUpdateUserActivationState(blink::UserActivationUpdateType update_type);
void OnScrollRectToVisible(const gfx::Rect& rect_to_scroll,
const blink::WebScrollIntoViewParams& params);
void OnBubbleLogicalScroll(blink::WebScrollDirection direction,
diff --git a/chromium/content/renderer/render_process_impl.cc b/chromium/content/renderer/render_process_impl.cc
index f839d5610a1..80559a12e02 100644
--- a/chromium/content/renderer/render_process_impl.cc
+++ b/chromium/content/renderer/render_process_impl.cc
@@ -115,7 +115,6 @@ RenderProcessImpl::RenderProcessImpl(
// closer to V8s normal performance and behavior.
constexpr char kDisabledFlags[] =
"--noturbo_verify "
- "--noverify_csa "
"--noturbo_verify_allocation "
"--nodebug_code";
@@ -138,23 +137,37 @@ RenderProcessImpl::RenderProcessImpl(
"--harmony-import-meta");
SetV8FlagIfFeature(features::kAsmJsToWebAssembly, "--validate-asm");
SetV8FlagIfNotFeature(features::kAsmJsToWebAssembly, "--no-validate-asm");
- SetV8FlagIfNotFeature(features::kWebAssembly,
- "--wasm-disable-structured-cloning");
+
+ SetV8FlagIfFeature(features::kV8Orinoco, "--no-single-threaded-gc");
+ SetV8FlagIfNotFeature(features::kV8Orinoco, "--single-threaded-gc");
SetV8FlagIfFeature(features::kV8VmFuture, "--future");
SetV8FlagIfNotFeature(features::kV8VmFuture, "--no-future");
- SetV8FlagIfFeature(features::kWebAssemblyBaseline, "--wasm-tier-up");
- SetV8FlagIfNotFeature(features::kWebAssemblyBaseline, "--no-wasm-tier-up");
-
- SetV8FlagIfFeature(features::kSharedArrayBuffer,
- "--harmony-sharedarraybuffer");
- SetV8FlagIfNotFeature(features::kSharedArrayBuffer,
- "--no-harmony-sharedarraybuffer");
+ SetV8FlagIfFeature(features::kWebAssemblyBaseline,
+ "--liftoff --wasm-tier-up");
+ SetV8FlagIfNotFeature(features::kWebAssemblyBaseline,
+ "--no-liftoff --no-wasm-tier-up");
+
+ if (base::FeatureList::IsEnabled(features::kWebAssemblyThreads)) {
+ constexpr char kFlags[] =
+ "--harmony-sharedarraybuffer "
+ "--no-wasm-disable-structured-cloning "
+ "--experimental-wasm-threads";
+
+ v8::V8::SetFlagsFromString(kFlags, sizeof(kFlags));
+ } else {
+ SetV8FlagIfNotFeature(features::kWebAssembly,
+ "--wasm-disable-structured-cloning");
+ SetV8FlagIfFeature(features::kSharedArrayBuffer,
+ "--harmony-sharedarraybuffer");
+ SetV8FlagIfNotFeature(features::kSharedArrayBuffer,
+ "--no-harmony-sharedarraybuffer");
+ }
SetV8FlagIfNotFeature(features::kWebAssemblyTrapHandler,
"--no-wasm-trap-handler");
-#if defined(OS_LINUX) && defined(ARCH_CPU_X86_64) && !defined(OS_ANDROID)
+#if defined(OS_LINUX) && defined(ARCH_CPU_X86_64)
if (base::FeatureList::IsEnabled(features::kWebAssemblyTrapHandler)) {
bool use_v8_signal_handler = false;
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
diff --git a/chromium/content/renderer/render_thread_impl.cc b/chromium/content/renderer/render_thread_impl.cc
index 06f7d448799..ca6a21b0308 100644
--- a/chromium/content/renderer/render_thread_impl.cc
+++ b/chromium/content/renderer/render_thread_impl.cc
@@ -42,6 +42,7 @@
#include "build/build_config.h"
#include "cc/base/histograms.h"
#include "cc/base/switches.h"
+#include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
#include "cc/raster/task_graph_runner.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_host_common.h"
@@ -49,14 +50,12 @@
#include "components/discardable_memory/client/client_discardable_shared_memory_manager.h"
#include "components/metrics/public/interfaces/single_sample_metrics.mojom.h"
#include "components/metrics/single_sample_metrics.h"
-#include "components/viz/client/client_layer_tree_frame_sink.h"
#include "components/viz/client/hit_test_data_provider.h"
#include "components/viz/client/hit_test_data_provider_draw_quad.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/switches.h"
-#include "content/child/memory/child_memory_coordinator_impl.h"
#include "content/child/runtime_features.h"
#include "content/child/thread_safe_sender.h"
#include "content/common/buildflags.h"
@@ -77,6 +76,7 @@
#include "content/public/common/service_names.mojom.h"
#include "content/public/common/simple_connection_filter.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/render_thread_observer.h"
#include "content/public/renderer/render_view_visitor.h"
@@ -94,7 +94,8 @@
#include "content/renderer/indexed_db/indexed_db_dispatcher.h"
#include "content/renderer/input/widget_input_handler_manager.h"
#include "content/renderer/loader/resource_dispatcher.h"
-#include "content/renderer/media/audio_renderer_mixer_manager.h"
+#include "content/renderer/low_memory_mode_controller.h"
+#include "content/renderer/media/audio/audio_renderer_mixer_manager.h"
#include "content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h"
#include "content/renderer/media/midi/midi_message_filter.h"
#include "content/renderer/media/render_media_client.h"
@@ -114,7 +115,6 @@
#include "content/renderer/renderer_blink_platform_impl.h"
#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_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"
@@ -148,10 +148,9 @@
#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
#include "services/ui/public/cpp/gpu/gpu.h"
#include "services/ui/public/interfaces/constants.mojom.h"
-#include "skia/ext/event_tracer_impl.h"
#include "skia/ext/skia_memory_dump_provider.h"
#include "third_party/blink/public/platform/scheduler/child/webthread_base.h"
-#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_cache.h"
#include "third_party/blink/public/platform/web_image_generator.h"
#include "third_party/blink/public/platform/web_memory_coordinator.h"
@@ -172,7 +171,6 @@
#include "ui/base/ui_base_switches.h"
#include "ui/display/display_switches.h"
-
#if defined(OS_ANDROID)
#include <cpu-features.h>
#include "content/renderer/android/synchronous_layer_tree_frame_sink.h"
@@ -183,7 +181,6 @@
#if defined(OS_MACOSX)
#include "base/mac/mac_util.h"
#include "content/renderer/theme_helper_mac.h"
-#include "content/renderer/webscrollbarbehavior_impl_mac.h"
#endif
#if defined(OS_WIN)
@@ -197,6 +194,7 @@
#if defined(ENABLE_IPC_FUZZER)
#include "content/common/external_ipc_dumper.h"
+#include "mojo/public/cpp/bindings/message_dumper.h"
#endif
#if defined(OS_MACOSX)
@@ -222,12 +220,6 @@ namespace {
const int64_t kInitialIdleHandlerDelayMs = 1000;
const int64_t kLongIdleHandlerDelayMs = 30 * 1000;
-// Maximum allocation size allowed for image scaling filters that
-// require pre-scaling. Skia will fallback to a filter that doesn't
-// require pre-scaling if the default filter would require an
-// allocation that exceeds this limit.
-const size_t kImageCacheSingleAllocationByteLimit = 64 * 1024 * 1024;
-
#if defined(OS_ANDROID)
// Unique identifier for each output surface created.
uint32_t g_next_layer_tree_frame_sink_id = 1;
@@ -650,9 +642,8 @@ RenderThreadImpl* RenderThreadImpl::Create(
const InProcessChildThreadParams& params,
base::MessageLoop* unowned_message_loop) {
TRACE_EVENT0("startup", "RenderThreadImpl::Create");
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler>
- main_thread_scheduler =
- blink::scheduler::WebMainThreadScheduler::Create();
+ std::unique_ptr<blink::scheduler::WebThreadScheduler> main_thread_scheduler =
+ blink::scheduler::WebThreadScheduler::CreateMainThreadScheduler();
scoped_refptr<base::SingleThreadTaskRunner> test_task_counter;
return new RenderThreadImpl(params, std::move(main_thread_scheduler),
test_task_counter, unowned_message_loop);
@@ -661,7 +652,7 @@ RenderThreadImpl* RenderThreadImpl::Create(
// static
RenderThreadImpl* RenderThreadImpl::Create(
std::unique_ptr<base::MessageLoop> main_message_loop,
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler>
+ std::unique_ptr<blink::scheduler::WebThreadScheduler>
main_thread_scheduler) {
TRACE_EVENT0("startup", "RenderThreadImpl::Create");
return new RenderThreadImpl(std::move(main_message_loop),
@@ -712,7 +703,7 @@ RenderThreadImpl::DeprecatedGetMainTaskRunner() {
// the browser
RenderThreadImpl::RenderThreadImpl(
const InProcessChildThreadParams& params,
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler> scheduler,
+ std::unique_ptr<blink::scheduler::WebThreadScheduler> scheduler,
const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue,
base::MessageLoop* unowned_message_loop)
: ChildThreadImpl(
@@ -736,7 +727,7 @@ RenderThreadImpl::RenderThreadImpl(
// which means that we need to make the render thread pump UI events.
RenderThreadImpl::RenderThreadImpl(
std::unique_ptr<base::MessageLoop> owned_message_loop,
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler> scheduler)
+ std::unique_ptr<blink::scheduler::WebThreadScheduler> scheduler)
: ChildThreadImpl(
Options::Builder()
.AutoStartServiceManagerConnection(false)
@@ -790,9 +781,9 @@ void RenderThreadImpl::Init(
main_thread_runner(), GetConnector()));
gpu_ = ui::Gpu::Create(GetConnector(),
- base::FeatureList::IsEnabled(features::kMash)
- ? ui::mojom::kServiceName
- : mojom::kBrowserServiceName,
+ features::IsAshInBrowserProcess()
+ ? mojom::kBrowserServiceName
+ : ui::mojom::kServiceName,
GetIOTaskRunner());
resource_dispatcher_.reset(new ResourceDispatcher());
@@ -802,7 +793,6 @@ void RenderThreadImpl::Init(
auto registry = std::make_unique<service_manager::BinderRegistry>();
InitializeWebKit(resource_task_queue, registry.get());
- blink_initialized_time_ = base::TimeTicks::Now();
// In single process the single process is all there is.
webkit_shared_timer_suspended_ = false;
@@ -848,7 +838,7 @@ void RenderThreadImpl::Init(
AddFilter(midi_message_filter_.get());
#if defined(USE_AURA)
- if (features::IsMashEnabled())
+ if (!features::IsAshInBrowserProcess())
CreateRenderWidgetWindowTreeClientFactory(GetServiceManagerConnection());
#endif
@@ -880,10 +870,6 @@ void RenderThreadImpl::Init(
base::Bind(&RenderThreadImpl::OnRendererInterfaceRequest,
base::Unretained(this)));
- InitSkiaEventTracer();
- base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
- skia::SkiaMemoryDumpProvider::GetInstance(), "Skia", nullptr);
-
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
@@ -894,6 +880,7 @@ void RenderThreadImpl::Init(
IPC::ChannelProxy::OutgoingMessageFilter* filter =
LoadExternalIPCDumper(dump_directory);
GetChannel()->set_outgoing_message_filter(filter);
+ mojo::MessageDumper::SetMessageDumpDirectory(dump_directory);
}
#endif
@@ -916,6 +903,8 @@ void RenderThreadImpl::Init(
is_elastic_overscroll_enabled_ = false;
#endif
+ is_zoom_for_dsf_enabled_ = content::IsUseZoomForDSFEnabled();
+
if (command_line.HasSwitch(switches::kDisableLCDText)) {
is_lcd_text_enabled_ = false;
} else if (command_line.HasSwitch(switches::kEnableLCDText)) {
@@ -980,20 +969,6 @@ void RenderThreadImpl::Init(
base::Bind(&RenderThreadImpl::OnSyncMemoryPressure,
base::Unretained(this))));
- if (base::FeatureList::IsEnabled(features::kMemoryCoordinator)) {
- // Disable MemoryPressureListener when memory coordinator is enabled.
- base::MemoryPressureListener::SetNotificationsSuppressed(true);
-
- // TODO(bashi): Revisit how to manage the lifetime of
- // ChildMemoryCoordinatorImpl.
- // https://codereview.chromium.org/2094583002/#msg52
- mojom::MemoryCoordinatorHandlePtr parent_coordinator;
- GetConnector()->BindInterface(mojom::kBrowserServiceName,
- mojo::MakeRequest(&parent_coordinator));
- memory_coordinator_ = CreateChildMemoryCoordinator(
- std::move(parent_coordinator), this);
- }
-
int num_raster_threads = 0;
std::string string_value =
command_line.GetSwitchValueASCII(switches::kNumRasterThreads);
@@ -1018,7 +993,7 @@ void RenderThreadImpl::Init(
categorized_worker_pool_->Start(num_raster_threads);
discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr;
- if (features::IsMashEnabled()) {
+ if (!features::IsAshInBrowserProcess()) {
#if defined(USE_AURA)
GetServiceManagerConnection()->GetConnector()->BindInterface(
ui::mojom::kServiceName, &manager_ptr);
@@ -1127,7 +1102,7 @@ bool RenderThreadImpl::Send(IPC::Message* msg) {
}
}
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler::RendererPauseHandle>
+ std::unique_ptr<blink::scheduler::WebThreadScheduler::RendererPauseHandle>
renderer_paused_handle;
if (pumping_events) {
@@ -1192,7 +1167,8 @@ void RenderThreadImpl::RegisterPendingFrameCreate(
CHECK(result.second) << "Inserting a duplicate item.";
}
-mojom::StoragePartitionService* RenderThreadImpl::GetStoragePartitionService() {
+blink::mojom::StoragePartitionService*
+RenderThreadImpl::GetStoragePartitionService() {
return storage_partition_service_.get();
}
@@ -1278,7 +1254,7 @@ void RenderThreadImpl::InitializeWebKit(
v8::Isolate* isolate = blink::MainThreadIsolate();
isolate->SetCreateHistogramFunction(CreateHistogram);
isolate->SetAddHistogramSampleFunction(AddHistogramSample);
- main_thread_scheduler_->SetRAILModeObserver(this);
+ main_thread_scheduler_->AddRAILModeObserver(this);
main_thread_compositor_task_runner_ =
main_thread_scheduler_->CompositorTaskRunner();
@@ -1286,12 +1262,6 @@ void RenderThreadImpl::InitializeWebKit(
if (!command_line.HasSwitch(switches::kDisableThreadedCompositing))
InitializeCompositorThread();
- scoped_refptr<base::SingleThreadTaskRunner> compositor_impl_side_task_runner;
- if (compositor_task_runner_)
- compositor_impl_side_task_runner = compositor_task_runner_;
- else
- compositor_impl_side_task_runner = base::ThreadTaskRunnerHandle::Get();
-
RenderThreadImpl::RegisterSchemes();
RenderMediaClient::Initialize();
@@ -1306,17 +1276,9 @@ void RenderThreadImpl::InitializeWebKit(
isolate->IsolateInBackgroundNotification();
}
- service_worker_message_filter_ = new ServiceWorkerMessageFilter(
- thread_safe_sender(), GetWebMainThreadScheduler()->IPCTaskRunner());
- AddFilter(service_worker_message_filter_->GetFilter());
-
- main_thread_scheduler_->SetFreezingWhenBackgroundedEnabled(
- GetContentClient()->renderer()->AllowFreezingWhenProcessBackgrounded());
-
- SkGraphics::SetResourceCacheSingleAllocationByteLimit(
- kImageCacheSingleAllocationByteLimit);
-
- // Hook up blink's codecs so skia can call them
+ // Hook up blink's codecs so skia can call them. Since only the renderer
+ // processes should be doing image decoding, this is not done in the common
+ // skia initialization code for the GPU.
SkGraphics::SetImageGeneratorFromEncodedDataFactory(
blink::WebImageGenerator::CreateAsSkImageGenerator);
@@ -1475,7 +1437,7 @@ media::GpuVideoAcceleratorFactories* RenderThreadImpl::GetGpuFactories() {
limits, support_locking, support_gles2_interface,
support_raster_interface,
support_oop_rasterization, support_grcontext,
- ui::command_buffer_metrics::MEDIA_CONTEXT,
+ ui::command_buffer_metrics::ContextType::MEDIA,
kGpuStreamIdMedia, kGpuStreamPriorityMedia);
const bool enable_video_accelerator =
@@ -1538,7 +1500,7 @@ RenderThreadImpl::SharedMainThreadContextProvider() {
std::move(gpu_channel_host), GetGpuMemoryBufferManager(),
gpu::SharedMemoryLimits(), support_locking, support_gles2_interface,
support_raster_interface, support_oop_rasterization, support_grcontext,
- ui::command_buffer_metrics::RENDERER_MAINTHREAD_CONTEXT,
+ ui::command_buffer_metrics::ContextType::RENDERER_MAIN_THREAD,
kGpuStreamIdDefault, kGpuStreamPriorityDefault);
auto result = shared_main_thread_contexts_->BindToCurrentThread();
if (result != gpu::ContextResult::kSuccess)
@@ -1647,6 +1609,10 @@ bool RenderThreadImpl::IsElasticOverscrollEnabled() {
return is_elastic_overscroll_enabled_;
}
+bool RenderThreadImpl::IsUseZoomForDSFEnabled() {
+ return is_zoom_for_dsf_enabled_;
+}
+
scoped_refptr<base::SingleThreadTaskRunner>
RenderThreadImpl::GetCompositorMainThreadTaskRunner() {
return main_thread_compositor_task_runner_;
@@ -1661,7 +1627,7 @@ gpu::GpuMemoryBufferManager* RenderThreadImpl::GetGpuMemoryBufferManager() {
return gpu_->gpu_memory_buffer_manager();
}
-blink::scheduler::WebMainThreadScheduler*
+blink::scheduler::WebThreadScheduler*
RenderThreadImpl::GetWebMainThreadScheduler() {
return main_thread_scheduler_.get();
}
@@ -1698,6 +1664,12 @@ RenderThreadImpl::CreateUkmRecorderFactory() {
return std::make_unique<UkmRecorderFactoryImpl>(GetConnector()->Clone());
}
+#ifdef OS_ANDROID
+bool RenderThreadImpl::UsingSynchronousCompositing() {
+ return GetContentClient()->UsingSynchronousCompositing();
+}
+#endif
+
void RenderThreadImpl::OnRAILModeChanged(v8::RAILMode rail_mode) {
blink::MainThreadIsolate()->SetRAILMode(rail_mode);
blink::SetRAILModeOnWorkerThreadIsolates(rail_mode);
@@ -1815,6 +1787,16 @@ void RenderThreadImpl::ProcessPurgeAndSuspend() {
base::TimeDelta::FromMinutes(90));
}
+void RenderThreadImpl::SetIsLockedToSite() {
+ DCHECK(blink_platform_impl_);
+ blink_platform_impl_->SetIsLockedToSite();
+}
+
+void RenderThreadImpl::EnableV8LowMemoryMode() {
+ if (!low_memory_mode_controller_)
+ low_memory_mode_controller_.reset(new LowMemoryModeController());
+}
+
bool RenderThreadImpl::GetRendererMemoryMetrics(
RendererMemoryMetrics* memory_metrics) const {
DCHECK(memory_metrics);
@@ -1980,7 +1962,7 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
int routing_id,
scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
const GURL& url,
- const LayerTreeFrameSinkCallback& callback,
+ LayerTreeFrameSinkCallback callback,
mojom::RenderFrameMetadataObserverClientRequest
render_frame_metadata_observer_client_request,
mojom::RenderFrameMetadataObserverPtr render_frame_metadata_observer_ptr) {
@@ -1993,7 +1975,7 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
- viz::ClientLayerTreeFrameSink::InitParams params;
+ cc::mojo_embedder::AsyncLayerTreeFrameSink::InitParams params;
params.compositor_task_runner = compositor_task_runner_;
params.enable_surface_synchronization =
features::IsSurfaceSynchronizationEnabled();
@@ -2017,22 +1999,22 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
params.synthetic_begin_frame_source = CreateSyntheticBeginFrameSource();
#if defined(USE_AURA)
- if (base::FeatureList::IsEnabled(features::kMash)) {
+ if (!features::IsAshInBrowserProcess()) {
if (!RendererWindowTreeClient::Get(routing_id)) {
- callback.Run(nullptr);
+ std::move(callback).Run(nullptr);
return;
}
scoped_refptr<gpu::GpuChannelHost> channel = EstablishGpuChannelSync();
// 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) {
- callback.Run(nullptr);
+ std::move(callback).Run(nullptr);
return;
}
RendererWindowTreeClient::Get(routing_id)
->RequestLayerTreeFrameSink(
gpu_->CreateContextProvider(std::move(channel)),
- GetGpuMemoryBufferManager(), callback);
+ GetGpuMemoryBufferManager(), std::move(callback));
frame_sink_provider_->RegisterRenderFrameMetadataObserver(
routing_id, std::move(render_frame_metadata_observer_client_request),
std::move(render_frame_metadata_observer_ptr));
@@ -2054,8 +2036,9 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
frame_sink_provider_->RegisterRenderFrameMetadataObserver(
routing_id, std::move(render_frame_metadata_observer_client_request),
std::move(render_frame_metadata_observer_ptr));
- callback.Run(std::make_unique<viz::ClientLayerTreeFrameSink>(
- nullptr, nullptr, &params));
+ std::move(callback).Run(
+ std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>(
+ nullptr, nullptr, &params));
return;
}
@@ -2064,7 +2047,7 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
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);
+ std::move(callback).Run(nullptr);
return;
}
@@ -2072,7 +2055,7 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
SharedCompositorWorkerContextProvider();
if (!worker_context_provider) {
// Cause the compositor to wait and try again.
- callback.Run(nullptr);
+ std::move(callback).Run(nullptr);
return;
}
@@ -2097,18 +2080,19 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
constexpr bool automatic_flushes = false;
constexpr bool support_locking = false;
- constexpr bool support_grcontext = false;
+ constexpr bool support_grcontext = true;
scoped_refptr<ui::ContextProviderCommandBuffer> context_provider(
new ui::ContextProviderCommandBuffer(
gpu_channel_host, GetGpuMemoryBufferManager(), kGpuStreamIdDefault,
kGpuStreamPriorityDefault, gpu::kNullSurfaceHandle, url,
automatic_flushes, support_locking, support_grcontext, limits,
- attributes, ui::command_buffer_metrics::RENDER_COMPOSITOR_CONTEXT));
+ attributes,
+ ui::command_buffer_metrics::ContextType::RENDER_COMPOSITOR));
if (layout_test_deps_) {
if (!layout_test_deps_->UseDisplayCompositorPixelDump()) {
- callback.Run(layout_test_deps_->CreateLayerTreeFrameSink(
+ std::move(callback).Run(layout_test_deps_->CreateLayerTreeFrameSink(
routing_id, std::move(gpu_channel_host), std::move(context_provider),
std::move(worker_context_provider), GetGpuMemoryBufferManager(),
this));
@@ -2123,14 +2107,14 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
#if defined(OS_ANDROID)
if (GetContentClient()->UsingSynchronousCompositing()) {
- RenderViewImpl* view = RenderViewImpl::FromRoutingID(routing_id);
- if (view) {
- callback.Run(std::make_unique<SynchronousLayerTreeFrameSink>(
+ RenderWidget* widget = RenderWidget::FromRoutingID(routing_id);
+ if (widget) {
+ std::move(callback).Run(std::make_unique<SynchronousLayerTreeFrameSink>(
std::move(context_provider), std::move(worker_context_provider),
compositor_task_runner_, GetGpuMemoryBufferManager(),
sync_message_filter(), routing_id, g_next_layer_tree_frame_sink_id++,
std::move(params.synthetic_begin_frame_source),
- view->widget_input_handler_manager()
+ widget->widget_input_handler_manager()
->GetSynchronousCompositorRegistry(),
std::move(frame_swap_message_queue)));
return;
@@ -2146,9 +2130,10 @@ void RenderThreadImpl::RequestNewLayerTreeFrameSink(
routing_id, std::move(render_frame_metadata_observer_client_request),
std::move(render_frame_metadata_observer_ptr));
params.gpu_memory_buffer_manager = GetGpuMemoryBufferManager();
- callback.Run(std::make_unique<viz::ClientLayerTreeFrameSink>(
- std::move(context_provider), std::move(worker_context_provider),
- &params));
+ std::move(callback).Run(
+ std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>(
+ std::move(context_provider), std::move(worker_context_provider),
+ &params));
}
blink::AssociatedInterfaceRegistry*
@@ -2166,12 +2151,10 @@ RenderThreadImpl::RequestCopyOfOutputForLayoutTest(
}
std::unique_ptr<blink::WebMediaStreamCenter>
-RenderThreadImpl::CreateMediaStreamCenter(
- blink::WebMediaStreamCenterClient* client) {
+RenderThreadImpl::CreateMediaStreamCenter() {
std::unique_ptr<blink::WebMediaStreamCenter> media_stream_center;
if (!media_stream_center) {
- media_stream_center = std::make_unique<MediaStreamCenter>(
- client, GetPeerConnectionDependencyFactory());
+ media_stream_center = std::make_unique<MediaStreamCenter>();
}
return media_stream_center;
}
@@ -2241,8 +2224,8 @@ void RenderThreadImpl::CreateFrameProxy(
void RenderThreadImpl::SetUpEmbeddedWorkerChannelForServiceWorker(
mojom::EmbeddedWorkerInstanceClientRequest client_request) {
- EmbeddedWorkerInstanceClientImpl::Create(
- blink_initialized_time_, GetIOTaskRunner(), std::move(client_request));
+ EmbeddedWorkerInstanceClientImpl::Create(GetIOTaskRunner(),
+ std::move(client_request));
}
void RenderThreadImpl::OnNetworkConnectionChanged(
@@ -2288,14 +2271,10 @@ void RenderThreadImpl::SetUserAgent(const std::string& user_agent) {
void RenderThreadImpl::UpdateScrollbarTheme(
mojom::UpdateScrollbarThemeParamsPtr params) {
#if defined(OS_MACOSX)
- static_cast<WebScrollbarBehaviorImpl*>(
- blink_platform_impl_->ScrollbarBehavior())
- ->set_jump_on_track_click(params->jump_on_track_click);
-
blink::WebScrollbarTheme::UpdateScrollbarsWithNSDefaults(
params->initial_button_delay, params->autoscroll_button_delay,
params->preferred_scroller_style, params->redraw,
- params->button_placement);
+ params->button_placement, params->jump_on_track_click);
is_elastic_overscroll_enabled_ = params->scroll_view_rubber_banding;
#else
@@ -2317,13 +2296,7 @@ void RenderThreadImpl::OnSystemColorsChanged(
void RenderThreadImpl::PurgePluginListCache(bool reload_pages) {
#if BUILDFLAG(ENABLE_PLUGINS)
- // The call below will cause a GetPlugins call with refresh=true, but at this
- // point we already know that the browser has refreshed its list, so disable
- // refresh temporarily to prevent each renderer process causing the list to be
- // regenerated.
- blink_platform_impl_->set_plugin_refresh_allowed(false);
blink::ResetPluginCache(reload_pages);
- blink_platform_impl_->set_plugin_refresh_allowed(true);
for (auto& observer : observers_)
observer.PluginListChanged();
@@ -2366,8 +2339,6 @@ void RenderThreadImpl::OnPurgeMemory() {
OnTrimMemoryImmediately();
ReleaseFreeMemory();
- if (blink_platform_impl_)
- blink::WebMemoryCoordinator::OnPurgeMemory();
}
void RenderThreadImpl::RecordPurgeMemory(RendererMemoryMetrics before) {
@@ -2417,17 +2388,21 @@ RenderThreadImpl::SharedCompositorWorkerContextProvider() {
bool support_locking = true;
bool support_oop_rasterization =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableOOPRasterization);
+ gpu_channel_host->gpu_feature_info()
+ .status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] ==
+ gpu::kGpuFeatureStatusEnabled;
bool support_gles2_interface = !support_oop_rasterization;
bool support_raster_interface = true;
bool support_grcontext = !support_oop_rasterization;
+ auto shared_memory_limits =
+ support_oop_rasterization ? gpu::SharedMemoryLimits::ForOOPRasterContext()
+ : gpu::SharedMemoryLimits();
shared_worker_context_provider_ = CreateOffscreenContext(
std::move(gpu_channel_host), GetGpuMemoryBufferManager(),
- gpu::SharedMemoryLimits(), support_locking, support_gles2_interface,
+ shared_memory_limits, support_locking, support_gles2_interface,
support_raster_interface, support_oop_rasterization, support_grcontext,
- ui::command_buffer_metrics::RENDER_WORKER_CONTEXT, kGpuStreamIdWorker,
- kGpuStreamPriorityWorker);
+ ui::command_buffer_metrics::ContextType::RENDER_WORKER,
+ kGpuStreamIdWorker, kGpuStreamPriorityWorker);
auto result = shared_worker_context_provider_->BindToCurrentThread();
if (result != gpu::ContextResult::kSuccess)
shared_worker_context_provider_ = nullptr;
@@ -2500,7 +2475,7 @@ void RenderThreadImpl::ReleaseFreeMemory() {
if (blink_platform_impl_) {
// Purge Skia font cache, resource cache, and image filter.
SkGraphics::PurgeAllCaches();
- blink::DecommitFreeableMemory();
+ blink::WebMemoryCoordinator::OnPurgeMemory();
}
}
diff --git a/chromium/content/renderer/render_thread_impl.h b/chromium/content/renderer/render_thread_impl.h
index 6ab16c9a4fa..78326bc4c21 100644
--- a/chromium/content/renderer/render_thread_impl.h
+++ b/chromium/content/renderer/render_thread_impl.h
@@ -40,13 +40,12 @@
#include "content/common/render_message_filter.mojom.h"
#include "content/common/renderer.mojom.h"
#include "content/common/renderer_host.mojom.h"
-#include "content/common/storage_partition_service.mojom.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/url_loader_throttle_provider.h"
#include "content/renderer/gpu/compositor_dependencies.h"
#include "content/renderer/layout_test_dependencies.h"
-#include "content/renderer/media/audio_input_ipc_factory.h"
-#include "content/renderer/media/audio_output_ipc_factory.h"
+#include "content/renderer/media/audio/audio_input_ipc_factory.h"
+#include "content/renderer/media/audio/audio_output_ipc_factory.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "ipc/ipc_sync_channel.h"
#include "media/media_buildflags.h"
@@ -59,7 +58,8 @@
#include "services/service_manager/public/cpp/bind_source_info.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/viz/public/interfaces/compositing/compositing_mode_watcher.mojom.h"
-#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
+#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_connection_type.h"
#include "third_party/blink/public/web/web_memory_statistics.h"
#include "ui/gfx/native_widget_types.h"
@@ -75,7 +75,6 @@ namespace scheduler {
class WebThreadBase;
}
class WebMediaStreamCenter;
-class WebMediaStreamCenterClient;
}
namespace base {
@@ -137,6 +136,7 @@ class FileSystemDispatcher;
class FrameSwapMessageQueue;
class GpuVideoAcceleratorFactoriesImpl;
class IndexedDBDispatcher;
+class LowMemoryModeController;
class MidiMessageFilter;
class P2PSocketDispatcher;
class PeerConnectionDependencyFactory;
@@ -144,7 +144,6 @@ class PeerConnectionTracker;
class RenderThreadObserver;
class RendererBlinkPlatformImpl;
class ResourceDispatcher;
-class ServiceWorkerMessageFilter;
class VideoCaptureImplManager;
#if defined(OS_ANDROID)
@@ -169,8 +168,7 @@ class StreamTextureFactory;
class CONTENT_EXPORT RenderThreadImpl
: public RenderThread,
public ChildThreadImpl,
- public blink::scheduler::WebMainThreadScheduler::RAILModeObserver,
- public ChildMemoryCoordinatorDelegate,
+ public blink::scheduler::WebThreadScheduler::RAILModeObserver,
public base::MemoryCoordinatorClient,
public mojom::Renderer,
public viz::mojom::CompositingModeWatcher,
@@ -180,7 +178,7 @@ class CONTENT_EXPORT RenderThreadImpl
base::MessageLoop* unowned_message_loop);
static RenderThreadImpl* Create(
std::unique_ptr<base::MessageLoop> main_message_loop,
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler>
+ std::unique_ptr<blink::scheduler::WebThreadScheduler>
main_thread_scheduler);
static RenderThreadImpl* current();
static mojom::RenderMessageFilter* current_render_message_filter();
@@ -250,18 +248,22 @@ class CONTENT_EXPORT RenderThreadImpl
bool IsPartialRasterEnabled() override;
bool IsGpuMemoryBufferCompositorResourcesEnabled() override;
bool IsElasticOverscrollEnabled() override;
+ bool IsUseZoomForDSFEnabled() override;
scoped_refptr<base::SingleThreadTaskRunner>
GetCompositorMainThreadTaskRunner() override;
scoped_refptr<base::SingleThreadTaskRunner>
GetCompositorImplThreadTaskRunner() override;
- blink::scheduler::WebMainThreadScheduler* GetWebMainThreadScheduler()
- override;
+ blink::scheduler::WebThreadScheduler* GetWebMainThreadScheduler() override;
cc::TaskGraphRunner* GetTaskGraphRunner() override;
- bool IsThreadedAnimationEnabled() override;
bool IsScrollAnimatorEnabled() override;
std::unique_ptr<cc::UkmRecorderFactory> CreateUkmRecorderFactory() override;
+#ifdef OS_ANDROID
+ bool UsingSynchronousCompositing() override;
+#endif
+
+ bool IsThreadedAnimationEnabled();
- // blink::scheduler::WebMainThreadScheduler::RAILModeObserver implementation.
+ // blink::scheduler::WebThreadScheduler::RAILModeObserver implementation.
void OnRAILModeChanged(v8::RAILMode rail_mode) override;
// viz::mojom::CompositingModeWatcher implementation.
@@ -281,12 +283,12 @@ class CONTENT_EXPORT RenderThreadImpl
gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager();
using LayerTreeFrameSinkCallback =
- base::Callback<void(std::unique_ptr<cc::LayerTreeFrameSink>)>;
+ base::OnceCallback<void(std::unique_ptr<cc::LayerTreeFrameSink>)>;
void RequestNewLayerTreeFrameSink(
int routing_id,
scoped_refptr<FrameSwapMessageQueue> frame_swap_message_queue,
const GURL& url,
- const LayerTreeFrameSinkCallback& callback,
+ LayerTreeFrameSinkCallback callback,
mojom::RenderFrameMetadataObserverClientRequest
render_frame_metadata_observer_client_request,
mojom::RenderFrameMetadataObserverPtr render_frame_metadata_observer_ptr);
@@ -305,6 +307,14 @@ class CONTENT_EXPORT RenderThreadImpl
std::unique_ptr<LayoutTestDependencies> deps) {
layout_test_deps_ = std::move(deps);
}
+ // Returns whether we are running layout tests with display compositor for
+ // pixel dump enabled. It is meant to disable feature that require display
+ // compositor while it is not enabled by default.
+ // This should only be called if currently running in layout tests.
+ bool LayoutTestModeUsesDisplayCompositorPixelDump() const {
+ DCHECK(layout_test_deps_);
+ return layout_test_deps_->UseDisplayCompositorPixelDump();
+ }
discardable_memory::ClientDiscardableSharedMemoryManager*
GetDiscardableSharedMemoryManagerForTest() {
@@ -352,8 +362,7 @@ class CONTENT_EXPORT RenderThreadImpl
// Creates the embedder implementation of WebMediaStreamCenter.
// The resulting object is owned by WebKit and deleted by WebKit at tear-down.
- std::unique_ptr<blink::WebMediaStreamCenter> CreateMediaStreamCenter(
- blink::WebMediaStreamCenterClient* client);
+ std::unique_ptr<blink::WebMediaStreamCenter> CreateMediaStreamCenter();
BrowserPluginManager* browser_plugin_manager() const {
return browser_plugin_manager_.get();
@@ -375,6 +384,10 @@ class CONTENT_EXPORT RenderThreadImpl
return vc_manager_.get();
}
+ LowMemoryModeController* low_memory_mode_controller() const {
+ return low_memory_mode_controller_.get();
+ }
+
mojom::RenderFrameMessageFilter* render_frame_message_filter();
mojom::RenderMessageFilter* render_message_filter();
@@ -486,7 +499,7 @@ class CONTENT_EXPORT RenderThreadImpl
int routing_id,
mojom::FrameRequest frame);
- mojom::StoragePartitionService* GetStoragePartitionService();
+ blink::mojom::StoragePartitionService* GetStoragePartitionService();
mojom::RendererHost* GetRendererHost();
// ChildMemoryCoordinatorDelegate implementation.
@@ -512,12 +525,12 @@ class CONTENT_EXPORT RenderThreadImpl
protected:
RenderThreadImpl(
const InProcessChildThreadParams& params,
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler> scheduler,
+ std::unique_ptr<blink::scheduler::WebThreadScheduler> scheduler,
const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue,
base::MessageLoop* unowned_message_loop);
RenderThreadImpl(
std::unique_ptr<base::MessageLoop> main_message_loop,
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler> scheduler);
+ std::unique_ptr<blink::scheduler::WebThreadScheduler> scheduler);
private:
void OnProcessFinalRelease() override;
@@ -581,6 +594,8 @@ class CONTENT_EXPORT RenderThreadImpl
void SetProcessBackgrounded(bool backgrounded) override;
void SetSchedulerKeepActive(bool keep_active) override;
void ProcessPurgeAndSuspend() override;
+ void SetIsLockedToSite() override;
+ void EnableV8LowMemoryMode() override;
void OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
@@ -612,8 +627,7 @@ class CONTENT_EXPORT RenderThreadImpl
std::unique_ptr<AppCacheDispatcher> appcache_dispatcher_;
std::unique_ptr<DomStorageDispatcher> dom_storage_dispatcher_;
std::unique_ptr<IndexedDBDispatcher> main_thread_indexed_db_dispatcher_;
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler>
- main_thread_scheduler_;
+ std::unique_ptr<blink::scheduler::WebThreadScheduler> main_thread_scheduler_;
std::unique_ptr<RendererBlinkPlatformImpl> blink_platform_impl_;
std::unique_ptr<ResourceDispatcher> resource_dispatcher_;
std::unique_ptr<FileSystemDispatcher> file_system_dispatcher_;
@@ -621,7 +635,6 @@ class CONTENT_EXPORT RenderThreadImpl
// Used on the renderer and IPC threads.
scoped_refptr<MidiMessageFilter> midi_message_filter_;
- scoped_refptr<ServiceWorkerMessageFilter> service_worker_message_filter_;
std::unique_ptr<BrowserPluginManager> browser_plugin_manager_;
@@ -650,9 +663,6 @@ class CONTENT_EXPORT RenderThreadImpl
// Used on the render thread.
std::unique_ptr<VideoCaptureImplManager> vc_manager_;
- // The time Blink was initialized. Used for UMA.
- base::TimeTicks blink_initialized_time_;
-
// The count of RenderWidgets running through this thread.
int widget_count_;
@@ -724,7 +734,9 @@ class CONTENT_EXPORT RenderThreadImpl
std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
- std::unique_ptr<ChildMemoryCoordinatorImpl> memory_coordinator_;
+ // Created in response to EnableV8LowMemoryMode(), this manages V8's
+ // memory saving mode.
+ std::unique_ptr<LowMemoryModeController> low_memory_mode_controller_;
std::unique_ptr<ui::Gpu> gpu_;
@@ -739,6 +751,7 @@ class CONTENT_EXPORT RenderThreadImpl
bool is_gpu_memory_buffer_compositor_resources_enabled_;
bool is_partial_raster_enabled_;
bool is_elastic_overscroll_enabled_;
+ bool is_zoom_for_dsf_enabled_;
bool is_threaded_animation_enabled_;
bool is_scroll_animator_enabled_;
@@ -773,7 +786,7 @@ class CONTENT_EXPORT RenderThreadImpl
std::map<int, scoped_refptr<PendingFrameCreate>>;
PendingFrameCreateMap pending_frame_creates_;
- mojom::StoragePartitionServicePtr storage_partition_service_;
+ blink::mojom::StoragePartitionServicePtr storage_partition_service_;
mojom::RendererHostAssociatedPtr renderer_host_;
AssociatedInterfaceRegistryImpl associated_interfaces_;
diff --git a/chromium/content/renderer/render_thread_impl_browsertest.cc b/chromium/content/renderer/render_thread_impl_browsertest.cc
index f5977ad2ea6..3e65072fe27 100644
--- a/chromium/content/renderer/render_thread_impl_browsertest.cc
+++ b/chromium/content/renderer/render_thread_impl_browsertest.cc
@@ -50,12 +50,12 @@
#include "gpu/ipc/host/gpu_switches.h"
#include "ipc/ipc.mojom.h"
#include "ipc/ipc_channel_mojo.h"
-#include "mojo/edk/embedder/embedder.h"
-#include "mojo/edk/embedder/outgoing_broker_client_invitation.h"
-#include "mojo/edk/embedder/scoped_ipc_support.h"
+#include "mojo/core/embedder/embedder.h"
+#include "mojo/core/embedder/scoped_ipc_support.h"
+#include "mojo/public/cpp/system/invitation.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "ui/base/ui_base_switches.h"
#include "ui/gfx/buffer_format_util.h"
@@ -132,7 +132,7 @@ class RenderThreadImplForTest : public RenderThreadImpl {
public:
RenderThreadImplForTest(
const InProcessChildThreadParams& params,
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler> scheduler,
+ std::unique_ptr<blink::scheduler::WebThreadScheduler> scheduler,
scoped_refptr<base::SingleThreadTaskRunner>& test_task_counter,
base::MessageLoop* unowned_message_loop)
: RenderThreadImpl(params,
@@ -209,10 +209,10 @@ class RenderThreadImplBrowserTest : public testing::Test {
blink::scheduler::GetSingleThreadTaskRunnerForTesting();
InitializeMojo();
- mojo_ipc_support_.reset(new mojo::edk::ScopedIPCSupport(
- io_task_runner, mojo::edk::ScopedIPCSupport::ShutdownPolicy::FAST));
+ mojo_ipc_support_.reset(new mojo::core::ScopedIPCSupport(
+ io_task_runner, mojo::core::ScopedIPCSupport::ShutdownPolicy::FAST));
shell_context_.reset(new TestServiceManagerContext);
- mojo::edk::OutgoingBrokerClientInvitation invitation;
+ mojo::OutgoingInvitation invitation;
service_manager::Identity child_identity(
mojom::kRendererServiceName, service_manager::mojom::kInheritUserID,
"test");
@@ -248,9 +248,9 @@ class RenderThreadImplBrowserTest : public testing::Test {
// in RenderThreadImpl::Init().
cmd->AppendSwitch(switches::kIgnoreGpuBlacklist);
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler>
+ std::unique_ptr<blink::scheduler::WebThreadScheduler>
main_thread_scheduler =
- blink::scheduler::WebMainThreadScheduler::Create();
+ blink::scheduler::WebThreadScheduler::CreateMainThreadScheduler();
scoped_refptr<base::SingleThreadTaskRunner> test_task_counter(
test_task_counter_.get());
@@ -293,7 +293,7 @@ class RenderThreadImplBrowserTest : public testing::Test {
std::unique_ptr<TestServiceManagerContext> shell_context_;
std::unique_ptr<ChildConnection> child_connection_;
std::unique_ptr<IPC::ChannelProxy> channel_;
- std::unique_ptr<mojo::edk::ScopedIPCSupport> mojo_ipc_support_;
+ std::unique_ptr<mojo::core::ScopedIPCSupport> mojo_ipc_support_;
std::unique_ptr<MockRenderProcess> mock_process_;
scoped_refptr<QuitOnTestMsgFilter> test_msg_filter_;
diff --git a/chromium/content/renderer/render_view_browsertest.cc b/chromium/content/renderer/render_view_browsertest.cc
index 79c8ff2cff0..caa6b4a4d37 100644
--- a/chromium/content/renderer/render_view_browsertest.cc
+++ b/chromium/content/renderer/render_view_browsertest.cc
@@ -29,6 +29,7 @@
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/native_web_keyboard_event.h"
+#include "content/public/browser/web_ui_controller.h"
#include "content/public/browser/web_ui_controller_factory.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/browser_side_navigation_policy.h"
@@ -45,7 +46,7 @@
#include "content/public/test/render_view_test.h"
#include "content/public/test/test_utils.h"
#include "content/renderer/accessibility/render_accessibility_impl.h"
-#include "content/renderer/gpu/render_widget_compositor.h"
+#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/history_entry.h"
#include "content/renderer/history_serialization.h"
#include "content/renderer/loader/request_extra_data.h"
@@ -56,6 +57,7 @@
#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/fake_compositor_dependencies.h"
#include "content/test/mock_keyboard.h"
#include "content/test/test_render_frame.h"
#include "net/base/net_errors.h"
@@ -63,7 +65,9 @@
#include "services/network/public/cpp/resource_request_body.h"
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_network_provider.h"
+#include "third_party/blink/public/common/origin_trials/origin_trial_policy.h"
+#include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_data.h"
#include "third_party/blink/public/platform/web_http_body.h"
@@ -78,6 +82,7 @@
#include "third_party/blink/public/web/web_history_item.h"
#include "third_party/blink/public/web/web_input_method_controller.h"
#include "third_party/blink/public/web/web_local_frame.h"
+#include "third_party/blink/public/web/web_origin_trials.h"
#include "third_party/blink/public/web/web_performance.h"
#include "third_party/blink/public/web/web_script_source.h"
#include "third_party/blink/public/web/web_settings.h"
@@ -160,8 +165,9 @@ int ConvertMockKeyboardModifier(MockKeyboard::Modifiers modifiers) {
class WebUITestWebUIControllerFactory : public WebUIControllerFactory {
public:
- WebUIController* CreateWebUIControllerForURL(WebUI* web_ui,
- const GURL& url) const override {
+ std::unique_ptr<WebUIController> CreateWebUIControllerForURL(
+ WebUI* web_ui,
+ const GURL& url) const override {
return nullptr;
}
WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
@@ -394,10 +400,9 @@ class RenderViewImplTest : public RenderViewTest {
return view()->preferred_size_;
}
- void SetZoomLevel(double level) {
- view()->OnSetZoomLevel(
- PageMsg_SetZoomLevel_Command::USE_CURRENT_TEMPORARY_MODE, level);
- }
+ void SetZoomLevel(double level) { view()->UpdateZoomLevel(level); }
+
+ double GetZoomLevel() { return view()->page_zoom_level(); }
int GetScrollbarWidth() {
blink::WebView* webview = view()->webview();
@@ -437,8 +442,16 @@ class RenderViewImplBlinkSettingsTest : public RenderViewImplTest {
void SetUp() override {}
};
-class RenderViewImplScaleFactorTest : public RenderViewImplBlinkSettingsTest {
+// This test class enables UseZoomForDSF based on the platform default value.
+class RenderViewImplScaleFactorTest : public RenderViewImplTest {
protected:
+ std::unique_ptr<CompositorDependencies> CreateCompositorDependencies()
+ override {
+ auto deps = std::make_unique<FakeCompositorDependencies>();
+ deps->set_use_zoom_for_dsf_enabled(content::IsUseZoomForDSFEnabled());
+ return deps;
+ }
+
void SetDeviceScaleFactor(float dsf) {
VisualProperties visual_properties;
visual_properties.screen_info.device_scale_factor = dsf;
@@ -482,10 +495,32 @@ class RenderViewImplScaleFactorTest : public RenderViewImplBlinkSettingsTest {
EXPECT_EQ(height, emulated_height);
EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_dpr, &emulated_dpr));
EXPECT_EQ(static_cast<int>(dpr * 10), emulated_dpr);
- EXPECT_EQ(compositor_dsf, view()
- ->compositor()
- ->layer_tree_host()
- ->device_scale_factor());
+ cc::LayerTreeHost* host = view()->layer_tree_view()->layer_tree_host();
+ EXPECT_EQ(compositor_dsf, host->device_scale_factor());
+ }
+};
+
+// This test class forces UseZoomForDSF to be on for all platforms.
+class RenderViewImplEnableZoomForDSFTest
+ : public RenderViewImplScaleFactorTest {
+ protected:
+ std::unique_ptr<CompositorDependencies> CreateCompositorDependencies()
+ override {
+ auto deps = std::make_unique<FakeCompositorDependencies>();
+ deps->set_use_zoom_for_dsf_enabled(true);
+ return deps;
+ }
+};
+
+// This test class forces UseZoomForDSF to be off for all platforms.
+class RenderViewImplDisableZoomForDSFTest
+ : public RenderViewImplScaleFactorTest {
+ protected:
+ std::unique_ptr<CompositorDependencies> CreateCompositorDependencies()
+ override {
+ auto deps = std::make_unique<FakeCompositorDependencies>();
+ deps->set_use_zoom_for_dsf_enabled(false);
+ return deps;
}
};
@@ -532,9 +567,8 @@ static blink::WebCoalescedInputEvent FatTap(int x,
}
TEST_F(RenderViewImplScaleFactorTest, TapDisambiguatorSize) {
- DoSetUp();
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableUseZoomForDSF);
+ // TODO(oshima): This test tried in the past to enable UseZoomForDSF but
+ // didn't actually do so for the compositor, and fails with it enabled.
const float device_scale = 2.625f;
SetDeviceScaleFactor(device_scale);
EXPECT_EQ(device_scale, view()->GetDeviceScaleFactor());
@@ -689,7 +723,7 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicy) {
request.SetFetchRedirectMode(network::mojom::FetchRedirectMode::kManual);
request.SetFrameType(network::mojom::RequestContextFrameType::kTopLevel);
request.SetRequestContext(blink::WebURLRequest::kRequestContextInternal);
- blink::WebFrameClient::NavigationPolicyInfo policy_info(request);
+ blink::WebLocalFrameClient::NavigationPolicyInfo policy_info(request);
policy_info.navigation_type = blink::kWebNavigationTypeLinkClicked;
policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;
blink::WebNavigationPolicy policy =
@@ -706,7 +740,8 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicy) {
// Verify that form posts to WebUI URLs will be sent to the browser process.
blink::WebURLRequest form_request(GURL("chrome://foo"));
- blink::WebFrameClient::NavigationPolicyInfo form_policy_info(form_request);
+ blink::WebLocalFrameClient::NavigationPolicyInfo form_policy_info(
+ form_request);
form_policy_info.navigation_type = blink::kWebNavigationTypeFormSubmitted;
form_policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;
form_request.SetHTTPMethod("POST");
@@ -715,7 +750,8 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicy) {
// Verify that popup links to WebUI URLs also are sent to browser.
blink::WebURLRequest popup_request(GURL("chrome://foo"));
- blink::WebFrameClient::NavigationPolicyInfo popup_policy_info(popup_request);
+ blink::WebLocalFrameClient::NavigationPolicyInfo popup_policy_info(
+ popup_request);
popup_policy_info.navigation_type = blink::kWebNavigationTypeLinkClicked;
popup_policy_info.default_policy =
blink::kWebNavigationPolicyNewForegroundTab;
@@ -741,7 +777,7 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicyHandlesAllTopLevel) {
};
blink::WebURLRequest request(GURL("http://foo.com"));
- blink::WebFrameClient::NavigationPolicyInfo policy_info(request);
+ blink::WebLocalFrameClient::NavigationPolicyInfo policy_info(request);
policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;
for (size_t i = 0; i < arraysize(kNavTypes); ++i) {
@@ -762,7 +798,7 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicyForWebUI) {
// Navigations to normal HTTP URLs will be sent to browser process.
blink::WebURLRequest request(GURL("http://foo.com"));
- blink::WebFrameClient::NavigationPolicyInfo policy_info(request);
+ blink::WebLocalFrameClient::NavigationPolicyInfo policy_info(request);
policy_info.navigation_type = blink::kWebNavigationTypeLinkClicked;
policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;
@@ -772,7 +808,8 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicyForWebUI) {
// Navigations to WebUI URLs will also be sent to browser process.
blink::WebURLRequest webui_request(GURL("chrome://foo"));
- blink::WebFrameClient::NavigationPolicyInfo webui_policy_info(webui_request);
+ blink::WebLocalFrameClient::NavigationPolicyInfo webui_policy_info(
+ webui_request);
webui_policy_info.navigation_type = blink::kWebNavigationTypeLinkClicked;
webui_policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;
policy = frame()->DecidePolicyForNavigation(webui_policy_info);
@@ -780,7 +817,8 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicyForWebUI) {
// Verify that form posts to data URLs will be sent to the browser process.
blink::WebURLRequest data_request(GURL("data:text/html,foo"));
- blink::WebFrameClient::NavigationPolicyInfo data_policy_info(data_request);
+ blink::WebLocalFrameClient::NavigationPolicyInfo data_policy_info(
+ data_request);
data_policy_info.navigation_type = blink::kWebNavigationTypeFormSubmitted;
data_policy_info.default_policy = blink::kWebNavigationPolicyCurrentTab;
data_request.SetHTTPMethod("POST");
@@ -796,7 +834,8 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicyForWebUI) {
blink::kWebNavigationPolicyNewForegroundTab, false,
blink::WebSandboxFlags::kNone);
RenderViewImpl* new_view = RenderViewImpl::FromWebView(new_web_view);
- blink::WebFrameClient::NavigationPolicyInfo popup_policy_info(popup_request);
+ blink::WebLocalFrameClient::NavigationPolicyInfo popup_policy_info(
+ popup_request);
popup_policy_info.navigation_type = blink::kWebNavigationTypeLinkClicked;
popup_policy_info.default_policy =
blink::kWebNavigationPolicyNewForegroundTab;
@@ -811,14 +850,13 @@ TEST_F(RenderViewImplTest, DecideNavigationPolicyForWebUI) {
// continues to receive the original ScreenInfo and not the emualted
// ScreenInfo.
TEST_F(RenderViewImplScaleFactorTest, DeviceEmulationWithOOPIF) {
- DoSetUp();
-
// This test should only run with --site-per-process.
if (!AreAllSitesIsolatedForTesting())
return;
const float device_scale = 2.0f;
- float compositor_dsf = IsUseZoomForDSFEnabled() ? 1.f : device_scale;
+ float compositor_dsf =
+ compositor_deps_->IsUseZoomForDSFEnabled() ? 1.f : device_scale;
SetDeviceScaleFactor(device_scale);
LoadHTML(
@@ -909,11 +947,7 @@ TEST_F(RenderViewImplTest, OriginReplicationForSwapOut) {
// 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);
+TEST_F(RenderViewImplEnableZoomForDSFTest, UpdateDSFAfterSwapIn) {
const float device_scale = 3.0f;
SetDeviceScaleFactor(device_scale);
EXPECT_EQ(device_scale, view()->GetDeviceScaleFactor());
@@ -952,9 +986,23 @@ TEST_F(RenderViewImplScaleFactorTest, UpdateDSFAfterSwapIn) {
common_params.transition = ui::PAGE_TRANSITION_TYPED;
provisional_frame->Navigate(common_params, request_params);
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(device_scale, view()->GetDeviceScaleFactor());
EXPECT_EQ(device_scale, view()->webview()->ZoomFactorForDeviceScaleFactor());
+
+ double device_pixel_ratio;
+ base::string16 get_dpr =
+ base::ASCIIToUTF16("Number(window.devicePixelRatio)");
+ EXPECT_TRUE(
+ ExecuteJavaScriptAndReturnNumberValue(get_dpr, &device_pixel_ratio));
+ EXPECT_EQ(device_scale, device_pixel_ratio);
+
+ int width;
+ base::string16 get_width =
+ base::ASCIIToUTF16("Number(document.documentElement.clientWidth)");
+ EXPECT_TRUE(ExecuteJavaScriptAndReturnIntValue(get_width, &width));
+ EXPECT_EQ(view()->webview()->Size().width, width * device_scale);
}
// Test that when a parent detaches a remote child after the provisional
@@ -1016,11 +1064,8 @@ TEST_F(RenderViewImplTest, DetachingProxyAlsoDestroysProvisionalFrame) {
// Verify that the renderer process doesn't crash when device scale factor
// changes after a cross-process navigation has commited.
// See https://crbug.com/571603.
-TEST_F(RenderViewImplTest, SetZoomLevelAfterCrossProcessNavigation) {
- // The bug reproduces if zoom is used for devices scale factor.
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableUseZoomForDSF);
-
+TEST_F(RenderViewImplEnableZoomForDSFTest,
+ SetZoomLevelAfterCrossProcessNavigation) {
LoadHTML("Hello world!");
// Swap the main frame out after which it should become a WebRemoteFrame.
@@ -2312,7 +2357,6 @@ TEST_F(RenderViewImplTest, PreferredSizeZoomed) {
}
TEST_F(RenderViewImplScaleFactorTest, PreferredSizeWithScaleFactor) {
- DoSetUp();
LoadHTML(
"<body style='margin:0;'><div style='display:inline-block; "
"width:400px; height:400px;'/></body>");
@@ -2523,13 +2567,11 @@ TEST_F(RenderViewImplBlinkSettingsTest, Negative) {
EXPECT_TRUE(settings()->ViewportEnabled());
}
-TEST_F(RenderViewImplScaleFactorTest, ConverViewportToWindowWithoutZoomForDSF) {
- DoSetUp();
- if (IsUseZoomForDSFEnabled())
- return;
+TEST_F(RenderViewImplDisableZoomForDSFTest,
+ ConverViewportToWindowWithoutZoomForDSF) {
SetDeviceScaleFactor(2.f);
blink::WebRect rect(20, 10, 200, 100);
- view()->ConvertViewportToWindow(&rect);
+ view()->WidgetClient()->ConvertViewportToWindow(&rect);
EXPECT_EQ(20, rect.x);
EXPECT_EQ(10, rect.y);
EXPECT_EQ(200, rect.width);
@@ -2537,7 +2579,6 @@ TEST_F(RenderViewImplScaleFactorTest, ConverViewportToWindowWithoutZoomForDSF) {
}
TEST_F(RenderViewImplScaleFactorTest, ScreenMetricsEmulationWithOriginalDSF1) {
- DoSetUp();
SetDeviceScaleFactor(1.f);
LoadHTML("<body style='min-height:1000px;'></body>");
@@ -2566,10 +2607,8 @@ TEST_F(RenderViewImplScaleFactorTest, ScreenMetricsEmulationWithOriginalDSF1) {
}
TEST_F(RenderViewImplScaleFactorTest, ScreenMetricsEmulationWithOriginalDSF2) {
- DoSetUp();
SetDeviceScaleFactor(2.f);
- float compositor_dsf =
- IsUseZoomForDSFEnabled() ? 1.f : 2.f;
+ float compositor_dsf = compositor_deps_->IsUseZoomForDSFEnabled() ? 1.f : 2.f;
LoadHTML("<body style='min-height:1000px;'></body>");
{
@@ -2596,14 +2635,12 @@ TEST_F(RenderViewImplScaleFactorTest, ScreenMetricsEmulationWithOriginalDSF2) {
// Don't disable here to test that emulation is being shutdown properly.
}
-TEST_F(RenderViewImplScaleFactorTest, ConverViewportToWindowWithZoomForDSF) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableUseZoomForDSF);
- DoSetUp();
+TEST_F(RenderViewImplEnableZoomForDSFTest,
+ ConverViewportToWindowWithZoomForDSF) {
SetDeviceScaleFactor(1.f);
{
blink::WebRect rect(20, 10, 200, 100);
- view()->ConvertViewportToWindow(&rect);
+ view()->WidgetClient()->ConvertViewportToWindow(&rect);
EXPECT_EQ(20, rect.x);
EXPECT_EQ(10, rect.y);
EXPECT_EQ(200, rect.width);
@@ -2613,7 +2650,7 @@ TEST_F(RenderViewImplScaleFactorTest, ConverViewportToWindowWithZoomForDSF) {
SetDeviceScaleFactor(2.f);
{
blink::WebRect rect(20, 10, 200, 100);
- view()->ConvertViewportToWindow(&rect);
+ view()->WidgetClient()->ConvertViewportToWindow(&rect);
EXPECT_EQ(10, rect.x);
EXPECT_EQ(5, rect.y);
EXPECT_EQ(100, rect.width);
@@ -2622,11 +2659,8 @@ TEST_F(RenderViewImplScaleFactorTest, ConverViewportToWindowWithZoomForDSF) {
}
#if defined(OS_MACOSX) || defined(USE_AURA)
-TEST_F(RenderViewImplScaleFactorTest,
+TEST_F(RenderViewImplEnableZoomForDSFTest,
DISABLED_GetCompositionCharacterBoundsTest) { // http://crbug.com/582016
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableUseZoomForDSF);
- DoSetUp();
SetDeviceScaleFactor(1.f);
#if defined(OS_WIN)
// http://crbug.com/508747
@@ -2679,10 +2713,7 @@ const char kAutoResizeTestPage[] =
} // namespace
-TEST_F(RenderViewImplScaleFactorTest, AutoResizeWithZoomForDSF) {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kEnableUseZoomForDSF);
- DoSetUp();
+TEST_F(RenderViewImplEnableZoomForDSFTest, AutoResizeWithZoomForDSF) {
view()->EnableAutoResizeForTesting(gfx::Size(5, 5), gfx::Size(1000, 1000));
LoadHTML(kAutoResizeTestPage);
gfx::Size size_at_1x = view()->GetWidget()->size();
@@ -2695,7 +2726,6 @@ TEST_F(RenderViewImplScaleFactorTest, AutoResizeWithZoomForDSF) {
}
TEST_F(RenderViewImplScaleFactorTest, AutoResizeWithoutZoomForDSF) {
- DoSetUp();
view()->EnableAutoResizeForTesting(gfx::Size(5, 5), gfx::Size(1000, 1000));
LoadHTML(kAutoResizeTestPage);
gfx::Size size_at_1x = view()->GetWidget()->size();
@@ -2707,6 +2737,104 @@ TEST_F(RenderViewImplScaleFactorTest, AutoResizeWithoutZoomForDSF) {
EXPECT_EQ(size_at_1x, size_at_2x);
}
+TEST_F(RenderViewImplScaleFactorTest, ZoomLevelUpdate) {
+ // 0 is the default zoom level, nothing will change.
+ SetZoomLevel(0);
+ EXPECT_NEAR(0.0, GetZoomLevel(), 0.01);
+
+ // Change the zoom level to 25% and check if the view gets the change.
+ SetZoomLevel(content::ZoomFactorToZoomLevel(0.25));
+ EXPECT_NEAR(content::ZoomFactorToZoomLevel(0.25), GetZoomLevel(), 0.01);
+}
+
#endif
+// Origin Trial Policy which vends the test public key so that the token
+// can be validated.
+class TestOriginTrialPolicy : public blink::OriginTrialPolicy {
+ bool IsOriginTrialsSupported() const override { return true; }
+ base::StringPiece GetPublicKey() const override {
+ // This is the public key which the test below will use to enable origin
+ // trial features. Trial tokens for use in tests can be created with the
+ // tool in /tools/origin_trials/generate_token.py, using the private key
+ // contained in /tools/origin_trials/eftest.key.
+ static const uint8_t kOriginTrialPublicKey[] = {
+ 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,
+ };
+ return base::StringPiece(
+ reinterpret_cast<const char*>(kOriginTrialPublicKey),
+ base::size(kOriginTrialPublicKey));
+ }
+ bool IsOriginSecure(const GURL& url) const override { return true; }
+};
+
+TEST_F(RenderViewImplTest, OriginTrialDisabled) {
+ // HTML Document with no origin trial.
+ const char kHTMLWithNoOriginTrial[] =
+ "<!DOCTYPE html>"
+ "<html>"
+ "<head>"
+ "<title>Origin Trial Test</title>"
+ "</head>"
+ "</html>";
+
+ // Override the origin trial policy to use the test keys.
+ TestOriginTrialPolicy policy;
+ blink::TrialTokenValidator::SetOriginTrialPolicyGetter(base::BindRepeating(
+ [](TestOriginTrialPolicy* policy_ptr) -> blink::OriginTrialPolicy* {
+ return policy_ptr;
+ },
+ base::Unretained(&policy)));
+
+ // Set the document URL.
+ LoadHTMLWithUrlOverride(kHTMLWithNoOriginTrial, "https://example.test/");
+ blink::WebFrame* web_frame = frame()->GetWebFrame();
+ ASSERT_TRUE(web_frame);
+ ASSERT_TRUE(web_frame->IsWebLocalFrame());
+ blink::WebDocument web_doc = web_frame->ToWebLocalFrame()->GetDocument();
+ EXPECT_FALSE(blink::WebOriginTrials::isTrialEnabled(&web_doc, "Frobulate"));
+ // Reset the origin trial policy.
+ blink::TrialTokenValidator::ResetOriginTrialPolicyGetter();
+}
+
+TEST_F(RenderViewImplTest, OriginTrialEnabled) {
+ // HTML Document with an origin trial.
+ // Note: The token below will expire in 2033. It was generated with the
+ // command:
+ // generate_token.py https://example.test Frobulate \
+ // -expire-timestamp=2000000000
+ const char kHTMLWithOriginTrial[] =
+ "<!DOCTYPE html>"
+ "<html>"
+ "<head>"
+ "<title>Origin Trial Test</title>"
+ "<meta http-equiv=\"origin-trial\" "
+ "content=\"AlrgXVXDH5RSr6sDZiO6/8Hejv3BIhODCSS/0zD8VmDDLNPn463JzEq/Cv/"
+ "wqt8cRHacGD3cUhKkibGIGQbaXAMAAABUeyJvcmlnaW4iOiAiaHR0cHM6Ly9leGFtcGxlLnR"
+ "lc3Q6NDQzIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlIiwgImV4cGlyeSI6IDIwMDAwMDAwMDB"
+ "9\">"
+ "</head>"
+ "</html>";
+
+ // Override the origin trial policy to use the test keys.
+ TestOriginTrialPolicy policy;
+ blink::TrialTokenValidator::SetOriginTrialPolicyGetter(base::BindRepeating(
+ [](TestOriginTrialPolicy* policy_ptr) -> blink::OriginTrialPolicy* {
+ return policy_ptr;
+ },
+ base::Unretained(&policy)));
+
+ // Set the document URL so the origin is correct for the trial.
+ LoadHTMLWithUrlOverride(kHTMLWithOriginTrial, "https://example.test/");
+ blink::WebFrame* web_frame = frame()->GetWebFrame();
+ ASSERT_TRUE(web_frame);
+ ASSERT_TRUE(web_frame->IsWebLocalFrame());
+ blink::WebDocument web_doc = web_frame->ToWebLocalFrame()->GetDocument();
+ EXPECT_TRUE(blink::WebOriginTrials::isTrialEnabled(&web_doc, "Frobulate"));
+ // Reset the origin trial policy.
+ blink::TrialTokenValidator::ResetOriginTrialPolicyGetter();
+}
+
} // namespace content
diff --git a/chromium/content/renderer/render_view_impl.cc b/chromium/content/renderer/render_view_impl.cc
index 4aba7a9e290..03d9cda9f95 100644
--- a/chromium/content/renderer/render_view_impl.cc
+++ b/chromium/content/renderer/render_view_impl.cc
@@ -39,6 +39,7 @@
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "cc/paint/skia_paint_canvas.h"
+#include "cc/trees/layer_tree_host.h"
#include "content/common/content_constants_internal.h"
#include "content/common/dom_storage/dom_storage_namespace_ids.h"
#include "content/common/dom_storage/dom_storage_types.h"
@@ -72,13 +73,13 @@
#include "content/renderer/browser_plugin/browser_plugin.h"
#include "content/renderer/browser_plugin/browser_plugin_manager.h"
#include "content/renderer/drop_data_builder.h"
-#include "content/renderer/gpu/render_widget_compositor.h"
+#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/history_serialization.h"
#include "content/renderer/idle_user_detector.h"
#include "content/renderer/ime_event_guard.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/audio/audio_device_factory.h"
#include "content/renderer/media/stream/media_stream_device_observer.h"
#include "content/renderer/media/video_capture_impl_manager.h"
#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
@@ -109,6 +110,7 @@
#include "ppapi/buildflags/buildflags.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
+#include "third_party/blink/public/common/frame/user_activation_update_source.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
#include "third_party/blink/public/platform/url_conversion.h"
@@ -148,7 +150,6 @@
#include "third_party/blink/public/web/web_hit_test_result.h"
#include "third_party/blink/public/web/web_input_element.h"
#include "third_party/blink/public/web/web_local_frame.h"
-#include "third_party/blink/public/web/web_media_player_action.h"
#include "third_party/blink/public/web/web_navigation_policy.h"
#include "third_party/blink/public/web/web_page_importance_signals.h"
#include "third_party/blink/public/web/web_plugin.h"
@@ -216,7 +217,6 @@ using blink::WebImage;
using blink::WebInputElement;
using blink::WebInputEvent;
using blink::WebLocalFrame;
-using blink::WebMediaPlayerAction;
using blink::WebMouseEvent;
using blink::WebNavigationPolicy;
using blink::WebNavigationType;
@@ -409,39 +409,6 @@ void ApplyBlinkSettings(const base::CommandLine& command_line,
}
}
-// This class represents promise which is robust to (will not be broken by)
-// |DidNotSwapReason::SWAP_FAILS| events.
-class AlwaysDrawSwapPromise : public cc::SwapPromise {
- public:
- explicit AlwaysDrawSwapPromise(const ui::LatencyInfo& latency_info)
- : latency_info_(latency_info) {}
-
- ~AlwaysDrawSwapPromise() override = default;
-
- void DidActivate() override {}
-
- void WillSwap(viz::CompositorFrameMetadata* metadata,
- cc::FrameTokenAllocator* frame_token_allocator) override {
- DCHECK(!latency_info_.terminated());
- metadata->latency_info.push_back(latency_info_);
- }
-
- void DidSwap() override {}
-
- DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override {
- return reason == DidNotSwapReason::SWAP_FAILS
- ? DidNotSwapAction::KEEP_ACTIVE
- : DidNotSwapAction::BREAK_PROMISE;
- }
-
- void OnCommit() override {}
-
- int64_t TraceId() const override { return latency_info_.trace_id(); }
-
- private:
- ui::LatencyInfo latency_info_;
-};
-
content::mojom::WindowContainerType WindowFeaturesToContainerType(
const blink::WebWindowFeatures& window_features) {
if (window_features.background) {
@@ -460,7 +427,7 @@ RenderViewImpl::RenderViewImpl(
CompositorDependencies* compositor_deps,
const mojom::CreateViewParams& params,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : RenderWidget(params.view_id,
+ : RenderWidget(params.main_frame_widget_routing_id,
compositor_deps,
blink::kWebPopupTypeNone,
params.visual_properties.screen_info,
@@ -468,6 +435,7 @@ RenderViewImpl::RenderViewImpl(
params.hidden,
params.never_visible,
task_runner),
+ routing_id_(params.view_id),
webkit_preferences_(params.web_preferences),
send_content_state_immediately_(false),
send_preferred_size_changes_(false),
@@ -476,7 +444,6 @@ RenderViewImpl::RenderViewImpl(
history_list_length_(0),
frames_in_progress_(0),
target_url_status_(TARGET_NONE),
- uses_temporary_zoom_level_(false),
#if defined(OS_ANDROID)
top_controls_constraints_(BROWSER_CONTROLS_STATE_BOTH),
#endif
@@ -484,7 +451,7 @@ RenderViewImpl::RenderViewImpl(
top_controls_height_(0.f),
bottom_controls_height_(0.f),
webview_(nullptr),
- page_zoom_level_(params.page_zoom_level),
+ page_zoom_level_(0),
main_render_frame_(nullptr),
frame_widget_(nullptr),
#if defined(OS_ANDROID)
@@ -495,11 +462,12 @@ RenderViewImpl::RenderViewImpl(
renderer_wide_named_frame_lookup_(false),
weak_ptr_factory_(this) {
GetWidget()->set_owner_delegate(this);
+ RenderThread::Get()->AddRoute(routing_id_, this);
}
void RenderViewImpl::Initialize(
mojom::CreateViewParamsPtr params,
- const RenderWidget::ShowCallback& show_callback,
+ RenderWidget::ShowCallback show_callback,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
bool was_created_by_renderer = !show_callback.is_null();
#if defined(OS_ANDROID)
@@ -513,12 +481,14 @@ void RenderViewImpl::Initialize(
WebFrame* opener_frame =
RenderFrameImpl::ResolveOpener(params->opener_frame_route_id);
+ // Pass WidgetClient(), not |this|, as the WebWidgetClient. The method may
+ // be overridden in layout tests to inject a test-only WebWidgetClient.
webview_ =
- WebView::Create(this,
+ WebView::Create(this, WidgetClient(),
is_hidden() ? blink::mojom::PageVisibilityState::kHidden
: blink::mojom::PageVisibilityState::kVisible,
opener_frame ? opener_frame->View() : nullptr);
- RenderWidget::Init(show_callback, webview_->GetWidget());
+ RenderWidget::Init(std::move(show_callback), webview_->GetWidget());
g_view_map.Get().insert(std::make_pair(webview(), this));
g_routing_id_view_map.Get().insert(std::make_pair(GetRoutingID(), this));
@@ -535,7 +505,7 @@ void RenderViewImpl::Initialize(
webview()->SetShowFPSCounter(
command_line.HasSwitch(cc::switches::kShowFPSCounter));
- ApplyWebPreferencesInternal(webkit_preferences_, webview(), compositor_deps_);
+ ApplyWebPreferencesInternal(webkit_preferences_, webview());
if (switches::IsTouchDragDropEnabled())
webview()->GetSettings()->SetTouchDragDropEnabled(true);
@@ -543,24 +513,34 @@ void RenderViewImpl::Initialize(
WebSettings::SelectionStrategyType selection_strategy =
WebSettings::SelectionStrategyType::kCharacter;
const std::string selection_strategy_str =
- base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kTouchTextSelectionStrategy);
+ command_line.GetSwitchValueASCII(switches::kTouchTextSelectionStrategy);
if (selection_strategy_str == "direction")
selection_strategy = WebSettings::SelectionStrategyType::kDirection;
webview()->GetSettings()->SetSelectionStrategy(selection_strategy);
- std::string passiveListenersDefault =
+ std::string passive_listeners_default =
command_line.GetSwitchValueASCII(switches::kPassiveListenersDefault);
- if (!passiveListenersDefault.empty()) {
+ if (!passive_listeners_default.empty()) {
WebSettings::PassiveEventListenerDefault passiveDefault =
WebSettings::PassiveEventListenerDefault::kFalse;
- if (passiveListenersDefault == "true")
+ if (passive_listeners_default == "true")
passiveDefault = WebSettings::PassiveEventListenerDefault::kTrue;
- else if (passiveListenersDefault == "forcealltrue")
+ else if (passive_listeners_default == "forcealltrue")
passiveDefault = WebSettings::PassiveEventListenerDefault::kForceAllTrue;
webview()->GetSettings()->SetPassiveEventListenerDefault(passiveDefault);
}
+ std::string fmp_network_quiet_timeout =
+ command_line.GetSwitchValueASCII(switches::kFMPNetworkQuietTimeout);
+ if (!fmp_network_quiet_timeout.empty()) {
+ double fmp_network_quiet_timeout_seconds = 0.0;
+ if (base::StringToDouble(fmp_network_quiet_timeout,
+ &fmp_network_quiet_timeout_seconds)) {
+ webview()->GetSettings()->SetFMPNetworkQuietTimeout(
+ fmp_network_quiet_timeout_seconds);
+ }
+ }
+
ApplyBlinkSettings(command_line, webview()->GetSettings());
if (params->main_frame_routing_id != MSG_ROUTING_NONE) {
@@ -609,8 +589,7 @@ void RenderViewImpl::Initialize(
idle_user_detector_.reset(new IdleUserDetector());
GetContentClient()->renderer()->RenderViewCreated(this);
-
- page_zoom_level_ = params->page_zoom_level;
+ page_zoom_level_ = 0;
nav_state_sync_timer_.SetTaskRunner(task_runner);
check_preferred_size_timer_.SetTaskRunner(std::move(task_runner));
@@ -618,6 +597,7 @@ void RenderViewImpl::Initialize(
RenderViewImpl::~RenderViewImpl() {
DCHECK(!frame_widget_);
+ RenderThread::Get()->RemoveRoute(routing_id_);
#if defined(OS_ANDROID)
// The date/time picker client is both a std::unique_ptr member of this class
@@ -845,15 +825,16 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
static_cast<WebSettings::SavePreviousDocumentResources>(
prefs.save_previous_document_resources));
+ settings->SetTextAutosizingEnabled(prefs.text_autosizing_enabled);
+ settings->SetDoubleTapToZoomEnabled(prefs.double_tap_to_zoom_enabled);
+
#if defined(OS_ANDROID)
settings->SetAllowCustomScrollbarInMainFrame(false);
- settings->SetTextAutosizingEnabled(prefs.text_autosizing_enabled);
settings->SetAccessibilityFontScaleFactor(prefs.font_scale_factor);
settings->SetDeviceScaleAdjustment(prefs.device_scale_adjustment);
settings->SetFullscreenSupported(prefs.fullscreen_supported);
web_view->SetIgnoreViewportTagScaleLimits(prefs.force_enable_zoom);
settings->SetAutoZoomFocusedNodeToLegibleScale(true);
- settings->SetDoubleTapToZoomEnabled(prefs.double_tap_to_zoom_enabled);
settings->SetMediaPlaybackGestureWhitelistScope(
blink::WebString::FromUTF8(prefs.media_playback_gesture_whitelist_scope));
settings->SetDefaultVideoPosterURL(
@@ -961,13 +942,47 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
static_cast<blink::WebEffectiveConnectionType>(
prefs.low_priority_iframes_threshold));
- settings->SetPictureInPictureEnabled(prefs.picture_in_picture_enabled);
+ settings->SetPictureInPictureEnabled(
+ prefs.picture_in_picture_enabled &&
+ MediaFactory::VideoSurfaceLayerEnabled());
settings->SetDataSaverHoldbackWebApi(
prefs.data_saver_holdback_web_api_enabled);
settings->SetDataSaverHoldbackMediaApi(
prefs.data_saver_holdback_media_api_enabled);
+ for (const auto& ect_distance_pair :
+ prefs.lazy_frame_loading_distance_thresholds_px) {
+ switch (ect_distance_pair.first) {
+ case net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN:
+ settings->SetLazyFrameLoadingDistanceThresholdPxUnknown(
+ ect_distance_pair.second);
+ break;
+ case net::EFFECTIVE_CONNECTION_TYPE_OFFLINE:
+ settings->SetLazyFrameLoadingDistanceThresholdPxOffline(
+ ect_distance_pair.second);
+ break;
+ case net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G:
+ settings->SetLazyFrameLoadingDistanceThresholdPxSlow2G(
+ ect_distance_pair.second);
+ break;
+ case net::EFFECTIVE_CONNECTION_TYPE_2G:
+ settings->SetLazyFrameLoadingDistanceThresholdPx2G(
+ ect_distance_pair.second);
+ break;
+ case net::EFFECTIVE_CONNECTION_TYPE_3G:
+ settings->SetLazyFrameLoadingDistanceThresholdPx3G(
+ ect_distance_pair.second);
+ break;
+ case net::EFFECTIVE_CONNECTION_TYPE_4G:
+ settings->SetLazyFrameLoadingDistanceThresholdPx4G(
+ ect_distance_pair.second);
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+
#if defined(OS_MACOSX)
settings->SetDoubleTapToZoomEnabled(true);
web_view->SetMaximumLegibleScale(prefs.default_maximum_page_scale_factor);
@@ -982,16 +997,17 @@ void RenderView::ApplyWebPreferences(const WebPreferences& prefs,
RenderViewImpl* RenderViewImpl::Create(
CompositorDependencies* compositor_deps,
mojom::CreateViewParamsPtr params,
- const RenderWidget::ShowCallback& show_callback,
+ RenderWidget::ShowCallback show_callback,
scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
DCHECK(params->view_id != MSG_ROUTING_NONE);
+ DCHECK(params->main_frame_widget_routing_id != MSG_ROUTING_NONE);
RenderViewImpl* render_view;
if (g_create_render_view_impl)
render_view = g_create_render_view_impl(compositor_deps, *params);
else
render_view = new RenderViewImpl(compositor_deps, *params, task_runner);
- render_view->Initialize(std::move(params), show_callback,
+ render_view->Initialize(std::move(params), std::move(show_callback),
std::move(task_runner));
return render_view;
}
@@ -1030,6 +1046,24 @@ bool RenderViewImpl::RenderWidgetWillHandleMouseEvent(
return mouse_lock_dispatcher_->WillHandleMouseEvent(event);
}
+void RenderViewImpl::SetActive(bool active) {
+ if (webview())
+ webview()->SetIsActive(active);
+}
+
+void RenderViewImpl::SetBackgroundOpaque(bool opaque) {
+ if (!frame_widget_)
+ return;
+
+ if (opaque) {
+ frame_widget_->ClearBaseBackgroundColorOverride();
+ frame_widget_->ClearBackgroundColorOverride();
+ } else {
+ frame_widget_->SetBaseBackgroundColorOverride(SK_ColorTRANSPARENT);
+ frame_widget_->SetBackgroundColorOverride(SK_ColorTRANSPARENT);
+ }
+}
+
// IPC::Listener implementation ----------------------------------------------
bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
@@ -1057,24 +1091,19 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
OnEnumerateDirectoryResponse)
IPC_MESSAGE_HANDLER(ViewMsg_ClosePage, OnClosePage)
IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
- IPC_MESSAGE_HANDLER(ViewMsg_SetBackgroundOpaque, OnSetBackgroundOpaque)
IPC_MESSAGE_HANDLER(ViewMsg_EnablePreferredSizeChangedMode,
OnEnablePreferredSizeChangedMode)
IPC_MESSAGE_HANDLER(ViewMsg_DisableScrollbarsForSmallWindows,
OnDisableScrollbarsForSmallWindows)
IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
- IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt)
IPC_MESSAGE_HANDLER(ViewMsg_PluginActionAt, OnPluginActionAt)
- IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
IPC_MESSAGE_HANDLER(ViewMsg_ResolveTapDisambiguation,
OnResolveTapDisambiguation)
- IPC_MESSAGE_HANDLER(ViewMsg_ForceRedraw, OnForceRedraw)
IPC_MESSAGE_HANDLER(ViewMsg_SelectWordAroundCaret, OnSelectWordAroundCaret)
// Page messages.
IPC_MESSAGE_HANDLER(PageMsg_UpdateWindowScreenRect,
OnUpdateWindowScreenRect)
- IPC_MESSAGE_HANDLER(PageMsg_SetZoomLevel, OnSetZoomLevel)
IPC_MESSAGE_HANDLER(PageMsg_WasHidden, OnPageWasHidden)
IPC_MESSAGE_HANDLER(PageMsg_WasShown, OnPageWasShown)
IPC_MESSAGE_HANDLER(PageMsg_SetHistoryOffsetAndLength,
@@ -1083,7 +1112,7 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(PageMsg_PausePageScheduledTasks,
OnPausePageScheduledTasks)
IPC_MESSAGE_HANDLER(PageMsg_UpdateScreenInfo, OnUpdateScreenInfo)
- IPC_MESSAGE_HANDLER(PageMsg_FreezePage, OnFreezePage)
+ IPC_MESSAGE_HANDLER(PageMsg_SetPageFrozen, SetPageFrozen)
#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose)
@@ -1099,6 +1128,7 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) {
}
void RenderViewImpl::OnSelectWordAroundCaret() {
+ // TODO(ajwong): Move this into RenderWidget. http://crbug.com/545684
// Set default values for the ACK
bool did_select = false;
int start_adjust = 0;
@@ -1120,8 +1150,8 @@ void RenderViewImpl::OnSelectWordAroundCaret() {
input_handler_->set_handling_input_event(false);
}
}
- Send(new ViewHostMsg_SelectWordAroundCaretAck(GetRoutingID(), did_select,
- start_adjust, end_adjust));
+ Send(new ViewHostMsg_SelectWordAroundCaretAck(
+ GetWidget()->routing_id(), did_select, start_adjust, end_adjust));
}
void RenderViewImpl::OnUpdateTargetURLAck() {
@@ -1189,25 +1219,16 @@ void RenderViewImpl::SendFrameStateUpdates() {
frames_with_pending_state_.clear();
}
-void RenderViewImpl::ApplyWebPreferencesInternal(
- const WebPreferences& prefs,
- blink::WebView* web_view,
- CompositorDependencies* compositor_deps) {
+void RenderViewImpl::ApplyWebPreferencesInternal(const WebPreferences& prefs,
+ blink::WebView* web_view) {
ApplyWebPreferences(prefs, web_view);
}
-void RenderViewImpl::OnForceRedraw(const ui::LatencyInfo& latency_info) {
- if (RenderWidgetCompositor* rwc = compositor()) {
- rwc->QueueSwapPromise(
- std::make_unique<AlwaysDrawSwapPromise>(latency_info));
- rwc->SetNeedsForcedRedraw();
- }
-}
-
// blink::WebViewClient ------------------------------------------------------
-// TODO(csharrison): Migrate this method to WebFrameClient / RenderFrameImpl, as
-// it is now serviced by a mojo interface scoped to the opener frame.
+// TODO(csharrison): Migrate this method to WebLocalFrameClient /
+// RenderFrameImpl, as it is now serviced by a mojo interface scoped to the
+// opener frame.
WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
const WebURLRequest& request,
const WebWindowFeatures& features,
@@ -1217,10 +1238,16 @@ 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(creator);
+
+ // User Activation v2 moves user gesture checks to the browser process, with
+ // the exception of the extensions case handled through the following |if|.
+ params->mimic_user_gesture =
+ base::FeatureList::IsEnabled(features::kUserActivationV2)
+ ? false
+ : WebUserGestureIndicator::IsProcessingUserGesture(creator);
if (GetContentClient()->renderer()->AllowPopup())
- params->user_gesture = true;
+ params->mimic_user_gesture = true;
+
params->window_container_type = WindowFeaturesToContainerType(features);
params->session_storage_namespace_id = AllocateSessionStorageNamespaceId();
@@ -1247,7 +1274,7 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
// moved on send.
bool is_background_tab =
params->disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB;
- bool opened_by_user_gesture = params->user_gesture;
+ bool opened_by_user_gesture = params->mimic_user_gesture;
mojom::CreateNewWindowStatus status;
mojom::CreateNewWindowReplyPtr reply;
@@ -1273,7 +1300,10 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
DCHECK_NE(MSG_ROUTING_NONE, reply->main_frame_route_id);
DCHECK_NE(MSG_ROUTING_NONE, reply->main_frame_widget_route_id);
- WebUserGestureIndicator::ConsumeUserGesture(creator);
+ // The browser allowed creation of a new window and consumed the user
+ // activation (UAv2 only).
+ WebUserGestureIndicator::ConsumeUserGesture(
+ creator, blink::UserActivationUpdateSource::kBrowser);
// 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
@@ -1314,13 +1344,12 @@ WebView* RenderViewImpl::CreateView(WebLocalFrame* creator,
view_params->hidden = is_background_tab;
view_params->never_visible = never_visible;
view_params->visual_properties = visual_properties;
- view_params->page_zoom_level = page_zoom_level_;
// Unretained() is safe here because our calling function will also call
// show().
RenderWidget::ShowCallback show_callback =
- base::Bind(&RenderFrameImpl::ShowCreatedWindow,
- base::Unretained(creator_frame), opened_by_user_gesture);
+ base::BindOnce(&RenderFrameImpl::ShowCreatedWindow,
+ base::Unretained(creator_frame), opened_by_user_gesture);
RenderViewImpl* view = RenderViewImpl::Create(
compositor_deps_, std::move(view_params), std::move(show_callback),
@@ -1620,73 +1649,12 @@ void RenderViewImpl::DidHandleGestureEvent(const WebGestureEvent& event,
}
}
-blink::WebLayerTreeView* RenderViewImpl::InitializeLayerTreeView() {
- // TODO(!wjmaclean): We should be able to just remove this function, and
- // expect the RenderWidget version of the function to be called instead.
- // However, we have a diamond inheritance pattern going on:
- // WebWidgetClient
- // | |
- // RenderWidget WebViewClient
- // | |
- // RenderViewImpl
- //
- // and this seems to prefer calling the empty version in WebWidgetClient
- // or WebViewClient over the non-empty one in RenderWidget.
- return RenderWidget::InitializeLayerTreeView();
-}
-
-void RenderViewImpl::CloseWidgetSoon() {
- RenderWidget::CloseWidgetSoon();
-}
-
-void RenderViewImpl::ConvertViewportToWindow(blink::WebRect* rect) {
- RenderWidget::ConvertViewportToWindow(rect);
-}
-
-void RenderViewImpl::ConvertWindowToViewport(blink::WebFloatRect* rect) {
- RenderWidget::ConvertWindowToViewport(rect);
-}
-
-void RenderViewImpl::DidAutoResize(const blink::WebSize& newSize) {
- RenderWidget::DidAutoResize(newSize);
-}
-
-void RenderViewImpl::DidOverscroll(
- const blink::WebFloatSize& overscrollDelta,
- const blink::WebFloatSize& accumulatedOverscroll,
- const blink::WebFloatPoint& positionInViewport,
- const blink::WebFloatSize& velocityInViewport,
- const cc::OverscrollBehavior& behavior) {
- RenderWidget::DidOverscroll(overscrollDelta, accumulatedOverscroll,
- positionInViewport, velocityInViewport, behavior);
-}
-
-void RenderViewImpl::HasTouchEventHandlers(bool has_handlers) {
- RenderWidget::HasTouchEventHandlers(has_handlers);
-}
-
-blink::WebRect RenderViewImpl::RootWindowRect() {
- return RenderWidget::WindowRect();
-}
-
-blink::WebScreenInfo RenderViewImpl::GetScreenInfo() {
- return RenderWidget::GetScreenInfo();
-}
-
-void RenderViewImpl::SetToolTipText(const blink::WebString& text,
- blink::WebTextDirection hint) {
- RenderWidget::SetToolTipText(text, hint);
-}
-
-void RenderViewImpl::SetTouchAction(blink::WebTouchAction touchAction) {
- RenderWidget::SetTouchAction(touchAction);
-}
-
blink::WebWidgetClient* RenderViewImpl::WidgetClient() {
- return static_cast<RenderWidget*>(this);
+ return this;
}
-// blink::WebFrameClient -----------------------------------------------------
+// blink::WebLocalFrameClient
+// -----------------------------------------------------
void RenderViewImpl::SetEditCommandForNextKeyEvent(const std::string& name,
const std::string& value) {
@@ -1702,13 +1670,13 @@ const std::string& RenderViewImpl::GetAcceptLanguages() const {
}
void RenderViewImpl::ConvertViewportToWindowViaWidget(blink::WebRect* rect) {
- ConvertViewportToWindow(rect);
+ WidgetClient()->ConvertViewportToWindow(rect);
}
gfx::RectF RenderViewImpl::ElementBoundsInWindow(
const blink::WebElement& element) {
blink::WebRect bounding_box_in_window = element.BoundsInViewport();
- ConvertViewportToWindowViaWidget(&bounding_box_in_window);
+ WidgetClient()->ConvertViewportToWindow(&bounding_box_in_window);
return gfx::RectF(bounding_box_in_window);
}
@@ -1720,7 +1688,7 @@ void RenderViewImpl::CheckPreferredSize() {
return;
blink::WebSize tmp_size = webview()->ContentsPreferredMinimumSize();
blink::WebRect tmp_rect(0, 0, tmp_size.width, tmp_size.height);
- ConvertViewportToWindow(&tmp_rect);
+ WidgetClient()->ConvertViewportToWindow(&tmp_rect);
gfx::Size size(tmp_rect.width, tmp_rect.height);
if (size == preferred_size_)
return;
@@ -1749,7 +1717,7 @@ RenderFrameImpl* RenderViewImpl::GetMainRenderFrame() {
}
int RenderViewImpl::GetRoutingID() const {
- return routing_id();
+ return routing_id_;
}
gfx::Size RenderViewImpl::GetSize() const {
@@ -1796,31 +1764,14 @@ void RenderViewImpl::OnSetPageScale(float page_scale_factor) {
webview()->SetPageScaleFactor(page_scale_factor);
}
-void RenderViewImpl::OnSetZoomLevel(
- PageMsg_SetZoomLevel_Command command,
- double zoom_level) {
- switch (command) {
- case PageMsg_SetZoomLevel_Command::CLEAR_TEMPORARY:
- uses_temporary_zoom_level_ = false;
- break;
- case PageMsg_SetZoomLevel_Command::SET_TEMPORARY:
- uses_temporary_zoom_level_ = true;
- break;
- case PageMsg_SetZoomLevel_Command::USE_CURRENT_TEMPORARY_MODE:
- // Don't override a temporary zoom level without an explicit SET.
- if (uses_temporary_zoom_level_)
- return;
- break;
- default:
- NOTIMPLEMENTED();
- }
+void RenderViewImpl::UpdateZoomLevel(double zoom_level) {
webview()->HidePopups();
SetZoomLevel(zoom_level);
}
void RenderViewImpl::OnUpdateWebPreferences(const WebPreferences& prefs) {
webkit_preferences_ = prefs;
- ApplyWebPreferencesInternal(webkit_preferences_, webview(), compositor_deps_);
+ ApplyWebPreferencesInternal(webkit_preferences_, webview());
}
void RenderViewImpl::OnEnumerateDirectoryResponse(
@@ -1882,12 +1833,6 @@ void RenderViewImpl::OnSetRendererPrefs(
}
}
-void RenderViewImpl::OnMediaPlayerActionAt(const gfx::Point& location,
- const WebMediaPlayerAction& action) {
- if (webview())
- webview()->PerformMediaPlayerAction(action, location);
-}
-
void RenderViewImpl::OnPluginActionAt(const gfx::Point& location,
const WebPluginAction& action) {
if (webview())
@@ -1910,11 +1855,13 @@ void RenderViewImpl::OnClosePage() {
Send(new ViewHostMsg_ClosePage_ACK(GetRoutingID()));
}
+#if defined(OS_MACOSX)
void RenderViewImpl::OnClose() {
if (closing_)
RenderThread::Get()->Send(new ViewHostMsg_Close_ACK(GetRoutingID()));
RenderWidget::OnClose();
}
+#endif
void RenderViewImpl::OnMoveOrResizeStarted() {
if (webview())
@@ -1927,6 +1874,13 @@ void RenderViewImpl::ResizeWebWidget() {
browser_controls_shrink_blink_size_);
}
+void RenderViewImpl::RequestScheduleAnimation() {
+ // RenderWidget is a WebWidgetClient but layout tests want to override the
+ // client for WebViews, and can't do it by subclassing RenderWidget since they
+ // have a RenderViewImpl in this case, which is-a RenderWidget.
+ WidgetClient()->ScheduleAnimation();
+}
+
void RenderViewImpl::OnSynchronizeVisualProperties(
const VisualProperties& params) {
TRACE_EVENT0("renderer", "RenderViewImpl::OnSynchronizeVisualProperties");
@@ -1998,24 +1952,6 @@ void RenderViewImpl::OnSynchronizeVisualProperties(
}
}
-void RenderViewImpl::OnSetBackgroundOpaque(bool opaque) {
- if (!frame_widget_)
- return;
-
- if (opaque) {
- frame_widget_->ClearBaseBackgroundColorOverride();
- frame_widget_->ClearBackgroundColorOverride();
- } else {
- frame_widget_->SetBaseBackgroundColorOverride(SK_ColorTRANSPARENT);
- frame_widget_->SetBackgroundColorOverride(SK_ColorTRANSPARENT);
- }
-}
-
-void RenderViewImpl::OnSetActive(bool active) {
- if (webview())
- webview()->SetIsActive(active);
-}
-
blink::WebWidget* RenderViewImpl::GetWebWidget() const {
if (frame_widget_)
return frame_widget_;
@@ -2077,10 +2013,9 @@ void RenderViewImpl::OnUpdateScreenInfo(const ScreenInfo& screen_info) {
screen_info_ = screen_info;
}
-void RenderViewImpl::OnFreezePage() {
- if (webview()) {
- webview()->FreezePage();
- }
+void RenderViewImpl::SetPageFrozen(bool frozen) {
+ if (webview())
+ webview()->SetPageFrozen(frozen);
}
GURL RenderViewImpl::GetURLForGraphicsContext3D() {
@@ -2117,7 +2052,7 @@ void RenderViewImpl::DidCompletePageScaleAnimation() {
void RenderViewImpl::SetScreenMetricsEmulationParameters(
bool enabled,
const blink::WebDeviceEmulationParams& params) {
- if (webview() && compositor()) {
+ if (webview() && layer_tree_view()) {
if (enabled)
webview()->EnableDeviceEmulation(params);
else
@@ -2167,6 +2102,14 @@ void RenderViewImpl::PageImportanceSignalsChanged() {
main_render_frame_->GetRoutingID(), signals));
}
+void RenderViewImpl::DidAutoResize(const blink::WebSize& newSize) {
+ RenderWidget::DidAutoResize(newSize);
+}
+
+blink::WebRect RenderViewImpl::RootWindowRect() {
+ return WidgetClient()->WindowRect();
+}
+
#if defined(OS_ANDROID)
bool RenderViewImpl::OpenDateTimeChooser(
const blink::WebDateTimeChooserParams& params,
@@ -2246,7 +2189,7 @@ bool RenderViewImpl::DidTapMultipleTargets(
DCHECK(webview_->IsAcceleratedCompositingActive());
webview_->UpdateAllLifecyclePhases();
- webview_->PaintIgnoringCompositing(&canvas, zoom_rect);
+ webview_->PaintContentIgnoringCompositing(&canvas, zoom_rect);
}
gfx::Rect zoom_rect_in_screen =
@@ -2260,7 +2203,7 @@ bool RenderViewImpl::DidTapMultipleTargets(
// A SharedMemoryHandle is sent to the browser process, which is
// responsible for freeing the shared memory when no longer needed.
Send(new ViewHostMsg_ShowDisambiguationPopup(
- GetRoutingID(), physical_window_zoom_rect, canvas_size,
+ GetWidget()->routing_id(), physical_window_zoom_rect, canvas_size,
shm->TakeHandle()));
handled = true;
@@ -2304,13 +2247,13 @@ void RenderViewImpl::SetFocusAndActivateForTesting(bool enable) {
if (enable) {
if (has_focus())
return;
- OnSetActive(true);
+ SetActive(true);
OnSetFocus(true);
} else {
if (!has_focus())
return;
OnSetFocus(false);
- OnSetActive(false);
+ SetActive(false);
}
}
@@ -2331,8 +2274,8 @@ void RenderViewImpl::SetDeviceScaleFactorForTesting(float factor) {
visual_properties.local_surface_id = local_surface_id_from_parent_;
// We are changing the device scale factor from the renderer, so allocate a
// new viz::LocalSurfaceId to avoid surface invariants violations in tests.
- if (compositor_)
- compositor_->RequestNewLocalSurfaceId();
+ if (layer_tree_view())
+ layer_tree_view()->RequestNewLocalSurfaceId();
OnSynchronizeVisualProperties(visual_properties);
}
@@ -2353,8 +2296,8 @@ void RenderViewImpl::SetDeviceColorSpaceForTesting(
visual_properties.local_surface_id = local_surface_id_from_parent_;
// We are changing the device color space from the renderer, so allocate a
// new viz::LocalSurfaceId to avoid surface invariants violations in tests.
- if (compositor_)
- compositor_->RequestNewLocalSurfaceId();
+ if (layer_tree_view())
+ layer_tree_view()->RequestNewLocalSurfaceId();
OnSynchronizeVisualProperties(visual_properties);
}
diff --git a/chromium/content/renderer/render_view_impl.h b/chromium/content/renderer/render_view_impl.h
index 77f18279cdd..bcd629c4386 100644
--- a/chromium/content/renderer/render_view_impl.h
+++ b/chromium/content/renderer/render_view_impl.h
@@ -28,7 +28,6 @@
#include "content/common/content_export.h"
#include "content/common/frame_message_enums.h"
#include "content/common/navigation_gesture.h"
-#include "content/common/page_message_enums.h"
#include "content/common/view_message_enums.h"
#include "content/public/common/browser_controls_state.h"
#include "content/public/common/drop_data.h"
@@ -53,6 +52,7 @@
#include "third_party/blink/public/web/web_navigation_type.h"
#include "third_party/blink/public/web/web_node.h"
#include "third_party/blink/public/web/web_view_client.h"
+#include "third_party/blink/public/web/web_widget_client.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
@@ -62,20 +62,12 @@
#include "content/renderer/android/renderer_date_time_picker.h"
#endif
-#if defined(COMPILER_MSVC)
-// RenderViewImpl is a diamond-shaped hierarchy, with WebWidgetClient at the
-// root. VS warns when we inherit the WebWidgetClient method implementations
-// from RenderWidget. It's safe to ignore that warning.
-#pragma warning(disable: 4250)
-#endif
-
namespace blink {
class WebDateTimeChooserCompletion;
class WebGestureEvent;
class WebMouseEvent;
class WebURLRequest;
struct WebDateTimeChooserParams;
-struct WebMediaPlayerAction;
struct WebPluginAction;
struct WebWindowFeatures;
} // namespace blink
@@ -107,7 +99,7 @@ class CreateViewParams;
//
// For context, please see https://crbug.com/467770 and
// https://www.chromium.org/developers/design-documents/site-isolation.
-class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
+class CONTENT_EXPORT RenderViewImpl : private RenderWidget,
public blink::WebViewClient,
public RenderWidgetOwnerDelegate,
public RenderView {
@@ -122,7 +114,7 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
static RenderViewImpl* Create(
CompositorDependencies* compositor_deps,
mojom::CreateViewParamsPtr params,
- const RenderWidget::ShowCallback& show_callback,
+ RenderWidget::ShowCallback show_callback,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
// Used by content_layouttest_support to hook into the creation of
@@ -243,34 +235,6 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
bool OnMessageReceived(const IPC::Message& msg) override;
- // blink::WebWidgetClient implementation ------------------------------------
-
- // Most methods are handled by RenderWidget.
- void Show(blink::WebNavigationPolicy policy) override;
- void DidHandleGestureEvent(const blink::WebGestureEvent& event,
- bool event_cancelled) override;
- blink::WebLayerTreeView* InitializeLayerTreeView() override;
-
- bool CanHandleGestureEvent() override;
- bool CanUpdateLayout() override;
-
- // TODO(lfg): Remove once WebViewClient no longer inherits from
- // WebWidgetClient.
- void CloseWidgetSoon() override;
- void ConvertViewportToWindow(blink::WebRect* rect) override;
- void ConvertWindowToViewport(blink::WebFloatRect* rect) override;
- void DidOverscroll(const blink::WebFloatSize& overscrollDelta,
- const blink::WebFloatSize& accumulatedOverscroll,
- const blink::WebFloatPoint& positionInViewport,
- const blink::WebFloatSize& velocityInViewport,
- const cc::OverscrollBehavior& behavior) override;
- void HasTouchEventHandlers(bool has_handlers) override;
- blink::WebScreenInfo GetScreenInfo() override;
- void SetToolTipText(const blink::WebString&,
- blink::WebTextDirection hint) override;
- void SetTouchAction(cc::TouchAction touchAction) override;
- blink::WebWidgetClient* WidgetClient() override;
-
// blink::WebViewClient implementation --------------------------------------
blink::WebView* CreateView(blink::WebLocalFrame* creator,
@@ -298,6 +262,7 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
void FocusPrevious() override;
void FocusedNodeChanged(const blink::WebNode& fromNode,
const blink::WebNode& toNode) override;
+ bool CanUpdateLayout() override;
void DidUpdateLayout() override;
#if defined(OS_ANDROID)
// |touch_rect| is in physical pixels if --use-zoom-for-dsf is enabled.
@@ -319,6 +284,8 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
void DidAutoResize(const blink::WebSize& newSize) override;
blink::WebRect RootWindowRect() override;
void DidFocus(blink::WebLocalFrame* calling_frame) override;
+ bool CanHandleGestureEvent() override;
+ WebWidgetClient* WidgetClient() override;
#if defined(OS_ANDROID)
// Only used on Android since all other platforms implement
@@ -354,8 +321,6 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
void ConvertViewportToWindowViaWidget(blink::WebRect* rect) override;
gfx::RectF ElementBoundsInWindow(const blink::WebElement& element) override;
- bool uses_temporary_zoom_level() const { return uses_temporary_zoom_level_; }
-
// Please do not add your stuff randomly to the end here. If there is an
// appropriate section, add it there. If not, there are some random functions
// nearer to the top you can add it to.
@@ -371,6 +336,7 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
bool renderer_wide_named_frame_lookup() {
return renderer_wide_named_frame_lookup_;
}
+ void UpdateZoomLevel(double zoom_level);
protected:
// RenderWidget overrides:
@@ -383,13 +349,14 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
void DidCommitCompositorFrame() override;
void DidCompletePageScaleAnimation() override;
void ResizeWebWidget() override;
+ void RequestScheduleAnimation() override;
RenderViewImpl(CompositorDependencies* compositor_deps,
const mojom::CreateViewParams& params,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
void Initialize(mojom::CreateViewParamsPtr params,
- const RenderWidget::ShowCallback& show_callback,
+ RenderWidget::ShowCallback show_callback,
scoped_refptr<base::SingleThreadTaskRunner> task_runner);
void SetScreenMetricsEmulationParameters(
bool enabled,
@@ -460,7 +427,7 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
SetZoomLevelAfterCrossProcessNavigation);
FRIEND_TEST_ALL_PREFIXES(RenderViewImplScaleFactorTest,
ConverViewportToScreenWithZoomForDSF);
- FRIEND_TEST_ALL_PREFIXES(RenderViewImplScaleFactorTest,
+ FRIEND_TEST_ALL_PREFIXES(RenderViewImplEnableZoomForDSFTest,
GetCompositionCharacterBoundsTest);
enum ErrorPageType {
@@ -469,17 +436,24 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
CONNECTION_ERROR,
};
+ // RenderWidget public API that should no longer go through RenderView.
+ using RenderWidget::routing_id;
+
// RenderWidgetOwnerDelegate implementation ----------------------------------
bool RenderWidgetWillHandleMouseEvent(
const blink::WebMouseEvent& event) override;
+ void SetActive(bool active) override;
+ void SetBackgroundOpaque(bool opaque) override;
- // Old WebFrameClient implementations ----------------------------------------
+ // Old WebLocalFrameClient implementations
+ // ----------------------------------------
- // RenderViewImpl used to be a WebFrameClient, but now RenderFrameImpl is the
- // WebFrameClient. However, many implementations of WebFrameClient methods
- // still live here and are called from RenderFrameImpl. These implementations
- // are to be moved to RenderFrameImpl <http://crbug.com/361761>.
+ // RenderViewImpl used to be a WebLocalFrameClient, but now RenderFrameImpl is
+ // the WebLocalFrameClient. However, many implementations of
+ // WebLocalFrameClient methods still live here and are called from
+ // RenderFrameImpl. These implementations are to be moved to RenderFrameImpl
+ // <http://crbug.com/361761>.
static Referrer GetReferrerFromRequest(
blink::WebFrame* frame,
@@ -489,8 +463,13 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
blink::WebNavigationPolicy policy);
void ApplyWebPreferencesInternal(const WebPreferences& prefs,
- blink::WebView* web_view,
- CompositorDependencies* compositor_deps);
+ blink::WebView* web_view);
+
+ // blink::WebWidgetClient overrides from RenderWidget ------------------------
+
+ void Show(blink::WebNavigationPolicy policy) override;
+ void DidHandleGestureEvent(const blink::WebGestureEvent& event,
+ bool event_cancelled) override;
// IPC message handlers ------------------------------------------------------
//
@@ -500,7 +479,9 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
void OnAllowScriptToClose(bool script_can_close);
void OnCancelDownload(int32_t download_id);
void OnClosePage();
+#if defined(OS_MACOSX)
void OnClose();
+#endif
void OnDeterminePageLanguage();
void OnDisableScrollbarsForSmallWindows(
@@ -508,16 +489,12 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
void OnEnablePreferredSizeChangedMode();
void OnEnumerateDirectoryResponse(int id,
const std::vector<base::FilePath>& paths);
- void OnMediaPlayerActionAt(const gfx::Point& location,
- const blink::WebMediaPlayerAction& action);
void OnPluginActionAt(const gfx::Point& location,
const blink::WebPluginAction& action);
void OnMoveOrResizeStarted();
void OnResolveTapDisambiguation(base::TimeTicks timestamp,
const gfx::Point& tap_viewport_offset,
bool is_long_press);
- void OnSetActive(bool active);
- void OnSetBackgroundOpaque(bool opaque);
void OnExitFullscreen();
void OnSetHistoryOffsetAndLength(int history_offset, int history_length);
void OnSetInitialFocus(bool reverse);
@@ -527,18 +504,16 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
void OnUpdateTargetURLAck();
void OnUpdateWebPreferences(const WebPreferences& prefs);
void OnSetPageScale(float page_scale_factor);
- void OnForceRedraw(const ui::LatencyInfo& latency_info);
void OnSelectWordAroundCaret();
void OnAudioStateChanged(bool is_audio_playing);
void OnPausePageScheduledTasks(bool paused);
// Page message handlers -----------------------------------------------------
void OnUpdateWindowScreenRect(gfx::Rect window_screen_rect);
- void OnSetZoomLevel(PageMsg_SetZoomLevel_Command command, double zoom_level);
void OnPageWasHidden();
void OnPageWasShown();
void OnUpdateScreenInfo(const ScreenInfo& screen_info);
- void OnFreezePage();
+ void SetPageFrozen(bool frozen);
// Adding a new message handler? Please add it in alphabetical order above
// and put it in the same position in the .cc file.
@@ -594,6 +569,10 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
// it in the same order in the .cc file as it was in the header.
// ---------------------------------------------------------------------------
+ // Routing ID that allows us to communicate with the corresponding
+ // RenderViewHost in the parent browser process.
+ const int32_t routing_id_;
+
// Settings ------------------------------------------------------------------
WebPreferences webkit_preferences_;
@@ -680,9 +659,6 @@ class CONTENT_EXPORT RenderViewImpl : public RenderWidget,
// The next target URL we want to send to the browser.
GURL pending_target_url_;
- // Indicates whether this view overrides url-based zoom settings.
- bool uses_temporary_zoom_level_;
-
#if defined(OS_ANDROID)
// Cache the old browser controls state constraints. Used when updating
// current value only without altering the constraints.
diff --git a/chromium/content/renderer/render_view_impl_android.cc b/chromium/content/renderer/render_view_impl_android.cc
index 2d9f48df496..f6835cd2ef5 100644
--- a/chromium/content/renderer/render_view_impl_android.cc
+++ b/chromium/content/renderer/render_view_impl_android.cc
@@ -7,35 +7,35 @@
#include "base/command_line.h"
#include "cc/trees/layer_tree_host.h"
#include "content/common/view_messages.h"
-#include "content/renderer/gpu/render_widget_compositor.h"
+#include "content/renderer/gpu/layer_tree_view.h"
#include "third_party/blink/public/web/web_view.h"
namespace content {
-// Check content::BrowserControlsState, and
-// blink::WebWidget::BrowserControlsState
+// Check content::BrowserControlsState, and cc::BrowserControlsState
// are kept in sync.
static_assert(int(BROWSER_CONTROLS_STATE_SHOWN) ==
- int(blink::kWebBrowserControlsShown),
+ int(cc::BrowserControlsState::kShown),
"mismatching enums: SHOWN");
static_assert(int(BROWSER_CONTROLS_STATE_HIDDEN) ==
- int(blink::kWebBrowserControlsHidden),
+ int(cc::BrowserControlsState::kHidden),
"mismatching enums: HIDDEN");
static_assert(int(BROWSER_CONTROLS_STATE_BOTH) ==
- int(blink::kWebBrowserControlsBoth),
+ int(cc::BrowserControlsState::kBoth),
"mismatching enums: BOTH");
-blink::WebBrowserControlsState ContentToBlink(BrowserControlsState state) {
- return static_cast<blink::WebBrowserControlsState>(state);
+cc::BrowserControlsState ContentToCc(BrowserControlsState state) {
+ return static_cast<cc::BrowserControlsState>(state);
}
void RenderViewImpl::UpdateBrowserControlsState(
BrowserControlsState constraints,
BrowserControlsState current,
bool animate) {
- if (GetWebWidget())
- GetWebWidget()->UpdateBrowserControlsState(
- ContentToBlink(constraints), ContentToBlink(current), animate);
+ if (GetWebWidget()) {
+ GetWebWidget()->UpdateBrowserControlsState(ContentToCc(constraints),
+ ContentToCc(current), animate);
+ }
top_controls_constraints_ = constraints;
}
diff --git a/chromium/content/renderer/render_widget.cc b/chromium/content/renderer/render_widget.cc
index f0374259db0..560c7caaa74 100644
--- a/chromium/content/renderer/render_widget.cc
+++ b/chromium/content/renderer/render_widget.cc
@@ -4,10 +4,13 @@
#include "content/renderer/render_widget.h"
+#include <cmath>
+#include <limits>
#include <memory>
#include <utility>
#include "base/auto_reset.h"
+#include "base/base_switches.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/feature_list.h"
@@ -17,22 +20,29 @@
#include "base/memory/singleton.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/sys_info.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/animation/animation_host.h"
+#include "cc/base/switches.h"
#include "cc/input/touch_action.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_host.h"
+#include "cc/trees/ukm_manager.h"
+#include "components/viz/common/features.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/switches.h"
+#include "content/common/content_switches_internal.h"
#include "content/common/drag_event_source_info.h"
#include "content/common/drag_messages.h"
#include "content/common/render_frame_metadata.mojom.h"
#include "content/common/render_message_filter.mojom.h"
#include "content/common/swapped_out_messages.h"
+#include "content/common/tab_switching_time_callback.h"
#include "content/common/text_input_state.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_client.h"
@@ -49,13 +59,14 @@
#include "content/renderer/drop_data_builder.h"
#include "content/renderer/external_popup_menu.h"
#include "content/renderer/gpu/frame_swap_message_queue.h"
+#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/gpu/queue_message_swap_promise.h"
-#include "content/renderer/gpu/render_widget_compositor.h"
#include "content/renderer/ime_event_guard.h"
#include "content/renderer/input/main_thread_event_queue.h"
#include "content/renderer/input/widget_input_handler_manager.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/render_frame_impl.h"
+#include "content/renderer/render_frame_metadata_observer_impl.h"
#include "content/renderer/render_frame_proxy.h"
#include "content/renderer/render_process.h"
#include "content/renderer/render_thread_impl.h"
@@ -63,14 +74,16 @@
#include "content/renderer/render_widget_owner_delegate.h"
#include "content/renderer/renderer_blink_platform_impl.h"
#include "content/renderer/resizing_mode_selector.h"
+#include "gpu/command_buffer/service/gpu_switches.h"
#include "ipc/ipc_message_start.h"
#include "ipc/ipc_sync_message.h"
#include "ipc/ipc_sync_message_filter.h"
+#include "media/base/media_switches.h"
#include "ppapi/buildflags/buildflags.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
-#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
#include "third_party/blink/public/platform/scheduler/web_render_widget_scheduling_state.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_cursor_info.h"
#include "third_party/blink/public/platform/web_drag_data.h"
#include "third_party/blink/public/platform/web_drag_operation.h"
@@ -95,12 +108,16 @@
#include "third_party/skia/include/core/SkShader.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/ui_base_features.h"
+#include "ui/base/ui_base_switches.h"
#include "ui/events/base_event_utils.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/skia_util.h"
+#include "ui/gfx/switches.h"
#include "ui/gl/gl_switches.h"
+#include "ui/native_theme/native_theme_features.h"
+#include "ui/native_theme/overlay_scrollbar_constants_aura.h"
#include "ui/surface/transport_dib.h"
#if defined(OS_ANDROID)
@@ -129,7 +146,6 @@ using blink::WebDragOperationsMask;
using blink::WebDragData;
using blink::WebFrameWidget;
using blink::WebGestureEvent;
-using blink::WebImage;
using blink::WebInputEvent;
using blink::WebInputEventResult;
using blink::WebInputMethodController;
@@ -155,6 +171,13 @@ namespace content {
namespace {
+using RoutingIDWidgetMap = std::map<int32_t, RenderWidget*>;
+base::LazyInstance<RoutingIDWidgetMap>::Leaky g_routing_id_widget_map =
+ LAZY_INSTANCE_INITIALIZER;
+
+const base::Feature kUnpremultiplyAndDitherLowBitDepthTiles = {
+ "UnpremultiplyAndDitherLowBitDepthTiles", base::FEATURE_ENABLED_BY_DEFAULT};
+
typedef std::map<std::string, ui::TextInputMode> TextInputModeMap;
static const int kInvalidNextPreviousFlagsValue = -1;
@@ -412,6 +435,8 @@ RenderWidget::RenderWidget(
task_runner_(task_runner),
weak_ptr_factory_(this) {
DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
+ // TODO(nasko, alexmos): ref count the process based on the lifetime of
+ // RenderFrames rather than RenderWidgets.
if (!swapped_out)
RenderProcess::current()->AddRefProcess();
DCHECK(RenderThread::Get());
@@ -425,13 +450,21 @@ RenderWidget::RenderWidget(
}
#if defined(USE_AURA)
RendererWindowTreeClient::CreateIfNecessary(routing_id_);
- if (features::IsMashEnabled())
+ if (!features::IsAshInBrowserProcess())
RendererWindowTreeClient::Get(routing_id_)->SetVisible(!is_hidden_);
#endif
+
+ if (routing_id_ != MSG_ROUTING_NONE)
+ g_routing_id_widget_map.Get().emplace(routing_id_, this);
}
RenderWidget::~RenderWidget() {
DCHECK(!webwidget_internal_) << "Leaking our WebWidget!";
+ // TODO(ajwong): Add in check that routing_id_ has been removed from
+ // g_routing_id_widget_map once the shutdown semantics for RenderWidget
+ // and RenderViewImpl are rationalized. Currently, too many unit and
+ // browser tests delete a RenderWidget without correclty going through
+ // the shutdown. https://crbug.com/545684
if (input_event_queue_)
input_event_queue_->ClearClient();
@@ -457,6 +490,13 @@ void RenderWidget::InstallCreateHook(
}
// static
+RenderWidget* RenderWidget::FromRoutingID(int32_t routing_id) {
+ RoutingIDWidgetMap* widgets = g_routing_id_widget_map.Pointer();
+ RoutingIDWidgetMap::iterator it = widgets->find(routing_id);
+ return it == widgets->end() ? NULL : it->second;
+}
+
+// static
RenderWidget* RenderWidget::CreateForPopup(
RenderViewImpl* opener,
CompositorDependencies* compositor_deps,
@@ -478,8 +518,8 @@ RenderWidget* RenderWidget::CreateForPopup(
scoped_refptr<RenderWidget> widget(new RenderWidget(
routing_id, compositor_deps, popup_type, screen_info, false, false, false,
task_runner, std::move(widget_channel_request)));
- ShowCallback opener_callback =
- base::Bind(&RenderViewImpl::ShowCreatedPopupWidget, opener->GetWeakPtr());
+ ShowCallback opener_callback = base::BindOnce(
+ &RenderViewImpl::ShowCreatedPopupWidget, opener->GetWeakPtr());
widget->Init(std::move(opener_callback),
RenderWidget::CreateWebWidget(widget.get()));
DCHECK(!widget->HasOneRef()); // RenderWidget::Init() adds a reference.
@@ -494,13 +534,19 @@ RenderWidget* RenderWidget::CreateForFrame(
CompositorDependencies* compositor_deps,
blink::WebLocalFrame* frame) {
CHECK_NE(widget_routing_id, MSG_ROUTING_NONE);
- // TODO(avi): Before RenderViewImpl has-a RenderWidget, the browser passes the
- // same routing ID for both the view routing ID and the main frame widget
- // routing ID. https://crbug.com/545684
- RenderViewImpl* view = RenderViewImpl::FromRoutingID(widget_routing_id);
- if (view) {
+ RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame);
+ // For the mainframe, the RenderWidget is attached to the RenderView.
+ // TODO(ajwong): Remove this when the widget is always attached to a frame.
+ // https://crbug.com/545684
+ if (!frame->Parent()) {
+ RenderViewImpl* view =
+ static_cast<RenderViewImpl*>(render_frame->GetRenderView());
+ // Use the WidgetClient() from the RenderViewImpl, rather than getting its
+ // RenderWidget directly. Layout tests may inject a different
+ // WebWidgetClient on the RenderViewImpl that intercepts calls before they
+ // get to the RenderWidget.
view->AttachWebFrameWidget(
- RenderWidget::CreateWebFrameWidget(view->GetWidget(), frame));
+ RenderWidget::CreateWebFrameWidget(view->WidgetClient(), frame));
view->GetWidget()->UpdateWebViewWithDeviceScaleFactor();
return view->GetWidget();
}
@@ -517,7 +563,7 @@ RenderWidget* RenderWidget::CreateForFrame(
widget->for_oopif_ = true;
// Init increments the reference count on |widget|, keeping it alive after
// this function returns.
- widget->Init(RenderWidget::ShowCallback(),
+ widget->Init(base::NullCallback(),
RenderWidget::CreateWebFrameWidget(widget.get(), frame));
widget->UpdateWebViewWithDeviceScaleFactor();
@@ -528,9 +574,9 @@ RenderWidget* RenderWidget::CreateForFrame(
// static
blink::WebFrameWidget* RenderWidget::CreateWebFrameWidget(
- RenderWidget* render_widget,
+ blink::WebWidgetClient* widget_client,
blink::WebLocalFrame* frame) {
- return blink::WebFrameWidget::Create(render_widget, frame);
+ return blink::WebFrameWidget::Create(widget_client, frame);
}
// static
@@ -554,18 +600,9 @@ void RenderWidget::SetSwappedOut(bool is_swapped_out) {
// We should only toggle between states.
DCHECK(is_swapped_out_ != is_swapped_out);
is_swapped_out_ = is_swapped_out;
-
- // If we are swapping out, we will call ReleaseProcess, allowing the process
- // to exit if all of its RenderViews are swapped out. We wait until the
- // WasSwappedOut call to do this, to allow the unload handler to finish.
- // If we are swapping in, we call AddRefProcess to prevent the process from
- // exiting.
- if (!is_swapped_out_)
- RenderProcess::current()->AddRefProcess();
}
-void RenderWidget::Init(const ShowCallback& show_callback,
- WebWidget* web_widget) {
+void RenderWidget::Init(ShowCallback show_callback, WebWidget* web_widget) {
DCHECK(!webwidget_internal_);
DCHECK_NE(routing_id_, MSG_ROUTING_NONE);
@@ -573,15 +610,18 @@ void RenderWidget::Init(const ShowCallback& show_callback,
RenderThreadImpl* render_thread_impl = RenderThreadImpl::current();
+ blink::scheduler::WebThreadScheduler* compositor_thread_scheduler =
+ blink::scheduler::WebThreadScheduler::CompositorThreadScheduler();
+
widget_input_handler_manager_ = WidgetInputHandlerManager::Create(
weak_ptr_factory_.GetWeakPtr(),
- render_thread_impl && compositor_
- ? render_thread_impl->compositor_task_runner()
+ compositor_thread_scheduler && layer_tree_view_
+ ? compositor_thread_scheduler->InputTaskRunner()
: nullptr,
render_thread_impl ? render_thread_impl->GetWebMainThreadScheduler()
: nullptr);
- show_callback_ = show_callback;
+ show_callback_ = std::move(show_callback);
webwidget_internal_ = web_widget;
webwidget_mouse_lock_target_.reset(
@@ -599,13 +639,6 @@ void RenderWidget::Init(const ShowCallback& show_callback,
}
}
-void RenderWidget::WasSwappedOut() {
- // If we have been swapped out and no one else is using this process,
- // it's safe to exit now.
- CHECK(is_swapped_out_);
- RenderProcess::current()->ReleaseProcess();
-}
-
void RenderWidget::SetPopupOriginAdjustmentsForEmulation(
RenderWidgetScreenMetricsEmulator* emulator) {
popup_origin_scale_for_emulation_ = emulator->scale();
@@ -657,9 +690,12 @@ bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
OnDisableDeviceEmulation)
IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden)
IPC_MESSAGE_HANDLER(ViewMsg_WasShown, OnWasShown)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetBackgroundOpaque, OnSetBackgroundOpaque)
IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection)
- IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck)
+ IPC_MESSAGE_HANDLER(ViewMsg_SetBounds_ACK, OnRequestSetBoundsAck)
IPC_MESSAGE_HANDLER(ViewMsg_UpdateScreenRects, OnUpdateScreenRects)
+ IPC_MESSAGE_HANDLER(ViewMsg_ForceRedraw, OnForceRedraw)
IPC_MESSAGE_HANDLER(ViewMsg_SetViewportIntersection,
OnSetViewportIntersection)
IPC_MESSAGE_HANDLER(ViewMsg_SetIsInert, OnSetIsInert)
@@ -726,8 +762,8 @@ void RenderWidget::SetWindowRectSynchronously(
visual_properties.local_surface_id = local_surface_id_from_parent_;
// We are resizing the window from the renderer, so allocate a new
// viz::LocalSurfaceId to avoid surface invariants violations in tests.
- if (compositor_)
- compositor_->RequestNewLocalSurfaceId();
+ if (layer_tree_view_)
+ layer_tree_view_->RequestNewLocalSurfaceId();
SynchronizeVisualProperties(visual_properties);
view_screen_rect_ = new_window_rect;
@@ -746,6 +782,7 @@ void RenderWidget::OnClose() {
// Browser correspondence is no longer needed at this point.
if (routing_id_ != MSG_ROUTING_NONE) {
RenderThread::Get()->RemoveRoute(routing_id_);
+ g_routing_id_widget_map.Get().erase(routing_id_);
SetHidden(false);
if (RenderThreadImpl::current())
RenderThreadImpl::current()->WidgetDestroyed();
@@ -825,7 +862,7 @@ void RenderWidget::OnWasHidden() {
}
void RenderWidget::OnWasShown(bool needs_repainting,
- const ui::LatencyInfo& latency_info) {
+ base::TimeTicks show_request_timestamp) {
TRACE_EVENT0("renderer", "RenderWidget::OnWasShown");
// During shutdown we can just ignore this message.
if (!GetWebWidget())
@@ -840,20 +877,32 @@ void RenderWidget::OnWasShown(bool needs_repainting,
if (!needs_repainting)
return;
- if (compositor_) {
- ui::LatencyInfo swap_latency_info(latency_info);
- std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor =
- compositor_->CreateLatencyInfoSwapPromiseMonitor(&swap_latency_info);
- // Force this SwapPromiseMonitor to trigger and insert a SwapPromise.
- compositor_->SetNeedsBeginFrame();
+ if (layer_tree_view_ && !show_request_timestamp.is_null()) {
+ layer_tree_view_->layer_tree_host()->RequestPresentationTimeForNextFrame(
+ CreateTabSwitchingTimeRecorder(show_request_timestamp));
}
}
-void RenderWidget::OnRequestMoveAck() {
+void RenderWidget::OnRequestSetBoundsAck() {
DCHECK(pending_window_rect_count_);
pending_window_rect_count_--;
}
+void RenderWidget::OnForceRedraw(int snapshot_id) {
+ if (LayerTreeView* ltv = layer_tree_view()) {
+ ltv->layer_tree_host()->RequestPresentationTimeForNextFrame(
+ base::BindOnce(&RenderWidget::DidPresentForceDrawFrame,
+ weak_ptr_factory_.GetWeakPtr(), snapshot_id));
+ ltv->SetNeedsForcedRedraw();
+ }
+}
+
+void RenderWidget::DidPresentForceDrawFrame(
+ int snapshot_id,
+ const gfx::PresentationFeedback& feedback) {
+ Send(new ViewHostMsg_ForceRedrawComplete(routing_id(), snapshot_id));
+}
+
GURL RenderWidget::GetURLForGraphicsContext3D() {
return GURL();
}
@@ -889,6 +938,16 @@ void RenderWidget::OnSetEditCommandsForNextKeyEvent(
edit_commands_ = edit_commands;
}
+void RenderWidget::OnSetActive(bool active) {
+ if (owner_delegate_)
+ owner_delegate_->SetActive(active);
+}
+
+void RenderWidget::OnSetBackgroundOpaque(bool opaque) {
+ if (owner_delegate_)
+ owner_delegate_->SetBackgroundOpaque(opaque);
+}
+
void RenderWidget::OnSetFocus(bool enable) {
has_focus_ = enable;
@@ -900,14 +959,14 @@ void RenderWidget::OnSetFocus(bool enable) {
}
void RenderWidget::SetNeedsMainFrame() {
- RenderWidgetCompositor* rwc = compositor();
- if (!rwc)
+ LayerTreeView* ltv = layer_tree_view();
+ if (!ltv)
return;
- rwc->SetNeedsBeginFrame();
+ ltv->SetNeedsBeginFrame();
}
///////////////////////////////////////////////////////////////////////////////
-// RenderWidgetCompositorDelegate
+// LayerTreeViewDelegate
void RenderWidget::ApplyViewportDeltas(
const gfx::Vector2dF& inner_delta,
@@ -941,7 +1000,7 @@ void RenderWidget::BeginMainFrame(base::TimeTicks frame_time) {
}
void RenderWidget::RequestNewLayerTreeFrameSink(
- const LayerTreeFrameSinkCallback& callback) {
+ 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.
@@ -954,11 +1013,14 @@ void RenderWidget::RequestNewLayerTreeFrameSink(
mojom::RenderFrameMetadataObserverClientPtrInfo client_info;
mojom::RenderFrameMetadataObserverClientRequest client_request =
mojo::MakeRequest(&client_info);
- compositor_->CreateRenderFrameObserver(std::move(request),
- std::move(client_info));
+ auto render_frame_metadata_observer =
+ std::make_unique<RenderFrameMetadataObserverImpl>(std::move(request),
+ std::move(client_info));
+ layer_tree_view_->SetRenderFrameObserver(
+ std::move(render_frame_metadata_observer));
RenderThreadImpl::current()->RequestNewLayerTreeFrameSink(
routing_id_, frame_swap_message_queue_, GetURLForGraphicsContext3D(),
- callback, std::move(client_request), std::move(ptr));
+ std::move(callback), std::move(client_request), std::move(ptr));
}
void RenderWidget::DidCommitAndDrawCompositorFrame() {
@@ -982,7 +1044,22 @@ void RenderWidget::DidReceiveCompositorFrameAck() {
}
bool RenderWidget::IsClosing() const {
- return host_closing_;
+ // TODO(ajwong): There is oddly 2 closing states. This API is used by
+ // LayerTreeView only as part of the LayerTreeViewDelegate interface and
+ // is the guard against creating new compositor frames unnecessarily.
+ // Historically, when RenderViewImpl and RenderWidget shared the same
+ // routing id, it was possible for |closing_| to be true, |host_closing_| to
+ // false, and for the code in
+ // RenderThreadImpl::RequestNewLayerTreeFrameSink() to still look up a valid
+ // RenderViewImpl from the routing id. This is actually a benign shutdown
+ // race in Android that can be triggered in the SynchronouslyComposite path
+ // via AwContentsGarbageCollectionTest#testCreateAndGcManyTimes.
+ //
+ // Once RenderViewImpl and RenderWidget are split, attempt to combine two
+ // states so the shutdown logic is cleaner.
+ //
+ // http://crbug.com/545684
+ return host_closing_ || closing_;
}
void RenderWidget::RequestScheduleAnimation() {
@@ -1228,8 +1305,8 @@ bool RenderWidget::WillHandleMouseEvent(const blink::WebMouseEvent& event) {
// RenderWidgetScreenMetricsDelegate
void RenderWidget::Redraw() {
- if (compositor_)
- compositor_->SetNeedsRedrawRect(gfx::Rect(size_));
+ if (layer_tree_view_)
+ layer_tree_view_->SetNeedsRedrawRect(gfx::Rect(size_));
}
void RenderWidget::ResizeWebWidget() {
@@ -1237,7 +1314,7 @@ void RenderWidget::ResizeWebWidget() {
}
gfx::Size RenderWidget::GetSizeForWebWidget() const {
- if (IsUseZoomForDSFEnabled()) {
+ if (compositor_deps_->IsUseZoomForDSFEnabled()) {
return gfx::ScaleToCeiledSize(size_,
GetOriginalScreenInfo().device_scale_factor);
}
@@ -1245,6 +1322,27 @@ gfx::Size RenderWidget::GetSizeForWebWidget() const {
return size_;
}
+void RenderWidget::UpdateZoom(double zoom_level) {
+ blink::WebFrameWidget* frame_widget = GetFrameWidget();
+ if (!frame_widget)
+ return;
+ RenderFrameImpl* render_frame =
+ RenderFrameImpl::FromWebFrame(frame_widget->LocalRoot());
+
+ // Return early if zoom level is unchanged.
+ if (render_frame->GetZoomLevel() == zoom_level) {
+ return;
+ }
+
+ render_frame->SetZoomLevel(zoom_level);
+
+ for (auto& observer : render_frame_proxies_)
+ observer.OnZoomLevelChanged(zoom_level);
+
+ for (auto& plugin : browser_plugins_)
+ plugin.OnZoomLevelChanged(zoom_level);
+}
+
void RenderWidget::SynchronizeVisualProperties(const VisualProperties& params) {
// Inform the rendering thread of the color space indicate the presence of HDR
// capabilities.
@@ -1265,14 +1363,16 @@ void RenderWidget::SynchronizeVisualProperties(const VisualProperties& params) {
params.local_surface_id.value_or(viz::LocalSurfaceId()),
new_compositor_viewport_pixel_size, params.screen_info);
UpdateCaptureSequenceNumber(params.capture_sequence_number);
- if (compositor_) {
- compositor_->SetBrowserControlsHeight(
+ if (layer_tree_view_) {
+ layer_tree_view_->SetBrowserControlsHeight(
params.top_controls_height, params.bottom_controls_height,
params.browser_controls_shrink_blink_size);
- compositor_->SetRasterColorSpace(
+ layer_tree_view_->SetRasterColorSpace(
screen_info_.color_space.GetRasterColorSpace());
}
+ UpdateZoom(params.zoom_level);
+
if (params.auto_resize_enabled)
return;
@@ -1289,7 +1389,7 @@ void RenderWidget::SynchronizeVisualProperties(const VisualProperties& params) {
ResizeWebWidget();
WebSize visual_viewport_size;
- if (IsUseZoomForDSFEnabled()) {
+ if (compositor_deps_->IsUseZoomForDSFEnabled()) {
visual_viewport_size =
gfx::ScaleToCeiledSize(params.visible_viewport_size,
GetOriginalScreenInfo().device_scale_factor);
@@ -1321,32 +1421,32 @@ void RenderWidget::SetScreenRects(const gfx::Rect& view_screen_rect,
blink::WebLayerTreeView* RenderWidget::InitializeLayerTreeView() {
DCHECK(!host_closing_);
- compositor_ = RenderWidgetCompositor::Create(this, compositor_deps_);
- auto animation_host = cc::AnimationHost::CreateMainInstance();
-
- // Oopif status must be set before the LayerTreeHost is created.
- compositor_->SetIsForOopif(for_oopif_);
- auto layer_tree_host = RenderWidgetCompositor::CreateLayerTreeHost(
- compositor_.get(), compositor_.get(), animation_host.get(),
- compositor_deps_, screen_info_);
- compositor_->Initialize(std::move(layer_tree_host),
- std::move(animation_host));
+ layer_tree_view_ = std::make_unique<LayerTreeView>(
+ this, compositor_deps_->GetCompositorMainThreadTaskRunner(),
+ compositor_deps_->GetCompositorImplThreadTaskRunner(),
+ compositor_deps_->GetTaskGraphRunner(),
+ compositor_deps_->GetWebMainThreadScheduler());
+ layer_tree_view_->Initialize(
+ GenerateLayerTreeSettings(compositor_deps_, for_oopif_,
+ screen_info_.rect.size(),
+ screen_info_.device_scale_factor),
+ compositor_deps_->CreateUkmRecorderFactory());
UpdateSurfaceAndScreenInfo(local_surface_id_from_parent_,
compositor_viewport_pixel_size_, screen_info_);
- compositor_->SetRasterColorSpace(
+ layer_tree_view_->SetRasterColorSpace(
screen_info_.color_space.GetRasterColorSpace());
- compositor_->SetContentSourceId(current_content_source_id_);
+ layer_tree_view_->SetContentSourceId(current_content_source_id_);
// For background pages and certain tests, we don't want to trigger
// LayerTreeFrameSink creation.
bool should_generate_frame_sink =
!compositor_never_visible_ && RenderThreadImpl::current();
if (!should_generate_frame_sink)
- compositor_->SetNeverVisible();
+ layer_tree_view_->SetNeverVisible();
StartCompositor();
DCHECK_NE(MSG_ROUTING_NONE, routing_id_);
- compositor_->SetFrameSinkId(
+ layer_tree_view_->SetFrameSinkId(
viz::FrameSinkId(RenderThread::Get()->GetClientId(), routing_id_));
RenderThreadImpl* render_thread = RenderThreadImpl::current();
@@ -1358,7 +1458,7 @@ blink::WebLayerTreeView* RenderWidget::InitializeLayerTreeView() {
UpdateURLForCompositorUkm();
- return compositor_.get();
+ return layer_tree_view_.get();
}
void RenderWidget::IntrinsicSizingInfoChanged(
@@ -1411,7 +1511,7 @@ std::unique_ptr<cc::SwapPromise> RenderWidget::QueueMessageImpl(
void RenderWidget::QueueMessage(IPC::Message* msg,
MessageDeliveryPolicy policy) {
// RenderThreadImpl::current() is NULL in some tests.
- if (!compositor_ || !RenderThreadImpl::current()) {
+ if (!layer_tree_view_ || !RenderThreadImpl::current()) {
Send(msg);
return;
}
@@ -1419,10 +1519,10 @@ void RenderWidget::QueueMessage(IPC::Message* msg,
std::unique_ptr<cc::SwapPromise> swap_promise =
QueueMessageImpl(msg, policy, frame_swap_message_queue_.get(),
RenderThreadImpl::current()->sync_message_filter(),
- compositor_->GetSourceFrameNumber());
+ layer_tree_view_->GetSourceFrameNumber());
if (swap_promise)
- compositor_->QueueSwapPromise(std::move(swap_promise));
+ layer_tree_view_->QueueSwapPromise(std::move(swap_promise));
}
void RenderWidget::DidChangeCursor(const WebCursorInfo& cursor_info) {
@@ -1458,7 +1558,7 @@ void RenderWidget::AutoscrollEnd() {
void RenderWidget::Show(WebNavigationPolicy policy) {
DCHECK(!did_show_) << "received extraneous Show call";
DCHECK(routing_id_ != MSG_ROUTING_NONE);
- DCHECK(!show_callback_.is_null());
+ DCHECK(show_callback_);
if (did_show_)
return;
@@ -1466,8 +1566,7 @@ void RenderWidget::Show(WebNavigationPolicy policy) {
did_show_ = true;
// The opener is responsible for actually showing this widget.
- show_callback_.Run(this, policy, initial_rect_);
- show_callback_.Reset();
+ std::move(show_callback_).Run(this, policy, initial_rect_);
// NOTE: initial_rect_ may still have its default values at this point, but
// that's okay. It'll be ignored if as_popup is false, or the browser
@@ -1510,7 +1609,7 @@ void RenderWidget::CloseWidgetSoon() {
void RenderWidget::Close() {
screen_metrics_emulator_.reset();
CloseWebWidget();
- compositor_.reset();
+ layer_tree_view_.reset();
}
void RenderWidget::CloseWebWidget() {
@@ -1527,7 +1626,7 @@ void RenderWidget::UpdateWebViewWithDeviceScaleFactor() {
frame_widget ? frame_widget->LocalRoot() : nullptr;
blink::WebView* webview = current_frame ? current_frame->View() : nullptr;
if (webview) {
- if (IsUseZoomForDSFEnabled())
+ if (compositor_deps_->IsUseZoomForDSFEnabled())
webview->SetZoomFactorForDeviceScaleFactor(
GetWebScreenInfo().device_scale_factor);
else
@@ -1617,7 +1716,7 @@ void RenderWidget::SetWindowRect(const WebRect& rect_in_screen) {
if (!resizing_mode_selector_->is_synchronous_mode()) {
if (did_show_) {
- Send(new ViewHostMsg_RequestMove(routing_id_, window_rect));
+ Send(new ViewHostMsg_RequestSetBounds(routing_id_, window_rect));
SetPendingWindowRect(window_rect);
} else {
initial_rect_ = window_rect;
@@ -1754,11 +1853,11 @@ void RenderWidget::UpdateSurfaceAndScreenInfo(
compositor_viewport_pixel_size_ = new_compositor_viewport_pixel_size;
screen_info_ = new_screen_info;
- if (compositor_) {
- compositor_->SetViewportVisibleRect(ViewportVisibleRect());
+ if (layer_tree_view_) {
+ layer_tree_view_->SetViewportVisibleRect(ViewportVisibleRect());
// Note carefully that the DSF specified in |new_screen_info| is not the
// DSF used by the compositor during device emulation!
- compositor_->SetViewportSizeAndScale(
+ layer_tree_view_->SetViewportSizeAndScale(
compositor_viewport_pixel_size_,
GetOriginalScreenInfo().device_scale_factor,
local_surface_id_from_parent_);
@@ -1824,7 +1923,7 @@ void RenderWidget::OnSetViewportIntersection(
DCHECK_EQ(popup_type_, WebPopupType::kWebPopupTypeNone);
compositor_visible_rect_ = compositor_visible_rect;
frame_widget->SetRemoteViewportIntersection(viewport_intersection);
- compositor_->SetViewportVisibleRect(ViewportVisibleRect());
+ layer_tree_view_->SetViewportVisibleRect(ViewportVisibleRect());
}
}
@@ -1983,7 +2082,7 @@ void RenderWidget::UpdateCompositionInfo(bool immediate_request) {
}
void RenderWidget::ConvertViewportToWindow(blink::WebRect* rect) {
- if (IsUseZoomForDSFEnabled()) {
+ if (compositor_deps_->IsUseZoomForDSFEnabled()) {
float reverse = 1 / GetOriginalScreenInfo().device_scale_factor;
// TODO(oshima): We may need to allow pixel precision here as the the
// anchor element can be placed at half pixel.
@@ -1997,7 +2096,7 @@ void RenderWidget::ConvertViewportToWindow(blink::WebRect* rect) {
}
void RenderWidget::ConvertWindowToViewport(blink::WebFloatRect* rect) {
- if (IsUseZoomForDSFEnabled()) {
+ if (compositor_deps_->IsUseZoomForDSFEnabled()) {
rect->x *= GetOriginalScreenInfo().device_scale_factor;
rect->y *= GetOriginalScreenInfo().device_scale_factor;
rect->width *= GetOriginalScreenInfo().device_scale_factor;
@@ -2043,7 +2142,7 @@ void RenderWidget::SetHidden(bool hidden) {
is_hidden_ = hidden;
#if defined(USE_AURA)
- if (features::IsMashEnabled())
+ if (!features::IsAshInBrowserProcess())
RendererWindowTreeClient::Get(routing_id_)->SetVisible(!hidden);
#endif
@@ -2177,8 +2276,8 @@ void RenderWidget::DidAutoResize(const gfx::Size& new_size) {
// |size_| from |compositor_viewport_pixel_size_|. Also note that the
// calculation of |new_compositor_viewport_pixel_size| does not appear to
// take into account device emulation.
- if (compositor_)
- compositor_->RequestNewLocalSurfaceId();
+ if (layer_tree_view_)
+ layer_tree_view_->RequestNewLocalSurfaceId();
gfx::Size new_compositor_viewport_pixel_size =
gfx::ScaleToCeiledSize(size_, GetWebScreenInfo().device_scale_factor);
UpdateSurfaceAndScreenInfo(local_surface_id_from_parent_,
@@ -2334,13 +2433,434 @@ void RenderWidget::DidOverscroll(
position, velocity, behavior);
}
-void RenderWidget::StartCompositor() {
- if (!is_hidden())
- compositor_->SetVisible(true);
+// static
+cc::LayerTreeSettings RenderWidget::GenerateLayerTreeSettings(
+ CompositorDependencies* compositor_deps,
+ bool is_for_subframe,
+ const gfx::Size& initial_screen_size,
+ float initial_device_scale_factor) {
+ const bool is_threaded =
+ !!compositor_deps->GetCompositorImplThreadTaskRunner();
+
+ const base::CommandLine& cmd = *base::CommandLine::ForCurrentProcess();
+ cc::LayerTreeSettings settings;
+
+ settings.resource_settings.use_r16_texture =
+ base::FeatureList::IsEnabled(media::kUseR16Texture);
+
+ settings.commit_to_active_tree = !is_threaded;
+ settings.is_layer_tree_for_subframe = is_for_subframe;
+
+ // For web contents, layer transforms should scale up the contents of layers
+ // to keep content always crisp when possible.
+ settings.layer_transforms_should_scale_layer_contents = true;
+
+ settings.main_frame_before_activation_enabled =
+ cmd.HasSwitch(cc::switches::kEnableMainFrameBeforeActivation);
+
+ // Checkerimaging is not supported for synchronous single-threaded mode, which
+ // is what the renderer uses if its not threaded.
+ settings.enable_checker_imaging =
+ !cmd.HasSwitch(cc::switches::kDisableCheckerImaging) && is_threaded;
+
+#if defined(OS_ANDROID)
+ // We can use a more aggressive limit on Android since decodes tend to take
+ // longer on these devices.
+ settings.min_image_bytes_to_checker = 512 * 1024; // 512kB
+
+ // Re-rasterization of checker-imaged content with software raster can be too
+ // costly on Android.
+ settings.only_checker_images_with_gpu_raster = true;
+#endif
+
+ auto switch_value_as_int = [](const base::CommandLine& command_line,
+ const std::string& switch_string, int min_value,
+ int max_value, int* result) {
+ std::string string_value = command_line.GetSwitchValueASCII(switch_string);
+ int int_value;
+ if (base::StringToInt(string_value, &int_value) && int_value >= min_value &&
+ int_value <= max_value) {
+ *result = int_value;
+ return true;
+ } else {
+ LOG(WARNING) << "Failed to parse switch " << switch_string << ": "
+ << string_value;
+ return false;
+ }
+ };
+
+ int default_tile_size = 256;
+#if defined(OS_ANDROID)
+ const gfx::Size screen_size =
+ gfx::ScaleToFlooredSize(initial_screen_size, initial_device_scale_factor);
+ int display_width = screen_size.width();
+ int display_height = screen_size.height();
+ int numTiles = (display_width * display_height) / (256 * 256);
+ if (numTiles > 16)
+ default_tile_size = 384;
+ if (numTiles >= 40)
+ default_tile_size = 512;
+
+ // Adjust for some resolutions that barely straddle an extra
+ // tile when in portrait mode. This helps worst case scroll/raster
+ // by not needing a full extra tile for each row.
+ constexpr int tolerance = 10; // To avoid rounding errors.
+ int portrait_width = std::min(display_width, display_height);
+ if (default_tile_size == 256 && std::abs(portrait_width - 768) < tolerance)
+ default_tile_size += 32;
+ if (default_tile_size == 384 && std::abs(portrait_width - 1200) < tolerance)
+ default_tile_size += 32;
+#elif defined(OS_CHROMEOS) || defined(OS_MACOSX)
+ // Use 512 for high DPI (dsf=2.0f) devices.
+ if (initial_device_scale_factor >= 2.0f)
+ default_tile_size = 512;
+#endif
+
+ // TODO(danakj): This should not be a setting O_O; it should change when the
+ // device scale factor on LayerTreeHost changes.
+ settings.default_tile_size = gfx::Size(default_tile_size, default_tile_size);
+ if (cmd.HasSwitch(switches::kDefaultTileWidth)) {
+ int tile_width = 0;
+ switch_value_as_int(cmd, switches::kDefaultTileWidth, 1,
+ std::numeric_limits<int>::max(), &tile_width);
+ settings.default_tile_size.set_width(tile_width);
+ }
+ if (cmd.HasSwitch(switches::kDefaultTileHeight)) {
+ int tile_height = 0;
+ switch_value_as_int(cmd, switches::kDefaultTileHeight, 1,
+ std::numeric_limits<int>::max(), &tile_height);
+ settings.default_tile_size.set_height(tile_height);
+ }
+
+ int max_untiled_layer_width = settings.max_untiled_layer_size.width();
+ if (cmd.HasSwitch(switches::kMaxUntiledLayerWidth)) {
+ switch_value_as_int(cmd, switches::kMaxUntiledLayerWidth, 1,
+ std::numeric_limits<int>::max(),
+ &max_untiled_layer_width);
+ }
+ int max_untiled_layer_height = settings.max_untiled_layer_size.height();
+ if (cmd.HasSwitch(switches::kMaxUntiledLayerHeight)) {
+ switch_value_as_int(cmd, switches::kMaxUntiledLayerHeight, 1,
+ std::numeric_limits<int>::max(),
+ &max_untiled_layer_height);
+ }
+
+ settings.max_untiled_layer_size =
+ gfx::Size(max_untiled_layer_width, max_untiled_layer_height);
+
+ settings.gpu_rasterization_msaa_sample_count =
+ compositor_deps->GetGpuRasterizationMSAASampleCount();
+ settings.gpu_rasterization_forced =
+ compositor_deps->IsGpuRasterizationForced();
+
+ settings.can_use_lcd_text = compositor_deps->IsLcdTextEnabled();
+ settings.use_zero_copy = compositor_deps->IsZeroCopyEnabled();
+ settings.use_partial_raster = compositor_deps->IsPartialRasterEnabled();
+ settings.enable_elastic_overscroll =
+ compositor_deps->IsElasticOverscrollEnabled();
+ settings.resource_settings.use_gpu_memory_buffer_resources =
+ compositor_deps->IsGpuMemoryBufferCompositorResourcesEnabled();
+ settings.use_painted_device_scale_factor =
+ compositor_deps->IsUseZoomForDSFEnabled();
+
+ // Build LayerTreeSettings from command line args.
+ if (cmd.HasSwitch(cc::switches::kBrowserControlsShowThreshold)) {
+ std::string top_threshold_str =
+ cmd.GetSwitchValueASCII(cc::switches::kBrowserControlsShowThreshold);
+ double show_threshold;
+ if (base::StringToDouble(top_threshold_str, &show_threshold) &&
+ show_threshold >= 0.f && show_threshold <= 1.f)
+ settings.top_controls_show_threshold = show_threshold;
+ }
+
+ if (cmd.HasSwitch(cc::switches::kBrowserControlsHideThreshold)) {
+ std::string top_threshold_str =
+ cmd.GetSwitchValueASCII(cc::switches::kBrowserControlsHideThreshold);
+ double hide_threshold;
+ if (base::StringToDouble(top_threshold_str, &hide_threshold) &&
+ hide_threshold >= 0.f && hide_threshold <= 1.f)
+ settings.top_controls_hide_threshold = hide_threshold;
+ }
+
+ settings.use_layer_lists = cmd.HasSwitch(cc::switches::kEnableLayerLists);
+
+ // The means the renderer compositor has 2 possible modes:
+ // - Threaded compositing with a scheduler.
+ // - Single threaded compositing without a scheduler (for layout tests only).
+ // Using the scheduler in layout tests introduces additional composite steps
+ // that create flakiness.
+ settings.single_thread_proxy_scheduler = false;
+
+ // These flags should be mirrored by UI versions in ui/compositor/.
+ if (cmd.HasSwitch(cc::switches::kShowCompositedLayerBorders))
+ settings.initial_debug_state.show_debug_borders.set();
+ settings.initial_debug_state.show_layer_animation_bounds_rects =
+ cmd.HasSwitch(cc::switches::kShowLayerAnimationBounds);
+ settings.initial_debug_state.show_paint_rects =
+ cmd.HasSwitch(switches::kShowPaintRects);
+ settings.initial_debug_state.show_property_changed_rects =
+ cmd.HasSwitch(cc::switches::kShowPropertyChangedRects);
+ settings.initial_debug_state.show_surface_damage_rects =
+ cmd.HasSwitch(cc::switches::kShowSurfaceDamageRects);
+ settings.initial_debug_state.show_screen_space_rects =
+ cmd.HasSwitch(cc::switches::kShowScreenSpaceRects);
+
+ settings.initial_debug_state.SetRecordRenderingStats(
+ cmd.HasSwitch(cc::switches::kEnableGpuBenchmarking));
+ settings.enable_surface_synchronization =
+ features::IsSurfaceSynchronizationEnabled();
+ settings.build_hit_test_data = features::IsVizHitTestingSurfaceLayerEnabled();
+
+ if (cmd.HasSwitch(cc::switches::kSlowDownRasterScaleFactor)) {
+ const int kMinSlowDownScaleFactor = 0;
+ const int kMaxSlowDownScaleFactor = INT_MAX;
+ switch_value_as_int(
+ cmd, cc::switches::kSlowDownRasterScaleFactor, kMinSlowDownScaleFactor,
+ kMaxSlowDownScaleFactor,
+ &settings.initial_debug_state.slow_down_raster_scale_factor);
+ }
+
+ // This is default overlay scrollbar settings for Android and DevTools mobile
+ // emulator. Aura Overlay Scrollbar will override below.
+ settings.scrollbar_animator = cc::LayerTreeSettings::ANDROID_OVERLAY;
+ settings.solid_color_scrollbar_color = SkColorSetARGB(128, 128, 128, 128);
+ settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(300);
+ settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(300);
+
+#if defined(OS_ANDROID)
+ bool using_synchronous_compositor =
+ compositor_deps->UsingSynchronousCompositing();
+ bool using_low_memory_policy = base::SysInfo::IsLowEndDevice();
+
+ settings.use_stream_video_draw_quad = true;
+ settings.using_synchronous_renderer_compositor = using_synchronous_compositor;
+ if (using_synchronous_compositor) {
+ // Android WebView uses system scrollbars, so make ours invisible.
+ // http://crbug.com/677348: This can't be done using hide_scrollbars
+ // setting because supporting -webkit custom scrollbars is still desired
+ // on sublayers.
+ settings.scrollbar_animator = cc::LayerTreeSettings::NO_ANIMATOR;
+ settings.solid_color_scrollbar_color = SK_ColorTRANSPARENT;
+
+ settings.enable_early_damage_check =
+ cmd.HasSwitch(cc::switches::kCheckDamageEarly);
+ }
+ // Android WebView handles root layer flings itself.
+ settings.ignore_root_layer_flings = using_synchronous_compositor;
+ // Memory policy on Android WebView does not depend on whether device is
+ // low end, so always use default policy.
+ if (using_low_memory_policy && !using_synchronous_compositor) {
+ // On low-end we want to be very carefull about killing other
+ // apps. So initially we use 50% more memory to avoid flickering
+ // or raster-on-demand.
+ settings.max_memory_for_prepaint_percentage = 67;
+ } else {
+ // On other devices we have increased memory excessively to avoid
+ // raster-on-demand already, so now we reserve 50% _only_ to avoid
+ // raster-on-demand, and use 50% of the memory otherwise.
+ settings.max_memory_for_prepaint_percentage = 50;
+ }
+
+ // TODO(danakj): Only do this on low end devices.
+ settings.create_low_res_tiling = true;
+
+#else // defined(OS_ANDROID)
+ bool using_synchronous_compositor = false; // Only for Android WebView.
+ // On desktop, we never use the low memory policy unless we are simulating
+ // low-end mode via a switch.
+ bool using_low_memory_policy =
+ cmd.HasSwitch(switches::kEnableLowEndDeviceMode);
+
+ if (ui::IsOverlayScrollbarEnabled()) {
+ settings.scrollbar_animator = cc::LayerTreeSettings::AURA_OVERLAY;
+ settings.scrollbar_fade_delay = ui::kOverlayScrollbarFadeDelay;
+ settings.scrollbar_fade_duration = ui::kOverlayScrollbarFadeDuration;
+ settings.scrollbar_thinning_duration =
+ ui::kOverlayScrollbarThinningDuration;
+ settings.scrollbar_flash_after_any_scroll_update =
+ ui::OverlayScrollbarFlashAfterAnyScrollUpdate();
+ settings.scrollbar_flash_when_mouse_enter =
+ ui::OverlayScrollbarFlashWhenMouseEnter();
+ }
+
+ // On desktop, if there's over 4GB of memory on the machine, increase the
+ // working set size to 256MB for both gpu and software.
+ const int kImageDecodeMemoryThresholdMB = 4 * 1024;
+ if (base::SysInfo::AmountOfPhysicalMemoryMB() >=
+ kImageDecodeMemoryThresholdMB) {
+ settings.decoded_image_working_set_budget_bytes = 256 * 1024 * 1024;
+ } else {
+ // This is the default, but recorded here as well.
+ settings.decoded_image_working_set_budget_bytes = 128 * 1024 * 1024;
+ }
+#endif // defined(OS_ANDROID)
+
+ if (using_low_memory_policy) {
+ // RGBA_4444 textures are only enabled:
+ // - If the user hasn't explicitly disabled them
+ // - If system ram is <= 512MB (1GB devices are sometimes low-end).
+ // - If we are not running in a WebView, where 4444 isn't supported.
+ if (!cmd.HasSwitch(switches::kDisableRGBA4444Textures) &&
+ base::SysInfo::AmountOfPhysicalMemoryMB() <= 512 &&
+ !using_synchronous_compositor) {
+ settings.use_rgba_4444 = viz::RGBA_4444;
+
+ // If we are going to unpremultiply and dither these tiles, we need to
+ // allocate an additional RGBA_8888 intermediate for each tile
+ // rasterization when rastering to RGBA_4444 to allow for dithering.
+ // Setting a reasonable sized max tile size allows this intermediate to
+ // be consistently reused.
+ if (base::FeatureList::IsEnabled(
+ kUnpremultiplyAndDitherLowBitDepthTiles)) {
+ settings.max_gpu_raster_tile_size = gfx::Size(512, 256);
+ settings.unpremultiply_and_dither_low_bit_depth_tiles = true;
+ }
+ }
+ }
+
+ if (cmd.HasSwitch(switches::kEnableLowResTiling))
+ settings.create_low_res_tiling = true;
+ if (cmd.HasSwitch(switches::kDisableLowResTiling))
+ settings.create_low_res_tiling = false;
+
+ if (cmd.HasSwitch(switches::kEnableRGBA4444Textures) &&
+ !cmd.HasSwitch(switches::kDisableRGBA4444Textures)) {
+ settings.use_rgba_4444 = true;
+ }
+
+ settings.max_staging_buffer_usage_in_bytes = 32 * 1024 * 1024; // 32MB
+ // Use 1/4th of staging buffers on low-end devices.
+ if (base::SysInfo::IsLowEndDevice())
+ settings.max_staging_buffer_usage_in_bytes /= 4;
+
+ cc::ManagedMemoryPolicy defaults = settings.memory_policy;
+ settings.memory_policy = GetGpuMemoryPolicy(defaults, initial_screen_size,
+ initial_device_scale_factor);
+
+ settings.disallow_non_exact_resource_reuse =
+ cmd.HasSwitch(switches::kDisallowNonExactResourceReuse);
+#if defined(OS_ANDROID)
+ // TODO(crbug.com/746931): This feature appears to be causing visual
+ // corruption on certain android devices. Will investigate and re-enable.
+ settings.disallow_non_exact_resource_reuse = true;
+#endif
+
+ if (cmd.HasSwitch(switches::kRunAllCompositorStagesBeforeDraw)) {
+ settings.wait_for_all_pipeline_stages_before_draw = true;
+ settings.enable_latency_recovery = false;
+ }
+
+ settings.enable_image_animation_resync =
+ !cmd.HasSwitch(switches::kDisableImageAnimationResync);
+
+ settings.always_request_presentation_time =
+ cmd.HasSwitch(cc::switches::kAlwaysRequestPresentationTime);
+ return settings;
+}
+
+// static
+cc::ManagedMemoryPolicy RenderWidget::GetGpuMemoryPolicy(
+ const cc::ManagedMemoryPolicy& default_policy,
+ const gfx::Size& initial_screen_size,
+ float initial_device_scale_factor) {
+ cc::ManagedMemoryPolicy actual = default_policy;
+ actual.bytes_limit_when_visible = 0;
+
+ // If the value was overridden on the command line, use the specified value.
+ static bool client_hard_limit_bytes_overridden =
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kForceGpuMemAvailableMb);
+ if (client_hard_limit_bytes_overridden) {
+ if (base::StringToSizeT(
+ base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kForceGpuMemAvailableMb),
+ &actual.bytes_limit_when_visible))
+ actual.bytes_limit_when_visible *= 1024 * 1024;
+ return actual;
+ }
+
+#if defined(OS_ANDROID)
+ // We can't query available GPU memory from the system on Android.
+ // Physical memory is also mis-reported sometimes (eg. Nexus 10 reports
+ // 1262MB when it actually has 2GB, while Razr M has 1GB but only reports
+ // 128MB java heap size). First we estimate physical memory using both.
+ size_t dalvik_mb = base::SysInfo::DalvikHeapSizeMB();
+ size_t physical_mb = base::SysInfo::AmountOfPhysicalMemoryMB();
+ size_t physical_memory_mb = 0;
+ if (base::SysInfo::IsLowEndDevice()) {
+ // TODO(crbug.com/742534): The code below appears to no longer work.
+ // |dalvik_mb| no longer follows the expected heuristic pattern, causing us
+ // to over-estimate memory on low-end devices. This entire section probably
+ // needs to be re-written, but for now we can address the low-end Android
+ // issues by ignoring |dalvik_mb|.
+ physical_memory_mb = physical_mb;
+ } else if (dalvik_mb >= 256) {
+ physical_memory_mb = dalvik_mb * 4;
+ } else {
+ physical_memory_mb = std::max(dalvik_mb * 4, (physical_mb * 4) / 3);
+ }
+
+ // Now we take a default of 1/8th of memory on high-memory devices,
+ // and gradually scale that back for low-memory devices (to be nicer
+ // to other apps so they don't get killed). Examples:
+ // Nexus 4/10(2GB) 256MB (normally 128MB)
+ // Droid Razr M(1GB) 114MB (normally 57MB)
+ // Galaxy Nexus(1GB) 100MB (normally 50MB)
+ // Xoom(1GB) 100MB (normally 50MB)
+ // Nexus S(low-end) 8MB (normally 8MB)
+ // Note that the compositor now uses only some of this memory for
+ // pre-painting and uses the rest only for 'emergencies'.
+ if (actual.bytes_limit_when_visible == 0) {
+ // NOTE: Non-low-end devices use only 50% of these limits,
+ // except during 'emergencies' where 100% can be used.
+ if (physical_memory_mb >= 1536)
+ actual.bytes_limit_when_visible = physical_memory_mb / 8; // >192MB
+ else if (physical_memory_mb >= 1152)
+ actual.bytes_limit_when_visible = physical_memory_mb / 8; // >144MB
+ else if (physical_memory_mb >= 768)
+ actual.bytes_limit_when_visible = physical_memory_mb / 10; // >76MB
+ else if (physical_memory_mb >= 513)
+ actual.bytes_limit_when_visible = physical_memory_mb / 12; // <64MB
+ else
+ // Devices with this little RAM have very little headroom so we hardcode
+ // the limit rather than relying on the heuristics above. (They also use
+ // 4444 textures so we can use a lower limit.)
+ actual.bytes_limit_when_visible = 8;
+
+ actual.bytes_limit_when_visible =
+ actual.bytes_limit_when_visible * 1024 * 1024;
+ // Clamp the observed value to a specific range on Android.
+ actual.bytes_limit_when_visible = std::max(
+ actual.bytes_limit_when_visible, static_cast<size_t>(8 * 1024 * 1024));
+ actual.bytes_limit_when_visible =
+ std::min(actual.bytes_limit_when_visible,
+ static_cast<size_t>(256 * 1024 * 1024));
+ }
+ actual.priority_cutoff_when_visible =
+ gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING;
+#else
+ // Ignore what the system said and give all clients the same maximum
+ // allocation on desktop platforms.
+ actual.bytes_limit_when_visible = 512 * 1024 * 1024;
+ actual.priority_cutoff_when_visible =
+ gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
+
+ // For large monitors (4k), double the tile memory to avoid frequent out of
+ // memory problems. 4k could mean a screen width of anywhere from 3840 to 4096
+ // (see https://en.wikipedia.org/wiki/4K_resolution). We use 3500 as a proxy
+ // for "large enough".
+ static const int kLargeDisplayThreshold = 3500;
+ int display_width =
+ std::round(initial_screen_size.width() * initial_device_scale_factor);
+ if (display_width >= kLargeDisplayThreshold)
+ actual.bytes_limit_when_visible *= 2;
+#endif
+ return actual;
}
-RenderWidgetCompositor* RenderWidget::compositor() const {
- return compositor_.get();
+void RenderWidget::StartCompositor() {
+ if (!is_hidden())
+ layer_tree_view_->SetVisible(true);
}
void RenderWidget::SetHandlingInputEventForTesting(bool handling_input_event) {
@@ -2441,16 +2961,15 @@ bool RenderWidget::IsPointerLocked() {
void RenderWidget::StartDragging(blink::WebReferrerPolicy policy,
const WebDragData& data,
WebDragOperationsMask mask,
- const WebImage& image,
- const WebPoint& webImageOffset) {
- blink::WebRect offset_in_window(webImageOffset.x, webImageOffset.y, 0, 0);
+ const SkBitmap& drag_image,
+ const WebPoint& web_image_offset) {
+ blink::WebRect offset_in_window(web_image_offset.x, web_image_offset.y, 0, 0);
ConvertViewportToWindow(&offset_in_window);
DropData drop_data(DropDataBuilder::Build(data));
drop_data.referrer_policy = policy;
- gfx::Vector2d imageOffset(offset_in_window.x, offset_in_window.y);
- Send(new DragHostMsg_StartDragging(routing_id(), drop_data, mask,
- image.GetSkBitmap(), imageOffset,
- possible_drag_event_info_));
+ gfx::Vector2d image_offset(offset_in_window.x, offset_in_window.y);
+ Send(new DragHostMsg_StartDragging(routing_id(), drop_data, mask, drag_image,
+ image_offset, possible_drag_event_info_));
}
uint32_t RenderWidget::GetContentSourceId() {
@@ -2459,9 +2978,10 @@ uint32_t RenderWidget::GetContentSourceId() {
void RenderWidget::DidNavigate() {
++current_content_source_id_;
- if (!compositor_)
+ if (!layer_tree_view_)
return;
- compositor_->SetContentSourceId(current_content_source_id_);
+ layer_tree_view_->SetContentSourceId(current_content_source_id_);
+ layer_tree_view_->ClearCachesOnNextCommit();
}
blink::WebWidget* RenderWidget::GetWebWidget() const {
@@ -2498,11 +3018,12 @@ void RenderWidget::SetMouseCapture(bool capture) {
}
bool RenderWidget::IsSurfaceSynchronizationEnabled() const {
- return compositor_ && compositor_->IsSurfaceSynchronizationEnabled();
+ return layer_tree_view_ &&
+ layer_tree_view_->IsSurfaceSynchronizationEnabled();
}
void RenderWidget::UpdateURLForCompositorUkm() {
- DCHECK(compositor_);
+ DCHECK(layer_tree_view_);
blink::WebFrameWidget* frame_widget = GetFrameWidget();
if (!frame_widget)
return;
@@ -2511,7 +3032,8 @@ void RenderWidget::UpdateURLForCompositorUkm() {
if (!render_frame->IsMainFrame())
return;
- compositor_->SetURLForUkm(render_frame->GetWebFrame()->GetDocument().Url());
+ layer_tree_view_->SetURLForUkm(
+ render_frame->GetWebFrame()->GetDocument().Url());
}
blink::WebLocalFrame* RenderWidget::GetFocusedWebLocalFrameInWidget() const {
diff --git a/chromium/content/renderer/render_widget.h b/chromium/content/renderer/render_widget.h
index 480c020d340..ab52a4efb1c 100644
--- a/chromium/content/renderer/render_widget.h
+++ b/chromium/content/renderer/render_widget.h
@@ -26,6 +26,8 @@
#include "build/build_config.h"
#include "cc/input/overscroll_behavior.h"
#include "cc/input/touch_action.h"
+#include "cc/trees/layer_tree_settings.h"
+#include "cc/trees/managed_memory_policy.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "content/common/buildflags.h"
#include "content/common/content_export.h"
@@ -36,7 +38,7 @@
#include "content/public/common/drop_data.h"
#include "content/public/common/screen_info.h"
#include "content/renderer/devtools/render_widget_screen_metrics_emulator_delegate.h"
-#include "content/renderer/gpu/render_widget_compositor_delegate.h"
+#include "content/renderer/gpu/layer_tree_view_delegate.h"
#include "content/renderer/input/main_thread_event_queue.h"
#include "content/renderer/input/render_widget_input_handler.h"
#include "content/renderer/input/render_widget_input_handler_delegate.h"
@@ -81,7 +83,6 @@ struct WebDeviceEmulationParams;
class WebDragData;
class WebFrameWidget;
class WebGestureEvent;
-class WebImage;
class WebInputMethodController;
class WebLocalFrame;
class WebMouseEvent;
@@ -106,12 +107,12 @@ class CompositorDependencies;
class ExternalPopupMenu;
class FrameSwapMessageQueue;
class ImeEventGuard;
+class LayerTreeView;
class MainThreadEventQueue;
class PepperPluginInstanceImpl;
class RenderFrameImpl;
class RenderFrameProxy;
class RenderViewImpl;
-class RenderWidgetCompositor;
class RenderWidgetOwnerDelegate;
class RenderWidgetScreenMetricsEmulator;
class ResizingModeSelector;
@@ -131,14 +132,19 @@ struct VisualProperties;
class CONTENT_EXPORT RenderWidget
: public IPC::Listener,
public IPC::Sender,
- virtual public blink::WebWidgetClient,
+ public blink::WebWidgetClient,
public mojom::Widget,
- public RenderWidgetCompositorDelegate,
+ public LayerTreeViewDelegate,
public RenderWidgetInputHandlerDelegate,
public RenderWidgetScreenMetricsEmulatorDelegate,
public base::RefCounted<RenderWidget>,
public MainThreadEventQueueClient {
public:
+ using ShowCallback =
+ base::OnceCallback<void(RenderWidget* widget_to_show,
+ blink::WebNavigationPolicy policy,
+ const gfx::Rect& initial_rect)>;
+
// Creates a new RenderWidget for a popup. |opener| is the RenderView that
// this widget lives inside.
static RenderWidget* CreateForPopup(
@@ -165,13 +171,13 @@ class CONTENT_EXPORT RenderWidget
bool,
bool);
using RenderWidgetInitializedCallback = void (*)(RenderWidget*);
- using ShowCallback = base::Callback<void(RenderWidget* widget_to_show,
- blink::WebNavigationPolicy policy,
- const gfx::Rect& initial_rect)>;
static void InstallCreateHook(
CreateRenderWidgetFunction create_render_widget,
RenderWidgetInitializedCallback render_widget_initialized_callback);
+ // Returns the RenderWidget for the given routing ID.
+ static RenderWidget* FromRoutingID(int32_t routing_id);
+
// Closes a RenderWidget that was created by |CreateForFrame|.
// TODO(avi): De-virtualize this once RenderViewImpl has-a RenderWidget.
// https://crbug.com/545684
@@ -249,7 +255,7 @@ class CONTENT_EXPORT RenderWidget
// IPC::Sender
bool Send(IPC::Message* msg) override;
- // RenderWidgetCompositorDelegate
+ // LayerTreeViewDelegate
void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta,
const gfx::Vector2dF& outer_delta,
const gfx::Vector2dF& elastic_overscroll_delta,
@@ -259,7 +265,7 @@ class CONTENT_EXPORT RenderWidget
bool has_scrolled_by_touch) override;
void BeginMainFrame(base::TimeTicks frame_time) override;
void RequestNewLayerTreeFrameSink(
- const LayerTreeFrameSinkCallback& callback) override;
+ LayerTreeFrameSinkCallback callback) override;
void DidCommitAndDrawCompositorFrame() override;
void DidCommitCompositorFrame() override;
void DidCompletePageScaleAnimation() override;
@@ -331,20 +337,34 @@ class CONTENT_EXPORT RenderWidget
void StartDragging(blink::WebReferrerPolicy policy,
const blink::WebDragData& data,
blink::WebDragOperationsMask mask,
- const blink::WebImage& image,
- const blink::WebPoint& imageOffset) override;
+ const SkBitmap& drag_image,
+ const blink::WebPoint& image_offset) override;
// Override point to obtain that the current input method state and caret
// position.
virtual ui::TextInputType GetTextInputType();
+ // Internal helper that generates the LayerTreeSettings to be given to the
+ // compositor in StartCompositor().
+ static cc::LayerTreeSettings GenerateLayerTreeSettings(
+ CompositorDependencies* compositor_deps,
+ bool is_for_subframe,
+ const gfx::Size& initial_screen_size,
+ float initial_device_scale_factor);
+ // Internal helper that generates the ManagedMemoryPolicy to be given to the
+ // compositor in StartCompositor().
+ static cc::ManagedMemoryPolicy GetGpuMemoryPolicy(
+ const cc::ManagedMemoryPolicy& policy,
+ const gfx::Size& initial_screen_size,
+ float initial_device_scale_factor);
+
// Begins the compositor's scheduler to start producing frames.
void StartCompositor();
// Stop compositing.
void WillCloseLayerTreeView();
- RenderWidgetCompositor* compositor() const;
+ LayerTreeView* layer_tree_view() const { return layer_tree_view_.get(); }
WidgetInputHandlerManager* widget_input_handler_manager() {
return widget_input_handler_manager_.get();
@@ -396,6 +416,9 @@ class CONTENT_EXPORT RenderWidget
// Called when the Widget has changed size as a result of an auto-resize.
void DidAutoResize(const gfx::Size& new_size);
+ void DidPresentForceDrawFrame(int snapshot_id,
+ const gfx::PresentationFeedback& feedback);
+
// Indicates whether this widget has focus.
bool has_focus() const { return has_focus_; }
@@ -447,7 +470,9 @@ class CONTENT_EXPORT RenderWidget
scoped_refptr<MainThreadEventQueue> GetInputEventQueue();
+ void OnSetActive(bool active);
virtual void OnSetFocus(bool enable);
+ void OnSetBackgroundOpaque(bool opaque);
void OnMouseCaptureLost();
void OnCursorVisibilityChange(bool is_visible);
void OnSetEditCommandsForNextKeyEvent(const EditCommands& edit_commands);
@@ -515,7 +540,7 @@ class CONTENT_EXPORT RenderWidget
~RenderWidget() override;
static blink::WebFrameWidget* CreateWebFrameWidget(
- RenderWidget* render_widget,
+ blink::WebWidgetClient* widget_client,
blink::WebLocalFrame* frame);
// Creates a WebWidget based on the popup type.
@@ -524,11 +549,7 @@ class CONTENT_EXPORT RenderWidget
// Called by Create() functions and subclasses to finish initialization.
// |show_callback| will be invoked once WebWidgetClient::show() occurs, and
// should be null if show() won't be triggered for this widget.
- void Init(const ShowCallback& show_callback, blink::WebWidget* web_widget);
-
- // Allows the process to exit once the unload handler has finished, if there
- // are no other active RenderWidgets.
- void WasSwappedOut();
+ void Init(ShowCallback show_callback, blink::WebWidget* web_widget);
void DoDeferredClose();
void NotifyOnClose();
@@ -568,10 +589,11 @@ class CONTENT_EXPORT RenderWidget
void OnDisableDeviceEmulation();
virtual void OnWasHidden();
virtual void OnWasShown(bool needs_repainting,
- const ui::LatencyInfo& latency_info);
+ base::TimeTicks show_request_timestamp);
void OnCreateVideoAck(int32_t video_id);
void OnUpdateVideoAck(int32_t video_id);
- void OnRequestMoveAck();
+ void OnRequestSetBoundsAck();
+ void OnForceRedraw(int snapshot_id);
// Request from browser to show context menu.
virtual void OnShowContextMenu(ui::MenuSourceType source_type,
const gfx::Point& location);
@@ -701,7 +723,7 @@ class CONTENT_EXPORT RenderWidget
RenderWidgetOwnerDelegate* owner_delegate_;
// This is lazily constructed and must not outlive webwidget_.
- std::unique_ptr<RenderWidgetCompositor> compositor_;
+ std::unique_ptr<LayerTreeView> layer_tree_view_;
// The rect where this view should be initially shown.
gfx::Rect initial_rect_;
@@ -906,6 +928,8 @@ class CONTENT_EXPORT RenderWidget
std::unique_ptr<ui::DidOverscrollParams>,
base::Optional<cc::TouchAction>);
+ void UpdateZoom(double zoom_level);
+
#if BUILDFLAG(ENABLE_PLUGINS)
// Returns the focused pepper plugin, if any, inside the WebWidget. That is
// the pepper plugin which is focused inside a frame which belongs to the
@@ -931,7 +955,7 @@ class CONTENT_EXPORT RenderWidget
bool for_oopif_;
// A callback into the creator/opener of this widget, to be executed when
- // WebWidgetClient::show() occurs.
+ // WebWidgetClient::Show() occurs.
ShowCallback show_callback_;
#if defined(OS_MACOSX)
diff --git a/chromium/content/renderer/render_widget_fullscreen_pepper.cc b/chromium/content/renderer/render_widget_fullscreen_pepper.cc
index 1e908be6d0f..28bf42737ca 100644
--- a/chromium/content/renderer/render_widget_fullscreen_pepper.cc
+++ b/chromium/content/renderer/render_widget_fullscreen_pepper.cc
@@ -10,15 +10,15 @@
#include "base/command_line.h"
#include "base/macros.h"
#include "build/build_config.h"
+#include "cc/paint/paint_canvas.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/use_zoom_for_dsf_policy.h"
-#include "content/renderer/gpu/render_widget_compositor.h"
+#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "gpu/ipc/client/gpu_channel_host.h"
#include "skia/ext/platform_canvas.h"
-#include "third_party/blink/public/platform/web_canvas.h"
#include "third_party/blink/public/platform/web_cursor_info.h"
#include "third_party/blink/public/platform/web_gesture_event.h"
#include "third_party/blink/public/platform/web_mouse_wheel_event.h"
@@ -28,7 +28,6 @@
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gl/gpu_preference.h"
-using blink::WebCanvas;
using blink::WebCoalescedInputEvent;
using blink::WebImeTextSpan;
using blink::WebCursorInfo;
@@ -254,19 +253,19 @@ class PepperWidget : public WebWidget {
// static
RenderWidgetFullscreenPepper* RenderWidgetFullscreenPepper::Create(
int32_t routing_id,
- const RenderWidget::ShowCallback& show_callback,
+ RenderWidget::ShowCallback show_callback,
CompositorDependencies* compositor_deps,
PepperPluginInstanceImpl* plugin,
const GURL& active_url,
const ScreenInfo& screen_info,
mojom::WidgetRequest widget_request) {
DCHECK_NE(MSG_ROUTING_NONE, routing_id);
- DCHECK(!show_callback.is_null());
+ DCHECK(show_callback);
scoped_refptr<RenderWidgetFullscreenPepper> widget(
new RenderWidgetFullscreenPepper(routing_id, compositor_deps, plugin,
active_url, screen_info,
std::move(widget_request)));
- widget->Init(show_callback, new PepperWidget(widget.get()));
+ widget->Init(std::move(show_callback), new PepperWidget(widget.get()));
widget->AddRef();
return widget.get();
}
@@ -335,15 +334,15 @@ void RenderWidgetFullscreenPepper::PepperDidChangeCursor(
void RenderWidgetFullscreenPepper::SetLayer(cc::Layer* layer) {
layer_ = layer;
if (!layer_) {
- if (compositor_)
- compositor_->ClearRootLayer();
+ if (layer_tree_view())
+ layer_tree_view()->ClearRootLayer();
return;
}
- if (!compositor())
+ if (!layer_tree_view())
InitializeLayerTreeView();
UpdateLayerBounds();
layer_->SetIsDrawable(true);
- compositor_->SetRootLayer(layer_);
+ layer_tree_view()->SetRootLayer(layer_);
}
bool RenderWidgetFullscreenPepper::OnMessageReceived(const IPC::Message& msg) {
@@ -392,7 +391,7 @@ void RenderWidgetFullscreenPepper::UpdateLayerBounds() {
if (!layer_)
return;
- if (IsUseZoomForDSFEnabled()) {
+ if (compositor_deps()->IsUseZoomForDSFEnabled()) {
// Note that root cc::Layers' bounds are specified in pixels (in contrast
// with non-root cc::Layers' bounds, which are specified in DIPs).
layer_->SetBounds(blink::WebSize(compositor_viewport_pixel_size()));
diff --git a/chromium/content/renderer/render_widget_fullscreen_pepper.h b/chromium/content/renderer/render_widget_fullscreen_pepper.h
index 0faccb2ee7c..548bc9913a6 100644
--- a/chromium/content/renderer/render_widget_fullscreen_pepper.h
+++ b/chromium/content/renderer/render_widget_fullscreen_pepper.h
@@ -32,7 +32,7 @@ class RenderWidgetFullscreenPepper : public RenderWidget,
public:
static RenderWidgetFullscreenPepper* Create(
int32_t routing_id,
- const RenderWidget::ShowCallback& show_callback,
+ RenderWidget::ShowCallback show_callback,
CompositorDependencies* compositor_deps,
PepperPluginInstanceImpl* plugin,
const GURL& active_url,
diff --git a/chromium/content/renderer/render_widget_owner_delegate.h b/chromium/content/renderer/render_widget_owner_delegate.h
index 22f573c9a7f..8438e9ac6a2 100644
--- a/chromium/content/renderer/render_widget_owner_delegate.h
+++ b/chromium/content/renderer/render_widget_owner_delegate.h
@@ -25,6 +25,12 @@ class CONTENT_EXPORT RenderWidgetOwnerDelegate {
virtual bool RenderWidgetWillHandleMouseEvent(
const blink::WebMouseEvent& event) = 0;
+ // See comment in RenderWidgetHost::SetActive().
+ virtual void SetActive(bool active) = 0;
+
+ // See comment in RenderWidgetHostImpl::SetBackgroundOpaque().
+ virtual void SetBackgroundOpaque(bool opaque) = 0;
+
protected:
virtual ~RenderWidgetOwnerDelegate() {}
};
diff --git a/chromium/content/renderer/render_widget_unittest.cc b/chromium/content/renderer/render_widget_unittest.cc
index 8a4a85433a9..91392d4c552 100644
--- a/chromium/content/renderer/render_widget_unittest.cc
+++ b/chromium/content/renderer/render_widget_unittest.cc
@@ -10,8 +10,10 @@
#include "base/macros.h"
#include "base/optional.h"
#include "base/run_loop.h"
-#include "base/test/histogram_tester.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_task_environment.h"
+#include "build/build_config.h"
+#include "cc/trees/layer_tree_host.h"
#include "components/viz/common/features.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "content/common/input/input_handler.mojom.h"
@@ -22,7 +24,7 @@
#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/gpu/render_widget_compositor.h"
+#include "content/renderer/gpu/layer_tree_view.h"
#include "content/renderer/input/widget_input_handler_manager.h"
#include "content/test/fake_compositor_dependencies.h"
#include "content/test/mock_render_process.h"
@@ -281,25 +283,6 @@ TEST_F(RenderWidgetUnittest, EventOverscroll) {
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), cc::OverscrollBehavior());
- base::RunLoop().RunUntilIdle();
-}
-
TEST_F(RenderWidgetUnittest, RenderWidgetInputEventUmaMetrics) {
SyntheticWebTouchEvent touch;
touch.PressPoint(10, 10);
@@ -385,13 +368,19 @@ TEST_F(RenderWidgetUnittest, AutoResizeAllocatedLocalSurfaceId) {
widget()->SynchronizeVisualProperties(visual_properties);
EXPECT_EQ(allocator.GetCurrentLocalSurfaceId(),
widget()->local_surface_id_from_parent());
- EXPECT_FALSE(widget()->compositor()->HasNewLocalSurfaceIdRequest());
+ EXPECT_FALSE(widget()
+ ->layer_tree_view()
+ ->layer_tree_host()
+ ->new_local_surface_id_request_for_testing());
constexpr gfx::Size size(200, 200);
widget()->DidAutoResize(size);
EXPECT_EQ(allocator.GetCurrentLocalSurfaceId(),
widget()->local_surface_id_from_parent());
- EXPECT_TRUE(widget()->compositor()->HasNewLocalSurfaceIdRequest());
+ EXPECT_TRUE(widget()
+ ->layer_tree_view()
+ ->layer_tree_host()
+ ->new_local_surface_id_request_for_testing());
}
class PopupRenderWidget : public RenderWidget {
@@ -520,4 +509,29 @@ TEST_F(RenderWidgetPopupUnittest, EmulatingPopupRect) {
EXPECT_EQ(popup_emulated_rect.y, widget()->ViewRect().y);
}
+// Verify desktop memory limit calculations.
+#if !defined(OS_ANDROID)
+TEST(RenderWidgetTest, IgnoreGivenMemoryPolicy) {
+ auto policy = RenderWidget::GetGpuMemoryPolicy(cc::ManagedMemoryPolicy(256),
+ gfx::Size(), 1.f);
+ EXPECT_EQ(512u * 1024u * 1024u, policy.bytes_limit_when_visible);
+ EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
+ policy.priority_cutoff_when_visible);
+}
+
+TEST(RenderWidgetTest, LargeScreensUseMoreMemory) {
+ auto policy = RenderWidget::GetGpuMemoryPolicy(cc::ManagedMemoryPolicy(256),
+ gfx::Size(4096, 2160), 1.f);
+ EXPECT_EQ(2u * 512u * 1024u * 1024u, policy.bytes_limit_when_visible);
+ EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
+ policy.priority_cutoff_when_visible);
+
+ policy = RenderWidget::GetGpuMemoryPolicy(cc::ManagedMemoryPolicy(256),
+ gfx::Size(2048, 1080), 2.f);
+ EXPECT_EQ(2u * 512u * 1024u * 1024u, policy.bytes_limit_when_visible);
+ EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE,
+ policy.priority_cutoff_when_visible);
+}
+#endif // !defined(OS_ANDROID)
+
} // namespace content
diff --git a/chromium/content/renderer/renderer_blink_platform_impl.cc b/chromium/content/renderer/renderer_blink_platform_impl.cc
index 4205c92765a..a9b86c68fe5 100644
--- a/chromium/content/renderer/renderer_blink_platform_impl.cc
+++ b/chromium/content/renderer/renderer_blink_platform_impl.cc
@@ -37,28 +37,26 @@
#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"
#include "content/public/common/webplugininfo.h"
#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/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_bundle.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/audio_device_factory.h"
#include "content/renderer/media/audio_decoder.h"
-#include "content/renderer/media/audio_device_factory.h"
#include "content/renderer/media/midi/renderer_webmidiaccessor_impl.h"
#include "content/renderer/media/renderer_webaudiodevice_impl.h"
#include "content/renderer/media_capture_from_element/canvas_capture_handler.h"
@@ -71,7 +69,6 @@
#include "content/renderer/storage_util.h"
#include "content/renderer/web_database_observer_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"
@@ -86,8 +83,8 @@
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "ppapi/buildflags/buildflags.h"
-#include "services/device/public/cpp/generic_sensor/motion_data.h"
#include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
@@ -96,19 +93,15 @@
#include "third_party/blink/public/common/origin_trials/trial_token_validator.h"
#include "third_party/blink/public/platform/blame_context.h"
#include "third_party/blink/public/platform/file_path_conversion.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_motion_listener.h"
-#include "third_party/blink/public/platform/modules/device_orientation/web_device_orientation_listener.h"
#include "third_party/blink/public/platform/modules/webmidi/web_midi_accessor.h"
#include "third_party/blink/public/platform/scheduler/child/webthread_base.h"
-#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_audio_latency_hint.h"
#include "third_party/blink/public/platform/web_blob_registry.h"
#include "third_party/blink/public/platform/web_file_info.h"
#include "third_party/blink/public/platform/web_media_recorder_handler.h"
#include "third_party/blink/public/platform/web_media_stream_center.h"
-#include "third_party/blink/public/platform/web_media_stream_center_client.h"
-#include "third_party/blink/public/platform/web_plugin_list_builder.h"
#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
#include "third_party/blink/public/platform/web_security_origin.h"
@@ -125,7 +118,6 @@
#if defined(OS_MACOSX)
#include "content/child/child_process_sandbox_support_impl_mac.h"
#include "content/common/mac/font_loader.h"
-#include "content/renderer/webscrollbarbehavior_impl_mac.h"
#include "third_party/blink/public/platform/mac/web_sandbox_support.h"
#endif
@@ -143,13 +135,6 @@
#endif
#endif
-#if defined(USE_AURA)
-#include "content/renderer/webscrollbarbehavior_impl_aura.h"
-#elif !defined(OS_MACOSX)
-#include "third_party/blink/public/platform/web_scrollbar_behavior.h"
-#define WebScrollbarBehaviorImpl blink::WebScrollbarBehavior
-#endif
-
#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
#include "content/renderer/media/webrtc/rtc_certificate_generator.h"
#include "content/renderer/media/webrtc/webrtc_uma_histograms.h"
@@ -168,7 +153,6 @@ using blink::WebMediaPlayer;
using blink::WebMediaRecorderHandler;
using blink::WebMediaStream;
using blink::WebMediaStreamCenter;
-using blink::WebMediaStreamCenterClient;
using blink::WebMediaStreamTrack;
using blink::WebRTCPeerConnectionHandler;
using blink::WebRTCPeerConnectionHandlerClient;
@@ -183,10 +167,6 @@ namespace content {
namespace {
bool g_sandbox_enabled = true;
-base::LazyInstance<device::MotionData>::Leaky g_test_device_motion_data =
- LAZY_INSTANCE_INITIALIZER;
-base::LazyInstance<device::OrientationData>::Leaky
- g_test_device_orientation_data = LAZY_INSTANCE_INITIALIZER;
media::AudioParameters GetAudioHardwareParams() {
blink::WebLocalFrame* const web_frame =
@@ -200,19 +180,14 @@ media::AudioParameters GetAudioHardwareParams() {
.output_params();
}
-network::mojom::URLLoaderFactoryPtr GetBlobURLLoaderFactoryGetter() {
- network::mojom::URLLoaderFactoryPtr blob_loader_factory;
- RenderThreadImpl::current()->GetRendererHost()->GetBlobURLLoaderFactory(
- mojo::MakeRequest(&blob_loader_factory));
- return blob_loader_factory;
-}
-
gpu::ContextType ToGpuContextType(blink::Platform::ContextType type) {
switch (type) {
case blink::Platform::kWebGL1ContextType:
return gpu::CONTEXT_TYPE_WEBGL1;
case blink::Platform::kWebGL2ContextType:
return gpu::CONTEXT_TYPE_WEBGL2;
+ case blink::Platform::kWebGL2ComputeContextType:
+ return gpu::CONTEXT_TYPE_WEBGL2_COMPUTE;
case blink::Platform::kGLES2ContextType:
return gpu::CONTEXT_TYPE_OPENGLES2;
case blink::Platform::kGLES3ContextType:
@@ -230,19 +205,26 @@ gpu::ContextType ToGpuContextType(blink::Platform::ContextType type) {
class RendererBlinkPlatformImpl::SandboxSupport
: public blink::WebSandboxSupport {
public:
+#if defined(OS_LINUX)
+ explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader)
+ : font_loader_(std::move(font_loader)) {}
+#endif
~SandboxSupport() override {}
#if defined(OS_MACOSX)
bool LoadFont(CTFontRef src_font,
CGFontRef* container,
uint32_t* font_id) override;
-#elif defined(OS_POSIX)
+#elif defined(OS_LINUX)
void GetFallbackFontForCharacter(
blink::WebUChar32 character,
const char* preferred_locale,
blink::WebFallbackFont* fallbackFont) override;
void GetWebFontRenderStyleForStrike(const char* family,
- int sizeAndStyle,
+ int size,
+ bool is_bold,
+ bool is_italic,
+ float device_scale_factor,
blink::WebFontRenderStyle* out) override;
private:
@@ -251,6 +233,7 @@ class RendererBlinkPlatformImpl::SandboxSupport
// here.
base::Lock unicode_font_families_mutex_;
std::map<int32_t, blink::WebFallbackFont> unicode_font_families_;
+ sk_sp<font_service::FontLoader> font_loader_;
#endif
};
#endif // !defined(OS_ANDROID) && !defined(OS_WIN)
@@ -258,7 +241,7 @@ class RendererBlinkPlatformImpl::SandboxSupport
//------------------------------------------------------------------------------
RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler)
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler)
: BlinkPlatformImpl(main_thread_scheduler->DefaultTaskRunner(),
RenderThreadImpl::current()
? RenderThreadImpl::current()->GetIOTaskRunner()
@@ -266,17 +249,9 @@ RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
compositor_thread_(nullptr),
main_thread_(main_thread_scheduler->CreateMainThread()),
sudden_termination_disables_(0),
- plugin_refresh_allowed_(true),
+ is_locked_to_site_(false),
default_task_runner_(main_thread_scheduler->DefaultTaskRunner()),
- web_scrollbar_behavior_(new WebScrollbarBehaviorImpl),
main_thread_scheduler_(main_thread_scheduler) {
-#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA)
- if (g_sandbox_enabled && sandboxEnabled()) {
- sandbox_support_.reset(new RendererBlinkPlatformImpl::SandboxSupport);
- } else {
- DVLOG(1) << "Disabling sandbox support for testing.";
- }
-#endif
// RenderThread may not exist in some tests.
if (RenderThreadImpl::current()) {
@@ -290,11 +265,28 @@ RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
web_idb_factory_.reset(new WebIDBFactoryImpl(
sync_message_filter_,
RenderThreadImpl::current()->GetIOTaskRunner().get()));
+#if defined(OS_LINUX)
+ font_loader_ = sk_make_sp<font_service::FontLoader>(connector_.get());
+ SkFontConfigInterface::SetGlobal(font_loader_);
+#endif
} else {
service_manager::mojom::ConnectorRequest request;
connector_ = service_manager::Connector::Create(&request);
}
+#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA)
+ if (g_sandbox_enabled && sandboxEnabled()) {
+#if defined(OS_MACOSX)
+ sandbox_support_.reset(new RendererBlinkPlatformImpl::SandboxSupport());
+#else
+ sandbox_support_.reset(
+ new RendererBlinkPlatformImpl::SandboxSupport(font_loader_));
+#endif
+ } else {
+ DVLOG(1) << "Disabling sandbox support for testing.";
+ }
+#endif
+
blink_interface_provider_.reset(
new BlinkInterfaceProviderImpl(connector_.get()));
top_level_blame_context_.Initialize();
@@ -344,6 +336,14 @@ RendererBlinkPlatformImpl::WrapURLLoaderFactory(
network::mojom::URLLoaderFactory::Version_)));
}
+std::unique_ptr<blink::WebURLLoaderFactory>
+RendererBlinkPlatformImpl::WrapSharedURLLoaderFactory(
+ scoped_refptr<network::SharedURLLoaderFactory> factory) {
+ return std::make_unique<WebURLLoaderFactoryImpl>(
+ RenderThreadImpl::current()->resource_dispatcher()->GetWeakPtr(),
+ std::move(factory));
+}
+
std::unique_ptr<blink::WebDataConsumerHandle>
RendererBlinkPlatformImpl::CreateDataConsumerHandle(
mojo::ScopedDataPipeConsumerHandle handle) {
@@ -354,10 +354,7 @@ scoped_refptr<ChildURLLoaderFactoryBundle>
RendererBlinkPlatformImpl::CreateDefaultURLLoaderFactoryBundle() {
return base::MakeRefCounted<ChildURLLoaderFactoryBundle>(
base::BindOnce(&RendererBlinkPlatformImpl::CreateNetworkURLLoaderFactory,
- base::Unretained(this)),
- base::FeatureList::IsEnabled(network::features::kNetworkService)
- ? base::BindOnce(&GetBlobURLLoaderFactoryGetter)
- : ChildURLLoaderFactoryBundle::FactoryGetterCallback());
+ base::Unretained(this)));
}
PossiblyAssociatedInterfacePtr<network::mojom::URLLoaderFactory>
@@ -406,7 +403,7 @@ blink::WebSandboxSupport* RendererBlinkPlatformImpl::GetSandboxSupport() {
}
blink::WebCookieJar* RendererBlinkPlatformImpl::CookieJar() {
- NOTREACHED() << "Use WebFrameClient::cookieJar() instead!";
+ NOTREACHED() << "Use WebLocalFrameClient::cookieJar() instead!";
return nullptr;
}
@@ -590,7 +587,7 @@ bool RendererBlinkPlatformImpl::SandboxSupport::LoadFont(CTFontRef src_font,
return content::LoadFont(src_font, out, font_id);
}
-#elif defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#elif defined(OS_POSIX) && !defined(OS_ANDROID)
void RendererBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter(
blink::WebUChar32 character,
@@ -610,16 +607,20 @@ void RendererBlinkPlatformImpl::SandboxSupport::GetFallbackFontForCharacter(
return;
}
- content::GetFallbackFontForCharacter(character, preferred_locale,
- fallbackFont);
+ content::GetFallbackFontForCharacter(font_loader_, character,
+ preferred_locale, fallbackFont);
unicode_font_families_.insert(std::make_pair(character, *fallbackFont));
}
void RendererBlinkPlatformImpl::SandboxSupport::GetWebFontRenderStyleForStrike(
const char* family,
- int sizeAndStyle,
+ int size,
+ bool is_bold,
+ bool is_italic,
+ float device_scale_factor,
blink::WebFontRenderStyle* out) {
- GetRenderStyleForStrike(family, sizeAndStyle, out);
+ GetRenderStyleForStrike(font_loader_, family, size, is_bold, is_italic,
+ device_scale_factor, out);
}
#endif
@@ -682,10 +683,12 @@ viz::FrameSinkId RendererBlinkPlatformImpl::GenerateFrameSinkId() {
RenderThread::Get()->GenerateRoutingID());
}
-bool RendererBlinkPlatformImpl::IsThreadedCompositingEnabled() {
- RenderThreadImpl* thread = RenderThreadImpl::current();
- // thread can be NULL in tests.
- return thread && thread->compositor_task_runner().get();
+bool RendererBlinkPlatformImpl::IsLockedToSite() const {
+ return is_locked_to_site_;
+}
+
+void RendererBlinkPlatformImpl::SetIsLockedToSite() {
+ is_locked_to_site_ = true;
}
bool RendererBlinkPlatformImpl::IsGpuCompositingDisabled() {
@@ -765,48 +768,6 @@ RendererBlinkPlatformImpl::CreateMIDIAccessor(
return std::make_unique<RendererWebMIDIAccessorImpl>(client);
}
-void RendererBlinkPlatformImpl::GetPluginList(
- bool refresh,
- const blink::WebSecurityOrigin& mainFrameOrigin,
- blink::WebPluginListBuilder* builder) {
-#if BUILDFLAG(ENABLE_PLUGINS)
- std::vector<WebPluginInfo> plugins;
- if (!plugin_refresh_allowed_)
- refresh = false;
- RenderThread::Get()->Send(
- new FrameHostMsg_GetPlugins(refresh, mainFrameOrigin, &plugins));
- for (const WebPluginInfo& plugin : plugins) {
- builder->AddPlugin(WebString::FromUTF16(plugin.name),
- WebString::FromUTF16(plugin.desc),
- blink::FilePathToWebString(plugin.path.BaseName()),
- plugin.background_color);
-
- for (const WebPluginMimeType& mime_type : plugin.mime_types) {
- builder->AddMediaTypeToLastPlugin(
- WebString::FromUTF8(mime_type.mime_type),
- WebString::FromUTF16(mime_type.description));
-
- for (const auto& extension : mime_type.file_extensions) {
- builder->AddFileExtensionToLastMediaType(
- WebString::FromUTF8(extension));
- }
- }
- }
-#endif
-}
-
-//------------------------------------------------------------------------------
-
-blink::WebPublicSuffixList* RendererBlinkPlatformImpl::PublicSuffixList() {
- return &public_suffix_list_;
-}
-
-//------------------------------------------------------------------------------
-
-blink::WebScrollbarBehavior* RendererBlinkPlatformImpl::ScrollbarBehavior() {
- return web_scrollbar_behavior_.get();
-}
-
//------------------------------------------------------------------------------
WebBlobRegistry* RendererBlinkPlatformImpl::GetBlobRegistry() {
@@ -817,11 +778,6 @@ WebBlobRegistry* RendererBlinkPlatformImpl::GetBlobRegistry() {
//------------------------------------------------------------------------------
void RendererBlinkPlatformImpl::SampleGamepads(device::Gamepads& gamepads) {
- PlatformEventObserverBase* observer =
- platform_event_observers_.Lookup(blink::kWebPlatformEventTypeGamepad);
- if (!observer)
- return;
- static_cast<RendererGamepadProvider*>(observer)->SampleGamepads(gamepads);
}
//------------------------------------------------------------------------------
@@ -860,13 +816,12 @@ RendererBlinkPlatformImpl::CreateRTCCertificateGenerator() {
//------------------------------------------------------------------------------
std::unique_ptr<WebMediaStreamCenter>
-RendererBlinkPlatformImpl::CreateMediaStreamCenter(
- WebMediaStreamCenterClient* client) {
+RendererBlinkPlatformImpl::CreateMediaStreamCenter() {
RenderThreadImpl* render_thread = RenderThreadImpl::current();
DCHECK(render_thread);
if (!render_thread)
return nullptr;
- return render_thread->CreateMediaStreamCenter(client);
+ return render_thread->CreateMediaStreamCenter();
}
// static
@@ -943,6 +898,28 @@ RendererBlinkPlatformImpl::CreateImageCaptureFrameGrabber() {
return std::make_unique<ImageCaptureFrameGrabber>();
}
+//------------------------------------------------------------------------------
+
+std::unique_ptr<webrtc::RtpCapabilities>
+RendererBlinkPlatformImpl::GetRtpSenderCapabilities(
+ const blink::WebString& kind) {
+ PeerConnectionDependencyFactory* pc_dependency_factory =
+ RenderThreadImpl::current()->GetPeerConnectionDependencyFactory();
+ pc_dependency_factory->EnsureInitialized();
+ return pc_dependency_factory->GetSenderCapabilities(kind.Utf8());
+}
+
+std::unique_ptr<webrtc::RtpCapabilities>
+RendererBlinkPlatformImpl::GetRtpReceiverCapabilities(
+ const blink::WebString& kind) {
+ PeerConnectionDependencyFactory* pc_dependency_factory =
+ RenderThreadImpl::current()->GetPeerConnectionDependencyFactory();
+ pc_dependency_factory->EnsureInitialized();
+ return pc_dependency_factory->GetReceiverCapabilities(kind.Utf8());
+}
+
+//------------------------------------------------------------------------------
+
void RendererBlinkPlatformImpl::UpdateWebRTCAPICount(
blink::WebRTCAPIName api_name) {
UpdateWebRTCMethodCount(api_name);
@@ -969,11 +946,12 @@ static void Collect3DContextInformation(
blink::Platform::GraphicsInfo* gl_info,
const gpu::GPUInfo& gpu_info) {
DCHECK(gl_info);
- gl_info->vendor_id = gpu_info.gpu.vendor_id;
- gl_info->device_id = gpu_info.gpu.device_id;
+ const gpu::GPUInfo::GPUDevice& active_gpu = gpu_info.active_gpu();
+ gl_info->vendor_id = active_gpu.vendor_id;
+ gl_info->device_id = active_gpu.device_id;
gl_info->renderer_info = WebString::FromUTF8(gpu_info.gl_renderer);
gl_info->vendor_info = WebString::FromUTF8(gpu_info.gl_vendor);
- gl_info->driver_version = WebString::FromUTF8(gpu_info.driver_version);
+ gl_info->driver_version = WebString::FromUTF8(active_gpu.driver_version);
gl_info->reset_notification_strategy =
gpu_info.gl_reset_notification_strategy;
gl_info->sandboxed = gpu_info.sandboxed;
@@ -1003,8 +981,6 @@ RendererBlinkPlatformImpl::CreateOffscreenGraphicsContext3DProvider(
}
Collect3DContextInformation(gl_info, gpu_channel_host->gpu_info());
- bool is_software_rendering = gpu_channel_host->gpu_info().software_rendering;
-
// This is an offscreen context. Generally it won't use the default
// frame buffer, in that case don't request any alpha, depth, stencil,
// antialiasing. But we do need those attributes for the "own
@@ -1040,9 +1016,9 @@ RendererBlinkPlatformImpl::CreateOffscreenGraphicsContext3DProvider(
gpu::kNullSurfaceHandle, GURL(top_document_web_url),
automatic_flushes, support_locking, web_attributes.support_grcontext,
gpu::SharedMemoryLimits(), attributes,
- ui::command_buffer_metrics::OFFSCREEN_CONTEXT_FOR_WEBGL));
+ ui::command_buffer_metrics::ContextType::WEBGL));
return std::make_unique<WebGraphicsContext3DProviderImpl>(
- std::move(provider), is_software_rendering);
+ std::move(provider));
}
//------------------------------------------------------------------------------
@@ -1061,15 +1037,12 @@ RendererBlinkPlatformImpl::CreateSharedOffscreenGraphicsContext3DProvider() {
// channel can become lost on the IO thread since then. It is important that
// this happens after getting |provider|. In the case that this GpuChannelHost
// is not the same one backing |provider|, the context behind the |provider|
- // will be already lost/dead on arrival, so the value we get for
- // |is_software_rendering| will never be wrong.
+ // will be already lost/dead on arrival.
if (!host)
return nullptr;
- bool is_software_rendering = host->gpu_info().software_rendering;
-
return std::make_unique<WebGraphicsContext3DProviderImpl>(
- std::move(provider), is_software_rendering);
+ std::move(provider));
}
//------------------------------------------------------------------------------
@@ -1099,65 +1072,6 @@ void RendererBlinkPlatformImpl::RecordRapporURL(const char* metric,
GetContentClient()->renderer()->RecordRapporURL(metric, url);
}
-//------------------------------------------------------------------------------
-
-// static
-void RendererBlinkPlatformImpl::SetMockDeviceMotionDataForTesting(
- const device::MotionData& data) {
- g_test_device_motion_data.Get() = data;
-}
-
-//------------------------------------------------------------------------------
-
-// static
-void RendererBlinkPlatformImpl::SetMockDeviceOrientationDataForTesting(
- const device::OrientationData& data) {
- g_test_device_orientation_data.Get() = data;
-}
-
-//------------------------------------------------------------------------------
-
-// static
-std::unique_ptr<PlatformEventObserverBase>
-RendererBlinkPlatformImpl::CreatePlatformEventObserverFromType(
- blink::WebPlatformEventType type) {
- RenderThread* thread = RenderThreadImpl::current();
-
- // When running layout tests, those observers should not listen to the actual
- // hardware changes. In order to make that happen, they will receive a null
- // thread.
- if (thread && RenderThreadImpl::current()->layout_test_mode())
- thread = nullptr;
-
- switch (type) {
- case blink::kWebPlatformEventTypeDeviceMotion:
- return std::make_unique<DeviceMotionEventPump>(thread);
- case blink::kWebPlatformEventTypeDeviceOrientation:
- return std::make_unique<DeviceOrientationEventPump>(thread,
- false /* absolute */);
- case blink::kWebPlatformEventTypeDeviceOrientationAbsolute:
- return std::make_unique<DeviceOrientationEventPump>(thread,
- true /* absolute */);
- case blink::kWebPlatformEventTypeGamepad:
- return std::make_unique<GamepadSharedMemoryReader>(thread);
- default:
- // A default statement is required to prevent compilation errors when
- // Blink adds a new type.
- DVLOG(1) << "RendererBlinkPlatformImpl::startListening() with "
- "unknown type.";
- }
-
- return nullptr;
-}
-
-void RendererBlinkPlatformImpl::SetPlatformEventObserverForTesting(
- blink::WebPlatformEventType type,
- std::unique_ptr<PlatformEventObserverBase> observer) {
- if (platform_event_observers_.Lookup(type))
- platform_event_observers_.Remove(type);
- platform_event_observers_.AddWithID(std::move(observer), type);
-}
-
service_manager::Connector* RendererBlinkPlatformImpl::GetConnector() {
return connector_.get();
}
@@ -1169,68 +1083,11 @@ blink::InterfaceProvider* RendererBlinkPlatformImpl::GetInterfaceProvider() {
void RendererBlinkPlatformImpl::StartListening(
blink::WebPlatformEventType type,
blink::WebPlatformEventListener* listener) {
- PlatformEventObserverBase* observer = platform_event_observers_.Lookup(type);
- if (!observer) {
- std::unique_ptr<PlatformEventObserverBase> new_observer =
- CreatePlatformEventObserverFromType(type);
- if (!new_observer)
- return;
- observer = new_observer.get();
- platform_event_observers_.AddWithID(std::move(new_observer),
- static_cast<int32_t>(type));
- }
- observer->Start(listener);
-
- // Device events (motion and orientation) expect to get an event fired
- // as soon as a listener is registered if a fake data was passed before.
- // TODO(mlamouri,timvolodine): make those send mock values directly instead of
- // using this broken pattern.
- if (RenderThreadImpl::current() &&
- RenderThreadImpl::current()->layout_test_mode() &&
- (type == blink::kWebPlatformEventTypeDeviceMotion ||
- type == blink::kWebPlatformEventTypeDeviceOrientation ||
- type == blink::kWebPlatformEventTypeDeviceOrientationAbsolute)) {
- SendFakeDeviceEventDataForTesting(type);
- }
-}
-
-void RendererBlinkPlatformImpl::SendFakeDeviceEventDataForTesting(
- blink::WebPlatformEventType type) {
- PlatformEventObserverBase* observer = platform_event_observers_.Lookup(type);
- CHECK(observer);
-
- void* data = nullptr;
- switch (type) {
- case blink::kWebPlatformEventTypeDeviceMotion:
- if (g_test_device_motion_data.IsCreated())
- data = &g_test_device_motion_data.Get();
- break;
- case blink::kWebPlatformEventTypeDeviceOrientation:
- case blink::kWebPlatformEventTypeDeviceOrientationAbsolute:
- if (g_test_device_orientation_data.IsCreated())
- data = &g_test_device_orientation_data.Get();
- break;
- default:
- NOTREACHED();
- break;
- }
-
- if (!data)
- return;
-
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&PlatformEventObserverBase::SendFakeDataForTesting,
- base::Unretained(observer), data));
}
void RendererBlinkPlatformImpl::StopListening(
blink::WebPlatformEventType type) {
- PlatformEventObserverBase* observer = platform_event_observers_.Lookup(type);
- if (!observer)
- return;
- observer->Stop();
}
//------------------------------------------------------------------------------
diff --git a/chromium/content/renderer/renderer_blink_platform_impl.h b/chromium/content/renderer/renderer_blink_platform_impl.h
index ecb5ce6d6aa..bebcd933b8c 100644
--- a/chromium/content/renderer/renderer_blink_platform_impl.h
+++ b/chromium/content/renderer/renderer_blink_platform_impl.h
@@ -22,7 +22,6 @@
#include "content/common/content_export.h"
#include "content/common/possibly_associated_interface_ptr.h"
#include "content/renderer/top_level_blame_context.h"
-#include "content/renderer/webpublicsuffixlist_impl.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h"
@@ -30,13 +29,18 @@
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h"
#include "third_party/blink/public/platform/modules/webdatabase/web_database.mojom.h"
+#if defined(OS_LINUX)
+#include "components/services/font/public/cpp/font_loader.h" // nogncheck
+#include "third_party/skia/include/core/SkRefCnt.h" // nogncheck
+#endif
+
namespace IPC {
class SyncMessageFilter;
}
namespace blink {
namespace scheduler {
-class WebMainThreadScheduler;
+class WebThreadScheduler;
class WebThreadBase;
}
class WebCanvasCaptureHandler;
@@ -47,32 +51,26 @@ class WebMediaStream;
class WebSecurityOrigin;
} // namespace blink
-namespace device {
-class Gamepads;
-class MotionData;
-class OrientationData;
+namespace network {
+class SharedURLLoaderFactory;
}
namespace content {
class BlinkInterfaceProviderImpl;
class ChildURLLoaderFactoryBundle;
class LocalStorageCachedAreas;
-class PlatformEventObserverBase;
class ThreadSafeSender;
class WebDatabaseObserverImpl;
class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
public:
explicit RendererBlinkPlatformImpl(
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler);
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler);
~RendererBlinkPlatformImpl() override;
// Shutdown must be called just prior to shutting down blink.
void Shutdown();
- void set_plugin_refresh_allowed(bool plugin_refresh_allowed) {
- plugin_refresh_allowed_ = plugin_refresh_allowed;
- }
// Platform methods:
blink::WebSandboxSupport* GetSandboxSupport() override;
blink::WebCookieJar* CookieJar() override;
@@ -120,18 +118,13 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
blink::WebString DatabaseCreateOriginIdentifier(
const blink::WebSecurityOrigin& origin) override;
viz::FrameSinkId GenerateFrameSinkId() override;
+ bool IsLockedToSite() const override;
- void GetPluginList(bool refresh,
- const blink::WebSecurityOrigin& mainFrameOrigin,
- blink::WebPluginListBuilder* builder) override;
- blink::WebPublicSuffixList* PublicSuffixList() override;
- blink::WebScrollbarBehavior* ScrollbarBehavior() override;
blink::WebIDBFactory* IdbFactory() override;
blink::WebFileSystem* FileSystem() override;
blink::WebString FileSystemCreateOriginIdentifier(
const blink::WebSecurityOrigin& origin) override;
- bool IsThreadedCompositingEnabled() override;
bool IsThreadedAnimationEnabled() override;
bool IsGpuCompositingDisabled() override;
double AudioHardwareSampleRate() override;
@@ -163,8 +156,8 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
CreateRTCCertificateGenerator() override;
std::unique_ptr<blink::WebMediaRecorderHandler> CreateMediaRecorderHandler(
scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
- std::unique_ptr<blink::WebMediaStreamCenter> CreateMediaStreamCenter(
- blink::WebMediaStreamCenterClient* client) override;
+ std::unique_ptr<blink::WebMediaStreamCenter> CreateMediaStreamCenter()
+ override;
std::unique_ptr<blink::WebCanvasCaptureHandler> CreateCanvasCaptureHandler(
const blink::WebSize& size,
double frame_rate,
@@ -178,6 +171,10 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
blink::WebMediaPlayer* web_media_player) override;
std::unique_ptr<blink::WebImageCaptureFrameGrabber>
CreateImageCaptureFrameGrabber() override;
+ std::unique_ptr<webrtc::RtpCapabilities> GetRtpSenderCapabilities(
+ const blink::WebString& kind) override;
+ std::unique_ptr<webrtc::RtpCapabilities> GetRtpReceiverCapabilities(
+ const blink::WebString& kind) override;
void UpdateWebRTCAPICount(blink::WebRTCAPIName api_name) override;
std::unique_ptr<blink::WebSocketHandshakeThrottle>
CreateWebSocketHandshakeThrottle() override;
@@ -205,14 +202,6 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
void WillStopWorkerThread() override;
void WorkerContextCreated(const v8::Local<v8::Context>& worker) override;
- // Set the PlatformEventObserverBase in |platform_event_observers_| associated
- // with |type| to |observer|. If there was already an observer associated to
- // the given |type|, it will be replaced.
- // Note that |observer| will be owned by this object after the call.
- void SetPlatformEventObserverForTesting(
- blink::WebPlatformEventType type,
- std::unique_ptr<PlatformEventObserverBase> observer);
-
// Disables the WebSandboxSupport implementation for testing.
// Tests that do not set up a full sandbox environment should call
// SetSandboxEnabledForTesting(false) _before_ creating any instances
@@ -222,13 +211,6 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
// Returns the previous |enable| value.
static bool SetSandboxEnabledForTesting(bool enable);
- // Set MotionData to return when setDeviceMotionListener is invoked.
- static void SetMockDeviceMotionDataForTesting(const device::MotionData& data);
- // Set OrientationData to return when setDeviceOrientationListener
- // is invoked.
- static void SetMockDeviceOrientationDataForTesting(
- const device::OrientationData& data);
-
WebDatabaseObserverImpl* web_database_observer_impl() {
return web_database_observer_impl_.get();
}
@@ -237,6 +219,8 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
override;
std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory(
mojo::ScopedMessagePipeHandle url_loader_factory_handle) override;
+ std::unique_ptr<blink::WebURLLoaderFactory> WrapSharedURLLoaderFactory(
+ scoped_refptr<network::SharedURLLoaderFactory> factory) override;
std::unique_ptr<blink::WebDataConsumerHandle> CreateDataConsumerHandle(
mojo::ScopedDataPipeConsumerHandle handle) override;
void RequestPurgeMemory() override;
@@ -259,17 +243,16 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
void CloneSessionStorageNamespace(const std::string& source_namespace,
const std::string& destination_namespace);
+ // Tells this platform that the renderer is locked to a site (i.e., a scheme
+ // plus eTLD+1, such as https://google.com), or to a more specific origin.
+ void SetIsLockedToSite();
+
private:
bool CheckPreparsedJsCachingEnabled() const;
- // Factory that takes a type and return PlatformEventObserverBase that matches
- // it.
- static std::unique_ptr<PlatformEventObserverBase>
- CreatePlatformEventObserverFromType(blink::WebPlatformEventType type);
-
- // Use the data previously set via SetMockDevice...DataForTesting() and send
- // them to the registered listener.
- void SendFakeDeviceEventDataForTesting(blink::WebPlatformEventType type);
+ // TODO(crbug.com/850997): Remove when Device*EventPump classes are
+ // moved to blink
+ void StopDeviceSensorEventPump(blink::WebPlatformEventType type);
// Ensure that the WebDatabaseHost has been initialized.
void InitializeWebDatabaseHostIfNeeded();
@@ -293,28 +276,21 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
// we tell the browser to enable fast termination.
int sudden_termination_disables_;
- // If true, then a GetPlugins call is allowed to rescan the disk.
- bool plugin_refresh_allowed_;
+ // If true, the renderer process is locked to a site.
+ bool is_locked_to_site_;
std::unique_ptr<blink::WebIDBFactory> web_idb_factory_;
std::unique_ptr<blink::WebBlobRegistry> blob_registry_;
- WebPublicSuffixListImpl public_suffix_list_;
-
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
scoped_refptr<IPC::SyncMessageFilter> sync_message_filter_;
scoped_refptr<ThreadSafeSender> thread_safe_sender_;
std::unique_ptr<WebDatabaseObserverImpl> web_database_observer_impl_;
- std::unique_ptr<blink::WebScrollbarBehavior> web_scrollbar_behavior_;
-
- base::IDMap<std::unique_ptr<PlatformEventObserverBase>>
- platform_event_observers_;
-
// NOT OWNED
- blink::scheduler::WebMainThreadScheduler* main_thread_scheduler_;
+ blink::scheduler::WebThreadScheduler* main_thread_scheduler_;
TopLevelBlameContext top_level_blame_context_;
@@ -325,6 +301,10 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
blink::mojom::WebDatabaseHostPtrInfo web_database_host_info_;
scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr> web_database_host_;
+#if defined(OS_LINUX)
+ sk_sp<font_service::FontLoader> font_loader_;
+#endif
+
THREAD_CHECKER(main_thread_checker_);
DISALLOW_COPY_AND_ASSIGN(RendererBlinkPlatformImpl);
diff --git a/chromium/content/renderer/renderer_main.cc b/chromium/content/renderer/renderer_main.cc
index f3664c6e0eb..0b722923ba6 100644
--- a/chromium/content/renderer/renderer_main.cc
+++ b/chromium/content/renderer/renderer_main.cc
@@ -25,6 +25,7 @@
#include "content/common/content_constants_internal.h"
#include "content/common/content_switches_internal.h"
#include "content/common/service_manager/service_manager_connection_impl.h"
+#include "content/common/skia_utils.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "content/public/renderer/content_renderer_client.h"
@@ -34,8 +35,7 @@
#include "media/media_buildflags.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/service_manager/sandbox/switches.h"
-#include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h"
-#include "third_party/skia/include/core/SkGraphics.h"
+#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/webrtc_overrides/init_webrtc.h" // nogncheck
#include "ui/base/ui_base_switches.h"
@@ -43,14 +43,6 @@
#include "base/android/library_loader/library_loader_hooks.h"
#endif // OS_ANDROID
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \
- !defined(OS_FUCHSIA)
-#include "content/common/font_config_ipc_linux.h"
-#include "services/service_manager/sandbox/linux/sandbox_linux.h"
-#include "services/service_manager/zygote/common/common_sandbox_support_linux.h"
-#include "third_party/skia/include/ports/SkFontConfigInterface.h"
-#endif
-
#if defined(OS_MACOSX)
#include <Carbon/Carbon.h>
#include <signal.h>
@@ -121,46 +113,7 @@ int RendererMain(const MainFunctionParams& parameters) {
}
#endif
- const base::CommandLine& process_command_line =
- *base::CommandLine::ForCurrentProcess();
-
-#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \
- !defined(OS_FUCHSIA)
- // This call could already have been made from zygote_main_linux.cc. However
- // we need to do it here if Zygote is disabled.
- if (process_command_line.HasSwitch(switches::kNoZygote)) {
- SkFontConfigInterface::SetGlobal(
- sk_make_sp<FontConfigIPC>(service_manager::GetSandboxFD()));
- }
-#endif
-
- if (!process_command_line.HasSwitch(switches::kDisableSkiaRuntimeOpts)) {
- SkGraphics::Init();
- }
-
- const int kMB = 1024 * 1024;
- size_t font_cache_limit;
-#if defined(OS_ANDROID)
- font_cache_limit = base::SysInfo::IsLowEndDevice() ? kMB : 8 * kMB;
- SkGraphics::SetFontCacheLimit(font_cache_limit);
-#else
- if (process_command_line.HasSwitch(switches::kSkiaFontCacheLimitMb)) {
- if (base::StringToSizeT(process_command_line.GetSwitchValueASCII(
- switches::kSkiaFontCacheLimitMb),
- &font_cache_limit)) {
- SkGraphics::SetFontCacheLimit(font_cache_limit * kMB);
- }
- }
-
- size_t resource_cache_limit;
- if (process_command_line.HasSwitch(switches::kSkiaResourceCacheLimitMb)) {
- if (base::StringToSizeT(process_command_line.GetSwitchValueASCII(
- switches::kSkiaResourceCacheLimitMb),
- &resource_cache_limit)) {
- SkGraphics::SetResourceCacheTotalByteLimit(resource_cache_limit * kMB);
- }
- }
-#endif
+ InitializeSkia();
// This function allows pausing execution using the --renderer-startup-dialog
// flag allowing us to attach a debugger.
@@ -183,9 +136,6 @@ int RendererMain(const MainFunctionParams& parameters) {
base::PlatformThread::SetName("CrRendererMain");
- bool no_sandbox =
- command_line.HasSwitch(service_manager::switches::kNoSandbox);
-
#if defined(OS_ANDROID)
// If we have any pending LibraryLoader histograms, record them.
base::android::RecordLibraryLoaderRendererHistograms();
@@ -200,8 +150,8 @@ int RendererMain(const MainFunctionParams& parameters) {
initial_virtual_time = base::Time::FromDoubleT(initial_time);
}
}
- std::unique_ptr<blink::scheduler::WebMainThreadScheduler>
- main_thread_scheduler(blink::scheduler::WebMainThreadScheduler::Create(
+ std::unique_ptr<blink::scheduler::WebThreadScheduler> main_thread_scheduler(
+ blink::scheduler::WebThreadScheduler::CreateMainThreadScheduler(
initial_virtual_time));
// PlatformInitialize uses FieldTrials, so this must happen later.
@@ -218,21 +168,26 @@ int RendererMain(const MainFunctionParams& parameters) {
InitializeWebRtcModule();
{
-#if defined(OS_WIN) || defined(OS_MACOSX)
- // TODO(markus): Check if it is OK to unconditionally move this
- // instruction down.
- auto render_process = RenderProcessImpl::Create();
- RenderThreadImpl::Create(std::move(main_message_loop),
- std::move(main_thread_scheduler));
-#endif
bool run_loop = true;
- if (!no_sandbox)
+ bool need_sandbox =
+ !command_line.HasSwitch(service_manager::switches::kNoSandbox);
+
+#if !defined(OS_WIN) && !defined(OS_MACOSX)
+ // Sandbox is enabled before RenderProcess initialization on all platforms,
+ // except Windows and Mac.
+ // TODO(markus): Check if it is OK to remove ifdefs for Windows and Mac.
+ if (need_sandbox) {
run_loop = platform.EnableSandbox();
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
+ need_sandbox = false;
+ }
+#endif
+
auto render_process = RenderProcessImpl::Create();
RenderThreadImpl::Create(std::move(main_message_loop),
std::move(main_thread_scheduler));
-#endif
+
+ if (need_sandbox)
+ run_loop = platform.EnableSandbox();
base::HighResolutionTimerManager hi_res_timer_manager;
diff --git a/chromium/content/renderer/renderer_main_platform_delegate_win.cc b/chromium/content/renderer/renderer_main_platform_delegate_win.cc
index d121f97ad00..f59a53dbc38 100644
--- a/chromium/content/renderer/renderer_main_platform_delegate_win.cc
+++ b/chromium/content/renderer/renderer_main_platform_delegate_win.cc
@@ -55,9 +55,6 @@ void RendererMainPlatformDelegate::PlatformInitialize() {
}
InitializeDWriteFontProxy();
-
- // TODO(robliao): This should use WebScreenInfo. See http://crbug.com/604555.
- blink::WebFontRendering::SetDeviceScaleFactor(display::win::GetDPIScale());
}
void RendererMainPlatformDelegate::PlatformUninitialize() {
diff --git a/chromium/content/renderer/sad_plugin.cc b/chromium/content/renderer/sad_plugin.cc
index 5437685fae8..f68f8f481a9 100644
--- a/chromium/content/renderer/sad_plugin.cc
+++ b/chromium/content/renderer/sad_plugin.cc
@@ -13,9 +13,9 @@
namespace content {
-void PaintSadPlugin(blink::WebCanvas* webcanvas,
+void PaintSadPlugin(cc::PaintCanvas* webcanvas,
const gfx::Rect& plugin_rect,
- const SkBitmap& sad_plugin_bitmap) {
+ const cc::PaintImage& sad_plugin_image) {
const int width = plugin_rect.width();
const int height = plugin_rect.height();
@@ -29,10 +29,10 @@ void PaintSadPlugin(blink::WebCanvas* webcanvas,
flags.setStyle(cc::PaintFlags::kFill_Style);
flags.setColor(SK_ColorBLACK);
canvas->drawRect(SkRect::MakeIWH(width, height), flags);
- canvas->drawBitmap(
- sad_plugin_bitmap,
- SkIntToScalar(std::max(0, (width - sad_plugin_bitmap.width()) / 2)),
- SkIntToScalar(std::max(0, (height - sad_plugin_bitmap.height()) / 2)));
+ canvas->drawImage(
+ sad_plugin_image,
+ SkIntToScalar(std::max(0, (width - sad_plugin_image.width()) / 2)),
+ SkIntToScalar(std::max(0, (height - sad_plugin_image.height()) / 2)));
}
} // namespace content
diff --git a/chromium/content/renderer/sad_plugin.h b/chromium/content/renderer/sad_plugin.h
index b14808b9f89..b619734266a 100644
--- a/chromium/content/renderer/sad_plugin.h
+++ b/chromium/content/renderer/sad_plugin.h
@@ -5,9 +5,11 @@
#ifndef CONTENT_RENDERER_SAD_PLUGIN_H_
#define CONTENT_RENDERER_SAD_PLUGIN_H_
-#include "third_party/blink/public/platform/web_canvas.h"
+#include "cc/paint/paint_canvas.h"
-class SkBitmap;
+namespace cc {
+class PaintImage;
+}
namespace gfx {
class Rect;
@@ -17,9 +19,9 @@ namespace content {
// Paints the sad plugin to the given canvas for the given plugin bounds. This
// is used by PPAPI out-of-process plugin impls.
-void PaintSadPlugin(blink::WebCanvas* canvas,
+void PaintSadPlugin(cc::PaintCanvas* canvas,
const gfx::Rect& plugin_rect,
- const SkBitmap& sad_plugin_bitmap);
+ const cc::PaintImage& sad_plugin_image);
} // namespace content
diff --git a/chromium/content/renderer/service_worker/controller_service_worker_connector.cc b/chromium/content/renderer/service_worker/controller_service_worker_connector.cc
index c1677a25c30..b9900a2e686 100644
--- a/chromium/content/renderer/service_worker/controller_service_worker_connector.cc
+++ b/chromium/content/renderer/service_worker/controller_service_worker_connector.cc
@@ -11,23 +11,15 @@
namespace content {
ControllerServiceWorkerConnector::ControllerServiceWorkerConnector(
- mojom::ServiceWorkerContainerHost* container_host,
- mojom::ControllerServiceWorkerPtr controller_ptr,
- const std::string& client_id)
- : container_host_(container_host), client_id_(client_id) {
- SetControllerServiceWorkerPtr(std::move(controller_ptr));
-}
-
-ControllerServiceWorkerConnector::ControllerServiceWorkerConnector(
mojom::ServiceWorkerContainerHostPtrInfo container_host_info,
+ mojom::ControllerServiceWorkerPtr controller_ptr,
const std::string& client_id)
: client_id_(client_id) {
container_host_ptr_.Bind(std::move(container_host_info));
container_host_ptr_.set_connection_error_handler(base::BindOnce(
&ControllerServiceWorkerConnector::OnContainerHostConnectionClosed,
base::Unretained(this)));
- container_host_ = container_host_ptr_.get();
- SetControllerServiceWorkerPtr(nullptr /* controller_ptr */);
+ SetControllerServiceWorkerPtr(std::move(controller_ptr));
}
mojom::ControllerServiceWorker*
@@ -36,9 +28,9 @@ ControllerServiceWorkerConnector::GetControllerServiceWorker(
switch (state_) {
case State::kDisconnected: {
DCHECK(!controller_service_worker_);
- DCHECK(container_host_);
+ DCHECK(container_host_ptr_);
mojom::ControllerServiceWorkerPtr controller_ptr;
- container_host_->EnsureControllerServiceWorker(
+ container_host_ptr_->EnsureControllerServiceWorker(
mojo::MakeRequest(&controller_ptr), purpose);
SetControllerServiceWorkerPtr(std::move(controller_ptr));
return controller_service_worker_.get();
@@ -51,7 +43,7 @@ ControllerServiceWorkerConnector::GetControllerServiceWorker(
return nullptr;
case State::kNoContainerHost:
DCHECK(!controller_service_worker_);
- DCHECK(!container_host_);
+ DCHECK(!container_host_ptr_);
return nullptr;
}
NOTREACHED();
@@ -68,7 +60,6 @@ void ControllerServiceWorkerConnector::RemoveObserver(Observer* observer) {
void ControllerServiceWorkerConnector::OnContainerHostConnectionClosed() {
state_ = State::kNoContainerHost;
- container_host_ = nullptr;
container_host_ptr_.reset();
controller_service_worker_.reset();
}
@@ -81,7 +72,12 @@ void ControllerServiceWorkerConnector::OnControllerConnectionClosed() {
observer.OnConnectionClosed();
}
-void ControllerServiceWorkerConnector::ResetControllerConnection(
+void ControllerServiceWorkerConnector::AddBinding(
+ mojom::ControllerServiceWorkerConnectorRequest request) {
+ bindings_.AddBinding(this, std::move(request));
+}
+
+void ControllerServiceWorkerConnector::UpdateController(
mojom::ControllerServiceWorkerPtr controller_ptr) {
if (state_ == State::kNoContainerHost)
return;
diff --git a/chromium/content/renderer/service_worker/controller_service_worker_connector.h b/chromium/content/renderer/service_worker/controller_service_worker_connector.h
index 9be6d162087..e24bbdac674 100644
--- a/chromium/content/renderer/service_worker/controller_service_worker_connector.h
+++ b/chromium/content/renderer/service_worker/controller_service_worker_connector.h
@@ -11,6 +11,7 @@
#include "content/common/content_export.h"
#include "content/common/service_worker/controller_service_worker.mojom.h"
#include "content/common/service_worker/service_worker_container.mojom.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
namespace content {
@@ -23,7 +24,8 @@ class ServiceWorkerContainerHost;
// ServiceWorkerProviderContext::ControlleeState and
// ServiceWorkerSubresourceLoader{,Factory}.
class CONTENT_EXPORT ControllerServiceWorkerConnector
- : public base::RefCounted<ControllerServiceWorkerConnector> {
+ : public mojom::ControllerServiceWorkerConnector,
+ public base::RefCounted<ControllerServiceWorkerConnector> {
public:
// Observes the connection to the controller.
class Observer {
@@ -55,17 +57,12 @@ class CONTENT_EXPORT ControllerServiceWorkerConnector
// |controller_ptr| may be nullptr if the caller does not yet have a Mojo
// connection to the controller. |state_| is set to kDisconnected in that
// case.
- ControllerServiceWorkerConnector(
- mojom::ServiceWorkerContainerHost* container_host,
- mojom::ControllerServiceWorkerPtr controller_ptr,
- const std::string& client_id);
-
- // Used by service worker clients that are workers (i.e., dedicated workers
- // and shared workers). Creates and holds the ownership of
- // |container_host_ptr_| (as |this| will be created on a different thread from
- // the worker thread that has the original |container_host|).
+ // Creates and holds the ownership of |container_host_ptr_| (as |this|
+ // will be created on a different thread from the thread that has the
+ // original |container_host|).
ControllerServiceWorkerConnector(
mojom::ServiceWorkerContainerHostPtrInfo container_host_info,
+ mojom::ControllerServiceWorkerPtr controller_ptr,
const std::string& client_id);
// This may return nullptr if the connection to the ContainerHost (in the
@@ -79,10 +76,11 @@ class CONTENT_EXPORT ControllerServiceWorkerConnector
void OnContainerHostConnectionClosed();
void OnControllerConnectionClosed();
- // Resets the controller connection with the given |controller_ptr|, this
- // can be called when a new controller is given, e.g. due to claim().
- void ResetControllerConnection(
- mojom::ControllerServiceWorkerPtr controller_ptr);
+ void AddBinding(mojom::ControllerServiceWorkerConnectorRequest request);
+
+ // mojom::ControllerServiceWorkerConnector:
+ void UpdateController(
+ mojom::ControllerServiceWorkerPtr controller_ptr) override;
State state() const { return state_; }
@@ -95,13 +93,9 @@ class CONTENT_EXPORT ControllerServiceWorkerConnector
State state_ = State::kDisconnected;
friend class base::RefCounted<ControllerServiceWorkerConnector>;
- ~ControllerServiceWorkerConnector();
+ ~ControllerServiceWorkerConnector() override;
- // Connection to the ServiceWorkerProviderHost that lives in the
- // browser process. This is used to (re-)obtain Mojo connection to
- // |controller_service_worker_| when it is not established.
- // Cleared when the connection is dropped.
- mojom::ServiceWorkerContainerHost* container_host_;
+ mojo::BindingSet<mojom::ControllerServiceWorkerConnector> bindings_;
// Keeps the mojo end to the browser process on its own.
// Non-null only for the service worker clients that are workers (i.e., only
diff --git a/chromium/content/renderer/service_worker/controller_service_worker_impl.cc b/chromium/content/renderer/service_worker/controller_service_worker_impl.cc
index 691fe701daa..a90ae551b9b 100644
--- a/chromium/content/renderer/service_worker/controller_service_worker_impl.cc
+++ b/chromium/content/renderer/service_worker/controller_service_worker_impl.cc
@@ -4,8 +4,8 @@
#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"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
@@ -13,7 +13,7 @@ ControllerServiceWorkerImpl::ControllerServiceWorkerImpl(
mojom::ControllerServiceWorkerRequest request,
base::WeakPtr<ServiceWorkerContextClient> context_client)
: context_client_(std::move(context_client)) {
- CHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ CHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
bindings_.AddBinding(this, std::move(request));
}
@@ -25,7 +25,7 @@ void ControllerServiceWorkerImpl::Clone(
}
void ControllerServiceWorkerImpl::DispatchFetchEvent(
- mojom::DispatchFetchEventParamsPtr params,
+ blink::mojom::DispatchFetchEventParamsPtr params,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback) {
DCHECK(context_client_);
diff --git a/chromium/content/renderer/service_worker/controller_service_worker_impl.h b/chromium/content/renderer/service_worker/controller_service_worker_impl.h
index f2ea0ce06c5..308fa39d3cb 100644
--- a/chromium/content/renderer/service_worker/controller_service_worker_impl.h
+++ b/chromium/content/renderer/service_worker/controller_service_worker_impl.h
@@ -39,7 +39,7 @@ class ControllerServiceWorkerImpl : public mojom::ControllerServiceWorker {
// mojom::ControllerServiceWorker:
void DispatchFetchEvent(
- mojom::DispatchFetchEventParamsPtr params,
+ blink::mojom::DispatchFetchEventParamsPtr params,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback) override;
void Clone(mojom::ControllerServiceWorkerRequest request) override;
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 5b7ceb07604..6c0ee47de40 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
@@ -15,7 +15,7 @@
#include "content/renderer/service_worker/service_worker_context_client.h"
#include "content/renderer/service_worker/web_service_worker_installed_scripts_manager_impl.h"
#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_installed_scripts_manager.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_installed_scripts_manager.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_url.h"
@@ -32,15 +32,12 @@ EmbeddedWorkerInstanceClientImpl::WorkerWrapper::~WorkerWrapper() = default;
// static
void EmbeddedWorkerInstanceClientImpl::Create(
- base::TimeTicks blink_initialized_time,
scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner,
mojom::EmbeddedWorkerInstanceClientRequest request) {
// This won't be leaked because the lifetime will be managed internally.
// See the class documentation for detail.
- EmbeddedWorkerInstanceClientImpl* client =
- new EmbeddedWorkerInstanceClientImpl(std::move(io_thread_runner),
- std::move(request));
- client->blink_initialized_time_ = blink_initialized_time;
+ new EmbeddedWorkerInstanceClientImpl(std::move(io_thread_runner),
+ std::move(request));
}
void EmbeddedWorkerInstanceClientImpl::WorkerContextDestroyed() {
@@ -57,6 +54,8 @@ void EmbeddedWorkerInstanceClientImpl::StartWorker(
DCHECK(!wrapper_);
TRACE_EVENT0("ServiceWorker",
"EmbeddedWorkerInstanceClientImpl::StartWorker");
+ auto start_timing = mojom::EmbeddedWorkerStartTiming::New();
+ start_timing->start_worker_received_time = base::TimeTicks::Now();
DCHECK(!params->provider_info->cache_storage ||
base::FeatureList::IsEnabled(
blink::features::kEagerCacheStorageSetupForServiceWorkers));
@@ -64,19 +63,22 @@ void EmbeddedWorkerInstanceClientImpl::StartWorker(
std::move(params->provider_info->cache_storage);
service_manager::mojom::InterfaceProviderPtrInfo interface_provider =
std::move(params->provider_info->interface_provider);
+ blink::PrivacyPreferences privacy_preferences(
+ params->renderer_preferences.enable_do_not_track,
+ params->renderer_preferences.enable_referrers);
auto client = std::make_unique<ServiceWorkerContextClient>(
params->embedded_worker_id, params->service_worker_version_id,
params->scope, params->script_url,
!params->installed_scripts_info.is_null(),
- std::move(params->dispatcher_request),
+ std::move(params->renderer_preferences),
+ std::move(params->service_worker_request),
std::move(params->controller_request), std::move(params->instance_host),
std::move(params->provider_info), std::move(temporal_self_),
+ std::move(start_timing),
RenderThreadImpl::current()
->GetWebMainThreadScheduler()
->DefaultTaskRunner());
- client->set_blink_initialized_time(blink_initialized_time_);
- client->set_start_worker_received_time(base::TimeTicks::Now());
// Record UMA to indicate StartWorker is received on renderer.
StartWorkerHistogramEnum metric =
params->is_installed ? StartWorkerHistogramEnum::RECEIVED_ON_INSTALLED
@@ -86,7 +88,8 @@ void EmbeddedWorkerInstanceClientImpl::StartWorker(
StartWorkerHistogramEnum::NUM_TYPES);
wrapper_ = StartWorkerContext(std::move(params), std::move(client),
std::move(cache_storage),
- std::move(interface_provider));
+ std::move(interface_provider),
+ std::move(privacy_preferences));
}
void EmbeddedWorkerInstanceClientImpl::StopWorker() {
@@ -143,7 +146,8 @@ EmbeddedWorkerInstanceClientImpl::StartWorkerContext(
mojom::EmbeddedWorkerStartParamsPtr params,
std::unique_ptr<ServiceWorkerContextClient> context_client,
blink::mojom::CacheStoragePtrInfo cache_storage,
- service_manager::mojom::InterfaceProviderPtrInfo interface_provider) {
+ service_manager::mojom::InterfaceProviderPtrInfo interface_provider,
+ blink::PrivacyPreferences privacy_preferences) {
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
@@ -174,6 +178,7 @@ EmbeddedWorkerInstanceClientImpl::StartWorkerContext(
params->pause_after_download
? blink::WebEmbeddedWorkerStartData::kPauseAfterDownload
: blink::WebEmbeddedWorkerStartData::kDontPauseAfterDownload;
+ start_data.privacy_preferences = std::move(privacy_preferences);
wrapper->worker()->StartWorkerContext(start_data);
return wrapper;
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 e755302db45..d86d3387c6b 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
@@ -13,6 +13,7 @@
#include "content/child/scoped_child_process_reference.h"
#include "content/common/service_worker/embedded_worker.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "third_party/blink/public/common/privacy_preferences.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom.h"
#include "third_party/blink/public/web/worker_content_settings_proxy.mojom.h"
@@ -59,7 +60,6 @@ class EmbeddedWorkerInstanceClientImpl
// TODO(shimazu): Create a service worker's execution context by this method
// instead of just creating an instance of EmbeddedWorkerInstanceClient.
static void Create(
- base::TimeTicks blink_initialized_time,
scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner,
mojom::EmbeddedWorkerInstanceClientRequest request);
@@ -103,7 +103,8 @@ class EmbeddedWorkerInstanceClientImpl
mojom::EmbeddedWorkerStartParamsPtr params,
std::unique_ptr<ServiceWorkerContextClient> context_client,
blink::mojom::CacheStoragePtrInfo cache_storage,
- service_manager::mojom::InterfaceProviderPtrInfo interface_provider);
+ service_manager::mojom::InterfaceProviderPtrInfo interface_provider,
+ blink::PrivacyPreferences privacy_preferences);
mojo::Binding<mojom::EmbeddedWorkerInstanceClient> binding_;
@@ -114,9 +115,6 @@ class EmbeddedWorkerInstanceClientImpl
// nullptr means the worker is not running.
std::unique_ptr<WorkerWrapper> wrapper_;
- // For UMA.
- base::TimeTicks blink_initialized_time_;
-
scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner_;
DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceClientImpl);
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 31065358f6e..fecbaf9bea3 100644
--- a/chromium/content/renderer/service_worker/service_worker_context_client.cc
+++ b/chromium/content/renderer/service_worker/service_worker_context_client.cc
@@ -19,9 +19,8 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
-#include "content/common/service_worker/service_worker_event_dispatcher.mojom.h"
+#include "content/common/service_worker/service_worker.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/common/content_features.h"
#include "content/public/common/push_event_payload.h"
@@ -57,6 +56,8 @@
#include "services/network/public/mojom/request_context_frame_type.mojom.h"
#include "storage/common/blob_storage/blob_handle.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
@@ -69,20 +70,21 @@
#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
#include "third_party/blink/public/platform/modules/payments/web_payment_handler_response.h"
#include "third_party/blink/public/platform/modules/payments/web_payment_request_event_data.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_client_query_options.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_error.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_network_provider.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_request.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_response.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_client_query_options.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_response.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_blob_registry.h"
+#include "third_party/blink/public/platform/web_http_body.h"
#include "third_party/blink/public/platform/web_referrer_policy.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url_response.h"
-#include "third_party/blink/public/web/modules/serviceworker/web_service_worker_context_client.h"
-#include "third_party/blink/public/web/modules/serviceworker/web_service_worker_context_proxy.h"
+#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h"
+#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h"
using blink::WebURLRequest;
using blink::MessagePortChannel;
@@ -117,21 +119,26 @@ class WebServiceWorkerNetworkProviderImpl
std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
const WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
+ std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle>
+ task_runner_handle) override {
RenderThreadImpl* render_thread = RenderThreadImpl::current();
if (render_thread && provider_->script_loader_factory() &&
- ServiceWorkerUtils::IsServicificationEnabled() &&
+ blink::ServiceWorkerUtils::IsServicificationEnabled() &&
IsScriptRequest(request)) {
// TODO(crbug.com/796425): Temporarily wrap the raw
// mojom::URLLoaderFactory pointer into SharedURLLoaderFactory.
return std::make_unique<WebURLLoaderImpl>(
- render_thread->resource_dispatcher(), std::move(task_runner),
+ render_thread->resource_dispatcher(), std::move(task_runner_handle),
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
provider_->script_loader_factory()));
}
return nullptr;
}
+ network::mojom::URLLoaderFactory* script_loader_factory() {
+ return provider_->script_loader_factory();
+ }
+
int ProviderID() const override { return provider_->provider_id(); }
private:
@@ -208,7 +215,7 @@ void ToWebServiceWorkerRequest(const network::ResourceRequest& request,
}
// S13nServiceWorker: The body is provided in |request|.
else if (request.request_body) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
// |blob_ptrs| should be empty when Network Service is enabled.
DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService) ||
blob_ptrs.empty());
@@ -238,6 +245,8 @@ void ToWebServiceWorkerRequest(const network::ResourceRequest& request,
web_request->SetIntegrity(
blink::WebString::FromUTF8(request.fetch_integrity));
web_request->SetKeepalive(request.keepalive);
+ web_request->SetIsHistoryNavigation(request.transition_type &
+ ui::PAGE_TRANSITION_FORWARD_BACK);
}
// Converts the |request| to its equivalent type in the Blink API.
@@ -267,6 +276,7 @@ void ToWebServiceWorkerRequest(const ServiceWorkerFetchRequest& request,
web_request->SetIsReload(request.is_reload);
web_request->SetIntegrity(blink::WebString::FromUTF8(request.integrity));
web_request->SetKeepalive(request.keepalive);
+ web_request->SetIsHistoryNavigation(request.is_history_navigation);
}
// Converts |response| to its equivalent type in the Blink API.
@@ -453,7 +463,7 @@ void DidNavigateClient(
// worker thread.
struct ServiceWorkerContextClient::WorkerContextData {
explicit WorkerContextData(ServiceWorkerContextClient* owner)
- : event_dispatcher_binding(owner),
+ : service_worker_binding(owner),
weak_factory(owner),
proxy_weak_factory(owner->proxy_) {}
@@ -464,10 +474,10 @@ struct ServiceWorkerContextClient::WorkerContextData {
// Map from version id to JavaScript ServiceWorker object.
std::map<int64_t, WebServiceWorkerImpl*> workers_;
- mojo::Binding<mojom::ServiceWorkerEventDispatcher> event_dispatcher_binding;
+ mojo::Binding<mojom::ServiceWorker> service_worker_binding;
// Bound by the first Mojo call received on the service worker thread
- // ServiceWorkerEventDispatcher::InitializeGlobalScope().
+ // ServiceWorker::InitializeGlobalScope().
blink::mojom::ServiceWorkerHostAssociatedPtr service_worker_host;
// Maps for inflight event callbacks.
@@ -535,9 +545,10 @@ struct ServiceWorkerContextClient::WorkerContextData {
class ServiceWorkerContextClient::NavigationPreloadRequest final
: public network::mojom::URLLoaderClient {
public:
- NavigationPreloadRequest(int fetch_event_id,
- const GURL& url,
- mojom::FetchEventPreloadHandlePtr preload_handle)
+ NavigationPreloadRequest(
+ int fetch_event_id,
+ const GURL& url,
+ blink::mojom::FetchEventPreloadHandlePtr preload_handle)
: fetch_event_id_(fetch_event_id),
url_(url),
url_loader_(std::move(preload_handle->url_loader)),
@@ -546,10 +557,8 @@ class ServiceWorkerContextClient::NavigationPreloadRequest final
~NavigationPreloadRequest() override {}
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override {
+ const network::ResourceResponseHead& response_head) override {
DCHECK(!response_);
- DCHECK(!downloaded_file);
response_ = std::make_unique<blink::WebURLResponse>();
// TODO(horo): Set report_security_info to true when DevTools is attached.
const bool report_security_info = false;
@@ -581,11 +590,6 @@ class ServiceWorkerContextClient::NavigationPreloadRequest final
0 /* decoded_body_length */);
}
- void OnDataDownloaded(int64_t data_length,
- int64_t encoded_data_length) override {
- NOTREACHED();
- }
-
void OnUploadProgress(int64_t current_position,
int64_t total_size,
OnUploadProgressCallback ack_callback) override {
@@ -693,22 +697,27 @@ ServiceWorkerContextClient::ServiceWorkerContextClient(
int64_t service_worker_version_id,
const GURL& service_worker_scope,
const GURL& script_url,
- bool is_script_streaming,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ bool is_starting_installed_worker,
+ RendererPreferences renderer_preferences,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
std::unique_ptr<EmbeddedWorkerInstanceClientImpl> embedded_worker_client,
+ mojom::EmbeddedWorkerStartTimingPtr start_timing,
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
: embedded_worker_id_(embedded_worker_id),
service_worker_version_id_(service_worker_version_id),
service_worker_scope_(service_worker_scope),
script_url_(script_url),
+ is_starting_installed_worker_(is_starting_installed_worker),
+ renderer_preferences_(std::move(renderer_preferences)),
main_thread_task_runner_(std::move(main_thread_task_runner)),
proxy_(nullptr),
- pending_dispatcher_request_(std::move(dispatcher_request)),
+ pending_service_worker_request_(std::move(service_worker_request)),
pending_controller_request_(std::move(controller_request)),
- embedded_worker_client_(std::move(embedded_worker_client)) {
+ embedded_worker_client_(std::move(embedded_worker_client)),
+ start_timing_(std::move(start_timing)) {
instance_host_ =
mojom::ThreadSafeEmbeddedWorkerInstanceHostAssociatedPtr::Create(
std::move(instance_host), main_thread_task_runner_);
@@ -724,7 +733,8 @@ ServiceWorkerContextClient::ServiceWorkerContextClient(
"script_url", script_url_.spec());
TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
"ServiceWorker", "LOAD_SCRIPT", this, "Source",
- (is_script_streaming ? "InstalledScriptsManager" : "ResourceLoader"));
+ (is_starting_installed_worker_ ? "InstalledScriptsManager"
+ : "ResourceLoader"));
}
ServiceWorkerContextClient::~ServiceWorkerContextClient() {}
@@ -798,7 +808,6 @@ void ServiceWorkerContextClient::WorkerContextFailedToStart() {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
DCHECK(!proxy_);
- (*instance_host_)->OnScriptLoadFailed();
(*instance_host_)->OnStopped();
TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker", "ServiceWorkerContextClient",
@@ -809,7 +818,8 @@ void ServiceWorkerContextClient::WorkerContextFailedToStart() {
}
void ServiceWorkerContextClient::WorkerScriptLoaded() {
- (*instance_host_)->OnScriptLoaded();
+ if (!is_starting_installed_worker_)
+ (*instance_host_)->OnScriptLoaded();
TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "LOAD_SCRIPT", this);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "START_WORKER_CONTEXT",
this);
@@ -832,38 +842,48 @@ void ServiceWorkerContextClient::WorkerContextStarted(
// willDestroyWorkerContext.
context_.reset(new WorkerContextData(this));
- DCHECK(pending_dispatcher_request_.is_pending());
+ DCHECK(pending_service_worker_request_.is_pending());
DCHECK(pending_controller_request_.is_pending());
- DCHECK(!context_->event_dispatcher_binding.is_bound());
+ DCHECK(!context_->service_worker_binding.is_bound());
DCHECK(!context_->controller_impl);
- context_->event_dispatcher_binding.Bind(
- std::move(pending_dispatcher_request_));
+ context_->service_worker_binding.Bind(
+ std::move(pending_service_worker_request_));
- if (ServiceWorkerUtils::IsServicificationEnabled()) {
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
context_->controller_impl = std::make_unique<ControllerServiceWorkerImpl>(
std::move(pending_controller_request_), GetWeakPtr());
}
- (*instance_host_)->OnThreadStarted(WorkerThread::GetCurrentId());
-
TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "START_WORKER_CONTEXT",
this);
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "EVALUATE_SCRIPT", this);
}
+void ServiceWorkerContextClient::WillEvaluateClassicScript() {
+ DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
+ start_timing_->script_evaluation_start_time = base::TimeTicks::Now();
+ (*instance_host_)->OnScriptEvaluationStart();
+}
+
void ServiceWorkerContextClient::DidEvaluateClassicScript(bool success) {
DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
- (*instance_host_)->OnScriptEvaluated(success);
+ start_timing_->script_evaluation_end_time = base::TimeTicks::Now();
- // Schedule a task to send back WorkerStarted asynchronously,
- // so that at the time we send it we can be sure that the
- // worker run loop has been started.
+ blink::mojom::ServiceWorkerStartStatus status =
+ success ? blink::mojom::ServiceWorkerStartStatus::kNormalCompletion
+ : blink::mojom::ServiceWorkerStartStatus::kAbruptCompletion;
+
+ // Schedule a task to send back WorkerStarted asynchronously, so we can be
+ // sure that the worker is really started.
+ // TODO(falken): Is this really needed? Probably if kNormalCompletion, the
+ // worker is definitely running so we can SendStartWorker immediately.
worker_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&ServiceWorkerContextClient::SendWorkerStarted,
- GetWeakPtr()));
+ GetWeakPtr(), status));
TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker", "EVALUATE_SCRIPT", this,
- "Status", success ? "Success" : "Failure");
+ "Status",
+ ServiceWorkerUtils::MojoEnumToString(status));
}
void ServiceWorkerContextClient::DidInitializeWorkerContext(
@@ -951,6 +971,10 @@ void ServiceWorkerContextClient::DidHandleActivateEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleActivateEvent", "event_id",
+ request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->activate_event_callbacks,
context_->timeout_timer.get(), request_id, status,
base::Time::FromDoubleT(event_dispatch_time));
@@ -960,6 +984,10 @@ void ServiceWorkerContextClient::DidHandleBackgroundFetchAbortEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleBackgroundFetchAbortEvent",
+ "event_id", request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->background_fetch_abort_event_callbacks,
context_->timeout_timer.get(), request_id, status,
base::Time::FromDoubleT(event_dispatch_time));
@@ -969,6 +997,10 @@ void ServiceWorkerContextClient::DidHandleBackgroundFetchClickEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleBackgroundFetchClickEvent",
+ "event_id", request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->background_fetch_click_event_callbacks,
context_->timeout_timer.get(), request_id, status,
base::Time::FromDoubleT(event_dispatch_time));
@@ -978,6 +1010,10 @@ void ServiceWorkerContextClient::DidHandleBackgroundFetchFailEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleBackgroundFetchFailEvent",
+ "event_id", request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->background_fetch_fail_event_callbacks,
context_->timeout_timer.get(), request_id, status,
base::Time::FromDoubleT(event_dispatch_time));
@@ -987,6 +1023,10 @@ void ServiceWorkerContextClient::DidHandleBackgroundFetchedEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleBackgroundFetchedEvent",
+ "event_id", request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->background_fetched_event_callbacks,
context_->timeout_timer.get(), request_id, status,
base::Time::FromDoubleT(event_dispatch_time));
@@ -996,6 +1036,10 @@ void ServiceWorkerContextClient::DidHandleCookieChangeEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleCookieChangeEvent",
+ "event_id", request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->cookie_change_event_callbacks,
context_->timeout_timer.get(), request_id, status,
base::Time::FromDoubleT(event_dispatch_time));
@@ -1005,6 +1049,10 @@ void ServiceWorkerContextClient::DidHandleExtendableMessageEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleExtendableMessageEvent",
+ "event_id", request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->message_event_callbacks,
context_->timeout_timer.get(), request_id, status,
base::Time::FromDoubleT(event_dispatch_time));
@@ -1014,6 +1062,10 @@ void ServiceWorkerContextClient::DidHandleInstallEvent(
int event_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleInstallEvent", "event_id",
+ event_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->install_event_callbacks,
context_->timeout_timer.get(), event_id, status,
proxy_->HasFetchEventHandler(),
@@ -1023,6 +1075,9 @@ void ServiceWorkerContextClient::DidHandleInstallEvent(
void ServiceWorkerContextClient::RespondToFetchEventWithNoResponse(
int fetch_event_id,
double event_dispatch_time) {
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::RespondToFetchEventWithNoResponse",
+ "event_id", fetch_event_id);
DCHECK(base::ContainsKey(context_->fetch_response_callbacks, fetch_event_id));
const mojom::ServiceWorkerFetchResponseCallbackPtr& response_callback =
context_->fetch_response_callbacks[fetch_event_id];
@@ -1035,6 +1090,9 @@ void ServiceWorkerContextClient::RespondToFetchEvent(
int fetch_event_id,
const blink::WebServiceWorkerResponse& web_response,
double event_dispatch_time) {
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::RespondToFetchEvent", "event_id",
+ fetch_event_id);
DCHECK(base::ContainsKey(context_->fetch_response_callbacks, fetch_event_id));
ServiceWorkerResponse response(
GetServiceWorkerResponseFromWebResponse(web_response));
@@ -1063,6 +1121,10 @@ void ServiceWorkerContextClient::RespondToFetchEventWithResponseStream(
const blink::WebServiceWorkerResponse& web_response,
blink::WebServiceWorkerStreamHandle* web_body_as_stream,
double event_dispatch_time) {
+ TRACE_EVENT1(
+ "ServiceWorker",
+ "ServiceWorkerContextClient::RespondToFetchEventWithResponseStream",
+ "event_id", fetch_event_id);
DCHECK(base::ContainsKey(context_->fetch_response_callbacks, fetch_event_id));
ServiceWorkerResponse response(
GetServiceWorkerResponseFromWebResponse(web_response));
@@ -1090,9 +1152,10 @@ void ServiceWorkerContextClient::DidHandleFetchEvent(
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",
+ TRACE_EVENT2("ServiceWorker",
"ServiceWorkerContextClient::DidHandleFetchEvent", "event_id",
- event_id);
+ event_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
if (RunEventCallback(&context_->fetch_event_callbacks,
context_->timeout_timer.get(), event_id, status,
base::Time::FromDoubleT(event_dispatch_time))) {
@@ -1104,6 +1167,10 @@ void ServiceWorkerContextClient::DidHandleNotificationClickEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleNotificationClickEvent",
+ "event_id", request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->notification_click_event_callbacks,
context_->timeout_timer.get(), request_id, status,
base::Time::FromDoubleT(event_dispatch_time));
@@ -1113,6 +1180,10 @@ void ServiceWorkerContextClient::DidHandleNotificationCloseEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleNotificationCloseEvent",
+ "event_id", request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->notification_close_event_callbacks,
context_->timeout_timer.get(), request_id, status,
base::Time::FromDoubleT(event_dispatch_time));
@@ -1122,6 +1193,10 @@ void ServiceWorkerContextClient::DidHandlePushEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandlePushEvent", "event_id",
+ request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->push_event_callbacks,
context_->timeout_timer.get(), request_id, status,
base::Time::FromDoubleT(event_dispatch_time));
@@ -1131,6 +1206,10 @@ void ServiceWorkerContextClient::DidHandleSyncEvent(
int request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleSyncEvent", "event_id",
+ request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
RunEventCallback(&context_->sync_event_callbacks,
context_->timeout_timer.get(), request_id, status,
base::Time::FromDoubleT(event_dispatch_time));
@@ -1140,6 +1219,9 @@ void ServiceWorkerContextClient::RespondToAbortPaymentEvent(
int event_id,
bool payment_aborted,
double dispatch_event_time) {
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::RespondToAbortPaymentEvent",
+ "event_id", event_id);
DCHECK(base::ContainsKey(context_->abort_payment_result_callbacks, event_id));
const payments::mojom::PaymentHandlerResponseCallbackPtr& result_callback =
context_->abort_payment_result_callbacks[event_id];
@@ -1152,6 +1234,10 @@ void ServiceWorkerContextClient::DidHandleAbortPaymentEvent(
int event_id,
blink::mojom::ServiceWorkerEventStatus status,
double dispatch_event_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleAbortPaymentEvent",
+ "event_id", event_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
if (RunEventCallback(&context_->abort_payment_event_callbacks,
context_->timeout_timer.get(), event_id, status,
base::Time::FromDoubleT(dispatch_event_time))) {
@@ -1163,6 +1249,9 @@ void ServiceWorkerContextClient::RespondToCanMakePaymentEvent(
int event_id,
bool can_make_payment,
double dispatch_event_time) {
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::RespondToCanMakePaymentEvent",
+ "event_id", event_id);
DCHECK(
base::ContainsKey(context_->can_make_payment_result_callbacks, event_id));
const payments::mojom::PaymentHandlerResponseCallbackPtr& result_callback =
@@ -1176,6 +1265,10 @@ void ServiceWorkerContextClient::DidHandleCanMakePaymentEvent(
int event_id,
blink::mojom::ServiceWorkerEventStatus status,
double dispatch_event_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandleCanMakePaymentEvent",
+ "event_id", event_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
if (RunEventCallback(&context_->can_make_payment_event_callbacks,
context_->timeout_timer.get(), event_id, status,
base::Time::FromDoubleT(dispatch_event_time))) {
@@ -1187,6 +1280,9 @@ void ServiceWorkerContextClient::RespondToPaymentRequestEvent(
int payment_request_id,
const blink::WebPaymentHandlerResponse& web_response,
double dispatch_event_time) {
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::RespondToPaymentRequestEvent",
+ "event_id", payment_request_id);
DCHECK(base::ContainsKey(context_->payment_response_callbacks,
payment_request_id));
const payments::mojom::PaymentHandlerResponseCallbackPtr& response_callback =
@@ -1204,6 +1300,10 @@ void ServiceWorkerContextClient::DidHandlePaymentRequestEvent(
int payment_request_id,
blink::mojom::ServiceWorkerEventStatus status,
double event_dispatch_time) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DidHandlePaymentRequestEvent",
+ "event_id", payment_request_id, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
if (RunEventCallback(&context_->payment_request_event_callbacks,
context_->timeout_timer.get(), payment_request_id,
status, base::Time::FromDoubleT(event_dispatch_time))) {
@@ -1219,7 +1319,8 @@ ServiceWorkerContextClient::CreateServiceWorkerNetworkProvider() {
}
std::unique_ptr<blink::WebWorkerFetchContext>
-ServiceWorkerContextClient::CreateServiceWorkerFetchContext() {
+ServiceWorkerContextClient::CreateServiceWorkerFetchContext(
+ blink::WebServiceWorkerNetworkProvider* provider) {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
scoped_refptr<ChildURLLoaderFactoryBundle> url_loader_factory_bundle =
@@ -1227,9 +1328,22 @@ ServiceWorkerContextClient::CreateServiceWorkerFetchContext() {
->blink_platform_impl()
->CreateDefaultURLLoaderFactoryBundle();
DCHECK(url_loader_factory_bundle);
+
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ script_loader_factory_info;
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled()) {
+ // TODO(crbug.com/796425): Temporarily wrap the raw
+ // mojom::URLLoaderFactory pointer into SharedURLLoaderFactory.
+ script_loader_factory_info =
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+ static_cast<WebServiceWorkerNetworkProviderImpl*>(provider)
+ ->script_loader_factory())
+ ->Clone();
+ }
+
return std::make_unique<ServiceWorkerFetchContextImpl>(
- script_url_, url_loader_factory_bundle->Clone(),
- provider_context_->provider_id(),
+ renderer_preferences_, script_url_, url_loader_factory_bundle->Clone(),
+ std::move(script_loader_factory_info), provider_context_->provider_id(),
GetContentClient()->renderer()->CreateURLLoaderThrottleProvider(
URLLoaderThrottleProviderType::kWorker),
GetContentClient()
@@ -1286,9 +1400,13 @@ void ServiceWorkerContextClient::Claim(
}
void ServiceWorkerContextClient::DispatchOrQueueFetchEvent(
- mojom::DispatchFetchEventParamsPtr params,
+ blink::mojom::DispatchFetchEventParamsPtr params,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback) {
+ TRACE_EVENT2("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchOrQueueFetchEvent", "url",
+ params->request.url.spec(), "queued",
+ RequestedTermination() ? "true" : "false");
if (RequestedTermination()) {
context_->timeout_timer->PushPendingTask(base::BindOnce(
&ServiceWorkerContextClient::DispatchFetchEvent, GetWeakPtr(),
@@ -1304,11 +1422,11 @@ void ServiceWorkerContextClient::DispatchSyncEvent(
bool last_chance,
base::TimeDelta timeout,
DispatchSyncEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchSyncEvent");
int request_id = context_->timeout_timer->StartEventWithCustomTimeout(
CreateAbortCallback(&context_->sync_event_callbacks), timeout);
context_->sync_event_callbacks.emplace(request_id, std::move(callback));
+ TRACE_EVENT1("ServiceWorker", "ServiceWorkerContextClient::DispatchSyncEvent",
+ "request_id", request_id);
// TODO(jkarlin): Make this blink::WebString::FromUTF8Lenient once
// https://crrev.com/1768063002/ lands.
@@ -1317,33 +1435,33 @@ void ServiceWorkerContextClient::DispatchSyncEvent(
}
void ServiceWorkerContextClient::DispatchAbortPaymentEvent(
- int /* event_id */, // TODO(shimazu): Remove this.
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchAbortPaymentEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchAbortPaymentEvent");
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));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchAbortPaymentEvent",
+ "event_id", event_id);
proxy_->DispatchAbortPaymentEvent(event_id);
}
void ServiceWorkerContextClient::DispatchCanMakePaymentEvent(
- int /* event_id */, // TODO(shimazu): Remove this.
payments::mojom::CanMakePaymentEventDataPtr eventData,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchCanMakePaymentEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchCanMakePaymentEvent");
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));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchCanMakePaymentEvent",
+ "event_id", event_id);
blink::WebCanMakePaymentEventData webEventData =
mojo::ConvertTo<blink::WebCanMakePaymentEventData>(std::move(eventData));
@@ -1351,31 +1469,31 @@ void ServiceWorkerContextClient::DispatchCanMakePaymentEvent(
}
void ServiceWorkerContextClient::DispatchPaymentRequestEvent(
- int /* payment_request_id */, // TODO(shimazu): Remove this.
payments::mojom::PaymentRequestEventDataPtr eventData,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchPaymentRequestEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchPaymentRequestEvent");
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));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchPaymentRequestEvent",
+ "event_id", event_id);
blink::WebPaymentRequestEventData webEventData =
mojo::ConvertTo<blink::WebPaymentRequestEventData>(std::move(eventData));
proxy_->DispatchPaymentRequestEvent(event_id, webEventData);
}
-void ServiceWorkerContextClient::SendWorkerStarted() {
+void ServiceWorkerContextClient::SendWorkerStarted(
+ blink::mojom::ServiceWorkerStartStatus status) {
DCHECK(worker_task_runner_->RunsTasksInCurrentSequence());
- mojom::EmbeddedWorkerStartTimingPtr timing =
- mojom::EmbeddedWorkerStartTiming::New();
- timing->start_worker_received_time = start_worker_received_time_;
- timing->blink_initialized_time = blink_initialized_time_;
- (*instance_host_)->OnStarted(std::move(timing));
+
+ (*instance_host_)
+ ->OnStarted(status, WorkerThread::GetCurrentId(),
+ std::move(start_timing_));
TRACE_EVENT_NESTABLE_ASYNC_END0("ServiceWorker", "ServiceWorkerContextClient",
this);
@@ -1387,11 +1505,12 @@ void ServiceWorkerContextClient::SendWorkerStarted() {
void ServiceWorkerContextClient::DispatchActivateEvent(
DispatchActivateEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchActivateEvent");
int request_id = context_->timeout_timer->StartEvent(
CreateAbortCallback(&context_->activate_event_callbacks));
context_->activate_event_callbacks.emplace(request_id, std::move(callback));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchActivateEvent",
+ "request_id", request_id);
proxy_->DispatchActivateEvent(request_id);
}
@@ -1400,12 +1519,13 @@ void ServiceWorkerContextClient::DispatchBackgroundFetchAbortEvent(
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
DispatchBackgroundFetchAbortEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchBackgroundFetchAbortEvent");
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));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchBackgroundFetchAbortEvent",
+ "request_id", request_id);
blink::WebVector<blink::WebBackgroundFetchSettledFetch> web_fetches(
fetches.size());
@@ -1423,12 +1543,13 @@ void ServiceWorkerContextClient::DispatchBackgroundFetchClickEvent(
const std::string& developer_id,
mojom::BackgroundFetchState state,
DispatchBackgroundFetchClickEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchBackgroundFetchClickEvent");
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));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchBackgroundFetchClickEvent",
+ "request_id", request_id);
// TODO(peter): Use typemap when this is moved to blink-side.
blink::WebServiceWorkerContextProxy::BackgroundFetchState web_state =
@@ -1443,12 +1564,13 @@ void ServiceWorkerContextClient::DispatchBackgroundFetchFailEvent(
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
DispatchBackgroundFetchFailEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchBackgroundFetchFailEvent");
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));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchBackgroundFetchFailEvent",
+ "request_id", request_id);
blink::WebVector<blink::WebBackgroundFetchSettledFetch> web_fetches(
fetches.size());
@@ -1467,12 +1589,13 @@ void ServiceWorkerContextClient::DispatchBackgroundFetchedEvent(
const std::string& unique_id,
const std::vector<BackgroundFetchSettledFetch>& fetches,
DispatchBackgroundFetchedEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchBackgroundFetchedEvent");
int request_id = context_->timeout_timer->StartEvent(
CreateAbortCallback(&context_->background_fetched_event_callbacks));
context_->background_fetched_event_callbacks.emplace(request_id,
std::move(callback));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchBackgroundFetchedEvent",
+ "request_id", request_id);
blink::WebVector<blink::WebBackgroundFetchSettledFetch> web_fetches(
fetches.size());
@@ -1507,23 +1630,25 @@ void ServiceWorkerContextClient::InitializeGlobalScope(
void ServiceWorkerContextClient::DispatchInstallEvent(
DispatchInstallEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchInstallEvent");
-
int event_id = context_->timeout_timer->StartEvent(CreateAbortCallback(
&context_->install_event_callbacks, false /* has_fetch_handler */));
context_->install_event_callbacks.emplace(event_id, std::move(callback));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchInstallEvent", "event_id",
+ event_id);
+
proxy_->DispatchInstallEvent(event_id);
}
void ServiceWorkerContextClient::DispatchExtendableMessageEvent(
mojom::ExtendableMessageEventPtr event,
DispatchExtendableMessageEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchExtendableMessageEvent");
int request_id = context_->timeout_timer->StartEvent(
CreateAbortCallback(&context_->message_event_callbacks));
context_->message_event_callbacks.emplace(request_id, std::move(callback));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchExtendableMessageEvent",
+ "request_id", request_id);
if (event->source_info_for_client) {
blink::WebServiceWorkerClientInfo web_client =
@@ -1545,7 +1670,7 @@ void ServiceWorkerContextClient::DispatchExtendableMessageEvent(
// S13nServiceWorker
void ServiceWorkerContextClient::DispatchFetchEvent(
- mojom::DispatchFetchEventParamsPtr params,
+ blink::mojom::DispatchFetchEventParamsPtr params,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback) {
int event_id = context_->timeout_timer->StartEvent(
@@ -1556,9 +1681,9 @@ void ServiceWorkerContextClient::DispatchFetchEvent(
// This TRACE_EVENT is used for perf benchmark to confirm if all of fetch
// events have completed. (crbug.com/736697)
- TRACE_EVENT1("ServiceWorker",
+ TRACE_EVENT2("ServiceWorker",
"ServiceWorkerContextClient::DispatchFetchEvent", "event_id",
- event_id);
+ event_id, "url", params->request.url.spec());
// Set up for navigation preload (FetchEvent#preloadResponse) if needed.
const bool navigation_preload_sent = !!params->preload_handle;
@@ -1583,13 +1708,13 @@ void ServiceWorkerContextClient::DispatchNotificationClickEvent(
int action_index,
const base::Optional<base::string16>& reply,
DispatchNotificationClickEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchNotificationClickEvent");
-
int request_id = context_->timeout_timer->StartEvent(
CreateAbortCallback(&context_->notification_click_event_callbacks));
context_->notification_click_event_callbacks.emplace(request_id,
std::move(callback));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchNotificationClickEvent",
+ "request_id", request_id);
blink::WebString web_reply;
if (reply)
@@ -1604,13 +1729,13 @@ void ServiceWorkerContextClient::DispatchNotificationCloseEvent(
const std::string& notification_id,
const PlatformNotificationData& notification_data,
DispatchNotificationCloseEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchNotificationCloseEvent");
-
int request_id = context_->timeout_timer->StartEvent(
CreateAbortCallback(&context_->notification_close_event_callbacks));
context_->notification_close_event_callbacks.emplace(request_id,
std::move(callback));
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchNotificationCloseEvent",
+ "request_id", request_id);
proxy_->DispatchNotificationCloseEvent(
request_id, blink::WebString::FromUTF8(notification_id),
ToWebNotificationData(notification_data));
@@ -1619,13 +1744,12 @@ void ServiceWorkerContextClient::DispatchNotificationCloseEvent(
void ServiceWorkerContextClient::DispatchPushEvent(
const PushEventPayload& payload,
DispatchPushEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchPushEvent");
-
int request_id = context_->timeout_timer->StartEventWithCustomTimeout(
CreateAbortCallback(&context_->push_event_callbacks),
base::TimeDelta::FromSeconds(mojom::kPushEventTimeoutSeconds));
context_->push_event_callbacks.emplace(request_id, std::move(callback));
+ TRACE_EVENT1("ServiceWorker", "ServiceWorkerContextClient::DispatchPushEvent",
+ "request_id", request_id);
// Only set data to be a valid string if the payload had decrypted data.
blink::WebString data;
@@ -1638,21 +1762,29 @@ void ServiceWorkerContextClient::DispatchCookieChangeEvent(
const net::CanonicalCookie& cookie,
::network::mojom::CookieChangeCause cause,
DispatchCookieChangeEventCallback callback) {
- TRACE_EVENT0("ServiceWorker",
- "ServiceWorkerContextClient::DispatchCookieChangeEvent");
-
int request_id = context_->timeout_timer->StartEvent(
CreateAbortCallback(&context_->cookie_change_event_callbacks));
context_->cookie_change_event_callbacks.emplace(request_id,
std::move(callback));
-
- // TODO(pwnall): Map |cause| to a blink enum. Currently, a cookie overwrite
- // shows up as delete + insert.
- bool is_cookie_delete =
- cause != ::network::mojom::CookieChangeCause::INSERTED;
- proxy_->DispatchCookieChangeEvent(
- request_id, blink::WebString::FromUTF8(cookie.Name()),
- blink::WebString::FromUTF8(cookie.Value()), is_cookie_delete);
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::DispatchCookieChangeEvent",
+ "request_id", request_id);
+
+ // After onion-souping, the conversion below will be done by mojo directly.
+ DCHECK(!cookie.IsHttpOnly());
+ base::Optional<blink::WebCanonicalCookie> web_cookie_opt =
+ blink::WebCanonicalCookie::Create(
+ blink::WebString::FromUTF8(cookie.Name()),
+ blink::WebString::FromUTF8(cookie.Value()),
+ blink::WebString::FromUTF8(cookie.Domain()),
+ blink::WebString::FromUTF8(cookie.Path()), cookie.CreationDate(),
+ cookie.ExpiryDate(), cookie.LastAccessDate(), cookie.IsSecure(),
+ false /* cookie.IsHttpOnly() */,
+ static_cast<network::mojom::CookieSameSite>(cookie.SameSite()),
+ static_cast<network::mojom::CookiePriority>(cookie.Priority()));
+ DCHECK(web_cookie_opt.has_value());
+
+ proxy_->DispatchCookieChangeEvent(request_id, web_cookie_opt.value(), cause);
}
void ServiceWorkerContextClient::Ping(PingCallback callback) {
@@ -1660,7 +1792,7 @@ void ServiceWorkerContextClient::Ping(PingCallback callback) {
}
void ServiceWorkerContextClient::SetIdleTimerDelayToZero() {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
DCHECK(context_);
DCHECK(context_->timeout_timer);
context_->timeout_timer->SetIdleTimerDelayToZero();
@@ -1670,6 +1802,9 @@ void ServiceWorkerContextClient::OnNavigationPreloadResponse(
int fetch_event_id,
std::unique_ptr<blink::WebURLResponse> response,
std::unique_ptr<blink::WebDataConsumerHandle> data_consumer_handle) {
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::OnNavigationPreloadResponse",
+ "event_id", fetch_event_id);
proxy_->OnNavigationPreloadResponse(fetch_event_id, std::move(response),
std::move(data_consumer_handle));
}
@@ -1677,6 +1812,9 @@ void ServiceWorkerContextClient::OnNavigationPreloadResponse(
void ServiceWorkerContextClient::OnNavigationPreloadError(
int fetch_event_id,
std::unique_ptr<blink::WebServiceWorkerError> error) {
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::OnNavigationPreloadError",
+ "event_id", fetch_event_id);
proxy_->OnNavigationPreloadError(fetch_event_id, std::move(error));
context_->preload_requests.Remove(fetch_event_id);
}
@@ -1687,6 +1825,9 @@ void ServiceWorkerContextClient::OnNavigationPreloadComplete(
int64_t encoded_data_length,
int64_t encoded_body_length,
int64_t decoded_body_length) {
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerContextClient::OnNavigationPreloadComplete",
+ "event_id", fetch_event_id);
proxy_->OnNavigationPreloadComplete(fetch_event_id, completion_time,
encoded_data_length, encoded_body_length,
decoded_body_length);
@@ -1696,7 +1837,7 @@ void ServiceWorkerContextClient::OnNavigationPreloadComplete(
void ServiceWorkerContextClient::SetupNavigationPreload(
int fetch_event_id,
const GURL& url,
- mojom::FetchEventPreloadHandlePtr preload_handle) {
+ blink::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),
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 61085729f81..b48aa9a8847 100644
--- a/chromium/content/renderer/service_worker/service_worker_context_client.h
+++ b/chromium/content/renderer/service_worker/service_worker_context_client.h
@@ -21,21 +21,21 @@
#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.mojom.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/common/service_worker/service_worker_types.h"
#include "ipc/ipc_listener.h"
#include "mojo/public/cpp/bindings/binding.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
#include "third_party/blink/public/platform/modules/payments/payment_app.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_error.h"
-#include "third_party/blink/public/web/modules/serviceworker/web_service_worker_context_client.h"
-#include "third_party/blink/public/web/modules/serviceworker/web_service_worker_context_proxy.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
+#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h"
+#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h"
#include "v8/include/v8.h"
namespace base {
@@ -73,38 +73,35 @@ class WebWorkerFetchContext;
// called on the worker thread.
class CONTENT_EXPORT ServiceWorkerContextClient
: public blink::WebServiceWorkerContextClient,
- public mojom::ServiceWorkerEventDispatcher {
+ public mojom::ServiceWorker {
public:
// Returns a thread-specific client instance. This does NOT create a
// new instance.
static ServiceWorkerContextClient* ThreadSpecificInstance();
// Called on the main thread.
- // |is_script_streaming| is true if the script is already installed and will
- // be streamed from the browser process.
+ // |is_starting_installed_worker| is true if the script is already installed
+ // and will be streamed from the browser process.
+ //
+ // |start_timing| should be initially populated with
+ // |start_worker_received_time|. This instance will fill in the rest during
+ // startup.
ServiceWorkerContextClient(
int embedded_worker_id,
int64_t service_worker_version_id,
const GURL& service_worker_scope,
const GURL& script_url,
- bool is_script_streaming,
- mojom::ServiceWorkerEventDispatcherRequest dispatcher_request,
+ bool is_starting_installed_worker,
+ RendererPreferences renderer_preferences,
+ mojom::ServiceWorkerRequest service_worker_request,
mojom::ControllerServiceWorkerRequest controller_request,
mojom::EmbeddedWorkerInstanceHostAssociatedPtrInfo instance_host,
mojom::ServiceWorkerProviderInfoForStartWorkerPtr provider_info,
std::unique_ptr<EmbeddedWorkerInstanceClientImpl> embedded_worker_client,
+ mojom::EmbeddedWorkerStartTimingPtr start_timing,
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
~ServiceWorkerContextClient() override;
- // Called on the main thread.
- void set_blink_initialized_time(base::TimeTicks blink_initialized_time) {
- blink_initialized_time_ = blink_initialized_time;
- }
- void set_start_worker_received_time(
- base::TimeTicks start_worker_received_time) {
- start_worker_received_time_ = start_worker_received_time;
- }
-
// Returns the service worker object described by |info|. Creates a new object
// if needed, or else returns the existing one.
scoped_refptr<WebServiceWorkerImpl> GetOrCreateServiceWorkerObject(
@@ -132,6 +129,7 @@ class CONTENT_EXPORT ServiceWorkerContextClient
void WorkerScriptLoaded() override;
void WorkerContextStarted(
blink::WebServiceWorkerContextProxy* proxy) override;
+ void WillEvaluateClassicScript() override;
void DidEvaluateClassicScript(bool success) override;
void DidInitializeWorkerContext(v8::Local<v8::Context> context) override;
void WillDestroyWorkerContext(v8::Local<v8::Context> context) override;
@@ -225,8 +223,8 @@ class CONTENT_EXPORT ServiceWorkerContextClient
double dispatch_event_time) override;
std::unique_ptr<blink::WebServiceWorkerNetworkProvider>
CreateServiceWorkerNetworkProvider() override;
- std::unique_ptr<blink::WebWorkerFetchContext>
- CreateServiceWorkerFetchContext() override;
+ std::unique_ptr<blink::WebWorkerFetchContext> CreateServiceWorkerFetchContext(
+ blink::WebServiceWorkerNetworkProvider*) override;
std::unique_ptr<blink::WebServiceWorkerProvider> CreateServiceWorkerProvider()
override;
void PostMessageToClient(const blink::WebString& uuid,
@@ -251,7 +249,7 @@ class CONTENT_EXPORT ServiceWorkerContextClient
// This method needs to be used only if the event comes directly from a
// client, which means it is coming through the ControllerServiceWorkerImpl.
void DispatchOrQueueFetchEvent(
- mojom::DispatchFetchEventParamsPtr params,
+ blink::mojom::DispatchFetchEventParamsPtr params,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback);
@@ -274,9 +272,9 @@ class CONTENT_EXPORT ServiceWorkerContextClient
// in the browser process.
int GetRoutingID() const { return embedded_worker_id_; }
- void SendWorkerStarted();
+ void SendWorkerStarted(blink::mojom::ServiceWorkerStartStatus status);
- // Implements mojom::ServiceWorkerEventDispatcher.
+ // Implements mojom::ServiceWorker.
void InitializeGlobalScope(
blink::mojom::ServiceWorkerHostAssociatedPtrInfo service_worker_host,
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info)
@@ -307,7 +305,7 @@ class CONTENT_EXPORT ServiceWorkerContextClient
mojom::ExtendableMessageEventPtr event,
DispatchExtendableMessageEventCallback callback) override;
void DispatchFetchEvent(
- mojom::DispatchFetchEventParamsPtr params,
+ blink::mojom::DispatchFetchEventParamsPtr params,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback) override;
void DispatchNotificationClickEvent(
@@ -327,16 +325,13 @@ class CONTENT_EXPORT ServiceWorkerContextClient
base::TimeDelta timeout,
DispatchSyncEventCallback callback) override;
void DispatchAbortPaymentEvent(
- int payment_request_id,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchAbortPaymentEventCallback callback) override;
void DispatchCanMakePaymentEvent(
- int payment_request_id,
payments::mojom::CanMakePaymentEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchCanMakePaymentEventCallback callback) override;
void DispatchPaymentRequestEvent(
- int payment_request_id,
payments::mojom::PaymentRequestEventDataPtr event_data,
payments::mojom::PaymentHandlerResponseCallbackPtr response_callback,
DispatchPaymentRequestEventCallback callback) override;
@@ -384,9 +379,10 @@ class CONTENT_EXPORT ServiceWorkerContextClient
int fetch_event_id,
std::unique_ptr<blink::WebServiceWorkerError> error);
- void SetupNavigationPreload(int fetch_event_id,
- const GURL& url,
- mojom::FetchEventPreloadHandlePtr preload_handle);
+ void SetupNavigationPreload(
+ int fetch_event_id,
+ const GURL& url,
+ blink::mojom::FetchEventPreloadHandlePtr preload_handle);
// Called by ServiceWorkerTimeoutTimer when a certain time has passed since
// the last task finished.
@@ -411,6 +407,11 @@ class CONTENT_EXPORT ServiceWorkerContextClient
const int64_t service_worker_version_id_;
const GURL service_worker_scope_;
const GURL script_url_;
+ // True if this service worker was already installed at worker
+ // startup time.
+ const bool is_starting_installed_worker_;
+
+ RendererPreferences renderer_preferences_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
scoped_refptr<base::TaskRunner> worker_task_runner_;
@@ -421,7 +422,7 @@ class CONTENT_EXPORT ServiceWorkerContextClient
blink::WebServiceWorkerContextProxy* proxy_;
// These Mojo objects are bound on the worker thread.
- mojom::ServiceWorkerEventDispatcherRequest pending_dispatcher_request_;
+ mojom::ServiceWorkerRequest pending_service_worker_request_;
mojom::ControllerServiceWorkerRequest pending_controller_request_;
// This is bound on the main thread.
@@ -441,8 +442,9 @@ class CONTENT_EXPORT ServiceWorkerContextClient
// destructed on the worker thread in willDestroyWorkerContext.
std::unique_ptr<WorkerContextData> context_;
- base::TimeTicks blink_initialized_time_;
- base::TimeTicks start_worker_received_time_;
+ // Accessed on the worker thread. Passed to the browser process after worker
+ // startup completes.
+ mojom::EmbeddedWorkerStartTimingPtr start_timing_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContextClient);
};
diff --git a/chromium/content/renderer/service_worker/service_worker_context_client_unittest.cc b/chromium/content/renderer/service_worker/service_worker_context_client_unittest.cc
index d9fbfee4759..fbd3fceab5d 100644
--- a/chromium/content/renderer/service_worker/service_worker_context_client_unittest.cc
+++ b/chromium/content/renderer/service_worker/service_worker_context_client_unittest.cc
@@ -14,7 +14,6 @@
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "content/child/thread_safe_sender.h"
-#include "content/common/service_worker/service_worker_utils.h"
#include "content/renderer/service_worker/embedded_worker_instance_client_impl.h"
#include "content/renderer/service_worker/service_worker_timeout_timer.h"
#include "content/renderer/service_worker/web_service_worker_impl.h"
@@ -25,18 +24,19 @@
#include "services/network/public/cpp/resource_request.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
#include "third_party/blink/public/platform/modules/background_fetch/web_background_fetch_settled_fetch.h"
#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h"
#include "third_party/blink/public/platform/modules/payments/web_payment_request_event_data.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_clients_info.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_error.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_request.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_clients_info.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h"
#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_data_consumer_handle.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url_response.h"
-#include "third_party/blink/public/web/modules/serviceworker/web_service_worker_context_proxy.h"
+#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h"
namespace content {
@@ -45,7 +45,7 @@ namespace {
// Pipes connected to the context client.
struct ContextClientPipes {
// From the browser to ServiceWorkerContextClient.
- mojom::ServiceWorkerEventDispatcherPtr event_dispatcher;
+ mojom::ServiceWorkerPtr service_worker;
mojom::ControllerServiceWorkerPtr controller;
blink::mojom::ServiceWorkerRegistrationObjectAssociatedPtr registration;
@@ -105,10 +105,10 @@ class MockWebServiceWorkerContextProxy
override {
NOTREACHED();
}
- void DispatchCookieChangeEvent(int event_id,
- const blink::WebString& name,
- const blink::WebString& value,
- bool is_deleted) override {
+ void DispatchCookieChangeEvent(
+ int event_id,
+ const blink::WebCanonicalCookie& cookie,
+ ::network::mojom::CookieChangeCause change_cause) override {
NOTREACHED();
}
void DispatchExtendableMessageEvent(
@@ -245,11 +245,12 @@ class ServiceWorkerContextClientTest : public testing::Test {
ServiceWorkerContextClient::ResetThreadSpecificInstanceForTesting();
// Unregister this thread from worker threads.
WorkerThreadRegistry::Instance()->WillStopCurrentWorkerThread();
+ task_runner_->RunUntilIdle();
}
void EnableServicification() {
feature_list_.InitWithFeatures({network::features::kNetworkService}, {});
- ASSERT_TRUE(ServiceWorkerUtils::IsServicificationEnabled());
+ ASSERT_TRUE(blink::ServiceWorkerUtils::IsServicificationEnabled());
}
// Creates an empty struct to initialize ServiceWorkerProviderContext.
@@ -264,8 +265,7 @@ class ServiceWorkerContextClientTest : public testing::Test {
std::unique_ptr<ServiceWorkerContextClient> CreateContextClient(
ContextClientPipes* out_pipes,
blink::WebServiceWorkerContextProxy* proxy) {
- auto event_dispatcher_request =
- mojo::MakeRequest(&out_pipes->event_dispatcher);
+ auto service_worker_request = mojo::MakeRequest(&out_pipes->service_worker);
auto controller_request = mojo::MakeRequest(&out_pipes->controller);
mojom::EmbeddedWorkerInstanceHostAssociatedPtr embedded_worker_host_ptr;
out_pipes->embedded_worker_host_request =
@@ -276,9 +276,11 @@ class ServiceWorkerContextClientTest : public testing::Test {
std::make_unique<ServiceWorkerContextClient>(
1 /* embedded_worker_id */, 1 /* service_worker_version_id */,
kScope, kScript, false /* is_script_streaming */,
- std::move(event_dispatcher_request), std::move(controller_request),
+ RendererPreferences(), std::move(service_worker_request),
+ std::move(controller_request),
embedded_worker_host_ptr.PassInterface(), CreateProviderInfo(),
nullptr /* embedded_worker_client */,
+ mojom::EmbeddedWorkerStartTiming::New(),
blink::scheduler::GetSingleThreadTaskRunnerForTesting());
context_client->WorkerContextStarted(proxy);
@@ -295,7 +297,7 @@ class ServiceWorkerContextClientTest : public testing::Test {
out_pipes->registration_host_request =
mojo::MakeRequest(&registration_info->host_ptr_info);
registration_info->request = mojo::MakeRequest(&out_pipes->registration);
- out_pipes->event_dispatcher->InitializeGlobalScope(
+ out_pipes->service_worker->InitializeGlobalScope(
std::move(service_worker_host), std::move(registration_info));
task_runner()->RunUntilIdle();
return context_client;
@@ -323,7 +325,7 @@ TEST_F(ServiceWorkerContextClientTest, Ping) {
CreateContextClient(&pipes, &mock_proxy);
bool is_called = false;
- pipes.event_dispatcher->Ping(CreateCallbackWithCalledFlag(&is_called));
+ pipes.service_worker->Ping(CreateCallbackWithCalledFlag(&is_called));
task_runner()->RunUntilIdle();
EXPECT_TRUE(is_called);
}
@@ -343,9 +345,9 @@ TEST_F(ServiceWorkerContextClientTest, DispatchFetchEvent) {
request->url = expected_url;
mojom::ServiceWorkerFetchResponseCallbackPtr fetch_callback_ptr;
fetch_callback_request = mojo::MakeRequest(&fetch_callback_ptr);
- auto params = mojom::DispatchFetchEventParams::New();
+ auto params = blink::mojom::DispatchFetchEventParams::New();
params->request = *request;
- pipes.event_dispatcher->DispatchFetchEvent(
+ pipes.service_worker->DispatchFetchEvent(
std::move(params), std::move(fetch_callback_ptr),
base::BindOnce(
[](blink::mojom::ServiceWorkerEventStatus, base::Time) {}));
@@ -380,7 +382,7 @@ TEST_F(ServiceWorkerContextClientTest,
mojo::MakeRequest(&fetch_callback_ptr);
auto request = std::make_unique<network::ResourceRequest>();
request->url = expected_url;
- auto params = mojom::DispatchFetchEventParams::New();
+ auto params = blink::mojom::DispatchFetchEventParams::New();
params->request = *request;
context_client->DispatchOrQueueFetchEvent(
std::move(params), std::move(fetch_callback_ptr),
@@ -428,7 +430,7 @@ TEST_F(ServiceWorkerContextClientTest,
fetch_callback_request = mojo::MakeRequest(&fetch_callback_ptr);
auto request = std::make_unique<network::ResourceRequest>();
request->url = expected_url;
- auto params = mojom::DispatchFetchEventParams::New();
+ auto params = blink::mojom::DispatchFetchEventParams::New();
params->request = *request;
pipes.controller->DispatchFetchEvent(
std::move(params), std::move(fetch_callback_ptr),
@@ -477,7 +479,7 @@ TEST_F(ServiceWorkerContextClientTest,
fetch_callback_request_1 = mojo::MakeRequest(&fetch_callback_ptr);
auto request = std::make_unique<network::ResourceRequest>();
request->url = expected_url_1;
- auto params = mojom::DispatchFetchEventParams::New();
+ auto params = blink::mojom::DispatchFetchEventParams::New();
params->request = *request;
pipes.controller->DispatchFetchEvent(
std::move(params), std::move(fetch_callback_ptr),
@@ -487,16 +489,16 @@ TEST_F(ServiceWorkerContextClientTest,
}
EXPECT_TRUE(mock_proxy.fetch_events().empty());
- // Another event dispatched to mojom::ServiceWorkerEventDispatcher wakes up
+ // Another event dispatched to mojom::ServiceWorker wakes up
// the context client.
{
mojom::ServiceWorkerFetchResponseCallbackPtr fetch_callback_ptr;
fetch_callback_request_2 = mojo::MakeRequest(&fetch_callback_ptr);
auto request = std::make_unique<network::ResourceRequest>();
request->url = expected_url_2;
- auto params = mojom::DispatchFetchEventParams::New();
+ auto params = blink::mojom::DispatchFetchEventParams::New();
params->request = *request;
- pipes.event_dispatcher->DispatchFetchEvent(
+ pipes.service_worker->DispatchFetchEvent(
std::move(params), std::move(fetch_callback_ptr),
base::BindOnce(
[](blink::mojom::ServiceWorkerEventStatus, base::Time) {}));
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 f432fa6d2e4..5cdaab338f6 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,6 +5,7 @@
#include "content/renderer/service_worker/service_worker_fetch_context_impl.h"
#include "base/feature_list.h"
+#include "content/common/content_constants_internal.h"
#include "content/public/common/content_features.h"
#include "content/public/renderer/url_loader_throttle_provider.h"
#include "content/public/renderer/websocket_handshake_throttle_provider.h"
@@ -18,15 +19,20 @@
namespace content {
ServiceWorkerFetchContextImpl::ServiceWorkerFetchContextImpl(
+ RendererPreferences renderer_preferences,
const GURL& worker_script_url,
std::unique_ptr<network::SharedURLLoaderFactoryInfo>
url_loader_factory_info,
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ script_loader_factory_info,
int service_worker_provider_id,
std::unique_ptr<URLLoaderThrottleProvider> throttle_provider,
std::unique_ptr<WebSocketHandshakeThrottleProvider>
websocket_handshake_throttle_provider)
- : worker_script_url_(worker_script_url),
+ : renderer_preferences_(std::move(renderer_preferences)),
+ worker_script_url_(worker_script_url),
url_loader_factory_info_(std::move(url_loader_factory_info)),
+ script_loader_factory_info_(std::move(script_loader_factory_info)),
service_worker_provider_id_(service_worker_provider_id),
throttle_provider_(std::move(throttle_provider)),
websocket_handshake_throttle_provider_(
@@ -47,6 +53,10 @@ void ServiceWorkerFetchContextImpl::InitializeOnWorkerThread() {
url_loader_factory_ = network::SharedURLLoaderFactory::Create(
std::move(url_loader_factory_info_));
+ if (script_loader_factory_info_) {
+ script_loader_factory_ = network::SharedURLLoaderFactory::Create(
+ std::move(script_loader_factory_info_));
+ }
}
std::unique_ptr<blink::WebURLLoaderFactory>
@@ -67,8 +77,20 @@ ServiceWorkerFetchContextImpl::WrapURLLoaderFactory(
network::mojom::URLLoaderFactory::Version_)));
}
+std::unique_ptr<blink::WebURLLoaderFactory>
+ServiceWorkerFetchContextImpl::CreateScriptLoaderFactory() {
+ if (!script_loader_factory_)
+ return nullptr;
+ return std::make_unique<content::WebURLLoaderFactoryImpl>(
+ resource_dispatcher_->GetWeakPtr(), std::move(script_loader_factory_));
+}
+
void ServiceWorkerFetchContextImpl::WillSendRequest(
blink::WebURLRequest& request) {
+ if (renderer_preferences_.enable_do_not_track) {
+ request.SetHTTPHeaderField(blink::WebString::FromUTF8(kDoNotTrackHeader),
+ "1");
+ }
auto extra_data = std::make_unique<RequestExtraData>();
extra_data->set_service_worker_provider_id(service_worker_provider_id_);
extra_data->set_originated_from_service_worker(true);
@@ -78,10 +100,16 @@ void ServiceWorkerFetchContextImpl::WillSendRequest(
MSG_ROUTING_NONE, request, WebURLRequestToResourceType(request)));
}
request.SetExtraData(std::move(extra_data));
+
+ if (!renderer_preferences_.enable_referrers) {
+ request.SetHTTPReferrer(blink::WebString(),
+ blink::kWebReferrerPolicyDefault);
+ }
}
-bool ServiceWorkerFetchContextImpl::IsControlledByServiceWorker() const {
- return false;
+blink::mojom::ControllerServiceWorkerMode
+ServiceWorkerFetchContextImpl::IsControlledByServiceWorker() const {
+ return blink::mojom::ControllerServiceWorkerMode::kNoController;
}
blink::WebURL ServiceWorkerFetchContextImpl::SiteForCookies() const {
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 8ccd9817f40..082614a85c7 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,6 +5,7 @@
#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/common/renderer_preferences.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "third_party/blink/public/platform/web_worker_fetch_context.h"
#include "url/gurl.h"
@@ -16,10 +17,20 @@ class WebSocketHandshakeThrottleProvider;
class ServiceWorkerFetchContextImpl : public blink::WebWorkerFetchContext {
public:
+ // |url_loader_factory_info| is used for regular loads from the service worker
+ // (i.e., Fetch API). It typically goes to network, but it might internally
+ // contain non-NetworkService factories for handling non-http(s) URLs like
+ // chrome-extension://.
+ // |script_loader_factory_info| is used for importScripts() from the service
+ // worker when InstalledScriptsManager doesn't have the requested script. It
+ // is a ServiceWorkerScriptLoaderFactory, which loads and installs the script.
ServiceWorkerFetchContextImpl(
+ RendererPreferences renderer_preferences,
const GURL& worker_script_url,
std::unique_ptr<network::SharedURLLoaderFactoryInfo>
url_loader_factory_info,
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ script_loader_factory_info,
int service_worker_provider_id,
std::unique_ptr<URLLoaderThrottleProvider> throttle_provider,
std::unique_ptr<WebSocketHandshakeThrottleProvider>
@@ -32,22 +43,32 @@ class ServiceWorkerFetchContextImpl : public blink::WebWorkerFetchContext {
std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory() override;
std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory(
mojo::ScopedMessagePipeHandle url_loader_factory_handle) override;
+ std::unique_ptr<blink::WebURLLoaderFactory> CreateScriptLoaderFactory()
+ override;
void WillSendRequest(blink::WebURLRequest&) override;
- bool IsControlledByServiceWorker() const override;
+ blink::mojom::ControllerServiceWorkerMode IsControlledByServiceWorker()
+ const override;
blink::WebURL SiteForCookies() const override;
std::unique_ptr<blink::WebSocketHandshakeThrottle>
CreateWebSocketHandshakeThrottle() override;
private:
+ RendererPreferences renderer_preferences_;
const GURL worker_script_url_;
// Consumed on the worker thread to create |url_loader_factory_|.
std::unique_ptr<network::SharedURLLoaderFactoryInfo> url_loader_factory_info_;
+ // Consumed on the worker thread to create |script_loader_factory_|.
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo>
+ script_loader_factory_info_;
const int service_worker_provider_id_;
// Initialized on the worker thread when InitializeOnWorkerThread() is called.
std::unique_ptr<ResourceDispatcher> resource_dispatcher_;
+ // Responsible for regular loads from the service worker (i.e., Fetch API).
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
+ // Responsible for handling importScripts().
+ scoped_refptr<network::SharedURLLoaderFactory> script_loader_factory_;
std::unique_ptr<URLLoaderThrottleProvider> throttle_provider_;
std::unique_ptr<WebSocketHandshakeThrottleProvider>
diff --git a/chromium/content/renderer/service_worker/service_worker_message_filter.cc b/chromium/content/renderer/service_worker/service_worker_message_filter.cc
deleted file mode 100644
index 1e99e493c4c..00000000000
--- a/chromium/content/renderer/service_worker/service_worker_message_filter.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/service_worker/service_worker_message_filter.h"
-
-#include <stddef.h>
-
-#include "content/common/service_worker/service_worker_messages.h"
-#include "ipc/ipc_message_macros.h"
-
-namespace content {
-
-ServiceWorkerMessageFilter::ServiceWorkerMessageFilter(
- ThreadSafeSender* sender,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
- : WorkerThreadMessageFilter(sender, std::move(main_thread_task_runner)) {}
-
-ServiceWorkerMessageFilter::~ServiceWorkerMessageFilter() {}
-
-bool ServiceWorkerMessageFilter::ShouldHandleMessage(
- const IPC::Message& msg) const {
- return IPC_MESSAGE_CLASS(msg) == ServiceWorkerMsgStart;
-}
-
-void ServiceWorkerMessageFilter::OnFilteredMessageReceived(
- const IPC::Message& 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
deleted file mode 100644
index 52cc42b69d5..00000000000
--- a/chromium/content/renderer/service_worker/service_worker_message_filter.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_MESSAGE_FILTER_H_
-#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_MESSAGE_FILTER_H_
-
-#include "base/macros.h"
-#include "base/single_thread_task_runner.h"
-#include "content/common/content_export.h"
-#include "content/renderer/worker_thread_message_filter.h"
-
-namespace content {
-
-// TODO(leonhsl): Eliminate this class since we're in a pure Mojo world now, no
-// longer need to handle any legacy IPCs.
-class CONTENT_EXPORT ServiceWorkerMessageFilter
- : public WorkerThreadMessageFilter {
- public:
- ServiceWorkerMessageFilter(
- ThreadSafeSender* thread_safe_sender,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
-
- 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/renderer/service_worker/service_worker_network_provider.cc b/chromium/content/renderer/service_worker/service_worker_network_provider.cc
index 7b64c4750ff..c3cec85dfed 100644
--- a/chromium/content/renderer/service_worker/service_worker_network_provider.cc
+++ b/chromium/content/renderer/service_worker/service_worker_network_provider.cc
@@ -8,7 +8,7 @@
#include "base/single_thread_task_runner.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_provider.mojom.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/origin_util.h"
@@ -21,8 +21,9 @@
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
#include "third_party/blink/public/common/frame/sandbox_flags.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_network_provider.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/web/web_local_frame.h"
@@ -54,7 +55,7 @@ bool IsFrameSecure(blink::WebFrame* frame) {
class WebServiceWorkerNetworkProviderForFrame
: public blink::WebServiceWorkerNetworkProvider {
public:
- WebServiceWorkerNetworkProviderForFrame(
+ explicit WebServiceWorkerNetworkProviderForFrame(
std::unique_ptr<ServiceWorkerNetworkProvider> provider)
: provider_(std::move(provider)) {}
@@ -74,14 +75,16 @@ class WebServiceWorkerNetworkProviderForFrame
network::mojom::RequestContextFrameType::kTopLevel &&
request.GetFrameType() !=
network::mojom::RequestContextFrameType::kNested &&
- !provider_->IsControlledByServiceWorker()) {
+ provider_->IsControlledByServiceWorker() ==
+ blink::mojom::ControllerServiceWorkerMode::kNoController) {
request.SetSkipServiceWorker(true);
}
}
int ProviderID() const override { return provider_->provider_id(); }
- bool HasControllerServiceWorker() override {
+ blink::mojom::ControllerServiceWorkerMode IsControlledByServiceWorker()
+ override {
return provider_->IsControlledByServiceWorker();
}
@@ -95,14 +98,15 @@ class WebServiceWorkerNetworkProviderForFrame
std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
+ std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle>
+ task_runner_handle) override {
// RenderThreadImpl is nullptr in some tests.
if (!RenderThreadImpl::current())
return nullptr;
// S13nServiceWorker:
// We only install our own URLLoader if Servicification is enabled.
- if (!ServiceWorkerUtils::IsServicificationEnabled())
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled())
return nullptr;
// We need SubresourceLoaderFactory populated in order to create our own
@@ -131,11 +135,13 @@ class WebServiceWorkerNetworkProviderForFrame
// pointer into SharedURLLoaderFactory.
return std::make_unique<WebURLLoaderImpl>(
RenderThreadImpl::current()->resource_dispatcher(),
- std::move(task_runner),
+ std::move(task_runner_handle),
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
provider_->context()->GetSubresourceLoaderFactory()));
}
+ void DispatchNetworkQuiet() override { provider_->DispatchNetworkQuiet(); }
+
private:
std::unique_ptr<ServiceWorkerNetworkProvider> provider_;
};
@@ -146,9 +152,8 @@ class WebServiceWorkerNetworkProviderForFrame
std::unique_ptr<blink::WebServiceWorkerNetworkProvider>
ServiceWorkerNetworkProvider::CreateForNavigation(
int route_id,
- const RequestNavigationParams& request_params,
+ const RequestNavigationParams* request_params,
blink::WebLocalFrame* frame,
- bool content_initiated,
mojom::ControllerServiceWorkerInfoPtr controller_info,
scoped_refptr<network::SharedURLLoaderFactory> fallback_loader_factory) {
// Determine if a ServiceWorkerNetworkProvider should be created and properly
@@ -157,13 +162,13 @@ ServiceWorkerNetworkProvider::CreateForNavigation(
// however it will have an invalid id.
bool should_create_provider = false;
int provider_id = kInvalidServiceWorkerProviderId;
- if (content_initiated) {
+ if (request_params) {
+ should_create_provider = request_params->should_create_service_worker;
+ provider_id = request_params->service_worker_provider_id;
+ } else {
should_create_provider =
((frame->EffectiveSandboxFlags() & blink::WebSandboxFlags::kOrigin) !=
blink::WebSandboxFlags::kOrigin);
- } else {
- should_create_provider = request_params.should_create_service_worker;
- provider_id = request_params.service_worker_provider_id;
}
// If we shouldn't create a real ServiceWorkerNetworkProvider, return one with
@@ -206,7 +211,7 @@ ServiceWorkerNetworkProvider::CreateForSharedWorker(
scoped_refptr<network::SharedURLLoaderFactory> fallback_loader_factory) {
// S13nServiceWorker: |info| holds info about the precreated provider host.
if (info) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
return base::WrapUnique(new ServiceWorkerNetworkProvider(
std::move(info), std::move(script_loader_factory_info),
std::move(fallback_loader_factory)));
@@ -232,7 +237,7 @@ ServiceWorkerNetworkProvider*
ServiceWorkerNetworkProvider::FromWebServiceWorkerNetworkProvider(
blink::WebServiceWorkerNetworkProvider* provider) {
if (!provider) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
return nullptr;
}
return static_cast<WebServiceWorkerNetworkProviderForFrame*>(provider)
@@ -251,9 +256,17 @@ int ServiceWorkerNetworkProvider::provider_id() const {
return context()->provider_id();
}
-bool ServiceWorkerNetworkProvider::IsControlledByServiceWorker() const {
- return context() && context()->GetControllerVersionId() !=
- blink::mojom::kInvalidServiceWorkerVersionId;
+blink::mojom::ControllerServiceWorkerMode
+ServiceWorkerNetworkProvider::IsControlledByServiceWorker() const {
+ if (!context())
+ return blink::mojom::ControllerServiceWorkerMode::kNoController;
+ return context()->IsControlledByServiceWorker();
+}
+
+void ServiceWorkerNetworkProvider::DispatchNetworkQuiet() {
+ if (!context())
+ return;
+ context()->DispatchNetworkQuiet();
}
// Creates an invalid instance (provider_id() returns
@@ -273,14 +286,15 @@ ServiceWorkerNetworkProvider::ServiceWorkerNetworkProvider(
provider_type ==
blink::mojom::ServiceWorkerProviderType::kForSharedWorker);
- ServiceWorkerProviderHostInfo host_info(provider_id, route_id, provider_type,
- is_parent_frame_secure);
+ auto host_info = mojom::ServiceWorkerProviderHostInfo::New(
+ provider_id, route_id, provider_type, is_parent_frame_secure,
+ nullptr /* host_request */, nullptr /* client_ptr_info */);
mojom::ServiceWorkerContainerAssociatedRequest client_request =
- mojo::MakeRequest(&host_info.client_ptr_info);
+ mojo::MakeRequest(&host_info->client_ptr_info);
mojom::ServiceWorkerContainerHostAssociatedPtrInfo host_ptr_info;
- host_info.host_request = mojo::MakeRequest(&host_ptr_info);
- DCHECK(host_info.host_request.is_pending());
- DCHECK(host_info.host_request.handle().is_valid());
+ host_info->host_request = mojo::MakeRequest(&host_ptr_info);
+ DCHECK(host_info->host_request.is_pending());
+ DCHECK(host_info->host_request.handle().is_valid());
// current() may be null in tests.
if (ChildThreadImpl::current()) {
diff --git a/chromium/content/renderer/service_worker/service_worker_network_provider.h b/chromium/content/renderer/service_worker/service_worker_network_provider.h
index 120b71cbdf9..ab53df97d40 100644
--- a/chromium/content/renderer/service_worker/service_worker_network_provider.h
+++ b/chromium/content/renderer/service_worker/service_worker_network_provider.h
@@ -16,7 +16,6 @@
#include "base/supports_user_data.h"
#include "content/common/content_export.h"
#include "content/common/service_worker/controller_service_worker.mojom.h"
-#include "content/common/service_worker/service_worker.mojom.h"
#include "content/common/service_worker/service_worker_provider.mojom.h"
#include "content/renderer/service_worker/service_worker_provider_context.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
@@ -60,6 +59,14 @@ class CONTENT_EXPORT ServiceWorkerNetworkProvider {
// Creates a ServiceWorkerNetworkProvider for navigation and wraps it
// with WebServiceWorkerNetworkProvider to be owned by Blink.
//
+ // |request_params| are navigation parameters that were transmitted to the
+ // renderer by the browser on a navigation commit. It is null if we have not
+ // yet heard from the browser (currently only during the time it takes from
+ // having the renderer initiate a navigation until the browser commits it).
+ // TODO(ahemery): Update this comment when do not create placeholder document
+ // loaders for renderer-initiated navigations. In this case, this should never
+ // be null.
+ //
// For S13nServiceWorker:
// |controller_info| contains the endpoint and object info that is needed to
// set up the controller service worker for the client.
@@ -70,9 +77,8 @@ class CONTENT_EXPORT ServiceWorkerNetworkProvider {
static std::unique_ptr<blink::WebServiceWorkerNetworkProvider>
CreateForNavigation(
int route_id,
- const RequestNavigationParams& request_params,
+ const RequestNavigationParams* request_params,
blink::WebLocalFrame* frame,
- bool content_initiated,
mojom::ControllerServiceWorkerInfoPtr controller_info,
scoped_refptr<network::SharedURLLoaderFactory> fallback_loader_factory);
@@ -103,7 +109,12 @@ class CONTENT_EXPORT ServiceWorkerNetworkProvider {
return script_loader_factory_.get();
}
- bool IsControlledByServiceWorker() const;
+ // Returns whether the context this provider is for is controlled by a service
+ // worker. Can be called only for providers for service worker clients.
+ blink::mojom::ControllerServiceWorkerMode IsControlledByServiceWorker() const;
+
+ // Called when blink::IdlenessDetector emits its network idle signal.
+ void DispatchNetworkQuiet();
private:
// Creates an invalid instance (provider_id() returns
diff --git a/chromium/content/renderer/service_worker/service_worker_provider_context.cc b/chromium/content/renderer/service_worker/service_worker_provider_context.cc
index e63e68b8ae2..c187d3c147e 100644
--- a/chromium/content/renderer/service_worker/service_worker_provider_context.cc
+++ b/chromium/content/renderer/service_worker/service_worker_provider_context.cc
@@ -11,10 +11,10 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
+#include "base/task_scheduler/post_task.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/renderer/service_worker/controller_service_worker_connector.h"
#include "content/renderer/service_worker/service_worker_subresource_loader.h"
@@ -27,11 +27,35 @@
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/interface_provider.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
namespace content {
+namespace {
+
+void CreateSubresourceLoaderFactoryForProviderContext(
+ mojom::ServiceWorkerContainerHostPtrInfo container_host_info,
+ mojom::ControllerServiceWorkerPtrInfo controller_ptr_info,
+ const std::string& client_id,
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory_info,
+ mojom::ControllerServiceWorkerConnectorRequest connector_request,
+ network::mojom::URLLoaderFactoryRequest request,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ mojom::ControllerServiceWorkerPtr controller_ptr;
+ controller_ptr.Bind(std::move(controller_ptr_info));
+ auto connector = base::MakeRefCounted<ControllerServiceWorkerConnector>(
+ std::move(container_host_info), std::move(controller_ptr), client_id);
+ connector->AddBinding(std::move(connector_request));
+ ServiceWorkerSubresourceLoaderFactory::Create(
+ std::move(connector),
+ network::SharedURLLoaderFactory::Create(std::move(fallback_factory_info)),
+ std::move(request), std::move(task_runner));
+}
+
+} // namespace
+
// Holds state for service worker clients.
struct ServiceWorkerProviderContext::ProviderStateForClient {
explicit ProviderStateForClient(
@@ -57,6 +81,9 @@ struct ServiceWorkerProviderContext::ProviderStateForClient {
// The Client#id value of the client.
std::string client_id;
+ blink::mojom::ControllerServiceWorkerMode controller_mode =
+ blink::mojom::ControllerServiceWorkerMode::kNoController;
+
// Tracks feature usage for UseCounter.
std::set<blink::mojom::WebFeature> used_features;
@@ -73,13 +100,26 @@ struct ServiceWorkerProviderContext::ProviderStateForClient {
// the shared worker.
std::vector<mojom::ServiceWorkerWorkerClientPtr> worker_clients;
+ // For adding new ServiceWorkerWorkerClients.
+ mojo::BindingSet<mojom::ServiceWorkerWorkerClientRegistry>
+ worker_client_registry_bindings;
+
// 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.
- // This is (re)set to nullptr if no controller is attached to this client.
- scoped_refptr<ControllerServiceWorkerConnector> controller_connector;
+ // controller service worker.
+ //
+ // |controller_endpoint| is a Mojo pipe to the controller service worker,
+ // and is to be passed to (i.e. taken by) a subresource loader factory when
+ // GetSubresourceLoaderFactory() is called for the first time when a valid
+ // controller exists.
+ //
+ // |controller_connector| is a Mojo pipe to the
+ // ControllerServiceWorkerConnector that is attached to the newly created
+ // subresource loader factory and lives on a background thread. This is
+ // populated when GetSubresourceLoader() creates the subresource loader
+ // factory and takes |controller_endpoint|.
+ mojom::ControllerServiceWorkerPtrInfo controller_endpoint;
+ mojom::ControllerServiceWorkerConnectorPtr controller_connector;
// For service worker clients. Map from registration id to JavaScript
// ServiceWorkerRegistration object.
@@ -139,27 +179,53 @@ ServiceWorkerProviderContext::TakeController() {
return std::move(state_for_client_->controller);
}
-int64_t ServiceWorkerProviderContext::GetControllerVersionId() {
+int64_t ServiceWorkerProviderContext::GetControllerVersionId() const {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
DCHECK(state_for_client_);
return state_for_client_->controller_version_id;
}
+blink::mojom::ControllerServiceWorkerMode
+ServiceWorkerProviderContext::IsControlledByServiceWorker() const {
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ DCHECK(state_for_client_);
+ return state_for_client_->controller_mode;
+}
+
network::mojom::URLLoaderFactory*
ServiceWorkerProviderContext::GetSubresourceLoaderFactory() {
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled())
+ return nullptr;
+
DCHECK(state_for_client_);
auto* state = state_for_client_.get();
- if (!state->controller_connector ||
- state->controller_connector->state() ==
- ControllerServiceWorkerConnector::State::kNoController) {
+ if (!state->controller_endpoint && !state->controller_connector) {
// No controller is attached.
return nullptr;
}
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+
+ if (state->controller_mode !=
+ blink::mojom::ControllerServiceWorkerMode::kControlled) {
+ // The controller does not exist or has no fetch event handler.
+ return nullptr;
+ }
+
if (!state->subresource_loader_factory) {
- ServiceWorkerSubresourceLoaderFactory::Create(
- state->controller_connector, state->fallback_loader_factory,
- mojo::MakeRequest(&state->subresource_loader_factory));
+ DCHECK(!state->controller_connector);
+ DCHECK(state->controller_endpoint);
+ // Create a SubresourceLoaderFactory on a background thread to avoid
+ // extra contention on the main thread.
+ auto task_runner = base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
+ task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&CreateSubresourceLoaderFactoryForProviderContext,
+ CloneContainerHostPtrInfo(),
+ std::move(state->controller_endpoint), state->client_id,
+ state->fallback_loader_factory->Clone(),
+ mojo::MakeRequest(&state->controller_connector),
+ mojo::MakeRequest(&state->subresource_loader_factory),
+ task_runner));
}
return state->subresource_loader_factory.get();
}
@@ -188,25 +254,31 @@ void ServiceWorkerProviderContext::SetWebServiceWorkerProvider(
state_for_client_->web_service_worker_provider = provider;
}
-mojom::ServiceWorkerWorkerClientRequest
-ServiceWorkerProviderContext::CreateWorkerClientRequest() {
+void ServiceWorkerProviderContext::RegisterWorkerClient(
+ mojom::ServiceWorkerWorkerClientPtr client) {
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;
+}
+
+void ServiceWorkerProviderContext::CloneWorkerClientRegistry(
+ mojom::ServiceWorkerWorkerClientRegistryRequest request) {
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ DCHECK(state_for_client_);
+ state_for_client_->worker_client_registry_bindings.AddBinding(
+ this, std::move(request));
}
mojom::ServiceWorkerContainerHostPtrInfo
ServiceWorkerProviderContext::CloneContainerHostPtrInfo() {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
DCHECK(state_for_client_);
mojom::ServiceWorkerContainerHostPtrInfo container_host_ptr_info;
+ // TODO(kinuko): rename this, now this can be used for non-worker clients.
container_host_->CloneForWorker(mojo::MakeRequest(&container_host_ptr_info));
return container_host_ptr_info;
}
@@ -248,8 +320,6 @@ ServiceWorkerProviderContext::GetOrCreateServiceWorkerObject(
void ServiceWorkerProviderContext::OnNetworkProviderDestroyed() {
container_host_.reset();
- if (state_for_client_ && state_for_client_->controller_connector)
- state_for_client_->controller_connector->OnContainerHostConnectionClosed();
}
void ServiceWorkerProviderContext::PingContainerHost(
@@ -258,6 +328,24 @@ void ServiceWorkerProviderContext::PingContainerHost(
container_host_->Ping(std::move(callback));
}
+void ServiceWorkerProviderContext::DispatchNetworkQuiet() {
+ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
+ ProviderStateForClient* state = state_for_client_.get();
+ DCHECK(state);
+
+ // In non-S13nSW, this hint isn't needed because the browser process
+ // sees all requests and schedules update at a convenient time.
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled())
+ return;
+
+ if (state->controller_mode ==
+ blink::mojom::ControllerServiceWorkerMode::kNoController) {
+ return;
+ }
+
+ container_host_->HintToUpdateServiceWorker();
+}
+
void ServiceWorkerProviderContext::UnregisterWorkerFetchContext(
mojom::ServiceWorkerWorkerClient* client) {
DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
@@ -286,6 +374,15 @@ void ServiceWorkerProviderContext::SetController(
state->client_id == controller_info->client_id);
state->client_id = controller_info->client_id;
+ DCHECK((controller_info->mode ==
+ blink::mojom::ControllerServiceWorkerMode::kNoController &&
+ !state->controller) ||
+ (controller_info->mode !=
+ blink::mojom::ControllerServiceWorkerMode::kNoController &&
+ state->controller));
+ state->controller_mode = controller_info->mode;
+ state->controller_endpoint = std::move(controller_info->endpoint);
+
// Propagate the controller to workers related to this provider.
if (state->controller) {
DCHECK_NE(blink::mojom::kInvalidServiceWorkerVersionId,
@@ -293,16 +390,16 @@ void ServiceWorkerProviderContext::SetController(
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);
+ worker->OnControllerChanged(state->controller_mode);
}
}
for (blink::mojom::WebFeature feature : used_features)
state->used_features.insert(feature);
// S13nServiceWorker:
- // Reset subresource loader factory if necessary.
+ // Reset connector state for subresource loader factory if necessary.
if (CanCreateSubresourceLoaderFactory()) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
// There could be four patterns:
// (A) Had a controller, and got a new controller.
@@ -310,26 +407,20 @@ void ServiceWorkerProviderContext::SetController(
// (C) Didn't have a controller, and got a new controller.
// (D) Didn't have a controller, and lost the controller (nothing to do).
if (state->controller_connector) {
- // Used to have a controller at least once.
- // Reset the existing connector so that subsequent resource requests
- // will get the new controller in case (A)/(C), or fallback to the
- // network in case (B). Inflight requests that are already dispatched may
- // just use the existing controller or may use the new controller
- // settings depending on when the request is actually passed to the
- // factory (this part is inherently racy).
- state->controller_connector->ResetControllerConnection(
+ // Used to have a controller at least once and have created a
+ // subresource loader factory before (if no subresource factory was
+ // created before, then the right controller, if any, will be used when
+ // the factory is created in GetSubresourceLoaderFactory, so there's
+ // nothing to do here).
+ // Update the connector's controller so that subsequent resource requests
+ // will get the new controller in case (A)/(C), or fallback to the network
+ // in case (B). Inflight requests that are already dispatched may just use
+ // the existing controller or may use the new controller settings
+ // depending on when the request is actually passed to the factory (this
+ // part is inherently racy).
+ state->controller_connector->UpdateController(
mojom::ControllerServiceWorkerPtr(
- std::move(controller_info->endpoint)));
- } else if (state->controller) {
- // Case (C): never had a controller, but got a new one now.
- // Set a new |state->controller_connector| so that subsequent resource
- // requests will see it.
- mojom::ControllerServiceWorkerPtr controller_ptr(
- std::move(controller_info->endpoint));
- state->controller_connector =
- base::MakeRefCounted<ControllerServiceWorkerConnector>(
- container_host_.get(), std::move(controller_ptr),
- controller_info->client_id);
+ std::move(state->controller_endpoint)));
}
}
@@ -419,7 +510,7 @@ bool ServiceWorkerProviderContext::CanCreateSubresourceLoaderFactory() const {
// Expected that it is called only for clients.
DCHECK(state_for_client_);
// |state_for_client_->fallback_loader_factory| could be null in unit tests.
- return (ServiceWorkerUtils::IsServicificationEnabled() &&
+ return (blink::ServiceWorkerUtils::IsServicificationEnabled() &&
state_for_client_->fallback_loader_factory);
}
diff --git a/chromium/content/renderer/service_worker/service_worker_provider_context.h b/chromium/content/renderer/service_worker/service_worker_provider_context.h
index 19fec07789a..405c40c960f 100644
--- a/chromium/content/renderer/service_worker/service_worker_provider_context.h
+++ b/chromium/content/renderer/service_worker/service_worker_provider_context.h
@@ -21,7 +21,7 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_provider_client.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h"
namespace base {
class SingleThreadTaskRunner;
@@ -47,12 +47,20 @@ struct ServiceWorkerProviderContextDeleter;
// the same underlying entity hold strong references to a shared instance of
// this class.
//
+// ServiceWorkerProviderContext is also a
+// mojom::ServiceWorkerWorkerClientRegistry. If it's a provider for a document,
+// then it tracks all the dedicated workers created from the document (including
+// nested workers), as dedicated workers don't yet have their own providers. If
+// it's a provider for a shared worker, then it tracks only the shared worker
+// itself.
+//
// Created and destructed on the main thread. Unless otherwise noted, all
// methods are called on the main thread.
class CONTENT_EXPORT ServiceWorkerProviderContext
: public base::RefCountedThreadSafe<ServiceWorkerProviderContext,
ServiceWorkerProviderContextDeleter>,
- public mojom::ServiceWorkerContainer {
+ public mojom::ServiceWorkerContainer,
+ public mojom::ServiceWorkerWorkerClientRegistry {
public:
// Constructor for service worker clients.
//
@@ -108,7 +116,9 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
// For service worker clients. Returns version id of the controller service
// worker object (ServiceWorkerContainer#controller).
- int64_t GetControllerVersionId();
+ int64_t GetControllerVersionId() const;
+
+ blink::mojom::ControllerServiceWorkerMode IsControlledByServiceWorker() const;
// For service worker clients. Takes the controller service worker object info
// set by SetController() if any, otherwise returns nullptr.
@@ -135,22 +145,18 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
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
- // shared) worker thread and receive SetControllerServiceWorker() method call
- // from the main thread.
- // A dedicated worker's WorkerFetchContext calls CreateWorkerClientRequest()
- // on its parent Document's ServiceWorkerProviderContext. A shared worker's
- // fetch context calls CreateWorkerClientRequest() on its own
- // ServiceWorkerProviderContext.
- mojom::ServiceWorkerWorkerClientRequest CreateWorkerClientRequest();
+ // mojom::ServiceWorkerWorkerClientRegistry:
+ void RegisterWorkerClient(
+ mojom::ServiceWorkerWorkerClientPtr client) override;
+ void CloneWorkerClientRegistry(
+ mojom::ServiceWorkerWorkerClientRegistryRequest request) override;
// S13nServiceWorker:
// For service worker clients. Creates a ServiceWorkerContainerHostPtrInfo
// which can be bound to a ServiceWorkerContainerHostPtr in a (dedicated or
- // shared) worker thread. WorkerFetchContextImpl will use the host pointer to
- // get the controller service worker by GetControllerServiceWorker() and send
- // FetchEvents to the service worker.
+ // shared) worker thread. WebWorkerFetchContextImpl 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
@@ -185,6 +191,11 @@ class CONTENT_EXPORT ServiceWorkerProviderContext
// for waiting for all messages the host sent thus far to arrive.
void PingContainerHost(base::OnceClosure callback);
+ // Called when blink::IdlenessDetector emits its network idle signal. Tells
+ // the browser process that this page is quiet soon after page load, as a
+ // hint to start the service worker update check.
+ void DispatchNetworkQuiet();
+
private:
friend class base::DeleteHelper<ServiceWorkerProviderContext>;
friend class base::RefCountedThreadSafe<ServiceWorkerProviderContext,
diff --git a/chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc b/chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc
index 7c73ae07a8a..d5d256d404b 100644
--- a/chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc
+++ b/chromium/content/renderer/service_worker/service_worker_provider_context_unittest.cc
@@ -10,6 +10,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
+#include "base/test/scoped_task_environment.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"
@@ -32,7 +33,8 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_provider_client.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h"
+#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "third_party/blink/public/platform/web_feature.mojom.h"
namespace content {
@@ -204,9 +206,15 @@ class FakeURLLoaderFactory final : public network::mojom::URLLoaderFactory {
// connection errors).
last_url_ = url_request.url;
clients_.push_back(std::move(client));
+ if (start_loader_callback_)
+ std::move(start_loader_callback_).Run();
}
void Clone(network::mojom::URLLoaderFactoryRequest factory) override {
- NOTREACHED();
+ bindings_.AddBinding(this, std::move(factory));
+ }
+
+ void set_start_loader_callback(base::OnceClosure closure) {
+ start_loader_callback_ = std::move(closure);
}
size_t clients_count() const { return clients_.size(); }
@@ -215,6 +223,7 @@ class FakeURLLoaderFactory final : public network::mojom::URLLoaderFactory {
private:
mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
std::vector<network::mojom::URLLoaderClientPtr> clients_;
+ base::OnceClosure start_loader_callback_;
GURL last_url_;
DISALLOW_COPY_AND_ASSIGN(FakeURLLoaderFactory);
@@ -229,23 +238,30 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
// mojom::ControllerServiceWorker:
void DispatchFetchEvent(
- mojom::DispatchFetchEventParamsPtr params,
+ blink::mojom::DispatchFetchEventParamsPtr params,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback) override {
fetch_event_count_++;
fetch_event_request_ = params->request;
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED,
base::Time());
+ if (fetch_event_callback_)
+ std::move(fetch_event_callback_).Run();
}
void Clone(mojom::ControllerServiceWorkerRequest request) override {
bindings_.AddBinding(this, std::move(request));
}
+ void set_fetch_callback(base::OnceClosure closure) {
+ fetch_event_callback_ = std::move(closure);
+ }
int fetch_event_count() const { return fetch_event_count_; }
const network::ResourceRequest& fetch_event_request() const {
return fetch_event_request_;
}
+ void Disconnect() { bindings_.CloseAllBindings(); }
+
private:
int fetch_event_count_ = 0;
network::ResourceRequest fetch_event_request_;
@@ -255,6 +271,50 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
DISALLOW_COPY_AND_ASSIGN(FakeControllerServiceWorker);
};
+class FakeServiceWorkerContainerHost
+ : public mojom::ServiceWorkerContainerHost {
+ public:
+ explicit FakeServiceWorkerContainerHost(
+ mojom::ServiceWorkerContainerHostAssociatedRequest request)
+ : associated_binding_(this, std::move(request)) {}
+ ~FakeServiceWorkerContainerHost() override = default;
+
+ // 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 EnsureControllerServiceWorker(
+ mojom::ControllerServiceWorkerRequest request,
+ mojom::ControllerServiceWorkerPurpose purpose) override {
+ NOTIMPLEMENTED();
+ }
+ void CloneForWorker(
+ mojom::ServiceWorkerContainerHostRequest request) override {
+ bindings_.AddBinding(this, std::move(request));
+ }
+ void Ping(PingCallback callback) override { NOTIMPLEMENTED(); }
+ void HintToUpdateServiceWorker() override { NOTIMPLEMENTED(); }
+
+ private:
+ mojo::BindingSet<mojom::ServiceWorkerContainerHost> bindings_;
+ mojo::AssociatedBinding<mojom::ServiceWorkerContainerHost>
+ associated_binding_;
+ DISALLOW_COPY_AND_ASSIGN(FakeServiceWorkerContainerHost);
+};
+
class ServiceWorkerProviderContextTest : public testing::Test {
public:
ServiceWorkerProviderContextTest() = default;
@@ -280,8 +340,6 @@ class ServiceWorkerProviderContextTest : public testing::Test {
mojo::MakeRequest(&loader), 0, 0, network::mojom::kURLLoadOptionNone,
request, loader_client.CreateInterfacePtr(),
net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
- // Need to run one more loop to make a Mojo call.
- base::RunLoop().RunUntilIdle();
}
bool ContainsRegistration(ServiceWorkerProviderContext* provider_context,
@@ -296,7 +354,7 @@ class ServiceWorkerProviderContextTest : public testing::Test {
}
protected:
- base::MessageLoop message_loop_;
+ base::test::ScopedTaskEnvironment task_environment;
// S13nServiceWorker:
base::test::ScopedFeatureList scoped_feature_list_;
@@ -329,6 +387,7 @@ TEST_F(ServiceWorkerProviderContextTest, SetController) {
nullptr /* controller_info */, nullptr /* loader_factory*/);
auto info = mojom::ControllerServiceWorkerInfo::New();
+ info->mode = blink::mojom::ControllerServiceWorkerMode::kControlled;
info->object_info = std::move(object_info);
container_ptr->SetController(std::move(info),
std::vector<blink::mojom::WebFeature>(), true);
@@ -373,6 +432,7 @@ TEST_F(ServiceWorkerProviderContextTest, SetController) {
ASSERT_FALSE(client->was_set_controller_called());
auto info = mojom::ControllerServiceWorkerInfo::New();
+ info->mode = blink::mojom::ControllerServiceWorkerMode::kControlled;
info->object_info = std::move(object_info);
container_ptr->SetController(std::move(info),
std::vector<blink::mojom::WebFeature>(), true);
@@ -430,15 +490,21 @@ TEST_F(ServiceWorkerProviderContextTest, SetControllerServiceWorker) {
auto controller_info1 = mojom::ControllerServiceWorkerInfo::New();
mojom::ControllerServiceWorkerPtr controller_ptr1;
fake_controller1.Clone(mojo::MakeRequest(&controller_ptr1));
+ controller_info1->mode =
+ blink::mojom::ControllerServiceWorkerMode::kControlled;
controller_info1->object_info = std::move(object_info1);
controller_info1->endpoint = controller_ptr1.PassInterface();
+ mojom::ServiceWorkerContainerHostAssociatedPtr host_ptr;
+ FakeServiceWorkerContainerHost host(
+ mojo::MakeRequestAssociatedWithDedicatedPipe(&host_ptr));
+
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 */,
+ std::move(container_request), host_ptr.PassInterface(),
std::move(controller_info1), loader_factory_);
base::RunLoop().RunUntilIdle();
@@ -449,7 +515,10 @@ TEST_F(ServiceWorkerProviderContextTest, SetControllerServiceWorker) {
// Performing a request should reach the controller.
const GURL kURL1("https://www.example.com/foo.png");
+ base::RunLoop loop1;
+ fake_controller1.set_fetch_callback(loop1.QuitClosure());
StartRequest(subresource_loader_factory1, kURL1);
+ loop1.Run();
EXPECT_EQ(kURL1, fake_controller1.fetch_event_request().url);
EXPECT_EQ(1, fake_controller1.fetch_event_count());
@@ -465,6 +534,8 @@ TEST_F(ServiceWorkerProviderContextTest, SetControllerServiceWorker) {
auto controller_info2 = mojom::ControllerServiceWorkerInfo::New();
mojom::ControllerServiceWorkerPtr controller_ptr2;
fake_controller2.Clone(mojo::MakeRequest(&controller_ptr2));
+ controller_info2->mode =
+ blink::mojom::ControllerServiceWorkerMode::kControlled;
controller_info2->object_info = std::move(object_info2);
controller_info2->endpoint = controller_ptr2.PassInterface();
container_ptr->SetController(std::move(controller_info2),
@@ -484,7 +555,10 @@ TEST_F(ServiceWorkerProviderContextTest, SetControllerServiceWorker) {
// Performing a request should reach the new controller.
const GURL kURL2("https://www.example.com/foo2.png");
+ base::RunLoop loop2;
+ fake_controller2.set_fetch_callback(loop2.QuitClosure());
StartRequest(subresource_loader_factory2, kURL2);
+ loop2.Run();
EXPECT_EQ(kURL2, fake_controller2.fetch_event_request().url);
EXPECT_EQ(1, fake_controller2.fetch_event_count());
// The request should not go to the previous controller.
@@ -505,8 +579,11 @@ TEST_F(ServiceWorkerProviderContextTest, SetControllerServiceWorker) {
// Performing a request using the subresource factory obtained before
// falls back to the network.
const GURL kURL3("https://www.example.com/foo3.png");
+ base::RunLoop loop3;
+ fake_loader_factory_.set_start_loader_callback(loop3.QuitClosure());
EXPECT_EQ(0UL, fake_loader_factory_.clients_count());
StartRequest(subresource_loader_factory2, kURL3);
+ loop3.Run();
EXPECT_EQ(kURL3, fake_loader_factory_.last_request_url());
EXPECT_EQ(1UL, fake_loader_factory_.clients_count());
@@ -526,6 +603,8 @@ TEST_F(ServiceWorkerProviderContextTest, SetControllerServiceWorker) {
auto controller_info4 = mojom::ControllerServiceWorkerInfo::New();
mojom::ControllerServiceWorkerPtr controller_ptr4;
fake_controller4.Clone(mojo::MakeRequest(&controller_ptr4));
+ controller_info4->mode =
+ blink::mojom::ControllerServiceWorkerMode::kControlled;
controller_info4->object_info = std::move(object_info4);
controller_info4->endpoint = controller_ptr4.PassInterface();
container_ptr->SetController(std::move(controller_info4),
@@ -539,7 +618,10 @@ TEST_F(ServiceWorkerProviderContextTest, SetControllerServiceWorker) {
// Performing a request should reach the new controller.
const GURL kURL4("https://www.example.com/foo4.png");
+ base::RunLoop loop4;
+ fake_controller4.set_fetch_callback(loop4.QuitClosure());
StartRequest(subresource_loader_factory4, kURL4);
+ loop4.Run();
EXPECT_EQ(kURL4, fake_controller4.fetch_event_request().url);
EXPECT_EQ(1, fake_controller4.fetch_event_count());
@@ -548,6 +630,41 @@ TEST_F(ServiceWorkerProviderContextTest, SetControllerServiceWorker) {
EXPECT_EQ(1, fake_controller2.fetch_event_count());
// The request should not go to the network.
EXPECT_EQ(1UL, fake_loader_factory_.clients_count());
+
+ // Perform a request again, but then drop the controller connection.
+ // The outcome is not deterministic but should not crash.
+ StartRequest(subresource_loader_factory4, kURL4);
+ fake_controller4.Disconnect();
+ base::RunLoop().RunUntilIdle();
+}
+
+TEST_F(ServiceWorkerProviderContextTest, ControllerWithoutFetchHandler) {
+ EnableS13nServiceWorker();
+ const int kProviderId = 10;
+ auto object_host =
+ std::make_unique<MockServiceWorkerObjectHost>(200 /* version_id */);
+
+ // Set a controller without ControllerServiceWorker ptr to emulate no
+ // fetch event handler.
+ blink::mojom::ServiceWorkerObjectInfoPtr object_info =
+ object_host->CreateObjectInfo();
+ auto controller_info = mojom::ControllerServiceWorkerInfo::New();
+ mojom::ControllerServiceWorkerPtr controller_ptr;
+ controller_info->mode =
+ blink::mojom::ControllerServiceWorkerMode::kNoFetchEventHandler;
+ controller_info->object_info = std::move(object_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), nullptr /* host_ptr_info */,
+ std::move(controller_info), loader_factory_);
+ base::RunLoop().RunUntilIdle();
+
+ // Subresource loader factory must not be available.
+ EXPECT_EQ(nullptr, provider_context->GetSubresourceLoaderFactory());
}
TEST_F(ServiceWorkerProviderContextTest, PostMessageToClient) {
diff --git a/chromium/content/renderer/service_worker/service_worker_subresource_loader.cc b/chromium/content/renderer/service_worker/service_worker_subresource_loader.cc
index 07c74494a64..3e5b7dbfd77 100644
--- a/chromium/content/renderer/service_worker/service_worker_subresource_loader.cc
+++ b/chromium/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -7,7 +7,9 @@
#include "base/atomic_sequence_num.h"
#include "base/callback.h"
#include "base/feature_list.h"
+#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
+#include "base/trace_event/trace_event.h"
#include "content/common/service_worker/service_worker_loader_helpers.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/service_worker/service_worker_utils.h"
@@ -18,13 +20,16 @@
#include "content/renderer/service_worker/controller_service_worker_connector.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "net/base/net_errors.h"
#include "net/url_request/redirect_util.h"
#include "net/url_request/url_request.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/blink/public/common/service_worker/service_worker_type_converters.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
+#include "third_party/blink/public/mojom/service_worker/dispatch_fetch_event_params.mojom.h"
#include "third_party/blink/public/platform/interface_provider.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_request.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h"
#include "third_party/blink/public/platform/web_http_body.h"
#include "third_party/blink/public/platform/web_string.h"
#include "ui/base/page_transition_types.h"
@@ -60,12 +65,10 @@ class HeaderRewritingURLLoaderClient : public network::mojom::URLLoaderClient {
private:
// network::mojom::URLLoaderClient implementation:
void OnReceiveResponse(
- const network::ResourceResponseHead& response_head,
- network::mojom::DownloadedTempFilePtr downloaded_file) override {
+ const network::ResourceResponseHead& response_head) override {
DCHECK(url_loader_client_.is_bound());
url_loader_client_->OnReceiveResponse(
- rewrite_header_callback_.Run(response_head),
- std::move(downloaded_file));
+ rewrite_header_callback_.Run(response_head));
}
void OnReceiveRedirect(
@@ -76,11 +79,6 @@ class HeaderRewritingURLLoaderClient : public network::mojom::URLLoaderClient {
redirect_info, rewrite_header_callback_.Run(response_head));
}
- void OnDataDownloaded(int64_t data_len, int64_t encoded_data_len) override {
- DCHECK(url_loader_client_.is_bound());
- url_loader_client_->OnDataDownloaded(data_len, encoded_data_len);
- }
-
void OnUploadProgress(int64_t current_position,
int64_t total_size,
OnUploadProgressCallback ack_callback) override {
@@ -152,12 +150,14 @@ ServiceWorkerSubresourceLoader::ServiceWorkerSubresourceLoader(
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
- scoped_refptr<network::SharedURLLoaderFactory> fallback_factory)
+ scoped_refptr<network::SharedURLLoaderFactory> fallback_factory,
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
: 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)),
+ controller_connector_observer_(this),
fetch_request_restarted_(false),
routing_id_(routing_id),
request_id_(request_id),
@@ -165,6 +165,7 @@ ServiceWorkerSubresourceLoader::ServiceWorkerSubresourceLoader(
traffic_annotation_(traffic_annotation),
resource_request_(resource_request),
fallback_factory_(std::move(fallback_factory)),
+ task_runner_(std::move(task_runner)),
weak_factory_(this) {
DCHECK(controller_connector_);
response_head_.request_start = base::TimeTicks::Now();
@@ -177,9 +178,7 @@ ServiceWorkerSubresourceLoader::ServiceWorkerSubresourceLoader(
StartRequest(resource_request);
}
-ServiceWorkerSubresourceLoader::~ServiceWorkerSubresourceLoader() {
- SettleInflightFetchRequestIfNeeded();
-};
+ServiceWorkerSubresourceLoader::~ServiceWorkerSubresourceLoader() = default;
void ServiceWorkerSubresourceLoader::OnConnectionError() {
delete this;
@@ -187,16 +186,17 @@ void ServiceWorkerSubresourceLoader::OnConnectionError() {
void ServiceWorkerSubresourceLoader::StartRequest(
const network::ResourceRequest& resource_request) {
+ TRACE_EVENT_WITH_FLOW1(
+ "ServiceWorker", "ServiceWorkerSubresourceLoader::StartRequest", this,
+ TRACE_EVENT_FLAG_FLOW_OUT, "url", resource_request.url.spec());
DCHECK_EQ(Status::kNotStarted, status_);
status_ = Status::kStarted;
DCHECK(!ServiceWorkerUtils::IsMainResourceType(
static_cast<ResourceType>(resource_request.resource_type)));
- DCHECK(!inflight_fetch_request_);
- inflight_fetch_request_ =
- std::make_unique<network::ResourceRequest>(resource_request);
- controller_connector_->AddObserver(this);
+ DCHECK(!controller_connector_observer_.IsObservingSources());
+ controller_connector_observer_.Add(controller_connector_.get());
fetch_request_restarted_ = false;
response_head_.service_worker_start_time = base::TimeTicks::Now();
@@ -209,15 +209,14 @@ void ServiceWorkerSubresourceLoader::StartRequest(
}
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(
mojom::ControllerServiceWorkerPurpose::FETCH_SUB_RESOURCE);
- // 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.
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerSubresourceLoader::DispatchFetchEvent",
+ "controller", (controller ? "exists" : "does not exist"));
if (!controller) {
auto controller_state = controller_connector_->state();
if (controller_state ==
@@ -231,14 +230,18 @@ void ServiceWorkerSubresourceLoader::DispatchFetchEvent() {
delete this;
return;
}
+
+ // When kNoContainerHost, 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.
DCHECK_EQ(ControllerServiceWorkerConnector::State::kNoContainerHost,
controller_state);
- SettleInflightFetchRequestIfNeeded();
+ SettleFetchEventDispatch(base::nullopt);
return;
}
- auto params = mojom::DispatchFetchEventParams::New();
- params->request = *inflight_fetch_request_;
+ auto params = blink::mojom::DispatchFetchEventParams::New();
+ params->request = resource_request_;
params->client_id = controller_connector_->client_id();
// S13nServiceWorker without NetworkService:
@@ -246,6 +249,10 @@ void ServiceWorkerSubresourceLoader::DispatchFetchEvent() {
// before dispatching the fetch event for keeping the blob alive.
if (resource_request_.request_body &&
!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
+ // We need this as GetBlobFromUUID is a sync IPC.
+ // TODO(kinuko): Remove the friend for ScopedAllowBaseSyncPrimitives
+ // in //base as well when we remove this code.
+ base::ScopedAllowBaseSyncPrimitives allow_sync_primitives;
params->request_body_blob_ptrs =
GetBlobPtrsForRequestBody(*resource_request_.request_body);
}
@@ -253,15 +260,27 @@ void ServiceWorkerSubresourceLoader::DispatchFetchEvent() {
controller->DispatchFetchEvent(
std::move(params), std::move(response_callback_ptr),
base::BindOnce(&ServiceWorkerSubresourceLoader::OnFetchEventFinished,
- weak_factory_.GetWeakPtr()));
+ weak_factory_.GetWeakPtr(), base::Time::Now()));
}
void ServiceWorkerSubresourceLoader::OnFetchEventFinished(
+ base::Time request_dispatch_time,
blink::mojom::ServiceWorkerEventStatus status,
- base::Time dispatch_event_time) {
+ base::Time actual_dispatch_time) {
+ TRACE_EVENT_WITH_FLOW1("ServiceWorker",
+ "ServiceWorkerSubresourceLoader::OnFetchEventFinished",
+ this, TRACE_EVENT_FLAG_FLOW_IN, "status",
+ ServiceWorkerUtils::MojoEnumToString(status));
+
// Stop restarting logic here since OnFetchEventFinished() indicates that the
- // fetch event was successfully dispatched.
- SettleInflightFetchRequestIfNeeded();
+ // fetch event dispatch reached the renderer.
+ SettleFetchEventDispatch(
+ mojo::ConvertTo<blink::ServiceWorkerStatusCode>(status));
+
+ base::TimeDelta delay = actual_dispatch_time - request_dispatch_time;
+ UMA_HISTOGRAM_TIMES("ServiceWorker.EventDispatchingDelay", delay);
+ UMA_HISTOGRAM_TIMES("ServiceWorker.EventDispatchingDelay_FETCH_SUB_RESOURCE",
+ delay);
switch (status) {
case blink::mojom::ServiceWorkerEventStatus::COMPLETED:
@@ -274,15 +293,17 @@ void ServiceWorkerSubresourceLoader::OnFetchEventFinished(
// promise, and handle this request.
break;
case blink::mojom::ServiceWorkerEventStatus::ABORTED:
- // We have an unexpected error: fetch event dispatch failed. Return
- // network error.
+ // Fetch event dispatch did not complete, possibly due to timeout of
+ // respondWith() or waitUntil(). Return network error.
+
+ // TODO(falken): This seems racy. respondWith() may have been called
+ // already and we could have an outstanding stream or blob in progress,
+ // and we might hit CommitCompleted() twice once that settles.
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
@@ -290,28 +311,40 @@ void ServiceWorkerSubresourceLoader::OnConnectionClosed() {
// 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();
+ SettleFetchEventDispatch(
+ blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed);
CommitCompleted(net::ERR_FAILED);
return;
}
fetch_request_restarted_ = true;
- base::ThreadTaskRunnerHandle::Get()->PostTask(
+ task_runner_->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::SettleFetchEventDispatch(
+ base::Optional<blink::ServiceWorkerStatusCode> status) {
+ if (!controller_connector_observer_.IsObservingSources()) {
+ // Already settled.
+ return;
+ }
+ controller_connector_observer_.RemoveAll();
+
+ if (status) {
+ blink::ServiceWorkerStatusCode value = status.value();
+ UMA_HISTOGRAM_ENUMERATION("ServiceWorker.FetchEvent.Subresource.Status",
+ value);
}
}
void ServiceWorkerSubresourceLoader::OnResponse(
const ServiceWorkerResponse& response,
base::Time dispatch_event_time) {
- SettleInflightFetchRequestIfNeeded();
+ TRACE_EVENT_WITH_FLOW0("ServiceWorker",
+ "ServiceWorkerSubresourceLoader::OnResponse", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ SettleFetchEventDispatch(blink::ServiceWorkerStatusCode::kOk);
StartResponse(response, nullptr /* body_as_blob */,
nullptr /* body_as_stream */);
}
@@ -320,30 +353,29 @@ void ServiceWorkerSubresourceLoader::OnResponseBlob(
const ServiceWorkerResponse& response,
blink::mojom::BlobPtr body_as_blob,
base::Time dispatch_event_time) {
- SettleInflightFetchRequestIfNeeded();
+ TRACE_EVENT_WITH_FLOW0("ServiceWorker",
+ "ServiceWorkerSubresourceLoader::OnResponseBlob", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ SettleFetchEventDispatch(blink::ServiceWorkerStatusCode::kOk);
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();
+ TRACE_EVENT_WITH_FLOW0(
+ "ServiceWorker", "ServiceWorkerSubresourceLoader::OnResponseStream", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
+ SettleFetchEventDispatch(blink::ServiceWorkerStatusCode::kOk);
StartResponse(response, nullptr /* body_as_blob */,
std::move(body_as_stream));
}
void ServiceWorkerSubresourceLoader::OnFallback(
base::Time dispatch_event_time) {
- SettleInflightFetchRequestIfNeeded();
+ SettleFetchEventDispatch(blink::ServiceWorkerStatusCode::kOk);
// When the request mode is CORS or CORS-with-forced-preflight and the origin
// of the request URL is different from the security origin of the document,
// we can't simply fallback to the network here. It is because the CORS
@@ -356,12 +388,18 @@ void ServiceWorkerSubresourceLoader::OnFallback(
(!resource_request_.request_initiator.has_value() ||
!resource_request_.request_initiator->IsSameOriginWith(
url::Origin::Create(resource_request_.url)))) {
+ TRACE_EVENT_WITH_FLOW0(
+ "ServiceWorker", "ServiceWorkerSubresourceLoader::OnFallback", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
response_head_.was_fetched_via_service_worker = true;
response_head_.was_fallback_required_by_service_worker = true;
CommitResponseHeaders();
CommitCompleted(net::OK);
return;
}
+ TRACE_EVENT_WITH_FLOW0("ServiceWorker",
+ "ServiceWorkerSubresourceLoader::OnFallback", this,
+ TRACE_EVENT_FLAG_FLOW_IN);
// Hand over to the network loader.
network::mojom::URLLoaderClientPtr client;
@@ -415,6 +453,7 @@ void ServiceWorkerSubresourceLoader::StartResponse(
}
response_head_.encoded_data_length = 0;
url_loader_client_->OnReceiveRedirect(*redirect_info_, response_head_);
+ // Set status to complete, but we expect to restart in FollowRedirect.
status_ = Status::kCompleted;
return;
}
@@ -437,18 +476,9 @@ void ServiceWorkerSubresourceLoader::StartResponse(
if (body_as_blob) {
DCHECK(!body_as_stream);
body_as_blob_ = std::move(body_as_blob);
- mojo::ScopedDataPipeConsumerHandle data_pipe;
- int error = ServiceWorkerLoaderHelpers::ReadBlobResponseBody(
- &body_as_blob_, resource_request_.headers,
- base::BindOnce(&ServiceWorkerSubresourceLoader::OnBlobReadingComplete,
- weak_factory_.GetWeakPtr()),
- &data_pipe);
- if (error != net::OK) {
- CommitCompleted(error);
- return;
- }
- url_loader_client_->OnStartLoadingResponseBody(std::move(data_pipe));
- // We continue in OnBlobReadingComplete().
+ body_as_blob_->ReadSideData(base::BindOnce(
+ &ServiceWorkerSubresourceLoader::OnBlobSideDataReadingComplete,
+ base::Unretained(this)));
return;
}
@@ -461,11 +491,14 @@ void ServiceWorkerSubresourceLoader::CommitResponseHeaders() {
DCHECK(url_loader_client_.is_bound());
status_ = Status::kSentHeader;
// TODO(kinuko): Fill the ssl_info.
- url_loader_client_->OnReceiveResponse(response_head_,
- nullptr /* downloaded_file */);
+ url_loader_client_->OnReceiveResponse(response_head_);
}
void ServiceWorkerSubresourceLoader::CommitCompleted(int error_code) {
+ TRACE_EVENT_WITH_FLOW1(
+ "ServiceWorker", "ServiceWorkerSubresourceLoader::CommitCompleted", this,
+ TRACE_EVENT_FLAG_FLOW_IN, "error_code", net::ErrorToString(error_code));
+
DCHECK_LT(status_, Status::kCompleted);
DCHECK(url_loader_client_.is_bound());
stream_waiter_.reset();
@@ -479,7 +512,13 @@ void ServiceWorkerSubresourceLoader::CommitCompleted(int error_code) {
// ServiceWorkerSubresourceLoader: URLLoader implementation -----------------
void ServiceWorkerSubresourceLoader::FollowRedirect(
+ const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
const base::Optional<net::HttpRequestHeaders>& modified_request_headers) {
+ TRACE_EVENT_WITH_FLOW1("ServiceWorker",
+ "ServiceWorkerSubresourceLoader::FollowRedirect", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
+ "new_url", redirect_info_->new_url.spec());
DCHECK(!modified_request_headers.has_value()) << "Redirect with modified "
"headers was not supported "
"yet. crbug.com/845683";
@@ -488,7 +527,8 @@ void ServiceWorkerSubresourceLoader::FollowRedirect(
bool should_clear_upload = false;
net::RedirectUtil::UpdateHttpRequest(
resource_request_.url, resource_request_.method, *redirect_info_,
- &resource_request_.headers, &should_clear_upload);
+ modified_request_headers, &resource_request_.headers,
+ &should_clear_upload);
if (should_clear_upload)
resource_request_.request_body = nullptr;
@@ -518,7 +558,34 @@ void ServiceWorkerSubresourceLoader::PauseReadingBodyFromNet() {}
void ServiceWorkerSubresourceLoader::ResumeReadingBodyFromNet() {}
+void ServiceWorkerSubresourceLoader::OnBlobSideDataReadingComplete(
+ const base::Optional<std::vector<uint8_t>>& metadata) {
+ TRACE_EVENT_WITH_FLOW1(
+ "ServiceWorker",
+ "ServiceWorkerSubresourceLoader::OnBlobSideDataReadingComplete", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "metadata size",
+ (metadata ? metadata->size() : 0));
+ DCHECK(url_loader_client_);
+ if (metadata.has_value())
+ url_loader_client_->OnReceiveCachedMetadata(metadata.value());
+ mojo::ScopedDataPipeConsumerHandle data_pipe;
+ int error = ServiceWorkerLoaderHelpers::ReadBlobResponseBody(
+ &body_as_blob_, resource_request_.headers,
+ base::BindOnce(&ServiceWorkerSubresourceLoader::OnBlobReadingComplete,
+ weak_factory_.GetWeakPtr()),
+ &data_pipe);
+ if (error != net::OK) {
+ CommitCompleted(error);
+ return;
+ }
+ url_loader_client_->OnStartLoadingResponseBody(std::move(data_pipe));
+ // We continue in OnBlobReadingComplete().
+}
+
void ServiceWorkerSubresourceLoader::OnBlobReadingComplete(int net_error) {
+ TRACE_EVENT_WITH_FLOW0(
+ "ServiceWorker", "ServiceWorkerSubresourceLoader::OnBlobReadingComplete",
+ this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
CommitCompleted(net_error);
body_as_blob_.reset();
}
@@ -529,18 +596,21 @@ void ServiceWorkerSubresourceLoader::OnBlobReadingComplete(int net_error) {
void ServiceWorkerSubresourceLoaderFactory::Create(
scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
scoped_refptr<network::SharedURLLoaderFactory> fallback_factory,
- network::mojom::URLLoaderFactoryRequest request) {
- new ServiceWorkerSubresourceLoaderFactory(std::move(controller_connector),
- std::move(fallback_factory),
- std::move(request));
+ network::mojom::URLLoaderFactoryRequest request,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ new ServiceWorkerSubresourceLoaderFactory(
+ std::move(controller_connector), std::move(fallback_factory),
+ std::move(request), std::move(task_runner));
}
ServiceWorkerSubresourceLoaderFactory::ServiceWorkerSubresourceLoaderFactory(
scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
scoped_refptr<network::SharedURLLoaderFactory> fallback_factory,
- network::mojom::URLLoaderFactoryRequest request)
+ network::mojom::URLLoaderFactoryRequest request,
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
: controller_connector_(std::move(controller_connector)),
- fallback_factory_(std::move(fallback_factory)) {
+ fallback_factory_(std::move(fallback_factory)),
+ task_runner_(std::move(task_runner)) {
DCHECK(fallback_factory_);
bindings_.AddBinding(this, std::move(request));
bindings_.set_connection_error_handler(base::BindRepeating(
@@ -563,10 +633,10 @@ void ServiceWorkerSubresourceLoaderFactory::CreateLoaderAndStart(
// network loader when fallback happens. When that happens the loader unbinds
// the request, passes the request to the fallback factory, and
// destructs itself (while the loader client continues to work).
- new ServiceWorkerSubresourceLoader(std::move(request), routing_id, request_id,
- options, resource_request,
- std::move(client), traffic_annotation,
- controller_connector_, fallback_factory_);
+ new ServiceWorkerSubresourceLoader(
+ std::move(request), routing_id, request_id, options, resource_request,
+ std::move(client), traffic_annotation, controller_connector_,
+ fallback_factory_, task_runner_);
}
void ServiceWorkerSubresourceLoaderFactory::Clone(
diff --git a/chromium/content/renderer/service_worker/service_worker_subresource_loader.h b/chromium/content/renderer/service_worker/service_worker_subresource_loader.h
index f209a0cd3b0..91b180b27af 100644
--- a/chromium/content/renderer/service_worker/service_worker_subresource_loader.h
+++ b/chromium/content/renderer/service_worker/service_worker_subresource_loader.h
@@ -8,16 +8,16 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
+#include "base/scoped_observer.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
-#include "content/common/service_worker/dispatch_fetch_event_params.mojom.h"
-#include "content/common/service_worker/service_worker_status_code.h"
#include "content/renderer/service_worker/controller_service_worker_connector.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_info.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_stream_handle.mojom.h"
@@ -51,11 +51,12 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
network::mojom::URLLoaderClientPtr client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
- scoped_refptr<network::SharedURLLoaderFactory> fallback_factory);
+ scoped_refptr<network::SharedURLLoaderFactory> fallback_factory,
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
~ServiceWorkerSubresourceLoader() override;
- // ControllerServiceWorkerConnector::Observer overrdies:
+ // ControllerServiceWorkerConnector::Observer overrides:
void OnConnectionClosed() override;
private:
@@ -65,9 +66,13 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
void StartRequest(const network::ResourceRequest& resource_request);
void DispatchFetchEvent();
- void OnFetchEventFinished(blink::mojom::ServiceWorkerEventStatus status,
+ void OnFetchEventFinished(base::Time request_dispatch_time,
+ blink::mojom::ServiceWorkerEventStatus status,
base::Time dispatch_event_time);
- void SettleInflightFetchRequestIfNeeded();
+ // Called when this loader no longer needs to restart dispatching the fetch
+ // event on failure. Null |status| means the event dispatch was not attempted.
+ void SettleFetchEventDispatch(
+ base::Optional<blink::ServiceWorkerStatusCode> status);
// mojom::ServiceWorkerFetchResponseCallback overrides:
void OnResponse(const ServiceWorkerResponse& response,
@@ -75,9 +80,6 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
void OnResponseBlob(const ServiceWorkerResponse& response,
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,
@@ -89,7 +91,9 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream);
// network::mojom::URLLoader overrides:
- void FollowRedirect(const base::Optional<net::HttpRequestHeaders>&
+ void FollowRedirect(const base::Optional<std::vector<std::string>>&
+ to_be_removed_request_headers,
+ const base::Optional<net::HttpRequestHeaders>&
modified_request_headers) override;
void ProceedWithResponse() override;
void SetPriority(net::RequestPriority priority,
@@ -97,6 +101,8 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
void PauseReadingBodyFromNet() override;
void ResumeReadingBodyFromNet() override;
+ void OnBlobSideDataReadingComplete(
+ const base::Optional<std::vector<uint8_t>>& metadata);
void OnBlobReadingComplete(int net_error);
// Calls url_loader_client_->OnReceiveResponse() with |response_head_|.
@@ -119,10 +125,12 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
scoped_refptr<ControllerServiceWorkerConnector> controller_connector_;
- // The request destined for the controller service worker. This is used
- // separately from |resource_request_| for the restarting mechanism when the
- // first attempt to dispatch to the controller failed.
- std::unique_ptr<network::ResourceRequest> inflight_fetch_request_;
+ // Observes |controller_connector_| while this loader dispatches a fetch event
+ // to the controller. If a broken connection is observed, this loader attempts
+ // to restart the controller and dispatch the event again.
+ ScopedObserver<ControllerServiceWorkerConnector,
+ ServiceWorkerSubresourceLoader>
+ controller_connector_observer_;
bool fetch_request_restarted_;
// These are given by the constructor (as the params for
@@ -149,6 +157,9 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoader
};
Status status_ = Status::kNotStarted;
+ // The task runner where this loader is running.
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
base::WeakPtrFactory<ServiceWorkerSubresourceLoader> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSubresourceLoader);
@@ -167,10 +178,14 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoaderFactory
// default URLLoaderFactory for network fallback. This should be the
// URLLoaderFactory that directly goes to network without going through
// any custom URLLoader factories.
+ // |task_runner| is the runner where this loader runs. (We need to pass
+ // this around because calling base::SequencedTaskRunnerHandle is
+ // prohibited in the renderer :()
static void Create(
scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
scoped_refptr<network::SharedURLLoaderFactory> fallback_factory,
- network::mojom::URLLoaderFactoryRequest request);
+ network::mojom::URLLoaderFactoryRequest request,
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
~ServiceWorkerSubresourceLoaderFactory() override;
@@ -189,7 +204,8 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoaderFactory
ServiceWorkerSubresourceLoaderFactory(
scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
scoped_refptr<network::SharedURLLoaderFactory> fallback_factory,
- network::mojom::URLLoaderFactoryRequest request);
+ network::mojom::URLLoaderFactoryRequest request,
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
void OnConnectionError();
@@ -200,6 +216,9 @@ class CONTENT_EXPORT ServiceWorkerSubresourceLoaderFactory
mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+ // The task runner where this factory is running.
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSubresourceLoaderFactory);
};
diff --git a/chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc b/chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
index 1dd21ee8447..73f5661eb9a 100644
--- a/chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
+++ b/chromium/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
@@ -6,6 +6,7 @@
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "content/common/service_worker/service_worker_container.mojom.h"
#include "content/common/service_worker/service_worker_utils.h"
@@ -25,11 +26,49 @@
#include "services/network/test/test_data_pipe_getter.h"
#include "services/network/test/test_url_loader_client.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/blob/blob.mojom.h"
+#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
#include "url/origin.h"
namespace content {
+namespace service_worker_subresource_loader_unittest {
-namespace {
+// A simple blob implementation for serving data stored in a vector.
+class FakeBlob final : public blink::mojom::Blob {
+ public:
+ FakeBlob(base::Optional<std::vector<uint8_t>> side_data, std::string body)
+ : side_data_(std::move(side_data)), body_(std::move(body)) {}
+
+ private:
+ // Implements blink::mojom::Blob.
+ void Clone(blink::mojom::BlobRequest) override { NOTREACHED(); }
+ void AsDataPipeGetter(network::mojom::DataPipeGetterRequest) override {
+ NOTREACHED();
+ }
+ void ReadRange(uint64_t offset,
+ uint64_t length,
+ mojo::ScopedDataPipeProducerHandle handle,
+ blink::mojom::BlobReaderClientPtr client) override {
+ NOTREACHED();
+ }
+ void ReadAll(mojo::ScopedDataPipeProducerHandle handle,
+ blink::mojom::BlobReaderClientPtr client) override {
+ EXPECT_TRUE(mojo::BlockingCopyFromString(body_, handle));
+ if (client) {
+ client->OnCalculatedSize(body_.size(), body_.size());
+ client->OnComplete(net::OK, body_.size());
+ }
+ }
+ void ReadSideData(ReadSideDataCallback callback) override {
+ std::move(callback).Run(side_data_);
+ }
+ void GetInternalUUID(GetInternalUUIDCallback callback) override {
+ NOTREACHED();
+ }
+
+ base::Optional<std::vector<uint8_t>> side_data_;
+ std::string body_;
+};
// A simple URLLoaderFactory that responds with status 200 to every request.
// This is the default network loader factory for
@@ -55,7 +94,7 @@ class FakeNetworkURLLoaderFactory final
network::ResourceResponseHead response;
response.headers = info.headers;
response.headers->GetMimeType(&response.mime_type);
- client->OnReceiveResponse(response, nullptr);
+ client->OnReceiveResponse(response);
std::string body = "this body came from the network";
uint32_t bytes_written = body.size();
@@ -82,6 +121,48 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
FakeControllerServiceWorker() = default;
~FakeControllerServiceWorker() override = default;
+ static ServiceWorkerResponse OkResponse() {
+ return 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 */);
+ }
+
+ static ServiceWorkerResponse ErrorResponse() {
+ return 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 */);
+ }
+
+ static ServiceWorkerResponse RedirectResponse(
+ const std::string& redirect_location_header) {
+ auto headers = std::make_unique<ServiceWorkerHeaderMap>();
+ (*headers)["Location"] = redirect_location_header;
+
+ return 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 */);
+ }
+
void CloseAllBindings() { bindings_.CloseAllBindings(); }
// Tells this controller to abort the fetch event without a response.
@@ -113,6 +194,14 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
redirect_location_header_ = redirect_location_header;
}
+ void RespondWithBlob(base::Optional<std::vector<uint8_t>> metadata,
+ std::string body) {
+ response_mode_ = ResponseMode::kBlob;
+ mojo::MakeStrongBinding(
+ std::make_unique<FakeBlob>(std::move(metadata), std::move(body)),
+ mojo::MakeRequest(&blob_));
+ }
+
void ReadRequestBody(std::string* out_string) {
ASSERT_TRUE(request_body_);
std::vector<network::DataElement>* elements =
@@ -143,7 +232,7 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
// mojom::ControllerServiceWorker:
void DispatchFetchEvent(
- mojom::DispatchFetchEventParamsPtr params,
+ blink::mojom::DispatchFetchEventParamsPtr params,
mojom::ServiceWorkerFetchResponseCallbackPtr response_callback,
DispatchFetchEventCallback callback) override {
EXPECT_FALSE(ServiceWorkerUtils::IsMainResourceType(
@@ -155,6 +244,7 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
switch (response_mode_) {
case ResponseMode::kDefault:
+ response_callback->OnResponse(OkResponse(), base::Time::Now());
std::move(callback).Run(
blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
break;
@@ -164,17 +254,13 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
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());
+ OkResponse(), std::move(stream_handle_), base::Time::Now());
+ std::move(callback).Run(
+ blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
+ break;
+ case ResponseMode::kBlob:
+ response_callback->OnResponseBlob(OkResponse(), std::move(blob_),
+ base::Time::Now());
std::move(callback).Run(
blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
break;
@@ -185,37 +271,14 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
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());
+ response_callback->OnResponse(ErrorResponse(), 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());
+ RedirectResponse(redirect_location_header_), base::Time::Now());
std::move(callback).Run(
blink::mojom::ServiceWorkerEventStatus::COMPLETED, base::Time());
break;
@@ -245,6 +308,7 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
kDefault,
kAbort,
kStream,
+ kBlob,
kFallbackResponse,
kErrorResponse,
kRedirectResponse
@@ -261,6 +325,9 @@ class FakeControllerServiceWorker : public mojom::ControllerServiceWorker {
// For ResponseMode::kStream.
blink::mojom::ServiceWorkerStreamHandlePtr stream_handle_;
+ // For ResponseMode::kBlob.
+ blink::mojom::BlobPtr blob_;
+
// For ResponseMode::kRedirectResponse
std::string redirect_location_header_;
@@ -284,7 +351,6 @@ class FakeServiceWorkerContainerHost
return get_controller_service_worker_count_;
}
- private:
// Implements mojom::ServiceWorkerContainerHost.
void Register(const GURL& script_url,
blink::mojom::ServiceWorkerRegistrationOptionsPtr options,
@@ -312,12 +378,15 @@ class FakeServiceWorkerContainerHost
}
void CloneForWorker(
mojom::ServiceWorkerContainerHostRequest request) override {
- NOTIMPLEMENTED();
+ bindings_.AddBinding(this, std::move(request));
}
void Ping(PingCallback callback) override { NOTIMPLEMENTED(); }
+ void HintToUpdateServiceWorker() override { NOTIMPLEMENTED(); }
+ private:
int get_controller_service_worker_count_ = 0;
FakeControllerServiceWorker* fake_controller_;
+ mojo::BindingSet<mojom::ServiceWorkerContainerHost> bindings_;
DISALLOW_COPY_AND_ASSIGN(FakeServiceWorkerContainerHost);
};
@@ -340,7 +409,8 @@ CreateResponseInfoFromServiceWorker() {
return head;
}
-} // namespace
+const char kHistogramSubresourceFetchEvent[] =
+ "ServiceWorker.FetchEvent.Subresource.Status";
class ServiceWorkerSubresourceLoaderTest : public ::testing::Test {
protected:
@@ -361,13 +431,17 @@ class ServiceWorkerSubresourceLoaderTest : public ::testing::Test {
network::mojom::URLLoaderFactoryPtr CreateSubresourceLoaderFactory() {
if (!connector_) {
+ mojom::ServiceWorkerContainerHostPtrInfo host_ptr_info;
+ fake_container_host_.CloneForWorker(mojo::MakeRequest(&host_ptr_info));
connector_ = base::MakeRefCounted<ControllerServiceWorkerConnector>(
- &fake_container_host_, nullptr /*controller_ptr*/, "" /*client_id*/);
+ std::move(host_ptr_info), nullptr /*controller_ptr*/,
+ "" /*client_id*/);
}
network::mojom::URLLoaderFactoryPtr service_worker_url_loader_factory;
ServiceWorkerSubresourceLoaderFactory::Create(
connector_, loader_factory_,
- mojo::MakeRequest(&service_worker_url_loader_factory));
+ mojo::MakeRequest(&service_worker_url_loader_factory),
+ blink::scheduler::GetSequencedTaskRunnerForTesting());
return service_worker_url_loader_factory;
}
@@ -466,6 +540,8 @@ class ServiceWorkerSubresourceLoaderTest : public ::testing::Test {
};
TEST_F(ServiceWorkerSubresourceLoaderTest, Basic) {
+ base::HistogramTester histogram_tester;
+
network::mojom::URLLoaderFactoryPtr factory =
CreateSubresourceLoaderFactory();
network::ResourceRequest request =
@@ -479,10 +555,15 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, Basic) {
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());
+
+ client->RunUntilComplete();
+ histogram_tester.ExpectUniqueSample(kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
}
TEST_F(ServiceWorkerSubresourceLoaderTest, Abort) {
fake_controller_.AbortEventWithNoResponse();
+ base::HistogramTester histogram_tester;
network::mojom::URLLoaderFactoryPtr factory =
CreateSubresourceLoaderFactory();
@@ -496,6 +577,9 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, Abort) {
client->RunUntilComplete();
EXPECT_EQ(net::ERR_FAILED, client->completion_status().error_code);
+ histogram_tester.ExpectUniqueSample(
+ kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kErrorAbort, 1);
}
TEST_F(ServiceWorkerSubresourceLoaderTest, DropController) {
@@ -570,9 +654,10 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, NoController) {
}
// Make the connector have no controller.
- connector_->ResetControllerConnection(nullptr);
+ connector_->UpdateController(nullptr);
base::RunLoop().RunUntilIdle();
+ base::HistogramTester histogram_tester;
{
// This should fallback to the network.
network::ResourceRequest request =
@@ -588,6 +673,9 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, NoController) {
EXPECT_EQ(1, fake_controller_.fetch_event_count());
EXPECT_EQ(1, fake_container_host_.get_controller_service_worker_count());
}
+
+ // No fetch event was dispatched, so no sample should be recorded.
+ histogram_tester.ExpectTotalCount(kHistogramSubresourceFetchEvent, 0);
}
TEST_F(ServiceWorkerSubresourceLoaderTest, DropController_RestartFetchEvent) {
@@ -623,8 +711,11 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, DropController_RestartFetchEvent) {
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());
+ client->RunUntilComplete();
}
+ base::HistogramTester histogram_tester;
+
network::ResourceRequest request =
CreateRequest(GURL("https://www.example.com/foo3.png"));
network::mojom::URLLoaderPtr loader;
@@ -641,9 +732,12 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, DropController_RestartFetchEvent) {
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());
+ histogram_tester.ExpectUniqueSample(kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
}
TEST_F(ServiceWorkerSubresourceLoaderTest, DropController_TooManyRestart) {
+ base::HistogramTester histogram_tester;
// Simulate the container host fails to start a service worker.
fake_container_host_.set_fake_controller(nullptr);
@@ -663,9 +757,15 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, DropController_TooManyRestart) {
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);
+
+ histogram_tester.ExpectUniqueSample(
+ kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kErrorStartWorkerFailed, 1);
}
TEST_F(ServiceWorkerSubresourceLoaderTest, StreamResponse) {
+ base::HistogramTester histogram_tester;
+
// Construct the Stream to respond with.
const char kResponseBody[] = "Here is sample text for the Stream.";
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
@@ -705,9 +805,14 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, StreamResponse) {
EXPECT_TRUE(
mojo::BlockingCopyToString(client->response_body_release(), &response));
EXPECT_EQ(kResponseBody, response);
+
+ histogram_tester.ExpectUniqueSample(kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
}
TEST_F(ServiceWorkerSubresourceLoaderTest, StreamResponse_Abort) {
+ base::HistogramTester histogram_tester;
+
// Construct the Stream to respond with.
const char kResponseBody[] = "Here is sample text for the Stream.";
blink::mojom::ServiceWorkerStreamCallbackPtr stream_callback;
@@ -747,11 +852,94 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, StreamResponse_Abort) {
EXPECT_TRUE(
mojo::BlockingCopyToString(client->response_body_release(), &response));
EXPECT_EQ(kResponseBody, response);
+
+ histogram_tester.ExpectUniqueSample(kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
+}
+
+TEST_F(ServiceWorkerSubresourceLoaderTest, BlobResponse) {
+ base::HistogramTester histogram_tester;
+
+ // Construct the Blob to respond with.
+ const std::string kResponseBody = "Here is sample text for the Blob.";
+ const std::vector<uint8_t> kMetadata = {0xE3, 0x81, 0x8F, 0xE3, 0x82,
+ 0x8D, 0xE3, 0x81, 0xBF, 0xE3,
+ 0x81, 0x86, 0xE3, 0x82, 0x80};
+ fake_controller_.RespondWithBlob(kMetadata, kResponseBody);
+
+ network::mojom::URLLoaderFactoryPtr factory =
+ CreateSubresourceLoaderFactory();
+
+ // Perform the request.
+ network::ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ network::mojom::URLLoaderPtr loader;
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ StartRequest(factory, request, &loader, &client);
+ client->RunUntilResponseReceived();
+
+ const network::ResourceResponseHead& info = client->response_head();
+ ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());
+
+ // Test the cached metadata.
+ client->RunUntilCachedMetadataReceived();
+ EXPECT_EQ(client->cached_metadata(),
+ std::string(kMetadata.begin(), kMetadata.end()));
+
+ 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::BlockingCopyToString(client->response_body_release(), &response));
+ EXPECT_EQ(kResponseBody, response);
+
+ histogram_tester.ExpectUniqueSample(kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
+}
+
+TEST_F(ServiceWorkerSubresourceLoaderTest, BlobResponseWithoutMetadata) {
+ base::HistogramTester histogram_tester;
+
+ // Construct the Blob to respond with.
+ const std::string kResponseBody = "Here is sample text for the Blob.";
+ fake_controller_.RespondWithBlob(base::nullopt, kResponseBody);
+
+ network::mojom::URLLoaderFactoryPtr factory =
+ CreateSubresourceLoaderFactory();
+
+ // Perform the request.
+ network::ResourceRequest request =
+ CreateRequest(GURL("https://www.example.com/foo.png"));
+ network::mojom::URLLoaderPtr loader;
+ std::unique_ptr<network::TestURLLoaderClient> client;
+ StartRequest(factory, request, &loader, &client);
+ client->RunUntilResponseReceived();
+
+ const network::ResourceResponseHead& info = client->response_head();
+ ExpectResponseInfo(info, *CreateResponseInfoFromServiceWorker());
+
+ 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::BlockingCopyToString(client->response_body_release(), &response));
+ EXPECT_EQ(kResponseBody, response);
+ EXPECT_FALSE(client->has_received_cached_metadata());
+
+ histogram_tester.ExpectUniqueSample(kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
}
// Test when the service worker responds with network fallback.
// i.e., does not call respondWith().
TEST_F(ServiceWorkerSubresourceLoaderTest, FallbackResponse) {
+ base::HistogramTester histogram_tester;
fake_controller_.RespondWithFallback();
network::mojom::URLLoaderFactoryPtr factory =
@@ -768,9 +956,13 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, FallbackResponse) {
// 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);
+
+ histogram_tester.ExpectUniqueSample(kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
}
TEST_F(ServiceWorkerSubresourceLoaderTest, ErrorResponse) {
+ base::HistogramTester histogram_tester;
fake_controller_.RespondWithError();
network::mojom::URLLoaderFactoryPtr factory =
@@ -785,9 +977,12 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, ErrorResponse) {
client->RunUntilComplete();
EXPECT_EQ(net::ERR_FAILED, client->completion_status().error_code);
+ histogram_tester.ExpectUniqueSample(kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 1);
}
TEST_F(ServiceWorkerSubresourceLoaderTest, RedirectResponse) {
+ base::HistogramTester histogram_tester;
fake_controller_.RespondWithRedirect("https://www.example.com/bar.png");
network::mojom::URLLoaderFactoryPtr factory =
@@ -813,7 +1008,7 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, RedirectResponse) {
// Redirect once more.
fake_controller_.RespondWithRedirect("https://other.example.com/baz.png");
- loader->FollowRedirect(base::nullopt);
+ loader->FollowRedirect(base::nullopt, base::nullopt);
client->RunUntilRedirectReceived();
EXPECT_EQ(net::OK, client->completion_status().error_code);
@@ -832,7 +1027,7 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, RedirectResponse) {
mojo::DataPipe data_pipe;
fake_controller_.RespondWithStream(mojo::MakeRequest(&stream_callback),
std::move(data_pipe.consumer_handle));
- loader->FollowRedirect(base::nullopt);
+ loader->FollowRedirect(base::nullopt, base::nullopt);
client->RunUntilResponseReceived();
const network::ResourceResponseHead& info = client->response_head();
@@ -858,9 +1053,15 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, RedirectResponse) {
EXPECT_TRUE(
mojo::BlockingCopyToString(client->response_body_release(), &response));
EXPECT_EQ(kResponseBody, response);
+
+ // There were 3 fetch events, so expect a count of 3.
+ histogram_tester.ExpectUniqueSample(kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk, 3);
}
TEST_F(ServiceWorkerSubresourceLoaderTest, TooManyRedirects) {
+ base::HistogramTester histogram_tester;
+
int count = 1;
std::string redirect_location =
std::string("https://www.example.com/redirect_") +
@@ -897,7 +1098,7 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, TooManyRedirects) {
redirect_location = std::string("https://www.example.com/redirect_") +
base::IntToString(count);
fake_controller_.RespondWithRedirect(redirect_location);
- loader->FollowRedirect(base::nullopt);
+ loader->FollowRedirect(base::nullopt, base::nullopt);
}
client->RunUntilComplete();
@@ -905,6 +1106,11 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, TooManyRedirects) {
EXPECT_FALSE(client->has_received_redirect());
EXPECT_EQ(net::ERR_TOO_MANY_REDIRECTS,
client->completion_status().error_code);
+
+ // Expect a sample for each fetch event (kMaxRedirects + 1).
+ histogram_tester.ExpectUniqueSample(kHistogramSubresourceFetchEvent,
+ blink::ServiceWorkerStatusCode::kOk,
+ net::URLRequest::kMaxRedirects + 1);
}
// Test when the service worker responds with network fallback to CORS request.
@@ -996,4 +1202,5 @@ TEST_F(ServiceWorkerSubresourceLoaderTest, FallbackWithRequestBody_DataPipe) {
RunFallbackWithRequestBodyTest(std::move(request_body), kData);
}
+} // namespace service_worker_subresource_loader_unittest
} // namespace content
diff --git a/chromium/content/renderer/service_worker/service_worker_timeout_timer.cc b/chromium/content/renderer/service_worker/service_worker_timeout_timer.cc
index 83b78f2fb59..f61a8b98a5d 100644
--- a/chromium/content/renderer/service_worker/service_worker_timeout_timer.cc
+++ b/chromium/content/renderer/service_worker/service_worker_timeout_timer.cc
@@ -7,8 +7,8 @@
#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"
#include "services/network/public/cpp/features.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
@@ -93,20 +93,20 @@ void ServiceWorkerTimeoutTimer::EndEvent(int event_id) {
void ServiceWorkerTimeoutTimer::PushPendingTask(
base::OnceClosure pending_task) {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
DCHECK(did_idle_timeout());
pending_tasks_.emplace(std::move(pending_task));
}
void ServiceWorkerTimeoutTimer::SetIdleTimerDelayToZero() {
- DCHECK(ServiceWorkerUtils::IsServicificationEnabled());
+ DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
zero_idle_timer_delay_ = true;
if (inflight_events_.empty())
MaybeTriggerIdleTimer();
}
void ServiceWorkerTimeoutTimer::UpdateStatus() {
- if (!ServiceWorkerUtils::IsServicificationEnabled())
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled())
return;
base::TimeTicks now = tick_clock_->NowTicks();
diff --git a/chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc b/chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
index 540a9912af8..27396c1bea6 100644
--- a/chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
+++ b/chromium/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
@@ -10,9 +10,9 @@
#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 "services/network/public/cpp/features.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
namespace content {
@@ -59,7 +59,7 @@ class ServiceWorkerTimeoutTimerTest : public testing::Test {
void EnableServicification() {
feature_list_.InitWithFeatures({network::features::kNetworkService}, {});
- ASSERT_TRUE(ServiceWorkerUtils::IsServicificationEnabled());
+ ASSERT_TRUE(blink::ServiceWorkerUtils::IsServicificationEnabled());
}
base::TestMockTimeTaskRunner* task_runner() { return task_runner_.get(); }
@@ -273,7 +273,8 @@ TEST_F(ServiceWorkerTimeoutTimerTest, SetIdleTimerDelayToZero) {
}
TEST_F(ServiceWorkerTimeoutTimerTest, NonS13nServiceWorker) {
- ASSERT_FALSE(ServiceWorkerUtils::IsServicificationEnabled());
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
+ return;
MockEvent event;
{
diff --git a/chromium/content/renderer/service_worker/service_worker_type_converters.cc b/chromium/content/renderer/service_worker/service_worker_type_converters.cc
index 3065d0e543e..ca15fab9670 100644
--- a/chromium/content/renderer/service_worker/service_worker_type_converters.cc
+++ b/chromium/content/renderer/service_worker/service_worker_type_converters.cc
@@ -72,15 +72,9 @@ blink::WebPaymentMethodData
TypeConverter<blink::WebPaymentMethodData,
payments::mojom::PaymentMethodDataPtr>::
Convert(const payments::mojom::PaymentMethodDataPtr& input) {
+ DCHECK(!input->supported_method.empty());
blink::WebPaymentMethodData output;
-
- output.supported_methods =
- blink::WebVector<blink::WebString>(input->supported_methods.size());
- for (size_t i = 0; i < input->supported_methods.size(); i++) {
- output.supported_methods[i] =
- blink::WebString::FromUTF8(input->supported_methods[i]);
- }
-
+ output.supported_method = blink::WebString::FromUTF8(input->supported_method);
output.stringified_data = blink::WebString::FromUTF8(input->stringified_data);
return output;
@@ -111,14 +105,11 @@ blink::WebPaymentDetailsModifier
TypeConverter<blink::WebPaymentDetailsModifier,
payments::mojom::PaymentDetailsModifierPtr>::
Convert(const payments::mojom::PaymentDetailsModifierPtr& input) {
+ DCHECK(!input->method_data->supported_method.empty());
blink::WebPaymentDetailsModifier output;
- output.supported_methods = blink::WebVector<blink::WebString>(
- input->method_data->supported_methods.size());
- for (size_t i = 0; i < input->method_data->supported_methods.size(); i++) {
- output.supported_methods[i] =
- blink::WebString::FromUTF8(input->method_data->supported_methods[i]);
- }
+ output.supported_method =
+ blink::WebString::FromUTF8(input->method_data->supported_method);
output.total = mojo::ConvertTo<blink::WebPaymentItem>(input->total);
diff --git a/chromium/content/renderer/service_worker/service_worker_type_converters.h b/chromium/content/renderer/service_worker/service_worker_type_converters.h
index b5ea9ca7bcb..796c7467632 100644
--- a/chromium/content/renderer/service_worker/service_worker_type_converters.h
+++ b/chromium/content/renderer/service_worker/service_worker_type_converters.h
@@ -5,13 +5,13 @@
#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_TYPE_CONVERTERS_H_
#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_TYPE_CONVERTERS_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.mojom.h"
+#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
#include "third_party/blink/public/platform/modules/payments/payment_app.mojom.h"
#include "third_party/blink/public/platform/modules/payments/web_can_make_payment_event_data.h"
#include "third_party/blink/public/platform/modules/payments/web_payment_request_event_data.h"
-#include "third_party/blink/public/web/modules/serviceworker/web_service_worker_context_proxy.h"
+#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h"
namespace mojo {
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 7741366348f..020f30164d2 100644
--- a/chromium/content/renderer/service_worker/service_worker_type_util.cc
+++ b/chromium/content/renderer/service_worker/service_worker_type_util.cc
@@ -10,8 +10,8 @@
#include "base/strings/utf_string_conversions.h"
#include "content/common/service_worker/service_worker_types.h"
#include "storage/common/blob_storage/blob_handle.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_request.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_response.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_response.h"
#include "third_party/blink/public/platform/web_http_header_visitor.h"
#include "third_party/blink/public/platform/web_string.h"
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 9e658ffe675..c0e8d6dbff2 100644
--- a/chromium/content/renderer/service_worker/thread_safe_script_container.h
+++ b/chromium/content/renderer/service_worker/thread_safe_script_container.h
@@ -12,7 +12,7 @@
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_installed_scripts_manager.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_installed_scripts_manager.h"
namespace content {
diff --git a/chromium/content/renderer/service_worker/web_service_worker_impl.cc b/chromium/content/renderer/service_worker/web_service_worker_impl.cc
index 2d3322a6f44..dba3fc329f7 100644
--- a/chromium/content/renderer/service_worker/web_service_worker_impl.cc
+++ b/chromium/content/renderer/service_worker/web_service_worker_impl.cc
@@ -11,7 +11,7 @@
#include "content/renderer/service_worker/service_worker_context_client.h"
#include "content/renderer/service_worker/service_worker_provider_context.h"
#include "content/renderer/service_worker/web_service_worker_provider_impl.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_proxy.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_proxy.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/public/platform/web_string.h"
diff --git a/chromium/content/renderer/service_worker/web_service_worker_impl.h b/chromium/content/renderer/service_worker/web_service_worker_impl.h
index 60e7f7e8584..8e183fa77f5 100644
--- a/chromium/content/renderer/service_worker/web_service_worker_impl.h
+++ b/chromium/content/renderer/service_worker/web_service_worker_impl.h
@@ -15,7 +15,7 @@
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker.h"
#include "third_party/blink/public/web/web_frame.h"
namespace blink {
@@ -51,8 +51,8 @@ class ServiceWorkerProviderContext;
// blink::mojom::ServiceWorkerObjectInfo, otherwise reuse the existing one.
//
// WebServiceWorkerImpl holds a Mojo connection (|host_|). The connection keeps
-// the ServiceWorkerHandle in the browser process alive, which in turn keeps the
-// relevant ServiceWorkerVersion alive.
+// the ServiceWorkerObjectHost in the browser process alive, which in turn keeps
+// the relevant ServiceWorkerVersion alive.
class CONTENT_EXPORT WebServiceWorkerImpl
: public blink::mojom::ServiceWorkerObject,
public blink::WebServiceWorker,
@@ -93,11 +93,11 @@ class CONTENT_EXPORT WebServiceWorkerImpl
// worker thread for service worker execution contexts.
//
// |host_| keeps the Mojo connection to the
- // browser-side ServiceWorkerHandle, whose lifetime is bound
+ // browser-side ServiceWorkerObjectHost, whose lifetime is bound
// to |host_| via the Mojo connection.
blink::mojom::ServiceWorkerObjectHostAssociatedPtr host_;
// |binding_| keeps the Mojo binding to serve its other Mojo endpoint (i.e.
- // the caller end) held by the content::ServiceWorkerHandle in the browser
+ // the caller end) held by the content::ServiceWorkerObjectHost in the browser
// process.
mojo::AssociatedBinding<blink::mojom::ServiceWorkerObject> binding_;
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 d9e7d0abe4c..5054d4830a0 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
@@ -11,7 +11,7 @@
#include "base/single_thread_task_runner.h"
#include "content/renderer/service_worker/thread_safe_script_container.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_installed_scripts_manager.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_installed_scripts_manager.h"
namespace content {
diff --git a/chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc
index 2813f6b69f4..f4ddf8af5be 100644
--- a/chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc
+++ b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.cc
@@ -16,7 +16,7 @@
#include "third_party/blink/public/common/message_port/message_port_channel.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_provider_client.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h"
#include "third_party/blink/public/platform/web_url.h"
using blink::WebURL;
@@ -230,7 +230,7 @@ void WebServiceWorkerProviderImpl::OnRegistered(
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration) {
TRACE_EVENT_ASYNC_END2(
"ServiceWorker", "WebServiceWorkerProviderImpl::RegisterServiceWorker",
- this, "Error", ServiceWorkerUtils::ErrorTypeToString(error), "Message",
+ this, "Error", ServiceWorkerUtils::MojoEnumToString(error), "Message",
error_msg ? *error_msg : "Success");
if (error != blink::mojom::ServiceWorkerErrorType::kNone) {
DCHECK(error_msg);
@@ -256,7 +256,7 @@ void WebServiceWorkerProviderImpl::OnDidGetRegistration(
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration) {
TRACE_EVENT_ASYNC_END2("ServiceWorker",
"WebServiceWorkerProviderImpl::GetRegistration", this,
- "Error", ServiceWorkerUtils::ErrorTypeToString(error),
+ "Error", ServiceWorkerUtils::MojoEnumToString(error),
"Message", error_msg ? *error_msg : "Success");
if (error != blink::mojom::ServiceWorkerErrorType::kNone) {
DCHECK(error_msg);
@@ -292,7 +292,7 @@ void WebServiceWorkerProviderImpl::OnDidGetRegistrations(
infos) {
TRACE_EVENT_ASYNC_END2("ServiceWorker",
"WebServiceWorkerProviderImpl::GetRegistrations", this,
- "Error", ServiceWorkerUtils::ErrorTypeToString(error),
+ "Error", ServiceWorkerUtils::MojoEnumToString(error),
"Message", error_msg ? *error_msg : "Success");
if (error != blink::mojom::ServiceWorkerErrorType::kNone) {
DCHECK(error_msg);
diff --git a/chromium/content/renderer/service_worker/web_service_worker_provider_impl.h b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.h
index b496a3f2f1a..9c73253eee5 100644
--- a/chromium/content/renderer/service_worker/web_service_worker_provider_impl.h
+++ b/chromium/content/renderer/service_worker/web_service_worker_provider_impl.h
@@ -15,7 +15,7 @@
#include "third_party/blink/public/common/message_port/transferable_message.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_provider.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h"
#include "third_party/blink/public/platform/web_feature.mojom.h"
namespace blink {
diff --git a/chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc b/chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc
index 8c78ad3263a..bd98361eb53 100644
--- a/chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc
+++ b/chromium/content/renderer/service_worker/web_service_worker_registration_impl.cc
@@ -13,9 +13,9 @@
#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/blink/public/platform/modules/serviceworker/web_navigation_preload_state.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_error.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_registration_proxy.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_navigation_preload_state.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_registration_proxy.h"
namespace content {
@@ -150,21 +150,8 @@ WebServiceWorkerRegistrationImpl::UpdateViaCache() const {
void WebServiceWorkerRegistrationImpl::Update(
std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks) {
- host_->Update(base::BindOnce(
- [](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();
- },
- std::move(callbacks)));
+ host_->Update(base::BindOnce(&WebServiceWorkerRegistrationImpl::OnUpdated,
+ this, std::move(callbacks)));
}
void WebServiceWorkerRegistrationImpl::Unregister(
@@ -321,6 +308,19 @@ WebServiceWorkerRegistrationImpl::GetOrCreateServiceWorkerObject(
return service_worker;
}
+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) {
+ callbacks->OnError(blink::WebServiceWorkerError(
+ error, blink::WebString::FromUTF8(*error_msg)));
+ return;
+ }
+ callbacks->OnSuccess(WebServiceWorkerRegistrationImpl::CreateHandle(
+ base::WrapRefCounted(this)));
+}
+
void WebServiceWorkerRegistrationImpl::SetVersionAttributes(
int changed_mask,
blink::mojom::ServiceWorkerObjectInfoPtr installing,
diff --git a/chromium/content/renderer/service_worker/web_service_worker_registration_impl.h b/chromium/content/renderer/service_worker/web_service_worker_registration_impl.h
index 4405d0415b7..e57e36208f4 100644
--- a/chromium/content/renderer/service_worker/web_service_worker_registration_impl.h
+++ b/chromium/content/renderer/service_worker/web_service_worker_registration_impl.h
@@ -19,7 +19,7 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_registration.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_registration.h"
namespace blink {
class WebServiceWorkerRegistrationProxy;
@@ -123,6 +123,10 @@ class CONTENT_EXPORT WebServiceWorkerRegistrationImpl
scoped_refptr<WebServiceWorkerImpl> GetOrCreateServiceWorkerObject(
blink::mojom::ServiceWorkerObjectInfoPtr info);
+ void OnUpdated(std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks,
+ blink::mojom::ServiceWorkerErrorType error,
+ const base::Optional<std::string>& error_msg);
+
// Implements blink::mojom::ServiceWorkerRegistrationObject.
void SetVersionAttributes(
int changed_mask,
diff --git a/chromium/content/renderer/shared_worker/OWNERS b/chromium/content/renderer/shared_worker/OWNERS
index 595a38572a7..6bda8b5e83f 100644
--- a/chromium/content/renderer/shared_worker/OWNERS
+++ b/chromium/content/renderer/shared_worker/OWNERS
@@ -1,3 +1,4 @@
+falken@chromium.org
horo@chromium.org
nhiroki@chromium.org
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 edf1d066262..a2be7d7cdef 100644
--- a/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc
+++ b/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -12,27 +12,34 @@
#include "base/threading/thread_task_runner_handle.h"
#include "content/child/scoped_child_process_reference.h"
#include "content/common/possibly_associated_wrapper_shared_url_loader_factory.h"
-#include "content/common/service_worker/service_worker_utils.h"
+#include "content/common/url_loader_factory_bundle.h"
#include "content/public/common/appcache_info.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/origin_util.h"
+#include "content/public/common/renderer_preferences.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/appcache/appcache_dispatcher.h"
#include "content/renderer/appcache/web_application_cache_host_impl.h"
#include "content/renderer/loader/child_url_loader_factory_bundle.h"
#include "content/renderer/loader/request_extra_data.h"
+#include "content/renderer/loader/tracked_child_url_loader_factory_bundle.h"
+#include "content/renderer/loader/web_worker_fetch_context_impl.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/renderer_blink_platform_impl.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 "ipc/ipc_message_macros.h"
+#include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "third_party/blink/public/common/message_port/message_port_channel.h"
+#include "third_party/blink/public/common/privacy_preferences.h"
+#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
#include "third_party/blink/public/platform/interface_provider.h"
-#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_network_provider.h"
+#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
+#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/url_conversion.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/web/web_shared_worker.h"
@@ -98,14 +105,16 @@ class WebServiceWorkerNetworkProviderForSharedWorker
// request and break the assumptions of the renderer.
if (request.GetRequestContext() !=
blink::WebURLRequest::kRequestContextSharedWorker &&
- !provider_->IsControlledByServiceWorker()) {
+ provider_->IsControlledByServiceWorker() ==
+ blink::mojom::ControllerServiceWorkerMode::kNoController) {
request.SetSkipServiceWorker(true);
}
}
int ProviderID() const override { return provider_->provider_id(); }
- bool HasControllerServiceWorker() override {
+ blink::mojom::ControllerServiceWorkerMode IsControlledByServiceWorker()
+ override {
return provider_->IsControlledByServiceWorker();
}
@@ -119,10 +128,11 @@ class WebServiceWorkerNetworkProviderForSharedWorker
std::unique_ptr<blink::WebURLLoader> CreateURLLoader(
const blink::WebURLRequest& request,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
+ std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle>
+ task_runner_handle) override {
// S13nServiceWorker:
// We only install our own URLLoader if Servicification is enabled.
- if (!ServiceWorkerUtils::IsServicificationEnabled())
+ if (!blink::ServiceWorkerUtils::IsServicificationEnabled())
return nullptr;
RenderThreadImpl* render_thread = RenderThreadImpl::current();
@@ -137,20 +147,28 @@ class WebServiceWorkerNetworkProviderForSharedWorker
// TODO(crbug.com/796425): Temporarily wrap the raw
// mojom::URLLoaderFactory pointer into SharedURLLoaderFactory.
return std::make_unique<WebURLLoaderImpl>(
- render_thread->resource_dispatcher(), std::move(task_runner),
+ render_thread->resource_dispatcher(), std::move(task_runner_handle),
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
provider_->script_loader_factory()));
}
- // Otherwise, it's an importScript. Use the subresource loader factory.
+ // Otherwise, it's an importScript. Use the subresource loader factory if
+ // it exists (we are controlled by a service worker).
if (!provider_->context() ||
!provider_->context()->GetSubresourceLoaderFactory()) {
return nullptr;
}
- // If it's not for HTTP or HTTPS, no need to intercept the request.
- if (!GURL(request.Url()).SchemeIsHTTPOrHTTPS())
+ // If the URL is not http(s) or otherwise whitelisted, do not intercept the
+ // request. Schemes like 'blob' and 'file' are not eligible to be
+ // intercepted by service workers.
+ // TODO(falken): Let ServiceWorkerSubresourceLoaderFactory handle the
+ // request and move this check there (i.e., for such URLs, it should use
+ // its fallback factory).
+ if (!GURL(request.Url()).SchemeIsHTTPOrHTTPS() &&
+ !OriginCanAccessServiceWorkers(request.Url())) {
return nullptr;
+ }
// If GetSkipServiceWorker() returns true, do not intercept the request.
if (request.GetSkipServiceWorker())
@@ -162,7 +180,7 @@ class WebServiceWorkerNetworkProviderForSharedWorker
// pointer into SharedURLLoaderFactory.
return std::make_unique<WebURLLoaderImpl>(
RenderThreadImpl::current()->resource_dispatcher(),
- std::move(task_runner),
+ std::move(task_runner_handle),
base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
provider_->context()->GetSubresourceLoaderFactory()));
}
@@ -178,18 +196,21 @@ EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
mojom::SharedWorkerInfoPtr info,
bool pause_on_start,
const base::UnguessableToken& devtools_worker_token,
+ const RendererPreferences& renderer_preferences,
blink::mojom::WorkerContentSettingsProxyPtr content_settings,
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_info,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider)
: binding_(this, std::move(request)),
host_(std::move(host)),
name_(info->name),
- url_(info->url) {
+ url_(info->url),
+ renderer_preferences_(renderer_preferences) {
impl_ = blink::WebSharedWorker::Create(this);
if (pause_on_start) {
// Pause worker context when it starts and wait until either DevTools client
@@ -200,11 +221,40 @@ EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
service_worker_provider_info_ = std::move(service_worker_provider_info);
script_loader_factory_info_ = std::move(script_loader_factory_info);
+ // Make the factory bundle.
+ loader_factories_ = base::MakeRefCounted<HostChildURLLoaderFactoryBundle>(
+ impl_->GetTaskRunner(blink::TaskType::kInternalLoading));
+ // In some tests |render_thread| could be null.
+ if (RenderThreadImpl* render_thread = RenderThreadImpl::current()) {
+ loader_factories_->Update(render_thread->blink_platform_impl()
+ ->CreateDefaultURLLoaderFactoryBundle()
+ ->PassInterface(),
+ base::nullopt /* subresource_overrides */);
+ }
+
+ if (subresource_loaders) {
+ loader_factories_->Update(std::make_unique<ChildURLLoaderFactoryBundleInfo>(
+ std::move(subresource_loaders)),
+ base::nullopt /* subresource_overrides */);
+ }
+
+ // It is important to understand the default factory of |loader_factories_|.
+ // |loader_factories_| was made from CreateDefaultURLLoaderFactoryBundle,
+ // which does not set a default factory, and |subresource_loaders|, whose
+ // default factory is the direct network factory (as SharedWorkerHost sets it
+ // that way). Therefore, the default factory either does not exist or is the
+ // direct network factory. So we don't need to call CloneWithoutDefault() to
+ // bypass features like AppCache, unlike the bundle created for a frame.
+
impl_->StartWorkerContext(
url_, blink::WebString::FromUTF8(name_),
blink::WebString::FromUTF8(info->content_security_policy),
info->content_security_policy_type, info->creation_address_space,
- devtools_worker_token, content_settings.PassInterface().PassHandle(),
+ devtools_worker_token,
+ blink::PrivacyPreferences(renderer_preferences_.enable_do_not_track,
+ renderer_preferences_.enable_referrers),
+ loader_factories_,
+ content_settings.PassInterface().PassHandle(),
interface_provider.PassInterface().PassHandle());
// If the host drops its connection, then self-destruct.
@@ -275,20 +325,11 @@ EmbeddedSharedWorkerStub::CreateApplicationCacheHost(
std::unique_ptr<blink::WebServiceWorkerNetworkProvider>
EmbeddedSharedWorkerStub::CreateServiceWorkerNetworkProvider() {
- scoped_refptr<network::SharedURLLoaderFactory> fallback_factory;
- // current() may be null in tests.
- if (RenderThreadImpl* render_thread = RenderThreadImpl::current()) {
- scoped_refptr<ChildURLLoaderFactoryBundle> bundle =
- render_thread->blink_platform_impl()
- ->CreateDefaultURLLoaderFactoryBundle();
- fallback_factory = network::SharedURLLoaderFactory::Create(
- bundle->CloneWithoutDefaultFactory());
- }
-
std::unique_ptr<ServiceWorkerNetworkProvider> provider =
ServiceWorkerNetworkProvider::CreateForSharedWorker(
std::move(service_worker_provider_info_),
- std::move(script_loader_factory_info_), std::move(fallback_factory));
+ std::move(script_loader_factory_info_), loader_factories_);
+
return std::make_unique<WebServiceWorkerNetworkProviderForSharedWorker>(
std::move(provider), IsOriginSecure(url_));
}
@@ -313,33 +354,46 @@ EmbeddedSharedWorkerStub::CreateWorkerFetchContext(
web_network_provider)
->provider()
->context();
- mojom::ServiceWorkerWorkerClientRequest request =
- context->CreateWorkerClientRequest();
+
+ mojom::ServiceWorkerWorkerClientRegistryPtrInfo
+ worker_client_registry_ptr_info;
+ context->CloneWorkerClientRegistry(
+ mojo::MakeRequest(&worker_client_registry_ptr_info));
+
+ mojom::ServiceWorkerWorkerClientPtr worker_client_ptr;
+ mojom::ServiceWorkerWorkerClientRequest worker_client_request =
+ mojo::MakeRequest(&worker_client_ptr);
+ context->RegisterWorkerClient(std::move(worker_client_ptr));
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())
+ if (blink::ServiceWorkerUtils::IsServicificationEnabled())
container_host_ptr_info = context->CloneContainerHostPtrInfo();
- scoped_refptr<ChildURLLoaderFactoryBundle> url_loader_factory_bundle =
- RenderThreadImpl::current()
- ->blink_platform_impl()
- ->CreateDefaultURLLoaderFactoryBundle();
- auto worker_fetch_context = std::make_unique<WorkerFetchContextImpl>(
- std::move(request), std::move(container_host_ptr_info),
- url_loader_factory_bundle->Clone(),
- url_loader_factory_bundle->CloneWithoutDefaultFactory(),
+ // We know |loader_factories_|'s default factory is not a feature like
+ // AppCache, so it's OK to call Clone() and not CloneWithoutDefault() to get
+ // the fallback factory. We don't want to call CloneWithoutDefault() because
+ // the default is a NetworkService-backed factory with auto-reconnect
+ // when NetworkService is enabled (it will support auto-reconnect once
+ // https://crbug.com/848256 is addressed). See comments in the constructor.
+ //
+ // TODO(falken): We might need to set the default factory of
+ // |loader_factories_| to AppCache if requests from this shared worker are
+ // supposed to go through AppCache.
+ std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory =
+ loader_factories_->Clone();
+
+ auto worker_fetch_context = std::make_unique<WebWorkerFetchContextImpl>(
+ std::move(renderer_preferences_), std::move(worker_client_request),
+ std::move(worker_client_registry_ptr_info),
+ std::move(container_host_ptr_info), loader_factories_->Clone(),
+ std::move(fallback_factory),
GetContentClient()->renderer()->CreateURLLoaderThrottleProvider(
URLLoaderThrottleProviderType::kWorker),
GetContentClient()
->renderer()
->CreateWebSocketHandshakeThrottleProvider(),
ChildThreadImpl::current()->thread_safe_sender(),
- RenderThreadImpl::current()->GetIOTaskRunner());
+ ChildThreadImpl::current()->GetConnector()->Clone());
// 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.
@@ -353,13 +407,11 @@ EmbeddedSharedWorkerStub::CreateWorkerFetchContext(
// 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());
- worker_fetch_context->set_is_controlled_by_service_worker(
- web_network_provider->HasControllerServiceWorker());
- }
+ worker_fetch_context->set_service_worker_provider_id(context->provider_id());
+ worker_fetch_context->set_is_controlled_by_service_worker(
+ context->IsControlledByServiceWorker());
worker_fetch_context->set_client_id(context->client_id());
+
return std::move(worker_fetch_context);
}
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 25b8d13f4d8..6014d199411 100644
--- a/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.h
+++ b/chromium/content/renderer/shared_worker/embedded_shared_worker_stub.h
@@ -15,7 +15,7 @@
#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 "content/public/common/renderer_preferences.h"
#include "ipc/ipc_listener.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
@@ -40,6 +40,8 @@ class MessagePortChannel;
}
namespace content {
+class HostChildURLLoaderFactoryBundle;
+class URLLoaderFactoryBundleInfo;
class WebApplicationCacheHostImpl;
// A stub class to receive IPC from browser process and talk to
@@ -58,11 +60,13 @@ class EmbeddedSharedWorkerStub : public blink::WebSharedWorkerClient,
mojom::SharedWorkerInfoPtr info,
bool pause_on_start,
const base::UnguessableToken& devtools_worker_token,
+ const RendererPreferences& renderer_preferences,
blink::mojom::WorkerContentSettingsProxyPtr content_settings,
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_info,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider);
@@ -104,6 +108,7 @@ class EmbeddedSharedWorkerStub : public blink::WebSharedWorkerClient,
const std::string name_;
bool running_ = false;
GURL url_;
+ RendererPreferences renderer_preferences_;
std::unique_ptr<blink::WebSharedWorker> impl_;
using PendingChannel =
@@ -121,6 +126,10 @@ class EmbeddedSharedWorkerStub : public blink::WebSharedWorkerClient,
// script.
network::mojom::URLLoaderFactoryAssociatedPtrInfo script_loader_factory_info_;
+ // S13nServiceWorker: The factory bundle used for loads from this shared
+ // worker.
+ scoped_refptr<HostChildURLLoaderFactoryBundle> loader_factories_;
+
DISALLOW_COPY_AND_ASSIGN(EmbeddedSharedWorkerStub);
};
diff --git a/chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc b/chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc
index 3fe8d6c26b6..48a5091476b 100644
--- a/chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc
+++ b/chromium/content/renderer/shared_worker/shared_worker_factory_impl.cc
@@ -5,6 +5,7 @@
#include "content/renderer/shared_worker/shared_worker_factory_impl.h"
#include "base/memory/ptr_util.h"
+#include "content/common/url_loader_factory_bundle.h"
#include "content/renderer/shared_worker/embedded_shared_worker_stub.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
@@ -23,20 +24,23 @@ void SharedWorkerFactoryImpl::CreateSharedWorker(
mojom::SharedWorkerInfoPtr info,
bool pause_on_start,
const base::UnguessableToken& devtools_worker_token,
+ const RendererPreferences& renderer_preferences,
blink::mojom::WorkerContentSettingsProxyPtr content_settings,
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_ptr_info,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
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, devtools_worker_token,
- std::move(content_settings), std::move(service_worker_provider_info),
- std::move(script_loader_factory_ptr_info), std::move(host),
- std::move(request), std::move(interface_provider));
+ renderer_preferences, std::move(content_settings),
+ std::move(service_worker_provider_info),
+ std::move(script_loader_factory_ptr_info), std::move(subresource_loaders),
+ 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 0fc2cfdf23c..78aef0102e6 100644
--- a/chromium/content/renderer/shared_worker/shared_worker_factory_impl.h
+++ b/chromium/content/renderer/shared_worker/shared_worker_factory_impl.h
@@ -11,6 +11,7 @@
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace content {
+class URLLoaderFactoryBundleInfo;
class SharedWorkerFactoryImpl : public mojom::SharedWorkerFactory {
public:
@@ -24,11 +25,13 @@ class SharedWorkerFactoryImpl : public mojom::SharedWorkerFactory {
mojom::SharedWorkerInfoPtr info,
bool pause_on_start,
const base::UnguessableToken& devtools_worker_token,
+ const RendererPreferences& renderer_preferences,
blink::mojom::WorkerContentSettingsProxyPtr content_settings,
mojom::ServiceWorkerProviderInfoForSharedWorkerPtr
service_worker_provider_info,
network::mojom::URLLoaderFactoryAssociatedPtrInfo
script_loader_factory_ptr_info,
+ std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
mojom::SharedWorkerHostPtr host,
mojom::SharedWorkerRequest request,
service_manager::mojom::InterfaceProviderPtr interface_provider) override;
diff --git a/chromium/content/renderer/shared_worker/shared_worker_repository.cc b/chromium/content/renderer/shared_worker/shared_worker_repository.cc
index 562ef5b2e82..a6dbd115561 100644
--- a/chromium/content/renderer/shared_worker/shared_worker_repository.cc
+++ b/chromium/content/renderer/shared_worker/shared_worker_repository.cc
@@ -26,6 +26,7 @@ void SharedWorkerRepository::Connect(
blink::mojom::IPAddressSpace creation_address_space,
blink::mojom::SharedWorkerCreationContextType creation_context_type,
blink::MessagePortChannel channel,
+ mojo::ScopedMessagePipeHandle blob_url_token,
std::unique_ptr<blink::WebSharedWorkerConnectListener> listener) {
// Lazy bind the connector.
if (!connector_)
@@ -40,8 +41,11 @@ void SharedWorkerRepository::Connect(
std::make_unique<SharedWorkerClientImpl>(std::move(listener)),
mojo::MakeRequest(&client));
- connector_->Connect(std::move(info), std::move(client), creation_context_type,
- channel.ReleaseHandle());
+ connector_->Connect(
+ std::move(info), std::move(client), creation_context_type,
+ channel.ReleaseHandle(),
+ blink::mojom::BlobURLTokenPtr(blink::mojom::BlobURLTokenPtrInfo(
+ std::move(blob_url_token), blink::mojom::BlobURLToken::Version_)));
}
void SharedWorkerRepository::DocumentDetached(DocumentID 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 d0a8ce2c909..066976ba6dc 100644
--- a/chromium/content/renderer/shared_worker/shared_worker_repository.h
+++ b/chromium/content/renderer/shared_worker/shared_worker_repository.h
@@ -44,6 +44,7 @@ class SharedWorkerRepository final
blink::mojom::IPAddressSpace,
blink::mojom::SharedWorkerCreationContextType,
blink::MessagePortChannel channel,
+ mojo::ScopedMessagePipeHandle blob_url_token,
std::unique_ptr<blink::WebSharedWorkerConnectListener> listener) override;
void DocumentDetached(DocumentID document_id) override;
diff --git a/chromium/content/renderer/speech_recognition_dispatcher.cc b/chromium/content/renderer/speech_recognition_dispatcher.cc
deleted file mode 100644
index 248a3f1d117..00000000000
--- a/chromium/content/renderer/speech_recognition_dispatcher.cc
+++ /dev/null
@@ -1,248 +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/speech_recognition_dispatcher.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <utility>
-
-#include "base/strings/utf_string_conversions.h"
-#include "build/build_config.h"
-#include "content/public/common/service_names.mojom.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/renderer/render_frame_impl.h"
-#include "services/service_manager/public/cpp/connector.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/web_speech_grammar.h"
-#include "third_party/blink/public/web/web_speech_recognition_params.h"
-#include "third_party/blink/public/web/web_speech_recognition_result.h"
-
-using blink::WebVector;
-using blink::WebString;
-using blink::WebSpeechGrammar;
-using blink::WebSpeechRecognitionHandle;
-using blink::WebSpeechRecognitionResult;
-using blink::WebSpeechRecognitionParams;
-using blink::WebSpeechRecognizerClient;
-
-namespace content {
-
-SpeechRecognitionDispatcher::SpeechRecognitionDispatcher(
- RenderFrame* render_frame)
- : RenderFrameObserver(render_frame) {}
-
-SpeechRecognitionDispatcher::~SpeechRecognitionDispatcher() = default;
-
-void SpeechRecognitionDispatcher::OnDestruct() {
- delete this;
-}
-
-void SpeechRecognitionDispatcher::WasHidden() {
-#if defined(OS_ANDROID)
- for (const auto& it : session_map_) {
- it.second->Abort();
- }
-#endif
-}
-
-void SpeechRecognitionDispatcher::Start(
- const WebSpeechRecognitionHandle& handle,
- const WebSpeechRecognitionParams& params,
- const WebSpeechRecognizerClient& recognizer_client) {
- DCHECK(recognizer_client_.IsNull() ||
- recognizer_client_ == recognizer_client);
- recognizer_client_ = recognizer_client;
-
- mojom::StartSpeechRecognitionRequestParamsPtr msg_params =
- mojom::StartSpeechRecognitionRequestParams::New();
- for (const WebSpeechGrammar& grammar : params.Grammars()) {
- msg_params->grammars.push_back(
- mojom::SpeechRecognitionGrammar::New(grammar.Src(), grammar.Weight()));
- }
- msg_params->language = params.Language().Utf8();
- msg_params->max_hypotheses = static_cast<uint32_t>(params.MaxAlternatives());
- msg_params->continuous = params.Continuous();
- msg_params->interim_results = params.InterimResults();
- msg_params->origin = params.Origin();
-
- mojom::SpeechRecognitionSessionClientPtrInfo client_ptr_info;
- mojom::SpeechRecognitionSessionClientRequest client_request =
- mojo::MakeRequest(&client_ptr_info);
- bindings_.AddBinding(std::make_unique<SpeechRecognitionSessionClientImpl>(
- this, handle, recognizer_client_),
- std::move(client_request));
-
- mojom::SpeechRecognitionSessionPtr session_client;
- mojom::SpeechRecognitionSessionRequest request =
- mojo::MakeRequest(&session_client);
-
- AddHandle(handle, std::move(session_client));
-
- msg_params->client = std::move(client_ptr_info);
- msg_params->session_request = std::move(request);
-
- GetSpeechRecognitionHost().Start(std::move(msg_params));
-}
-
-void SpeechRecognitionDispatcher::Stop(
- const WebSpeechRecognitionHandle& handle,
- const WebSpeechRecognizerClient& recognizer_client) {
- // Ignore a |stop| issued without a matching |start|.
- if (recognizer_client_ != recognizer_client || !HandleExists(handle))
- return;
- GetSession(handle)->StopCapture();
-}
-
-void SpeechRecognitionDispatcher::Abort(
- const WebSpeechRecognitionHandle& handle,
- const WebSpeechRecognizerClient& recognizer_client) {
- // Ignore an |abort| issued without a matching |start|.
- if (recognizer_client_ != recognizer_client || !HandleExists(handle))
- return;
- GetSession(handle)->Abort();
-}
-
-static WebSpeechRecognizerClient::ErrorCode WebKitErrorCode(
- SpeechRecognitionErrorCode e) {
- switch (e) {
- case SPEECH_RECOGNITION_ERROR_NONE:
- NOTREACHED();
- return WebSpeechRecognizerClient::kOtherError;
- case SPEECH_RECOGNITION_ERROR_NO_SPEECH:
- return WebSpeechRecognizerClient::kNoSpeechError;
- case SPEECH_RECOGNITION_ERROR_ABORTED:
- return WebSpeechRecognizerClient::kAbortedError;
- case SPEECH_RECOGNITION_ERROR_AUDIO_CAPTURE:
- return WebSpeechRecognizerClient::kAudioCaptureError;
- case SPEECH_RECOGNITION_ERROR_NETWORK:
- return WebSpeechRecognizerClient::kNetworkError;
- case SPEECH_RECOGNITION_ERROR_NOT_ALLOWED:
- return WebSpeechRecognizerClient::kNotAllowedError;
- case SPEECH_RECOGNITION_ERROR_SERVICE_NOT_ALLOWED:
- return WebSpeechRecognizerClient::kServiceNotAllowedError;
- case SPEECH_RECOGNITION_ERROR_BAD_GRAMMAR:
- return WebSpeechRecognizerClient::kBadGrammarError;
- case SPEECH_RECOGNITION_ERROR_LANGUAGE_NOT_SUPPORTED:
- return WebSpeechRecognizerClient::kLanguageNotSupportedError;
- case SPEECH_RECOGNITION_ERROR_NO_MATCH:
- NOTREACHED();
- return WebSpeechRecognizerClient::kOtherError;
- }
- NOTREACHED();
- return WebSpeechRecognizerClient::kOtherError;
-}
-
-void SpeechRecognitionDispatcher::AddHandle(
- const blink::WebSpeechRecognitionHandle& handle,
- mojom::SpeechRecognitionSessionPtr session) {
- DCHECK(!HandleExists(handle));
- session_map_[handle] = std::move(session);
-}
-
-bool SpeechRecognitionDispatcher::HandleExists(
- const WebSpeechRecognitionHandle& handle) {
- return session_map_.find(handle) != session_map_.end();
-}
-
-void SpeechRecognitionDispatcher::RemoveHandle(
- const blink::WebSpeechRecognitionHandle& handle) {
- session_map_.erase(handle);
-}
-
-mojom::SpeechRecognitionSession* SpeechRecognitionDispatcher::GetSession(
- const blink::WebSpeechRecognitionHandle& handle) {
- DCHECK(HandleExists(handle));
- return session_map_[handle].get();
-}
-
-mojom::SpeechRecognizer&
-SpeechRecognitionDispatcher::GetSpeechRecognitionHost() {
- if (!speech_recognition_host_) {
- render_frame()->GetRemoteInterfaces()->GetInterface(
- mojo::MakeRequest(&speech_recognition_host_));
- }
- return *speech_recognition_host_;
-}
-
-// ------------ SpeechRecognitionSessionClientImpl
-// ------------------------------------
-
-SpeechRecognitionSessionClientImpl::SpeechRecognitionSessionClientImpl(
- SpeechRecognitionDispatcher* dispatcher,
- const blink::WebSpeechRecognitionHandle& handle,
- const blink::WebSpeechRecognizerClient& client)
- : parent_dispatcher_(dispatcher), handle_(handle), web_client_(client) {}
-
-void SpeechRecognitionSessionClientImpl::Started() {
- web_client_.DidStart(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::AudioStarted() {
- web_client_.DidStartAudio(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::SoundStarted() {
- web_client_.DidStartSound(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::SoundEnded() {
- web_client_.DidEndSound(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::AudioEnded() {
- web_client_.DidEndAudio(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::ErrorOccurred(
- const content::SpeechRecognitionError& error) {
- if (error.code == SPEECH_RECOGNITION_ERROR_NO_MATCH) {
- web_client_.DidReceiveNoMatch(handle_, WebSpeechRecognitionResult());
- } else {
- web_client_.DidReceiveError(handle_,
- WebString(), // TODO(primiano): message?
- WebKitErrorCode(error.code));
- }
-}
-
-void SpeechRecognitionSessionClientImpl::Ended() {
- parent_dispatcher_->RemoveHandle(handle_);
- web_client_.DidEnd(handle_);
-}
-
-void SpeechRecognitionSessionClientImpl::ResultRetrieved(
- const std::vector<content::SpeechRecognitionResult>& results) {
- size_t provisional_count =
- std::count_if(results.begin(), results.end(),
- [](const SpeechRecognitionResult& result) {
- return result.is_provisional;
- });
-
- WebVector<WebSpeechRecognitionResult> provisional(provisional_count);
- WebVector<WebSpeechRecognitionResult> final(results.size() -
- provisional_count);
-
- int provisional_index = 0, final_index = 0;
- for (const SpeechRecognitionResult& result : results) {
- WebSpeechRecognitionResult* webkit_result =
- result.is_provisional ? &provisional[provisional_index++]
- : &final[final_index++];
-
- const size_t num_hypotheses = result.hypotheses.size();
- WebVector<WebString> transcripts(num_hypotheses);
- WebVector<float> confidences(num_hypotheses);
- for (size_t i = 0; i < num_hypotheses; ++i) {
- transcripts[i] = WebString::FromUTF16(result.hypotheses[i].utterance);
- confidences[i] = static_cast<float>(result.hypotheses[i].confidence);
- }
- webkit_result->Assign(transcripts, confidences, !result.is_provisional);
- }
-
- web_client_.DidReceiveResults(handle_, final, provisional);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/speech_recognition_dispatcher.h b/chromium/content/renderer/speech_recognition_dispatcher.h
deleted file mode 100644
index eb261b705f0..00000000000
--- a/chromium/content/renderer/speech_recognition_dispatcher.h
+++ /dev/null
@@ -1,120 +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_SPEECH_RECOGNITION_DISPATCHER_H_
-#define CONTENT_RENDERER_SPEECH_RECOGNITION_DISPATCHER_H_
-
-#include <map>
-#include <memory>
-
-#include "base/macros.h"
-#include "content/common/speech_recognizer.mojom.h"
-#include "content/public/common/speech_recognition_result.h"
-#include "content/public/renderer/render_frame_observer.h"
-#include "mojo/public/cpp/bindings/strong_binding_set.h"
-#include "third_party/blink/public/web/web_speech_recognition_handle.h"
-#include "third_party/blink/public/web/web_speech_recognizer.h"
-#include "third_party/blink/public/web/web_speech_recognizer_client.h"
-
-namespace content {
-struct SpeechRecognitionError;
-
-// SpeechRecognitionDispatcher is a delegate for methods used by WebKit for
-// scripted JS speech APIs. It's the complement of
-// SpeechRecognitionDispatcherHost (owned by RenderFrameHost), and communicates
-// with it using two mojo interfaces (SpeechRecognizer and
-// SpeechRecognitionSession).
-class SpeechRecognitionDispatcher : public RenderFrameObserver,
- public blink::WebSpeechRecognizer {
- public:
- explicit SpeechRecognitionDispatcher(RenderFrame* render_frame);
- ~SpeechRecognitionDispatcher() override;
-
- private:
- // RenderFrameObserver implementation.
- void OnDestruct() override;
- void WasHidden() override;
-
- // blink::WebSpeechRecognizer implementation.
- void Start(const blink::WebSpeechRecognitionHandle&,
- const blink::WebSpeechRecognitionParams&,
- const blink::WebSpeechRecognizerClient&) override;
- void Stop(const blink::WebSpeechRecognitionHandle&,
- const blink::WebSpeechRecognizerClient&) override;
- void Abort(const blink::WebSpeechRecognitionHandle&,
- const blink::WebSpeechRecognizerClient&) override;
-
- // Methods to interact with |session_map_|
- void AddHandle(const blink::WebSpeechRecognitionHandle& handle,
- mojom::SpeechRecognitionSessionPtr session);
- bool HandleExists(const blink::WebSpeechRecognitionHandle& handle);
- void RemoveHandle(const blink::WebSpeechRecognitionHandle& handle);
- mojom::SpeechRecognitionSession* GetSession(
- const blink::WebSpeechRecognitionHandle& handle);
-
- mojom::SpeechRecognizer& GetSpeechRecognitionHost();
-
- // InterfacePtr used to communicate with SpeechRecognitionDispatcherHost to
- // start a session for each WebSpeechRecognitionHandle.
- mojom::SpeechRecognizerPtr speech_recognition_host_;
-
- // The Blink client class that we use to send events back to the JS world.
- // This is passed to each SpeechRecognitionSessionClientImpl instance.
- blink::WebSpeechRecognizerClient recognizer_client_;
-
- // Owns a SpeechRecognitionSessionClientImpl for each session created. The
- // bindings are automatically cleaned up when the connection is closed by the
- // browser process. We use mojo::StrongBindingSet instead of using
- // mojo::MakeStrongBinding for each individual binding as
- // SpeechRecognitionSessionClientImpl holds a pointer to its parent
- // SpeechRecognitionDispatcher, and we need to clean up the
- // SpeechRecognitionSessionClientImpl objects when |this| is deleted.
- mojo::StrongBindingSet<mojom::SpeechRecognitionSessionClient> bindings_;
-
- // Owns a SpeechRecognitionSessionPtr per session created. Each
- // WebSpeechRecognitionHandle has its own speech recognition session, and is
- // used as a key for the map.
- using SessionMap = std::map<blink::WebSpeechRecognitionHandle,
- mojom::SpeechRecognitionSessionPtr>;
- SessionMap session_map_;
-
- DISALLOW_COPY_AND_ASSIGN(SpeechRecognitionDispatcher);
- friend class SpeechRecognitionSessionClientImpl;
-};
-
-// SpeechRecognitionSessionClientImpl is owned by SpeechRecognitionDispatcher
-// and is cleaned up either when the end point is closed by the browser process,
-// or if SpeechRecognitionDispatcher is deleted.
-class SpeechRecognitionSessionClientImpl
- : public mojom::SpeechRecognitionSessionClient {
- public:
- SpeechRecognitionSessionClientImpl(
- SpeechRecognitionDispatcher* dispatcher,
- const blink::WebSpeechRecognitionHandle& handle,
- const blink::WebSpeechRecognizerClient& client);
- ~SpeechRecognitionSessionClientImpl() override = default;
-
- // mojom::SpeechRecognitionSessionClient implementation
- void Started() override;
- void AudioStarted() override;
- void SoundStarted() override;
- void SoundEnded() override;
- void AudioEnded() override;
- void ErrorOccurred(const content::SpeechRecognitionError& error) override;
- void Ended() override;
- void ResultRetrieved(
- const std::vector<content::SpeechRecognitionResult>& results) override;
-
- private:
- // Not owned, |parent_dispatcher_| owns |this|.
- SpeechRecognitionDispatcher* parent_dispatcher_;
- // WebSpeechRecognitionHandle that this instance is associated with.
- blink::WebSpeechRecognitionHandle handle_;
- // The Blink client class that we use to send events back to the JS world.
- blink::WebSpeechRecognizerClient web_client_;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_SPEECH_RECOGNITION_DISPATCHER_H_
diff --git a/chromium/content/renderer/web_database_observer_impl.cc b/chromium/content/renderer/web_database_observer_impl.cc
index 087cf47ede2..31a64d45f1b 100644
--- a/chromium/content/renderer/web_database_observer_impl.cc
+++ b/chromium/content/renderer/web_database_observer_impl.cc
@@ -9,8 +9,6 @@
#include "base/single_thread_task_runner.h"
#include "base/strings/string16.h"
#include "base/threading/thread_task_runner_handle.h"
-#include "content/renderer/storage_util.h"
-#include "storage/common/database/database_identifier.h"
#include "third_party/blink/public/platform/web_security_origin.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/sqlite/sqlite3.h"
@@ -62,7 +60,6 @@ int DetermineHistogramResult(int websql_error, int sqlite_error) {
WebDatabaseObserverImpl::WebDatabaseObserverImpl(
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()) {
DCHECK(main_thread_task_runner_);
}
@@ -74,8 +71,6 @@ void WebDatabaseObserverImpl::DatabaseOpened(
const WebString& database_name,
const WebString& database_display_name,
unsigned long estimated_size) {
- open_connections_->AddOpenConnection(storage::GetIdentifierFromOrigin(origin),
- database_name.Utf16());
GetWebDatabaseHost().Opened(origin, database_name.Utf16(),
database_display_name.Utf16(), estimated_size);
}
@@ -89,8 +84,6 @@ void WebDatabaseObserverImpl::DatabaseClosed(const WebSecurityOrigin& origin,
const WebString& database_name) {
DCHECK(!main_thread_task_runner_->RunsTasksInCurrentSequence());
GetWebDatabaseHost().Closed(origin, database_name.Utf16());
- open_connections_->RemoveOpenConnection(
- storage::GetIdentifierFromOrigin(origin), database_name.Utf16());
}
void WebDatabaseObserverImpl::ReportOpenDatabaseResult(
@@ -99,17 +92,15 @@ void WebDatabaseObserverImpl::ReportOpenDatabaseResult(
int callsite,
int websql_error,
int sqlite_error,
- double call_time) {
+ base::TimeDelta call_time) {
UMA_HISTOGRAM_WEBSQL_RESULT("OpenResult", callsite,
websql_error, sqlite_error);
HandleSqliteError(origin, database_name, sqlite_error);
if (websql_error == kWebSQLSuccess && sqlite_error == SQLITE_OK) {
- UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Success",
- base::TimeDelta::FromSecondsD(call_time));
+ UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Success", call_time);
} else {
- UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Error",
- base::TimeDelta::FromSecondsD(call_time));
+ UMA_HISTOGRAM_TIMES("websql.Async.OpenTime.Error", call_time);
}
}
@@ -167,12 +158,6 @@ void WebDatabaseObserverImpl::ReportVacuumDatabaseResult(
HandleSqliteError(origin, database_name, sqlite_error);
}
-bool WebDatabaseObserverImpl::WaitForAllDatabasesToClose(
- base::TimeDelta timeout) {
- DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
- return open_connections_->WaitForAllDatabasesToClose(timeout);
-}
-
void WebDatabaseObserverImpl::HandleSqliteError(const WebSecurityOrigin& origin,
const WebString& database_name,
int error) {
diff --git a/chromium/content/renderer/web_database_observer_impl.h b/chromium/content/renderer/web_database_observer_impl.h
index df5c4c1eb2f..74544bca0f8 100644
--- a/chromium/content/renderer/web_database_observer_impl.h
+++ b/chromium/content/renderer/web_database_observer_impl.h
@@ -7,7 +7,6 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "storage/common/database/database_connections.h"
#include "third_party/blink/public/platform/modules/webdatabase/web_database.mojom.h"
#include "third_party/blink/public/platform/web_database_observer.h"
@@ -37,7 +36,7 @@ class WebDatabaseObserverImpl : public blink::WebDatabaseObserver {
int callsite,
int websql_error,
int sqlite_error,
- double call_time) override;
+ base::TimeDelta call_time) override;
void ReportChangeVersionResult(const blink::WebSecurityOrigin& origin,
const blink::WebString& database_name,
int callsite,
@@ -62,8 +61,6 @@ class WebDatabaseObserverImpl : public blink::WebDatabaseObserver {
const blink::WebString& database_name,
int sqlite_error) override;
- bool WaitForAllDatabasesToClose(base::TimeDelta timeout);
-
private:
void HandleSqliteError(const blink::WebSecurityOrigin& origin,
const blink::WebString& database_name,
@@ -73,7 +70,6 @@ class WebDatabaseObserverImpl : public blink::WebDatabaseObserver {
blink::mojom::WebDatabaseHost& GetWebDatabaseHost();
scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr> web_database_host_;
- scoped_refptr<storage::DatabaseConnectionsWrapper> open_connections_;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
DISALLOW_COPY_AND_ASSIGN(WebDatabaseObserverImpl);
diff --git a/chromium/content/renderer/web_frame_utils.cc b/chromium/content/renderer/web_frame_utils.cc
deleted file mode 100644
index cba1820c98f..00000000000
--- a/chromium/content/renderer/web_frame_utils.cc
+++ /dev/null
@@ -1,28 +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/renderer/web_frame_utils.h"
-
-#include "content/renderer/render_frame_impl.h"
-#include "content/renderer/render_frame_proxy.h"
-#include "ipc/ipc_message.h"
-#include "third_party/blink/public/web/web_frame.h"
-#include "third_party/blink/public/web/web_local_frame.h"
-#include "third_party/blink/public/web/web_remote_frame.h"
-
-namespace content {
-
-blink::WebFrame* GetWebFrameFromRoutingIdForFrameOrProxy(int routing_id) {
- auto* render_frame = RenderFrameImpl::FromRoutingID(routing_id);
- if (render_frame)
- return render_frame->GetWebFrame();
-
- auto* render_frame_proxy = RenderFrameProxy::FromRoutingID(routing_id);
- if (render_frame_proxy)
- return render_frame_proxy->web_frame();
-
- return nullptr;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/web_frame_utils.h b/chromium/content/renderer/web_frame_utils.h
deleted file mode 100644
index 5b888d5cbb7..00000000000
--- a/chromium/content/renderer/web_frame_utils.h
+++ /dev/null
@@ -1,20 +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_RENDERER_WEB_FRAME_UTILS_H_
-#define CONTENT_RENDERER_WEB_FRAME_UTILS_H_
-
-namespace blink {
-class WebFrame;
-}
-
-namespace content {
-
-// Returns either a WebLocalFrame or WebRemoteFrame based on |routing_id|.
-// Returns nullptr if |routing_id| doesn't properly map to a frame.
-blink::WebFrame* GetWebFrameFromRoutingIdForFrameOrProxy(int routing_id);
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_WEB_FRAME_UTILS_H_
diff --git a/chromium/content/renderer/webclipboard_impl_browsertest.cc b/chromium/content/renderer/webclipboard_impl_browsertest.cc
index 13b7c7560ce..181dfe0a8e1 100644
--- a/chromium/content/renderer/webclipboard_impl_browsertest.cc
+++ b/chromium/content/renderer/webclipboard_impl_browsertest.cc
@@ -55,10 +55,11 @@ IN_PROC_BROWSER_TEST_F(WebClipboardImplTest, ImageCopy) {
NavigateIframeToURL(web_contents, "copyme",
GetTestUrl(".", "media/blackwhite.png"));
- // Run script to copy image contents and wait for completion.
- web_contents->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
- base::ASCIIToUTF16("frames[0].document.execCommand('copy');"
- "document.title = 'copied';"));
+ // Run script in child frame to copy image contents and wait for completion.
+ RenderFrameHost* child_frame = ChildFrameAt(web_contents->GetMainFrame(), 0);
+ child_frame->ExecuteJavaScriptWithUserGestureForTests(
+ base::ASCIIToUTF16("document.execCommand('copy');"
+ "parent.document.title = 'copied';"));
TitleWatcher watcher1(web_contents, base::ASCIIToUTF16("copied"));
EXPECT_EQ(base::ASCIIToUTF16("copied"), watcher1.WaitAndGetTitle());
diff --git a/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc b/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc
index ad82d6cfea9..f44ed327657 100644
--- a/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc
+++ b/chromium/content/renderer/webgraphicscontext3d_provider_impl.cc
@@ -12,10 +12,8 @@
namespace content {
WebGraphicsContext3DProviderImpl::WebGraphicsContext3DProviderImpl(
- scoped_refptr<ui::ContextProviderCommandBuffer> provider,
- bool software_rendering)
- : provider_(std::move(provider)), software_rendering_(software_rendering) {
-}
+ scoped_refptr<ui::ContextProviderCommandBuffer> provider)
+ : provider_(std::move(provider)) {}
WebGraphicsContext3DProviderImpl::~WebGraphicsContext3DProviderImpl() {
provider_->RemoveObserver(this);
@@ -56,10 +54,6 @@ viz::GLHelper* WebGraphicsContext3DProviderImpl::GetGLHelper() {
return gl_helper_.get();
}
-bool WebGraphicsContext3DProviderImpl::IsSoftwareRendering() const {
- return software_rendering_;
-}
-
void WebGraphicsContext3DProviderImpl::SetLostContextCallback(
base::RepeatingClosure c) {
context_lost_callback_ = std::move(c);
diff --git a/chromium/content/renderer/webgraphicscontext3d_provider_impl.h b/chromium/content/renderer/webgraphicscontext3d_provider_impl.h
index 97d65fcdcf0..28947063460 100644
--- a/chromium/content/renderer/webgraphicscontext3d_provider_impl.h
+++ b/chromium/content/renderer/webgraphicscontext3d_provider_impl.h
@@ -36,8 +36,7 @@ class CONTENT_EXPORT WebGraphicsContext3DProviderImpl
public viz::ContextLostObserver {
public:
WebGraphicsContext3DProviderImpl(
- scoped_refptr<ui::ContextProviderCommandBuffer> provider,
- bool software_rendering);
+ scoped_refptr<ui::ContextProviderCommandBuffer> provider);
~WebGraphicsContext3DProviderImpl() override;
// WebGraphicsContext3DProvider implementation.
@@ -47,7 +46,6 @@ class CONTENT_EXPORT WebGraphicsContext3DProviderImpl
const gpu::Capabilities& GetCapabilities() const override;
const gpu::GpuFeatureInfo& GetGpuFeatureInfo() const override;
viz::GLHelper* GetGLHelper() override;
- bool IsSoftwareRendering() const override;
void SetLostContextCallback(base::RepeatingClosure) override;
void SetErrorMessageCallback(
base::RepeatingCallback<void(const char*, int32_t)>) override;
@@ -63,7 +61,6 @@ class CONTENT_EXPORT WebGraphicsContext3DProviderImpl
scoped_refptr<ui::ContextProviderCommandBuffer> provider_;
std::unique_ptr<viz::GLHelper> gl_helper_;
- const bool software_rendering_;
base::RepeatingClosure context_lost_callback_;
std::unique_ptr<cc::ImageDecodeCache> image_decode_cache_;
diff --git a/chromium/content/renderer/webpublicsuffixlist_impl.cc b/chromium/content/renderer/webpublicsuffixlist_impl.cc
deleted file mode 100644
index 03ba14cbca3..00000000000
--- a/chromium/content/renderer/webpublicsuffixlist_impl.cc
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/webpublicsuffixlist_impl.h"
-
-#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-
-namespace content {
-
-WebPublicSuffixListImpl::~WebPublicSuffixListImpl() {
-}
-
-size_t WebPublicSuffixListImpl::GetPublicSuffixLength(
- const blink::WebString& host) {
- // Blink passes some things that aren't technically hosts like "*.foo", so
- // use the permissive variant.
- size_t result =
- net::registry_controlled_domains::PermissiveGetHostRegistryLength(
- host.Utf8(),
- net::registry_controlled_domains::INCLUDE_UNKNOWN_REGISTRIES,
- net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
- return result ? result : host.length();
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/webpublicsuffixlist_impl.h b/chromium/content/renderer/webpublicsuffixlist_impl.h
deleted file mode 100644
index a38010e0de3..00000000000
--- a/chromium/content/renderer/webpublicsuffixlist_impl.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_WEBPUBLICSUFFIXLIST_IMPL_H_
-#define CONTENT_RENDERER_WEBPUBLICSUFFIXLIST_IMPL_H_
-
-#include <stddef.h>
-
-#include "base/compiler_specific.h"
-#include "third_party/blink/public/platform/web_public_suffix_list.h"
-
-namespace content {
-
-class WebPublicSuffixListImpl : public blink::WebPublicSuffixList {
- public:
- // WebPublicSuffixList methods:
- size_t GetPublicSuffixLength(const blink::WebString&) override;
- ~WebPublicSuffixListImpl() override;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_WEBPUBLICSUFFIXLIST_IMPL_H_
diff --git a/chromium/content/renderer/webscrollbarbehavior_impl_aura.cc b/chromium/content/renderer/webscrollbarbehavior_impl_aura.cc
deleted file mode 100644
index c6c15715a90..00000000000
--- a/chromium/content/renderer/webscrollbarbehavior_impl_aura.cc
+++ /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.
-
-#include "content/renderer/webscrollbarbehavior_impl_aura.h"
-
-#include "build/build_config.h"
-#include "third_party/blink/public/platform/web_point.h"
-#include "third_party/blink/public/platform/web_rect.h"
-
-namespace content {
-
-bool WebScrollbarBehaviorImpl::ShouldCenterOnThumb(
- blink::WebPointerProperties::Button mouseButton,
- bool shiftKeyPressed,
- bool altKeyPressed) {
-#if (defined(OS_LINUX) && !defined(OS_CHROMEOS))
- if (mouseButton == blink::WebPointerProperties::Button::kMiddle)
- return true;
-#endif
- return (mouseButton == blink::WebPointerProperties::Button::kLeft) &&
- shiftKeyPressed;
-}
-
-bool WebScrollbarBehaviorImpl::ShouldSnapBackToDragOrigin(
- const blink::WebPoint& eventPoint,
- const blink::WebRect& scrollbarRect,
- bool isHorizontal) {
-// Disable snapback on desktop Linux to better integrate with the desktop
-// behavior. Typically, Linux apps do not implement scrollbar snapback (this is
-// true for at least GTK and QT apps).
-#if (defined(OS_LINUX) && !defined(OS_CHROMEOS))
- return false;
-#endif
-
- // Constants used to figure the drag rect outside which we should snap the
- // scrollbar thumb back to its origin. These calculations are based on
- // observing the behavior of the MSVC8 main window scrollbar + some
- // guessing/extrapolation.
- static const int kOffEndMultiplier = 3;
- static const int kOffSideMultiplier = 8;
- static const int kDefaultWinScrollbarThickness = 17;
-
- // Find the rect within which we shouldn't snap, by expanding the track rect
- // in both dimensions.
- gfx::Rect noSnapRect(scrollbarRect);
- int thickness = isHorizontal ? noSnapRect.height() : noSnapRect.width();
- // Even if the platform's scrollbar is narrower than the default Windows one,
- // we still want to provide at least as much slop area, since a slightly
- // narrower scrollbar doesn't necessarily imply that users will drag
- // straighter.
- thickness = std::max(thickness, kDefaultWinScrollbarThickness);
- noSnapRect.Inset(
- (isHorizontal ? kOffEndMultiplier : kOffSideMultiplier) * -thickness,
- (isHorizontal ? kOffSideMultiplier : kOffEndMultiplier) * -thickness);
-
- return !noSnapRect.Contains(eventPoint);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/webscrollbarbehavior_impl_aura.h b/chromium/content/renderer/webscrollbarbehavior_impl_aura.h
deleted file mode 100644
index f06717ddc56..00000000000
--- a/chromium/content/renderer/webscrollbarbehavior_impl_aura.h
+++ /dev/null
@@ -1,24 +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_WEBSCROLLBARBEHAVIOR_IMPL_AURA_H_
-#define CONTENT_RENDERER_WEBSCROLLBARBEHAVIOR_IMPL_AURA_H_
-
-#include "third_party/blink/public/platform/web_scrollbar_behavior.h"
-
-namespace content {
-
-class WebScrollbarBehaviorImpl : public blink::WebScrollbarBehavior {
- public:
- bool ShouldCenterOnThumb(blink::WebPointerProperties::Button mouseButton,
- bool shiftKeyPressed,
- bool altKeyPressed) override;
- bool ShouldSnapBackToDragOrigin(const blink::WebPoint& eventPoint,
- const blink::WebRect& scrollbarRect,
- bool isHorizontal) override;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_WEBSCROLLBARBEHAVIOR_IMPL_AURA_H_
diff --git a/chromium/content/renderer/webscrollbarbehavior_impl_mac.h b/chromium/content/renderer/webscrollbarbehavior_impl_mac.h
deleted file mode 100644
index c6303816875..00000000000
--- a/chromium/content/renderer/webscrollbarbehavior_impl_mac.h
+++ /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.
-
-#ifndef CONTENT_RENDERER_WEBSCROLLBARBEHAVIOR_IMPL_MAC_H_
-#define CONTENT_RENDERER_WEBSCROLLBARBEHAVIOR_IMPL_MAC_H_
-
-#include "third_party/blink/public/platform/web_scrollbar_behavior.h"
-
-namespace content {
-
-class WebScrollbarBehaviorImpl : public blink::WebScrollbarBehavior {
- public:
- WebScrollbarBehaviorImpl();
-
- bool ShouldCenterOnThumb(blink::WebPointerProperties::Button mouseButton,
- bool shiftKeyPressed,
- bool altKeyPressed) override;
-
- void set_jump_on_track_click(bool jump_on_track_click) {
- jump_on_track_click_ = jump_on_track_click;
- }
-
- private:
- // The current value of AppleScrollerPagingBehavior from NSUserDefaults.
- bool jump_on_track_click_;
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_WEBSCROLLBARBEHAVIOR_IMPL_MAC_H_
diff --git a/chromium/content/renderer/webscrollbarbehavior_impl_mac.mm b/chromium/content/renderer/webscrollbarbehavior_impl_mac.mm
deleted file mode 100644
index b2f3fbdff6f..00000000000
--- a/chromium/content/renderer/webscrollbarbehavior_impl_mac.mm
+++ /dev/null
@@ -1,21 +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/webscrollbarbehavior_impl_mac.h"
-
-namespace content {
-
-WebScrollbarBehaviorImpl::WebScrollbarBehaviorImpl()
- : jump_on_track_click_(false) {
-}
-
-bool WebScrollbarBehaviorImpl::ShouldCenterOnThumb(
- blink::WebPointerProperties::Button mouseButton,
- bool shiftKeyPressed,
- bool altKeyPressed) {
- return (mouseButton == blink::WebPointerProperties::Button::kLeft) &&
- (jump_on_track_click_ != altKeyPressed);
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/worker_thread_message_filter.cc b/chromium/content/renderer/worker_thread_message_filter.cc
deleted file mode 100644
index f1f259f7c15..00000000000
--- a/chromium/content/renderer/worker_thread_message_filter.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/worker_thread_message_filter.h"
-
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/child/thread_safe_sender.h"
-#include "content/renderer/worker_thread_registry.h"
-#include "ipc/ipc_message_macros.h"
-
-namespace content {
-
-WorkerThreadMessageFilter::WorkerThreadMessageFilter(
- ThreadSafeSender* thread_safe_sender,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
- : main_thread_task_runner_(std::move(main_thread_task_runner)),
- thread_safe_sender_(thread_safe_sender) {}
-
-WorkerThreadMessageFilter::~WorkerThreadMessageFilter() {
-}
-
-base::TaskRunner* WorkerThreadMessageFilter::OverrideTaskRunnerForMessage(
- const IPC::Message& msg) {
- if (!ShouldHandleMessage(msg))
- return nullptr;
- int ipc_thread_id = 0;
- const bool success = GetWorkerThreadIdForMessage(msg, &ipc_thread_id);
- DCHECK(success);
- if (!ipc_thread_id)
- return main_thread_task_runner_.get();
- return WorkerThreadRegistry::Instance()->GetTaskRunnerFor(ipc_thread_id);
-}
-
-bool WorkerThreadMessageFilter::OnMessageReceived(const IPC::Message& msg) {
- if (!ShouldHandleMessage(msg))
- return false;
- // If the IPC message is received in a worker thread, but it has already been
- // stopped, then drop the message.
- if (!main_thread_task_runner_->BelongsToCurrentThread() &&
- !WorkerThread::GetCurrentId()) {
- return false;
- }
- OnFilteredMessageReceived(msg);
- return true;
-}
-
-} // namespace content
diff --git a/chromium/content/renderer/worker_thread_message_filter.h b/chromium/content/renderer/worker_thread_message_filter.h
deleted file mode 100644
index 64c0d47b896..00000000000
--- a/chromium/content/renderer/worker_thread_message_filter.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_WORKER_THREAD_MESSAGE_FILTER_H_
-#define CONTENT_RENDERER_WORKER_THREAD_MESSAGE_FILTER_H_
-
-#include "base/macros.h"
-#include "content/renderer/child_message_filter.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace content {
-
-class ThreadSafeSender;
-
-// A base class for filtering IPC messages targeted for worker threads.
-class WorkerThreadMessageFilter : public ChildMessageFilter {
- public:
- WorkerThreadMessageFilter(
- ThreadSafeSender* thread_safe_sender,
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
-
- protected:
- ~WorkerThreadMessageFilter() override;
-
- base::SingleThreadTaskRunner* main_thread_task_runner() {
- return main_thread_task_runner_.get();
- }
- ThreadSafeSender* thread_safe_sender() { return thread_safe_sender_.get(); }
-
- private:
- // Returns whether this filter should process |msg|.
- virtual bool ShouldHandleMessage(const IPC::Message& msg) const = 0;
-
- // Processes the IPC message in the worker thread, if the filter could extract
- // its thread id. Otherwise, runs in the main thread. It only receives a
- // message if ShouldHandleMessage() returns true for it.
- virtual void OnFilteredMessageReceived(const IPC::Message& msg) = 0;
-
- // Attempts to extract the thread-id of the worker-thread that should process
- // the IPC message. Returns whether the thread-id could be determined and set
- // in |ipc_thread_id|.
- virtual bool GetWorkerThreadIdForMessage(const IPC::Message& msg,
- int* ipc_thread_id) = 0;
-
- // ChildMessageFilter implementation:
- base::TaskRunner* OverrideTaskRunnerForMessage(const IPC::Message& msg) final;
- bool OnMessageReceived(const IPC::Message& msg) final;
-
- scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
- scoped_refptr<ThreadSafeSender> thread_safe_sender_;
-
- DISALLOW_COPY_AND_ASSIGN(WorkerThreadMessageFilter);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_WORKER_THREAD_MESSAGE_FILTER_H_
diff --git a/chromium/content/shell/BUILD.gn b/chromium/content/shell/BUILD.gn
index bd604be447c..698aaa4c79d 100644
--- a/chromium/content/shell/BUILD.gn
+++ b/chromium/content/shell/BUILD.gn
@@ -78,6 +78,8 @@ static_library("content_shell_lib") {
"browser/layout_test/devtools_protocol_test_bindings.h",
"browser/layout_test/fake_bluetooth_chooser.cc",
"browser/layout_test/fake_bluetooth_chooser.h",
+ "browser/layout_test/layout_test_background_fetch_delegate.cc",
+ "browser/layout_test/layout_test_background_fetch_delegate.h",
"browser/layout_test/layout_test_bluetooth_adapter_provider.cc",
"browser/layout_test/layout_test_bluetooth_adapter_provider.h",
"browser/layout_test/layout_test_bluetooth_chooser_factory.cc",
@@ -102,8 +104,6 @@ static_library("content_shell_lib") {
"browser/layout_test/layout_test_javascript_dialog_manager.h",
"browser/layout_test/layout_test_message_filter.cc",
"browser/layout_test/layout_test_message_filter.h",
- "browser/layout_test/layout_test_notification_manager.cc",
- "browser/layout_test/layout_test_notification_manager.h",
"browser/layout_test/layout_test_permission_manager.cc",
"browser/layout_test/layout_test_permission_manager.h",
"browser/layout_test/layout_test_push_messaging_service.cc",
@@ -249,6 +249,8 @@ static_library("content_shell_lib") {
"//components/crash/content/app:test_support",
"//components/crash/content/browser",
"//components/crash/core/common:crash_key",
+ "//components/download/content/factory",
+ "//components/download/public/background_service:public",
"//components/download/public/common:public",
"//components/keyed_service/content",
"//components/network_session_configurator/browser",
@@ -269,7 +271,6 @@ static_library("content_shell_lib") {
"//device/bluetooth",
"//device/bluetooth:fake_bluetooth",
"//device/bluetooth:mocks",
- "//device/geolocation/public/cpp:test_support",
"//gin",
"//gpu",
"//media",
@@ -280,6 +281,7 @@ static_library("content_shell_lib") {
"//net:test_support",
"//ppapi/buildflags",
"//sandbox",
+ "//services/device/public/cpp/test:test_support",
"//services/device/public/mojom",
"//services/network/public/cpp",
"//services/service_manager/embedder:embedder_result_codes",
@@ -306,6 +308,7 @@ static_library("content_shell_lib") {
"//ui/gfx/ipc/geometry",
"//ui/gfx/ipc/skia",
"//ui/gl",
+ "//ui/platform_window",
"//url",
"//v8",
]
@@ -317,6 +320,7 @@ static_library("content_shell_lib") {
"//components/crash/content/app:test_support",
"//components/crash/content/browser",
]
+ deps += [ "//third_party/fuchsia-sdk:policy" ]
}
# Annoyingly, this target and layouttest_support have circular includes.
@@ -365,7 +369,9 @@ static_library("content_shell_lib") {
]
deps += [
"//base/test:test_support",
+ "//components/embedder_support/android:view",
"//content/shell/android:content_shell_jni_headers",
+ "//mojo/public/java/system:test_support",
]
}
@@ -414,6 +420,10 @@ static_library("content_shell_lib") {
deps += [ "//build/config/freetype" ]
}
+ if (use_ozone) {
+ deps += [ "//ui/ozone" ]
+ }
+
if (!enable_plugins) {
sources -= [
"browser/shell_plugin_service_filter.cc",
@@ -532,25 +542,18 @@ if (is_android) {
testonly = true
output_name = content_shell_product_name
sources = [
- "app/shell_main.cc",
+ "app/shell_main_mac.cc",
]
+ defines = [ "SHELL_PRODUCT_NAME=\"$content_shell_product_name\"" ]
deps = [
":content_shell_framework_bundle_data",
":content_shell_resources_bundle_data",
- "//build/config:exe_and_shlib_deps",
# TODO(rsesek): Remove this after GYP is gone, since it only needs to
# be here per the comment in blink_test_platform_support_mac.mm about
# the bundle structure.
"//content/shell/test_runner:resources",
]
- ldflags = [
- # The main app is at Content Shell.app/Contents/MacOS/Content Shell
- # so set the rpath up to Contents/ so that the loader can find
- # Framworks/.
- "-rpath",
- "@executable_path/../",
- ]
info_plist_target = ":content_shell_plist"
data_deps = [
":content_shell_lib",
@@ -573,15 +576,11 @@ if (is_android) {
deps = [
":content_shell_lib",
":pak",
- "//build/config:exe_and_shlib_deps",
"//build/win:default_exe_manifest",
]
data_deps = [
":pak",
- ]
-
- public_deps = [
"//tools/v8_context_snapshot:v8_context_snapshot",
]
@@ -608,16 +607,19 @@ if (is_android) {
# Set rpath to find our own libfreetype even in a non-component build.
configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
}
-
- if (use_aura) {
- data_deps += [ "//services/ui" ]
- }
}
if (is_fuchsia) {
- fuchsia_executable_runner("content_shell_fuchsia") {
+ fuchsia_package("content_shell_pkg") {
+ testonly = true
+ binary = ":content_shell"
+ package_name_override = "content_shell"
+ }
+
+ fuchsia_package_runner("content_shell_fuchsia") {
testonly = true
- exe_target = ":content_shell"
+ package = ":content_shell_pkg"
+ package_name_override = "content_shell"
}
}
}
@@ -751,11 +753,7 @@ if (is_mac) {
# install_name_tool on one of the executables. However install_name_tool
# only operates in-place, which is problematic to express in GN. Instead,
# use rpath-based loading.
- # TODO(rsesek): After GYP is gone, re-write content_shell_main to be like
- # chrome_main and use dlopen() instead of a linked framework.
- ldflags = [
- "-Wl,-install_name,@rpath/Frameworks/$output_name.framework/$output_name",
- ]
+ ldflags = [ "-Wl,-install_name,@executable_path/../Frameworks/$output_name.framework/$output_name" ]
if (is_component_build) {
# Set up the rpath for the framework so that it can find dylibs in the
@@ -787,17 +785,20 @@ if (is_mac) {
testonly = true
output_name = content_shell_helper_name
sources = [
- "app/shell_main.cc",
+ "app/shell_main_mac.cc",
+ ]
+ defines = [
+ "HELPER_EXECUTABLE",
+ "SHELL_PRODUCT_NAME=\"$content_shell_product_name\"",
]
deps = [
- ":content_shell_framework+link",
- "//build/config:exe_and_shlib_deps",
+ "//sandbox/mac:seatbelt",
]
ldflags = [
# The helper is in Content Shell.app/Contents/Frameworks/Content Shell Helper.app/Contents/MacOS/
- # so set rpath up to Contents/ so that the loader can find Frameworks/.
+ # so set rpath up to the base.
"-rpath",
- "@executable_path/../../../..",
+ "@executable_path/../../../../../..",
]
info_plist_target = ":content_shell_helper_plist"
}
@@ -812,7 +813,7 @@ if (is_mac) {
"{{bundle_contents_dir}}/Frameworks/{{source_file_part}}",
]
public_deps = [
- ":content_shell_framework+link",
+ ":content_shell_framework",
":content_shell_helper_app",
]
}
diff --git a/chromium/content/shell/android/BUILD.gn b/chromium/content/shell/android/BUILD.gn
index a0560dde21a..20e35f2f218 100644
--- a/chromium/content/shell/android/BUILD.gn
+++ b/chromium/content/shell/android/BUILD.gn
@@ -31,7 +31,6 @@ shared_library("libcontent_shell_content_view") {
deps = [
":content_shell_jni_headers",
":content_shell_jni_registration",
- "//build/config:exe_and_shlib_deps",
"//components/crash/content/browser",
"//content/shell:content_shell_lib",
"//content/shell:pak",
@@ -78,9 +77,9 @@ android_library("content_shell_java") {
":content_shell_java_resources",
":content_shell_manifest",
"//base:base_java",
- "//components/content_view:content_view_java",
+ "//components/embedder_support/android:content_view_java",
+ "//components/embedder_support/android:view_java",
"//content/public/android:content_java",
- "//device/geolocation:geolocation_java",
"//media/base/android:media_java",
"//media/capture/video/android:capture_java",
"//mojo/public/java:system_java",
@@ -198,6 +197,7 @@ android_library("content_shell_test_java") {
"//content/public/android:content_java",
"//content/public/test/android:content_java_test_support",
"//content/shell/android:content_shell_java",
+ "//mojo/public/java/system:test_support_java",
"//third_party/android_support_test_runner:rules_java",
"//third_party/android_support_test_runner:runner_java",
"//third_party/junit:junit",
@@ -302,7 +302,6 @@ if (current_cpu != "x64") {
deps = [
":linker_test_jni_headers",
":linker_test_jni_registration",
- "//build/config:exe_and_shlib_deps",
"//content/shell:content_shell_lib",
# Required to include "content/public/browser/android/compositor.h"
diff --git a/chromium/content/shell/test_runner/BUILD.gn b/chromium/content/shell/test_runner/BUILD.gn
index 33d550d2b6e..1b5c11abca9 100644
--- a/chromium/content/shell/test_runner/BUILD.gn
+++ b/chromium/content/shell/test_runner/BUILD.gn
@@ -42,8 +42,6 @@ component("test_runner") {
"mock_web_document_subresource_filter.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",
"pixel_dump.cc",
@@ -98,10 +96,13 @@ component("test_runner") {
"//cc/paint",
"//components/viz/common",
"//content/public/common",
+ "//content/public/common:service_names",
"//content/public/renderer",
"//content/shell:layout_test_switches",
"//content/test:test_runner_support",
+ "//device/base/synchronization",
"//device/gamepad/public/cpp:shared_with_blink",
+ "//device/gamepad/public/mojom",
"//gin",
"//gpu",
"//gpu/command_buffer/client:gles2_interface",
diff --git a/chromium/content/test/BUILD.gn b/chromium/content/test/BUILD.gn
index c1d0124e86f..15a64a49d5c 100644
--- a/chromium/content/test/BUILD.gn
+++ b/chromium/content/test/BUILD.gn
@@ -42,6 +42,8 @@ jumbo_static_library("test_support") {
"../browser/background_fetch/background_fetch_test_base.h",
"../browser/background_fetch/background_fetch_test_browser_context.cc",
"../browser/background_fetch/background_fetch_test_browser_context.h",
+ "../browser/background_fetch/background_fetch_test_data_manager.cc",
+ "../browser/background_fetch/background_fetch_test_data_manager.h",
"../browser/background_fetch/mock_background_fetch_delegate.cc",
"../browser/background_fetch/mock_background_fetch_delegate.h",
"../browser/media/session/mock_media_session_observer.cc",
@@ -52,6 +54,8 @@ jumbo_static_library("test_support") {
"../browser/service_worker/service_worker_test_utils.h",
"../browser/web_package/mock_signed_exchange_handler.cc",
"../browser/web_package/mock_signed_exchange_handler.h",
+ "../public/test/audio_service_test_helper.cc",
+ "../public/test/audio_service_test_helper.h",
"../public/test/background_sync_test_util.cc",
"../public/test/background_sync_test_util.h",
"../public/test/blink_test_environment.cc",
@@ -81,6 +85,8 @@ jumbo_static_library("test_support") {
"../public/test/find_test_utils.h",
"../public/test/frame_load_waiter.cc",
"../public/test/frame_load_waiter.h",
+ "../public/test/hit_test_region_observer.cc",
+ "../public/test/hit_test_region_observer.h",
"../public/test/javascript_test_observer.cc",
"../public/test/javascript_test_observer.h",
"../public/test/memory_coordinator_test_utils.cc",
@@ -89,6 +95,8 @@ jumbo_static_library("test_support") {
"../public/test/mock_browsing_data_remover_delegate.h",
"../public/test/mock_download_manager.cc",
"../public/test/mock_download_manager.h",
+ "../public/test/mock_network_connection_tracker.cc",
+ "../public/test/mock_network_connection_tracker.h",
"../public/test/mock_notification_observer.cc",
"../public/test/mock_notification_observer.h",
"../public/test/mock_permission_manager.cc",
@@ -209,8 +217,6 @@ jumbo_static_library("test_support") {
"gmock_util.h",
"gpu_browsertest_helpers.cc",
"gpu_browsertest_helpers.h",
- "leveldb_wrapper_test_util.cc",
- "leveldb_wrapper_test_util.h",
"mock_background_sync_controller.cc",
"mock_background_sync_controller.h",
"mock_clipboard_host.cc",
@@ -219,6 +225,8 @@ jumbo_static_library("test_support") {
"mock_keyboard.h",
"mock_keyboard_driver_win.cc",
"mock_keyboard_driver_win.h",
+ "mock_navigation_client_impl.cc",
+ "mock_navigation_client_impl.h",
"mock_overscroll_observer.h",
"mock_platform_notification_service.cc",
"mock_platform_notification_service.h",
@@ -240,6 +248,8 @@ jumbo_static_library("test_support") {
"ppapi_unittest.h",
"storage_partition_test_utils.cc",
"storage_partition_test_utils.h",
+ "stub_layer_tree_view_delegate.cc",
+ "stub_layer_tree_view_delegate.h",
"test_background_sync_context.cc",
"test_background_sync_context.h",
"test_background_sync_manager.cc",
@@ -300,7 +310,6 @@ jumbo_static_library("test_support") {
"//media/mojo/interfaces",
"//third_party/blink/public:blink",
"//third_party/blink/public:test_support",
- "//tools/v8_context_snapshot",
]
deps = [
":content_test_mojo_bindings",
@@ -324,15 +333,14 @@ jumbo_static_library("test_support") {
"//content/shell:pak",
"//content/utility:for_content_tests",
"//device/base/synchronization",
- "//device/geolocation",
- "//device/geolocation/public/cpp:test_support",
"//gpu/ipc:gl_in_process_context",
"//ipc:test_support",
"//media",
"//media/capture",
"//media/capture/mojom:image_capture",
- "//mojo/edk",
+ "//mojo/core/embedder",
"//net:test_support",
+ "//services/audio/public/mojom",
"//services/device/public/mojom",
"//services/ui/public/cpp/gpu",
@@ -358,7 +366,6 @@ jumbo_static_library("test_support") {
"//third_party/webrtc/rtc_base:rtc_base_approved",
"//third_party/webrtc/stats:rtc_stats",
"//third_party/webrtc_overrides:init_webrtc",
- "//tools/v8_context_snapshot:v8_context_snapshot",
"//ui/accessibility:ax_enums_mojo",
"//ui/base",
"//ui/base:test_support",
@@ -383,12 +390,13 @@ jumbo_static_library("test_support") {
data_deps = [
"//content/shell:pak",
+ "//tools/v8_context_snapshot:v8_context_snapshot",
]
if (is_android) {
deps += [
"//content/shell:android_shell_descriptors",
- "//mojo/android:libsystem_java",
+ "//mojo/public/java/system:native_support",
]
}
@@ -459,7 +467,6 @@ jumbo_static_library("test_support") {
]
deps += [
- "//device/geolocation:geolocation_java",
"//media/capture/video/android:android",
"//ui/android",
"//ui/android:test_support",
@@ -476,7 +483,10 @@ jumbo_static_library("test_support") {
}
if (is_mac) {
- deps += [ "//ui/accelerated_widget_mac" ]
+ deps += [
+ "//sandbox/mac:seatbelt",
+ "//ui/accelerated_widget_mac",
+ ]
}
}
@@ -658,6 +668,7 @@ if (is_android) {
":content_browsertests_resources",
"//base:base_java",
"//base:base_java_test_support",
+ "//components/viz/service:service_java",
"//content/public/android:content_java",
"//content/public/test/android:content_java_test_support",
"//content/shell/android:content_shell_browsertests_java",
@@ -693,6 +704,7 @@ test("content_browsertests") {
"../browser/accessibility/dump_accessibility_tree_browsertest.cc",
"../browser/accessibility/fullscreen_browsertest.cc",
"../browser/accessibility/hit_testing_browsertest.cc",
+ "../browser/accessibility/line_layout_browsertest.cc",
"../browser/accessibility/site_per_process_accessibility_browsertest.cc",
"../browser/accessibility/snapshot_ax_tree_browsertest.cc",
"../browser/accessibility/touch_accessibility_aura_browsertest.cc",
@@ -708,7 +720,7 @@ test("content_browsertests") {
"../browser/browsing_data/conditional_cache_deletion_helper_browsertest.cc",
"../browser/child_process_launcher_browsertest.cc",
"../browser/child_process_security_policy_browsertest.cc",
- "../browser/compositor/image_transport_factory_browsertest.cc",
+ "../browser/content_service_browsertest.cc",
"../browser/cross_site_transfer_browsertest.cc",
"../browser/database_browsertest.cc",
"../browser/device_sensors/device_sensor_browsertest.cc",
@@ -716,6 +728,7 @@ test("content_browsertests") {
"../browser/devtools/protocol/devtools_protocol_browsertest.cc",
"../browser/devtools/render_frame_devtools_agent_host_browsertest.cc",
"../browser/devtools/site_per_process_devtools_browsertest.cc",
+ "../browser/display_cutout/display_cutout_browsertest.cc",
"../browser/do_not_track_browsertest.cc",
"../browser/dom_storage/dom_storage_browsertest.cc",
"../browser/download/download_browsertest.cc",
@@ -723,7 +736,10 @@ test("content_browsertests") {
"../browser/download/mhtml_generation_browsertest.cc",
"../browser/download/save_package_browsertest.cc",
"../browser/fileapi/file_system_browsertest.cc",
- "../browser/fileapi/file_system_url_loader_factory_browsertest.cc",
+
+ # These tests have incorrect threading (https://crbug.com/860547).
+ #"../browser/fileapi/file_system_url_loader_factory_browsertest.cc",
+
"../browser/fileapi/fileapi_browsertest.cc",
"../browser/find_request_manager_browsertest.cc",
"../browser/frame_host/blocked_scheme_navigation_browsertest.cc",
@@ -754,6 +770,7 @@ test("content_browsertests") {
"../browser/loader/resource_scheduler_browsertest.cc",
"../browser/manifest/manifest_browsertest.cc",
"../browser/media/encrypted_media_browsertest.cc",
+ "../browser/media/media_autoplay_browsertest.cc",
"../browser/media/media_browsertest.cc",
"../browser/media/media_browsertest.h",
"../browser/media/media_canplaytype_browsertest.cc",
@@ -779,6 +796,7 @@ test("content_browsertests") {
"../browser/network_service_restart_browsertest.cc",
"../browser/oop_browsertest.cc",
"../browser/payments/payment_app_browsertest.cc",
+ "../browser/performance_memory_browsertest.cc",
"../browser/pointer_lock_browsertest.cc",
"../browser/pointer_lock_browsertest.h",
"../browser/pointer_lock_browsertest_mac.mm",
@@ -794,6 +812,7 @@ test("content_browsertests") {
"../browser/renderer_host/input/touch_action_browsertest.cc",
"../browser/renderer_host/input/touch_input_browsertest.cc",
"../browser/renderer_host/input/touch_selection_controller_client_aura_browsertest.cc",
+ "../browser/renderer_host/input/touchpad_pinch_browsertest.cc",
"../browser/renderer_host/input/wheel_scroll_latching_browsertest.cc",
"../browser/renderer_host/media/video_capture_browsertest.cc",
"../browser/renderer_host/render_process_host_browsertest.cc",
@@ -828,7 +847,7 @@ test("content_browsertests") {
"../browser/web_contents/web_contents_impl_browsertest.cc",
"../browser/web_contents/web_contents_view_aura_browsertest.cc",
"../browser/web_contents_binding_set_browsertest.cc",
- "../browser/web_package/web_package_request_handler_browsertest.cc",
+ "../browser/web_package/signed_exchange_request_handler_browsertest.cc",
"../browser/webkit_browsertest.cc",
"../browser/webrtc/webrtc_audio_browsertest.cc",
"../browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc",
@@ -845,10 +864,12 @@ 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_stress_image_capture_browsertest.cc",
"../browser/webrtc/webrtc_stress_pause_browsertest.cc",
"../browser/webrtc/webrtc_stress_resolution_switch_browsertest.cc",
"../browser/webrtc/webrtc_stress_source_switch_browsertest.cc",
"../browser/webrtc/webrtc_video_capture_browsertest.cc",
+ "../browser/webrtc/webrtc_video_capture_service_browsertest.cc",
"../browser/webrtc/webrtc_webcam_browsertest.cc",
"../browser/webrtc/webrtc_webcam_browsertest.h",
"../browser/webui/web_ui_mojo_browsertest.cc",
@@ -893,6 +914,8 @@ test("content_browsertests") {
"//components/discardable_memory/service",
"//components/network_session_configurator/common",
"//components/payments/mojom",
+ "//components/services/leveldb/public/cpp:cpp",
+ "//components/ukm:test_support",
"//components/url_formatter:url_formatter",
"//components/viz/test:test_support",
"//content:resources",
@@ -919,17 +942,20 @@ test("content_browsertests") {
"//ipc",
"//ipc:test_support",
"//media:test_support",
- "//mojo/edk",
+ "//mojo/core/embedder",
"//mojo/public/cpp/bindings",
"//net:test_support",
"//ppapi/buildflags",
"//services/audio/public/cpp",
"//services/catalog:lib",
+ "//services/content/public/cpp",
+ "//services/content/public/mojom",
"//services/device/public/cpp:device_features",
"//services/device/public/cpp/generic_sensor",
"//services/device/public/cpp/test:test_support",
"//services/device/public/mojom",
"//services/device/public/mojom:generic_sensor",
+ "//services/metrics/public/cpp:ukm_builders",
"//services/network:test_support",
"//services/service_manager/public/cpp",
"//services/test/echo/public/mojom",
@@ -1042,10 +1068,7 @@ test("content_browsertests") {
}
if (is_linux) {
- sources += [
- "../browser/linux_ipc_browsertest.cc",
- "../zygote/zygote_browsertest.cc",
- ]
+ sources += [ "../zygote/zygote_browsertest.cc" ]
deps += [ "//ui/gfx:test_support" ]
}
@@ -1096,6 +1119,7 @@ test("content_browsertests") {
if (!is_linux_without_udev && !is_android) {
sources += [ "../browser/webauth/webauth_browsertest.cc" ]
deps += [
+ "//device/base",
"//device/fido:mocks",
"//device/fido:test_support",
]
@@ -1118,8 +1142,8 @@ test("content_browsertests") {
deps += [ "//ui/events:test_support" ]
}
- if (!use_aura && !is_mac) {
- sources -=
+ if (use_aura) {
+ sources +=
[ "../browser/compositor/image_transport_factory_browsertest.cc" ]
}
@@ -1169,7 +1193,6 @@ test("content_browsertests") {
"//ui/touch_selection:test_support",
"//ui/touch_selection:touch_selection",
]
- data_deps += [ "//services/ui" ]
} else {
sources -= [
"../browser/accessibility/touch_accessibility_aura_browsertest.cc",
@@ -1267,7 +1290,7 @@ test("content_unittests") {
"../browser/cache_storage/cache_storage_scheduler_unittest.cc",
"../browser/child_process_security_policy_unittest.cc",
"../browser/cocoa/system_hotkey_map_unittest.mm",
- "../browser/compositor/gpu_vsync_begin_frame_source_unittest.cc",
+ "../browser/code_cache/generated_code_cache_unittest.cc",
"../browser/compositor/reflector_impl_unittest.cc",
"../browser/compositor/software_browser_compositor_output_surface_unittest.cc",
"../browser/cookie_store/cookie_store_manager_unittest.cc",
@@ -1279,18 +1302,21 @@ test("content_unittests") {
"../browser/dom_storage/dom_storage_context_impl_unittest.cc",
"../browser/dom_storage/dom_storage_database_unittest.cc",
"../browser/dom_storage/local_storage_context_mojo_unittest.cc",
+ "../browser/dom_storage/session_storage_area_impl_unittest.cc",
"../browser/dom_storage/session_storage_context_mojo_unittest.cc",
"../browser/dom_storage/session_storage_data_map_unittest.cc",
"../browser/dom_storage/session_storage_database_unittest.cc",
- "../browser/dom_storage/session_storage_leveldb_wrapper_unittest.cc",
"../browser/dom_storage/session_storage_metadata_unittest.cc",
"../browser/dom_storage/session_storage_namespace_impl_mojo_unittest.cc",
+ "../browser/dom_storage/storage_area_impl_unittest.cc",
"../browser/dom_storage/test/fake_leveldb_database_error_on_write.cc",
"../browser/dom_storage/test/fake_leveldb_database_error_on_write.h",
"../browser/dom_storage/test/fake_leveldb_service.cc",
"../browser/dom_storage/test/fake_leveldb_service.h",
"../browser/dom_storage/test/mojo_test_with_file_service.cc",
"../browser/dom_storage/test/mojo_test_with_file_service.h",
+ "../browser/dom_storage/test/storage_area_test_util.cc",
+ "../browser/dom_storage/test/storage_area_test_util.h",
"../browser/download/download_manager_impl_unittest.cc",
"../browser/download/download_request_core_unittest.cc",
"../browser/download/save_package_unittest.cc",
@@ -1306,6 +1332,7 @@ test("content_unittests") {
"../browser/frame_host/navigation_entry_impl_unittest.cc",
"../browser/frame_host/navigation_handle_impl_unittest.cc",
"../browser/frame_host/navigator_impl_unittest.cc",
+ "../browser/frame_host/origin_policy_throttle_unittest.cc",
"../browser/frame_host/render_frame_host_feature_policy_unittest.cc",
"../browser/frame_host/render_frame_host_manager_unittest.cc",
"../browser/frame_host/render_widget_host_view_guest_unittest.cc",
@@ -1349,7 +1376,6 @@ test("content_unittests") {
"../browser/indexed_db/mock_mojo_indexed_db_callbacks.h",
"../browser/indexed_db/mock_mojo_indexed_db_database_callbacks.cc",
"../browser/indexed_db/mock_mojo_indexed_db_database_callbacks.h",
- "../browser/leveldb_wrapper_impl_unittest.cc",
"../browser/loader/cross_site_document_resource_handler_unittest.cc",
"../browser/loader/data_pipe_to_source_stream_unittest.cc",
"../browser/loader/detachable_resource_handler_unittest.cc",
@@ -1361,12 +1387,9 @@ test("content_unittests") {
"../browser/loader/mojo_async_resource_handler_unittest.cc",
"../browser/loader/navigation_url_loader_impl_unittest.cc",
"../browser/loader/navigation_url_loader_unittest.cc",
- "../browser/loader/redirect_to_file_resource_handler_unittest.cc",
- "../browser/loader/resource_buffer_unittest.cc",
"../browser/loader/resource_dispatcher_host_unittest.cc",
"../browser/loader/resource_loader_unittest.cc",
"../browser/loader/source_stream_to_data_pipe_unittest.cc",
- "../browser/loader/temporary_file_stream_unittest.cc",
"../browser/loader/test_resource_handler.cc",
"../browser/loader/test_resource_handler.h",
"../browser/loader/throttling_resource_handler_unittest.cc",
@@ -1374,7 +1397,6 @@ test("content_unittests") {
"../browser/loader/url_loader_factory_impl_unittest.cc",
"../browser/mach_broker_mac_unittest.cc",
"../browser/manifest/manifest_icon_downloader_unittest.cc",
- "../browser/manifest/manifest_icon_selector_unittest.cc",
"../browser/media/audible_metrics_unittest.cc",
"../browser/media/audio_input_stream_broker_unittest.cc",
"../browser/media/audio_loopback_stream_broker_unittest.cc",
@@ -1402,6 +1424,7 @@ test("content_unittests") {
"../browser/memory/test_memory_monitor.h",
"../browser/net/network_quality_observer_impl_unittest.cc",
"../browser/net/quota_policy_cookie_store_unittest.cc",
+ "../browser/network_service_client_unittest.cc",
"../browser/notification_service_impl_unittest.cc",
"../browser/notifications/blink_notification_service_impl_unittest.cc",
"../browser/notifications/notification_database_data_unittest.cc",
@@ -1409,7 +1432,6 @@ test("content_unittests") {
"../browser/notifications/notification_event_dispatcher_impl_unittest.cc",
"../browser/notifications/notification_id_generator_unittest.cc",
"../browser/notifications/platform_notification_context_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",
@@ -1439,6 +1461,7 @@ test("content_unittests") {
"../browser/renderer_host/input/tap_suppression_controller_unittest.cc",
"../browser/renderer_host/input/touch_action_filter_unittest.cc",
"../browser/renderer_host/input/touch_emulator_unittest.cc",
+ "../browser/renderer_host/input/touchpad_pinch_event_queue_unittest.cc",
"../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",
@@ -1497,13 +1520,13 @@ test("content_unittests") {
"../browser/service_worker/service_worker_data_pipe_reader_unittest.cc",
"../browser/service_worker/service_worker_database_unittest.cc",
"../browser/service_worker/service_worker_dispatcher_host_unittest.cc",
- "../browser/service_worker/service_worker_handle_unittest.cc",
"../browser/service_worker/service_worker_installed_scripts_sender_unittest.cc",
"../browser/service_worker/service_worker_job_unittest.cc",
"../browser/service_worker/service_worker_lifetime_tracker_unittest.cc",
"../browser/service_worker/service_worker_metrics_unittest.cc",
"../browser/service_worker/service_worker_navigation_loader_unittest.cc",
"../browser/service_worker/service_worker_new_script_loader_unittest.cc",
+ "../browser/service_worker/service_worker_object_host_unittest.cc",
"../browser/service_worker/service_worker_process_manager_unittest.cc",
"../browser/service_worker/service_worker_provider_host_unittest.cc",
"../browser/service_worker/service_worker_read_from_cache_job_unittest.cc",
@@ -1525,7 +1548,6 @@ test("content_unittests") {
"../browser/storage_partition_impl_unittest.cc",
"../browser/streams/stream_unittest.cc",
"../browser/streams/stream_url_request_job_unittest.cc",
- "../browser/tracing/background_memory_tracing_observer_unittest.cc",
"../browser/tracing/background_tracing_config_unittest.cc",
"../browser/tracing/tracing_ui_unittest.cc",
"../browser/web_contents/aura/gesture_nav_simple_unittest.cc",
@@ -1541,9 +1563,10 @@ test("content_unittests") {
"../browser/web_contents/web_drag_source_mac_unittest.mm",
"../browser/web_package/signed_exchange_cert_fetcher_unittest.cc",
"../browser/web_package/signed_exchange_certificate_chain_unittest.cc",
+ "../browser/web_package/signed_exchange_envelope_unittest.cc",
"../browser/web_package/signed_exchange_handler_unittest.cc",
- "../browser/web_package/signed_exchange_header_parser_unittest.cc",
- "../browser/web_package/signed_exchange_header_unittest.cc",
+ "../browser/web_package/signed_exchange_prologue_unittest.cc",
+ "../browser/web_package/signed_exchange_signature_header_field_unittest.cc",
"../browser/web_package/signed_exchange_signature_verifier_unittest.cc",
"../browser/webrtc/webrtc_internals_message_handler_unittest.cc",
"../browser/webrtc/webrtc_internals_unittest.cc",
@@ -1591,11 +1614,11 @@ test("content_unittests") {
"../common/throttling_url_loader_unittest.cc",
"../common/unique_name_helper_unittest.cc",
"../common/webplugininfo_unittest.cc",
+ "../public/browser/network_connection_tracker_unittest.cc",
"../public/browser/site_isolation_policy_unittest.cc",
# TODO(jam): move these network/ tests to services/network.
"../public/common/drop_data_unittest.cc",
- "../public/common/network_connection_tracker_unittest.cc",
"../public/common/url_utils_unittest.cc",
"../public/test/referrer_unittest.cc",
"../public/test/test_browser_thread_bundle_unittest.cc",
@@ -1603,8 +1626,6 @@ test("content_unittests") {
"../renderer/bmp_image_decoder_unittest.cc",
"../renderer/categorized_worker_pool_unittest.cc",
"../renderer/child_frame_compositing_helper_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",
@@ -1612,8 +1633,8 @@ test("content_unittests") {
"../renderer/dom_storage/mock_leveldb_wrapper.h",
"../renderer/fileapi/webfilewriter_base_unittest.cc",
"../renderer/gpu/frame_swap_message_queue_unittest.cc",
+ "../renderer/gpu/layer_tree_view_unittest.cc",
"../renderer/gpu/queue_message_swap_promise_unittest.cc",
- "../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",
@@ -1629,14 +1650,15 @@ test("content_unittests") {
"../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/low_memory_mode_controller_unittest.cc",
"../renderer/manifest/manifest_parser_unittest.cc",
- "../renderer/media/audio_output_ipc_factory_unittest.cc",
- "../renderer/media/audio_renderer_mixer_manager_unittest.cc",
- "../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/audio/audio_output_ipc_factory_unittest.cc",
+ "../renderer/media/audio/audio_renderer_mixer_manager_unittest.cc",
+ "../renderer/media/audio/audio_renderer_sink_cache_unittest.cc",
+ "../renderer/media/audio/mock_audio_device_factory.cc",
+ "../renderer/media/audio/mock_audio_device_factory.h",
+ "../renderer/media/audio/mojo_audio_input_ipc_unittest.cc",
+ "../renderer/media/audio/mojo_audio_output_ipc_unittest.cc",
"../renderer/media/render_media_log_unittest.cc",
"../renderer/media/renderer_webaudiodevice_impl_unittest.cc",
"../renderer/media/stream/media_stream_audio_processor_unittest.cc",
@@ -1674,17 +1696,17 @@ test("content_unittests") {
"../renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc",
"../renderer/media/webrtc/rtc_rtp_receiver_unittest.cc",
"../renderer/media/webrtc/rtc_rtp_sender_unittest.cc",
+ "../renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc",
"../renderer/media/webrtc/rtc_stats_unittest.cc",
"../renderer/media/webrtc/rtc_video_decoder_unittest.cc",
"../renderer/media/webrtc/rtc_video_encoder_unittest.cc",
"../renderer/media/webrtc/stun_field_trial_unittest.cc",
+ "../renderer/media/webrtc/transceiver_state_surfacer_unittest.cc",
"../renderer/media/webrtc/two_keys_adapter_map_unittest.cc",
"../renderer/media/webrtc/webrtc_audio_renderer_unittest.cc",
- "../renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc",
- "../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_set_description_observer_unittest.cc",
"../renderer/media/webrtc/webrtc_uma_histograms_unittest.cc",
"../renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc",
"../renderer/media/webrtc_local_audio_source_provider_unittest.cc",
@@ -1698,6 +1720,7 @@ test("content_unittests") {
"../renderer/p2p/filtering_network_manager_unittest.cc",
"../renderer/p2p/ipc_network_manager_unittest.cc",
"../renderer/peripheral_content_heuristic_unittest.cc",
+ "../renderer/render_frame_metadata_observer_impl_unittest.cc",
"../renderer/render_thread_impl_unittest.cc",
"../renderer/render_widget_unittest.cc",
"../renderer/service_worker/service_worker_context_client_unittest.cc",
@@ -1785,7 +1808,6 @@ test("content_unittests") {
"//device/gamepad",
"//device/gamepad:test_helpers",
"//device/gamepad/public/cpp:shared_with_blink",
- "//device/geolocation/public/cpp:test_support",
"//gin",
"//gpu",
"//gpu:test_support",
@@ -1798,7 +1820,7 @@ test("content_unittests") {
"//media/capture",
"//media/midi:midi",
"//media/midi:mojo",
- "//mojo/edk",
+ "//mojo/core/embedder",
"//mojo/public/cpp/bindings",
"//mojo/public/cpp/test_support:test_utils",
"//net:extras",
@@ -1812,7 +1834,6 @@ test("content_unittests") {
"//services/device/public/cpp/generic_sensor",
"//services/device/public/cpp/test:test_support",
"//services/device/public/mojom",
- "//services/device/public/mojom",
"//services/file:lib",
"//services/file/public/mojom",
"//services/metrics/public/cpp:ukm_builders",
@@ -1884,10 +1905,6 @@ test("content_unittests") {
sources += [ "../browser/posix_file_descriptor_info_impl_unittest.cc" ]
}
- if (enable_net_mojo) {
- deps += [ "//net:net_utility_services" ]
- }
-
if (enable_plugins) {
sources += [
"../browser/plugin_service_impl_unittest.cc",
@@ -1944,10 +1961,6 @@ test("content_unittests") {
if (is_mac) {
sources += [ "../browser/media/capture/cursor_renderer_mac_unittest.mm" ]
}
- if (is_chromeos) {
- sources +=
- [ "../browser/media/capture/desktop_capture_device_aura_unittest.cc" ]
- }
}
if (is_linux) {
@@ -1992,7 +2005,6 @@ test("content_unittests") {
deps += [
"//base:base_java_unittest_support",
"//content/public/android:content_java",
- "//device/geolocation:geolocation_java",
"//media/capture/content/android",
"//media/capture/content/android:screen_capture_java",
"//ui/android:android",
@@ -2021,7 +2033,10 @@ test("content_unittests") {
is_linux_without_udev = is_linux && !use_udev
if (!is_linux_without_udev && !is_android) {
sources += [ "../browser/webauth/authenticator_impl_unittest.cc" ]
- deps += [ "//device/fido:test_support" ]
+ deps += [
+ "//device/base",
+ "//device/fido:test_support",
+ ]
}
if (use_aura) {
@@ -2030,7 +2045,6 @@ test("content_unittests") {
"//ui/aura_extra",
"//ui/wm",
]
- data_deps += [ "//services/ui" ]
} else {
sources -= [
"../browser/renderer_host/render_widget_host_view_aura_unittest.cc",
@@ -2051,7 +2065,6 @@ test("content_unittests") {
}
if (!use_aura && !is_mac) {
sources -= [
- "../browser/compositor/gpu_vsync_begin_frame_source_unittest.cc",
"../browser/compositor/reflector_impl_unittest.cc",
"../browser/compositor/software_browser_compositor_output_surface_unittest.cc",
]
diff --git a/chromium/content/test/fuzzer/BUILD.gn b/chromium/content/test/fuzzer/BUILD.gn
index 7ca98f71ecb..8c30eb47d2b 100644
--- a/chromium/content/test/fuzzer/BUILD.gn
+++ b/chromium/content/test/fuzzer/BUILD.gn
@@ -40,15 +40,16 @@ fuzzer_test("origin_trial_token_fuzzer") {
seed_corpus = "//content/test/data/fuzzer_corpus/origin_trial_token_data/"
}
-fuzzer_test("origin_manifest_parser_fuzzer") {
+fuzzer_test("origin_policy_parser_fuzzer") {
sources = [
- "origin_manifest_parser_fuzzer.cc",
+ "origin_policy_parser_fuzzer.cc",
]
deps = [
"//content/test:test_support",
]
- dict = "//content/test/data/fuzzer_dictionaries/origin_manifest_parser_fuzzer.dict"
- seed_corpus = "//content/test/data/fuzzer_corpus/origin_manifest_parser_data/"
+ dict =
+ "//content/test/data/fuzzer_dictionaries/origin_policy_parser_fuzzer.dict"
+ seed_corpus = "//content/test/data/fuzzer_corpus/origin_policy_parser_data/"
}
fuzzer_test("renderer_fuzzer") {
@@ -99,27 +100,26 @@ proto_library("html_tree_proto") {
testonly = true
}
-fuzzer_test("signed_exchange_header_fuzzer") {
+fuzzer_test("signed_exchange_envelope_fuzzer") {
sources = [
- "signed_exchange_header_fuzzer.cc",
+ "signed_exchange_envelope_fuzzer.cc",
]
deps = [
"//base:i18n",
"//content/test:test_support",
]
- seed_corpus = "//content/test/data/htxg/"
+ seed_corpus = "//content/test/data/sxg/"
}
-fuzzer_test("signed_exchange_header_parser_fuzzer") {
+fuzzer_test("signed_exchange_signature_header_field_fuzzer") {
sources = [
- "signed_exchange_header_parser_fuzzer.cc",
+ "signed_exchange_signature_header_field_fuzzer.cc",
]
deps = [
"//base:i18n",
"//content/test:test_support",
]
- seed_corpus =
- "//content/test/data/fuzzer_corpus/signed_exchange_header_parser_data/"
+ seed_corpus = "//content/test/data/fuzzer_corpus/signed_exchange_signature_header_field_data/"
}
fuzzer_test("signed_exchange_certificate_chain_fuzzer") {
diff --git a/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.cc b/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.cc
index 3a06b3d4ddb..51eab091720 100644
--- a/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.cc
+++ b/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.cc
@@ -10,9 +10,11 @@
#include "base/mac/foundation_util.h"
#include "content/child/child_process_sandbox_support_impl_mac.h"
#include "third_party/blink/public/platform/mac/web_sandbox_support.h"
-#elif defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#elif defined(OS_POSIX) && !defined(OS_ANDROID)
#include "base/synchronization/lock.h"
#include "content/child/child_process_sandbox_support_impl_linux.h"
+#include "content/child/child_thread_impl.h"
+#include "services/service_manager/public/cpp/connector.h"
#include "third_party/blink/public/platform/linux/web_fallback_font.h"
#include "third_party/blink/public/platform/linux/web_sandbox_support.h"
#endif
@@ -25,11 +27,15 @@ struct WebFontRenderStyle;
namespace content {
-#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
class UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport
: public blink::WebSandboxSupport {
public:
+#if defined(OS_LINUX)
+ explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader)
+ : font_loader_(std::move(font_loader)) {}
+#endif
~SandboxSupport() override {}
#if defined(OS_MACOSX)
@@ -40,7 +46,10 @@ class UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport
const char* preferred_locale,
blink::WebFallbackFont* fallbackFont) override;
void GetWebFontRenderStyleForStrike(const char* family,
- int sizeAndStyle,
+ int size,
+ bool is_bold,
+ bool is_italic,
+ float device_scale_factor,
blink::WebFontRenderStyle* out) override;
private:
@@ -50,14 +59,20 @@ class UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport
base::Lock unicode_font_families_mutex_;
// Maps unicode chars to their fallback fonts.
std::map<int32_t, blink::WebFallbackFont> unicode_font_families_;
+ sk_sp<font_service::FontLoader> font_loader_;
#endif // defined(OS_MACOSX)
};
-#endif // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#endif // defined(OS_POSIX) && !defined(OS_ANDROID)
UtilityBlinkPlatformWithSandboxSupportImpl::
- UtilityBlinkPlatformWithSandboxSupportImpl() {
-#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+ UtilityBlinkPlatformWithSandboxSupportImpl(
+ service_manager::Connector* connector) {
+#if defined(OS_LINUX)
+ font_loader_ = sk_make_sp<font_service::FontLoader>(connector);
+ SkFontConfigInterface::SetGlobal(font_loader_);
+ sandbox_support_ = std::make_unique<SandboxSupport>(font_loader_);
+#elif defined(OS_MACOSX)
sandbox_support_ = std::make_unique<SandboxSupport>();
#endif
}
@@ -67,7 +82,7 @@ UtilityBlinkPlatformWithSandboxSupportImpl::
blink::WebSandboxSupport*
UtilityBlinkPlatformWithSandboxSupportImpl::GetSandboxSupport() {
-#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
return sandbox_support_.get();
#else
return nullptr;
@@ -83,7 +98,7 @@ bool UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport::LoadFont(
return content::LoadFont(src_font, out, font_id);
}
-#elif defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#elif defined(OS_POSIX) && !defined(OS_ANDROID)
void UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport::
GetFallbackFontForCharacter(blink::WebUChar32 character,
@@ -102,17 +117,20 @@ void UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport::
fallback_font->is_italic = iter->second.is_italic;
return;
}
-
- content::GetFallbackFontForCharacter(character, preferred_locale,
- fallback_font);
+ content::GetFallbackFontForCharacter(font_loader_, character,
+ preferred_locale, fallback_font);
unicode_font_families_.emplace(character, *fallback_font);
}
void UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport::
GetWebFontRenderStyleForStrike(const char* family,
- int size_and_style,
+ int size,
+ bool is_bold,
+ bool is_italic,
+ float device_scale_factor,
blink::WebFontRenderStyle* out) {
- GetRenderStyleForStrike(family, size_and_style, out);
+ GetRenderStyleForStrike(font_loader_, family, size, is_bold, is_italic,
+ device_scale_factor, out);
}
#endif
diff --git a/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.h b/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.h
index db4236a6c97..3461acddb50 100644
--- a/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.h
+++ b/chromium/content/utility/utility_blink_platform_with_sandbox_support_impl.h
@@ -11,10 +11,19 @@
#include "build/build_config.h"
#include "content/utility/utility_blink_platform_impl.h"
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
+#include "components/services/font/public/cpp/font_loader.h" // nogncheck
+#include "third_party/skia/include/core/SkRefCnt.h" // nogncheck
+#endif
+
namespace blink {
class WebSandboxSupport;
}
+namespace service_manager {
+class Connector;
+}
+
namespace content {
// This class extends from UtilityBlinkPlatformImpl with added blink web
@@ -22,17 +31,22 @@ namespace content {
class UtilityBlinkPlatformWithSandboxSupportImpl
: public UtilityBlinkPlatformImpl {
public:
- UtilityBlinkPlatformWithSandboxSupportImpl();
+ UtilityBlinkPlatformWithSandboxSupportImpl() = delete;
+ explicit UtilityBlinkPlatformWithSandboxSupportImpl(
+ service_manager::Connector*);
~UtilityBlinkPlatformWithSandboxSupportImpl() override;
// BlinkPlatformImpl
blink::WebSandboxSupport* GetSandboxSupport() override;
private:
-#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
class SandboxSupport;
std::unique_ptr<SandboxSupport> sandbox_support_;
#endif
+#if defined(OS_LINUX)
+ sk_sp<font_service::FontLoader> font_loader_;
+#endif
DISALLOW_COPY_AND_ASSIGN(UtilityBlinkPlatformWithSandboxSupportImpl);
};
diff --git a/chromium/content/utility/utility_main.cc b/chromium/content/utility/utility_main.cc
index 890477a27dc..b8eca5578f5 100644
--- a/chromium/content/utility/utility_main.cc
+++ b/chromium/content/utility/utility_main.cc
@@ -24,6 +24,10 @@
#include "services/service_manager/sandbox/linux/sandbox_linux.h"
#endif
+#if defined(OS_MACOSX)
+#include "base/message_loop/message_pump_mac.h"
+#endif
+
#if defined(OS_WIN)
#include "base/rand_util.h"
#include "sandbox/win/src/sandbox.h"
@@ -39,6 +43,20 @@ int UtilityMain(const MainFunctionParams& parameters) {
parameters.command_line.HasSwitch(switches::kMessageLoopTypeUi)
? base::MessageLoop::TYPE_UI
: base::MessageLoop::TYPE_DEFAULT;
+
+#if defined(OS_MACOSX)
+ // On Mac, the TYPE_UI pump for the main thread is an NSApplication loop. In
+ // a sandboxed utility process, NSApp attempts to acquire more Mach resources
+ // than a restrictive sandbox policy should allow. Services that require a
+ // TYPE_UI pump generally just need a NS/CFRunLoop to pump system work
+ // sources, so choose that pump type instead. A NSRunLoop MessagePump is used
+ // for TYPE_UI MessageLoops on non-main threads.
+ base::MessageLoop::InitMessagePumpForUIFactory(
+ []() -> std::unique_ptr<base::MessagePump> {
+ return std::make_unique<base::MessagePumpNSRunLoop>();
+ });
+#endif
+
// The main message loop of the utility process.
base::MessageLoop main_message_loop(message_loop_type);
base::PlatformThread::SetName("CrUtilityMain");
diff --git a/chromium/content/utility/utility_service_factory.cc b/chromium/content/utility/utility_service_factory.cc
index b7fd74830e8..4d2eb9525b2 100644
--- a/chromium/content/utility/utility_service_factory.cc
+++ b/chromium/content/utility/utility_service_factory.cc
@@ -4,7 +4,8 @@
#include "content/utility/utility_service_factory.h"
-#include <memory>
+#include <utility>
+#include <vector>
#include "base/bind.h"
#include "base/command_line.h"
@@ -107,7 +108,8 @@ std::unique_ptr<service_manager::Service> CreateVizService() {
} // namespace
UtilityServiceFactory::UtilityServiceFactory()
- : network_registry_(std::make_unique<service_manager::BinderRegistry>()) {}
+ : network_registry_(std::make_unique<service_manager::BinderRegistry>()),
+ audio_registry_(std::make_unique<service_manager::BinderRegistry>()) {}
UtilityServiceFactory::~UtilityServiceFactory() {}
@@ -131,8 +133,10 @@ void UtilityServiceFactory::RegisterServices(ServiceMap* services) {
services->insert(
std::make_pair(video_capture::mojom::kServiceName, video_capture_info));
+ GetContentClient()->utility()->RegisterAudioBinders(audio_registry_.get());
service_manager::EmbeddedServiceInfo audio_info;
- audio_info.factory = base::BindRepeating(&audio::CreateStandaloneService);
+ audio_info.factory = base::BindRepeating(
+ &UtilityServiceFactory::CreateAudioService, base::Unretained(this));
services->insert(std::make_pair(audio::mojom::kServiceName, audio_info));
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
@@ -185,4 +189,9 @@ UtilityServiceFactory::CreateNetworkService() {
std::move(network_registry_));
}
+std::unique_ptr<service_manager::Service>
+UtilityServiceFactory::CreateAudioService() {
+ return audio::CreateStandaloneService(std::move(audio_registry_));
+}
+
} // namespace content
diff --git a/chromium/content/utility/utility_service_factory.h b/chromium/content/utility/utility_service_factory.h
index 45283fe61a7..639f286c68a 100644
--- a/chromium/content/utility/utility_service_factory.h
+++ b/chromium/content/utility/utility_service_factory.h
@@ -34,10 +34,12 @@ class UtilityServiceFactory : public ServiceFactory {
void OnLoadFailed() override;
std::unique_ptr<service_manager::Service> CreateNetworkService();
+ std::unique_ptr<service_manager::Service> CreateAudioService();
// Allows embedders to register their interface implementations before the
- // network service is created.
+ // network or audio services are created. Used for testing.
std::unique_ptr<service_manager::BinderRegistry> network_registry_;
+ std::unique_ptr<service_manager::BinderRegistry> audio_registry_;
DISALLOW_COPY_AND_ASSIGN(UtilityServiceFactory);
};
diff --git a/chromium/content/utility/utility_thread_impl.cc b/chromium/content/utility/utility_thread_impl.cc
index 767ee872b5e..607cea7465d 100644
--- a/chromium/content/utility/utility_thread_impl.cc
+++ b/chromium/content/utility/utility_thread_impl.cc
@@ -99,7 +99,7 @@ void UtilityThreadImpl::EnsureBlinkInitialized() {
EnsureBlinkInitializedInternal(/*sandbox_support=*/false);
}
-#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
void UtilityThreadImpl::EnsureBlinkInitializedWithSandboxSupport() {
EnsureBlinkInitializedInternal(/*sandbox_support=*/true);
}
@@ -118,7 +118,8 @@ void UtilityThreadImpl::EnsureBlinkInitializedInternal(bool sandbox_support) {
blink_platform_impl_ =
sandbox_support
- ? std::make_unique<UtilityBlinkPlatformWithSandboxSupportImpl>()
+ ? std::make_unique<UtilityBlinkPlatformWithSandboxSupportImpl>(
+ GetConnector())
: std::make_unique<UtilityBlinkPlatformImpl>();
blink::Platform::Initialize(blink_platform_impl_.get());
}
diff --git a/chromium/content/utility/utility_thread_impl.h b/chromium/content/utility/utility_thread_impl.h
index 618459cc875..a1b8d47b379 100644
--- a/chromium/content/utility/utility_thread_impl.h
+++ b/chromium/content/utility/utility_thread_impl.h
@@ -42,7 +42,7 @@ class UtilityThreadImpl : public UtilityThread,
// UtilityThread:
void ReleaseProcess() override;
void EnsureBlinkInitialized() override;
-#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#if defined(OS_POSIX) && !defined(OS_ANDROID)
void EnsureBlinkInitializedWithSandboxSupport() override;
#endif
#if defined(OS_MACOSX)